From 977615baed31cba59bc820f38bab1e6b2def1891 Mon Sep 17 00:00:00 2001 From: dzq Date: Fri, 20 Jun 2025 08:41:37 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E8=A7=92=E8=89=B2=E7=AE=A1=E7=90=86):=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=95=B0=E6=8D=AE=E6=9D=83=E9=99=90=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增数据权限字段并与菜单权限联动 - 重构菜单权限界面为左右布局 - 添加数据权限与菜单权限的双向绑定逻辑 - 优化菜单选项数据结构,增加数据权限字段 --- src/views/system/role/index.vue | 121 ++++++++++++++++++++++++++------ 1 file changed, 98 insertions(+), 23 deletions(-) diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index 3c85c60..5eb6f11 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -34,6 +34,8 @@ const { const opType = ref<"add" | "update">("add"); const opRow = ref(); +const dataScope = ref>({}); +(window as any).dataScope = dataScope; const formData = reactive({ roleId: 0, @@ -87,6 +89,7 @@ watch(activeTab, async (val) => { await getRoleInfo("update", opRow.value); Object.assign(formData, opRow.value); formData.menuIds = opRow.value.selectedMenuList; + updateDataScope(); }); async function getRoleInfo(type: "add" | "update", row?: RoleDTO) { try { @@ -103,7 +106,8 @@ async function getRoleInfo(type: "add" | "update", row?: RoleDTO) { opType.value = type; opRow.value = row; } -const processedMenuOptions = ref<{ categoryName: string; items: MenuDTO[] }[]>([]); +const processedMenuOptions = ref<{ id:number, categoryName: string; items: MenuDTO[]; dataScope: string }[]>([]); +(window as any).processedMenuOptions = processedMenuOptions; // 监听菜单树变化,处理菜单选项结构 watch(menuTree, (val) => { @@ -127,8 +131,9 @@ watch(menuTree, (val) => { // 如果有叶子节点,则创建分类 if (leaves.length) { categories.push({ - categoryName: menuOption.menuName, // 使用菜单名作为分类名 - items: leaves // 包含当前菜单及其叶子节点 + id: menuOption.id, + categoryName: menuOption.menuName, + items: leaves }); } @@ -154,10 +159,45 @@ watch(menuTree, (val) => { processedMenuOptions.value = categories; }); +// 监听菜单选择变化,更新数据权限 +const updateDataScope = () => { + dataScope.value = {}; + processedMenuOptions.value.forEach(category => { + const selectedItem = category.items.find(item => item.menuName == '读写' && formData.menuIds.includes(item.id)); + const permission = selectedItem ? '1' : '0'; + dataScope.value[category.id] = `${category.id}-${permission}`; + }); +}; + +// 监听dataScope变化,反向更新menuIds +watch( + dataScope, + (newDataScope) => { + Object.entries(newDataScope).forEach(([categoryId, scopeValue]) => { + const [id, permission] = scopeValue.split('-'); + const category = processedMenuOptions.value.find(cat => cat.id === Number(id)); + if (!category) return; + + const writeReadItem = category.items.find(item => item.menuName === '读写'); + if (!writeReadItem) return; + + if (permission === '1') { + if (!formData.menuIds.includes(writeReadItem.id)) { + formData.menuIds.push(writeReadItem.id); + } + } else { + formData.menuIds = formData.menuIds.filter(id => id !== writeReadItem.id); + } + }); + }, + { deep: true } +); + async function handleConfirm() { try { await formRef.value?.validate(); loading.value = true; + formData.dataScope = Object.values(dataScope.value).join(','); console.log("opType", opType.value); if (opType.value === 'add') { await addRoleApi(formData as AddRoleCommand); @@ -216,27 +256,42 @@ onSearch().then(() => { statusList[item].label }} --> - - - - - - + +
+ +
+ @@ -303,6 +358,13 @@ onSearch().then(() => { flex: 1; } +.form-input-data { + margin-left: 50px; + + .el-radio { + margin-right: 12px; + } +} .form-input { width: 40%; } @@ -316,4 +378,17 @@ onSearch().then(() => { margin-top: 20px; text-align: right; } + +.menu-container { + border-radius: 4px; +} + +.menu-label { + padding-bottom: 8px; + margin-bottom: 10px; + border-bottom: 1px solid #e4e7ed; +} +.empty-placeholder { + height: 32px; +}