Handler.cs 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Domain.Entities.Store.ValueObject;
  4. using Microsoft.EntityFrameworkCore;
  5. namespace Application.Features.Api.Member.Items.List;
  6. internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response>
  7. {
  8. public async Task<Response> Handle(Query request, CancellationToken ct)
  9. {
  10. var now = DateTime.UtcNow;
  11. var query = db.MemberItem.AsNoTracking()
  12. .Include(i => i.Product)
  13. .Where(i => i.MemberID == request.MemberID && i.RevokedAt == null);
  14. if (!request.IncludeUsed)
  15. {
  16. query = query.Where(i => i.UsedAt == null);
  17. }
  18. if (!request.IncludeExpired)
  19. {
  20. query = query.Where(i => i.ExpiresAt == null || i.ExpiresAt > now);
  21. }
  22. if (request.ConsumableOnly)
  23. {
  24. query = query.Where(i => i.Kind >= ItemKind.ChatBanLift);
  25. }
  26. var total = await query.CountAsync(ct);
  27. var list = await query
  28. .OrderByDescending(i => i.ID)
  29. .Skip((request.Page - 1) * request.PerPage)
  30. .Take(request.PerPage)
  31. .Select(i => new Response.Row(
  32. i.ID,
  33. i.ProductID,
  34. i.Product!.Name,
  35. i.Product.Thumbnail,
  36. i.Kind,
  37. i.EquipSlot,
  38. i.IsEquipped,
  39. i.EquipSlot != null,
  40. i.Product.EffectPayload,
  41. i.DurationDays,
  42. i.AcquiredAt,
  43. i.ExpiresAt,
  44. i.UsedAt,
  45. i.GiftFromMemberID,
  46. i.GiftFromMemberID == null ? null : db.Member.Where(m => m.ID == i.GiftFromMemberID).Select(m => m.Name).FirstOrDefault()
  47. ))
  48. .ToListAsync(ct);
  49. return new Response(total, list);
  50. }
  51. }