ba33d517c1
后端: - 新增 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>
101 lines
3.1 KiB
TypeScript
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);
|
|
}
|
|
}
|
|
}
|