Handler.cs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Domain.Entities.Wallets.Policy;
  4. using Microsoft.EntityFrameworkCore;
  5. using SharedKernel.Results;
  6. namespace Application.Features.Api.MyPage.Dropdown;
  7. public sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Result<Response>>
  8. {
  9. public async Task<Result<Response>> Handle(Query request, CancellationToken ct)
  10. {
  11. var member = await db.Member.AsNoTracking()
  12. .Where(m => m.ID == request.MemberID)
  13. .Select(m => new { m.SID, m.Name, m.Thumb, m.IsCreator })
  14. .FirstOrDefaultAsync(ct);
  15. if (member is null)
  16. {
  17. return Result.Failure<Response>(Error.NotFound("Member.NotFound", "회원을 찾을 수 없습니다."));
  18. }
  19. // 후원 가능 잔액 (SpendPolicy 순서의 잔액 합산)
  20. var spendableBalance = 0m;
  21. var wallet = await db.Wallet.AsNoTracking()
  22. .Include(w => w.Balances)
  23. .FirstOrDefaultAsync(w => w.MemberID == request.MemberID, ct);
  24. if (wallet is not null)
  25. {
  26. foreach (var balanceType in SpendPolicy.DefaultSpendOrder)
  27. {
  28. var balance = wallet.Balances.FirstOrDefault(b => b.Type == balanceType);
  29. if (balance is not null)
  30. {
  31. spendableBalance += balance.Amount.Value;
  32. }
  33. }
  34. }
  35. // 채널 조회
  36. int? channelID = null;
  37. decimal? withdrawableBalance = null;
  38. var channel = await db.Channel.AsNoTracking()
  39. .FirstOrDefaultAsync(c => c.MemberID == request.MemberID && c.IsActive, ct);
  40. if (channel is not null)
  41. {
  42. channelID = channel.ID;
  43. if (wallet is not null)
  44. {
  45. var donationBalance = wallet.Balances
  46. .FirstOrDefault(b => b.Type == Domain.Entities.Wallets.ValueObject.WalletBalanceType.Donation);
  47. withdrawableBalance = donationBalance?.Amount.Value ?? 0;
  48. }
  49. }
  50. return new Response(
  51. member.SID,
  52. member.Name,
  53. member.Thumb,
  54. member.IsCreator,
  55. channelID,
  56. (int)spendableBalance,
  57. withdrawableBalance.HasValue ? (int)withdrawableBalance.Value : null
  58. );
  59. }
  60. }