|
|
|
|
@ -26,12 +26,13 @@
|
|
|
|
|
</el-form>
|
|
|
|
|
<div class="score-table-wrap">
|
|
|
|
|
<table class="score-table">
|
|
|
|
|
<thead><tr><th>题型</th><th>题库题目数量</th><th>选题数量</th><th>小计</th></tr></thead>
|
|
|
|
|
<thead><tr><th>题型</th><th>题库题目数量</th><th>选题数量</th><th>每题分值</th><th>小计</th></tr></thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
<tr v-for="item in typeOptions" :key="item.value">
|
|
|
|
|
<td>{{ item.label }}</td>
|
|
|
|
|
<td>{{ questionCount(item.value) }}</td>
|
|
|
|
|
<td>{{ selectedByType(item.value) }}</td>
|
|
|
|
|
<td><el-input-number v-model="typeScores[item.value]" :min="0" :max="100" size="small" controls-position="right" :disabled="inProgress" @change="onTypeScoreChange(item.value)" /></td>
|
|
|
|
|
<td>{{ scoreByType(item.value) }}</td>
|
|
|
|
|
</tr>
|
|
|
|
|
</tbody>
|
|
|
|
|
@ -229,6 +230,7 @@ function selectedByType(type) { const ids = new Set(bank.value.filter((item) =>
|
|
|
|
|
function questionCount(type) { return bank.value.filter((item) => item.type === type).length; }
|
|
|
|
|
function scoreByType(type) { return selectedQuestions(type).reduce((sum, item) => sum + Number(selectedScore(item.id)), 0); }
|
|
|
|
|
function scorePerQuestion(type) { return Number(typeScores[type] || 1); }
|
|
|
|
|
function onTypeScoreChange(type) { const score = Number(typeScores[type] || 0); for (const item of form.questions) { const bankItem = bank.value.find((q) => q.id === item.questionId); if (bankItem && bankItem.type === type) item.score = score; } }
|
|
|
|
|
function selectedQuestions(type) { const selected = new Set(form.questions.map((item) => item.questionId)); return bank.value.filter((item) => item.type === type && selected.has(item.id)); }
|
|
|
|
|
async function nextStep() { if (activeStep.value === 0) { try { await formRef.value.validate(); const start = new Date(form.startTime.replace(" ", "T")); const end = new Date(form.endTime.replace(" ", "T")); if (end <= start) return ElMessage.warning("结束时间必须晚于开始时间"); duration.value = Math.round((end - start) / 60000); } catch { return; } } if (activeStep.value === 1 && !form.questions.length) return ElMessage.warning("至少选择一道试题"); activeStep.value++; }
|
|
|
|
|
async function save(publish) { if (inProgress.value) { await examApi.updateExam(id.value, form); ElMessage.success("结束时间已更新"); return router.push("/exam/index"); } try { await formRef.value?.validate(); } catch { activeStep.value = 0; return; } if (!form.questions.length) { activeStep.value = 1; return ElMessage.warning("至少选择一道试题"); } const result = isNew.value ? await examApi.createExam(form) : await examApi.updateExam(id.value, form); const examId = result.data.id; if (publish) await examApi.publishExam(examId); ElMessage.success(publish ? "考试已保存并发布" : "考试已保存"); router.push("/exam/index"); }
|
|
|
|
|
@ -351,7 +353,7 @@ function toBoolean(value, fallback) { if (value === undefined || value === null
|
|
|
|
|
|
|
|
|
|
.score-table {
|
|
|
|
|
width: 100%;
|
|
|
|
|
min-width: 720px;
|
|
|
|
|
min-width: 860px;
|
|
|
|
|
border-collapse: collapse;
|
|
|
|
|
table-layout: fixed;
|
|
|
|
|
background: #ffffff;
|
|
|
|
|
@ -378,6 +380,9 @@ function toBoolean(value, fallback) { if (value === undefined || value === null
|
|
|
|
|
td:last-child { border-right: 0; }
|
|
|
|
|
tbody tr:last-child td { border-bottom: 0; }
|
|
|
|
|
tbody tr:hover td { background: #fafcff; }
|
|
|
|
|
|
|
|
|
|
:deep(.el-input-number) { width: 100px; }
|
|
|
|
|
:deep(.el-input-number .el-input__wrapper) { padding: 0 8px; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.fixed-step-actions {
|
|
|
|
|
|