<template>
  <div class="tree-container">
    <el-row :gutter="20">
      <el-col :lg="6" :md="24" :sm="24" :xl="6" :xs="24">
        <el-divider content-position="left">常规树</el-divider>
        <el-input v-model="filterText" placeholder="输入关键字过滤" />
        <el-tree
          ref="demoTree"
          :data="data2"
          :default-checked-keys="defaultCheckedKeys"
          :default-expanded-keys="defaultExpendedKeys"
          :expand-on-click-node="false"
          :filter-node-method="filterNode"
          :highlight-current="true"
          :props="defaultProps"
          class="vab-filter-tree"
          node-key="id"
          show-checkbox
          @check="checkNode"
          @node-click="nodeClick"
          @node-collapse="nodeCollapse"
          @node-expand="nodeExpand"
        >
          <template #defalut="{ node, data }" class="vab-custom-tree-node">
            <span class="vab-tree-item">
              <i v-if="node.data.rank == 4" class="el-icon-s-custom"></i>
              {{ node.label }}
            </span>
            <span class="vab-tree-options">
              <a
                v-if="node.data.rank !== 4"
                class="vab-tree-btn"
                title="添加"
                @click="() => append(node, data, 0)"
              >
                <i class="el-icon-plus"></i>
              </a>
              <a
                class="vab-tree-btn"
                title="编辑"
                @click="() => edit(node, data, 1)"
              >
                <i class="el-icon-edit"></i>
              </a>
              <a
                v-if="node.data.rank !== 1"
                class="vab-tree-btn"
                title="刪除"
                @click="() => remove(node, data)"
              >
                <i class="el-icon-delete"></i>
              </a>
            </span>
          </template>
        </el-tree>
      </el-col>
      <el-col :lg="6" :md="24" :sm="24" :xl="6" :xs="24">
        <el-divider content-position="left">懒加载树</el-divider>
        <el-input
          v-model.lazy="keyW"
          :value="keyW"
          class="input-with-select"
          placeholder="请输入内容"
          @keyup.enter.native="showTreeList"
        ></el-input>
        <div v-show="isShow" class="blur-tree">
          <el-tree
            ref="treeFilter"
            :data="filterDevLlist"
            :expand-on-click-node="false"
            :props="defaultProps"
            class="vab-filter-tree"
            default-expand-all
            highlight-current
            node-key="indexCode"
            @node-click="nodeClick"
          >
            <template #defalut="{ node }" class="vab-custom-tree-node">
              <span class="vab-tree-item">
                <i v-if="node.data.rank == 4" class="el-icon-s-custom"></i>
                {{ node.label }}
              </span>
              <span class="vab-tree-options">
                <a
                  v-if="node.data.rank !== 4"
                  class="vab-tree-btn"
                  title="添加"
                >
                  <i class="el-icon-plus"></i>
                </a>
                <a class="vab-tree-btn" title="编辑">
                  <i class="el-icon-edit"></i>
                </a>
                <a
                  v-if="node.data.rank !== 1"
                  class="vab-tree-btn"
                  title="刪除"
                >
                  <i class="el-icon-delete"></i>
                </a>
              </span>
            </template>
          </el-tree>
        </div>
        <div v-show="!isShow" class="el-tree-wrap">
          <el-tree
            ref="tree"
            v-loading="loading"
            :expand-on-click-node="false"
            :load="loadNode"
            :props="defaultProps"
            class="vab-filter-tree"
            highlight-current
            lazy
            node-key="indexCode"
            @node-click="nodeClick"
          >
            <template #defalut="{ node }" class="vab-custom-tree-node">
              <span class="vab-tree-item">
                <i v-if="node.data.rank == 4" class="el-icon-s-custom"></i>
                {{ node.label }}
              </span>
              <span class="vab-tree-options">
                <!-- <a v-if="node.data.rank !== 4" class="vab-tree-btn" title="添加""><i class="el-icon-plus"></i></a> -->
                <a class="vab-tree-btn" title="编辑">
                  <i class="el-icon-edit"></i>
                </a>
                <a
                  v-if="node.data.rank !== 1"
                  class="vab-tree-btn"
                  title="刪除"
                >
                  <i class="el-icon-delete"></i>
                </a>
              </span>
            </template>
          </el-tree>
        </div>
      </el-col>
      <el-col :lg="6" :md="24" :sm="24" :xl="6" :xs="24">
        <el-divider content-position="left">单选树</el-divider>
        <el-select
          ref="singleTree"
          v-model="singleSelectTreeVal"
          class="vab-tree-select"
          clearable
          popper-class="select-tree-popper"
          value-key="id"
          @clear="selectTreeClearHandle('single')"
        >
          <el-option :value="singleSelectTreeKey">
            <el-tree
              id="singleSelectTree"
              ref="singleSelectTree"
              :current-node-key="singleSelectTreeKey"
              :data="selectTreeData"
              :default-expanded-keys="selectTreeDefaultSelectedKeys"
              :highlight-current="true"
              :props="selectTreeDefaultProps"
              node-key="id"
              @node-click="selectTreeNodeClick"
            >
              <template #defalut="{ node }" class="vab-custom-tree-node">
                <span class="vab-tree-item">{{ node.label }}</span>
              </template>
            </el-tree>
          </el-option>
        </el-select>
      </el-col>
      <el-col :lg="6" :md="24" :sm="24" :xl="6" :xs="24">
        <el-divider content-position="left">多选树</el-divider>
        <el-select
          v-model="multipleSelectTreeVal"
          class="vab-tree-select"
          clearable
          collapse-tags
          multiple
          popper-class="select-tree-popper"
          @change="changeMultipleSelectTreeHandle"
          @clear="selectTreeClearHandle('multiple')"
          @remove-tag="removeSelectTreeTag"
        >
          <el-option :value="multipleSelectTreeKey">
            <el-tree
              id="multipleSelectTree"
              ref="multipleSelectTree"
              :current-node-key="multipleSelectTreeKey"
              :data="selectTreeData"
              :default-checked-keys="selectTreeDefaultSelectedKeys"
              :default-expanded-keys="selectTreeDefaultSelectedKeys"
              :highlight-current="true"
              :props="selectTreeDefaultProps"
              node-key="id"
              show-checkbox
              @check="multipleSelectTreeCheckNode"
            ></el-tree>
          </el-option>
        </el-select>
      </el-col>
    </el-row>
    <!--添加/编辑节点弹框-------------------start-->
    <el-dialog
      :title="dialogTitle"
      :visible.sync="treeDialogVisible"
      class="tree-operate-dialog"
      width="400px"
      @close="treeDialogVisible = false"
    >
      <el-form ref="treeForm" :model="treeForm">
        <el-form-item label="节点名称" required>
          <el-input v-model="treeForm.name"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="treeDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveTree">确 定</el-button>
      </div>
    </el-dialog>
    <!--添加/编辑节点弹框-------------------end-->
  </div>
