using System.Text.Json; using Admin.NET.Plugin.AiDOP.Dto.S8; using Admin.NET.Plugin.AiDOP.Entity.S8; using Admin.NET.Plugin.AiDOP.Infrastructure; using Microsoft.Extensions.Logging; namespace Admin.NET.Plugin.AiDOP.Service.S8; /// /// S8 通知日志只读查询(S8-NOTIFY-AUDIT-LOG-API-1) /// 仅读 ado_s8_notification_log,不写任何表,不调用 FlowNotifyService。 /// public class S8NotificationLogQueryService : ITransient { private readonly SqlSugarRepository _rep; private readonly ILogger _logger; public S8NotificationLogQueryService( SqlSugarRepository rep, ILogger logger) { _rep = rep; _logger = logger; } public async Task<(int total, List list)> GetPagedAsync(AdoS8NotificationLogQueryDto q) { (q.Page, q.PageSize) = PagingGuard.Normalize(q.Page, q.PageSize); // payload LIKE patterns(System.Text.Json camelCase 序列化,格式稳定) var recoveredPattern = q.Recovered.HasValue ? (q.Recovered.Value ? "\"recovered\":true" : "\"recovered\":false") : null; var successPattern = q.Success.HasValue ? (q.Success.Value ? "\"success\":true" : "\"success\":false") : null; var query = _rep.AsQueryable() .Where(x => x.TenantId == q.TenantId && x.FactoryId == q.FactoryId) .WhereIF(q.ExceptionId.HasValue, x => x.ExceptionId == q.ExceptionId!.Value) .WhereIF(!string.IsNullOrWhiteSpace(q.Channel), x => x.Channel == q.Channel) .WhereIF(recoveredPattern != null, x => x.Payload != null && x.Payload.Contains(recoveredPattern!)) .WhereIF(successPattern != null, x => x.Payload != null && x.Payload.Contains(successPattern!)) .WhereIF(!string.IsNullOrWhiteSpace(q.Keyword), x => (x.Payload != null && x.Payload.Contains(q.Keyword!)) || x.Channel.Contains(q.Keyword!)) .WhereIF(q.CreatedAtStart.HasValue, x => x.CreatedAt >= q.CreatedAtStart!.Value) .WhereIF(q.CreatedAtEnd.HasValue, x => x.CreatedAt <= q.CreatedAtEnd!.Value); var total = await query.CountAsync(); var rows = await query .OrderBy(x => x.CreatedAt, OrderByType.Desc) .OrderBy(x => x.Id, OrderByType.Desc) .ToPageListAsync(q.Page, q.PageSize); var list = rows.Select(x => MapToDto(x)).ToList(); return (total, list); } private AdoS8NotificationLogListItemDto MapToDto(AdoS8NotificationLog x) { var dto = new AdoS8NotificationLogListItemDto { Id = x.Id, TenantId = x.TenantId, FactoryId = x.FactoryId, ExceptionId = x.ExceptionId, Channel = x.Channel, Payload = x.Payload, CreatedAt = x.CreatedAt, }; if (string.IsNullOrWhiteSpace(x.Payload)) return dto; try { using var doc = JsonDocument.Parse(x.Payload); var root = doc.RootElement; if (root.TryGetProperty("success", out var sv) && (sv.ValueKind == JsonValueKind.True || sv.ValueKind == JsonValueKind.False)) dto.Success = sv.GetBoolean(); if (root.TryGetProperty("recovered", out var rv) && (rv.ValueKind == JsonValueKind.True || rv.ValueKind == JsonValueKind.False)) dto.Recovered = rv.GetBoolean(); if (root.TryGetProperty("targetCount", out var tc) && tc.ValueKind == JsonValueKind.Number) dto.TargetCount = tc.GetInt32(); if (root.TryGetProperty("error", out var ev) && ev.ValueKind == JsonValueKind.String) dto.ErrorMessage = ev.GetString(); } catch (Exception ex) { _logger.LogWarning(ex, "S8NotificationLogQuery: payload parse failed for id={Id}", x.Id); } return dto; } }