/**
* @Description: 库房查询树
* @author wangzhao
* @date 2022/12/02
*/
<template>
  <div class="dee-as-tree-com">
    <div class="root">
      <div class="root-title sub-title sub-title-fix">仓储组织</div>
      <div class="root-add" src="/icons/add-L.png" title="新增库房" @click.stop="addKF" />
    </div>
    <div class="search-area">
      <el-input
        v-model="inputVal"
        placeholder="输入关键字筛选,快速定位"
        clearable
        size="small"
        class="search-input"
      />
      <dee-tools :tools="tools" mode="dual" />
    </div>
    <div class="tree-box">
      <el-tree
        id="houseTree"
        ref="houseTree"
        :key="treeId"
        class="tree"
        node-key="id"
        :data="treeData"
        :props="props"
        :check-strictly="true"
        :expand-on-click-node="true"
        :default-expand-all="false"
        :highlight-current="true"
        :default-expanded-keys="defaultExpandedKeys"
        @node-expand="highLightTreeNode"
      >
        <div
          slot-scope="{ node, data }"
          :class="['house-tree-node', node.data.endless?'endless':null]"
          @click="clickNode(node.data)"
        >
          <div>
            <img class="node-prefix-icon" :src="data.subTypeName === 'DxStOrgHouse' ? '/icons/dee-storage/icons/stg-kf.png' : '/icons/dee-storage/icons/stg-kq.png'">
            <span class="change-text">
              {{ data.name }}
            </span>
          </div>
          <span class="node-handle">
            <img v-if="data.subTypeName === 'DxStOrgHouse'" class="node-handle-icon" src="/icons/add-L.png" title="新增库区" @click.stop="addStorageOrg(data, node)">
            <img class="node-handle-icon" src="/icons/edit-L.png" :title="'编辑' + data.subTypeDisplayName" @click.stop="editCurrentNode(data, node)">
          </span>
        </div>
      </el-tree>
    </div>
    <dee-drawer
      width="766px"
      :title="dialogTitle"
      :dialog-visible="showDialog"
      @handleClose="closeDialog"
    >
      <dee-as-com
        v-if="showDialog"
        parent-show-mode="dialog"
        :lay-config="layConfig"
        :basic-data="clickItem"
        v-bind="formConfig"
        @close="closeDialog"
        @on-cancel="closeDialog"
        @completeEven="completeEven"
      />
    </dee-drawer>
  </div>
</template>

<script>
import _get from 'lodash.get'

