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([]); const permissionList = ref([]); const manageableRoleList = ref([]); const grantablePermissionList = ref([]); const loading = ref(false); const loaded = ref(false); let loadTask: Promise | null = null; const roleTree = computed>(() => { 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())); }); // ---------- 基础数据 ---------- async function loadAll(force = false): Promise { 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 { if (!id) { return createEmptyRole(); } const role = normalizeRole(await RoleAPI.detail(id)); upsertLocalRole(role); return role; } // ---------- 授权范围 ---------- async function loadManageableRoles(): Promise { manageableRoleList.value = []; const list = await RoleAPI.manageableList(moduleCode); manageableRoleList.value = (list || []).map(normalizeRole); return manageableRoleList.value; } async function loadGrantablePermissions(targetModuleCode: ModuleCode = moduleCode): Promise { grantablePermissionList.value = []; const list = await PermissionAPI.grantableList(targetModuleCode); grantablePermissionList.value = list || []; return grantablePermissionList.value; } async function loadGrantableRolePermissions(roleId: string): Promise { return await RoleAPI.grantablePermissionList(roleId); } async function loadDelegationPermissions(roleId: string): Promise { return await RoleAPI.delegationList(roleId); } async function loadGrantableDelegationPermissions(roleId: string): Promise { return await RoleAPI.grantableDelegationList(roleId); } async function loadParentGrantableRoles(roleId: string): Promise { return (await RoleAPI.parentGrantableList(roleId)).map(normalizeRole); } async function loadPermissionDetail(id: string): Promise { 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): Array { 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(); 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 { 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 { 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 { 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 { 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 { await RoleAPI.update({ id: roleId, permissionIdList: [...permissionIds] }); const role = await loadRoleDetail(roleId); upsertLocalRole(role); } async function setRoleChildRoleList(roleId: string, childRoleIds: string[]): Promise { await RoleAPI.update({ id: roleId, childRoleIdList: [...childRoleIds] }); const role = await loadRoleDetail(roleId); upsertLocalRole(role); } async function setRoleDelegationPermissionList(roleId: string, permissionIds: string[]): Promise { await RoleAPI.updateDelegation({ id: roleId, delegationPermissionIdList: permissionIds }); const role = await loadRoleDetail(roleId); upsertLocalRole(role); } async function setRoleParentRole(roleId: string, parentRoleId: string): Promise { 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 }; });