forked from wangziqi/gongxue-base
feat: add exam score management
This commit is contained in:
104
apps/server/src/exams/exams.controller.ts
Normal file
104
apps/server/src/exams/exams.controller.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Get,
|
||||
Param,
|
||||
ParseIntPipe,
|
||||
Post,
|
||||
Put,
|
||||
Query,
|
||||
Request,
|
||||
UseGuards,
|
||||
UsePipes,
|
||||
ValidationPipe,
|
||||
} from '@nestjs/common';
|
||||
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
|
||||
import { RequirePermission } from '../auth/decorators/permission.decorator';
|
||||
import { extractRequestInfo } from '../common/request-utils';
|
||||
import { OperationLogsService } from '../operation-logs/operation-logs.service';
|
||||
import type { AuthenticatedUser } from '../authorization';
|
||||
import { CreateExamDto, QueryExamDto, UpdateExamScoreValueDto } from './dto/exam.dto';
|
||||
import { ExamsService } from './exams.service';
|
||||
|
||||
interface AuthenticatedRequest {
|
||||
user: AuthenticatedUser;
|
||||
ip?: string;
|
||||
headers?: Record<string, string | string[] | undefined>;
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@UsePipes(new ValidationPipe({ transform: true, whitelist: true, forbidNonWhitelisted: true }))
|
||||
@Controller('exams')
|
||||
export class ExamsController {
|
||||
constructor(
|
||||
private readonly service: ExamsService,
|
||||
private readonly logService: OperationLogsService,
|
||||
) {}
|
||||
|
||||
private canManageAll(req: AuthenticatedRequest) {
|
||||
return req.user.isSuperAdmin || req.user.permissions.includes('exam:edit');
|
||||
}
|
||||
|
||||
@Get()
|
||||
@RequirePermission('exam:view')
|
||||
async findAll(@Query() query: QueryExamDto, @Request() req: AuthenticatedRequest) {
|
||||
const classIds = await this.service.getAccessibleClassIds(req.user.id, this.canManageAll(req));
|
||||
return this.service.findAll(query, classIds);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@RequirePermission('exam:view')
|
||||
findOne(@Param('id', ParseIntPipe) id: number, @Request() req: AuthenticatedRequest) {
|
||||
return this.service.findOne(id, req.user.id, this.canManageAll(req));
|
||||
}
|
||||
|
||||
@Post()
|
||||
@RequirePermission('exam:view')
|
||||
async create(@Body() dto: CreateExamDto, @Request() req: AuthenticatedRequest) {
|
||||
const result = await this.service.create(dto, req.user.id, this.canManageAll(req));
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
await this.logService.log({
|
||||
userId: req.user.id,
|
||||
username: req.user.username,
|
||||
module: '考试管理',
|
||||
action: '创建考试',
|
||||
targetId: result.id,
|
||||
targetType: 'exam',
|
||||
detail: `${dto.examName} - ${dto.subject}`,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@Put(':examId/scores/:scoreId')
|
||||
@RequirePermission('exam:view')
|
||||
async updateScore(
|
||||
@Param('examId', ParseIntPipe) examId: number,
|
||||
@Param('scoreId', ParseIntPipe) scoreId: number,
|
||||
@Body() dto: UpdateExamScoreValueDto,
|
||||
@Request() req: AuthenticatedRequest,
|
||||
) {
|
||||
const result = await this.service.updateScore(
|
||||
examId,
|
||||
scoreId,
|
||||
dto.score,
|
||||
req.user.id,
|
||||
this.canManageAll(req),
|
||||
);
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
await this.logService.log({
|
||||
userId: req.user.id,
|
||||
username: req.user.username,
|
||||
module: '考试管理',
|
||||
action: dto.score === null || dto.score === undefined ? '清空成绩' : '录入成绩',
|
||||
targetId: scoreId,
|
||||
targetType: 'exam_score',
|
||||
detail: dto.score === null || dto.score === undefined ? '成绩已清空' : `成绩:${dto.score}`,
|
||||
ipAddress,
|
||||
userAgent,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user