From 2ca82d0da34be547ab5c809056c7dc4314330c01 Mon Sep 17 00:00:00 2001 From: qubiaobiao <3294694717@qq.com> Date: Mon, 28 Sep 2026 17:44:55 +0800 Subject: [PATCH] =?UTF-8?q?refactor(admin):=20=E8=AF=84=E5=88=86=E5=85=A5?= =?UTF-8?q?=E5=8F=A3=E6=94=B6=E6=95=9B=20+=20=E5=A4=A7=E9=A2=98=E5=B0=8F?= =?UTF-8?q?=E9=97=AE=E5=BE=97=E5=88=86=E5=8F=AF=E8=A7=81=EF=BC=88R30?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 文案:「考生大题作答查证」提示由「作品评分」改为「大题评分」 (保存后将写入该考生「大题评分」,总分 = 客观题得分 + 大题评分) - 删除「考生答题记录」的评分操作:操作列(评分按钮)+ 评分弹窗 + examScoreDialog* / openExamScoreDialog / saveExamScore + .exam-score-form 样式 ⇒ 大题评分统一由「考生大题作答查证」按小问给分,word_score 不再有两条口径 ⛔ 刻意保留:adminApi.setScores(作品管理 batchSaveWorkScores 仍在用) 与后端 PUT /api/admin/scores/:group(10+ 门禁脚本依赖:verify_full_e2e / exam_regression_test / verify_large_scale_17 / verify_agg_key_mismatch 等) - 新增「小问得分」列(「大题得分」之后):后端 listAnswersForAdmin 本就返回 score1/2/3 ⇒ 纯前端改动、未动后端。新增 subScoresOf / hasSubScores / fmtSubScores; hasSubScores 用于区分「未评分」与「三问都给 0 分」(二者不可都显示成 0) 验证: - TDZ 顺序扫描:src 38 文件 + dist 打包产物 26 文件 全 PASS - 真 chromium(playwright)ui-runtime-check.mjs:16/16 断言全过 / 致命错误 0 / 告警 0 (含 expectText "10 / 8 / 9" 直证小问得分列渲染;DOM dump 证实答题记录表头 已无「操作」列、大题查证表头含「小问得分」) - dist 重建 built in 13.00s / VITE_EXIT=0;产物「作品评分」= 0,「小问得分」「大题评分」在 --- src/views/Admin.vue | 120 ++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 66 deletions(-) diff --git a/src/views/Admin.vue b/src/views/Admin.vue index 8762f01..7cd6ef4 100644 --- a/src/views/Admin.vue +++ b/src/views/Admin.vue @@ -828,11 +828,6 @@ 总分:{{ row.totalScore ?? 0 }} - - - @@ -848,29 +843,12 @@ /> - - - - - {{ examScoreDialogRow.userName }} - - {{ examScoreDialogRow.examScore ?? 0 }} 分(系统自动评分,不可修改) - - - - - - - + @@ -943,6 +921,14 @@ 未评分 + + + + @@ -1921,6 +1907,31 @@ function fmtScore(v) { return Number.isInteger(n) ? String(n) : String(Math.round(n * 100) / 100) } +/** + * R30:该考生各小问得分数组(按 bigSubCount 顺序)。 + * + * 数据源 = 后端 listAnswersForAdmin 返回的 score1 / score2 / score3(未评分时为 null)。 + * ⇒ 仅是「把已有数据显示出来」,**不需要任何后端改动**。 + */ +function subScoresOf(row) { + const out = [] + for (let i = 1; i <= bigSubCount.value; i++) out.push(row ? row[`score${i}`] : null) + return out +} + +/** + * 是否已有任一小问得分。 + * 用于区分「尚未评分」(false) 与「三小问都给 0 分」(true) —— 二者不能都显示成 0 分。 + */ +function hasSubScores(row) { + return subScoresOf(row).some(v => v !== null && v !== undefined && v !== '') +} + +/** 「8 / 9.5 / 9.5」形式的小问得分展示(某一小问未给分则该项显示 '--') */ +function fmtSubScores(row) { + return subScoresOf(row).map(v => fmtScore(v)).join(' / ') +} + const bigScoreTotal = computed(() => { let sum = 0 for (let i = 1; i <= bigSubCount.value; i++) { @@ -2517,35 +2528,12 @@ function onExamSubsFilterChange() { examSubmissionsPage.value = 1 } -// 考生答题评分弹窗 -const examScoreDialogVisible = ref(false) -const examScoreDialogRow = ref(null) -const examScoreDialogWord = ref(0) -const examScoreSaving = ref(false) -function openExamScoreDialog(row) { - examScoreDialogRow.value = row - examScoreDialogWord.value = row.wordScore ?? 0 - examScoreDialogVisible.value = true -} -async function saveExamScore() { - if (!examScoreDialogRow.value) return - examScoreSaving.value = true - try { - // R29:组别跟随「成绩管理」页 - await adminApi.setScores(scoreExportGroup.value, { - scores: [{ - contestantId: examScoreDialogRow.value.contestantId, - // 客观分回传弹窗所见值,避免后端按答题记录重算导致与所见不一致 - examScore: Number(examScoreDialogRow.value.examScore ?? 0), - wordScore: Number(examScoreDialogWord.value), - }], - }) - ElMessage.success('评分已保存') - examScoreDialogVisible.value = false - // 客观分 / 大题分同时影响成绩明细表与考生答题记录,必须一起刷新 - await refreshScorePageData(true) - } catch (e) { ElMessage.error('保存失败') } finally { examScoreSaving.value = false } -} +// R30:原「考生答题评分弹窗」的 state 与 openExamScoreDialog / saveExamScore 已整体移除。 +// 大题评分改由「考生大题作答查证」按小问给分(adminApi.setBigAnswerScores +// → service.bigQuestion.setSubScores → service.admin.updateScores), +// 使 word_score 的**写入入口收敛为唯一一条**,不再出现两个口径。 +// ⚠️ adminApi.setScores 本身**保留**:作品管理页 batchSaveWorkScores(本科/教师)仍在使用; +// 后端 PUT /api/admin/scores/:group 亦须保留(10+ 个门禁脚本依赖)。 // 组别切换 → 刷新该组全部相关数据(唯一刷新入口) // 2026-09-23 修复:原仅刷新 fetchExamSubmissions(),题库 / 大题目录 / 大题作答 @@ -3550,14 +3538,7 @@ onMounted(() => { align-items: center; } -/* R29:评分弹窗标签左对齐且禁止折行(「客观分(卷面)」曾折行成两行导致错位) */ -.exam-score-form .el-form-item__label { - text-align: left; - white-space: nowrap; -} -.exam-score-form .exam-score-readonly { - color: #606266; -} +/* R30:`.exam-score-form` 相关样式已随「考生答题记录 · 评分」弹窗一并删除 */ .search-input { width: 220px; } .filter-select { width: 140px; } @@ -4119,6 +4100,13 @@ onMounted(() => { color: #909399; } +/* R30:「考生大题作答查证」列表的「小问得分」列(如 8 / 9.5 / 9.5)。 + 使用等宽数字,避免切组/刷新时列宽抖动。 */ +.big-sub-scores { + font-variant-numeric: tabular-nums; + color: #303133; +} + /* ==================== 评分输入 ==================== */ .score-input { width: 80px;