
<template>
  <div class="el-tree-node">
    <div class="filter-input">
      <el-input placeholder="输入关键字进行过滤"
                v-model.trim="filterText"
                clearable>
      </el-input>
    </div>
    <el-tree v-if="lazy === true"
             ref="tree"
             lazy
             node-key="id"
             v-loading="loading"
             :default-expanded-keys="defaultExpandKeys"
             :expand-on-click-node="defaultExpandOnClickNode"
             :render-content="renderContent"
             :show-checkbox="showCheckbox"
             :default-checked-keys="defaultCheckedKeys"
             :default-expand-all="defaultExpandAll"
             :current-node-key="currentNodeKey"
             :filter-node-method="filterNode"
             :check-on-click-node="checkOnClickNode"
             highlight-current
             :props="props"
             :load="loadNode"
             @node-click="handleNodeClick"
             @node-expand="handleNodeExpand"></el-tree>
    <el-tree v-else
             node-key="id"
             ref="tree"
             :data="nodeData"
             v-loading="loading"
             :default-expand-all="defaultExpandAll"
             :default-expanded-keys="defaultExpandKeys"
             :filter-node-method="filterNode"
             :expand-on-click-node="defaultExpandOnClickNode"
             :render-content="renderContent"
             :show-checkbox="showCheckbox"
             :current-node-key="currentNodeKey"
             :check-on-click-node="checkOnClickNode"
             highlight-current
             :props="props"
             @node-click="handleNodeClick"
             @check="handleCheckBox"
             @current-change="handleCurrentChange"></el-tree>
  </div>
</template>

