From 781b8b3e072a4e00b1cee56f961280c753cbb460 Mon Sep 17 00:00:00 2001
From: zzw <228544128@qq.com>
Date: 星期二, 06 十月 2026 17:34:29 +0800
Subject: [PATCH] feat: add assigned scope to role permission settings

---
 emergency-repair-web/src/views/system/RolePermissionDialog.vue |   43 +++++++++++++++++++++++++++++++++++++++----
 1 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/emergency-repair-web/src/views/system/RolePermissionDialog.vue b/emergency-repair-web/src/views/system/RolePermissionDialog.vue
index 7271f40..3180bb7 100644
--- a/emergency-repair-web/src/views/system/RolePermissionDialog.vue
+++ b/emergency-repair-web/src/views/system/RolePermissionDialog.vue
@@ -15,16 +15,21 @@
       <span class="selected-total">宸查�夋潈闄� {{ selectedRoleIds.length }} 涓�</span>
     </div>
     <div class="permission-toolbar">
-      <el-checkbox v-model="checkAll" @change="toggleAll">鍏ㄩ��</el-checkbox>
-      <span class="permission-tip">鑿滃崟鍜屾寜閽潈闄愬潎鍙嬀閫夛紝淇濆瓨鍚庡垏鎹㈣鑹蹭細鑷姩鍙嶆樉銆�</span>
+      <el-radio-group v-model="permissionScope" size="small" @change="handleScopeChange">
+        <el-radio-button label="all">鍏ㄩ儴</el-radio-button>
+        <el-radio-button label="assigned">宸茶缃�</el-radio-button>
+      </el-radio-group>
+      <el-checkbox v-if="permissionScope === 'all'" v-model="checkAll" @change="toggleAll">鍏ㄩ��</el-checkbox>
+      <span class="permission-tip">{{ permissionTip }}</span>
     </div>
     <div v-loading="loading" class="permission-tree">
       <el-tree
         ref="permissionTree"
-        :data="menus"
+        :data="displayMenus"
         node-key="id"
         show-checkbox
         default-expand-all
+        empty-text="璇ヨ鑹插皻鏈缃潈闄�"
         :render-content="renderContent"
         :props="{ label: 'name', children: 'children' }"
         @check="syncCheckAllState"
@@ -52,6 +57,7 @@
       loading: false,
       saving: false,
       checkAll: false,
+      permissionScope: 'all',
       selectedRoleIds: []
     }
   },
@@ -62,6 +68,23 @@
     },
     allMenuIds() {
       return this.flatMenus.map(item => String(item.id))
+    },
+    displayMenus() {
+      if (this.permissionScope === 'all') return this.menus
+      const assigned = new Set(this.selectedRoleIds.map(String))
+      const filterAssigned = nodes => (nodes || []).reduce((result, node) => {
+        const children = filterAssigned(node.children)
+        if (assigned.has(String(node.id)) || children.length) {
+          result.push({ ...node, children })
+        }
+        return result
+      }, [])
+      return filterAssigned(this.menus)
+    },
+    permissionTip() {
+      return this.permissionScope === 'all'
+        ? '鑿滃崟鍜屾寜閽潈闄愬潎鍙嬀閫夛紝淇濆瓨鍚庡垏鎹㈣鑹蹭細鑷姩鍙嶆樉銆�'
+        : '浠呮樉绀哄綋鍓嶈鑹插凡璁剧疆鐨勬潈闄愬強鍏剁埗绾ц妭鐐广��'
     }
   },
   watch: {
@@ -74,6 +97,7 @@
       if (!this.role || !this.role.id) return
       this.loading = true
       this.checkAll = false
+      this.permissionScope = 'all'
       this.selectedRoleIds = []
       Promise.all([
         api.get('/system/menu/tree'),
@@ -90,6 +114,15 @@
           this.syncCheckAllState()
         })
       }).finally(() => { this.loading = false })
+
+    },
+    handleScopeChange() {
+      this.selectedRoleIds = this.checkedMenuIds()
+      this.$nextTick(() => {
+        if (!this.$refs.permissionTree) return
+        this.$refs.permissionTree.setCheckedKeys(this.displayCheckedKeys(this.selectedRoleIds))
+        this.syncCheckAllState()
+      })
     },
     renderContent(h, { data }) {
       const label = data.menuType === 2 ? data.name + ' [鎸夐挳 ' + (data.permissions || '') + ']' : data.name
@@ -128,7 +161,9 @@
       return [...new Set([...(tree.getCheckedKeys(false) || []), ...(tree.getHalfCheckedKeys() || [])].map(String))]
     },
     syncCheckAllState() {
-      this.checkAll = this.checkedMenuIds().length === this.allMenuIds.length
+      const checked = this.checkedMenuIds()
+      this.selectedRoleIds = checked
+      this.checkAll = checked.length === this.allMenuIds.length
     },
     toggleAll() {
       if (!this.$refs.permissionTree) return

--
Gitblit v1.9.1