feat(考试编辑器): 新增题型每题分值配置项

新增每题分值列到分数表格,添加分值输入组件及联动更新逻辑,调整表格最小宽度适配新增列
fix/exam-question-access-material-excel-delete-draft
qinzhenpen 2 weeks ago
parent 36052437c3
commit 6c1a8149ae

@ -26,12 +26,13 @@
</el-form> </el-form>
<div class="score-table-wrap"> <div class="score-table-wrap">
<table class="score-table"> <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> <tbody>
<tr v-for="item in typeOptions" :key="item.value"> <tr v-for="item in typeOptions" :key="item.value">
<td>{{ item.label }}</td> <td>{{ item.label }}</td>
<td>{{ questionCount(item.value) }}</td> <td>{{ questionCount(item.value) }}</td>
<td>{{ selectedByType(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> <td>{{ scoreByType(item.value) }}</td>
</tr> </tr>
</tbody> </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 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 scoreByType(type) { return selectedQuestions(type).reduce((sum, item) => sum + Number(selectedScore(item.id)), 0); }
function scorePerQuestion(type) { return Number(typeScores[type] || 1); } 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)); } 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 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"); } 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 { .score-table {
width: 100%; width: 100%;
min-width: 720px; min-width: 860px;
border-collapse: collapse; border-collapse: collapse;
table-layout: fixed; table-layout: fixed;
background: #ffffff; background: #ffffff;
@ -378,6 +380,9 @@ function toBoolean(value, fallback) { if (value === undefined || value === null
td:last-child { border-right: 0; } td:last-child { border-right: 0; }
tbody tr:last-child td { border-bottom: 0; } tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover td { background: #fafcff; } 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 { .fixed-step-actions {

Loading…
Cancel
Save