fix(role): 优化角色资源树选中ID处理逻辑
This commit is contained in:
@@ -4,7 +4,7 @@ import type { TreeInstance } from 'element-plus';
|
||||
import { menuTypeRecord } from '@/constants/business';
|
||||
import { fetchAssignRoleMenus, fetchGetRoleMenuIds } from '@/service/api';
|
||||
import { $t } from '@/locales';
|
||||
import { resolveRoleMenuSubmitIds } from './role-resource-tree';
|
||||
import { normalizeRoleMenuCheckedIds, resolveRoleMenuSubmitIds } from './role-resource-tree';
|
||||
|
||||
defineOptions({ name: 'RoleResourcePanel' });
|
||||
|
||||
@@ -127,9 +127,14 @@ async function loadRoleMenus() {
|
||||
return;
|
||||
}
|
||||
|
||||
baselineMenuIds.value = [...data];
|
||||
const normalizedMenuIds = normalizeRoleMenuCheckedIds({
|
||||
menuTree: props.menuTree,
|
||||
checkedIds: data
|
||||
});
|
||||
|
||||
baselineMenuIds.value = normalizedMenuIds;
|
||||
dirtyMenuIds.value = new Set();
|
||||
await applyCheckedKeys(data);
|
||||
await applyCheckedKeys(normalizedMenuIds);
|
||||
treeRef.value?.filter(filterKeyword.value);
|
||||
}
|
||||
|
||||
@@ -144,13 +149,11 @@ async function handleSave() {
|
||||
}
|
||||
|
||||
const checkedMenuIds = (treeRef.value?.getCheckedKeys(false) as string[]) ?? [];
|
||||
const halfCheckedMenuIds = (treeRef.value?.getHalfCheckedKeys() as string[]) ?? [];
|
||||
const menuIds = resolveRoleMenuSubmitIds({
|
||||
menuTree: props.menuTree,
|
||||
baselineIds: baselineMenuIds.value,
|
||||
dirtyIds: [...dirtyMenuIds.value],
|
||||
checkedIds: checkedMenuIds,
|
||||
halfCheckedIds: halfCheckedMenuIds
|
||||
checkedIds: checkedMenuIds
|
||||
});
|
||||
|
||||
submitting.value = true;
|
||||
@@ -190,7 +193,13 @@ watch(
|
||||
() => props.menuTree.length,
|
||||
async value => {
|
||||
if (value && props.role) {
|
||||
await applyCheckedKeys(baselineMenuIds.value);
|
||||
const normalizedMenuIds = normalizeRoleMenuCheckedIds({
|
||||
menuTree: props.menuTree,
|
||||
checkedIds: baselineMenuIds.value
|
||||
});
|
||||
|
||||
baselineMenuIds.value = normalizedMenuIds;
|
||||
await applyCheckedKeys(normalizedMenuIds);
|
||||
treeRef.value?.filter(filterKeyword.value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,11 @@ type ResolveRoleMenuSubmitIdsInput = {
|
||||
baselineIds: string[];
|
||||
dirtyIds: string[];
|
||||
checkedIds: string[];
|
||||
halfCheckedIds: string[];
|
||||
};
|
||||
|
||||
type NormalizeRoleMenuCheckedIdsInput = {
|
||||
menuTree: RoleResourceTreeNode[];
|
||||
checkedIds: string[];
|
||||
};
|
||||
|
||||
type TreeIndex = {
|
||||
@@ -17,6 +21,39 @@ type TreeIndex = {
|
||||
subtreeIdsById: Map<string, string[]>;
|
||||
};
|
||||
|
||||
export function normalizeRoleMenuCheckedIds(input: NormalizeRoleMenuCheckedIdsInput) {
|
||||
const checkedIds = normalizeIds(input.checkedIds);
|
||||
|
||||
if (!checkedIds.length) {
|
||||
return checkedIds;
|
||||
}
|
||||
|
||||
const treeIndex = buildTreeIndex(input.menuTree);
|
||||
const normalizedIdSet = new Set(checkedIds);
|
||||
|
||||
treeIndex.orderedIds.forEach(id => {
|
||||
if (!normalizedIdSet.has(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const descendantIds = (treeIndex.subtreeIdsById.get(id) ?? [id]).slice(1);
|
||||
|
||||
if (!descendantIds.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedDescendantCount = descendantIds.reduce((count, descendantId) => {
|
||||
return normalizedIdSet.has(descendantId) ? count + 1 : count;
|
||||
}, 0);
|
||||
|
||||
if (selectedDescendantCount > 0 && selectedDescendantCount < descendantIds.length) {
|
||||
normalizedIdSet.delete(id);
|
||||
}
|
||||
});
|
||||
|
||||
return sortIdsByTreeOrder(treeIndex.orderedIds, normalizedIdSet);
|
||||
}
|
||||
|
||||
export function resolveRoleMenuSubmitIds(input: ResolveRoleMenuSubmitIdsInput) {
|
||||
const baselineIds = normalizeIds(input.baselineIds);
|
||||
|
||||
@@ -39,7 +76,8 @@ export function resolveRoleMenuSubmitIds(input: ResolveRoleMenuSubmitIdsInput) {
|
||||
}
|
||||
});
|
||||
|
||||
normalizeIds([...input.checkedIds, ...input.halfCheckedIds]).forEach(id => {
|
||||
// 半选父节点只用于树态展示,提交它会把整棵子树误当成完整授权。
|
||||
normalizeIds(input.checkedIds).forEach(id => {
|
||||
if (affectedIds.has(id)) {
|
||||
nextIdSet.add(id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user