- Update food, outfits, props, home-decor pages and components - Add permissions page and sidebar updates - Update API client and all API modules (auth, food, dances, etc.) - Add card model migrations for optional fields - Update Django views, serializers, and authentication - Add affinity level migrations and user app updates - Add project documentation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
123 lines
3.6 KiB
TypeScript
123 lines
3.6 KiB
TypeScript
/**
|
||
* 权限矩阵 - 定义各角色对各模块的访问权限
|
||
*
|
||
* 权限矩阵对照表:
|
||
* | 模块 | 超级管理员 | 内容管理员 | 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";
|
||
|
||
// 权限矩阵定义
|
||
const PERMISSION_MATRIX: Record<RoleName, PermissionModule[]> = {
|
||
超级管理员: [
|
||
"dashboard", "users", "permissions", "ai-model",
|
||
"outfits", "props", "home-decor", "food",
|
||
"songs", "dances", "achievements", "affinity", "settings",
|
||
],
|
||
内容管理员: [
|
||
"dashboard", "outfits", "props", "home-decor", "food",
|
||
"songs", "dances", "achievements", "affinity",
|
||
],
|
||
AI模型管理员: [
|
||
"dashboard", "ai-model",
|
||
],
|
||
卡牌管理员: [
|
||
"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);
|
||
}
|