src/views/dnc/base/modules/ProductStructure/ProductStructureTree.vue
@@ -4,7 +4,7 @@
      <div style="display: flex;flex-direction: column;height: 100%">
        <div style="display: flex;justify-content: space-between">
          <a-input placeholder="输入关键字进行搜索" allowClear v-model="searchInput"
                   @change="handleSearchInputChange" />
                   @change="handleSearchInputChange"/>
          <!--          <a-tooltip title="刷新">-->
          <!--            <a-button icon="reload" @click="handleTreeReload" style="width: 18%;margin-left: 8px"></a-button>-->
          <!--          </a-tooltip>-->
@@ -31,16 +31,16 @@
                  @select="handleTreeSelect" @expand="handleTreeExpand" @rightClick="handleTreeRightClick">
            <template slot="title" slot-scope="{ label, parentId, key:treeKey,type}">
              <ProductStructureTreeContextMenu ref="contextMenuRef"
                                               :treeParams="{label,treeKey,searchValue,type}" />
                                               :treeParams="{label,treeKey,searchValue,type}"/>
            </template>
            <a-icon slot="switcherIcon" type="down" />
            <a-icon slot="product" type="shopping" />
            <a-icon slot="component" type="camera" />
            <a-icon slot="part" type="hdd" />
            <a-icon slot="processSpecVersion" type="tag" />
            <a-icon slot="process" type="apartment" />
            <a-icon slot="processStep" type="tool" />
            <a-icon slot="switcherIcon" type="down"/>
            <a-icon slot="product" type="shopping"/>
            <a-icon slot="component" type="camera"/>
            <a-icon slot="part" type="hdd"/>
            <a-icon slot="processSpecVersion" type="tag"/>
            <a-icon slot="process" type="apartment"/>
            <a-icon slot="processStep" type="tool"/>
          </a-tree>
        </div>
      </div>
@@ -48,421 +48,481 @@
    <!--产品弹窗-->
    <ProductModal ref="productModalFormRef" :currentTreeNodeInfo="rightClickSelected"
                  @submitSuccess="getTreeDataByApi" />
                  @submitSuccess="getTreeDataByApi"/>
    <!--部件弹窗-->
    <ComponentModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess" />
    <ComponentModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/>
    <!--零件弹窗-->
    <PartModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess" />
    <PartModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/>
    <!--工艺规程版本弹窗-->
    <ProcessSpecVersionModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess" />
    <ProcessSpecVersionModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/>
    <!--工序弹窗-->
    <ProcessModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess" />
    <ProcessModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/>
    <!--工步弹窗-->
    <ProcessStepModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess" />
    <ProcessStepModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/>
    <!--权限配置弹窗-->
    <AssignPermissionModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess" />
    <AssignPermissionModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/>
    <!--检索电子模板弹窗-->
    <NcDocumentSearchModal :currentDocumentInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess" />
    <NcDocumentSearchModal :currentDocumentInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/>
    <!--检索NC文件弹窗-->
    <NcDocumentSearchNcModal :currentDocumentInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess" />
    <NcDocumentSearchNcModal :currentDocumentInfo="rightClickSelected" @searchTreeNode="searchTreeNode"
                             @submitSuccess="modalFormSubmitSuccess"/>
    <!--引用部件-->
    <NcComponentBorrowModal :currentBorrowInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess" />
    <NcComponentBorrowModal :currentBorrowInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/>
    <!--产品结构树基本右键菜单(空白处触发)-->
    <ProductStructureBaseContextMenu ref="baseContextmenuRef" />
    <ProductStructureBaseContextMenu ref="baseContextmenuRef"/>
    <div class="full-screen-container" v-if="fullScreenSpinning">
      <a-spin :spinning="fullScreenSpinning" size="large" tip="NC文件检索中..."/>
    </div>
  </a-card>
