Handler.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Domain.Entities.Common.ValueObject;
  4. using Microsoft.EntityFrameworkCore;
  5. namespace Application.Features.Admin.Mail.Search;
  6. public sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response>
  7. {
  8. public async Task<Response> Handle(Query request, CancellationToken ct)
  9. {
  10. var query = db.EmailLog.AsNoTracking().AsQueryable();
  11. if (!string.IsNullOrWhiteSpace(request.Keyword))
  12. {
  13. var keyword = request.Keyword.Trim();
  14. query = request.Search switch
  15. {
  16. 1 => long.TryParse(keyword, out var id) ? query.Where(x => x.ID == id) : query.Where(x => false),
  17. 2 => query.Where(x => x.ToAddress.Contains(keyword)),
  18. 3 => query.Where(x => x.Subject.Contains(keyword)),
  19. 4 => query.Where(x => x.Category != null && x.Category.Contains(keyword)),
  20. _ => query
  21. };
  22. }
  23. if (!string.IsNullOrWhiteSpace(request.StartAt) && DateTime.TryParse(request.StartAt, out var startAt))
  24. {
  25. query = query.Where(x => x.CreatedAt >= startAt);
  26. }
  27. if (!string.IsNullOrWhiteSpace(request.EndAt) && DateTime.TryParse(request.EndAt, out var endAt))
  28. {
  29. query = query.Where(x => x.CreatedAt <= endAt);
  30. }
  31. // 탭별 건수 집계 (탭 필터 적용 전)
  32. var counts = await query.GroupBy(c => 1).Select(c => new
  33. {
  34. Pending = c.Count(x => x.Status == MailStatus.Pending),
  35. Processing = c.Count(x => x.Status == MailStatus.Processing),
  36. Sent = c.Count(x => x.Status == MailStatus.Sent),
  37. Failed = c.Count(x => x.Status == MailStatus.Failed)
  38. }).FirstOrDefaultAsync(ct);
  39. var pendingCount = counts?.Pending ?? 0;
  40. var processingCount = counts?.Processing ?? 0;
  41. var sentCount = counts?.Sent ?? 0;
  42. var failedCount = counts?.Failed ?? 0;
  43. query = request.Tab switch
  44. {
  45. 1 => query.Where(x => x.Status == MailStatus.Pending),
  46. 2 => query.Where(x => x.Status == MailStatus.Processing),
  47. 3 => query.Where(x => x.Status == MailStatus.Sent),
  48. 4 => query.Where(x => x.Status == MailStatus.Failed),
  49. _ => query
  50. };
  51. var total = await query.CountAsync(ct);
  52. var skip = (request.Page - 1) * request.PerPage;
  53. var list = await query
  54. .OrderByDescending(x => x.ID)
  55. .Skip(skip)
  56. .Take(request.PerPage)
  57. .Select(x => new
  58. {
  59. x.ID,
  60. x.ToAddress,
  61. x.Subject,
  62. x.Status,
  63. x.RetryCount,
  64. x.MaxRetryCount,
  65. x.NextRetryAt,
  66. x.LastError,
  67. x.Category,
  68. x.CreatedAt,
  69. x.ProcessedAt,
  70. x.FailedAt
  71. })
  72. .ToListAsync(ct);
  73. var rows = list.Select((x, idx) => new Response.Row
  74. {
  75. Num = total - skip - idx,
  76. ID = x.ID,
  77. ToAddress = x.ToAddress,
  78. Subject = x.Subject,
  79. Status = (byte)x.Status,
  80. StatusName = x.Status.ToString(),
  81. RetryCount = x.RetryCount,
  82. MaxRetryCount = x.MaxRetryCount,
  83. NextRetryAt = x.NextRetryAt,
  84. LastError = x.LastError,
  85. Category = x.Category,
  86. CreatedAt = x.CreatedAt,
  87. ProcessedAt = x.ProcessedAt,
  88. FailedAt = x.FailedAt
  89. }).ToList();
  90. return new Response
  91. {
  92. Total = total,
  93. Pending = pendingCount,
  94. Processing = processingCount,
  95. Sent = sentCount,
  96. Failed = failedCount,
  97. List = rows
  98. };
  99. }
  100. }