Handler.cs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Microsoft.EntityFrameworkCore;
  4. namespace Application.Features.Api.Channel.SearchForOrder;
  5. public sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response>
  6. {
  7. public async Task<Response> Handle(Query request, CancellationToken ct)
  8. {
  9. var query = db.Channel.AsNoTracking()
  10. .Where(c => c.IsActive && c.MemberID != request.MemberID)
  11. .AsQueryable();
  12. if (!string.IsNullOrWhiteSpace(request.Keyword))
  13. {
  14. var kw = request.Keyword.Trim();
  15. var codeKw = kw.ToUpperInvariant();
  16. query = query.Where(c =>
  17. c.Name.Contains(kw)
  18. || (c.Handle != null && c.Handle.Contains(kw))
  19. || (c.DonationCode != null && c.DonationCode == codeKw));
  20. }
  21. var total = await query.CountAsync(ct);
  22. // Random=true 면 SQL NEWID() 로 셔플 — 공평한 노출.
  23. // 그 외는 인증/구독자 수 정렬 (관리자 노출 기준).
  24. var ordered = request.Random
  25. ? query.OrderBy(c => Guid.NewGuid())
  26. : query
  27. .OrderByDescending(c => c.IsVerified)
  28. .ThenByDescending(c => c.SubscriberCount);
  29. var list = await ordered
  30. .Skip((request.Page - 1) * request.PerPage)
  31. .Take(request.PerPage)
  32. .Select(c => new Response.Row(
  33. c.ID,
  34. c.SID,
  35. c.Name,
  36. c.Handle,
  37. c.ThumbnailUrl,
  38. c.SubscriberCount,
  39. c.IsVerified,
  40. c.DonationCode
  41. ))
  42. .ToListAsync(ct);
  43. return new Response(total, list);
  44. }
  45. }