</template>
<script>
import dncApi from '@/api/dnc'
import { deleteAction } from '@/api/manage'
import ProductStructureTreeContextMenu from './ProductStructureTreeContextMenu'
import ProductModal from './Product/ProductModal'
import ComponentModal from './Component/ComponentModal'
import PartModal from './Part/PartModal'
import ProcessSpecVersionModal from './ProcessSpecVersion/ProcessSpecVersionModal'
import ProcessModal from './Process/ProcessModal'
import ProcessStepModal from './ProcessStep/ProcessStepModal'
import AssignPermissionModal from './Permission/AssignPermissionModal'
import DeviceCustomTypeModal from '@views/dnc/base/modules/ProductStructure/DeviceCustomType/DeviceCustomTypeModal.vue'
import ProductStructureBaseContextMenu
  from '@views/dnc/base/modules/ProductStructure/ProductStructureBaseContextMenu.vue'
import NcDocumentSearchModal from '@views/dnc/base/modules/ProductStructure/Document/NcDocumentSearchModal.vue'
import NcDocumentSearchNcModal from '@views/dnc/base/modules/ProductStructure/Document/NcDocumentSearchNcModal.vue'
import NcComponentBorrowModal from '@views/dnc/base/modules/ProductStructure/Document/NcComponentBorrowModal.vue'
  import dncApi from '@/api/dnc'
  import { deleteAction } from '@/api/manage'
  import ProductStructureTreeContextMenu from './ProductStructureTreeContextMenu'
  import ProductModal from './Product/ProductModal'
  import ComponentModal from './Component/ComponentModal'
  import PartModal from './Part/PartModal'
  import ProcessSpecVersionModal from './ProcessSpecVersion/ProcessSpecVersionModal'
  import ProcessModal from './Process/ProcessModal'
  import ProcessStepModal from './ProcessStep/ProcessStepModal'
  import AssignPermissionModal from './Permission/AssignPermissionModal'
  import DeviceCustomTypeModal
    from '@views/dnc/base/modules/ProductStructure/DeviceCustomType/DeviceCustomTypeModal.vue'
  import ProductStructureBaseContextMenu
    from '@views/dnc/base/modules/ProductStructure/ProductStructureBaseContextMenu.vue'
  import NcDocumentSearchModal from '@views/dnc/base/modules/ProductStructure/Document/NcDocumentSearchModal.vue'
  import NcDocumentSearchNcModal from '@views/dnc/base/modules/ProductStructure/Document/NcDocumentSearchNcModal.vue'
  import NcComponentBorrowModal from '@views/dnc/base/modules/ProductStructure/Document/NcComponentBorrowModal.vue'
