| | | 1 | | using System; |
| | | 2 | | using System.Collections.Generic; |
| | | 3 | | using System.IO; |
| | | 4 | | using System.Linq; |
| | | 5 | | using CounterDrone.Core.Models; |
| | | 6 | | using SQLite; |
| | | 7 | | using SimEvent = CounterDrone.Core.Simulation.SimEvent; |
| | | 8 | | |
| | | 9 | | namespace CounterDrone.Core.Services |
| | | 10 | | { |
| | | 11 | | public class ReportService : IReportService |
| | | 12 | | { |
| | | 13 | | private readonly SQLiteConnection _db; |
| | 5 | 14 | | private readonly ReportGenerator _generator = new(); |
| | | 15 | | private readonly IPathProvider _paths; |
| | | 16 | | |
| | 5 | 17 | | public ReportService(SQLiteConnection db, IPathProvider paths) |
| | 5 | 18 | | { |
| | 5 | 19 | | _db = db; |
| | 5 | 20 | | _paths = paths; |
| | 5 | 21 | | } |
| | | 22 | | |
| | | 23 | | public SimulationReport Generate(string taskId, TaskFullConfig config, |
| | | 24 | | List<SimEvent> events, string finalDroneStatus, float duration) |
| | 6 | 25 | | { |
| | 33 | 26 | | var destroyed = events.Count(e => e.Type == SimEventType.DroneDestroyed); |
| | 33 | 27 | | var reached = events.Count(e => e.Type == SimEventType.DroneReachedTarget); |
| | 33 | 28 | | var intruded = events.Count(e => e.Type == SimEventType.ZoneIntruded); |
| | 12 | 29 | | var total = config.Targets.Sum(t => t.Quantity); |
| | 6 | 30 | | var result = _generator.DetermineInterceptResult(destroyed, reached + intruded, total); |
| | | 31 | | |
| | 6 | 32 | | var report = new SimulationReport |
| | 6 | 33 | | { |
| | 6 | 34 | | TaskId = taskId, |
| | 6 | 35 | | TaskName = config.Task.Name, |
| | 6 | 36 | | TaskNumber = config.Task.TaskNumber, |
| | 6 | 37 | | CompletedAt = DateTime.UtcNow.ToString("o"), |
| | 6 | 38 | | TargetCount = total, |
| | 6 | 39 | | EquipmentCount = config.Equipment.Count, |
| | 6 | 40 | | InterceptResult = (int)result, |
| | 6 | 41 | | Content = _generator.Generate(config, events, Simulation.DroneStatus.Flying, duration), |
| | 6 | 42 | | }; |
| | | 43 | | |
| | 6 | 44 | | _db.Insert(report); |
| | 6 | 45 | | return report; |
| | 6 | 46 | | } |
| | | 47 | | |
| | | 48 | | public SimulationReport GetReport(string id) |
| | 2 | 49 | | { |
| | 2 | 50 | | return _db.Find<SimulationReport>(id); |
| | 2 | 51 | | } |
| | | 52 | | |
| | | 53 | | public void DeleteReport(string id) |
| | 1 | 54 | | { |
| | 1 | 55 | | _db.Delete<SimulationReport>(id); |
| | 1 | 56 | | } |
| | | 57 | | |
| | | 58 | | public PagedResult<SimulationReport> SearchReports(string keyword, string? dateFrom, string? dateTo, int page, i |
| | 1 | 59 | | { |
| | 1 | 60 | | if (page < 1) page = 1; |
| | 1 | 61 | | if (pageSize < 1) pageSize = 10; |
| | 1 | 62 | | var offset = (page - 1) * pageSize; |
| | | 63 | | |
| | 1 | 64 | | var query = _db.Table<SimulationReport>().AsQueryable(); |
| | 1 | 65 | | if (!string.IsNullOrWhiteSpace(keyword)) |
| | 1 | 66 | | query = query.Where(r => r.TaskName.Contains(keyword) || r.TaskNumber.Contains(keyword)); |
| | 1 | 67 | | if (!string.IsNullOrWhiteSpace(dateFrom)) |
| | 0 | 68 | | query = query.Where(r => r.CompletedAt.CompareTo(dateFrom) >= 0); |
| | 1 | 69 | | if (!string.IsNullOrWhiteSpace(dateTo)) |
| | 0 | 70 | | query = query.Where(r => r.CompletedAt.CompareTo(dateTo) <= 0); |
| | | 71 | | |
| | 1 | 72 | | var total = query.Count(); |
| | 1 | 73 | | var items = query.OrderByDescending(r => r.CompletedAt).Skip(offset).Take(pageSize).ToList(); |
| | | 74 | | |
| | 1 | 75 | | return new PagedResult<SimulationReport> |
| | 1 | 76 | | { |
| | 1 | 77 | | Items = items, TotalCount = total, Page = page, PageSize = pageSize, |
| | 1 | 78 | | }; |
| | 1 | 79 | | } |
| | | 80 | | |
| | | 81 | | public string ExportToFile(string reportId, string outputDir) |
| | 2 | 82 | | { |
| | 2 | 83 | | var report = _db.Find<SimulationReport>(reportId); |
| | 2 | 84 | | if (report == null) throw new ArgumentException($"报告 {reportId} 不存在"); |
| | | 85 | | |
| | 2 | 86 | | Directory.CreateDirectory(outputDir); |
| | 2 | 87 | | var safeTime = DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"); |
| | 2 | 88 | | var fileName = $"{report.TaskName}_{safeTime}.md"; |
| | 2 | 89 | | var filePath = Path.Combine(outputDir, fileName); |
| | 2 | 90 | | File.WriteAllText(filePath, report.Content); |
| | 2 | 91 | | return filePath; |
| | 2 | 92 | | } |
| | | 93 | | } |
| | | 94 | | } |