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;
}
}