S8NotificationLogQueryService.cs 4.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. using System.Text.Json;
  2. using Admin.NET.Plugin.AiDOP.Dto.S8;
  3. using Admin.NET.Plugin.AiDOP.Entity.S8;
  4. using Admin.NET.Plugin.AiDOP.Infrastructure;
  5. using Microsoft.Extensions.Logging;
  6. namespace Admin.NET.Plugin.AiDOP.Service.S8;
  7. /// <summary>
  8. /// S8 通知日志只读查询(S8-NOTIFY-AUDIT-LOG-API-1)
  9. /// 仅读 ado_s8_notification_log,不写任何表,不调用 FlowNotifyService。
  10. /// </summary>
  11. public class S8NotificationLogQueryService : ITransient
  12. {
  13. private readonly SqlSugarRepository<AdoS8NotificationLog> _rep;
  14. private readonly ILogger<S8NotificationLogQueryService> _logger;
  15. public S8NotificationLogQueryService(
  16. SqlSugarRepository<AdoS8NotificationLog> rep,
  17. ILogger<S8NotificationLogQueryService> logger)
  18. {
  19. _rep = rep;
  20. _logger = logger;
  21. }
  22. public async Task<(int total, List<AdoS8NotificationLogListItemDto> list)> GetPagedAsync(AdoS8NotificationLogQueryDto q)
  23. {
  24. (q.Page, q.PageSize) = PagingGuard.Normalize(q.Page, q.PageSize);
  25. // payload LIKE patterns(System.Text.Json camelCase 序列化,格式稳定)
  26. var recoveredPattern = q.Recovered.HasValue
  27. ? (q.Recovered.Value ? "\"recovered\":true" : "\"recovered\":false")
  28. : null;
  29. var successPattern = q.Success.HasValue
  30. ? (q.Success.Value ? "\"success\":true" : "\"success\":false")
  31. : null;
  32. var query = _rep.AsQueryable()
  33. .Where(x => x.TenantId == q.TenantId && x.FactoryId == q.FactoryId)
  34. .WhereIF(q.ExceptionId.HasValue, x => x.ExceptionId == q.ExceptionId!.Value)
  35. .WhereIF(!string.IsNullOrWhiteSpace(q.Channel), x => x.Channel == q.Channel)
  36. .WhereIF(recoveredPattern != null, x => x.Payload != null && x.Payload.Contains(recoveredPattern!))
  37. .WhereIF(successPattern != null, x => x.Payload != null && x.Payload.Contains(successPattern!))
  38. .WhereIF(!string.IsNullOrWhiteSpace(q.Keyword),
  39. x => (x.Payload != null && x.Payload.Contains(q.Keyword!)) || x.Channel.Contains(q.Keyword!))
  40. .WhereIF(q.CreatedAtStart.HasValue, x => x.CreatedAt >= q.CreatedAtStart!.Value)
  41. .WhereIF(q.CreatedAtEnd.HasValue, x => x.CreatedAt <= q.CreatedAtEnd!.Value);
  42. var total = await query.CountAsync();
  43. var rows = await query
  44. .OrderBy(x => x.CreatedAt, OrderByType.Desc)
  45. .OrderBy(x => x.Id, OrderByType.Desc)
  46. .ToPageListAsync(q.Page, q.PageSize);
  47. var list = rows.Select(x => MapToDto(x)).ToList();
  48. return (total, list);
  49. }
  50. private AdoS8NotificationLogListItemDto MapToDto(AdoS8NotificationLog x)
  51. {
  52. var dto = new AdoS8NotificationLogListItemDto
  53. {
  54. Id = x.Id,
  55. TenantId = x.TenantId,
  56. FactoryId = x.FactoryId,
  57. ExceptionId = x.ExceptionId,
  58. Channel = x.Channel,
  59. Payload = x.Payload,
  60. CreatedAt = x.CreatedAt,
  61. };
  62. if (string.IsNullOrWhiteSpace(x.Payload)) return dto;
  63. try
  64. {
  65. using var doc = JsonDocument.Parse(x.Payload);
  66. var root = doc.RootElement;
  67. if (root.TryGetProperty("success", out var sv) && (sv.ValueKind == JsonValueKind.True || sv.ValueKind == JsonValueKind.False))
  68. dto.Success = sv.GetBoolean();
  69. if (root.TryGetProperty("recovered", out var rv) && (rv.ValueKind == JsonValueKind.True || rv.ValueKind == JsonValueKind.False))
  70. dto.Recovered = rv.GetBoolean();
  71. if (root.TryGetProperty("targetCount", out var tc) && tc.ValueKind == JsonValueKind.Number)
  72. dto.TargetCount = tc.GetInt32();
  73. if (root.TryGetProperty("error", out var ev) && ev.ValueKind == JsonValueKind.String)
  74. dto.ErrorMessage = ev.GetString();
  75. }
  76. catch (Exception ex)
  77. {
  78. _logger.LogWarning(ex, "S8NotificationLogQuery: payload parse failed for id={Id}", x.Id);
  79. }
  80. return dto;
  81. }
  82. }