using Admin.NET.Plugin.AiDOP.Dto.S8; using Admin.NET.Plugin.AiDOP.Entity.S8; using Admin.NET.Plugin.AiDOP.Infrastructure.S8; namespace Admin.NET.Plugin.AiDOP.Service.S8; public class S8MonitoringService : ITransient { private readonly SqlSugarRepository _rep; public S8MonitoringService(SqlSugarRepository rep) { _rep = rep; } /// /// 异常监控汇总:按 module_code 分组统计红/黄/绿/超时数。 /// 供综合全景页顶部徽标和模块汇总表使用。 /// public async Task GetSummaryAsync(AdoS8MonitoringSummaryQueryDto q) { var query = _rep.AsQueryable() .Where(e => e.TenantId == q.TenantId && e.FactoryId == q.FactoryId && !e.IsDeleted) .WhereIF(!string.IsNullOrWhiteSpace(q.SceneCode), e => e.SceneCode == q.SceneCode) .WhereIF(!string.IsNullOrWhiteSpace(q.ModuleCode), e => e.ModuleCode == q.ModuleCode) .WhereIF(q.BizDateFrom.HasValue, e => e.CreatedAt >= q.BizDateFrom!.Value) .WhereIF(q.BizDateTo.HasValue, e => e.CreatedAt <= q.BizDateTo!.Value); // 聚合到内存(数据量在可控范围内,避免复杂 GROUP BY 兼容性问题) var raw = await query .Select(e => new { e.ModuleCode, e.SceneCode, e.Severity, e.TimeoutFlag, e.Status }) .ToListAsync(); var byModule = raw .GroupBy(e => new { mc = e.ModuleCode ?? string.Empty, sc = e.SceneCode ?? string.Empty }) .Select(g => new AdoS8ModuleSummaryItem { ModuleCode = g.Key.mc, ModuleLabel = S8ModuleCode.Label(g.Key.mc), SceneCode = g.Key.sc, SceneLabel = S8SceneCode.Label(g.Key.sc), Total = g.Count(), Red = g.Count(e => e.Severity == "CRITICAL" || e.Severity == "HIGH"), Yellow = g.Count(e => e.Severity == "MEDIUM"), Green = g.Count(e => e.Severity == "LOW"), Timeout = g.Count(e => e.TimeoutFlag && e.Status != "CLOSED") }) // 按 S8ModuleCode.All 顺序排列 .OrderBy(r => Array.IndexOf(S8ModuleCode.All, r.ModuleCode)) .ToList(); return new AdoS8MonitoringSummaryDto { Total = raw.Count, Red = raw.Count(e => e.Severity == "CRITICAL" || e.Severity == "HIGH"), Yellow = raw.Count(e => e.Severity == "MEDIUM"), Green = raw.Count(e => e.Severity == "LOW"), Timeout = raw.Count(e => e.TimeoutFlag && e.Status != "CLOSED"), ByModule = byModule }; } }