<!--
 * @Author: your name
 * @Date: 2019-11-01 08:42:24
 * @LastEditTime: 2019-11-13 08:48:36
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \BASE\node_modules\zfs-component\src\async-tree.vue
 -->
<template>
<div class="zte-tree">
  <el-input
    v-if="filter"
      placeholder="输入关键字过滤, 按回车搜索"
      @keyup.enter.native="handleSeach"
      v-model="filterText">
  </el-input>
  <div class="tree-container">
        <!-- render-after-expand  -->
    <el-scrollbar :style="heightObj">
      <el-tree
        v-if="showLazyTree"
        key="lazyTree"
        ref="lazyTree"
        class="filter-tree"
        lazy
        check-strictly
        :indent='12'
        :load="loadNode"
        :node-key="nodeKey"
        :default-expand-all="false"
        :props="defaultProps"
        :show-checkbox="showCheckbox"
        :check-on-click-node="clickCheck"
        :expand-on-click-node="clickExpand"
        @check="checkChange"
        @node-click="nodeOriginClick"
        >
      </el-tree>
      <el-tree
        v-else
        ref="tree"
        key="tree"
        :data="treeData"
        check-strictly
        :indent='12'
        class="filter-tree"
        :node-key="nodeKey"
        render-after-expand
        default-expand-all
        :props="defaultProps"
        :show-checkbox="showCheckbox"
        :check-on-click-node="clickCheck"
        :expand-on-click-node="clickExpand"
        @check="checkChange"
        @node-click="nodeOriginClick"
        >
      </el-tree>
    </el-scrollbar>
  </div>
</div>
</template>

<script>
export default {
  name: 'asyncTree',
  props: {
    data: {
      type: Array,
      default: () => [],
    },
    filterAjax: {
      type: String,
      required: true,
    },
    treeAjax: {
      type: String,
      required: true,
    },
    selectedAjax: {
      type: String,
    },
    clickExpand: {
      type: Boolean,
      default: true,
    },
    clickCheck: {
      type: Boolean,
      default: true,
    },
    expandAll: {
      type: Boolean,
      default: true,
    },
    nodeKey: {
      type: String,
      default: 'id',
    },
    childrenProp: {
      type: String,
      default: 'children',
    },
    labelProp: {
      type: String,
      default: 'name',
    },
    isLeafProp: {
      type: String,
      default: 'leaf',
    },
    highlight: {
      type: Boolean,
      default: false,
    },
    showCheckbox: {
      type: Boolean,
      default: false,
    },
    editable: {
      type: Boolean,
      default: false,
    },
    filter: {
      type: Boolean,
      default: true,
    },
    height: {
      type: String,
    },
    selected: {
      type: String,
      default: '',
    },
    level: {
      type: Number,
    },
    searchLazy: {
      type: Boolean,
      default: false,
    },
    rootParentId: {
      type: String,
      default: '0',
    },
  },
  data() {
    return {
      filterText: '',
      selectedArr: [],
      defaultProps: {
        children: this.childrenProp,
        label: this.labelProp,
        isLeaf: this.isLeafProp,
      },
      currencyNode: {},
      showLazyTree: true,
      treeData: [],
      selectedNodeObjs: [],
    };
  },
  computed: {
    heightObj() {
      return this.height ? { height: this.height } : {};
    },
    refTree() {
      return this.showLazyTree ? this.$refs.lazyTree : this.$refs.tree;
    },
  },
  watch: {
    data() {
      this.$nextTick(() => {
        if (!this.filterFlag) {
          this.expandLevel(this.$refs.tree);
        } else {
          this.filterFlag = false;
        }
      });
    },
  },
  methods: {
    nodeOriginClick(data, node) {
      this.$emit('node-click', node);
    },
    resolveTree(node) {
      this.$refs.lazyTree.updateKeyChildren(node.data[this.nodeKey], []);
      this.$nextTick(() => {
        if (node.resolve) {
          this.loadNode(node, node.resolve);
        }
      })
    },
    loadNode(node, resolve) {
      if (node.data && node.data[this.isLeafProp]) {
        return;
      }
      node.resolve = (d) => { resolve(d) };

      const key = node.level === 0 ? this.rootParentId : node.data[this.nodeKey];
      this.$http.get(`${this.treeAjax}/${key}`)
        .then(({ data }) => {
          const tree = data.tree;
          if (node.data) {
            node.data.children = tree;
          }
          resolve(tree);
        });
    },
    handleSeach() {
      if (this.filterText) {
        this.$http.get(`${this.filterAjax}/${this.filterText}`)
          .then(({ data }) => {
            this.showLazyTree = this.searchLazy;
            this.treeData = data.tree;
          });
      } else {
        this.showLazyTree = true;
      }
    },
    checkChange(node, selfChecked ) {
      const nodeKeyValue = node[this.nodeKey];
      if (selfChecked && !this.selectedNodeObjs.find(obj => obj[this.nodeKey] === nodeKeyValue)) {
        this.selectedNodeObjs.push(node.obj);
      } else {
        this.selectedNodeObjs = this.selectedNodeObjs.filter(item => item[this.nodeKey] !== nodeKeyValue);
      }
    },
    getSelected() {
      return this.selectedNodeObjs;
    },
    getCheckedNodes(leafOnly) {
      return this.refTree.getCheckedNodes(leafOnly);
    },
    getHalfCheckedNodes() {
      return this.refTree.getHalfCheckedNodes();
    },
    setCheckedNodes(array) {
      this.refTree.setCheckedNodes(array);
    },
    setCheckedkeys(array) {
      this.refTree.setCheckedKeys(array);
    },
    getNode(node) {
      return this.refTree.getNode(node);
    },
    setCurrentNode(node) {
      this.refTree.setCurrentNode(node);
    },
    remove(node) {
      this.refTree.remove(node);
    },
  },
  mounted() {
    if (this.selected) {
      this.selectedArr = this.selected.split('^');
      this.$http.post(this.selectedAjax, this.selectedArr)
        .then(({ data }) => {
          this.selectedNodeObjs = data.list;
        });
      this.setCheckedkeys(this.selectedArr);
    }
  },
};
</script>
