<!--
 * @Author: fengyang9326@163.com
 * @Date: 2024-05-15 15:22:52
 * @LastEditors: fengyang9326@163.com
 * @LastEditTime: 2024-05-16 10:27:18
 * @FilePath: /web/framework/src/views/system/temporary/tree-dynamic.vue
 * @Description:
-->
<template>
  <div class="tree_dynamic">
    <!-- 搜索框 -->
    <el-input
      v-if="hasSearch"
      v-model="filterText"
      class="filter_input"
      clearable
      :size="inputSize"
      :placeholder="filterPlaceholder"
    />
    <!-- 树结构 -->
    <el-tree
      ref="dynamicTree"
      :class="hasSearch ? 'whole_tree' : 'part_tree'"
      :data="treeData"
      :props="treeProps"
      :style="{ height: treeHeight }"
      :expand-on-click-node="expandOnClickNode"
      :node-key="nodeKey"
      :default-expand-all="defaultExpandAll"
      :filter-node-method="filterNode"
      highlight-current
      @node-click="treeNodeClick"
    >
      <span
        slot-scope="{ node, data }"
        class="custom-tree-node"
        @mouseenter="mouseenter(data)"
        @mouseleave="mouseleave(data)"
      >
        <span :title="node.label" class="tree_node_span">
          <template id="">
            <i class="el-icon-folder-opened" style="margin-right: 3px" />
          </template>
          <span :title="node.label" class="title_tree">{{ node.label }}</span>
        </span>
        <span class="tree_operation" style="display: inline-block; width: 80px; text-align: right">
          <slot v-if="treeNodeHandle" class="fr_text" :data="data">操作按钮</slot>
        </span>
      </span>
    </el-tree>
  </div>
</template>

<script>
export default {
  name: 'TreeDynamic',
  components: {},
  props: {
    /* 是否可搜索 */
    hasSearch: {
      type: Boolean,
      default: true,
    },
    /* 搜索框文字提示 */
    filterPlaceholder: {
      type: String,
      default: '输入关键字进行过滤',
    },
    // 搜索框大小
    inputSize: {
      type: String,
      default: 'small',
    },
    /* 树结构数据 */
    treeData: {
      type: Array,
      default: () => [],
      required: true,
    },
    /* 树结构 props */
    treeProps: {
      type: Object,
      default: () => {},
      required: true,
    },
    /* 是否默认展开所有节点 */
    defaultExpandAll: {
      type: Boolean,
      default: true,
    },
    /* 是否在点击节点的时候展开或者收缩节点 */
    expandOnClickNode: {
      type: Boolean,
      default: false,
    },
    /* 树节点 nodeKey */
    nodeKey: {
      type: String,
      default: 'id',
    },
    /* 树结构节点操作 */
    treeNodeHandle: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      /* 搜索字段 */
      filterText: '',
      treeHeight: '',
    };
  },
  computed: {},
  watch: {
    filterText(val) {
      this.$refs.dynamicTree.filter(val);
    },
    deep: true,
  },
  created() {},
  mounted() {
    /* 获取搜索框样式，动态赋值树高度 */
    if (this.hasSearch) {
      const that = this;
      this.$nextTick(() => {
        const inputDom = document.getElementsByClassName('filter_input')[0];
        if (inputDom) {
          const inputDomHeight = inputDom.scrollHeight + 8;
          if (inputDomHeight) {
            const treeCalcHeight = `calc(100% - ${inputDomHeight}px)`;
            that.$set(that, 'treeHeight', treeCalcHeight);
          }
        }
      });
    } else {
      this.$set(this, 'treeHeight', '100%');
    }
  },
  methods: {
    /* 搜索 */
    filterNode(value, data) {
      if (!value) return true;
      const label = this.treeProps.label;
      return data[label].indexOf(value) !== -1;
    },
    /* 树结构 点击节点 */
    treeNodeClick(node) {
      this.$emit('treeNodeClick', node);
    },
    /** 树节点鼠标移入移出 */
    mouseenter(data) {
      this.$set(data, 'show', true);
    },
    mouseleave(data) {
      this.$set(data, 'show', false);
    },
  },
};
</script>
<style lang="scss" scoped>
.tree_dynamic {
  height: 100%;
  width: 100%;
  box-sizing: border-box;
  padding-right: 1px;
  overflow: hidden;
}
/* 搜索框样式 */
.filter_input {
  margin-bottom: 8px;
}
/* 树结构样式 */
.el-tree {
  width: 100%;
  overflow-y: auto;
  .custom-tree-node {
    display: flex;
    align-items: center;
    width: calc(100% - 24px) !important;
    font-size: 14px;
  }
  .custom-tree-node .tree_node_span {
    display: flex;
    align-items: center;
    font-size: 14px;
    width: calc(100% - 80px) !important;
    i {
      display: inline-block;
    }
    .title_tree {
      display: inline-block;
      width: calc(100% - 18px) !important;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
      height: 100%;
    }
  }
}
.part_tree {
  height: 100%;
}
.whole_tree {
  height: v-bind(treeHeight);
}
</style>
