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/Permission/DepartPermissionTransfer.vue |  174 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 167 insertions(+), 7 deletions(-)

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

--
Gitblit v1.9.3