Handler.cs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. using Application.Abstractions.Messaging;
  2. using Application.Abstractions.Data;
  3. using Application.Abstractions.Cache;
  4. using Application.Abstractions.Crypto;
  5. using Microsoft.EntityFrameworkCore;
  6. namespace Application.Features.Api.Crypto.Ticker.GetAll;
  7. public sealed class Handler(IAppDbContext db, ICacheService cache) : IQueryHandler<Query, Response>
  8. {
  9. public async Task<Response> Handle(Query request, CancellationToken ct)
  10. {
  11. var quote = string.IsNullOrWhiteSpace(request.Quote) ? "KRW" : request.Quote.ToUpper();
  12. // Redis에서 Ticker 목록 가져오기
  13. var tickers = await cache.GetAsync<List<UpbitTicker>>(CacheKeys.CryptoTickers(quote), ct) ?? [];
  14. var tickerMap = tickers.ToDictionary(t => t.Market, t => t);
  15. // DB에서 CoinMarket + Coin 정보 가져오기
  16. var prefix = $"{quote}-";
  17. var query = db.CoinMarket.AsNoTracking().Include(cm => cm.Coin).Where(cm => cm.Market.StartsWith(prefix) && cm.Coin.IsActive && !cm.Coin.IsDelisted);
  18. if (request.FeaturedOnly)
  19. {
  20. query = query.Where(cm => cm.Coin.IsFeatured);
  21. }
  22. var coinMarkets = await query.OrderByDescending(cm => cm.Coin.IsFeatured).ThenBy(cm => cm.Coin.DisplayOrder).ThenBy(cm => cm.Coin.Symbol).Select(cm => new { cm.Market, cm.Coin.Symbol, cm.Coin.KorName, cm.Coin.EngName, cm.Coin.LogoImage, cm.Coin.IsFeatured, cm.Coin.DisplayOrder }).ToListAsync(ct);
  23. var rows = new List<Response.Row>();
  24. foreach (var cm in coinMarkets)
  25. {
  26. tickerMap.TryGetValue(cm.Market, out var ticker);
  27. rows.Add(new Response.Row(
  28. cm.Market,
  29. cm.Symbol,
  30. cm.KorName,
  31. cm.EngName,
  32. cm.LogoImage,
  33. ticker?.OpeningPrice ?? 0m,
  34. ticker?.HighPrice ?? 0m,
  35. ticker?.LowPrice ?? 0m,
  36. ticker?.TradePrice ?? 0m,
  37. ticker?.PrevClosingPrice ?? 0m,
  38. ticker?.Change ?? "",
  39. ticker?.ChangePrice ?? 0m,
  40. ticker?.SignedChangePrice ?? 0m,
  41. ticker?.ChangeRate ?? 0m,
  42. ticker?.SignedChangeRate ?? 0m,
  43. ticker?.TradeVolume ?? 0m,
  44. ticker?.AccTradeVolume ?? 0m,
  45. ticker?.AccTradeVolume24h ?? 0m,
  46. ticker?.AccTradePrice ?? 0m,
  47. ticker?.AccTradePrice24h ?? 0m,
  48. cm.IsFeatured,
  49. cm.DisplayOrder
  50. ));
  51. }
  52. return new Response(rows);
  53. }
  54. }