export default {
  componentName: '库房查询树',
  name: 'HouseTree',
  props: {
    rootId: {
      type: [String, Number],
      default: () => ''
    },
    defaultLevel: {
      type: Number,
      default: 2 // 懒加载,默认展开层级
    },
    canOperate: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      formConfig: {},
      defaultExpandedKeys: [],
      evenList: [
        {
          even: 'showTop',
          name: '刷新仓储查看列表'
        }
      ],
      inputVal: '',
      index: 0,
      stateOption: [],
      defaultExpandAll: false,
      treeId: 1,
      // 选择工具条
      filterTool: {
        keyword: '',
        currentIndex: -1,
        nodes: []
      },
      treeData: [],
      defaultNode: {},
      props: {
        children: 'children',
        label: 'label',
        isLeaf: 'isLeaf'
      },
      dialogTitle: '新建库房',
      showDialog: false,
      typeName: '',
      layKey: '',
      layConfig: null,
      curentNodeData: null,
      clickItem: null
    }
  },
  computed: {
    Props() {
      return {
        children: 'children',
        label: 'name',
        isLeaf: 'isLeaf'
      }
    },
    tools() {
      return [
        {
          name: '下一个',
          icon: '/icons/c-next.png',
          handler: {
            click: () => {
              this.findNext()
            }
          }
        },
        {
          name: '上一个',
          icon: '/icons/c-last.png',
          handler: {
            click: () => {
              this.findPrev()
            }
          }
        },
        {
          name: '全部展开',
          icon: '/icons/b-expansion.png',
          handler: {
            click: () => {
              this.expandAllFun(true)
            }
          }
        },
        {
          name: '全部收起',
          icon: '/icons/b-allpackup.png',
          handler: {
            click: () => {
              this.expandAllFun(false)
            }
          }
        },
        {
          name: '刷新',
          icon: '/icons/b-fresh.png',
          handler: {
            click: () => {
            }
          }
        }
      ]
    }
  },
  watch: {
    inputVal: {
      handler: function(keyword) {
        this.filterTool.currentIndex = -1
        this.highLightTreeNode()
      }
    }
  },
  mounted() {
    this.getTreeData(() => {
      this.clickNode(this.treeData[0])
      this.$refs.houseTree.setCurrentKey(this.treeData[0].id)
    })
    this.$bus.$on('DxStOrgHouse-submit', (data) => {
      this.treeData.push(data.items)
      this.$refs.houseTree.$forceUpdate()
    })
  },
  beforeDestroy() {
    this.$bus.$off('DxStOrgHouse-submit')
  },
  methods: {
    getTreeData(cb) {
      const params = {
        'openProps': [
          { 'name': 'dxStOrgUnitResClassLinks', 'openProps': [{ 'name': 'target' }] }
        ],
        'searchItems': {
          'children': [
            {
              'items': [
                {
                  'fieldName': 'subTypeName',
                  'operator': 'EQ',
                  'value': 'DxStOrgArea'
                },
                {
                  'fieldName': 'subTypeName',
                  'operator': 'EQ',
                  'value': 'DxStOrgHouse'
                }
              ],
              'operator': 'OR'
            },
            {
              'items': [
                {
                  'fieldName': 'enabledState',
                  'operator': 'EQ',
                  'value': true
                },
                {
                  'fieldName': 'enabledState',
                  'operator': 'EQ',
                  'value': false
                }
              ],
              'operator': 'OR'
            }
          ],
          'operator': 'AND'
        },
        sortItem: [{ fieldName: 'name', sortOrder: 'asc' }]
      }
      this.$api.searchApi('DxStOrganization', params)
        .then(res => {
          this.treeData = this.$utils.generateTree(this.$utils._clonedeep(_get(res, 'items.content', [])), { id: 'id', pid: 'parentId' })
          if (typeof cb === 'function') {
            this.$nextTick(cb)
          }
        })
    },
    // 查询下一个
    findNext() {
      if (!this.inputVal) {
        return
      }
      this.findAll().then(() => {
        if (this.filterTool.nodes.length < 1) {
          return
        }
        if (++this.filterTool.currentIndex >= this.filterTool.nodes.length) {
          this.filterTool.currentIndex = 0
        }
        this.expandToMatchNode()
      })
    },
    // 查询上一个
    findPrev() {
      if (!this.inputVal) {
        return
      }
      this.findAll().then(() => {
        if (this.filterTool.nodes.length < 1) {
          return
        }
        if (--this.filterTool.currentIndex < 0) {
          this.filterTool.currentIndex = this.filterTool.nodes.length - 1
        }
        this.expandToMatchNode()
      })
    },
    // 查找所有满足条件的节点
    findAll() {
      return new Promise((resolve) => {
        this.findMatchNodes()
        resolve()
      })
    },
    expandAllFun(bool) {
      var nodes = this.$refs.houseTree.store._getAllNodes()
      this.expandAll = bool
      this.setNodeExpanded(nodes, bool)
      this.highLightTreeNode()
    },
    findMatchNodes() {
      let nodeMap = this.$refs.houseTree.store.nodesMap
      nodeMap = Object.values(nodeMap)
      this.filterTool.nodes = nodeMap.filter(node => node.data.name && node.data.name.toUpperCase().includes(this.inputVal.toUpperCase()))
    },
    expandToMatchNode() {
      const node = this.filterTool.nodes[this.filterTool.currentIndex]
      let currentNode = node.parent
      while (currentNode) {
        currentNode.expanded = true
        currentNode = currentNode.parent
      }
      this.$refs.houseTree.setCurrentKey(node.key)
      this.highLightTreeNode()
      this.$nextTick(() => {
        const treeEl = document.getElementById('houseTree')
        const el = this.$refs.houseTree.$el.getElementsByClassName('is-current')[0]
        let parentNode = el.parentNode
        let offsetParent = el.offsetParent
        let offsetTop = el.offsetTop || 0
        while (parentNode !== treeEl) {
          if (offsetParent !== parentNode.offsetParent) {
            offsetTop += parentNode.offsetTop || 0
          } else {
            offsetParent = parentNode.offsetParent
          }
          parentNode = parentNode.parentNode
        }
        treeEl.scrollTop = offsetTop - treeEl.clientHeight * 0.5 + 10
      })
    },
    setNodeExpanded(nodes, bool) {
      nodes.forEach(Node => {
        if (bool) {
          Node.expand()
        } else {
          Node.collapse()
        }
      })
    },
    highLightTreeNode() {
      this.$nextTick(() => {
        const treeNode = this.$refs.houseTree.$el
        const spans = treeNode.getElementsByClassName('change-text')
        if (spans.length > 0) {
          for (let i = 0; i < spans.length; i++) {
            var labelText = spans[i].textContent
            const reg = this.inputVal
              .replace(/\(/g, '\\(')
              .replace(/\)/g, '\\)')
              .replace(/\./g, '\\.')
            const allVal = labelText.match(new RegExp(reg, 'ig'))
            if (allVal) {
              const newAllVal = [...new Set(allVal)]
              for (let j = 0; j < newAllVal.length; j++) {
                if (newAllVal[j]) {
                  const tp = newAllVal[j]
                    .replace(/\(/g, '\\(')
                    .replace(/\)/g, '\\)')
                    .replace(/\./g, '\\.')
                  labelText = labelText.replace(
                    new RegExp(tp, 'g'),
                    '*' + newAllVal[j] + '*'
                  )
                }
              }
              for (let k = 0; k < allVal.length; k++) {
                if (allVal[k]) {
                  labelText = labelText.replace(
                    '*' + allVal[k] + '*',
                    '<span class="highlight-text">' + allVal[k] + '</span>'
                  )
                }
              }
            }
            spans[i].innerHTML = labelText
          }
        }
      })
    },
    // 节点点击事件
    clickNode(data) {
      this.curentNodeData = data
      this.$emit('showTop', data)
    },
    completeEven() {
      // 重新加载树
      this.closeDialog()
      this.treeData = []
      this.getTreeData(() => {
        // 获取指定id节点
        const nodeKey = _get(this, 'curentNodeData.id', '')
        if (nodeKey) {
          const node = this.$refs.houseTree.getNode(nodeKey)
          if (node) {
            this.$bus.$emit('DetailCom-update', node.data)
          }
        }
      })
    },
    closeDialog() {
      this.showDialog = false
    },
    findState(data) {
      let state = ''
      this.stateOption.forEach(item => {
        if (item.value === data) {
          state = item.label
        }
      })
      return state
    },
    // 关闭新增弹窗
    cancel() {
      this.$emit('close')
    },
    // 添加仓储组织节点
    addStorageOrg(item) {
      this.index++
      this.addArea(item)
      this.showDialog = true
    },
    // 添加库区
    addArea(item) {
      this.clickItem = item
      this.formConfig = {
        form: {
          parentId: item.id,
          subTypeName: 'DxStOrgArea'
        }
      }
      this.layConfig = {
        typeName: 'DxStOrgArea',
        layKey: 'defaultCreate'
      }
      this.dialogTitle = '新增库区'
    },
    // 编辑当前节点(库房/库区)
    editCurrentNode(item, node) {
      this.index++
      // 将父node数据 传到basicData中 用于控制库区物料范围
      this.clickItem = JSON.parse(JSON.stringify(item))
      this.clickItem.parent = node.parent.data
      this.formConfig = {
        form: {
          parentId: item.parentId,
          subTypeName: item.subTypeName
        }
      }
      this.dialogTitle = '编辑' + item.subTypeDisplayName
      this.layConfig = {
        typeName: item.subTypeName,
        layKey: 'defaultEdit'
      }
      this.showDialog = true
    },
    // 添加库房
    addKF() {
      this.index++
      this.clickItem = {}
      this.formConfig = {
        form: {
          subTypeName: 'DxStOrgHouse'
        }
      }
      this.dialogTitle = '新增库房'
      this.layConfig = {
        typeName: 'DxStOrgHouse',
        layKey: 'defaultCreate'
      }
      this.showDialog = true
    }
  }
}
</script>

