Index.cshtml.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. using SharedKernel.Extensions;
  2. using SharedKernel.Helpers;
  3. using Application.Abstractions.Messaging;
  4. using Microsoft.AspNetCore.Mvc;
  5. using Microsoft.AspNetCore.Mvc.RazorPages;
  6. using System.ComponentModel;
  7. using System.ComponentModel.DataAnnotations;
  8. namespace Admin.Pages.Store.Coupon;
  9. public class IndexModel(IMediator mediator) : PageModel
  10. {
  11. [BindProperty(SupportsGet = true)]
  12. public QueryParams Query { get; set; } = new();
  13. public List<(int ID, string Name)> Games { get; set; } = [];
  14. public sealed class QueryParams
  15. {
  16. [Range(1, int.MaxValue)]
  17. public int PageNum { get; set; } = 1;
  18. [Range(1, 100)]
  19. public ushort PerPage { get; set; } = 20;
  20. [DisplayName("게임")]
  21. public int? GameID { get; set; }
  22. [DisplayName("검색어")]
  23. public string? Keyword { get; set; }
  24. }
  25. public int Total { get; set; }
  26. public List<(
  27. int Num,
  28. int ID,
  29. string ProductName,
  30. string GameName,
  31. string Name,
  32. string UsagePolicyText,
  33. string? ExpiresAt,
  34. int GeneratedCount,
  35. int UsedCount,
  36. int AvailableCount,
  37. int LowStockThreshold,
  38. bool IsLowStock,
  39. string CreatedAt,
  40. string EditURL,
  41. string CodesURL
  42. )> List { get; set; } = [];
  43. public Pagination? Pagination { get; set; }
  44. public async Task OnGetAsync(CancellationToken ct)
  45. {
  46. if (!ModelState.IsValid)
  47. {
  48. return;
  49. }
  50. var gamesResult = await mediator.Send(new GetGames.Query(false), ct);
  51. Games = [.. gamesResult.List.Select(g => (ID: g.ID, Name: g.KorName))];
  52. var result = await mediator.Send(new SearchCoupons.Query(Query.GameID, null, Query.Keyword, Query.PageNum, Query.PerPage), ct);
  53. Total = result.Total;
  54. List = [.. result.List.Select(c => (
  55. c.Num,
  56. c.ID,
  57. c.ProductName,
  58. c.GameName,
  59. c.Name,
  60. UsagePolicyText: c.UsagePolicy == Domain.Entities.Store.ValueObject.CouponUsagePolicy.SingleUse ? "1회 사용" : "재사용",
  61. c.ExpiresAt?.ToString("yyyy-MM-dd"),
  62. c.GeneratedCount,
  63. c.UsedCount,
  64. c.AvailableCount,
  65. c.LowStockThreshold,
  66. c.IsLowStock,
  67. c.CreatedAt.GetDateAt(),
  68. EditURL: $"/Store/Coupon/Edit/{c.ID}{Request.QueryString}",
  69. CodesURL: $"/Store/Coupon/Codes/{c.ID}{Request.QueryString}"
  70. ))];
  71. Pagination = new Pagination(result.Total, Query.PageNum, Query.PerPage);
  72. }
  73. public async Task<IActionResult> OnPostDeleteAsync(int[] ids, CancellationToken ct)
  74. {
  75. if (ids is null || ids.Length == 0)
  76. {
  77. TempData["ErrorMessages"] = "삭제할 쿠폰을 선택해 주세요.";
  78. return RedirectToPage("/Store/Coupon/Index", Query);
  79. }
  80. var result = await mediator.Send(new DeleteCoupon.Command(ids), ct);
  81. if (result.IsFailure)
  82. {
  83. TempData["ErrorMessages"] = result.Error.Description;
  84. }
  85. else
  86. {
  87. TempData["SuccessMessage"] = $"{ids.Length}개 쿠폰이 삭제되었습니다.";
  88. }
  89. return RedirectToPage("/Store/Coupon/Index", Query);
  90. }
  91. }