lty/qy-lty-admin/lib/permissions.ts
pmc d60dd897c7 feat(02-01): 扩展 RBAC 矩阵增加 credential-slot 模块
- PermissionModule union 末尾追加 'credential-slot' 字面量(共 14 项)
- 超级管理员 / AI模型管理员 两角色数组末尾追加 'credential-slot'
- 顶部权限矩阵注释表新增「凭据槽位」行
- 其他 4 角色(内容管理员/卡牌管理员/查看者/管理员)数组逐字不变
- getModuleFromPath 不动(凭据槽位是 /ai-model 子能力,无独立路由)
2026-05-08 11:43:14 +08:00

127 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 权限矩阵 - 定义各角色对各模块的访问权限
*
* 权限矩阵对照表:
* | 模块 | 超级管理员 | 内容管理员 | AI模型管理员 | 卡牌管理员 | 查看者 |
* |-------------|-----------|-----------|------------|-----------|-------|
* | 仪表盘查看 | ✓ | ✓ | ✓ | ✓ | ✓ |
* | 用户管理 | ✓ | | | | |
* | 角色权限管理 | ✓ | | | | |
* | AI模型管理 | ✓ | | ✓ | | |
* | 凭据槽位 | ✓ | | ✓ | | |
* | 服装管理 | ✓ | ✓ | | ✓ | |
* | 道具管理 | ✓ | ✓ | | ✓ | |
* | 歌曲管理 | ✓ | ✓ | | | |
* | 系统设置 | ✓ | | | | |
*/
// 所有可识别的角色名称
export type RoleName = "超级管理员" | "内容管理员" | "AI模型管理员" | "卡牌管理员" | "查看者" | "管理员";
// 模块权限 key
export type PermissionModule =
| "dashboard"
| "users"
| "permissions"
| "ai-model"
| "outfits"
| "props"
| "home-decor"
| "food"
| "songs"
| "dances"
| "achievements"
| "affinity"
| "settings"
| "credential-slot";
// 权限矩阵定义
const PERMISSION_MATRIX: Record<RoleName, PermissionModule[]> = {
: [
"dashboard", "users", "permissions", "ai-model",
"outfits", "props", "home-decor", "food",
"songs", "dances", "achievements", "affinity", "settings",
"credential-slot",
],
: [
"dashboard", "outfits", "props", "home-decor", "food",
"songs", "dances", "achievements", "affinity",
],
AI模型管理员: [
"dashboard", "ai-model",
"credential-slot",
],
: [
"dashboard", "outfits", "props", "home-decor", "food",
],
: [
"dashboard",
],
// 后备角色:普通管理员等同于查看者
: [
"dashboard",
],
};
/**
* 获取当前用户角色
*/
export function getUserRole(): RoleName {
if (typeof window === "undefined") return "查看者";
const role = localStorage.getItem("user_role");
if (role && role in PERMISSION_MATRIX) {
return role as RoleName;
}
return "查看者";
}
/**
* 获取当前用户有权限的模块列表
*/
export function getAllowedModules(): PermissionModule[] {
const role = getUserRole();
return PERMISSION_MATRIX[role] || PERMISSION_MATRIX["查看者"];
}
/**
* 检查当前用户是否有某个模块的权限
*/
export function hasPermission(module: PermissionModule): boolean {
return getAllowedModules().includes(module);
}
/**
* 根据路径判断所需的模块权限
*/
export function getModuleFromPath(pathname: string): PermissionModule | null {
// 去掉开头的斜杠,取第一段路径
const segment = pathname.replace(/^\//, "").split("/")[0];
const pathMap: Record<string, PermissionModule> = {
"": "dashboard",
"ai-model": "ai-model",
"outfits": "outfits",
"props": "props",
"home-decor": "home-decor",
"food": "food",
"songs": "songs",
"dances": "dances",
"achievements": "achievements",
"affinity": "affinity",
"users": "users",
"permissions": "permissions",
"settings": "settings",
};
return pathMap[segment] ?? null;
}
/**
* 检查当前用户是否有访问某个路径的权限
*/
export function hasPathPermission(pathname: string): boolean {
const module = getModuleFromPath(pathname);
if (module === null) return true; // 未知路径默认允许(如 login、register
return hasPermission(module);
}