Change report download from JSON to PDF

- Add GenerateSingleReport() method to PdfReportService for individual CV reports
- PDF includes: score header, employment verification table, timeline analysis,
  gaps/overlaps sections, and color-coded flags (critical/warning/info)
- Update Report.razor to use PdfReportService instead of JSON serialization
- Add TrueCV.Web.Services to _Imports.razor

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-20 22:49:22 +01:00
parent 1a53431757
commit a6b24d2c64
3 changed files with 210 additions and 53 deletions

View File

@@ -9,6 +9,7 @@
@inject ILogger<Report> Logger
@inject IJSRuntime JSRuntime
@inject IAuditService AuditService
@inject PdfReportService PdfReportService
<PageTitle>Verification Report - TrueCV</PageTitle>
@@ -603,58 +604,11 @@
try
{
var reportData = new
{
CandidateName = _check.OriginalFileName,
GeneratedAt = _report.GeneratedAt,
OverallScore = _report.OverallScore,
ScoreLabel = _report.ScoreLabel,
EmploymentVerifications = _report.EmploymentVerifications.Select(v => new
{
v.ClaimedCompany,
ClaimedStartDate = v.ClaimedStartDate?.ToString("yyyy-MM"),
ClaimedEndDate = v.ClaimedEndDate?.ToString("yyyy-MM"),
v.MatchedCompanyName,
v.MatchedCompanyNumber,
v.MatchScore,
v.IsVerified,
v.VerificationNotes
}),
TimelineAnalysis = new
{
_report.TimelineAnalysis.TotalGapMonths,
_report.TimelineAnalysis.TotalOverlapMonths,
Gaps = _report.TimelineAnalysis.Gaps.Select(g => new
{
StartDate = g.StartDate.ToString("yyyy-MM"),
EndDate = g.EndDate.ToString("yyyy-MM"),
g.Months
}),
Overlaps = _report.TimelineAnalysis.Overlaps.Select(o => new
{
o.Company1,
o.Company2,
OverlapStart = o.OverlapStart.ToString("yyyy-MM"),
OverlapEnd = o.OverlapEnd.ToString("yyyy-MM"),
o.Months
})
},
Flags = _report.Flags.Select(f => new
{
f.Severity,
f.Title,
f.Description,
f.ScoreImpact
})
};
var candidateName = Path.GetFileNameWithoutExtension(_check.OriginalFileName);
var pdfBytes = PdfReportService.GenerateSingleReport(candidateName, _report);
var json = System.Text.Json.JsonSerializer.Serialize(reportData, new System.Text.Json.JsonSerializerOptions
{
WriteIndented = true
});
var fileName = $"TrueCV_Report_{Path.GetFileNameWithoutExtension(_check.OriginalFileName)}_{DateTime.Now:yyyyMMdd}.json";
await DownloadFileAsync(fileName, json, "application/json");
var fileName = $"TrueCV_Report_{candidateName}_{DateTime.Now:yyyyMMdd}.pdf";
await DownloadFileAsync(fileName, pdfBytes, "application/pdf");
}
catch (Exception ex)
{
@@ -662,9 +616,8 @@
}
}
private async Task DownloadFileAsync(string fileName, string content, string contentType)
private async Task DownloadFileAsync(string fileName, byte[] bytes, string contentType)
{
var bytes = System.Text.Encoding.UTF8.GetBytes(content);
var base64 = Convert.ToBase64String(bytes);
await JSRuntime.InvokeVoidAsync("downloadFile", fileName, base64, contentType);
}

View File

@@ -14,6 +14,7 @@
@using TrueCV.Web
@using TrueCV.Web.Components
@using TrueCV.Web.Components.Shared
@using TrueCV.Web.Services
@using TrueCV.Application.Interfaces
@using TrueCV.Application.DTOs
@using TrueCV.Application.Models