import { useRbacUserStore } from '@/store/modules/rbac-user' import { normalizeResourcePermissionCode, PAGE_BUTTON_PARENT_ALIASES, } from '@/constants/pageButtonCatalog' /** 页面级动作后缀:有资源码或动作码之一即可进页 */ const PAGE_ACTION_SUFFIX = /\.(Query|Use|View)$/i /** * 展开权限码候选(含资源级、动作级、历史别名),用于路由/按钮校验互认。 * * 例: * - `System.BatchEmail.Use` ↔ `System.BatchEmail` ↔ `Rbac.email` * - `Rbac.Roles.Query` ↔ `Rbac.Roles` */ function expandPermissionCandidates(permission: string): string[] { const code = permission.trim() if (!code) return [] const set = new Set([code]) const addAliasFamily = (raw: string) => { if (!raw) return set.add(raw) const mapped = PAGE_BUTTON_PARENT_ALIASES[raw] if (mapped) set.add(mapped) if (PAGE_ACTION_SUFFIX.test(raw)) { const resource = raw.replace(PAGE_ACTION_SUFFIX, '') set.add(resource) const mappedResource = PAGE_BUTTON_PARENT_ALIASES[resource] if (mappedResource) set.add(mappedResource) } else { set.add(`${raw}.Query`) set.add(`${raw}.Use`) set.add(`${raw}.View`) } } addAliasFamily(code) // 反向:别名表里指向同一资源的历史菜单码 const resources = Array.from(set) for (const [from, to] of Object.entries(PAGE_BUTTON_PARENT_ALIASES)) { if (resources.includes(to) || resources.includes(from)) { addAliasFamily(from) addAliasFamily(to) } } // normalizeResourcePermissionCode 仅剥 .Query,这里再补一层 for (const item of Array.from(set)) { const normalized = normalizeResourcePermissionCode(item) if (normalized) set.add(normalized) } return Array.from(set) } /** * 检查是否有权限(三级按钮 / 路由 meta.permission) * * 兼容菜单同步后的编码差异: * - 二级菜单可能是资源码 `Operation.PrintLabel` * - 路由 meta 可能是 `Operation.PrintLabel.Query` * - 历史菜单码如 `Rbac.email` 与目录码 `System.BatchEmail.Use` * 以上互相视为可访问。 */ export function hasPermission(permission: string): boolean { const userStore = useRbacUserStore() if (!permission?.trim()) return true // Admin 角色默认全权限,无需在角色管理中逐项分配 if (hasRole('Admin')) return true const granted = userStore.permissions return expandPermissionCandidates(permission).some((code) => granted.includes(code)) } /** * 检查是否有任一权限 */ export function hasAnyPermission(permissions: string[]): boolean { if (!permissions?.length) return true return permissions.some((p) => hasPermission(p)) } /** * 检查是否有所有权限 */ export function hasAllPermissions(permissions: string[]): boolean { if (!permissions?.length) return true return permissions.every((p) => hasPermission(p)) } /** * 检查是否有角色 */ export function hasRole(roleCode: string): boolean { const userStore = useRbacUserStore() return userStore.userInfo?.roles?.some((r) => r.code === roleCode) || false } /** * 检查是否有任一角色 */ export function hasAnyRole(roleCodes: string[]): boolean { const userStore = useRbacUserStore() return roleCodes.some((code) => userStore.userInfo?.roles?.some((r) => r.code === code), ) }