diff --git a/CodePlay.Core/Models/ConversionModels.cs b/CodePlay.Core/Models/ConversionModels.cs index 80d5e09..52f0470 100644 --- a/CodePlay.Core/Models/ConversionModels.cs +++ b/CodePlay.Core/Models/ConversionModels.cs @@ -115,6 +115,26 @@ public class ConversionResult /// public class ConversionReport { + /// + /// 报告 ID + /// + public string Id { get; set; } = Guid.NewGuid().ToString("N")[..20]; + + /// + /// 项目 ID + /// + public string ProjectId { get; set; } = string.Empty; + + /// + /// 源语言 + /// + public LanguageType SourceLanguage { get; set; } + + /// + /// 目标语言 + /// + public LanguageType TargetLanguage { get; set; } + /// /// 转换的行数 /// @@ -135,6 +155,16 @@ public class ConversionReport /// public TimeSpan Duration { get; set; } + /// + /// 问题数量 + /// + public int IssueCount { get; set; } + + /// + /// TODO 数量 + /// + public int TodoCount { get; set; } + /// /// 问题列表 /// @@ -149,6 +179,21 @@ public class ConversionReport /// TODO 列表 /// public List TodoItems { get; set; } = new(); + + /// + /// 验证状态 + /// + public string ValidationStatus { get; set; } = "NotValidated"; + + /// + /// 最后验证时间 + /// + public DateTime? LastValidatedAt { get; set; } + + /// + /// 创建时间 + /// + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; } /// diff --git a/CodePlay.Core/Services/ReportStorageService.cs b/CodePlay.Core/Services/ReportStorageService.cs new file mode 100644 index 0000000..f81353b --- /dev/null +++ b/CodePlay.Core/Services/ReportStorageService.cs @@ -0,0 +1,119 @@ +using System.Collections.Concurrent; +using System.Text.Json; +using CodePlay.Core.Models; +using CodePlay.Core.Common; + +namespace CodePlay.Core.Services; + +/// +/// 转换报告存储服务(内存版 MVP) +/// +public interface IReportStorageService +{ + Task SaveReportAsync(ConversionReport report, string? projectId = null); + Task GetReportAsync(string reportId); + Task> GetReportsByProjectAsync(string projectId); + Task> GetAllReportsAsync(); + Task DeleteReportAsync(string reportId); + Task GetStatisticsAsync(); +} + +public class ReportStorageService : IReportStorageService +{ + private readonly ConcurrentDictionary _reports = new(); + private readonly ConcurrentDictionary _projects = new(); + + public Task SaveReportAsync(ConversionReport report, string? projectId = null) + { + report.Id = Guid.NewGuid().ToString("N")[..20]; + report.ProjectId = projectId ?? "default"; + report.CreatedAt = DateTime.UtcNow; + + _reports[report.Id] = report; + + // 更新项目统计 + if (projectId != null && _projects.ContainsKey(projectId)) + { + _projects[projectId].TotalConversions++; + _projects[projectId].UpdatedAt = DateTime.UtcNow; + } + + return Task.FromResult(report); + } + + public Task GetReportAsync(string reportId) + { + _reports.TryGetValue(reportId, out var report); + return Task.FromResult(report); + } + + public Task> GetReportsByProjectAsync(string projectId) + { + var reports = _reports.Values + .Where(r => r.ProjectId == projectId) + .OrderByDescending(r => r.CreatedAt) + .ToList(); + + return Task.FromResult(reports); + } + + public Task> GetAllReportsAsync() + { + var reports = _reports.Values + .OrderByDescending(r => r.CreatedAt) + .ToList(); + + return Task.FromResult(reports); + } + + public Task DeleteReportAsync(string reportId) + { + _reports.TryRemove(reportId, out _); + return Task.CompletedTask; + } + + public Task GetStatisticsAsync() + { + var reports = _reports.Values.ToList(); + + var statistics = new ConversionStatistics + { + TotalConversions = reports.Count, + TotalProjects = _projects.Count, + ConversionsByLanguage = reports.GroupBy(r => r.TargetLanguage) + .ToDictionary(g => g.Key, g => g.Count()), + AverageLinesConverted = reports.Any() ? reports.Average(r => r.LinesConverted) : 0, + TotalIssuesDetected = reports.Sum(r => r.IssueCount), + TotalTODOs = reports.Sum(r => r.TodoCount) + }; + + return Task.FromResult(statistics); + } +} + +/// +/// 转换统计信息 +/// +public class ConversionStatistics +{ + public int TotalConversions { get; set; } + public int TotalProjects { get; set; } + public Dictionary ConversionsByLanguage { get; set; } = new(); + public double AverageLinesConverted { get; set; } + public int TotalIssuesDetected { get; set; } + public int TotalTODOs { get; set; } +} + +/// +/// 项目信息 +/// +public class ProjectInfo +{ + public string Id { get; set; } = Guid.NewGuid().ToString("N")[..20]; + public string Name { get; set; } = string.Empty; + public string Description { get; set; } = string.Empty; + public List Languages { get; set; } = new(); + public int TotalConversions { get; set; } + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + public DateTime? UpdatedAt { get; set; } +} diff --git a/CodePlay.WebAPI/Controllers/ReportController.cs b/CodePlay.WebAPI/Controllers/ReportController.cs new file mode 100644 index 0000000..894ce4b --- /dev/null +++ b/CodePlay.WebAPI/Controllers/ReportController.cs @@ -0,0 +1,55 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using CodePlay.Core.Services; +using CodePlay.Core.Models; + +namespace CodePlay.WebAPI.Controllers; + +[ApiController] +[Route("api/[controller]")] +[Authorize] +public class ReportController : ControllerBase +{ + private readonly IReportStorageService _storageService; + + public ReportController(IReportStorageService storageService) + { + _storageService = storageService; + } + + [HttpGet] + public async Task>> GetAllReports() + { + var reports = await _storageService.GetAllReportsAsync(); + return Ok(reports); + } + + [HttpGet("{reportId}")] + public async Task> GetReport(string reportId) + { + var report = await _storageService.GetReportAsync(reportId); + if (report == null) return NotFound(); + return Ok(report); + } + + [HttpGet("project/{projectId}")] + public async Task>> GetReportsByProject(string projectId) + { + var reports = await _storageService.GetReportsByProjectAsync(projectId); + return Ok(reports); + } + + [HttpDelete("{reportId}")] + public async Task DeleteReport(string reportId) + { + await _storageService.DeleteReportAsync(reportId); + return NoContent(); + } + + [HttpGet("stats")] + public async Task> GetStatistics() + { + var stats = await _storageService.GetStatisticsAsync(); + return Ok(stats); + } +}