Files
gao-customer-h5/src/store/permissionSettingsStore.ts
T
2026-08-11 15:24:29 +08:00

410 lines
11 KiB
TypeScript

import { defineStore } from "pinia";
import {
PermissionAPI,
RoleAPI,
type ModuleCode,
type PermissionPayload,
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,
PermissionDraft,
Role,
RoleDraft,
RolePayload
} from "@/types/PermissionSettings";
function normalizeRole(role: UserRole): Role {
return {
...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)) || [],
delegationPermissionIdList: role.delegationPermissionIdList || role.delegationPermissionList?.map((item: Permission) => item.id) || []
};
}
function createEmptyRole(): Role {
return {
id: "",
moduleCode: moduleCode,
code: "",
name: "",
description: "",
permissionIdList: [],
childRoleIdList: [],
delegationPermissionIdList: []
};
}
function createEmptyPermission(): Permission {
return {
id: "",
moduleCode: moduleCode,
code: "",
name: "",
description: ""
};
}
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 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>()));
});
// ---------- 基础数据 ----------
async function loadAll(force = false): Promise<void> {
if (loaded.value && !force) {
return;
}
if (loadTask && !force) {
await loadTask;
return;
}
loading.value = true;
loadTask = (async () => {
const [roleResult, permissionResult] = await Promise.all([
RoleAPI.list({
index: 0,
size: pageSize,
equalsExample: {
moduleCode: moduleCode
},
orderMap: {
code: "ASC"
}
}),
PermissionAPI.list({
index: 0,
size: pageSize,
equalsExample: {
moduleCode: moduleCode
},
orderMap: {
code: "ASC"
}
})
]);
roleList.value = roleResult.list.map(normalizeRole);
permissionList.value = permissionResult.list;
loaded.value = true;
})();
try {
await loadTask;
} finally {
loadTask = null;
loading.value = false;
}
}
async function loadRoleDetail(id: string): Promise<Role> {
if (!id) {
return createEmptyRole();
}
const role = normalizeRole(await RoleAPI.detail(id));
upsertLocalRole(role);
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();
}
const permission = permissionList.value.find(item => item.id === id);
if (!permission) {
throw new Error("权限不存在");
}
upsertLocalPermission(permission);
return permission;
}
function upsertLocalRole(role: Role): void {
const index = roleList.value.findIndex(item => item.id === role.id);
if (-1 < index) {
roleList.value.splice(index, 1, role);
return;
}
roleList.value.unshift(role);
}
function upsertLocalPermission(permission: Permission): void {
const index = permissionList.value.findIndex(item => item.id === permission.id);
if (-1 < index) {
permissionList.value.splice(index, 1, permission);
return;
}
permissionList.value.unshift(permission);
}
// ---------- 查询 ----------
function buildRoleTree(roleId: string, level: number, visitedRoleIds: Set<string>): Array<Role & { level: number }> {
const current = getRoleById(roleId);
if (!current || visitedRoleIds.has(roleId)) {
return [];
}
const nextVisitedRoleIds = new Set(visitedRoleIds);
nextVisitedRoleIds.add(roleId);
const childRoleIdList = roleList.value
.filter(item => item.parentRoleId === roleId)
.map(item => item.id);
return [{
...current,
level
}, ...childRoleIdList.flatMap(childRoleId => buildRoleTree(childRoleId, level + 1, nextVisitedRoleIds))];
}
function getRoleById(id: string): Role | undefined {
return roleList.value.find(item => item.id === id);
}
function getPermissionById(id: string): Permission | undefined {
return permissionList.value.find(item => item.id === id);
}
function getChildRoles(role: Role): Role[] {
return role.childRoleIdList.map(getRoleById).filter(Boolean) as Role[];
}
function getRolePermissionList(role: Role): Permission[] {
return role.permissionIdList.map(getPermissionById).filter(Boolean) as Permission[];
}
function getInheritedPermissionList(role: Role): Permission[] {
const permissionMap = new Map<string, Permission>();
const permissionList = role.allPermissionList?.length
? role.allPermissionList
: getRolePermissionList(role);
for (const permission of permissionList) {
permissionMap.set(permission.id, permission);
}
return Array.from(permissionMap.values());
}
// ---------- 写入 ----------
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,
nameLangId: current?.nameLangId,
name,
description
};
if (draft.permissionIdList !== undefined) {
payload.permissionIdList = [...draft.permissionIdList];
}
if (draft.childRoleIdList !== undefined) {
payload.childRoleIdList = [...draft.childRoleIdList];
}
if (createMode) {
await RoleAPI.create({
moduleCode: moduleCode,
code,
name,
description,
parentRoleId: payload.parentRoleId,
ownerType: payload.ownerType,
ownerId: payload.ownerId,
permissionIdList: payload.permissionIdList,
childRoleIdList: payload.childRoleIdList
});
await loadAll(true);
return roleList.value.find(item => item.code === payload.code && item.moduleCode === moduleCode);
}
await RoleAPI.update(payload);
const role = await loadRoleDetail(payload.id || "");
await loadAll(true);
return role;
}
async function removeRole(id: string): Promise<void> {
await RoleAPI.remove(id);
roleList.value = roleList.value
.filter(item => item.id !== id)
.map(item => ({
...item,
parentRoleId: item.parentRoleId === id ? undefined : item.parentRoleId,
childRoleIdList: item.childRoleIdList.filter(childId => childId !== id)
}));
}
async function upsertPermission(draft: PermissionDraft, createMode: boolean): Promise<Permission | undefined> {
const current = getPermissionById(draft.id || "");
const payload: PermissionPayload = {
...draft,
moduleCode: moduleCode,
code: draft.code.trim(),
nameLangId: current?.nameLangId,
name: draft.name.trim(),
description: draft.description.trim()
};
if (createMode) {
await PermissionAPI.create({
moduleCode: payload.moduleCode,
code: payload.code,
name: payload.name,
description: payload.description
});
await loadAll(true);
return undefined;
}
await PermissionAPI.update(payload);
const permission = await loadPermissionDetail(payload.id || "");
await loadAll(true);
return permission;
}
async function removePermission(id: string): Promise<void> {
await PermissionAPI.remove(id);
permissionList.value = permissionList.value.filter(item => item.id !== id);
roleList.value = roleList.value.map(item => ({
...item,
permissionIdList: item.permissionIdList.filter(permissionId => permissionId !== id)
}));
}
async function setRolePermissionList(roleId: string, permissionIds: string[]): Promise<void> {
await RoleAPI.update({
id: roleId,
permissionIdList: [...permissionIds]
});
const role = await loadRoleDetail(roleId);
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,
getPermissionById,
getChildRoles,
getRolePermissionList,
getInheritedPermissionList,
upsertRole,
removeRole,
upsertPermission,
removePermission,
setRolePermissionList,
setRoleChildRoleList,
setRoleDelegationPermissionList,
setRoleParentRole
};
});