<!--
 * @Tite: 树形控件
 * @Des: 带关键字过滤功能树形控件的组件
 * @Author: Rockery <1113269755@qq.com>
-->

<template>
  <div class="commonfilterselecttree" v-loading="loading">
    <el-row :gutter="10" class="cfstree-row">
      <el-col :span="24" class="mt10 mb20 cfstree-filtertext">
        <el-input
          v-model="filterText"
          placeholder="请输入关键字进行过滤"
          clearable
          size="small"
          style="text-align: center;"
        >
          <i slot="suffix" class="el-input__icon el-icon-search"></i>
        </el-input>
      </el-col>

      <el-col :span="24" class="cfstree-tree">
        <el-tree
          class="filter-tree cfstree-row-tree"
          :data="currentTreeData"
          :props="defaultProps"
          :lazy="isTreeLazy"
          :load="handleLoadNode"
          :node-key="treeNodeKey"
          :highlight-current="true"
          :default-expanded-keys="defaultExpandedKeys"
          :filter-node-method="filterNodeMethod"
          ref="custFilterSelectTreeRef"
          @node-click="handleNodeClick"
        ></el-tree>
      </el-col>
    </el-row>
  </div>
</template>

<script>

export default {
  name: 'CommonFilterSelectTree',
  props: {
    // 树形控件数据对象
    treeData: {
      required: false,
      type: Array,
      default() {
        return [{
          id: '0001',
          label: '一级 1',
          children: [{
            id: '00010001',
            label: '二级 1-1',
            children: [{
              id: '000100010001',
              label: '三级 1-1-1'
            }]
          }]
        }, {
          id: '0002',
          label: '一级 2',
          children: [{
            id: '00020001',
            label: '二级 2-1',
            children: [{
              id: '000200010001',
              label: '三级 2-1-1'
            }]
          }, {
            id: '00020002',
            label: '二级 2-2',
            children: [{
              id: '000200020001',
              label: '三级 2-2-1'
            }]
          }]
        }, {
          id: '0003',
          label: '一级 3',
          children: [{
            id: '00030001',
            label: '二级 3-1',
            children: [{
              id: '00030002',
              label: '三级 3-1-1'
            }]
          }, {
            id: '00030002',
            label: '二级 3-2',
            children: [{
              id: '000300020001',
              label: '三级 3-2-1'
            }]
          }]
        }];
      }
    },
    // 树形控件默认属性
    defaultProps: {
      required: false,
      type: Object,
      default() {
        return {
          children: 'children',
          label: 'label',
          isLeaf: 'leaf'
        };
      }
    },
    // 树形控件节点标识
    treeNodeKey: {
      required: false,
      type: String,
      default: 'id'
    },
    // 树形控件过滤字段标识
    filterKeyWord: {
      required: false,
      type: String,
      default: 'label'
    },
    // 树形控件默认展开节点标识
    defaultExpandedKeys: {
      required: false,
      type: Array,
      default() {
        return [];
      }
    },
    // 是否懒加载
    isTreeLazy: {
      required: false,
      type: Boolean,
      default: false
    },
    // 懒加载数据请求方法
    treeLazyRequstFun: {
      type: Function,
      require: false
    },
    /**
    * 懒加载数据请求参数Key值
    * @key 参数属性
    * @value 参数取值属性
    */
    treeLazyRequstParam: {
      type: Array,
      require: false,
      default() {
        return [
          {
            key: 'parentId',
            value: 'id'
          }
        ];
      }
    }
  },
  data() {
    return {
      loading: true,
      filterText: '',
      handleLoadNodeTimeout: null
    };
  },
  computed: {
    // 当前树形控件数据
    currentTreeData: {
      get() {
        return this.treeData;
      },
      set(value) {
        this.$emit('update:treeData', value);
      }
    },
  },
  watch: {
    filterText(val) {
      this.$refs.custFilterSelectTreeRef?.filter?.(val);
    }
  },
  methods: {
    /** 过滤节点数据 */
    filterNodeMethod(value, data) {
      if (!value) return true;
      return data[this.filterKeyWord].indexOf(value) !== -1;
    },
    /** 选择树形控件节点操作 */
    handleNodeClick(value) {
      this.$emit('selectTreeNodeClick', value);
    },
    handleLoadNode(node, resolve) {
      this.loading = true;
      // 判断是否为懒加载操作
      if (!this.isTreeLazy) return resolve([]);

      // 判断懒加载请求方法是否存在
      if (!this.treeLazyRequstFun) {
        this.msgWarning('Sorry，懒加载请求方法不在！');
        return resolve([]);
      }

      // 获取当前节点数据
      let currNodeDataObj = node?.data ?? '';

      // 如果当前节点数据不存在返回空
      if (!currNodeDataObj) {
        return resolve([]);
      }

      this.handleLoadNodeTimeout = setTimeout(() => {
        // 组装请求参数
        let treeLazyReqObj = {};
        for (let item of this.treeLazyRequstParam) {
          treeLazyReqObj[item?.key] = currNodeDataObj[item?.value];
        }

        // 获取懒加载请求数据
        this.treeLazyRequstFun(treeLazyReqObj).then(
          response => {
            resolve(response?.data || []);
            this.closeHandleLoadNodeTimeout();
            this.loading = false;
          }
        ).catch(() => {
          resolve([]);
          this.closeHandleLoadNodeTimeout();
          this.loading = false;
        });
      }, 300);
    },
    closeHandleLoadNodeTimeout() {
      this.handleLoadNodeTimeout != null && clearTimeout(this.handleLoadNodeTimeout);
    }
  },
  beforeDestroy() {
    this.closeHandleLoadNodeTimeout();
  }
};
</script>

<style lang="scss" scoped>
.commonfilterselecttree {
  background: #fff;
  .cfstree-row {
    margin: 0 !important;

    &-tree {
      height: calc(100vh - 220px);
      overflow-y: auto;
      margin-bottom: -17px;
      margin-right: -17px;
      overflow-x: hidden;
      /* border: 1px solid #dcdfe6; */
    }
  }
}
</style>
