Files
gongxue-base/apps/server/src/rbac/rbac.controller.ts
2026-07-16 10:16:56 +08:00

326 lines
8.7 KiB
TypeScript

import {
Controller,
Get,
Post,
Put,
Delete,
Body,
Param,
Query,
UseGuards,
Request,
BadRequestException,
} from '@nestjs/common';
import { RbacService } from './rbac.service';
import {
CreateRoleDto,
UpdateRoleDto,
CreateUserDto,
UpdateUserDto,
ResetPasswordDto,
UpdateProfileDto,
} from './dto/rbac.dto';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { RequirePermission } from '../auth/decorators/permission.decorator';
import { OperationLogsService } from '../operation-logs/operation-logs.service';
import { extractRequestInfo } from '../common/request-utils';
@UseGuards(JwtAuthGuard)
@Controller('rbac')
export class RbacController {
constructor(
private rbacService: RbacService,
private logService: OperationLogsService,
) {}
// ==================== 角色管理 ====================
@Get('roles')
@RequirePermission('role:view')
findAllRoles() {
return this.rbacService.findAllRoles();
}
@Get('roles/:id')
@RequirePermission('role:view')
findRoleById(@Param('id') id: string) {
return this.rbacService.findRoleById(+id);
}
@Post('roles')
@RequirePermission('role:create')
async createRole(@Body() dto: CreateRoleDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.rbacService.createRole(dto);
await this.logService.log({
userId: req.user?.id,
username: req.user?.username,
module: 'RBAC',
action: '创建角色',
detail: `角色: ${dto.name}`,
ipAddress,
userAgent,
});
return result;
}
@Put('roles/:id')
@RequirePermission('role:edit')
async updateRole(@Param('id') id: string, @Body() dto: UpdateRoleDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
try {
const result = await this.rbacService.updateRole(+id, dto);
await this.logService.log({
userId: req.user?.id,
username: req.user?.username,
module: 'RBAC',
action: '编辑角色',
targetId: +id,
targetType: 'role',
detail: JSON.stringify(dto),
ipAddress,
userAgent,
});
return result;
} catch (e: any) {
throw new BadRequestException(e.message);
}
}
@Delete('roles/:id')
@RequirePermission('role:delete')
async deleteRole(@Param('id') id: string, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
try {
const result = await this.rbacService.deleteRole(+id);
await this.logService.log({
userId: req.user?.id,
username: req.user?.username,
module: 'RBAC',
action: '删除角色',
targetId: +id,
targetType: 'role',
ipAddress,
userAgent,
});
return result;
} catch (e: any) {
throw new BadRequestException(e.message);
}
}
// ==================== 权限管理 ====================
@Get('permissions')
@RequirePermission('role:view')
findAllPermissions() {
return this.rbacService.findAllPermissions();
}
@Get('permissions/tree')
@RequirePermission('role:view')
getPermissionTree() {
return this.rbacService.getPermissionTree();
}
// ==================== 用户管理 ====================
@Get('users')
@RequirePermission('user:view', 'teacher:view')
getUsers(@Query('isArchived') isArchived?: string) {
const archived = isArchived === 'true';
return this.rbacService.findAllUsers(archived);
}
@Post('users')
@RequirePermission('user:create')
async createUser(@Body() dto: CreateUserDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
try {
const result = await this.rbacService.createUser(dto);
await this.logService.log({
userId: req.user?.id,
username: req.user?.username,
module: '账号',
action: '创建账号',
detail: `用户名: ${dto.username}`,
ipAddress,
userAgent,
});
return result;
} catch (e: any) {
throw new BadRequestException(e.message);
}
}
@Put('users/:id')
@RequirePermission('user:edit')
async updateUser(@Param('id') id: string, @Body() dto: UpdateUserDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
try {
const result = await this.rbacService.updateUser(+id, dto);
await this.logService.log({
userId: req.user?.id,
username: req.user?.username,
module: '账号',
action: '更新账号',
targetId: +id,
targetType: 'user',
detail: JSON.stringify(dto),
ipAddress,
userAgent,
});
return result;
} catch (e: any) {
throw new BadRequestException(e.message);
}
}
@Put('users/:id/password')
@RequirePermission('user:reset-password')
async resetPassword(@Param('id') id: string, @Body() dto: ResetPasswordDto, @Request() req: any) {
const { ipAddress, userAgent } = extractRequestInfo(req);
try {
const result = await this.rbacService.resetPassword(+id, dto.password);
await this.logService.log({
userId: req.user?.id,
username: req.user?.username,
module: '账号',
action: '重置密码',
targetId: +id,
targetType: 'user',
ipAddress,
userAgent,
});
return result;
} catch (e: any) {
throw new BadRequestException(e.message);
}
}
@Put('users/:id/archive')
@RequirePermission('user:edit')
async archiveUser(@Param('id') id: string) {
try {
return await this.rbacService.archiveUser(+id);
} catch (e: unknown) {
const err = e as { message?: string };
throw new BadRequestException(err?.message);
}
}
@Put('users/:id/restore')
@RequirePermission('user:edit')
async restoreUser(@Param('id') id: string) {
try {
return await this.rbacService.restoreUser(+id);
} catch (e: unknown) {
const err = e as { message?: string };
throw new BadRequestException(err?.message);
}
}
@Put('users/:id/mark-staff')
@RequirePermission('user:edit')
async markAsStaff(@Param('id') id: string) {
try {
return await this.rbacService.markAsStaff(+id);
} catch (e: unknown) {
const err = e as { message?: string };
throw new BadRequestException(err?.message);
}
}
@Put('users/:id/mark-student')
@RequirePermission('user:edit')
async markAsStudent(@Param('id') id: string) {
try {
return await this.rbacService.markAsStudent(+id);
} catch (e: unknown) {
const err = e as { message?: string };
throw new BadRequestException(err?.message);
}
}
// ---- 用户资料 ----
@Get('users/:id/profile')
@RequirePermission('user:view')
getUserProfile(@Param('id') id: string) {
return this.rbacService.getUserProfile(+id);
}
@Put('users/:id/profile')
@RequirePermission('user:edit')
async updateUserProfile(
@Param('id') id: string,
@Body() dto: UpdateProfileDto,
@Request() req: any,
) {
const { ipAddress, userAgent } = extractRequestInfo(req);
try {
const result = await this.rbacService.updateUserProfile(+id, dto);
await this.logService.log({
userId: req.user?.id,
username: req.user?.username,
module: '账号',
action: '更新资料',
targetId: +id,
targetType: 'user',
ipAddress,
userAgent,
});
return result;
} catch (e: any) {
throw new BadRequestException(e.message);
}
}
// ---- 教师工作台 ----
@Get('teacher-workspace')
@RequirePermission('teacher-workspace:view')
async getTeacherWorkspace(@Request() req: any) {
return this.rbacService.getTeacherWorkspace(req.user?.id);
}
// ---- 教师管理 ----
@Get('teachers')
@RequirePermission('teacher:view')
async getTeachers(
@Query('search') search?: string,
@Query('page') page?: string,
@Query('pageSize') pageSize?: string,
) {
return this.rbacService.getTeachers({
search,
page: page ? +page : undefined,
pageSize: pageSize ? +pageSize : undefined,
});
}
@Put('teachers/:id/profile')
@RequirePermission('teacher:edit')
async updateTeacherProfile(
@Param('id') id: string,
@Body() profile: UpdateProfileDto,
@Request() req: { user?: { id: number; username: string } },
) {
const { ipAddress, userAgent } = extractRequestInfo(req);
const result = await this.rbacService.updateTeacherProfile(+id, profile);
await this.logService.log({
userId: req.user?.id,
username: req.user?.username,
module: '教师管理',
action: '编辑档案',
targetId: +id,
targetType: 'user',
detail: '更新教师档案',
ipAddress,
userAgent,
});
return result;
}
}