CounterDroneBackend/src/CounterDrone.Core/Services/ReportService.cs
tian 8a198a27a0 新增 LaunchPlatformSpec:发射平台与探测设备分离
- LaunchPlatformSpec(纯发射参数,无探测字段)
- ScenarioUnit.FireUnitSpecId → LaunchPlatformSpecId
- PlatformEntity/BuildFireUnits/BuildDetectionSources 适配
- ReportGenerator/ReportService 适配
- FireUnitSpec 保留但不使用
- 243/250 通过,7 个待修
2026-06-19 21:43:06 +08:00

103 lines
3.9 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using CounterDrone.Core.Models;
using SQLite;
using CounterDrone.Core.Simulation;
namespace CounterDrone.Core.Services
{
public class ReportService : IReportService
{
private readonly SQLiteConnection _db;
private readonly ReportGenerator _generator = new();
private readonly IPathProvider _paths;
public ReportService(SQLiteConnection db, IPathProvider paths)
{
_db = db;
_paths = paths;
}
public SimulationReport Generate(string scenarioId, ScenarioConfig config,
List<SimEvent> events, string finalDroneStatus, float duration)
{
var droneSpecs = _db.Table<DroneSpec>().ToDictionary(d => d.Id);
var fireUnitSpecs = _db.Table<LaunchPlatformSpec>().ToDictionary(f => f.Id);
var sensorSpecs = _db.Table<SensorSpec>().ToDictionary(s => s.Id);
var destroyed = events.Count(e => e.Type == SimEventType.DroneDestroyed);
var reached = events.Count(e => e.Type == SimEventType.DroneReachedTarget);
var intruded = events.Count(e => e.Type == SimEventType.ZoneIntruded);
var total = config.Drones.Sum(t => t.Quantity);
var result = _generator.DetermineInterceptResult(destroyed, reached + intruded, total);
var report = new SimulationReport
{
ScenarioId = scenarioId,
ScenarioName = config.Info.Name,
ScenarioNumber = config.Info.ScenarioNumber,
CompletedAt = DateTime.UtcNow.ToString("o"),
DroneCount = total,
UnitCount = config.Units.Count,
InterceptResult = (int)result,
Content = _generator.Generate(config, events, Simulation.DroneStatus.Flying, duration,
droneSpecs, fireUnitSpecs, sensorSpecs),
};
_db.Insert(report);
return report;
}
public SimulationReport GetReport(string id)
{
return _db.Find<SimulationReport>(id);
}
public void DeleteReport(string id)
{
_db.Delete<SimulationReport>(id);
}
public PagedResult<SimulationReport> SearchReports(string keyword, string? dateFrom, string? dateTo, int page, int pageSize)
{
if (page < 1) page = 1;
if (pageSize < 1) pageSize = 10;
var offset = (page - 1) * pageSize;
var query = _db.Table<SimulationReport>().AsQueryable();
if (!string.IsNullOrWhiteSpace(keyword))
query = query.Where(r => r.ScenarioName.Contains(keyword) || r.ScenarioNumber.Contains(keyword));
if (!string.IsNullOrWhiteSpace(dateFrom))
query = query.Where(r => r.CompletedAt.CompareTo(dateFrom) >= 0);
if (!string.IsNullOrWhiteSpace(dateTo))
query = query.Where(r => r.CompletedAt.CompareTo(dateTo) <= 0);
var total = query.Count();
var items = query.OrderByDescending(r => r.CompletedAt).Skip(offset).Take(pageSize).ToList();
return new PagedResult<SimulationReport>
{
Items = items,
TotalCount = total,
Page = page,
PageSize = pageSize,
};
}
public string ExportToFile(string reportId, string outputDir)
{
var report = _db.Find<SimulationReport>(reportId);
if (report == null) throw new ArgumentException($"报告 {reportId} 不存在");
Directory.CreateDirectory(outputDir);
var safeTime = DateTime.UtcNow.ToString("yyyyMMdd_HHmmss");
var fileName = $"{report.ScenarioName}_{safeTime}.md";
var filePath = Path.Combine(outputDir, fileName);
File.WriteAllText(filePath, report.Content);
return filePath;
}
}
}