using Application.Abstractions.Messaging; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using System.ComponentModel; using System.ComponentModel.DataAnnotations; namespace Admin.Pages.Channel.Exp; public class IndexModel(IMediator mediator) : PageModel { [BindProperty] public InputModel Input { get; set; } = new(); public sealed class InputModel { [DisplayName("채팅 메시지당 XP")] [Range(0, 100, ErrorMessage = "{0}은(는) {1}~{2} 사이여야 합니다.")] public int ChatXpPerMessage { get; set; } = 1; [DisplayName("후원 POINT당 1 XP 환산 기준")] [Range(1, 1000000, ErrorMessage = "{0}은(는) {1} 이상이어야 합니다.")] public int DonationXpPerAmount { get; set; } = 1000; [DisplayName("방송 세션당 채팅 XP 상한")] [Range(0, 10000, ErrorMessage = "{0}은(는) {1}~{2} 사이여야 합니다.")] public int ChatXpSessionLimit { get; set; } = 50; [DisplayName("XP 적립 최소 글자수")] [Range(1, 500, ErrorMessage = "{0}은(는) {1}~{2} 사이여야 합니다.")] public int MinContentLength { get; set; } = 2; [DisplayName("채팅 쿨다운(초)")] [Range(0, 60, ErrorMessage = "{0}은(는) {1}~{2} 사이여야 합니다.")] public int RateLimitSec { get; set; } = 2; [DisplayName("리더보드 표시 인원")] [Range(1, 500, ErrorMessage = "{0}은(는) {1}~{2} 사이여야 합니다.")] public int LeaderboardSize { get; set; } = 50; [DisplayName("크라운 뱃지 부여 Top N")] [Range(0, 10, ErrorMessage = "{0}은(는) {1}~{2} 사이여야 합니다.")] public int CrownTopN { get; set; } = 3; [DisplayName("리더보드 노출")] public bool UxShowLeaderboard { get; set; } = true; [DisplayName("내 XP 뱃지 노출")] public bool UxShowMyXpBadge { get; set; } = true; } public async Task OnGetAsync(CancellationToken ct) { var data = await mediator.Send(new GetChannelExpConfig.Query(), ct); Input = new InputModel { ChatXpPerMessage = data.ChatXpPerMessage, DonationXpPerAmount = data.DonationXpPerAmount, ChatXpSessionLimit = data.ChatXpSessionLimit, MinContentLength = data.MinContentLength, RateLimitSec = data.RateLimitSec, LeaderboardSize = data.LeaderboardSize, CrownTopN = data.CrownTopN, UxShowLeaderboard = data.UxShowLeaderboard, UxShowMyXpBadge = data.UxShowMyXpBadge }; } public async Task OnPostAsync(CancellationToken ct) { if (!ModelState.IsValid) { return Page(); } try { await mediator.Send(new UpdateChannelExpConfig.Command( Input.ChatXpPerMessage, Input.DonationXpPerAmount, Input.ChatXpSessionLimit, Input.MinContentLength, Input.RateLimitSec, Input.LeaderboardSize, Input.CrownTopN, Input.UxShowLeaderboard, Input.UxShowMyXpBadge ), ct); TempData["SuccessMessage"] = "경험치 설정이 저장되었습니다."; } catch (Exception e) { TempData["ErrorMessages"] = e.Message; } return RedirectToPage("/Channel/Exp/Index"); } }