export default {
  name: 'ProductStructureTree',
  components: {
    ProductStructureBaseContextMenu,
    DeviceCustomTypeModal,
    AssignPermissionModal,
    ProcessStepModal,
    ProcessModal,
    ProcessSpecVersionModal,
    PartModal,
    ComponentModal,
    ProductModal,
    ProductStructureTreeContextMenu,
    NcDocumentSearchModal,
    NcDocumentSearchNcModal,
    NcComponentBorrowModal
  },
  data() {
    return {
      searchInput: '',
      cardLoading: false,
      loading: false,
      treeDataSource: [],
      selectedKeys: [],
      expandedKeys: [],
      beforeSearchExpandedKeys: [],
      searchValue: '',
      dataList: [],
      autoExpandParent: true,
      checkStrictly: true,
      allTreeKeys: [],
      rightClickSelected: {},
      url: {
        delete: '/nc/product/delete'
      }
    }
  },
  created() {
    this.getTreeDataByApi()
    this.$bus.$on('treeMenuItemMethodTrigger', this.triggerCorrespondingMethod)
  },
  beforeDestroy() {
    this.$bus.$off('treeMenuItemMethodTrigger', this.triggerCorrespondingMethod)
  },
  methods: {
    // 调用接口获取树的数据
    getTreeDataByApi() {
      this.loading = true
      this.cardLoading = true
      this.treeDataSource = []
      dncApi.getProductStructureTreeApi()
        .then(res => {
          if (res.success) {
            this.dataList = []
            this.allTreeKeys = []
            this.treeDataSource = res.result
            this.generateList(this.treeDataSource)
            // this.expandedKeys = this.allTreeKeys
            if (this.expandedKeys.length === 0) this.expandedKeys = this.beforeSearchExpandedKeys = [this.treeDataSource[0].id]
          } else {
            this.$message.warn(res.message)
          }
        }).finally(() => {
        this.loading = false
        this.cardLoading = false
      })
  export default {
    name: 'ProductStructureTree',
    components: {
      ProductStructureBaseContextMenu,
      DeviceCustomTypeModal,
      AssignPermissionModal,
      ProcessStepModal,
      ProcessModal,
      ProcessSpecVersionModal,
      PartModal,
      ComponentModal,
      ProductModal,
      ProductStructureTreeContextMenu,
      NcDocumentSearchModal,
      NcDocumentSearchNcModal,
      NcComponentBorrowModal
    },
    /**
     * 树节点选中时触发
     * @param selectedKeys 选中节点key
     * @param {node} node 节点对象
     */
    handleTreeSelect(selectedKeys, { node }) {
      const that = this
      let record = node.dataRef
      const { id, type } = record
      dncApi.getProductStructureTreeNodeEntityApi({ id, type })
        .then(res => {
          if (res.success) {
            let currentSelectedNodeInfo
            if (res.result.length > 0) {
              currentSelectedNodeInfo = Object.assign({}, record, { entity: res.result[0] })
            } else {
              currentSelectedNodeInfo = {}
              that.$notification.warning({
                message: '消息',
                description: '暂无该节点详细信息'
              })
            }
            // 向右侧父级组件发送当前选中树节点信息
            this.$bus.$emit('sendCurrentTreeNodeInfo', currentSelectedNodeInfo)
          } else {
            that.$notification.error({
              message: '消息',
              description: res.message
            })
          }
        })
      if (selectedKeys.length === 0) return
      this.selectedKeys = selectedKeys
    },
    /**
     * 树节点右键单击节点时触发
     * @param node 节点对象
     */
    handleTreeRightClick({ node }) {
      if (this.$refs.baseContextmenuRef) this.$refs.baseContextmenuRef.menuVisible = false
      const that = this
      const record = node.dataRef
      const { id, type } = record
      dncApi.getProductStructureTreeNodeEntityApi({ id, type })
        .then(res => {
          if (res.success) {
            if (res.result.length > 0) {
              that.rightClickSelected = Object.assign({}, record, { entity: res.result[0] })
            } else {
              that.rightClickSelected = {}
              that.$notification.warning({
                message: '消息',
                description: '暂无该节点详细信息'
              })
            }
          } else {
            that.$notification.error({
              message: '消息',
              description: res.message
            })
          }
        })
    },
    // 树节点右键单击菜单中删除按钮时触发
    handleDelete() {
      const that = this
      const { rightClickSelected: { id, type }, $confirm, url, $notification } = that
      $confirm({
        title: '提示',
        content: '确认删除此条记录吗?',
        okText: '确认',
        okType: 'danger',
        cancelText: '取消',
        onOk: () => {
          if (!url.delete) {
            this.$message.error('请设置url.delete属性!')
            return
          }
          deleteAction(url.delete + `/${id}/${type}`)
            .then((res) => {
              if (res.success) {
                that.getTreeDataByApi()
                $notification.success({
                  message: '消息',
                  description: res.message
                })
              } else {
                $notification.warning({
                  message: '消息',
                  description: res.message
                })
              }
            })
            .finally(() => {
              that.$destroyAll()
            })
        },
        onCancel: () => {
          that.$destroyAll()
    data() {
      return {
        searchInput: '',
        cardLoading: false,
        loading: false,
        treeDataSource: [],
        selectedKeys: [],
        expandedKeys: [],
        beforeSearchExpandedKeys: [],
        searchValue: '',
        dataList: [],
        autoExpandParent: true,
        checkStrictly: true,
        allTreeKeys: [],
        rightClickSelected: {},
        fullScreenSpinning: false,
        url: {
          delete: '/nc/product/delete'
        }
      })
      }
    },
    /**
     * 自动展开添加下级节点的父节点
     * @param isAddNextLevel 是否需要展开下级
     */
    modalFormSubmitSuccess(isAddNextLevel) {
      // 判断是否为添加下级并且判断父节点是否展开
      if (isAddNextLevel && !this.expandedKeys.includes(this.rightClickSelected.id)) this.expandedKeys.push(this.rightClickSelected.id)
    created() {
      this.getTreeDataByApi()
      this.$bus.$on('treeMenuItemMethodTrigger', this.triggerCorrespondingMethod)
      this.$bus.$on('searchNcFinished', () => this.fullScreenSpinning = false)
    },
    /**
     * 树节点展开合并时触发
     * @param expandedKeys 展开项key
     */
    handleTreeExpand(expandedKeys) {
      this.expandedKeys = this.beforeSearchExpandedKeys = expandedKeys
      this.autoExpandParent = false
    beforeDestroy() {
      this.$bus.$off('treeMenuItemMethodTrigger', this.triggerCorrespondingMethod)
    },
    methods: {
      // 调用接口获取树的数据
      getTreeDataByApi() {
        this.loading = true
        this.cardLoading = true
        this.treeDataSource = []
        dncApi.getProductStructureTreeApi()
          .then(res => {
            if (res.success) {
              this.dataList = []
              this.allTreeKeys = []
              this.treeDataSource = res.result
              this.generateList(this.treeDataSource)
              // this.expandedKeys = this.allTreeKeys
              if (this.expandedKeys.length === 0) this.expandedKeys = this.beforeSearchExpandedKeys = [this.treeDataSource[0].id]
            } else {
              this.$message.warn(res.message)
            }
          }).finally(() => {
          this.loading = false
          this.cardLoading = false
        })
      },
    // 输入查询内容变化时触发(增加防抖机制)
    handleSearchInputChange() {
      const that = this
      let timer
      if (timer) clearTimeout(timer)
      timer = setTimeout(function() {
        that.searchAndExpandTreeNode() // 加小括号调用函数
      }, 1000)
    },
    // 防抖函数中触发搜索并展开树节点
    searchAndExpandTreeNode() {
      let search = this.searchInput
      let expandedKeys
      let autoExpandParent
      if (search !== '') {
        expandedKeys = this.dataList
          .map(item => {
            if (item.title != null) {
              if (item.title.indexOf(search) > -1) {
                return this.getParentKey(item.key, this.treeDataSource)
      /**
       * 树节点选中时触发
       * @param selectedKeys 选中节点key
       * @param eventOrRecord  节点对象或者手动传入record
       */
      handleTreeSelect(selectedKeys, eventOrRecord) {
        const that = this
        let record = eventOrRecord.node ? eventOrRecord.node.dataRef : eventOrRecord
        const { id, type } = record
        dncApi.getProductStructureTreeNodeEntityApi({ id, type })
          .then(res => {
            if (res.success) {
              let currentSelectedNodeInfo
              if (res.result.length > 0) {
                currentSelectedNodeInfo = Object.assign({}, record, { entity: res.result[0] })
              } else {
                currentSelectedNodeInfo = {}
                that.$notification.warning({
                  message: '消息',
                  description: '暂无该节点详细信息'
                })
              }
              return null
              // 向右侧父级组件发送当前选中树节点信息
              this.$bus.$emit('sendCurrentTreeNodeInfo', currentSelectedNodeInfo)
            } else {
              that.$notification.error({
                message: '消息',
                description: res.message
              })
            }
          })
          .filter((item, i, self) => item && self.indexOf(item) === i)
        autoExpandParent = true
      } else {
        expandedKeys = this.beforeSearchExpandedKeys
        autoExpandParent = false
      }
      Object.assign(this, {
        expandedKeys,
        searchValue: search,
        autoExpandParent
      })
    },
        if (selectedKeys.length === 0) return
        this.selectedKeys = selectedKeys
      },
    /**
     * 递归获得输入项的父级key
     * @param key 子项key
     * @param tree 子项
     */
    getParentKey(key, tree) {
      let parentKey
      for (let i = 0; i < tree.length; i++) {
        const node = tree[i]
        if (node.children) {
          if (node.children.some(item => item.key === key)) {
            parentKey = node.key
          } else if (
            this.getParentKey(key, node.children)) {
            parentKey = this.getParentKey(key, node.children)
      /**
       * 树节点右键单击节点时触发
       * @param node 节点对象
       */
      handleTreeRightClick({ node }) {
        if (this.$refs.baseContextmenuRef) this.$refs.baseContextmenuRef.menuVisible = false
        const that = this
        const record = node.dataRef
        const { id, type } = record
        dncApi.getProductStructureTreeNodeEntityApi({ id, type })
          .then(res => {
            if (res.success) {
              if (res.result.length > 0) {
                that.rightClickSelected = Object.assign({}, record, { entity: res.result[0] })
              } else {
                that.rightClickSelected = {}
                that.$notification.warning({
                  message: '消息',
                  description: '暂无该节点详细信息'
                })
              }
            } else {
              that.$notification.error({
                message: '消息',
                description: res.message
              })
            }
          })
      },
      // 树节点右键单击菜单中删除按钮时触发
      handleDelete() {
        const that = this
        const { rightClickSelected: { id, type }, $confirm, url, $notification } = that
        $confirm({
          title: '提示',
          content: '确认删除此条记录吗?',
          okText: '确认',
          okType: 'danger',
          cancelText: '取消',
          onOk: () => {
            if (!url.delete) {
              this.$message.error('请设置url.delete属性!')
              return
            }
            deleteAction(url.delete + `/${id}/${type}`)
              .then((res) => {
                if (res.success) {
                  that.getTreeDataByApi()
                  $notification.success({
                    message: '消息',
                    description: res.message
                  })
                } else {
                  $notification.warning({
                    message: '消息',
                    description: res.message
                  })
                }
              })
              .finally(() => {
                that.$destroyAll()
              })
          },
          onCancel: () => {
            that.$destroyAll()
          }
        })
      },
      /**
       * 自动展开添加下级节点的父节点
       * @param isAddNextLevel 是否需要展开下级
       */
      modalFormSubmitSuccess(isAddNextLevel) {
        // 判断是否为添加下级并且判断父节点是否展开
        if (isAddNextLevel && !this.expandedKeys.includes(this.rightClickSelected.id)) this.expandedKeys.push(this.rightClickSelected.id)
        this.getTreeDataByApi()
      },
      /**
       * 树节点展开合并时触发
       * @param expandedKeys 展开项key
       */
      handleTreeExpand(expandedKeys) {
        this.expandedKeys = this.beforeSearchExpandedKeys = expandedKeys
        this.autoExpandParent = false
      },
      /**
       * 检索NC文件弹窗中双击行记录后触发搜索NC文件对应树节点并模拟选中树节点查询对应设备类或NC文件
       * @param searchNcRecord 检索NC文件弹窗中双击获得的NC文件列表行记录
       */
      searchTreeNode(searchNcRecord) {
        this.fullScreenSpinning = true
        const { attributionId, nodeCode, nodeName, nodeId, docId } = searchNcRecord
        this.searchInput = `[${nodeCode}]${nodeName}`
        this.searchAndExpandTreeNode()
        const treeNodeRecord = Object.assign({
          autoClickedLevelInfo: {
            attributionId,
            docId
          }
        }, this.getTreeNodeRecord(nodeId, this.treeDataSource))
        this.handleTreeSelect([treeNodeRecord.id], treeNodeRecord)
      },
      // 输入查询内容变化时触发(增加防抖机制)
      handleSearchInputChange() {
        const that = this
        let timer
        if (timer) clearTimeout(timer)
        timer = setTimeout(function() {
          that.searchAndExpandTreeNode() // 加小括号调用函数
        }, 1000)
      },
      // 防抖函数中触发搜索并展开树节点
      searchAndExpandTreeNode() {
        let search = this.searchInput
        let expandedKeys
        let autoExpandParent
        if (search !== '') {
          expandedKeys = this.dataList
            .map(item => {
              if (item.title != null) {
                if (item.title.indexOf(search) > -1) {
                  return this.getParentKey(item.key, this.treeDataSource)
                }
                return null
              }
            })
            .filter((item, i, self) => item && self.indexOf(item) === i)
          autoExpandParent = true
        } else {
          expandedKeys = this.beforeSearchExpandedKeys
          autoExpandParent = false
        }
        Object.assign(this, {
          expandedKeys,
          searchValue: search,
          autoExpandParent
        })
      },
      /**
       * 递归获得输入项的父级key
       * @param key 子项key
       * @param tree 子项
       */
      getParentKey(key, tree) {
        let parentKey
        for (let i = 0; i < tree.length; i++) {
          const node = tree[i]
          if (node.children) {
            if (node.children.some(item => item.key === key)) {
              parentKey = node.key
            } else if (
              this.getParentKey(key, node.children)) {
              parentKey = this.getParentKey(key, node.children)
            }
          }
        }
        return parentKey
      },
      /**
       * 递归获得输入项的record对象
       * @param key record对象key值
       * @param tree 树节点
       */
      getTreeNodeRecord(key, tree) {
        let treeNodeRecord
        for (let i = 0; i < tree.length; i++) {
          const node = tree[i]
          if (node.children) {
            if (node.children.findIndex(item => item.key === key) > -1) {
              treeNodeRecord = node.children.find(item => item.key === key)
            } else if (this.getTreeNodeRecord(key, node.children)) {
              treeNodeRecord = this.getTreeNodeRecord(key, node.children)
            }
          }
        }
        return treeNodeRecord
      },
      /**
       * 递归获得所有树节点key
       * @param data
       */
      generateList(data) {
        for (let i = 0; i < data.length; i++) {
          data[i].key = data[i].id
          const node = data[i]
          const key = node.id
          const title = node.label
          this.dataList.push({ key, title })
          this.allTreeKeys.push(key)
          this.setTreeNodeIcon(node)
          if (node.children) this.generateList(node.children)
        }
      },
      /**
       * 树所在父元素的右键事件
       * @param event 事件对象
       */
      openBaseContextMenu(event) {
        event.preventDefault()
        if (event.target.id !== 'tree-container') return
        this.$refs.baseContextmenuRef.menuStyle.top = event.clientY + 'px'
        this.$refs.baseContextmenuRef.menuStyle.left = event.clientX + 'px'
        this.$refs.baseContextmenuRef.menuVisible = true
        document.body.addEventListener('click', this.handleBaseContextMenuClose)
      },
      /**
       * 设置树节点图标
       * @param treeNode
       */
      setTreeNodeIcon(treeNode) {
        switch (+treeNode.type) {
          case 1:
            treeNode.slots = { icon: 'product' }
            break
          case 2:
            treeNode.slots = { icon: 'component' }
            break
          case 3:
            treeNode.slots = { icon: 'part' }
            break
          case 4:
            treeNode.slots = { icon: 'processSpecVersion' }
            break
          case 5:
            treeNode.slots = { icon: 'process' }
            break
          case 6:
            treeNode.slots = { icon: 'processStep' }
            break
          default:
        }
      },
      // 控制基础右键菜单关闭
      handleBaseContextMenuClose() {
        if (this.$refs.baseContextmenuRef) this.$refs.baseContextmenuRef.menuVisible = false
        document.body.removeEventListener('click', this.handleBaseContextMenuClose)
      },
      // 刷新重新获取树的数据
      handleTreeReload() {
        this.getTreeDataByApi()
      },
      triggerCorrespondingMethod({ methodName }) {
        if (this[methodName]) this[methodName]()
      }
      return parentKey
    },
    /**
     * 递归获得所有树节点key
     * @param data
     */
    generateList(data) {
      for (let i = 0; i < data.length; i++) {
        data[i].key = data[i].id
        const node = data[i]
        const key = node.id
        const title = node.label
        this.dataList.push({ key, title })
        this.allTreeKeys.push(key)
        this.setTreeNodeIcon(node)
        if (node.children) this.generateList(node.children)
      }
    },
    /**
     * 树所在父元素的右键事件
     * @param event 事件对象
     */
    openBaseContextMenu(event) {
      event.preventDefault()
      if (event.target.id !== 'tree-container') return
      this.$refs.baseContextmenuRef.menuStyle.top = event.clientY + 'px'
      this.$refs.baseContextmenuRef.menuStyle.left = event.clientX + 'px'
      this.$refs.baseContextmenuRef.menuVisible = true
      document.body.addEventListener('click', this.handleBaseContextMenuClose)
    },
    /**
     * 设置树节点图标
     * @param treeNode
     */
    setTreeNodeIcon(treeNode) {
      switch (+treeNode.type) {
        case 1:
          treeNode.slots = { icon: 'product' }
          break
        case 2:
          treeNode.slots = { icon: 'component' }
          break
        case 3:
          treeNode.slots = { icon: 'part' }
          break
        case 4:
          treeNode.slots = { icon: 'processSpecVersion' }
          break
        case 5:
          treeNode.slots = { icon: 'process' }
          break
        case 6:
          treeNode.slots = { icon: 'processStep' }
          break
        default:
      }
    },
    // 控制基础右键菜单关闭
    handleBaseContextMenuClose() {
      if(this.$refs.baseContextmenuRef)this.$refs.baseContextmenuRef.menuVisible = false
      document.body.removeEventListener('click', this.handleBaseContextMenuClose)
    },
    // 刷新重新获取树的数据
    handleTreeReload() {
      this.getTreeDataByApi()
    },
    triggerCorrespondingMethod({ methodName }) {
      if (this[methodName]) this[methodName]()
    }
  }
}
</script>
<style lang="less" scoped>
/deep/ .ant-card-body {
  padding: 0 12px 0 0;
}
/deep/ .ant-card-body, /deep/ .ant-spin-nested-loading, /deep/ .ant-spin-container {
  height: 100%;
}
/deep/ .ant-tree-title, .ant-tree-title .ant-dropdown-trigger {
  display: inline-block;
  width: calc(100% - 24px) !important;
}
::-webkit-scrollbar {
  width: 8px;
}
@media screen and (min-width: 1920px) {
  .tree_con {
    height: 748px !important;
  /deep/ .ant-card-body {
    padding: 0 12px 0 0;
  }
}
@media screen and (min-width: 1680px) and (max-width: 1920px) {
  .tree_con {
    height: 748px !important;
  /deep/ .ant-card-body, /deep/ .ant-spin-nested-loading, /deep/ .ant-spin-container {
    height: 100%;
  }
}
@media screen and (min-width: 1400px) and (max-width: 1680px) {
  .tree_con {
    height: 600px !important;
  /deep/ .ant-tree-title, .ant-tree-title .ant-dropdown-trigger {
    display: inline-block;
    width: calc(100% - 24px) !important;
  }
}
@media screen and (min-width: 1280px) and (max-width: 1400px) {
  .tree_con {
    height: 501px !important;
  ::-webkit-scrollbar {
    width: 8px;
  }
}
@media screen and (max-width: 1280px) {
  .tree_con {
    height: 501px !important;
  .full-screen-container {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, .8);
    z-index: 9999;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }
}
  @media screen and (min-width: 1920px) {
    .tree_con {
      height: 748px !important;
    }
  }
  @media screen and (min-width: 1680px) and (max-width: 1920px) {
    .tree_con {
      height: 748px !important;
    }
  }
  @media screen and (min-width: 1400px) and (max-width: 1680px) {
    .tree_con {
      height: 600px !important;
    }
  }
  @media screen and (min-width: 1280px) and (max-width: 1400px) {
    .tree_con {
      height: 501px !important;
    }
  }
  @media screen and (max-width: 1280px) {
    .tree_con {
      height: 501px !important;
    }
  }
</style>