Handler.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using SharedKernel.Results;
  4. using Domain.Entities.Donations;
  5. using Microsoft.EntityFrameworkCore;
  6. namespace Application.Features.Api.DonationRank.SaveConfig;
  7. internal sealed class Handler(IAppDbContext db) : ICommandHandler<Command, Result>
  8. {
  9. public async Task<Result> Handle(Command r, CancellationToken ct)
  10. {
  11. // 같은 기간 타입 동시 활성 검증
  12. if (r.IsActive)
  13. {
  14. if (r.Period == Domain.Entities.Donations.ValueObject.RankPeriodType.Custom
  15. && r.StartAt.HasValue && r.EndAt.HasValue)
  16. {
  17. // 사용자 지정: 기간 겹침 검증
  18. var overlap = await db.DonationRankConfig
  19. .AnyAsync(c => c.ChannelID == r.ChannelID
  20. && c.IsActive
  21. && c.ID != (r.ID ?? 0)
  22. && c.Period == Domain.Entities.Donations.ValueObject.RankPeriodType.Custom
  23. && c.StartAt != null && c.EndAt != null
  24. && c.StartAt < r.EndAt && c.EndAt > r.StartAt, ct);
  25. if (overlap)
  26. {
  27. return Result.Failure(Error.Conflict("DonationRank.PeriodOverlap", "해당 기간에 이미 활성화된 순위 설정이 존재합니다."));
  28. }
  29. }
  30. else
  31. {
  32. // 고정 기간(일간/주간/월간/연간/전체): 같은 타입 1개만
  33. var duplicate = await db.DonationRankConfig
  34. .AnyAsync(c => c.ChannelID == r.ChannelID
  35. && c.IsActive
  36. && c.ID != (r.ID ?? 0)
  37. && c.Period == r.Period, ct);
  38. if (duplicate)
  39. {
  40. return Result.Failure(Error.Conflict("DonationRank.DuplicatePeriod", "같은 기간 유형의 활성화된 순위 설정이 이미 존재합니다."));
  41. }
  42. }
  43. }
  44. if (r.ID.HasValue)
  45. {
  46. var config = await db.DonationRankConfig
  47. .FirstOrDefaultAsync(c => c.ID == r.ID.Value && c.ChannelID == r.ChannelID, ct);
  48. if (config is null)
  49. {
  50. return Result.Failure(Error.NotFound("DonationRank.NotFound", "설정을 찾을 수 없습니다."));
  51. }
  52. config.Update(
  53. r.Title, r.Theme, r.Period,
  54. r.StartAt, r.EndAt,
  55. r.IsShowAmount, r.MaxRankCount, r.NameMode, r.IsActive,
  56. r.TitleFontFamily, r.TitleFontSizePx, r.TitleFontColor,
  57. r.NameDisplayType,
  58. r.IsShowDonationCount, r.IsShowGradeIcon, r.IsShowMemberIcon,
  59. r.Rank1FontFamily, r.Rank1FontSizePx, r.Rank1FontColor,
  60. r.Rank2FontFamily, r.Rank2FontSizePx, r.Rank2FontColor,
  61. r.Rank3FontFamily, r.Rank3FontSizePx, r.Rank3FontColor
  62. );
  63. }
  64. else
  65. {
  66. var config = DonationRankConfig.Create(
  67. r.ChannelID, r.MemberID, r.Title,
  68. r.Theme, r.Period,
  69. r.StartAt, r.EndAt,
  70. r.IsShowAmount, r.MaxRankCount, r.NameMode, r.IsActive,
  71. r.TitleFontFamily, r.TitleFontSizePx, r.TitleFontColor,
  72. r.NameDisplayType,
  73. r.IsShowDonationCount, r.IsShowGradeIcon, r.IsShowMemberIcon,
  74. r.Rank1FontFamily, r.Rank1FontSizePx, r.Rank1FontColor,
  75. r.Rank2FontFamily, r.Rank2FontSizePx, r.Rank2FontColor,
  76. r.Rank3FontFamily, r.Rank3FontSizePx, r.Rank3FontColor
  77. );
  78. db.DonationRankConfig.Add(config);
  79. }
  80. await db.SaveChangesAsync(ct);
  81. return Result.Success();
  82. }
  83. }