<script>
export default {
  data () {
    return {
      nodeData: [],
      currentNodeKey: this.defaultNodeKey,
      checkedKeys: this.defaultCheckedKeys,
      firstData: null,
      props: {
        children: 'children',
        label: 'label',
        isLeaf: 'leaf'
      },
      filterText: '',
      defaultExpandKeys: ['0'],

      loading: false, //  加载中
      selNode: '',//  后台数据选中的节点
      expandKeys: []
    }
  },
  watch: {
    filterText (val) {
      this.$refs.tree.filter(val)
    }
  },
  props: {
    url: {
      type: String,
      required: true
    },
    params: {
      type: Object,
      default () {
        return {}
      }
    },
    //  默认全展开
    defaultExpandAll: {
      type: Boolean,
      default: true
    },
    lazy: {
      type: Boolean,
      default: false
    },
    autoLoad: {
      type: Boolean,
      default: true
    },
    showCheckbox: {
      type: Boolean,
      default: false
    },
    defaultOnlyLeaf: {
      //  点击所有节点都能选中，为true时表示：只能选择叶节点
      type: Boolean,
      default: false
    },
    defaultExpandOnClickNode: {
      //  默认点击节点时展开节点
      type: Boolean,
      default: false
    },
    defaultCheckedKeys: {
      //   默认勾选节点
      type: Array,
      default () {
        return []
      }
    },

    defaultNodeKey: {
      //   默认选中节点(节点id)
      type: [Number, String]
    },

    isDialogTree: {
      //  是否是从选择树弹出框打开的树
      type: Boolean,
      default: false
    },
    //  能够选择的节点类型，默认为空
    nodeType: {
      type: String,
      default: ''
    },
    //  是否在点击节点的时候选中节点，默认值为 false，即只有在点击复选框时才会选中节点
    checkOnClickNode: {
      type: Boolean,
      default: true
    },
    tenantCode: {
      type: String,
      default: ''
    }
  },

  methods: {
    setExpandKeys (expandKeys) {

      this.expandKeys = expandKeys
    },
    filterNode (value, data) {
      if (!value) return true
      return data.label.indexOf(value) !== -1
    },
    loadData (callback, currentKey, checkedKeys, expandKeys) {

      this.expandKeys = expandKeys
      var headers = {}
      if (this.tenantCode !== '') {
        headers = {
          tenantCode: this.tenantCode
        }
      }
      this.selNode = ''
      this.currentNodeKey = currentKey
      this.checkedKeys = checkedKeys

      this.resetFilterText()
      window.app.ajax.post(
        this.url,
        this.params,
        (data, rspMsg) => {
          let arrayData = data
          if (!Array.isArray(data)) {
            arrayData = []
            arrayData.push(data)
          }
          //  alert(JSON.stringify(data))
          this.nodeData = data
          //  console.log(this.nodeData)
          this.processData(this.nodeData, null)
          this.initCheckNodes()
          this.loading = false
        },
        (rspMsg, data) => {
          this.$message.error(rspMsg)
          this.loading = false
        }, headers
      )
      if (typeof callback === 'function') callback()
    },
    loadDataByUrl (url, callback, currentKey) {
      this.selNode = ''
      this.currentNodeKey = currentKey

      this.loading = true
      this.resetFilterText()
      window.app.ajax.get(
        url,
        this.params,
        (data, rspMsg) => {
          this.nodeData = data
          console.log(this.nodeData)
          this.firstData = null
          this.processData(this.nodeData, null)
          this.initCheckNodes()
          this.loading = false
        },
        (rspMsg, data) => {
          this.$message.error(rspMsg)
          this.loading = false
        }
      )
      if (typeof callback === 'function') callback()
    },
    processData (data, parentData) {
      //  处理节点数据
      data.forEach(_data => {
        _data.parent = parentData

        if (_data.selectNode === '1') {
          this.selNode = _data.id
        }
        if (_data.children && _data.children.length > 0) {
          this.processData(_data.children, _data)
        } else {
          _data.isLeaf = true //  叶子节点

          if (!this.firstData) { //  保存第一层节点数据
            this.firstData = _data
          }
        }
      })
    },
    initCheckNodes () {
      // 默认展开的节点

      if (this.expandKeys.length > 0) {
        this.expandKeys.forEach((oneKey, index) => { // 组织数据
          this.defaultExpandKeys.push(oneKey + '')
        })
      }
      //  设置节点状态
      if (this.showCheckbox) { // 多选节点
        //  if (this.defaultCheckedKeys.length > 0) {
        //  设置勾选节点
        if (this.checkedKeys === undefined) {
          this.$nextTick(() => {
            this.$refs['tree'].setCheckedKeys(this.defaultCheckedKeys)
          })
        } else {
          this.$nextTick(() => {
            this.$refs['tree'].setCheckedKeys(this.checkedKeys)
          })
        }

        // }
      } else { // 单选节点
        //  如果没有设置默认勾选和展开节点，设置第一层级的第一个叶子节点为勾选状态
        if (this.currentNodeKey === undefined || this.currentNodeKey === null) {
          if (this.selNode !== '') {
            this.currentNodeKey = this.selNode
          } else {
            this.currentNodeKey = this.firstData.id
          }

          //  if (this.showCheckbox) {
          //    this.defaultCheckedKeys.push(this.currentNodeKey)
          //  }

          //  要在数据更新视图之后，设置高亮, 设置勾选
          this.$nextTick(() => {
            this.setCurrentKey(this.currentNodeKey)
            //  if (this.showCheckbox)
            //    this.$refs['tree'].setCheckedKeys(this.defaultCheckedKeys)
          })
        } else {
          this.$nextTick(() => {
            this.setCurrentKey(this.currentNodeKey)
          })
        }
      }
      //  if (this.defaultCheckedKeys.length > 0) { // 多选节点
      //    //  设置勾选节点
      //    this.$nextTick(() => {
      //      this.$refs['tree'].setCheckedKeys(this.defaultCheckedKeys)
      //    })
      //  } else { // 单选节点

      //  }
      this.$emit('dataFinish')
    },
    setCurrentKey (key) {
      this.$refs['tree'].setCurrentKey(key)
      if (!this.isDialogTree) {
        //  获取当前被选中节点的 data,主动触发点击事件
        this.handleNodeClick(this.$refs['tree'].getCurrentNode(), '', '')
      }
    },
    renderContent (h, { node, data, store }) {
      //  渲染tree
      return h(
        'span',
        {
          class: 'custom-tree-node'
        },
        [
          data.icon
            ? h('svg-icon', {
              class: 'blue', // 图标颜色
              props: {
                iconClass: data.icon
              }
            })
            : '',
          h('span', {
            class: 'mLeft'// 节点名称span新增左边距属性
          }, node.label)
        ]
      )
    },
    addDefaultExpandedKeys (data) {
      if (data.parent && data.parent.length > 0) {
        this.addDefaultExpandedKeys(data.parent)
      } else {
        this.defaultExpandKeys.push(data)
      }
    },
    handleNodeClick (data, node, store) {
      let checkedArr = this.$refs['tree'].getCheckedNodes()
      if (this.defaultOnlyLeaf) { // 只能选择叶子节点
        if (data.children && data.children.length > 0) { // 如果没有子节点
        } else {
          this.$emit('nodeClick', data, node)
        }
      } else {
        this.$emit('nodeClick', data, node, checkedArr)
      }
    },
    handleCheckBox (data, status) {
      let checkedArr = this.$refs['tree'].getCheckedNodes()
      this.$emit('chechBoxClick', data, checkedArr)
    },
    handleCurrentChange (data, node, store) {
      // console.logconsole.log(data, node)
    },
    handleNodeExpand (data, node, store) {
      // console.log(data, node, store)
    },
    loadNode (node, resolve) {
      if (node.level === 0) {
        this.loadData(() => {
          resolve(this.nodeData[0])
          this.$refs['tree'].setCurrentKey(this.nodeData[0].id)
        })
      } else {
        resolve([])
      }
    },
    // 获取多选节点的id数组（全部）
    getCheckedKeysAll () {
      return this.$refs['tree'].getCheckedKeys()
    },
    // 获取多选节点的id字符串（只有叶子节点）
    getCheckedKeys () {
      var checkedNodes = this.getCheckedNodes()
      var p = /[a-z]/i
      var selIds = ''
      if (this.nodeType === '') { // 没有指定的节点类型
        checkedNodes.forEach(element => {
          var id = element.id
          // if (p.test(element.id)) { // 判断第一位是否是字母，是的话截掉
          if (p.test(element.id.substring(0, 1))) { // 判断第一位是否是字母，是的话截掉
            id = element.id.substring(1)
          }
          selIds = selIds + id + ','
        })
      } else { // 指定了节点类型
        checkedNodes.forEach(element => {
          if (element.role === this.nodeType) {
            var id = element.id
            selIds = selIds + id + ','
          }
        })
      }
      if (selIds !== '') {
        selIds = selIds.substring(0, selIds.length - 1)
      }
      return selIds
    },
    setCheckedKeys (key) {
      this.$refs['tree'].setCheckedKeys(key)
      //  获取当前被选中节点的 data,主动触发点击事件
      // this.handleNodeClick(this.$refs['tree'].getCurrentNode())
    },
    // 获取多选节点的对象数组（全部）
    getCheckedNodesAll () {
      return this.$refs['tree'].getCheckedNodes()
    },
    // 获取多选节点的对象数组（只有叶子节点）
    getCheckedNodes () {
      var checkedNodesAll = this.$refs['tree'].getCheckedNodes()// 所有选中的节点，包括父节点
      var checkedNodes = []
      // 剔除父节点
      checkedNodesAll.forEach(oneNodes => {
        if (oneNodes.children && oneNodes.children.length > 0) {
        } else {
          checkedNodes.push(oneNodes)
        }
      })
      // console.log(checkedNodes)
      return checkedNodes
    },
    // 重置查询条件
    resetFilterText () {
      this.filterText = ''
    }
  },
  mounted () {
    if (!this.lazy) {
      if (this.autoLoad) {
        this.loading = true
        this.loadData(null, this.currentNodeKey, this.checkedKeys, this.expandKeys)
      }

    }
  }
}
</script>

