fix: 代码整合修复 - Entity类型、题库生成、评估流程等14项修复

This commit is contained in:
Developer
2026-05-14 09:55:07 +08:00
parent 122ab5e96f
commit 368eddfd75
17 changed files with 1666 additions and 115 deletions
+104 -11
View File
@@ -6,13 +6,17 @@ import {
Param,
UseGuards,
Request,
Req,
Sse,
MessageEvent,
Query,
Delete,
Put,
ForbiddenException,
} from '@nestjs/common';
import { map } from 'rxjs/operators';
import { AssessmentService } from './assessment.service';
import { ExportService } from './services/export.service';
import { CombinedAuthGuard } from '../auth/combined-auth.guard';
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
@@ -20,7 +24,10 @@ import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
@Controller('assessment')
@UseGuards(CombinedAuthGuard)
export class AssessmentController {
constructor(private readonly assessmentService: AssessmentService) {}
constructor(
private readonly assessmentService: AssessmentService,
private readonly exportService: ExportService,
) {}
@Post('start')
@ApiOperation({ summary: 'Start a new assessment session' })
@@ -102,16 +109,6 @@ export class AssessmentController {
return this.assessmentService.getSessionState(sessionId, userId);
}
@Get()
@ApiOperation({ summary: 'Get assessment session history' })
async getHistory(@Request() req: any) {
const { id: userId, tenantId } = req.user;
console.log(
`[AssessmentController] getHistory: user=${userId}, tenant=${tenantId}`,
);
return this.assessmentService.getHistory(userId, tenantId);
}
@Delete(':id')
@ApiOperation({ summary: 'Delete an assessment session' })
async deleteSession(@Request() req: any, @Param('id') sessionId: string) {
@@ -135,6 +132,23 @@ export class AssessmentController {
return this.assessmentService.generateCertificate(sessionId, userId, tenantId);
}
@Get('certificate/verify/:certificateId')
@ApiOperation({ summary: 'Verify certificate by ID (public)' })
@UseGuards()
async verifyCertificate(
@Param('certificateId') certificateId: string,
) {
return this.assessmentService.verifyCertificate(certificateId);
}
@Get('certificate/public/:sessionId')
@ApiOperation({ summary: 'Get public certificate info for verification' })
async getPublicCertificate(
@Param('sessionId') sessionId: string,
) {
return this.assessmentService.getPublicCertificateInfo(sessionId);
}
@Get('history')
@ApiOperation({ summary: 'Get current user assessment history (keep latest 3)' })
async getHistory(
@@ -168,6 +182,38 @@ export class AssessmentController {
);
}
@Get('stats/radar')
@ApiOperation({ summary: 'Get radar chart data for dimension scores' })
async getRadarStats(
@Request() req: any,
@Query('templateId') templateId?: string,
) {
const { id: userId, tenantId, role } = req.user;
return this.assessmentService.getRadarStats(
userId,
tenantId,
role,
templateId,
);
}
@Get('stats/trend')
@ApiOperation({ summary: 'Get trend data for scores over time' })
async getTrendStats(
@Request() req: any,
@Query('startDate') startDate?: string,
@Query('endDate') endDate?: string,
) {
const { id: userId, tenantId, role } = req.user;
return this.assessmentService.getTrendStats(
userId,
tenantId,
role,
startDate,
endDate,
);
}
@Put(':id/review')
@ApiOperation({ summary: 'Review assessment - adjust final score' })
async review(
@@ -184,4 +230,51 @@ export class AssessmentController {
tenantId,
);
}
@Get(':id/time-check')
@ApiOperation({ summary: 'Check assessment time limits' })
async checkTimeLimits(@Param('id') sessionId: string) {
return this.assessmentService.checkTimeLimits(sessionId);
}
@Post(':id/next-question')
@ApiOperation({ summary: 'Start timing for next question' })
async nextQuestion(@Param('id') sessionId: string) {
await this.assessmentService.updateQuestionStartTime(sessionId);
return { success: true };
}
@Post(':id/force-end')
@ApiOperation({ summary: 'Force end assessment (admin only)' })
async forceEnd(
@Param('id') sessionId: string,
@Request() req: any,
) {
const { role } = req.user;
const isAdmin = role === 'super_admin' || role === 'admin';
if (!isAdmin) {
throw new ForbiddenException('Only admin can force end assessment');
}
return this.assessmentService.forceEndAssessment(sessionId);
}
@Get(':id/export/excel')
@ApiOperation({ summary: 'Export assessment to Excel' })
async exportExcel(@Param('id') sessionId: string) {
const buffer = await this.exportService.exportToExcel(sessionId);
return {
filename: `assessment-${sessionId}.xlsx`,
buffer: buffer.toString('base64'),
};
}
@Get(':id/export/pdf')
@ApiOperation({ summary: 'Export assessment to PDF (text format)' })
async exportPdf(@Param('id') sessionId: string) {
const buffer = await this.exportService.exportToPdf(sessionId);
return {
filename: `assessment-${sessionId}.txt`,
content: buffer.toString('utf-8'),
};
}
}