using SharedKernel.Extensions; using SharedKernel.Helpers; using Application.Abstractions.Messaging; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using System.ComponentModel; using System.ComponentModel.DataAnnotations; namespace Admin.Pages.Store.Game; public class IndexModel(IMediator mediator) : PageModel { [BindProperty(SupportsGet = true)] public QueryParams Query { get; set; } = new(); public sealed class QueryParams { [Range(1, int.MaxValue)] [DisplayName("페이지 번호")] public int PageNum { get; set; } = 1; [Range(1, 100)] [DisplayName("페이지 목록 수")] public ushort PerPage { get; set; } = 20; [DisplayName("검색 조건")] [Range(1, 5, ErrorMessage = "{0}이(가) 올바르지 않습니다.")] public int? Search { get; set; } [DisplayName("검색어")] [MaxLength(100, ErrorMessage = "{0}은(는) {1}자 이하로 입력하세요.")] public string? Keyword { get; set; } [DisplayName("시작일")] public string? StartAt { get; set; } [DisplayName("종료일")] public string? EndAt { get; set; } [DisplayName("활성화")] public int? IsActive { get; set; } } public int Total { get; set; } public List<( int Num, int ID, string? Code, string KorName, string? EngName, string Publisher, string? Thumbnail, decimal CommissionRate, string? Link, char IsActive, int Order, int ProductCount, string? UpdatedAt, string CreatedAt, string EditURL )> List { get; set; } = []; public Pagination? Pagination { get; set; } public async Task OnGetAsync(CancellationToken ct) { if (!ModelState.IsValid) { return; } // IsActive: 1=활성만, 2=비활성만, null=전체 bool? isActive = Query.IsActive switch { 1 => true, 2 => false, _ => null }; var result = await mediator.Send(new SearchGames.Query( Query.Search, Query.Keyword, Query.StartAt, Query.EndAt, isActive, Query.PageNum, Query.PerPage ), ct); Total = result.Total; var qs = Request.QueryString.ToString(); List = [.. result.List.Select(c => ( c.Num, c.ID, c.Code, c.KorName, c.EngName, c.Publisher, c.Thumbnail, c.CommissionRate, c.Link, c.IsActive ? 'Y' : 'N', c.Order, c.ProductCount, c.UpdatedAt.GetDateAt() ?? "-", c.CreatedAt.GetDateAt(), EditURL: $"/Store/Game/Edit/{c.ID}{qs}" ))]; Pagination = new Pagination(result.Total, Query.PageNum, Query.PerPage); } public async Task OnPostDeleteAsync(int[] ids, CancellationToken ct) { try { if (ids is null || ids.Length == 0) { throw new Exception("삭제할 항목을 선택해주세요."); } var result = await mediator.Send(new DeleteGame.Command(ids), ct); if (result.IsFailure) { throw new Exception(result.Error.Description); } TempData["SuccessMessage"] = $"{ids.Length}건이 삭제되었습니다."; } catch (Exception e) { TempData["ErrorMessages"] = e.Message; } return Redirect($"{Request.Path}{Request.QueryString}"); } }