From c56b9a47d4642582020edd51bf664ed7b1935022 Mon Sep 17 00:00:00 2001
From: zhaowei <zhaowei>
Date: 星期六, 08 二月 2025 10:39:55 +0800
Subject: [PATCH] 产品结构树: 1、调整权限配置功能 2、调整指派到设备树组件子节点选中逻辑

---
 src/views/dnc/base/modules/ProductStructure/Document/NcDocumentAssignModal.vue      |   12 +
 src/views/dnc/base/modules/ProductStructure/Permission/UserPermissionTransfer.vue   |   13 +-
 src/views/dnc/base/modules/ProductStructure/ProductStructureTree.vue                |    6 -
 src/views/dnc/base/modules/ProductStructure/Permission/DepartPermissionTransfer.vue |  174 +++++++++++++++++++++++++++++++++-
 src/views/dnc/base/modules/ProductStructure/Permission/AssignPermissionModal.vue    |   40 ++++++-
 5 files changed, 215 insertions(+), 30 deletions(-)

diff --git a/src/views/dnc/base/modules/ProductStructure/Document/NcDocumentAssignModal.vue b/src/views/dnc/base/modules/ProductStructure/Document/NcDocumentAssignModal.vue
index 2679fb1..492ec83 100644
--- a/src/views/dnc/base/modules/ProductStructure/Document/NcDocumentAssignModal.vue
+++ b/src/views/dnc/base/modules/ProductStructure/Document/NcDocumentAssignModal.vue
@@ -52,9 +52,9 @@
 
                 <!--浜у搧缁撴瀯鏍�-->
                 <div style="overflow:auto;margin-top: 10px;height: 400px">
-                  <a-tree ref="tree" checkable :checkedKeys="checkedKeys" :expandedKeys.sync="expandedKeys"
-                          :autoExpandParent="autoExpandParent"
-                          :treeData="treeDataSource" @check="handleTreeNodeCheck" @expand="handleTreeExpand">
+                  <a-tree blockNode checkable :checkedKeys="checkedKeys" :expandedKeys.sync="expandedKeys"
+                          :autoExpandParent="autoExpandParent" @select="handleTreeNodeSelect"
+                          :treeData="treeDataSource" @check="handleTreeNodeCheck" @expand="handleTreeNodeExpand">
                     <template slot="title" slot-scope="{ label, parentId, entity, key:treeKey,type}">
                      <span v-if="label.indexOf(searchValue) > -1">{{ label.substr(0, label.indexOf(searchValue)) }}<span
                        class="replaceSearch">{{ searchValue }}</span>{{ label.substr(label.indexOf(searchValue) + searchValue.length) }}</span>
@@ -287,7 +287,7 @@
        * 鏍戣妭鐐瑰睍寮�鍚堝苟鏃惰Е鍙�
        * @param expandedKeys 灞曞紑椤筴ey
        */
-      handleTreeExpand(expandedKeys) {
+      handleTreeNodeExpand(expandedKeys) {
         this.expandedKeys = expandedKeys
         this.autoExpandParent = false
       },
@@ -302,6 +302,10 @@
         this.checkedKeys = checkedKeys
       },
 
