<template>
  <div :class="{ 'u-tree_pop': title }">
    <h4 v-if="title" class="dg-words-title-second">{{ title }}</h4>
    <slot></slot>
    <div v-if="search" class="u-tree__search">
      <!--<el-input placeholder="关键字搜索" suffix-icon="el-icon-search" v-model="filterText" />-->
      <el-input
        placeholder="关键字搜索"
        v-model="searchForm.name"
        class="tree__search__input"
        clearable
        size="mini"
        @keyup.enter.native="handleSearch"
      ></el-input>
      <dg-button type="primary" @click="handleSearch" icon="el-icon-search" class="u-tree__search-btn" size="mini"
        >查询</dg-button
      >
    </div>
    <div v-if="searchResultList.length == 0 && isclickSearch && !loading" class="no-search-data">暂无数据</div>
    <div class="u-tree__bar" :style="{ height: treeHeight }">
      <dg-scrollbar v-show="!isclickSearch" :key="key">
        <dg-tree
          ref="tree"
          node-key="id"
          :props="props"
          :load="loadNode"
          :filter-node-method="filterNode"
          :draggable="draggable"
          :lazy="lazy"
          v-bind="$attrs"
          v-on="$listeners"
          :expand-on-click-node="true"
          :style="{ 'padding-right': paddingRight }"
        >
          <div slot-scope="{ node, data }" class="u-tree-label">
            <p @dblclick="handlerNodeDoubleClick(data)" @click="handleNodeClick(data)">
              <i class="el-icon-folder-opened" v-if="data.isParent"></i>
              <i class="el-icon-document" v-else></i>
              <span class="tree-node__text" :title="data[labelName]"> {{ data[labelName] }}</span>
            </p>
          </div>
        </dg-tree>
      </dg-scrollbar>
      <!-- <div v-show="isclickSearch"> -->
        <dg-scrollbar load-distance @scroll-bottom="handleScrollToBottomLoading" v-loading="loading">
          <ul class="search-result" v-show="searchResultList.length > 0">
            <li
              :class="{ 'is-active': item.selected }"
              v-for="(item, index) in searchResultList"
              :key="index"
              @click="doClickSearchItem(item, index)"
              :title="item.fullName"
            >
              {{ item.fullName }}
            </li>
          </ul>
        </dg-scrollbar>
      <!-- </div> -->
    </div>
  </div>
</template>

<script>
// 懒加载数据源
import * as commonApi from '@/api/common';
let debounceTimer;

