Edit.cshtml 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. @page "{id:int}"
  2. @model Admin.Pages.Channel.List.EditModel
  3. @{
  4. ViewData["Title"] = "채널 수정";
  5. }
  6. <div class="container">
  7. <h3>@ViewData["Title"]</h3>
  8. <hr />
  9. <partial name="_StatusMessage" />
  10. <div class="alert alert-success" role="alert">
  11. 채널 등록 시 YouTube API를 통해 자동 수집된 정보입니다.<br />
  12. 관리자가 직접 수정 시 잘못된 결과가 발생할 수 있습니다.
  13. </div>
  14. <form id="fAdminWrite" method="post" accept-charset="utf-8" autocomplete="off">
  15. <input type="hidden" asp-for="Input.ID" />
  16. <input type="hidden" asp-for="Input.MemberID" />
  17. <div class="row mb-2">
  18. <label class="col-sm-2 col-form-label">PK</label>
  19. <div class="col-sm-10">
  20. <input type="text" asp-for="Input.ID" class="form-control-plaintext" readonly />
  21. </div>
  22. </div>
  23. <div class="row mb-2">
  24. <label class="col-sm-2 col-form-label">회원(소유자)</label>
  25. <div class="col-sm-10">
  26. <input type="text" readonly class="form-control-plaintext" value="[@Model.Input.MemberID] @Model.MemberInfo" />
  27. </div>
  28. </div>
  29. <div class="row mb-2">
  30. <label asp-for="Input.Name" class="col-sm-2 col-form-label"><span class="text-danger">*</span> 이름</label>
  31. <div class="col-sm-10">
  32. <input type="text" asp-for="Input.Name" class="form-control" required maxlength="200" />
  33. </div>
  34. </div>
  35. <div class="row mb-2">
  36. <label asp-for="Input.Handle" class="col-sm-2 col-form-label">핸들</label>
  37. <div class="col-sm-10">
  38. <div class="input-group">
  39. <span class="input-group-text">@@</span>
  40. <input type="text" asp-for="Input.Handle" class="form-control" maxlength="30" />
  41. </div>
  42. </div>
  43. </div>
  44. <div class="row mb-2">
  45. <label asp-for="Input.YouTubeUrl" class="col-sm-2 col-form-label"><span class="text-danger">*</span> YouTube 주소</label>
  46. <div class="col-sm-10">
  47. <input type="url" asp-for="Input.YouTubeUrl" class="form-control" required maxlength="255" />
  48. <div class="text-muted form-text">
  49. YouTube 채널 주소 (예: https://www.youtube.com/channel/UCxxxxxxxxxxxxxxxxxxxxxx)
  50. </div>
  51. </div>
  52. </div>
  53. <div class="row mb-2">
  54. <label asp-for="Input.DonationCode" class="col-sm-2 col-form-label">후원 코드</label>
  55. <div class="col-sm-10">
  56. <div class="row">
  57. <div class="col col-md-auto">
  58. <div class="input-group">
  59. <input type="text" asp-for="Input.DonationCode" id="channelDonationCode" class="form-control" maxlength="7" placeholder="자동 생성" autocomplete="off" />
  60. <button type="button" id="btnRegenerateDonationCode" class="btn btn-outline-secondary" title="새 코드 재생성">
  61. <i class="fa-solid fa-rotate"></i> 재생성
  62. </button>
  63. </div>
  64. </div>
  65. </div>
  66. <small class="form-text text-muted">자동 생성된 6자 영숫자 코드 (UNIQUE, 대문자). 직접 4~7자 영문/숫자로 입력하거나 재생성 버튼으로 갱신할 수 있습니다. 비워두면 후원 코드를 해제합니다.</small>
  67. <span asp-validation-for="Input.DonationCode" class="text-danger"></span>
  68. </div>
  69. </div>
  70. <div class="row mb-2">
  71. <label asp-for="Input.PlatformFeeRate" class="col-sm-2 col-form-label"><span class="text-danger">*</span> 후원 수수료(%)</label>
  72. <div class="col-sm-10">
  73. <div class="row">
  74. <div class="col col-md-auto">
  75. <div class="input-group">
  76. <input type="number" asp-for="Input.PlatformFeeRate" class="form-control" required min="0" max="100" step="any" />
  77. <span class="input-group-text">%</span>
  78. </div>
  79. </div>
  80. </div>
  81. <small class="form-text text-muted">후원 받은 금액 중 dpot 이 가져가는 비율 (채널주는 100-PlatformFee% 보유)</small>
  82. <span asp-validation-for="Input.PlatformFeeRate" class="text-danger"></span>
  83. </div>
  84. </div>
  85. <div class="row mb-2">
  86. <label asp-for="Input.StoreCommissionRate" class="col-sm-2 col-form-label"><span class="text-danger">*</span> 상점 보상률(%)</label>
  87. <div class="col-sm-10">
  88. <div class="row">
  89. <div class="col col-md-auto">
  90. <div class="input-group">
  91. <input type="number" asp-for="Input.StoreCommissionRate" class="form-control" required min="0" max="100" step="any" />
  92. <span class="input-group-text">%</span>
  93. </div>
  94. </div>
  95. </div>
  96. <small class="form-text text-muted">상점 후원 시 채널주에게 보상으로 지급하는 비율 (StoreRevenue 잔액에 입금)</small>
  97. <span asp-validation-for="Input.StoreCommissionRate" class="text-danger"></span>
  98. </div>
  99. </div>
  100. <div class="row mb-2">
  101. <label asp-for="Input.IsVerified" class="col-sm-2 col-form-label">인증 여부</label>
  102. <div class="col-sm-10 align-content-center">
  103. <div class="form-check form-check-inline">
  104. <input type="checkbox" asp-for="Input.IsVerified" class="form-check-input" />
  105. <label class="form-check-label" asp-for="Input.IsVerified">인증합니다.</label>
  106. </div>
  107. </div>
  108. </div>
  109. <div class="row mb-2">
  110. <label asp-for="Input.IsActive" class="col-sm-2 col-form-label">사용 여부</label>
  111. <div class="col-sm-10 align-content-center">
  112. <div class="form-check form-check-inline">
  113. <input type="checkbox" asp-for="Input.IsActive" class="form-check-input" />
  114. <label class="form-check-label" asp-for="Input.IsActive">사용합니다.</label>
  115. </div>
  116. </div>
  117. </div>
  118. @if (Model.Input.UpdatedAt is not null)
  119. {
  120. <div class="row mb-2">
  121. <label class="col-sm-2 col-form-label">수정일시</label>
  122. <div class="col-sm-10">
  123. <input type="text" asp-for="Input.UpdatedAt" class="form-control-plaintext" readonly />
  124. </div>
  125. </div>
  126. }
  127. <div class="row mb-2">
  128. <label class="col-sm-2 col-form-label">등록일시</label>
  129. <div class="col-sm-10">
  130. <input type="text" asp-for="Input.CreatedAt" class="form-control-plaintext" readonly />
  131. </div>
  132. </div>
  133. <hr />
  134. <div class="d-grid gap-2 text-center d-md-block">
  135. <button type="submit" class="btn btn-success">저장</button>
  136. <a href="@(Model.ReturnUrl ?? "/Channel/List")" class="btn btn-secondary">취소</a>
  137. <button type="submit"
  138. class="btn btn-danger"
  139. formaction="?handler=Delete"
  140. formnovalidate
  141. onclick="return confirm('삭제 하시겠습니까?');">
  142. 삭제
  143. </button>
  144. </div>
  145. <br />
  146. </form>
  147. </div>
  148. @section Scripts {
  149. <script>
  150. // 후원 코드 재생성
  151. document.getElementById('btnRegenerateDonationCode').addEventListener('click', async function () {
  152. const btn = this;
  153. btn.disabled = true;
  154. try {
  155. const res = await fetch('?handler=GenerateDonationCode', {
  156. method: 'GET',
  157. headers: { 'Accept': 'application/json' }
  158. });
  159. if (!res.ok) {
  160. throw new Error('코드 생성 실패');
  161. }
  162. const data = await res.json();
  163. if (data && data.code) {
  164. document.getElementById('channelDonationCode').value = data.code;
  165. }
  166. } catch (e) {
  167. alert('후원 코드 재생성 중 오류가 발생했습니다.');
  168. } finally {
  169. btn.disabled = false;
  170. }
  171. });
  172. </script>
  173. }