diff --git a/server/src/assessment/assessment.controller.ts b/server/src/assessment/assessment.controller.ts index 827d0bc..59f51f4 100644 --- a/server/src/assessment/assessment.controller.ts +++ b/server/src/assessment/assessment.controller.ts @@ -306,11 +306,11 @@ export class AssessmentController { } @Get(':id/export/pdf') - @ApiOperation({ summary: 'Export assessment to PDF' }) + @ApiOperation({ summary: 'Export assessment to HTML report' }) async exportPdf(@Param('id') sessionId: string) { const buffer = await this.exportService.exportToPdf(sessionId); return { - filename: `assessment-${sessionId}.pdf`, + filename: `assessment-${sessionId}.html`, buffer: buffer.toString('base64'), }; } diff --git a/server/src/assessment/services/export.service.ts b/server/src/assessment/services/export.service.ts index 8c7a62b..1e3adae 100644 --- a/server/src/assessment/services/export.service.ts +++ b/server/src/assessment/services/export.service.ts @@ -143,68 +143,47 @@ export class ExportService { throw new Error('Session not found'); } - const certificate = await this.certificateRepository.findOne({ + const cert = await this.certificateRepository.findOne({ where: { sessionId }, }); - const questions = await this.questionRepository.find({ - where: { sessionId }, - order: { createdAt: 'ASC' }, - }); - - const answers = await this.answerRepository.find({ - where: { questionId: In(questions.map((q) => q.id)) }, - }); - - const answerMap = new Map(answers.map((a) => [a.questionId, a])); - - const detailLines: string[] = []; - for (let i = 0; i < questions.length; i++) { - const q = questions[i]; - const a = answerMap.get(q.id); - detailLines.push(`Q${i + 1}: ${q.questionText || '-'}`); - detailLines.push(` A: ${a?.userAnswer || '-'}`); - detailLines.push(` Score: ${a?.score ?? '-'}`); - detailLines.push(` Feedback: ${a?.feedback || '-'}`); - } - - const certificateLines: string[] = []; - if (certificate) { - certificateLines.push(`Level: ${certificate.level}`); - certificateLines.push(`Total Score: ${certificate.totalScore}`); - certificateLines.push(`Passed: ${certificate.passed ? 'Yes' : 'No'}`); - certificateLines.push(`Issued: ${certificate.issuedAt ? new Date(certificate.issuedAt).toLocaleString() : '-'}`); - } + const questions = (session.questions_json || []) as any[]; const userName = session.user?.displayName || session.user?.username || session.userId; + const templateName = session.template?.name || session.templateJson?.name || '-'; + const dimensionScores = (session as any).dimensionScores || {}; - return generateAssessmentPdf({ - title: 'Assessment Report', - subtitle: `${userName} — ${new Date(session.createdAt).toLocaleDateString()}`, - sections: [ - { - title: 'Summary', - lines: [ - `Session: ${session.id}`, - `User: ${userName}`, - `Status: ${session.status}`, - `Score: ${session.finalScore ?? '-'}`, - `Template: ${session.template?.name || session.templateJson?.name || '-'}`, - ], - }, - ...(certificate ? [{ - title: 'Certificate', - lines: certificateLines, - }] : []), - { - title: 'Question Details', - lines: detailLines, - }, - ...(session.finalReport ? [{ - title: 'Final Report', - lines: [session.finalReport], - }] : []), - ], + let dimRows = ''; + for (const [dim, score] of Object.entries(dimensionScores)) { + dimRows += `
${userName} — ${new Date(session.createdAt).toLocaleDateString()}
+Template: ${templateName}
+${session.finalScore ?? '-'}/10
+${(session as any).passed ? 'PASSED' : 'FAILED'}
+${cert ? `Level: ${cert.level}
` : ''} +| # | Question | Type | Dimension |
|---|
${session.finalReport}` : ''}
+`;
+
+ return Buffer.from(html, 'utf-8');
}
}
\ No newline at end of file
diff --git a/server/src/assessment/services/pdf-generator.ts b/server/src/assessment/services/pdf-generator.ts
index fef869e..f1bbcca 100644
--- a/server/src/assessment/services/pdf-generator.ts
+++ b/server/src/assessment/services/pdf-generator.ts
@@ -3,9 +3,9 @@ import * as path from 'path';
import { PDFDocument, rgb, StandardFonts, PageSizes } from 'pdf-lib';
const FONT_SEARCH_PATHS = [
+ 'C:/Windows/Fonts/NotoSansSC-VF.ttf',
+ 'C:/Windows/Fonts/NotoSansJP-VF.ttf',
path.join(__dirname, '..', '..', '..', 'assets', 'fonts', 'NotoSansSC-VF.ttf'),
- 'C:/Windows/Fonts/msyh.ttf',
- 'C:/Windows/Fonts/simsun.ttf',
'/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc',
];
diff --git a/web/components/views/AssessmentView.tsx b/web/components/views/AssessmentView.tsx
index f3516d9..11d4ae3 100644
--- a/web/components/views/AssessmentView.tsx
+++ b/web/components/views/AssessmentView.tsx
@@ -923,13 +923,9 @@ export const AssessmentView: React.FC