Handler.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. using Application.Abstractions.Messaging;
  2. using Application.Abstractions.Data;
  3. using Application.Abstractions.Cache;
  4. using Microsoft.EntityFrameworkCore;
  5. namespace Application.Features.Api.Banner.Item.GetByCode;
  6. public sealed class Handler(IAppDbContext db, ICacheService cache) : IQueryHandler<Query, Response>
  7. {
  8. private static readonly TimeSpan ActiveCacheTtl = TimeSpan.FromMinutes(10);
  9. public async Task<Response> Handle(Query request, CancellationToken ct)
  10. {
  11. var cacheKey = request.OnlyActive ? CacheKeys.BannerByCodeActive(request.Code) : CacheKeys.BannerByCode(request.Code);
  12. var cached = await cache.GetAsync<Response>(cacheKey, ct);
  13. if (cached is not null)
  14. {
  15. return cached;
  16. }
  17. var position = await db.BannerPosition.AsNoTracking().FirstOrDefaultAsync(c => c.Code == request.Code, ct);
  18. if (position is null)
  19. {
  20. return new Response(0, []);
  21. }
  22. var query = db.BannerItem.AsNoTracking().Include(c => c.BannerPosition).Where(c => c.PositionID == position.ID);
  23. if (request.OnlyActive)
  24. {
  25. var now = DateTime.UtcNow;
  26. query = query.Where(c => c.IsActive && (c.StartAt == null || c.StartAt <= now) && (c.EndAt == null || c.EndAt > now));
  27. }
  28. var total = await query.CountAsync(ct);
  29. var list = await query
  30. .OrderBy(c => c.Order)
  31. .ThenByDescending(c => c.ID)
  32. .Select(c => new
  33. {
  34. c.ID,
  35. c.PositionID,
  36. PositionCode = c.BannerPosition.Code,
  37. PositionSubject = c.BannerPosition.Subject,
  38. c.Subject,
  39. c.DesktopImage,
  40. c.MobileImage,
  41. c.Link,
  42. c.LinkTarget,
  43. c.Order,
  44. c.IsActive,
  45. c.StartAt,
  46. c.EndAt,
  47. c.UpdatedAt,
  48. c.CreatedAt
  49. })
  50. .ToListAsync(ct);
  51. var response = new Response(
  52. total,
  53. [..list.Select(c => new Response.Row(
  54. c.ID,
  55. c.PositionID,
  56. c.PositionCode,
  57. c.PositionSubject,
  58. c.Subject,
  59. c.DesktopImage,
  60. c.MobileImage,
  61. c.Link,
  62. c.LinkTarget,
  63. c.Order,
  64. c.IsActive,
  65. c.StartAt,
  66. c.EndAt,
  67. c.UpdatedAt,
  68. c.CreatedAt
  69. ))]
  70. );
  71. if (request.OnlyActive)
  72. {
  73. await cache.SetAsync(cacheKey, response, ActiveCacheTtl, ct);
  74. }
  75. else
  76. {
  77. await cache.SetAsync(cacheKey, response, ct);
  78. }
  79. return response;
  80. }
  81. }