diff --git a/docs/architecture/CLI命令设计.md b/docs/architecture/CLI命令设计.md index 33b374e..d080ed9 100644 --- a/docs/architecture/CLI命令设计.md +++ b/docs/architecture/CLI命令设计.md @@ -11,7 +11,6 @@ | `parse` | 解析日志文件到本地库 | log → local.db | | `aggregate` | 从本地库汇总生成发布库 | local.db → release.db | | `export` | 导出发布库到 CSV | release.db → CSV | -| `stats` | 查询本地库统计信息 | 只读 local.db | | `clean` | 清理本地库数据(软删除) | 只写 local.db | --- @@ -60,26 +59,7 @@ dotnet run export --type qfod --format csv dotnet run export --format json --type qfod ``` -### 2.4 stats - -```bash -# 查看整体统计 -dotnet run stats --summary - -# 按 FOD 类型统计 -dotnet run stats --by-fod-type - -# 按面板统计 -dotnet run stats --by-panel - -# 按硬件版本统计 -dotnet run stats --by-hardware - -# 按 RX 类型统计 -dotnet run stats --by-rx-type -``` - -### 2.5 clean +### 2.4 clean ```bash # 清理指定场景 @@ -97,13 +77,10 @@ dotnet run clean --all --confirm # 1. 解析日志 dotnet run parse --dir ./data/test_input --recursive -# 2. 查看统计 -dotnet run stats --summary - -# 3. 汇总生成发布库 +# 2. 汇总生成发布库 dotnet run aggregate -# 4. 导出正式 CSV +# 3. 导出正式 CSV dotnet run export --output ./data/output ``` diff --git a/docs/architecture/概览.md b/docs/architecture/概览.md index 38ba8c1..2947f1a 100644 --- a/docs/architecture/概览.md +++ b/docs/architecture/概览.md @@ -45,7 +45,7 @@ log 文件 │ Application Layer │ │ ┌───────────────┐ ┌──────────────┐ ┌────────────┐ ┌──────────────┐ │ │ │ LocalIngestion│ │ Publishing │ │ Exporting │ │Administration│ │ -│ │ ParseService │ │AggregationSvc│ │ExportSvc │ │ StatsService │ │ +│ │ ParseService │ │AggregationSvc│ │ExportSvc │ │ CleanService │ │ │ │ ScenarioSvc │ │ThresholdCalc │ │ │ │ CleanService │ │ │ │ DimensionSvc │ │ │ │ │ │ │ │ │ └───────────────┘ └──────────────┘ └────────────┘ └──────────────┘ │ @@ -92,7 +92,6 @@ src/ │ ├── Commands/ # 命令实现 │ │ ├── ParseCommand.cs │ │ ├── AggregateCommand.cs -│ │ ├── StatsCommand.cs │ │ ├── ExportCommand.cs │ │ └── CleanCommand.cs │ ├── Program.cs @@ -115,7 +114,6 @@ src/ │ ├── Exporting/ # 导出 │ │ └── ExportService.cs │ └── Administration/ # 管理 - │ ├── StatsService.cs │ └── CleanService.cs ├── Domain/ # 领域实体 │ └── Models/ diff --git a/docs/architecture/模块划分.md b/docs/architecture/模块划分.md index 4669b04..c8efa7e 100644 --- a/docs/architecture/模块划分.md +++ b/docs/architecture/模块划分.md @@ -58,7 +58,6 @@ | 类 | 职责 | |----|------| -| `StatsService` | 本地库统计查询 | | `CleanService` | 软删除管理 | --- diff --git a/src/Gpulse.WCT.DataAnalyzer.Core/Application/Administration/StatsService.cs b/src/Gpulse.WCT.DataAnalyzer.Core/Application/Administration/StatsService.cs deleted file mode 100644 index 2a3d9a0..0000000 --- a/src/Gpulse.WCT.DataAnalyzer.Core/Application/Administration/StatsService.cs +++ /dev/null @@ -1,142 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Logging; -using Gpulse.WCT.DataAnalyzer.Core.Infrastructure.LocalData; -using Gpulse.WCT.DataAnalyzer.Core.Domain.Local; - -namespace Gpulse.WCT.DataAnalyzer.Core.Application; - -/// -/// 统计查询服务 - 使用数据库端聚合优化内存效率 -/// -public class StatsService -{ - private readonly WctMinerDbContext _context; - private readonly ILogger _logger; - - public StatsService(WctMinerDbContext context, ILogger logger) - { - _context = context; - _logger = logger; - } - - /// - /// 获取整体统计摘要(并行查询优化) - /// - public async Task GetSummaryAsync() - { - // 使用 Task.WhenAll 并行执行多个查询 - var tasks = new[] - { - _context.TestScenarios.CountAsync(), - _context.QfodRecords.CountAsync(), - _context.PlossRecords.CountAsync(), - _context.TxPanels.CountAsync(), - _context.TxHardwares.CountAsync(), - _context.TxSoftwares.CountAsync(), - _context.RxTypes.CountAsync() - }; - - var results = await Task.WhenAll(tasks); - - var summary = new StatsSummary( - results[0], results[1], results[2], - results[3], results[4], results[5], results[6] - ); - - _logger.LogDebug("统计摘要: Scenarios={ScenarioCount}, Qfod={QfodCount}, Ploss={PlossCount}", - summary.ScenarioCount, summary.QfodCount, summary.PlossCount); - - return summary; - } - - /// - /// 按FOD类型统计Qfod记录(数据库端聚合) - /// - public async Task> GetStatsByFodTypeAsync() - { - // 使用数据库端 GroupBy - var stats = await _context.QfodRecords - .GroupBy(r => r.FodType) - .Select(g => new FodTypeStats(g.Key, g.Count())) - .OrderBy(s => s.FodType) - .ToListAsync(); - - _logger.LogDebug("按 FOD 类型统计完成: {Count} 种类型", stats.Count); - return stats; - } - - /// - /// 按面板类型统计(数据库端聚合 - 使用维度表反向统计) - /// - public async Task> GetStatsByPanelAsync() - { - // 方式: 使用维度表反向统计(更高效) - var stats = await _context.TxPanels - .Select(p => new DimensionStats( - p.Name, - p.TestScenarios.Count() - )) - .OrderByDescending(s => s.Count) - .ToListAsync(); - - _logger.LogDebug("按面板类型统计完成: {Count} 种面板", stats.Count); - return stats; - } - - /// - /// 按硬件版本统计(数据库端聚合) - /// - public async Task> GetStatsByHardwareAsync() - { - var stats = await _context.TxHardwares - .Select(h => new DimensionStats( - h.Version, - h.TestScenarios.Count() - )) - .OrderByDescending(s => s.Count) - .ToListAsync(); - - _logger.LogDebug("按硬件版本统计完成: {Count} 种版本", stats.Count); - return stats; - } - - /// - /// 按RX类型统计(数据库端聚合) - /// - public async Task> GetStatsByRxTypeAsync() - { - var stats = await _context.RxTypes - .Select(r => new DimensionStats( - r.Name, - r.TestScenarios.Count() - )) - .OrderByDescending(s => s.Count) - .ToListAsync(); - - _logger.LogDebug("按 RX 类型统计完成: {Count} 种类型", stats.Count); - return stats; - } -} - -/// -/// 整体统计摘要 -/// -public record StatsSummary( - int ScenarioCount, - int QfodCount, - int PlossCount, - int PanelCount, - int HardwareCount, - int SoftwareCount, - int RxTypeCount -); - -/// -/// FOD类型统计 -/// -public record FodTypeStats(byte FodType, int Count); - -/// -/// 维度统计 -/// -public record DimensionStats(string Name, int Count); \ No newline at end of file diff --git a/src/Gpulse.WCT.DataAnalyzer.Core/Infrastructure/Extensions/ServiceCollectionExtensions.cs b/src/Gpulse.WCT.DataAnalyzer.Core/Infrastructure/Extensions/ServiceCollectionExtensions.cs index e26d5e3..0a4c4d4 100644 --- a/src/Gpulse.WCT.DataAnalyzer.Core/Infrastructure/Extensions/ServiceCollectionExtensions.cs +++ b/src/Gpulse.WCT.DataAnalyzer.Core/Infrastructure/Extensions/ServiceCollectionExtensions.cs @@ -54,7 +54,6 @@ public static class ServiceCollectionExtensions services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/src/Gpulse.WCT.DataAnalyzer/Commands/StatsCommand.cs b/src/Gpulse.WCT.DataAnalyzer/Commands/StatsCommand.cs deleted file mode 100644 index 8ac1c98..0000000 --- a/src/Gpulse.WCT.DataAnalyzer/Commands/StatsCommand.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System.CommandLine; -using Gpulse.WCT.DataAnalyzer.Core.Application; - -namespace Gpulse.WCT.DataAnalyzer.Commands; - -/// -/// 统计查询命令 -/// -public class StatsCommand : Command -{ - public StatsCommand(StatsService statsService) - : base("stats", "Query statistics from database") - { - var summaryOption = new Option( - "--summary", - () => false, - "Show overall statistics summary" - ); - - var byFodTypeOption = new Option( - "--by-fod-type", - () => false, - "Show statistics by FOD type" - ); - - var byPanelOption = new Option( - "--by-panel", - () => false, - "Show statistics by TX panel" - ); - - var byHardwareOption = new Option( - "--by-hardware", - () => false, - "Show statistics by TX hardware version" - ); - - var byRxTypeOption = new Option( - "--by-rx-type", - () => false, - "Show statistics by RX type" - ); - - AddOption(summaryOption); - AddOption(byFodTypeOption); - AddOption(byPanelOption); - AddOption(byHardwareOption); - AddOption(byRxTypeOption); - - this.SetHandler(async (summary, byFodType, byPanel, byHardware, byRxType) => - { - // 如果没有指定任何选项,默认显示摘要 - if (!summary && !byFodType && !byPanel && !byHardware && !byRxType) - { - summary = true; - } - - if (summary) - { - var s = await statsService.GetSummaryAsync(); - Console.WriteLine("=== Statistics Summary ==="); - Console.WriteLine($" Scenarios: {s.ScenarioCount}"); - Console.WriteLine($" Qfod Records: {s.QfodCount}"); - Console.WriteLine($" Ploss Records: {s.PlossCount}"); - Console.WriteLine($" TX Panels: {s.PanelCount}"); - Console.WriteLine($" TX Hardware: {s.HardwareCount}"); - Console.WriteLine($" TX Software: {s.SoftwareCount}"); - Console.WriteLine($" RX Types: {s.RxTypeCount}"); - } - - if (byFodType) - { - Console.WriteLine("\n=== By FOD Type ==="); - var stats = await statsService.GetStatsByFodTypeAsync(); - foreach (var s in stats) - { - Console.WriteLine($" FOD Type {s.FodType}: {s.Count}"); - } - } - - if (byPanel) - { - Console.WriteLine("\n=== By TX Panel ==="); - var stats = await statsService.GetStatsByPanelAsync(); - foreach (var s in stats) - { - Console.WriteLine($" {s.Name}: {s.Count}"); - } - } - - if (byHardware) - { - Console.WriteLine("\n=== By TX Hardware ==="); - var stats = await statsService.GetStatsByHardwareAsync(); - foreach (var s in stats) - { - Console.WriteLine($" {s.Name}: {s.Count}"); - } - } - - if (byRxType) - { - Console.WriteLine("\n=== By RX Type ==="); - var stats = await statsService.GetStatsByRxTypeAsync(); - foreach (var s in stats) - { - Console.WriteLine($" {s.Name}: {s.Count}"); - } - } - }, summaryOption, byFodTypeOption, byPanelOption, byHardwareOption, byRxTypeOption); - } -} \ No newline at end of file diff --git a/src/Gpulse.WCT.DataAnalyzer/Program.cs b/src/Gpulse.WCT.DataAnalyzer/Program.cs index 3418911..dbe6a28 100644 --- a/src/Gpulse.WCT.DataAnalyzer/Program.cs +++ b/src/Gpulse.WCT.DataAnalyzer/Program.cs @@ -74,7 +74,6 @@ public class Program rootCommand.AddCommand(new ParseCommand(provider.GetRequiredService())); rootCommand.AddCommand(new AggregateCommand(provider.GetRequiredService())); - rootCommand.AddCommand(new StatsCommand(provider.GetRequiredService())); rootCommand.AddCommand(new ExportCommand(provider.GetRequiredService())); rootCommand.AddCommand(new CleanCommand(provider.GetRequiredService()));