Handler.cs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Microsoft.EntityFrameworkCore;
  4. namespace Application.Features.Api.ChannelTitle.GetMyTitles;
  5. internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response>
  6. {
  7. public async Task<Response> Handle(Query request, CancellationToken ct)
  8. {
  9. var stats = await db.DonorChannelStats.AsNoTracking()
  10. .Where(s => s.DonorMemberID == request.MemberID && s.CumulativeAmount > 0)
  11. .Join(db.Channel.AsNoTracking(), s => s.ChannelID, c => c.ID, (s, c) => new
  12. {
  13. s.ChannelID,
  14. ChannelName = c.Name,
  15. ChannelThumb = c.ThumbnailUrl,
  16. s.CumulativeAmount,
  17. s.DonationCount
  18. })
  19. .ToListAsync(ct);
  20. if (stats.Count == 0)
  21. {
  22. return new Response([]);
  23. }
  24. var channelIds = stats.Select(s => s.ChannelID).ToList();
  25. var titles = await db.ChannelTitle.AsNoTracking()
  26. .Where(t => t.IsActive && channelIds.Contains(t.ChannelID))
  27. .OrderBy(t => t.ChannelID).ThenBy(t => t.MinAmount)
  28. .ToListAsync(ct);
  29. var selections = await db.DonorTitleSelection.AsNoTracking()
  30. .Where(s => s.DonorMemberID == request.MemberID && channelIds.Contains(s.ChannelID))
  31. .ToListAsync(ct);
  32. var groups = stats.Select(stat => {
  33. var selected = selections.FirstOrDefault(s => s.ChannelID == stat.ChannelID);
  34. var channelTitles = titles.Where(t => t.ChannelID == stat.ChannelID).ToList();
  35. var items = channelTitles.Select(t => {
  36. var acquired = stat.CumulativeAmount >= t.MinAmount;
  37. var remaining = Math.Max(0, t.MinAmount - stat.CumulativeAmount);
  38. var isSelected = selected?.SelectedTitleID == t.ID;
  39. return new MyTitleItem(
  40. t.ID,
  41. t.Name,
  42. t.Description,
  43. t.MinAmount,
  44. t.Color,
  45. t.IconUrl,
  46. acquired,
  47. isSelected,
  48. remaining
  49. );
  50. }).ToList();
  51. return new ChannelTitleGroup(
  52. stat.ChannelID,
  53. stat.ChannelName,
  54. stat.ChannelThumb,
  55. stat.CumulativeAmount,
  56. stat.DonationCount,
  57. selected?.SelectedTitleID,
  58. items
  59. );
  60. }).ToList();
  61. return new Response(groups);
  62. }
  63. }