From 86f0166e2a759e6ec2c34b0dd0b388bafa80cedd Mon Sep 17 00:00:00 2001
From: zhaowei <zhaowei>
Date: 星期二, 15 七月 2025 19:41:12 +0800
Subject: [PATCH] 数据报表页面数据列设置固定宽度

---
 src/views/dnc/base/modules/ProductStructure/ProductStructureTree.vue |  317 ++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 252 insertions(+), 65 deletions(-)

diff --git a/src/views/dnc/base/modules/ProductStructure/ProductStructureTree.vue b/src/views/dnc/base/modules/ProductStructure/ProductStructureTree.vue
index c19f1d8..7ca8dcb 100644
--- a/src/views/dnc/base/modules/ProductStructure/ProductStructureTree.vue
+++ b/src/views/dnc/base/modules/ProductStructure/ProductStructureTree.vue
@@ -1,41 +1,44 @@
 <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>
+          <!--          <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-tree>
@@ -50,12 +53,27 @@
     <ComponentModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/>
     <!--闆朵欢寮圭獥-->
     <PartModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/>
+    <!--宸ヨ壓瑙勭▼鐗堟湰寮圭獥-->
+    <ProcessSpecVersionModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/>
     <!--宸ュ簭寮圭獥-->
     <ProcessModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/>
     <!--宸ユ寮圭獥-->
     <ProcessStepModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/>
     <!--鏉冮檺閰嶇疆寮圭獥-->
     <AssignPermissionModal :currentTreeNodeInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/>
+    <!--妫�绱㈢數瀛愭ā鏉垮脊绐�-->
+    <NcDocumentSearchModal :currentDocumentInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/>
+    <!--妫�绱C鏂囦欢寮圭獥-->
+    <NcDocumentSearchNcModal :currentDocumentInfo="rightClickSelected" @searchTreeNode="searchTreeNode"
+                             @submitSuccess="modalFormSubmitSuccess"/>
+    <!--寮曠敤閮ㄤ欢-->
+    <NcComponentBorrowModal :currentBorrowInfo="rightClickSelected" @submitSuccess="modalFormSubmitSuccess"/>
+    <!--浜у搧缁撴瀯鏍戝熀鏈彸閿彍鍗�(绌虹櫧澶勮Е鍙�)-->
+    <ProductStructureBaseContextMenu ref="baseContextmenuRef"/>
+
+    <div class="full-screen-container" v-if="fullScreenSpinning">
+      <a-spin :spinning="fullScreenSpinning" size="large" tip="NC鏂囦欢妫�绱腑..."/>
+    </div>
   </a-card>
 </template>
 
@@ -66,20 +84,34 @@
   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
+      ProductStructureTreeContextMenu,
+      NcDocumentSearchModal,
+      NcDocumentSearchNcModal,
+      NcComponentBorrowModal
     },
     data() {
       return {
@@ -89,13 +121,14 @@
         treeDataSource: [],
         selectedKeys: [],
         expandedKeys: [],
+        beforeSearchExpandedKeys: [],
         searchValue: '',
         dataList: [],
         autoExpandParent: true,
         checkStrictly: true,
         allTreeKeys: [],
-        currentSelected: {},
         rightClickSelected: {},
+        fullScreenSpinning: false,
         url: {
           delete: '/nc/product/delete'
         }
@@ -104,23 +137,30 @@
     created() {
       this.getTreeDataByApi()
       this.$bus.$on('treeMenuItemMethodTrigger', this.triggerCorrespondingMethod)
+      this.$bus.$on('searchNcFinished', () => this.fullScreenSpinning = false)
+    },
+    beforeDestroy() {
+      this.$bus.$off('treeMenuItemMethodTrigger', this.triggerCorrespondingMethod)
     },
     methods: {
+      // 璋冪敤鎺ュ彛鑾峰彇鏍戠殑鏁版嵁
       getTreeDataByApi() {
         this.loading = true
         this.cardLoading = true
-        dncApi.getProductStructureTreeApi().then(res => {
-          if (res.success) {
-            this.dataList = []
-            this.allTreeKeys = []
-            this.treeDataSource = res.list
-            this.generateList(this.treeDataSource)
-            // this.expandedKeys = this.allTreeKeys
-            if (this.expandedKeys.length === 0) this.expandedKeys = [this.treeDataSource[0].id]
-          } else {
-            this.$message.warn(res.message)
-          }
-        }).finally(() => {
+        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
         })
@@ -129,62 +169,111 @@
       /**
        * 鏍戣妭鐐归�変腑鏃惰Е鍙�
        * @param selectedKeys 閫変腑鑺傜偣key
-       * @param {node} node 鑺傜偣瀵硅薄
+       * @param eventOrRecord  鑺傜偣瀵硅薄鎴栬�呮墜鍔ㄤ紶鍏ecord
        */
-      handleTreeSelect(selectedKeys, { node }) {
-        let record = node.dataRef
-        this.currentSelected = Object.assign({}, 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: '鏆傛棤璇ヨ妭鐐硅缁嗕俊鎭�'
+                })
+              }
+              // 鍚戝彸渚х埗绾х粍浠跺彂閫佸綋鍓嶉�変腑鏍戣妭鐐逛俊鎭�
+              this.$bus.$emit('sendCurrentTreeNodeInfo', currentSelectedNodeInfo)
+            } else {
+              that.$notification.error({
+                message: '娑堟伅',
+                description: res.message
+              })
+            }
+          })
+        if (selectedKeys.length === 0) return
         this.selectedKeys = selectedKeys
