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