mobile app database models admin_contests admin_dashboard admin_exams admin_posts admin_teacher_applications admin_users apply_contest apply_teacher base chat contest_detail contest_list exam_result forum notifications profile themes

This commit is contained in:
2026-03-03 16:02:23 +08:00
parent 0764566742
commit 9a08140623
30 changed files with 1531 additions and 834 deletions

View File

@@ -47,10 +47,18 @@
<!-- 考试密码设置 -->
<div class="bg-white shadow-sm rounded-lg p-6 border border-slate-200">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-slate-700">考试可见性</label>
<select id="exam-visibility" class="mt-1 block w-full px-3 py-2 border border-slate-300 rounded-md sm:text-sm">
<option value="private">私有(仅自己可见)</option>
<option value="public">公开(所有人可见)</option>
</select>
<p class="mt-1 text-xs text-slate-400">私有考试只有您自己可以看到和管理</p>
</div>
<div>
<label class="block text-sm font-medium text-slate-700">考试密码 <span class="text-slate-400 font-normal">(可选)</span></label>
<input id="exam-password" type="text" class="mt-1 block w-full px-3 py-2 border border-slate-300 rounded-md sm:text-sm" placeholder="留空则不设密码">
<p class="mt-1 text-xs text-slate-400">设置密码后考生需输入密码才能进入考试,试卷内容将加密存储</p>
<p class="mt-1 text-xs text-slate-400">设置密码后考生需输入密码才能进入考试</p>
</div>
</div>
</div>
@@ -291,7 +299,7 @@ function addQuestion(type, prefill) {
<div class="flex justify-between items-center mb-4">
<div class="flex items-center space-x-3">
<span class="drag-handle cursor-grab text-slate-400 hover:text-slate-600">⠿</span>
<span class="q-number flex-shrink-0 w-8 h-8 bg-${typeColor}-100 rounded-full flex items-center justify-center text-${typeColor}-600 font-medium text-sm">${qid}</span>
<span class="q-number flex-shrink-0 w-8 h-8 bg-${typeColor}-100 rounded-full flex items-center justify-center text-${typeColor}-600 font-medium text-sm">1</span>
<span class="text-xs font-medium px-2 py-1 rounded bg-${typeColor}-50 text-${typeColor}-700">${typeLabel}</span>
<input type="number" class="q-score w-20 px-2 py-1 border border-slate-300 rounded text-sm" placeholder="分值" value="${prefill?.score || defaultScore}" min="1">
</div>
@@ -299,7 +307,7 @@ function addQuestion(type, prefill) {
<button onclick="moveQuestion(${qid}, -1)" class="text-slate-400 hover:text-slate-600 text-sm" title="上移">↑</button>
<button onclick="moveQuestion(${qid}, 1)" class="text-slate-400 hover:text-slate-600 text-sm" title="下移">↓</button>
<button onclick="duplicateQuestion(${qid})" class="text-blue-400 hover:text-blue-600 text-sm" title="复制">复制</button>
<button onclick="document.getElementById('q-${qid}').remove();updateStats();" class="text-red-400 hover:text-red-600 text-sm">删除</button>
<button onclick="document.getElementById('q-${qid}').remove();updateStats();renumberQuestions();" class="text-red-400 hover:text-red-600 text-sm">删除</button>
</div>
</div>
<div class="space-y-3">
@@ -357,6 +365,7 @@ function addQuestion(type, prefill) {
// 选择题选项公式预览
if (type === 'choice' && prefill?.options) { setTimeout(function() { previewOptMath(qid); }, 50); }
updateStats();
renumberQuestions();
}
// 数学公式实时预览
@@ -575,9 +584,10 @@ function submitExam() {
}
}
const access_password = document.getElementById('exam-password').value.trim();
const visibility = document.getElementById('exam-visibility').value;
fetch('/api/exams', {
method: 'POST', headers: {'Content-Type':'application/json'},
body: JSON.stringify({ title, subject, duration, questions, scheduled_start, scheduled_end, score_release_time, access_password })
body: JSON.stringify({ title, subject, duration, questions, scheduled_start, scheduled_end, score_release_time, access_password, visibility })
}).then(r => r.json()).then(data => {
if (data.success) { alert('试卷创建成功!'); window.location.href = '/exams'; }
else alert(data.message);