| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- @page
- @model Admin.Pages.Config.Attendance.IndexModel
- @{
- ViewData["Title"] = "출석 관리";
- }
- <div class="container">
- <h3>@ViewData["Title"]</h3>
- <hr />
- <div asp-validation-summary="ModelOnly" class="text-danger"></div>
- <partial name="_StatusMessage" />
- <form name="f_admin_write" id="fAdminWrite" class="mt-2" method="post" autocomplete="off" accept-charset="UTF-8">
- <!-- 출석 기능 -->
- <details open>
- <summary class="fs-5 mb-3">출석 기능</summary>
- <div class="row mb-2">
- <label asp-for="Input.Attendance.IsEnabled" class="col-sm-2 col-form-label">출석 기능 활성화</label>
- <div class="col-sm-10 align-content-center">
- <div class="form-check-inline">
- <input asp-for="Input.Attendance.IsEnabled" class="form-check-input" />
- <label class="form-check-label" for="Input_Attendance_IsEnabled">사용</label>
- </div>
- <span asp-validation-for="Input.Attendance.IsEnabled" class="text-danger"></span>
- </div>
- </div>
- </details>
- <hr />
- <!-- 기본 보상 -->
- <details open>
- <summary class="fs-5 mb-3">기본 보상</summary>
- <div class="row mb-2">
- <label asp-for="Input.Attendance.BaseExp" class="col-sm-2 col-form-label">기본 경험치</label>
- <div class="col-sm-3">
- <input asp-for="Input.Attendance.BaseExp" type="number" class="form-control" min="0" max="100000" />
- <div class="form-text text-muted">출석 시 기본으로 지급되는 경험치</div>
- <span asp-validation-for="Input.Attendance.BaseExp" class="text-danger"></span>
- </div>
- </div>
- <div class="row mb-2">
- <label asp-for="Input.Attendance.BasePoint" class="col-sm-2 col-form-label">기본 코인</label>
- <div class="col-sm-3">
- <input asp-for="Input.Attendance.BasePoint" type="number" class="form-control" min="0" max="100000" />
- <div class="form-text text-muted">출석 시 기본으로 지급되는 코인</div>
- <span asp-validation-for="Input.Attendance.BasePoint" class="text-danger"></span>
- </div>
- </div>
- </details>
- <hr />
- <!-- 연속 출석 가중치 -->
- <details open>
- <summary class="fs-5 mb-3">연속 출석 가중치</summary>
- <div class="row mb-2">
- <label asp-for="Input.Attendance.UseStreakBonus" class="col-sm-2 col-form-label">가중치 사용</label>
- <div class="col-sm-10 align-content-center">
- <div class="form-check-inline">
- <input asp-for="Input.Attendance.UseStreakBonus" class="form-check-input" />
- <label class="form-check-label" for="Input_Attendance_UseStreakBonus">사용</label>
- </div>
- <div class="form-text text-muted">연속 출석 시 추가 보상을 지급합니다.</div>
- <span asp-validation-for="Input.Attendance.UseStreakBonus" class="text-danger"></span>
- </div>
- </div>
- <div class="row mb-2">
- <label asp-for="Input.Attendance.StreakBonusPerDay" class="col-sm-2 col-form-label">1일당 추가 경험치</label>
- <div class="col-sm-3">
- <input asp-for="Input.Attendance.StreakBonusPerDay" type="number" class="form-control" min="0" max="10000" />
- <div class="form-text text-muted">연속 출석 1일당 추가 지급 경험치</div>
- <span asp-validation-for="Input.Attendance.StreakBonusPerDay" class="text-danger"></span>
- </div>
- </div>
- <div class="row mb-2">
- <label asp-for="Input.Attendance.StreakBonusPointPerDay" class="col-sm-2 col-form-label">1일당 추가 코인</label>
- <div class="col-sm-3">
- <input asp-for="Input.Attendance.StreakBonusPointPerDay" type="number" class="form-control" min="0" max="10000" />
- <div class="form-text text-muted">연속 출석 1일당 추가 지급 코인</div>
- <span asp-validation-for="Input.Attendance.StreakBonusPointPerDay" class="text-danger"></span>
- </div>
- </div>
- <div class="row mb-2">
- <label asp-for="Input.Attendance.StreakBonusMaxDays" class="col-sm-2 col-form-label">가중치 최대 적용 일수</label>
- <div class="col-sm-3">
- <input asp-for="Input.Attendance.StreakBonusMaxDays" type="number" class="form-control" min="0" max="365" />
- <div class="form-text text-muted">가중치가 적용되는 최대 연속 출석 일수 (0 = 무제한)</div>
- <span asp-validation-for="Input.Attendance.StreakBonusMaxDays" class="text-danger"></span>
- </div>
- </div>
- </details>
- <hr />
- <!-- 순위 보상 -->
- <details open>
- <summary class="fs-5 mb-3">순위 보상</summary>
- <div class="row mb-2">
- <label asp-for="Input.Attendance.UseRankBonus" class="col-sm-2 col-form-label">순위 보상 사용</label>
- <div class="col-sm-10 align-content-center">
- <div class="form-check-inline">
- <input asp-for="Input.Attendance.UseRankBonus" class="form-check-input" />
- <label class="form-check-label" for="Input_Attendance_UseRankBonus">사용</label>
- </div>
- <div class="form-text text-muted">출석 순위(1~10등)에 따라 추가 보상을 지급합니다.</div>
- <span asp-validation-for="Input.Attendance.UseRankBonus" class="text-danger"></span>
- </div>
- </div>
- <div class="row mb-2">
- <div class="col-sm-2"></div>
- <div class="col-sm-10">
- <table class="table table-bordered table-sm" style="max-width: 500px;" id="rankBonusTable">
- <thead class="table-light">
- <tr>
- <th class="text-center" style="width: 80px;">순위</th>
- <th class="text-center">추가 경험치</th>
- <th class="text-center">추가 코인</th>
- </tr>
- </thead>
- <tbody>
- @for (var i = 1; i <= 10; i++)
- {
- <tr>
- <td class="text-center align-middle fw-bold">@(i)등</td>
- <td><input type="number" class="form-control form-control-sm rank-exp" data-rank="@i" min="0" max="100000" value="0" /></td>
- <td><input type="number" class="form-control form-control-sm rank-point" data-rank="@i" min="0" max="100000" value="0" /></td>
- </tr>
- }
- </tbody>
- </table>
- </div>
- </div>
- <input asp-for="Input.Attendance.RankBonusConfig" type="hidden" id="rankBonusConfigInput" />
- </details>
- <hr />
- <!-- 보상 계산 예시 -->
- <details>
- <summary class="fs-5 mb-3">보상 계산 예시</summary>
- <div class="alert alert-info mb-0">
- <strong>보상 계산 예시</strong><br />
- 기본 경험치 10, 1일당 추가 경험치 2, 최대 7일 설정 시:<br />
- 1일차: 10 EXP | 2일차: 12 EXP | 3일차: 14 EXP | ... | 7일차+: 22 EXP<br />
- <br />
- 순위 보상이 설정된 경우 위 보상에 추가로 지급됩니다.
- </div>
- </details>
- <hr />
- <div class="row">
- <div class="col text-center p-3">
- <button type="submit" class="btn btn-success">저장하기</button>
- </div>
- </div>
- <br />
- </form>
- </div>
- @section Scripts {
- <script>
- (function () {
- const configInput = document.getElementById('rankBonusConfigInput');
- const table = document.getElementById('rankBonusTable');
- // 초기 로드: JSON → 테이블
- try {
- const data = JSON.parse(configInput.value || '[]');
- data.forEach(item => {
- const expInput = table.querySelector(`.rank-exp[data-rank="${item.rank}"]`);
- const pointInput = table.querySelector(`.rank-point[data-rank="${item.rank}"]`);
- if (expInput) expInput.value = item.exp || 0;
- if (pointInput) pointInput.value = item.point || 0;
- });
- } catch (e) { }
- // 폼 제출 시: 테이블 → JSON
- document.getElementById('fAdminWrite').addEventListener('submit', function () {
- const entries = [];
- for (let i = 1; i <= 10; i++) {
- const exp = parseInt(table.querySelector(`.rank-exp[data-rank="${i}"]`).value) || 0;
- const point = parseInt(table.querySelector(`.rank-point[data-rank="${i}"]`).value) || 0;
- if (exp > 0 || point > 0) {
- entries.push({ rank: i, exp: exp, point: point });
- }
- }
- configInput.value = JSON.stringify(entries);
- });
- })();
- </script>
- }
|