</template>

<script>
  import { getTreeList } from '@/api/tree'

  export default {
    name: 'Tree',
    data() {
      return {
        dialogTitle: '添加节点',
        treeFlag: 0,
        treeDialogVisible: false,
        treeForm: {
          id: '',
          name: '',
        },
        checkNodeKeys: [],
        filterText: '',
        data2: [],
        defaultProps: {
          children: 'children',
          label: 'name',
        },
        defaultExpendedKeys: [],
        defaultCheckedKeys: [],
        loading: true,
        keyW: '',
        filterDevLlist: [],
        isShow: false,
        updateTree: true,
        /* 单选树-多选树---------开始 */
        selectLevel: 4, // 树可选叶子level等级
        singleSelectTreeVal: '', //单选树默认label值
        singleSelectTreeKey: '', //单选树默认key值
        selectTreeData: [], //单选树的值
        selectTreeDefaultSelectedKeys: [], //单选树默认展开的key值数组
        selectTreeDefaultProps: {
          children: 'children',
          label: 'name',
        },
        multipleSelectTreeVal: [], //多选树默认label值
        multipleSelectTreeKey: '', //多选树默认key值
        /* 单选树-多选树---------结束 */
      }
    },
    watch: {
      filterText(val) {
        this.$refs.demoTree.filter(val)
      },
    },
    mounted() {
      this.$nextTick(() => {
        this.getTreeListFuc(1)
        this.setCheckedKeys()
        // 初始化单选树
        this.initSingleTree('single')
        // 初始化多选树
        this.initSingleTree('multiple')
      })
    },
    methods: {
      // 树level小于n级展开方法
      openTree(treeData, n) {
        const each = (data) => {
          data.forEach((e) => {
            if (e.rank <= n) {
              this.defaultExpendedKeys.push(e.id)
            }
            if (e.children.length > 0) {
              each(e.children)
            }
          })
        }

        each(treeData)
      },
      // 获取tree数据
      async getTreeListFuc(flag) {
        const { data } = await getTreeList()
        this.data2 = data
        if (flag) {
          this.openTree(this.data2, 2)
        }
      },
      // 节点过滤操作
      filterNode(value, data) {
        if (!value) return true
        return data.name.indexOf(value) !== -1
      },
      // 添加节点操作
      append(node, data, flag) {
        this.treeFlag = flag
        this.dialogTitle = '添加节点'
        this.treeForm = {
          id: '',
          name: '',
        }
        this.treeDialogVisible = true
      },
      // 编辑节点操作
      edit(node, data, flag) {
        this.treeFlag = flag
        this.dialogTitle = '编辑节点'
        this.treeForm = {
          id: data.id,
          name: data.name,
        }
        this.treeDialogVisible = true
      },
      // 删除节点操作
      remove(node, data) {
        this.$baseConfirm('你确定要删除该节点?', null, async () => {
          const { msg } = getTreeList()
          this.$baseMessage(msg, 'success')
          this.getTreeListFuc(0)
        })
      },
      // 保存添加和编辑
      saveTree() {
        this.$refs.treeForm.validate(async (valid) => {
          if (valid) {
            const { msg } = await getTreeList()
            this.$baseMessage(msg, 'success')
            this.treeDialogVisible = false
            this.getTreeListFuc(0)
          }
        })
      },
      // 设置节点选中
      setCheckedKeys() {
        this.$refs.demoTree.setCheckedKeys([1])
      },
      // 点击叶子节点
      nodeClick(data, node, el) {},
      // 节点选中操作
      checkNode(data, node, el) {
        this.checkNodeKeys = node.checkedKeys
      },
      // 节点展开操作
      nodeExpand(data, node, el) {
        this.defaultExpendedKeys.push(data.id)
      },
      // 节点关闭操作
      nodeCollapse(data, node, el) {
        this.defaultExpendedKeys.splice(
          this.defaultExpendedKeys.findIndex((item) => item.id === data.id),
          1
        )
      },
      async loadNode(node, resolve) {
        if (node.level === 0) {
          const { data } = await getTreeList()
          this.loading = false
          return resolve(data)
        } else {
          const { data } = await getTreeList()
          return resolve(res.data)
        }
      },
      //懒加载树输入框筛选方法
      async showTreeList(value) {
        if (typeof value === 'string') {
          this.keyW = value.trim()
        }
        if (this.keyW.length !== 0) {
          // 请求后台返回查询结果
          let treeOption = {}
          treeOption = {
            keyWord: this.keyW,
          }
          const { data } = await getTreeList()
          this.filterDevLlist = data
          this.isShow = true
        } else {
          this.isShow = false
        }
      },
      /* 单选/多选树方法-------------------开始 */
      // 初始化单选树的值
      async initSingleTree(treeType) {
        const { data } = await getTreeList()
        this.selectTreeData = data
        this.$nextTick(() => {
          this.selectTreeDefaultSelectedKeys =
            this.singleSelectTreeKey.split(',') // 设置默认展开
          if (treeType == 'single') {
            //单选树
            this.$refs.singleSelectTree.setCurrentKey(this.singleSelectTreeKey) // 设置默认选中
          } else {
            // 多选树
            this.$refs.multipleSelectTree.setCheckedKeys(
              this.selectTreeDefaultSelectedKeys
            )
          }
        })
      },
      // 清除单选树选中
      selectTreeClearHandle(type) {
        this.selectTreeDefaultSelectedKeys = []
        this.clearSelected()
        if (type == 'single') {
          this.singleSelectTreeVal = ''
          this.singleSelectTreeKey = ''
          this.$refs.singleSelectTree.setCurrentKey('') // 设置默认选中
        } else {
          this.multipleSelectTreeVal = []
          this.multipleSelectTreeKey = ''
          this.$refs.multipleSelectTree.setCheckedKeys([])
        }
      },
      /* 清空选中样式 */
      clearSelected() {
        const allNode = document.querySelectorAll(
          '#singleSelectTree .el-tree-node'
        )
        allNode.forEach((element) => element.classList.remove('is-current'))
      },
      // select多选时移除某项操作
      removeSelectTreeTag(val) {
        const stack = JSON.parse(JSON.stringify(this.selectTreeData))
        while (stack.length) {
          const curr = stack.shift()
          if (curr.name == val) {
            return this.$refs.multipleSelectTree.setChecked(curr.id, false)
          }
          if (curr.children && curr.children.length) {
            stack.unshift(...curr.children)
          }
        }
      },
      changeMultipleSelectTreeHandle(val) {},
      // 点击叶子节点
      selectTreeNodeClick(data, node, el) {
        if (data.rank >= this.selectLevel) {
          this.singleSelectTreeVal = data.name
          this.singleSelectTreeKey = data.id
          this.$refs.singleTree.blur()
        }
      },
      // 节点选中操作
      multipleSelectTreeCheckNode(data, node, el) {
        const checkedNodes = this.$refs.multipleSelectTree.getCheckedNodes()
        const keyArr = []
        const valueArr = []
        checkedNodes.forEach((item) => {
          if (item.rank >= this.selectLevel) {
            keyArr.push(item.id)
            valueArr.push(item.name)
          }
        })
        this.multipleSelectTreeVal = valueArr
        this.multipleSelectTreeKey = keyArr.join(',')
      },
      /* 单选/多选树方法-------------------结束 */
    },
  }
</script>
