lyh
2025-05-09 79dda6eb5451d16a148bd5c51f61567e8847b136
src/views/dnc/base/modules/ProductStructure/ProductStructureTree.vue
@@ -1,44 +1,46 @@
<template>
  <a-card class="tree_con" :loading="cardLoading" :bordered="false" @contextmenu.native="e=>e.preventDefault()">
  <a-card class="tree_con" :loading="cardLoading" :bordered="false" @contextmenu.native.stop="openBaseContextMenu">
    <a-spin :spinning="loading">
      <div style="display: flex;flex-direction: column;height: 100%">
        <div style="display: flex">
        <div style="display: flex;justify-content: space-between">
          <a-input placeholder="输入关键字进行搜索" allowClear v-model="searchInput"
                   @change="handleSearchInputChange"/>
          <a-dropdown :trigger="['click']" placement="bottomCenter" style="margin: 0 8px">
            <a-menu slot="overlay">
              <a-menu-item key="1" @click="expandedKeys = allTreeKeys">展开所有</a-menu-item>
              <a-menu-item key="2" @click="expandedKeys = ['-1']">合并所有</a-menu-item>
              <a-menu-item key="3" @click="getTreeDataByApi">刷新</a-menu-item>
            </a-menu>
            <a-button>
              <a-icon type="bars"/>
            </a-button>
          </a-dropdown>
          <a-button type="primary" v-has="'product_add'"
                    @click="$refs.productModalFormRef.triggerCorrespondingMethod({modalTitle:'添加产品',methodName:'handleProductAdd'})">
            <a-icon type="plus"></a-icon>
            产品
          </a-button>
                   @change="handleSearchInputChange" />
          <!--          <a-tooltip title="刷新">-->
          <!--            <a-button icon="reload" @click="handleTreeReload" style="width: 18%;margin-left: 8px"></a-button>-->
          <!--          </a-tooltip>-->
          <!--          <a-button type="primary" v-has="'product_add'" icon="plus" style="margin-left: 8px"-->
          <!--                    @click="$refs.productModalFormRef.triggerCorrespondingMethod({modalTitle:'添加产品',methodName:'handleProductAdd'})">-->
          <!--            产品-->
          <!--          </a-button>-->
          <!--          <a-dropdown :trigger="['click']" placement="bottomCenter" style="margin: 0 8px">-->
          <!--            <a-menu slot="overlay">-->
          <!--              <a-menu-item key="1" @click="expandedKeys = allTreeKeys">展开所有</a-menu-item>-->
          <!--              <a-menu-item key="2" @click="expandedKeys = ['-1']">合并所有</a-menu-item>-->
          <!--              <a-menu-item key="3" @click="getTreeDataByApi">刷新</a-menu-item>-->
          <!--            </a-menu>-->
          <!--            <a-button>-->
          <!--              <a-icon type="bars"/>-->
          <!--            </a-button>-->
          <!--          </a-dropdown>-->
        </div>
        <!--产品结构树-->
        <div style="flex: 1;overflow:auto;margin-top: 10px">
        <div id="tree-container" style="flex: 1;overflow:auto;margin-top: 10px">
          <a-tree blockNode show-icon :expandedKeys.sync="expandedKeys"
                  :selectedKeys="selectedKeys" :treeData="treeDataSource" :autoExpandParent="autoExpandParent"
                  @select="handleTreeSelect" @expand="handleTreeExpand" @rightClick="handleTreeRightClick">
            <template slot="title" slot-scope="{ label, parentId, entity, key:treeKey,type}">
            <template slot="title" slot-scope="{ label, parentId, key:treeKey,type}">
              <ProductStructureTreeContextMenu ref="contextMenuRef"
                                               :treeParams="{label,treeKey,searchValue,type,entity}"/>
                                               :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>
@@ -46,19 +48,25 @@
    <!--产品弹窗-->
    <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" />
    <!--引用部件-->
    <NcComponentBorrowModal :currentBorrowInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess" />
    <!--产品结构树基本右键菜单(空白处触发)-->
    <ProductStructureBaseContextMenu ref="baseContextmenuRef" />
  </a-card>
</template>
@@ -73,10 +81,17 @@
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 NcComponentBorrowModal from '@views/dnc/base/modules/ProductStructure/Document/NcComponentBorrowModal.vue'
export default {
  name: 'ProductStructureTree',
  components: {
    ProductStructureBaseContextMenu,
    DeviceCustomTypeModal,
    AssignPermissionModal,
    ProcessStepModal,
    ProcessModal,
@@ -84,7 +99,9 @@
    PartModal,
    ComponentModal,
    ProductModal,
    ProductStructureTreeContextMenu
    ProductStructureTreeContextMenu,
    NcDocumentSearchModal,
    NcComponentBorrowModal
  },
  data() {
    return {
@@ -100,7 +117,6 @@
      autoExpandParent: true,
      checkStrictly: true,
      allTreeKeys: [],
      currentSelected: {},
      rightClickSelected: {},
      url: {
        delete: '/nc/product/delete'
@@ -111,14 +127,18 @@
    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) {
            console.log('res=================', res)
            this.dataList = []
            this.allTreeKeys = []
            this.treeDataSource = res.result
@@ -140,22 +160,63 @@
     * @param {node} node 节点对象
     */
    handleTreeSelect(selectedKeys, { node }) {
      const that = this
      let record = node.dataRef
      this.currentSelected = Object.assign({}, record)
      // 向右侧父级组件发送当前选中树节点信息
      this.$bus.$emit('sendCurrentTreeNodeInfo', this.currentSelected)
      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 event 事件对象
     * @param node 节点对象
     */
    handleTreeRightClick({ event, node }) {
    handleTreeRightClick({ node }) {
      if (this.$refs.baseContextmenuRef) this.$refs.baseContextmenuRef.menuVisible = false
      const that = this
      const record = node.dataRef
      this.rightClickSelected = Object.assign({}, record)
      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
            })
          }
        })
    },
    // 树节点右键单击菜单中删除按钮时触发
@@ -200,6 +261,7 @@
    /**
     * 自动展开添加下级节点的父节点
     * @param isAddNextLevel 是否需要展开下级
     */
    modalFormSubmitSuccess(isAddNextLevel) {
      // 判断是否为添加下级并且判断父节点是否展开
@@ -216,8 +278,18 @@
      this.autoExpandParent = 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
@@ -237,7 +309,6 @@
        expandedKeys = this.beforeSearchExpandedKeys
        autoExpandParent = false
      }
      Object.assign(this, {
        expandedKeys,
        searchValue: search,
@@ -283,8 +354,17 @@
      }
    },
    triggerCorrespondingMethod({ methodName }) {
      if (this[methodName]) this[methodName]()
    /**
     * 树所在父元素的右键事件
     * @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)
    },
    /**
@@ -292,7 +372,7 @@
     * @param treeNode
     */
    setTreeNodeIcon(treeNode) {
      switch (treeNode.type) {
      switch (+treeNode.type) {
        case 1:
          treeNode.slots = { icon: 'product' }
          break
@@ -313,7 +393,23 @@
          break
        default:
      }
    },
    // 控制基础右键菜单关闭
    handleBaseContextMenuClose() {
      this.$refs.baseContextmenuRef.menuVisible = false
      document.body.removeEventListener('click', this.handleBaseContextMenuClose)
    },
    // 刷新重新获取树的数据
    handleTreeReload() {
      this.getTreeDataByApi()
    },
    triggerCorrespondingMethod({ methodName }) {
      if (this[methodName]) this[methodName]()
    }
  }
}
</script>