133 lines
4.9 KiB
HTML
133 lines
4.9 KiB
HTML
{% extends 'admin.html' %}
|
||||
|
|
{% block content %}
|
|||
|
|
<div class="admin-page-header">
|
|||
|
|
<div>
|
|||
|
|
<h1>单曲活动设置</h1>
|
|||
|
|
<p class="admin-kicker">公开页面只会加载并游玩这里指定的一首歌曲。</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{% for category, message in get_flashed_messages(with_categories=true) %}
|
|||
|
|
<div class="message{% if category == 'error' %} message-error{% endif %}">{{ message }}</div>
|
|||
|
|
{% endfor %}
|
|||
|
|
|
|||
|
|
<form method="post" action="{{ config.basedir }}admin/experience" class="experience-admin-form">
|
|||
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
|||
|
|
|
|||
|
|
<section class="admin-panel">
|
|||
|
|
<h2>游玩内容</h2>
|
|||
|
|
<label class="admin-field">
|
|||
|
|
<span>指定歌曲</span>
|
|||
|
|
<select name="song_id" id="experience-song">
|
|||
|
|
<option value="">暂不开放</option>
|
|||
|
|
{% for song in songs %}
|
|||
|
|
<option
|
|||
|
|
value="{{ song.id }}"
|
|||
|
|
{% if settings_doc.song_id == song.id %}selected{% endif %}
|
|||
|
|
>#{{ song.id }} · {{ song.title_lang.cn or song.title_lang.en or song.title }}</option>
|
|||
|
|
{% endfor %}
|
|||
|
|
</select>
|
|||
|
|
</label>
|
|||
|
|
|
|||
|
|
<label class="admin-field">
|
|||
|
|
<span>固定难度</span>
|
|||
|
|
<select name="difficulty" id="experience-difficulty" required>
|
|||
|
|
{% for difficulty in ['easy', 'normal', 'hard', 'oni', 'ura'] %}
|
|||
|
|
<option
|
|||
|
|
value="{{ difficulty }}"
|
|||
|
|
{% if settings_doc.difficulty == difficulty %}selected{% endif %}
|
|||
|
|
>{{ difficulty|upper }}</option>
|
|||
|
|
{% endfor %}
|
|||
|
|
</select>
|
|||
|
|
</label>
|
|||
|
|
<p class="admin-note">保存时会校验歌曲是否真的包含所选难度。</p>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section class="admin-panel">
|
|||
|
|
<h2>验证 API Token</h2>
|
|||
|
|
<p>
|
|||
|
|
当前状态:
|
|||
|
|
<strong class="{% if token_configured %}status-ready{% else %}status-missing{% endif %}">
|
|||
|
|
{% if token_configured %}已配置{% else %}未配置{% endif %}
|
|||
|
|
</strong>
|
|||
|
|
</p>
|
|||
|
|
<label class="admin-field">
|
|||
|
|
<span>设置新 Token</span>
|
|||
|
|
<input
|
|||
|
|
type="password"
|
|||
|
|
name="verification_token"
|
|||
|
|
minlength="16"
|
|||
|
|
maxlength="512"
|
|||
|
|
autocomplete="new-password"
|
|||
|
|
placeholder="留空则保留现有 Token"
|
|||
|
|
>
|
|||
|
|
</label>
|
|||
|
|
<label class="admin-check">
|
|||
|
|
<input type="checkbox" name="clear_token" value="1">
|
|||
|
|
清除当前 Token
|
|||
|
|
</label>
|
|||
|
|
<p class="admin-note">Token 只保存 SHA-256 摘要,保存后无法从后台读取原文。</p>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<button type="submit" class="side-button experience-save">保存设置</button>
|
|||
|
|
</form>
|
|||
|
|
|
|||
|
|
<section class="admin-panel code-panel">
|
|||
|
|
<div class="admin-page-header">
|
|||
|
|
<div>
|
|||
|
|
<h2>彩蛋码记录</h2>
|
|||
|
|
<p class="admin-kicker">共 {{ code_count }} 个,下面显示最新 {{ codes|length }} 个。</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
{% if codes %}
|
|||
|
|
<div class="admin-table-wrap">
|
|||
|
|
<table class="admin-table">
|
|||
|
|
<thead>
|
|||
|
|
<tr>
|
|||
|
|
<th>彩蛋码</th>
|
|||
|
|
<th>歌曲 / 难度</th>
|
|||
|
|
<th>成绩</th>
|
|||
|
|
<th>领取时间(UTC)</th>
|
|||
|
|
<th>验证次数</th>
|
|||
|
|
</tr>
|
|||
|
|
</thead>
|
|||
|
|
<tbody>
|
|||
|
|
{% for item in codes %}
|
|||
|
|
<tr>
|
|||
|
|
<td><code class="egg-code">{{ item.code }}</code></td>
|
|||
|
|
<td>
|
|||
|
|
{{ item.song_title }}
|
|||
|
|
<small>#{{ item.song_id }} · {{ item.difficulty|upper }}</small>
|
|||
|
|
</td>
|
|||
|
|
<td>
|
|||
|
|
{{ item.result.points|default(0) }}
|
|||
|
|
<small>良 {{ item.result.good|default(0) }} / 可 {{ item.result.ok|default(0) }} / 不可 {{ item.result.bad|default(0) }}</small>
|
|||
|
|
</td>
|
|||
|
|
<td>{{ item.created_at.strftime('%Y-%m-%d %H:%M:%S') if item.created_at else '--' }}</td>
|
|||
|
|
<td>{{ item.verified_count|default(0) }}</td>
|
|||
|
|
</tr>
|
|||
|
|
{% endfor %}
|
|||
|
|
</tbody>
|
|||
|
|
</table>
|
|||
|
|
</div>
|
|||
|
|
{% else %}
|
|||
|
|
<div class="admin-message empty-message">还没有用户领取彩蛋码。</div>
|
|||
|
|
{% endif %}
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section class="admin-panel api-panel">
|
|||
|
|
<h2>验证接口</h2>
|
|||
|
|
<p><code>POST {{ config.basedir }}api/easter-eggs/verify</code></p>
|
|||
|
|
<pre>{
|
|||
|
|
"headers": {
|
|||
|
|
"Authorization": "Bearer <管理员设置的 Token>",
|
|||
|
|
"Content-Type": "application/json"
|
|||
|
|
},
|
|||
|
|
"body": {
|
|||
|
|
"code": "AI4-XXXX-XXXX"
|
|||
|
|
}
|
|||
|
|
}</pre>
|
|||
|
|
<p class="admin-note">只有 Token 正确并且彩蛋码存在时,响应中的 <code>success</code> 才会是 <code>true</code>。</p>
|
|||
|
|
</section>
|
|||
|
|
{% endblock %}
|