refactor permission

This commit is contained in:
Timi
2026-08-11 15:24:29 +08:00
parent 45ea8b46aa
commit 575d41b2e2
20 changed files with 1789 additions and 625 deletions
+129 -61
View File
@@ -3,40 +3,27 @@ import {
PermissionAPI,
RoleAPI,
type ModuleCode,
type Permission as UserPermission,
type PermissionPayload,
type Role as UserRole,
type RolePayload
type Role as UserRole
} from "timi-web";
import type {
Permission,
PermissionDraft,
Role,
RoleDraft,
RolePayload
} from "@/types/PermissionSettings";
export const moduleCode: ModuleCode = "GAO";
const pageSize = 1000;
export type Permission = UserPermission;
export type Role = Omit<UserRole, "id" | "permissionIdList" | "childRoleIdList"> & {
id: string;
permissionIdList: string[];
childRoleIdList: string[];
};
export type RoleDraft = {
id?: string;
code: string;
name: string;
description: string;
nameLangId?: string;
moduleCode?: ModuleCode;
permissionIdList: string[];
childRoleIdList: string[];
};
export type PermissionDraft = {
id?: string;
code: string;
name: string;
description: string;
nameLangId?: string;
moduleCode?: ModuleCode;
};
export type {
Permission,
PermissionDraft,
Role,
RoleDraft,
RolePayload
} from "@/types/PermissionSettings";
function normalizeRole(role: UserRole): Role {
return {
@@ -44,8 +31,10 @@ function normalizeRole(role: UserRole): Role {
id: role.id || "",
moduleCode: role.moduleCode || moduleCode,
description: role.description || "",
parentRoleId: role.parentRoleId || role.parentRole?.id,
permissionIdList: role.permissionIdList || role.permissionList?.map(item => item.id) || [],
childRoleIdList: role.childRoleIdList || role.childRoleList?.map(item => item.id).filter((id): id is string => Boolean(id)) || []
childRoleIdList: role.childRoleIdList || role.childRoleList?.map(item => item.id).filter((id): id is string => Boolean(id)) || [],
delegationPermissionIdList: role.delegationPermissionIdList || role.delegationPermissionList?.map((item: Permission) => item.id) || []
};
}
@@ -57,7 +46,8 @@ function createEmptyRole(): Role {
name: "",
description: "",
permissionIdList: [],
childRoleIdList: []
childRoleIdList: [],
delegationPermissionIdList: []
};
}
@@ -74,13 +64,15 @@ function createEmptyPermission(): Permission {
export const usePermissionSettingsStore = defineStore("permission-settings", () => {
const roleList = ref<Role[]>([]);
const permissionList = ref<Permission[]>([]);
const manageableRoleList = ref<Role[]>([]);
const grantablePermissionList = ref<Permission[]>([]);
const loading = ref(false);
const loaded = ref(false);
let loadTask: Promise<void> | null = null;
const roleTree = computed<Array<Role & { level: number }>>(() => {
const childIdSet = new Set(roleList.value.flatMap(item => item.childRoleIdList));
const roots = roleList.value.filter(item => !childIdSet.has(item.id));
const roleIdSet = new Set(roleList.value.map(item => item.id));
const roots = roleList.value.filter(item => !item.parentRoleId || !roleIdSet.has(item.parentRoleId));
return roots.flatMap(item => buildRoleTree(item.id, 0, new Set<string>()));
});
@@ -143,6 +135,38 @@ export const usePermissionSettingsStore = defineStore("permission-settings", ()
return role;
}
// ---------- 授权范围 ----------
async function loadManageableRoles(): Promise<Role[]> {
manageableRoleList.value = [];
const list = await RoleAPI.manageableList(moduleCode);
manageableRoleList.value = (list || []).map(normalizeRole);
return manageableRoleList.value;
}
async function loadGrantablePermissions(targetModuleCode: ModuleCode = moduleCode): Promise<Permission[]> {
grantablePermissionList.value = [];
const list = await PermissionAPI.grantableList(targetModuleCode);
grantablePermissionList.value = list || [];
return grantablePermissionList.value;
}
async function loadGrantableRolePermissions(roleId: string): Promise<Permission[]> {
return await RoleAPI.grantablePermissionList(roleId);
}
async function loadDelegationPermissions(roleId: string): Promise<Permission[]> {
return await RoleAPI.delegationList(roleId);
}
async function loadGrantableDelegationPermissions(roleId: string): Promise<Permission[]> {
return await RoleAPI.grantableDelegationList(roleId);
}
async function loadParentGrantableRoles(roleId: string): Promise<Role[]> {
return (await RoleAPI.parentGrantableList(roleId)).map(normalizeRole);
}
async function loadPermissionDetail(id: string): Promise<Permission> {
if (!id) {
return createEmptyPermission();
@@ -185,10 +209,13 @@ export const usePermissionSettingsStore = defineStore("permission-settings", ()
const nextVisitedRoleIds = new Set(visitedRoleIds);
nextVisitedRoleIds.add(roleId);
const childRoleIdList = roleList.value
.filter(item => item.parentRoleId === roleId)
.map(item => item.id);
return [{
...current,
level
}, ...current.childRoleIdList.flatMap(childRoleId => buildRoleTree(childRoleId, level + 1, nextVisitedRoleIds))];
}, ...childRoleIdList.flatMap(childRoleId => buildRoleTree(childRoleId, level + 1, nextVisitedRoleIds))];
}
function getRoleById(id: string): Role | undefined {
@@ -209,17 +236,13 @@ export const usePermissionSettingsStore = defineStore("permission-settings", ()
function getInheritedPermissionList(role: Role): Permission[] {
const permissionMap = new Map<string, Permission>();
const allPermissionList = role.allPermissionList || [];
for (const permission of [...getRolePermissionList(role), ...allPermissionList]) {
const permissionList = role.allPermissionList?.length
? role.allPermissionList
: getRolePermissionList(role);
for (const permission of permissionList) {
permissionMap.set(permission.id, permission);
}
for (const childRole of getChildRoles(role)) {
for (const permission of getRolePermissionList(childRole)) {
permissionMap.set(permission.id, permission);
}
}
return Array.from(permissionMap.values());
}
@@ -227,28 +250,38 @@ export const usePermissionSettingsStore = defineStore("permission-settings", ()
async function upsertRole(draft: RoleDraft, createMode: boolean): Promise<Role | undefined> {
const current = getRoleById(draft.id || "");
const code = draft.code.trim();
const name = draft.name.trim();
const description = draft.description.trim();
const payload: RolePayload = {
...draft,
moduleCode: moduleCode,
code: draft.code.trim(),
code,
nameLangId: current?.nameLangId,
name: draft.name.trim(),
description: draft.description.trim(),
permissionIdList: [...draft.permissionIdList],
childRoleIdList: [...draft.childRoleIdList]
name,
description
};
if (draft.permissionIdList !== undefined) {
payload.permissionIdList = [...draft.permissionIdList];
}
if (draft.childRoleIdList !== undefined) {
payload.childRoleIdList = [...draft.childRoleIdList];
}
if (createMode) {
await RoleAPI.create({
moduleCode: payload.moduleCode,
code: payload.code,
name: payload.name,
description: payload.description,
moduleCode: moduleCode,
code,
name,
description,
parentRoleId: payload.parentRoleId,
ownerType: payload.ownerType,
ownerId: payload.ownerId,
permissionIdList: payload.permissionIdList,
childRoleIdList: payload.childRoleIdList
});
await loadAll(true);
return undefined;
return roleList.value.find(item => item.code === payload.code && item.moduleCode === moduleCode);
}
await RoleAPI.update(payload);
@@ -263,6 +296,7 @@ export const usePermissionSettingsStore = defineStore("permission-settings", ()
.filter(item => item.id !== id)
.map(item => ({
...item,
parentRoleId: item.parentRoleId === id ? undefined : item.parentRoleId,
childRoleIdList: item.childRoleIdList.filter(childId => childId !== id)
}));
}
@@ -305,25 +339,56 @@ export const usePermissionSettingsStore = defineStore("permission-settings", ()
}
async function setRolePermissionList(roleId: string, permissionIds: string[]): Promise<void> {
await RoleAPI.update({
id: roleId,
permissionIdList: [...permissionIds]
});
const role = await loadRoleDetail(roleId);
await upsertRole({
id: role.id,
moduleCode: moduleCode,
code: role.code,
name: role.name || "",
description: role.description || "",
permissionIdList: [...permissionIds],
childRoleIdList: [...role.childRoleIdList]
}, false);
upsertLocalRole(role);
}
async function setRoleChildRoleList(roleId: string, childRoleIds: string[]): Promise<void> {
await RoleAPI.update({
id: roleId,
childRoleIdList: [...childRoleIds]
});
const role = await loadRoleDetail(roleId);
upsertLocalRole(role);
}
async function setRoleDelegationPermissionList(roleId: string, permissionIds: string[]): Promise<void> {
await RoleAPI.updateDelegation({
id: roleId,
delegationPermissionIdList: permissionIds
});
const role = await loadRoleDetail(roleId);
upsertLocalRole(role);
}
async function setRoleParentRole(roleId: string, parentRoleId: string): Promise<void> {
await RoleAPI.updateParent({
id: roleId,
parentRoleId
});
const role = await loadRoleDetail(roleId);
upsertLocalRole(role);
}
return {
roleList,
permissionList,
manageableRoleList,
grantablePermissionList,
roleTree,
loading,
loaded,
loadAll,
loadManageableRoles,
loadGrantablePermissions,
loadGrantableRolePermissions,
loadDelegationPermissions,
loadGrantableDelegationPermissions,
loadParentGrantableRoles,
loadRoleDetail,
loadPermissionDetail,
getRoleById,
@@ -335,7 +400,10 @@ export const usePermissionSettingsStore = defineStore("permission-settings", ()
removeRole,
upsertPermission,
removePermission,
setRolePermissionList
setRolePermissionList,
setRoleChildRoleList,
setRoleDelegationPermissionList,
setRoleParentRole
};
});