-        // 鍚戝彸渚х埗绾х粍浠跺彂閫佸綋鍓嶉�変腑鏍戣妭鐐逛俊鎭�
-        this.$bus.$emit('sendCurrentTreeNodeInfo', this.currentSelected)
       },
 
       /**
        * 鏍戣妭鐐瑰彸閿崟鍑昏妭鐐规椂瑙﹀彂
-       * @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
+              })
+            }
+          })
       },
 
       // 鏍戣妭鐐瑰彸閿崟鍑昏彍鍗曚腑鍒犻櫎鎸夐挳鏃惰Е鍙�
       handleDelete() {
-        this.$confirm({
+        const that = this
+        const { rightClickSelected: { id, type }, $confirm, url, $notification } = that
+        $confirm({
           title: '鎻愮ず',
           content: '纭鍒犻櫎姝ゆ潯璁板綍鍚楋紵',
           okText: '纭',
           okType: 'danger',
           cancelText: '鍙栨秷',
           onOk: () => {
-            console.log('this.rightClickSelected.id', this.rightClickSelected.id)
-            if (!this.url.delete) {
+            if (!url.delete) {
               this.$message.error('璇疯缃畊rl.delete灞炴��!')
               return
             }
-            const that = this
-            deleteAction(that.url.delete, { id: this.rightClickSelected.id })
+            deleteAction(url.delete + `/${id}/${type}`)
               .then((res) => {
                 if (res.success) {
                   that.getTreeDataByApi()
-                  that.$notification.success({
+                  $notification.success({
                     message: '娑堟伅',
                     description: res.message
                   })
                 } else {
-                  that.$notification.warning({
+                  $notification.warning({
                     message: '娑堟伅',
                     description: res.message
                   })
                 }
               })
+              .finally(() => {
+                that.$destroyAll()
+              })
+          },
+          onCancel: () => {
+            that.$destroyAll()
           }
         })
       },
 
       /**
        * 鑷姩灞曞紑娣诲姞涓嬬骇鑺傜偣鐨勭埗鑺傜偣
+       * @param isAddNextLevel 鏄惁闇�瑕佸睍寮�涓嬬骇
        */
       modalFormSubmitSuccess(isAddNextLevel) {
         // 鍒ゆ柇鏄惁涓烘坊鍔犱笅绾у苟涓斿垽鏂埗鑺傜偣鏄惁灞曞紑
@@ -197,27 +286,63 @@
        * @param expandedKeys 灞曞紑椤筴ey
        */
       handleTreeExpand(expandedKeys) {
-        this.expandedKeys = expandedKeys
+        this.expandedKeys = this.beforeSearchExpandedKeys = expandedKeys
         this.autoExpandParent = false
       },
 
-      /* 杈撳叆鏌ヨ鍐呭鍙樺寲鏃惰Е鍙� */
+      /**
+       * 妫�绱C鏂囦欢寮圭獥涓弻鍑昏璁板綍鍚庤Е鍙戞悳绱C鏂囦欢瀵瑰簲鏍戣妭鐐瑰苟妯℃嫙閫変腑鏍戣妭鐐规煡璇㈠搴旇澶囩被鎴朜C鏂囦欢
+       * @param searchNcRecord 妫�绱C鏂囦欢寮圭獥涓弻鍑昏幏寰楃殑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 = this.dataList
-          .map(item => {
-            if (item.title != null) {
-              if (item.title.indexOf(search) > -1) {
-                return this.getParentKey(item.key, this.treeDataSource)
+        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
               }
-              return null
-            }
-          })
-          .filter((item, i, self) => item && self.indexOf(item) === i)
+            })
+            .filter((item, i, self) => item && self.indexOf(item) === i)
+          autoExpandParent = true
+        } else {
+          expandedKeys = this.beforeSearchExpandedKeys
+          autoExpandParent = false
+        }
         Object.assign(this, {
           expandedKeys,
           searchValue: search,
-          autoExpandParent: true
+          autoExpandParent
         })
       },
 
@@ -243,6 +368,26 @@
       },
 
       /**
+       * 閫掑綊鑾峰緱杈撳叆椤圭殑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
        */
@@ -259,8 +404,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)
       },
 
       /**
@@ -268,7 +422,7 @@
        * @param treeNode
        */
       setTreeNodeIcon(treeNode) {
-        switch (treeNode.type) {
+        switch (+treeNode.type) {
           case 1:
             treeNode.slots = { icon: 'product' }
             break
@@ -278,6 +432,9 @@
           case 3:
             treeNode.slots = { icon: 'part' }
             break
+          case 4:
+            treeNode.slots = { icon: 'processSpecVersion' }
+            break
           case 5:
             treeNode.slots = { icon: 'process' }
             break
@@ -286,7 +443,23 @@
             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>
@@ -309,6 +482,20 @@
     width: 8px;
   }
 
+  .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;

--
Gitblit v1.9.3