export default {
  name: 'lTree',

  props: {
    props: {
      type: Object,
      default() {
        return {
          value: 'id',
          label: 'name',
          children: 'children',
          isLeaf(data) {
            return data.isParent !== true;
          }
        };
      }
    },
    params: {
      type: Object,
      default: () => {}
    },
    // 标题
    title: {
      type: String,
      default: ''
    },
    apiName: {
      type: String,
      default: 'getTree'
    },
    // 是否拖拽
    draggable: {
      type: Boolean,
      default: false
    },
    // 关键字查询
    search: {
      type: Boolean,
      default: false
    },
    // label
    labelName: {
      type: String,
      default: 'name'
    },
    // 自定义查询参数
    searchParams: {
      type: Object,
      default() {
        return {
          name: '',
          mtType: 'app',
          pageNum: 0,
          pageSize: 50
        };
      }
    },
    // 根节点是否默认选中
    ifCheckedFirstNode: {
      type: Boolean,
      default: true
    },
    // 树高度
    treeHeight: {
      type: String,
      default: 'calc(100vh - 24rem)'
    },
    // 是否取消选中节点
    isClearSelectedNode: {
      type: Boolean,
      default: false
    },
    paddingRight: {
      type: String,
      default: '0px'
    },
    lazy: {
      type: Boolean,
      default: true
    }
  },
  computed: {
    searchForm() {
      return this.searchParams;
    }
  },
  watch: {
    filterText: {
      handler(val) {
        this.$refs.tree.filter(val);
      },
      immediate: false
    },
    isClearSelectedNode(val) {
      if (val) {
        this.$refs.tree.setCurrentKey(null);
        this.$emit('setClearNodesFlag', false);
      }
    }
  },
  data() {
    return {
      // 过滤文本
      filterText: '',
      rootNode: '', // 第一个节点ID
      dataTree: [],
      timer: null,
      isShowSearchResult: false,
      searchResultList: [],
      isclickSearch: false,
      key: 0,
      loading: false
    };
  },
  methods: {
    // 滚动条触底加载数据
    handleScrollToBottomLoading() {
      if (this.isLast) {
        return;
      }
      this.loading = true;
      setTimeout(() => {
        this.searchForm.pageNum++;
        this.treeMatch();
      }, 500);
    },
    // 加载数据
    treeMatch() {
      const { searchForm } = this;
      commonApi.treeMatch(searchForm).then((res) => {
        let { content, totalElements } = res.data;
        for (let i = 0; i < content.length; i++) {
          content[i].selected = false;
        }
        this.searchResultList = [...this.searchResultList, ...content];
        this.isLast = this.searchResultList.length == totalElements;
        this.loading = false;
      });
    },
    handleSearch() {
      if (this.searchForm.name) {
        this.loading = true;
        this.isclickSearch = true;
        this.$set(this.searchForm, 'pageNum', 0);
        this.$set(this, 'searchResultList', []);
        this.treeMatch();
      } else {
        this.searchResultList = [];
        this.isclickSearch = false;
        this.key++;
      }
    },
    doClickSearchItem(item, index) {
      // 清空选中效果
      for (let i = 0; i < this.searchResultList.length; i++) {
        this.searchResultList[i].selected = false;
      }
      // 设置选中效果
      this.searchResultList[index].selected = true;
      this.$emit('doClickSearchItem', item);
      this.$emit('handleGetNode', { ...item, code: item.id });
    },
    handlerNodeDoubleClick(data) {
      const that = this;
      debounceTimer = that.timer;
      if (debounceTimer) {
        clearTimeout(debounceTimer);
        that.timer = null;
      }
      that.$emit('handleDoubleClick', data);
    },

    handleNodeClick(data) {
      const that = this;
      debounceTimer = that.timer;
      if (debounceTimer) {
        clearTimeout(debounceTimer);
        that.timer = null;
      }
      that.timer = setTimeout(() => {
        that.$emit('handleGetNode', data);
      }, 300);
    },

    filterNode(value, data) {
      if (!value) return true;
      return data[this.labelName].indexOf(value) !== -1;
    },

    // 刷新局部
    refreshNodeBy(id) {
      const that = this;
      let node = this.$refs.tree.getNode(id || that.rootNode); // 通过节点id找到对应树节点对象
      if (!node) {
        return;
      }
      node.loaded = false;
      node.expand();
    },
    getParentNode(id) {
      let node = this.$refs.tree.getNode(id || this.rootNode); // 通过节点id找到对应树节点对象
      if (!node.parent) {
        return;
      }
      return node.parent;
    },
    getTargetNode(targetId) {
      return this.$refs.tree.getNode(targetId);
    },
    setCurrentKey(id) {
      const node = this.$refs.tree.getNode(id);
      if (!node) {
        return;
      }
      this.$refs.tree.setCurrentKey(id);
    },
    loadNode(node, resolve) {
      const that = this;
      that.getTree(node.level === 0 ? void 0 : node.key, resolve, node.level);
    },
    // 组织机构
    getTree(id, resolve, level) {
      const that = this;
      const { params, apiName } = this;
      return commonApi[apiName]({ id, ...params })
        .then((res) => {
          // 就为了存根节点, 用于刷新
          resolve(res || []);
          if (level === 0) {
            that.rootNode = id || (res[0] || {}).id;
            if (that.ifCheckedFirstNode) {
              that.setCurrentKey(that.rootNode);
            }
            that.$emit('submitRootNode', { id: that.rootNode, name: res[0].name, code: res[0].code });
          }
        })
        .catch(() => resolve([]));
    }
  }
};
</script>

<style lang="scss" scoped>
.u-tree__seach {
  .tree__search__input {
    width: 65%;
    margin-bottom: 10px;
  }
}
.u-tree_pop {
  width: 100%;
  border: 1px solid #eef2fa;
  display: inline-block;
  vertical-align: top;

  & > h4 {
    font-size: 14px;
    height: 48px;
    line-height: 48px;
    padding: 0 15px;
    border: 0 none;
    background-color: #eef2fa;
    text-align: left;
  }

  .dg-tree-node .el-tree-node__content > .el-tree-node__expand-icon {
    margin-left: 7px;
  }
}

.u-tree__search {
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  &-btn {
    margin-left: 5px;
  }
}

.no-search-data {
  text-align: center;
  color: rgba(0, 0, 0, 0.45);
  margin-top: 40px;
}
.search-result {
  li {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 5px 12px;
    cursor: pointer;
  }
  li:hover {
    background-color: rgba(24, 144, 255, 0.12);
  }
  .is-active {
    background-color: rgba(24, 144, 255, 0.12);
  }
}
.u-tree-label {
  width: 85%;
  padding-right: 10px;
}
// /deep/ .el-tree {
//     padding-right: 15px;
// }
</style>
