326 lines
8.7 KiB
TypeScript
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;
|
|
}
|
|
}
|