+      handleTreeNodeSelect(selectedKeys, { node }) {
+        node.$el.childNodes[1].click()
+      },
+
       /**
        * 閫掑綊鑾峰緱杈撳叆椤圭殑鐖剁骇key
        * @param key 瀛愰」key
diff --git a/src/views/dnc/base/modules/ProductStructure/Permission/AssignPermissionModal.vue b/src/views/dnc/base/modules/ProductStructure/Permission/AssignPermissionModal.vue
index d9851a5..0de6856 100644
--- a/src/views/dnc/base/modules/ProductStructure/Permission/AssignPermissionModal.vue
+++ b/src/views/dnc/base/modules/ProductStructure/Permission/AssignPermissionModal.vue
@@ -5,7 +5,7 @@
       <a-form-item label="鍚嶇О">
         <a-input readOnly :value="currentTreeNodeInfo.label"></a-input>
       </a-form-item>
-      <a-form-item label="鏄惁鍒嗛厤瀛愯妭鐐�">
+      <a-form-item label="鏄惁鍚屾椂閰嶇疆瀛愯妭鐐�">
         <a-switch v-model="isAssignSonNode"></a-switch>
       </a-form-item>
     </a-form-model>
@@ -13,7 +13,8 @@
     <a-tabs v-model="activeTabKey">
       <a-tab-pane :key="1" tab="鍒嗛厤閮ㄩ棬">
         <DepartPermissionTransfer ref="departPermissionTransferRef" :currentTreeNodeInfo="currentTreeNodeInfo"
-                                      :dataSource="allDepartmentsList" :isAssignSonNode="isAssignSonNode"/>
+                                  :treeDataProps="allDepartmentsList" :allTreeKeys="allTreeKeys"
+                                  :isAssignSonNode="isAssignSonNode"/>
       </a-tab-pane>
 
       <a-tab-pane :key="2" tab="鍒嗛厤鐢ㄦ埛">
@@ -28,6 +29,7 @@
   import dncApi from '@/api/dnc'
   import DepartPermissionTransfer from './DepartPermissionTransfer'
   import UserPermissionTransfer from './UserPermissionTransfer'
+  import { queryProductionTreeList } from '@/api/api'
 
   export default {
     name: 'AssignPermissionModal',
@@ -45,6 +47,7 @@
         activeTabKey: 1,
         allDepartmentsList: [],
         allUsersList: [],
+        allTreeKeys: [],
         hasLoadedDataTabKeyArray: []
       }
     },
@@ -77,11 +80,18 @@
 
       // 璋冪敤鎺ュ彛鑾峰彇鎵�鏈夐儴闂ㄥ垪琛�
       getAllDepartmentsListByApi() {
-        dncApi.getAllDepartmentsListApi()
+        this.allTreeKeys = []
+        queryProductionTreeList()
           .then(res => {
+            console.log('res-------------------', res)
             if (res.success) {
-              this.allDepartmentsList = res.list
-              this.$nextTick(() => this.$refs.departPermissionTransferRef.getHasPermissionDepartByApi())
+              this.allDepartmentsList = res.result
+              this.generateList(this.allDepartmentsList)
+              this.$nextTick(() => {
+                this.$refs.departPermissionTransferRef.getHasPermissionDepartByApi()
+                this.$refs.departPermissionTransferRef.expandedKeys = this.allTreeKeys
+                this.$refs.departPermissionTransferRef.flatten(JSON.parse(JSON.stringify(this.allDepartmentsList)))
+              })
               // 鍙湁涓婃閫�鍑烘椂鍦ㄩ儴闂ㄥ垎閰峵ab鐣岄潰鎵嶄細杩涘叆姝ゅ垽鏂�
               // 鑻ヤ笂娆¢��鍑烘椂鍦ㄧ敤鎴峰垎閰峵ab鐣岄潰鍒欏啀娆¤繘鍏ユ椂key鐢�2鍙樹负1鏃朵細瑙﹀彂watch鐩戞祴activeTabKey鍙樺寲鍒欎細灏唊ey:1鍔犲叆hasLoadedDataTabKeyArray锛屽洜姝ゆ棤闇�鍐嶆鍔犲叆key:1
               if (!this.hasLoadedDataTabKeyArray.includes(this.activeTabKey)) this.hasLoadedDataTabKeyArray.push(this.activeTabKey)
@@ -89,12 +99,30 @@
           })
       },
 
+      /**
+       * 閫掑綊鑾峰緱鎵�鏈夋爲鑺傜偣key
+       * @param data
+       */
+      generateList(data) {
+        for (let i = 0; i < data.length; i++) {
+          const node = data[i]
+          const key = node.key
+          this.allTreeKeys.push(key)
+          if (node.children) this.generateList(node.children)
+        }
+      },
+
       // 璋冪敤鎺ュ彛鑾峰彇鎵�鏈夌敤鎴峰垪琛�
       getAllUsersListByApi() {
         dncApi.getAllUsersListApi()
           .then(res => {
             if (res.success) {
-              this.allUsersList = res.result.records
+              this.allUsersList = res.result.records.map(item => {
+                return {
+                  ...item,
+                  disabled: item.username === 'admin'
+                }
+              })
               this.$nextTick(() => this.$refs.userPermissionTransferRef.getHasPermissionUserByApi())
             }
           })
diff --git a/src/views/dnc/base/modules/ProductStructure/Permission/DepartPermissionTransfer.vue b/src/views/dnc/base/modules/ProductStructure/Permission/DepartPermissionTransfer.vue
index 3315fef..58f406a 100644
--- a/src/views/dnc/base/modules/ProductStructure/Permission/DepartPermissionTransfer.vue
+++ b/src/views/dnc/base/modules/ProductStructure/Permission/DepartPermissionTransfer.vue
@@ -1,17 +1,44 @@
 <template>
   <a-spin :spinning="spinning">
     <a-transfer
-      class="transfer-container"
+      class="tree-transfer"
       :data-source="dataSource"
       show-search
       :list-style="{flex:1,height: '500px'}"
       :titles="['鏈垎閰嶉儴闂�', '宸插垎閰嶉儴闂�']"
       :operations="['鍒嗛厤閮ㄩ棬', '绉婚櫎閮ㄩ棬']"
       :target-keys="targetKeys"
-      :render="item => `${item.departName}`"
+      :render="item => `${item.title}`"
       @change="handleChange"
-      :rowKey="record => record.departId"
+      @search="handleSearch"
     >
+      <template slot="children" slot-scope="{ props: { direction, selectedKeys }, on: { itemSelect } }">
+        <a-tree
+          v-if="direction === 'left'"
+          blockNode
+          checkable
+          checkStrictly
+          :expandedKeys="expandedKeys"
+          :autoExpandParent="autoExpandParent"
+          @expand="handleTreeNodeExpand"
+          :checkedKeys="[...selectedKeys, ...targetKeys]"
+          :treeData="treeData"
+          @check="(_, props) => {onChecked(_, props, [...selectedKeys, ...targetKeys], itemSelect);}"
+          @select="(_, props) => {onChecked(_, props, [...selectedKeys, ...targetKeys], itemSelect); }">
+          <template slot="title" slot-scope="{title}">
+                     <span v-if="title.indexOf(searchValue) > -1">{{ title.substr(0, title.indexOf(searchValue)) }}<span
+                       class="replaceSearch">{{ searchValue }}</span>{{ title.substr(title.indexOf(searchValue) + searchValue.length) }}</span>
+            <span v-else>{{ title }}</span>
+          </template>
+        </a-tree>
+      </template>
+
+      <template slot="footer" slot-scope="{direction}" v-if="direction==='left'">
+        <a-button type="primary" style="float:right;margin: 5px;margin-right: 10px"
+                  @click="isExpandAllTreeNode=!isExpandAllTreeNode">
+          灞曞紑/鎶樺彔
+        </a-button>
+      </template>
 
       <span slot="notFoundContent">鏆傛棤鏁版嵁</span>
     </a-transfer>
@@ -21,6 +48,8 @@
 <script>
   import dncApi from '@/api/dnc'
 
+  const transferDataSource = []
+
   export default {
     name: 'DepartPermissionTransfer',
     components: {},
@@ -28,7 +57,10 @@
       currentTreeNodeInfo: {
         type: Object
       },
-      dataSource: {
+      allTreeKeys: {
+        type: Array
+      },
+      treeDataProps: {
         type: Array
       },
       isAssignSonNode: {
@@ -38,15 +70,65 @@
     data() {
       return {
         targetKeys: [],
-        spinning: false
+        spinning: false,
+        isExpandAllTreeNode: true,
+        searchValue: '',
+        expandedKeys: [],
+        autoExpandParent: true,
+        dataSource: transferDataSource
+      }
+    },
+    watch: {
+      isExpandAllTreeNode: {
+        handler(value) {
+          if (value) this.expandedKeys = this.allTreeKeys
+          else this.expandedKeys = []
+        }
+      }
+    },
+    computed: {
+      treeData() {
+        return this.handleTreeData(this.treeDataProps, this.targetKeys)
       }
     },
     methods: {
+      // 璋冪敤鎺ュ彛鑾峰彇鏈夋潈闄愮殑閮ㄩ棬鍒楄〃
       getHasPermissionDepartByApi() {
+        const that = this
+        that.spinning = true
         dncApi.getHasPermissionDepartApi(this.currentTreeNodeInfo)
           .then(res => {
-            if (res.success) this.targetKeys = res.list.map(item => item.departId)
+            if (res.success) this.targetKeys = res.list.map(item => item.id)
           })
+          .finally(() => {
+            that.spinning = false
+          })
+      },
+
+      /**
+       * 绌挎妗嗘悳绱㈡杈撳叆鏃惰Е鍙�
+       * @param direction 绌挎妗嗙殑宸﹀彸 "left"||"right"
+       * @param value 杈撳叆鍊�
+       */
+      handleSearch(direction, value) {
+        if (direction === 'left') {
+          let search = value
+          let expandedKeys = transferDataSource
+            .map(item => {
+              if (item.title != null) {
+                if (item.title.indexOf(search) > -1) {
+                  return this.getParentKey(item.key, this.treeDataProps)
+                }
+                return null
+              }
+            })
+            .filter((item, i, self) => item && self.indexOf(item) === i)
+          Object.assign(this, {
+            expandedKeys,
+            searchValue: search,
+            autoExpandParent: true
+          })
+        }
       },
 
       handleChange(targetKeys, direction, moveKeys) {
@@ -91,14 +173,92 @@
           .finally(() => {
             that.spinning = false
           })
+      },
+
+      onChecked(_, e, checkedKeys, itemSelect) {
+        const { eventKey } = e.node
+        itemSelect(eventKey, !this.isChecked(checkedKeys, eventKey))
+      },
+
+      handleTreeData(data, targetKeys = []) {
+        data.forEach(item => {
+          item['disabled'] = targetKeys.includes(item.key)
+          if (item.children) {
+            this.handleTreeData(item.children, targetKeys)
+          }
+        })
+        return data
+      },
+
+      handleTreeNodeExpand(expandedKeys) {
+        this.expandedKeys = expandedKeys
+        this.autoExpandParent = false
+      },
+
+      /**
+       * 閫掑綊鑾峰緱杈撳叆椤圭殑鐖剁骇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
+      },
+
+      isChecked(selectedKeys, eventKey) {
+        return selectedKeys.indexOf(eventKey) !== -1
+      },
+
+      flatten(list = []) {
+        list.forEach(item => {
+          transferDataSource.push(item)
+          if (item.children) {
+            this.flatten(item.children)
+          }
+        })
       }
     }
   }
 </script>
 
 <style scoped lang="less">
-  .transfer-container {
+  .tree-transfer {
     display: flex;
     align-items: center;
+
+    ::-webkit-scrollbar {
+      width: 8px;
+    }
+  }
+
+  .tree-transfer .ant-transfer-list .ant-transfer-list-body {
+    display: flex;
+    flex-direction: column;
+  }
+
+  /deep/ .ant-transfer-list-body {
+    display: flex;
+    flex-direction: column;
+    .ant-transfer-list-body-customize-wrapper {
+      flex: 1;
+      overflow: auto;
+    }
+  }
+
+  .replaceSearch {
+    color: #40a9ff;
+    font-weight: bold;
+    background-color: rgb(204, 204, 204);
   }
 </style>
\ No newline at end of file
diff --git a/src/views/dnc/base/modules/ProductStructure/Permission/UserPermissionTransfer.vue b/src/views/dnc/base/modules/ProductStructure/Permission/UserPermissionTransfer.vue
index 4521965..fc0824b 100644
--- a/src/views/dnc/base/modules/ProductStructure/Permission/UserPermissionTransfer.vue
+++ b/src/views/dnc/base/modules/ProductStructure/Permission/UserPermissionTransfer.vue
@@ -42,9 +42,14 @@
     },
     methods: {
       getHasPermissionUserByApi() {
+        const that = this
+        that.spinning = true
         dncApi.getHasPermissionUserApi(this.currentTreeNodeInfo)
           .then(res => {
             if (res.success) this.targetKeys = res.list.map(item => item.id)
+          })
+          .finally(() => {
+            that.spinning = false
           })
       },
 
@@ -64,14 +69,6 @@
           method = dncApi.assignPermissionToUser
         } else {
           method = dncApi.removePermissionFromUser
-          const adminId = dataSource.find(item => item.username === 'admin').id
-          if (moveKeys.includes(adminId)) {
-            $notification.warning({
-              message: '娑堟伅',
-              description: '涓嶈兘绉婚櫎绠$悊鍛樻潈闄�'
-            })
-            return
-          }
         }
         that.spinning = true
         method(params)
diff --git a/src/views/dnc/base/modules/ProductStructure/ProductStructureTree.vue b/src/views/dnc/base/modules/ProductStructure/ProductStructureTree.vue
index 5a995f9..c19f1d8 100644
--- a/src/views/dnc/base/modules/ProductStructure/ProductStructureTree.vue
+++ b/src/views/dnc/base/modules/ProductStructure/ProductStructureTree.vue
@@ -24,7 +24,7 @@
 
         <!--浜у搧缁撴瀯鏍�-->
         <div style="flex: 1;overflow:auto;margin-top: 10px">
-          <a-tree ref="tree" show-icon :expandedKeys.sync="expandedKeys"
+          <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}">
@@ -298,10 +298,6 @@
 
   /deep/ .ant-card-body, /deep/ .ant-spin-nested-loading, /deep/ .ant-spin-container {
     height: 100%;
-  }
-
-  /deep/ .ant-tree-node-content-wrapper {
-    width: calc(100% - 24px);
   }
 
   /deep/ .ant-tree-title, .ant-tree-title .ant-dropdown-trigger {

--
Gitblit v1.9.3