using Admin.NET.Plugin.AiDOP.Dto.S8; using Admin.NET.Plugin.AiDOP.Entity.S8; using Admin.NET.Plugin.AiDOP.Infrastructure; using Admin.NET.Plugin.AiDOP.Infrastructure.S8; namespace Admin.NET.Plugin.AiDOP.Service.S8; /// /// G-06 只读最小问题台账服务。 /// 仅按《G-06 开发清单 最小问题台账》§4.1~§4.3 对 ado_s8_exception 做只读聚合; /// 一异常单一台账条目;不写库、不落缓存、不建独立表;State 仅接受 discovered / processing / closed 或空。 /// public class S8IssueLedgerService : ITransient { private readonly SqlSugarRepository _rep; public S8IssueLedgerService(SqlSugarRepository rep) { _rep = rep; } /// /// 查询台账条目。State 非法、分页越界由 PagingGuard 收敛;State 非法抛 S8BizException。 /// public async Task<(int total, List list)> QueryAsync( AdoS8IssueLedgerQueryDto q) { (q.Page, q.PageSize) = PagingGuard.Normalize(q.Page, q.PageSize, maxPageSize: 100); var statuses = ResolveStatuses(q.State); var query = _rep.AsQueryable() .Where(x => x.TenantId == q.TenantId && x.FactoryId == q.FactoryId) .Where(x => !x.IsDeleted) .Where(x => statuses.Contains(x.Status)) .WhereIF(q.ExceptionId.HasValue, x => x.Id == q.ExceptionId!.Value) .WhereIF(q.BeginTime.HasValue, x => x.CreatedAt >= q.BeginTime!.Value) .WhereIF(q.EndTime.HasValue, x => x.CreatedAt <= q.EndTime!.Value) .OrderBy(x => x.CreatedAt, OrderByType.Desc); var total = await query.CountAsync(); var rows = await query .Skip((q.Page - 1) * q.PageSize) .Take(q.PageSize) .ToListAsync(); var list = rows.Select(x => new AdoS8IssueLedgerItemDto { Id = x.Id, TenantId = x.TenantId, FactoryId = x.FactoryId, SourceType = x.SourceType, State = S8IssueLedgerStates.TryGetShortCode(x.Status) ?? string.Empty, RawStatus = x.Status, CreatedAt = x.CreatedAt, ClosedAt = x.ClosedAt }).ToList(); return (total, list); } // 入参短码 → 主链状态集合: // "discovered" → [NEW] // "processing" → [ASSIGNED, IN_PROGRESS, PENDING_VERIFICATION, ESCALATED, RESOLVED] // "closed" → [CLOSED, REJECTED] // null / 空 → 三档合并(即八个现行主链状态全量) // 其他(含 hold / suspend / pending / all)→ 抛 S8BizException(参数非法) private static IReadOnlyList ResolveStatuses(string? state) { if (string.IsNullOrWhiteSpace(state)) return S8IssueLedgerStates.AllStatuses; var normalized = state.Trim().ToLowerInvariant(); return normalized switch { S8IssueLedgerStates.Discovered => S8IssueLedgerStates.GetStatuses(S8IssueLedgerStates.Discovered), S8IssueLedgerStates.Processing => S8IssueLedgerStates.GetStatuses(S8IssueLedgerStates.Processing), S8IssueLedgerStates.Closed => S8IssueLedgerStates.GetStatuses(S8IssueLedgerStates.Closed), _ => throw new S8BizException("state 仅支持 discovered / processing / closed 或留空") }; } }