<!--
 * @Author: fengyang9326@163.com
 * @Date: 2024-05-13 10:36:07
 * @LastEditors: fengyang9326@163.com
 * @LastEditTime: 2024-05-20 09:38:24
 * @FilePath: /web/components/com-selectTree/index.vue
 * @Description: 树结构下拉框
-->
<template>
  <el-select
    ref="Select"
    v-model="formData"
    :value-key="selectKey"
    :placeholder="placeholderTitle"
    size="medium"
    :clearable="clearable"
    :disabled="disabled"
    :filterable="filterable"
    :filter-method="filterMethod"
    style="width: 100%"
    @clear="clear"
    @visible-change="visibleChange"
    @focus="setMinWidth"
  >
    <el-option
      ref="option"
      class="select_tree_option"
      :value="formData.id"
      :label="formData.name"
      :style="{ width: minWidth + 2 + 'px' }"
    >
      <el-tree
        ref="Tree"
        class="select_tree_tree"
        :node-key="treeNodeKey"
        :current-node-key="currentSelect"
        :data="treeData"
        :props="treeProps"
        :highlight-current="true"
        :expand-on-click-node="false"
        :default-expanded-keys="parentList"
        :filter-node-method="filterNode"
        @node-click="handleNodeClick"
      >
        <span slot-scope="{ node }" class="custom-tree-node">
          <span :title="node.label" class="title_tree">{{ node.label }}</span>
        </span>
      </el-tree>
    </el-option>
  </el-select>
</template>
<script>
export default {
  name: 'SelectTree',
  props: {
    // v-model绑定
    // 作为 el-select value 唯一标识的键名，绑定值为对象类型时必填
    selectKey: {
      type: String,
      default: 'id',
    },
    valueKey: {
      type: String,
      default: 'id',
    },
    valueName: {
      type: String,
      default: 'name',
    },
    // 树形的数据
    treeData: {
      type: Array,
      default: () => [],
    },
    // 下拉框默认提示
    placeholderTitle: {
      type: String,
      default: '请选择',
    },
    // 每个树节点用来作为唯一标识的属性
    treeNodeKey: {
      type: [String, Number],
      default: 'id',
    },
    // 是否可搜
    filterable: {
      type: Boolean,
      default: false,
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false,
    },
    // 是否可清空input
    clearable: {
      type: Boolean,
      default: false,
    },
    // tree的props配置
    treeProps: {
      type: Object,
      default: () => ({}),
    },
    // 弹窗标题
    title: {
      type: String,
      default: '新建',
    },
    echoData: {
      type: Object,
      default: () => ({}),
    },
  },
  data() {
    return {
      // 下拉框最小宽度样式
      minWidth: undefined,
      formData: {
        id: '',
        name: '',
      },
      parentList: [], // 树结构默认展开的节点的 key 的数组
      filterFlag: false,
      currentSelect: '', // 当前选中的节点
    };
  },
  computed: {},
  created() {
    if (this.echoData[this.selectKey]) {
      this.parentList.push(this.echoData[this.selectKey]);
      this.$set(this, 'currentSelect', this.echoData[this.selectKey]);
      this.$set(this.formData, 'id', this.echoData[this.selectKey]);
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.$refs.Tree.setCurrentKey(this.currentSelect);
      const nodeTree = this.$refs.Tree.getCurrentNode();
      if (nodeTree) {
        this.$set(this.formData, 'name', nodeTree[this.valueName]);
      }
      if (!nodeTree) this.$set(this.formData, 'id', '');
    });
  },
  methods: {
    /* 下拉框样式 无数据的情况下，给请选择提示设置最小宽度*/
    setMinWidth(val) {
      this.minWidth = val.srcElement.clientWidth;
    },
    /* 树节点被点击时的回调 */
    handleNodeClick(data) {
      if (!data[this.valueKey]) return;
      const DataId = data[this.valueKey];
      const DataName = data[this.valueName];
      this.$set(this.formData, 'id', DataId);
      this.$set(this.formData, 'name', DataName);
      this.$set(this, 'currentSelect', data[this.valueKey]);
      this.$refs.Select.visible = false;
      // this.$emit('nodeClickTree', this.formData)
      this.$emit('nodeClickTree', data);
    },
    /* 下拉框出现/隐藏时触发 */
    visibleChange(e) {
      if (e) {
        const tree = this.$refs.Tree;
        this.filterFlag && tree.filter('');
        this.filterFlag = false;
        let selectDom = null;
        selectDom = tree.$el.querySelector('.is-current');
        setTimeout(() => {
          this.$refs.Select.scrollToOption({ $el: selectDom });
        }, 0);
      }
    },
    clear() {
      this.formData = {
        id: '',
        name: '',
      };
      this.$refs.Tree.setCurrentKey(null);
      this.$emit('nodeClickTree', this.formData);
    },
    /* 自定义搜索方法 */
    filterMethod(val) {
      this.filterFlag = true;
      this.$refs.Tree.filter(val);
    },
    /* 对树节点进行筛选时执行的方法 */
    filterNode(value, data) {
      if (!value) return true;
      const label = this.treeProps.label || 'name';
      return data[label].indexOf(value) !== -1;
    },
  },
};
</script>
<style lang="scss" scope>
.el-select-dropdown {
  padding: 5px 0;
}
.select_tree_option {
  &.el-select-dropdown__item {
    height: auto;
    line-height: 1;
    padding: 0;
    background-color: #fff;
  }
}

.select_tree_tree {
  padding: 0px 0px;
  font-weight: 400;
}
.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
  background-color: #fff;
  color: #1890ff;
}
.el-tree-node__content {
  width: 100% !important;
  height: 34px !important;
  line-height: 34px !important;
  overflow: hidden;
  &:hover {
    background-color: transparent !important;
  }
}
::v-deep .select_tree_tree .el-tree-node .el-tree-node__content .custom-tree-node {
  display: inline-block;
  vertical-align: middle;
  width: calc(100% - 50px) !important;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
</style>