<style lang="scss" >
.dee-as-tree-com{
    height: 100%;
    background-color: #fff;
    overflow: hidden !important;
    .root{
      display: flex;
      justify-content: space-between;
      padding-top: 12px;
      padding-bottom: 6px;
      padding-left:8px;
      .sub-title-fix{
        align-self: center;
        padding-top: 0px;
        padding-bottom: 0px;
      }
    }
  .search-area {
    //border-bottom: 1px solid #DDDDDD;
    display: flex;
    align-items: center;
    justify-content:flex-start;
    padding: 6px 0px;
    .search-input{
      width: calc(100% - 150px);
      flex:1;
      margin-right:10px;
    }
  }

  .tree {
    height: calc(100% - 83px);
    overflow-y: scroll;
    padding-bottom: 10px;
    /deep/ .el-tree-node__content {
      height: 30px;
    }
  }
  .el-tree-node__content:hover .house-tree-node .node-handle{
    visibility: visible;
  }
  .house-tree-node {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    color: #212121;
    font-size: 14px;
    padding-right: 8px;
    &.endless{
      .change-text{
        color: #F56C6C
      }
    }
    .node-prefix-icon {
      vertical-align: middle;
    }
    .node-handle {
      visibility: hidden;
      .node-handle-icon {
        height: 14px;
        margin-left: 10px;
      }
    }
  }
  .tree-btn-box{
        width: 66px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        height: 100%;
        display: none;
        .btn-item img{
            padding: 4px;
            width: 16px;
            height: 16px;
        }
    }
  .highlight-text{
    background-color: #FFFF00;
  }
  .house-tree-node{
    &> div >.change-text > .highlight-text{
      background-color: #FF9632;
    }
  }
  .changeText {
    font-size: 14px
  }
  .root {
    display: flex;
    justify-content: space-between;
    padding-left: 8px;
    .root-title {
      font-size: 16px;
    }
    .root-add {
      display: inline-block;
      width: 14px;
      height: 14px;
      margin: auto 0px;
      background-size: cover;
      background-position: center;
      background-image: url('/icons/add-L.png');
    }
  }
  .tree-box{
    height: 100%;
    margin: 4px 0;
    overflow-y: auto;
  }
  .custom-tree-node{
      width: 100%;
      display: flex;
      justify-content: space-between;
      div{
        width: 100px;
        display: flex;
        justify-content: flex-end;
      }
      div >span{
        width:14px;
        height:14px;
        margin: 0 4px;
        background-size: cover;
        background-position: center;
      }
    }
   .load-more {
      line-height: 50px;
      height: 50px;
      text-align: center;
      span {
        margin: auto;
        color: #2f90e2;
        height: 26px;
        line-height: 26px;
        padding: 0 20px;
        font-size: 12px;
        background: #e7f2ff;
        border-radius: 13px;
        display: inline-block;
        cursor: pointer;
      }
    }
}
</style>