<style>
.mLeft {
  margin-left: 6px;
}
.blue {
  color: #003585;
}
</style>
<style scoped>
.el-tree-node {
  outline: 0;
  font-size: 14px;
  word-wrap: break-word !important;
  line-height: 14px !important;
}

.el-tree-node:focus > .el-tree-node__content {
  background-color: #f5f7fa;
}

.el-tree-node.is-drop-inner > .el-tree-node__content .el-tree-node__label {
  background-color: #00d1b2;
  color: #fff;
}

.el-tree-node__content {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  height: 26px;
  cursor: pointer;
}

.el-tree-node__content > .el-tree-node__expand-icon {
  padding: 6px;
}

.el-tree-node__content > .el-checkbox {
  margin-right: 8px;
}

.el-tree-node__content:hover {
  background-color: #f5f7fa;
}

.el-tree.is-dragging .el-tree-node__content {
  cursor: move;
}

.el-tree.is-dragging.is-drop-not-allow .el-tree-node__content {
  cursor: not-allowed;
}

.el-tree-node__expand-icon {
  cursor: pointer;
  color: #c0c4cc;
  font-size: 12px;
  -webkit-transform: rotate(0);
  transform: rotate(0);
  -webkit-transition: -webkit-transform 0.3s ease-in-out;
  transition: -webkit-transform 0.3s ease-in-out;
  transition: transform 0.3s ease-in-out;
  transition: transform 0.3s ease-in-out, -webkit-transform 0.3s ease-in-out;
}

.el-tree-node__expand-icon.expanded {
  -webkit-transform: rotate(90deg);
  transform: rotate(90deg);
}

.el-tree-node__expand-icon.is-leaf {
  color: transparent;
  cursor: default;
}

.el-tree-node__label {
  font-size: 14px;
}

.el-tree-node__loading-icon {
  margin-right: 8px;
  font-size: 14px;
  color: #c0c4cc;
}

.el-tree-node > .el-tree-node__children {
  overflow: hidden;
  background-color: transparent;
}

.el-tree-node.is-expanded > .el-tree-node__children {
  display: block;
}

.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
  background-color: #f0f7ff;
}

.filter-input {
  margin-bottom: 10px;
}
</style>
