|
|
@@ -30,17 +30,24 @@ public class S8DashboardService : ITransient
|
|
|
_processNodeRep = processNodeRep;
|
|
|
}
|
|
|
|
|
|
- public async Task<object> GetOverviewAsync(long tenantId, long factoryId, DateTime? beginTime = null, DateTime? endTime = null, string? severity = null)
|
|
|
+ public async Task<object> GetOverviewAsync(long tenantId, long factoryId, DateTime? beginTime = null, DateTime? endTime = null, string? severity = null, string? period = null)
|
|
|
{
|
|
|
// 看板顶部的"开始/结束日期"通过 beginTime/endTime 透传,与列表的 beginTime/endTime 同语义。
|
|
|
// BUG-12:补 severity 过滤,与异常列表 API 的 severity 口径一致(精确匹配 LOW/MEDIUM/HIGH/CRITICAL)。
|
|
|
// BUG-22:REJECTED 状态归入 pending 桶,避免从总数视角"消失";与列表 statusBucket="pending" 同步对齐。
|
|
|
// S8-DASHBOARD-DATA-ALIGN-S1S7-1:统一只统计 module_code IN S1-S7;NULL module 的 legacy 行不参与看板 KPI。
|
|
|
+ // 显式日期范围优先;未传时从 period 解析。
|
|
|
+ var (periodFrom, periodTo) = (!beginTime.HasValue && !endTime.HasValue)
|
|
|
+ ? S8PeriodHelper.Resolve(period)
|
|
|
+ : ((DateTime?)null, (DateTime?)null);
|
|
|
+ var effectiveFrom = beginTime ?? periodFrom;
|
|
|
+ var effectiveTo = endTime ?? periodTo;
|
|
|
+
|
|
|
var q = _rep.AsQueryable()
|
|
|
.Where(x => x.TenantId == tenantId && x.FactoryId == factoryId && !x.IsDeleted)
|
|
|
.Where(x => S8ModuleCode.All.Contains(x.ModuleCode))
|
|
|
- .WhereIF(beginTime.HasValue, x => x.CreatedAt >= beginTime!.Value)
|
|
|
- .WhereIF(endTime.HasValue, x => x.CreatedAt <= endTime!.Value)
|
|
|
+ .WhereIF(effectiveFrom.HasValue, x => x.CreatedAt >= effectiveFrom!.Value)
|
|
|
+ .WhereIF(effectiveTo.HasValue, x => x.CreatedAt < effectiveTo!.Value)
|
|
|
.WhereIF(!string.IsNullOrWhiteSpace(severity), x => x.Severity == severity);
|
|
|
var total = await q.CountAsync();
|
|
|
var pending = await q.CountAsync(x => x.Status == "NEW" || x.Status == "ASSIGNED" || x.Status == "IN_PROGRESS" || x.Status == "PENDING_VERIFICATION" || x.Status == "REJECTED");
|
|
|
@@ -85,11 +92,15 @@ public class S8DashboardService : ITransient
|
|
|
.ToList();
|
|
|
}
|
|
|
|
|
|
- public async Task<object> GetDistributionsAsync(long tenantId, long factoryId)
|
|
|
+ public async Task<object> GetDistributionsAsync(long tenantId, long factoryId, string? period = null)
|
|
|
{
|
|
|
+ var (periodFrom, periodTo) = S8PeriodHelper.Resolve(period);
|
|
|
+
|
|
|
var list = await _rep.AsQueryable()
|
|
|
.Where(x => x.TenantId == tenantId && x.FactoryId == factoryId && !x.IsDeleted)
|
|
|
.Where(x => S8ModuleCode.All.Contains(x.ModuleCode))
|
|
|
+ .WhereIF(periodFrom.HasValue, x => x.CreatedAt >= periodFrom!.Value)
|
|
|
+ .WhereIF(periodTo.HasValue, x => x.CreatedAt < periodTo!.Value)
|
|
|
.Select(x => new
|
|
|
{
|
|
|
x.Status,
|
|
|
@@ -176,14 +187,17 @@ public class S8DashboardService : ITransient
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- public async Task<object> GetDeptBacklogAsync(long tenantId, long factoryId)
|
|
|
+ public async Task<object> GetDeptBacklogAsync(long tenantId, long factoryId, string? period = null)
|
|
|
{
|
|
|
var pendingStatuses = new[] { "NEW", "ASSIGNED", "IN_PROGRESS" };
|
|
|
+ var (periodFrom, periodTo) = S8PeriodHelper.Resolve(period);
|
|
|
|
|
|
// S8-SLA-TIMEOUT-RUNTIME-1(P3):投影 SlaDeadline 替代 TimeoutFlag;timeout 由内存计算(与 GetSummaryAsync 一致 now)。
|
|
|
var list = await _rep.AsQueryable()
|
|
|
.Where(x => x.TenantId == tenantId && x.FactoryId == factoryId && !x.IsDeleted)
|
|
|
.Where(x => S8ModuleCode.All.Contains(x.ModuleCode))
|
|
|
+ .WhereIF(periodFrom.HasValue, x => x.CreatedAt >= periodFrom!.Value)
|
|
|
+ .WhereIF(periodTo.HasValue, x => x.CreatedAt < periodTo!.Value)
|
|
|
.Select(x => new { x.ResponsibleDeptId, x.Status, x.SlaDeadline })
|
|
|
.ToListAsync();
|
|
|
var nowForTimeout = DateTime.Now;
|