Files
aurak/server/src/auth/permission/role.controller.ts
T
Developer ba33d517c1 feat: 分层 RBAC 权限管理系统
后端:
- 新增 Role / RolePermission 实体(自动 seed 系统角色)
- PermissionService——通过 isAdmin / TenantMember 链路解析用户权限
- @Permission() 装饰器 + PermissionsGuard 守卫
- /api/permissions 和 /api/roles REST API
- UserController 内联 role 检查迁移到 @Permission()
- PermissionModule 全局注册

前端:
- usePermissions hook——获取当前用户权限集
- PermissionGate 组件级门控
- PermissionSettingsView——角色列表+权限矩阵编辑页面
- SettingsView 新增「权限管理」Tab(仅 admin 可见)
- 权限预览(26 项,7 分类)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 23:25:22 +08:00

101 lines
3.1 KiB
TypeScript

import {
Controller,
Get,
Post,
Put,
Delete,
Body,
Param,
Request,
UseGuards,
NotFoundException,
BadRequestException,
} from '@nestjs/common';
import { PermissionService } from './permission.service';
import { CombinedAuthGuard } from '../combined-auth.guard';
import { RolesGuard } from '../roles.guard';
import { Roles } from '../roles.decorator';
import { UserRole } from '../../user/user-role.enum';
@Controller('roles')
@UseGuards(CombinedAuthGuard, RolesGuard)
export class RoleController {
constructor(private readonly permissionService: PermissionService) {}
/** 列出角色(系统角色 + 租户自定义角色) */
@Get()
@Roles(UserRole.SUPER_ADMIN, UserRole.TENANT_ADMIN)
async findAll(@Request() req) {
const tenantId = req.tenantId || req.user.tenantId;
return this.permissionService.findAllRoles(tenantId);
}
/** 获取单个角色 */
@Get(':id')
@Roles(UserRole.SUPER_ADMIN, UserRole.TENANT_ADMIN)
async findOne(@Param('id') id: string) {
const role = await this.permissionService.findRoleById(id);
if (!role) throw new NotFoundException('角色不存在');
return role;
}
/** 创建自定义角色 */
@Post()
@Roles(UserRole.SUPER_ADMIN, UserRole.TENANT_ADMIN)
async create(@Body() body: { name: string; description?: string }, @Request() req) {
if (!body.name) throw new BadRequestException('角色名不能为空');
const tenantId = req.tenantId || req.user.tenantId;
try {
return await this.permissionService.createRole(body.name, body.description || '', tenantId);
} catch (err: any) {
throw new BadRequestException(err.message);
}
}
/** 修改角色基本信息 */
@Put(':id')
@Roles(UserRole.SUPER_ADMIN, UserRole.TENANT_ADMIN)
async update(@Param('id') id: string, @Body() body: { name?: string; description?: string }) {
try {
return await this.permissionService.updateRole(id, body);
} catch (err: any) {
throw new BadRequestException(err.message);
}
}
/** 删除自定义角色 */
@Delete(':id')
@Roles(UserRole.SUPER_ADMIN, UserRole.TENANT_ADMIN)
async remove(@Param('id') id: string) {
try {
await this.permissionService.deleteRole(id);
return { success: true };
} catch (err: any) {
throw new BadRequestException(err.message);
}
}
/** 获取角色的权限列表 */
@Get(':id/permissions')
@Roles(UserRole.SUPER_ADMIN, UserRole.TENANT_ADMIN)
async getPermissions(@Param('id') id: string) {
const perms = await this.permissionService.getRolePermissions(id);
return { permissions: perms };
}
/** 设置角色的权限(全量替换) */
@Put(':id/permissions')
@Roles(UserRole.SUPER_ADMIN, UserRole.TENANT_ADMIN)
async setPermissions(@Param('id') id: string, @Body() body: { permissions: string[] }) {
if (!Array.isArray(body.permissions)) {
throw new BadRequestException('permissions 必须是数组');
}
try {
await this.permissionService.setRolePermissions(id, body.permissions);
return { success: true, permissions: body.permissions };
} catch (err: any) {
throw new BadRequestException(err.message);
}
}
}