Handler.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Domain.Entities.Store.ValueObject;
  4. using Microsoft.EntityFrameworkCore;
  5. namespace Application.Features.Admin.Store.Product.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.Product.AsNoTracking().Include(c => c.Game).AsQueryable();
  11. if (request.GameID.HasValue)
  12. {
  13. query = query.Where(c => c.GameID == request.GameID.Value);
  14. }
  15. if (request.Type.HasValue)
  16. {
  17. query = query.Where(c => c.Type == request.Type.Value);
  18. }
  19. if (request.IsActive.HasValue)
  20. {
  21. query = query.Where(c => c.IsActive == request.IsActive.Value);
  22. }
  23. if (!string.IsNullOrWhiteSpace(request.Keyword))
  24. {
  25. var kw = request.Keyword.Trim();
  26. query = request.Search switch
  27. {
  28. 1 => int.TryParse(kw, out var id) ? query.Where(c => c.ID == id) : query.Where(c => false),
  29. _ => query.Where(c => c.Name.Contains(kw))
  30. };
  31. }
  32. if (DateTime.TryParse(request.StartAt, out var startAt))
  33. {
  34. query = query.Where(c => c.CreatedAt >= startAt);
  35. }
  36. if (DateTime.TryParse(request.EndAt, out var endAt))
  37. {
  38. query = query.Where(c => c.CreatedAt <= endAt);
  39. }
  40. var total = await query.CountAsync(ct);
  41. var list = await query
  42. .OrderBy(c => c.Order)
  43. .ThenByDescending(c => c.ID)
  44. .Skip((request.Page - 1) * request.PerPage)
  45. .Take(request.PerPage)
  46. .Select(c => new
  47. {
  48. c.ID,
  49. c.GameID,
  50. GameName = c.Game!.KorName,
  51. c.Name,
  52. c.Thumbnail,
  53. c.Type,
  54. c.Price,
  55. c.DiscountType,
  56. c.DiscountValue,
  57. c.Stock,
  58. c.IsActive,
  59. c.Order,
  60. c.SaleStartAt,
  61. c.SaleEndAt,
  62. c.UpdatedAt,
  63. c.CreatedAt
  64. })
  65. .ToListAsync(ct);
  66. var startNum = total - ((request.Page - 1) * request.PerPage);
  67. return new Response(
  68. total,
  69. [.. list.Select((c, i) => {
  70. var salePrice = c.DiscountType switch
  71. {
  72. DiscountType.Percent => Math.Max(0, c.Price - (c.Price * c.DiscountValue / 100)),
  73. DiscountType.Amount => Math.Max(0, c.Price - c.DiscountValue),
  74. _ => c.Price
  75. };
  76. return new Response.Row(
  77. Num: startNum - i,
  78. c.ID,
  79. c.GameID ?? 0,
  80. c.GameName,
  81. c.Name,
  82. c.Thumbnail,
  83. c.Type,
  84. c.Price,
  85. c.DiscountType,
  86. c.DiscountValue,
  87. salePrice,
  88. c.Stock,
  89. c.IsActive,
  90. c.Order,
  91. c.SaleStartAt,
  92. c.SaleEndAt,
  93. c.UpdatedAt,
  94. c.CreatedAt
  95. );
  96. })]
  97. );
  98. }
  99. }