<template>
  <div class="menu-tree">
    <div class="operation">
      <el-button
        size="mini"
        type="primary"
        @click="addMenu()"
      >添加一级菜单</el-button>

      <el-button size="mini" @click="restTree()">刷新菜单</el-button>

      <el-button
        size="mini"
        @click="expandFirstNodeTree()"
      >展开一级</el-button>
      <el-button size="mini" @click="expandTree(true)">全部展开</el-button>
      <el-button size="mini" @click="expandTree(false)">全部收起</el-button>
    </div>
    <el-alert
      class="operation"
      type="info"
      :description="alertDescription"
      show-icon
      :closable="false"
    />
    <el-input
      v-model="filterText"
      class="operation"
      size="small"
      placeholder="输入关键字进行过滤"
    />
    <el-tree
      ref="tree"
      v-loading="treeLoading"
      :data="menus"
      :expand-on-click-node="false"
      node-key="id"
      :render-content="handlerRenderContent"
      highlight-current
      :filter-node-method="filterNode"
      @node-click="handleNodeClick"
    />

  </div>
</template>
<script>
import { allMenus, delMenu } from '@/api/ops-system'
import { deepClone } from '@/utils'
export default {

  name: 'MenuTree',
  data() {
    return {
      treeLoading: false,
      menus: [],
      menusList: [],
      filterText: '',
      alertDescription: '当前选中节点：',
      firstNodeDesc: '根节点',
      formData: {
        id: '',
        menuName: '',
        alias: '',
        menuType: '',
        status: '',
        icon: ''
      }
    }
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val)
    }
  },
  created() {
    this.appendTost(this.firstNodeDesc)
    this.renderTreeData()
  },
  methods: {
    renderTreeData() {
      const that = this
      that.treeLoading = true
      allMenus().then(res => {
        that.treeLoading = false
        that.menusList = res.body || []
        that.menus = that.menuToTree(res.body)
        that.$emit('loadSuccess', that.menus)
      }).catch(er => {
        that.treeLoading = false
      })
    },
    menuToTree(list) {
      if (!list || list.length === 0) {
        return
      }

      const resultMenus = []
      const childrenMenus = []
      list.forEach(item => {
        if (!item.parentId) {
          resultMenus.push(item)
        } else {
          childrenMenus.push(item)
        }
      })

      resultMenus.forEach(item => {
        findChildren(item)
      })

      function findChildren(item) {
        childrenMenus.forEach(childrenItem => {
          if (item.id === childrenItem.parentId) {
            if (item.children) {
              item.children.push(childrenItem)
            } else {
              item.children = [childrenItem]
            }
            findChildren(childrenItem)
          }
        })
      }
      return resultMenus
    },
    filterNode(value, data) {
      if (!value) return true
      return data.menuName.indexOf(value) !== -1
    },
    handlerRenderContent(h, { node, data, store }) {
      let tag = ''
      if (data.status === 1) {
        tag = <el-tag size='mini' type='warning' effect='plain'>禁用</el-tag>
      }
      return (
        <span class='custom-tree-node'>
          <span>{data.menuName}&nbsp; {tag}</span>
          <span>
            <el-button
              size='mini'
              type='text'
              on-click={($event) => this.updateTree($event, data)}
            >
              修改
            </el-button>
            <el-button
              size='mini'
              type='text'
              on-click={($event) => this.appendTree($event, data)}
            >
              添加
            </el-button>
            <el-button
              size='mini'
              type='text'
              on-click={($event) => this.removeTree($event, node, data)}
            >
              删除
            </el-button>
          </span>
        </span>
      )
    },
    handleNodeClick(data, node, compt) {
      this.appendTost(data.menuName)
    },
    appendTost(text) {
      this.alertDescription = `当前选中节点：${text}`
    },
    handlerExpanded(list, isExpand) {
      const that = this
      const size = list ? list.length : 0
      for (let index = 0; index < size; index++) {
        const id = list[index].id
        if (id) {
          const nodesMap = that.$refs.tree.store.nodesMap[id]
          if (nodesMap) {
            nodesMap.expanded = isExpand
          }
        }
      }
    },
    expandTree(isExpand) {
      this.handlerExpanded(this.menusList, isExpand)
    },
    expandFirstNodeTree() {
      this.expandTree(false)
      this.handlerExpanded(this.menus, true)
    },
    appendTree(event, data) {
      event.preventDefault()
      event.stopPropagation()
      this.$emit('addNode', deepClone(data))
    },
    updateTree(event, data) {
      // event.preventDefault()
      // event.stopPropagation()
      this.$emit('updateNode', deepClone(data))
    },
    removeTree(event, node, data) {
      // event.preventDefault()
      // event.stopPropagation()
      this.$emit('removeNode', deepClone(data))
      const that = this
      that.$confirm('此操作将永删除, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        delMenu(data.id).then(res => {
          that.$refs.tree.remove(data.id)
        })
      }).catch(() => {
        that.$message({
          type: 'info',
          message: '已取消删除'
        })
      })
    },
    restTree() {
      this.renderTreeData()
      this.$emit('restTree')
    },
    updateNodeData(key, data) {
      var node = this.$refs.tree.getNode(key)
      if (node != null) {
        for (const k in node.data) {
          this.$set(node.data, k, data[k])
        }
      }
    },
    addMenu() {
      this.appendTost(this.firstNodeDesc)
      this.$emit('addRootNode')
    }
  }
}
</script>
<style scoped lang="scss">
.menu-tree {
  height: 90vh;
  overflow: auto;
  .operation {
    margin: 0px 0px 10px 0px;
  }
}

</style>
