From e7af00beb9d3213fa51895cfcdfe0060e29ec357 Mon Sep 17 00:00:00 2001 From: qubiaobiao <3294694717@qq.com> Date: Tue, 22 Sep 2026 13:05:35 +0800 Subject: [PATCH] =?UTF-8?q?fix(admin):=20CSV=20=E8=A1=A8=E5=A4=B4=E3=80=8C?= =?UTF-8?q?Word=E5=88=86=E3=80=8D=E6=94=B9=E4=B8=BA=E3=80=8C=E5=A4=A7?= =?UTF-8?q?=E9=A2=98=E5=88=86=E3=80=8D+=20=E7=A7=BB=E9=99=A4=20getExamSubm?= =?UTF-8?q?issions=20=E9=87=8D=E5=A4=8D=20examScore=20=E9=94=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 改动(3 处): ① getExamSubmissions CSV 表头(L631): 「...,客观题分,Word分,总分」→「...,客观题分,大题分,总分」 ② 移除 getExamSubmissions 返回对象中重复定义的 examScore 键(原 L445): 该键与 L456 的 `examScore: autoScore` 重名,对象字面量重复键「后者静默胜出」, L445 实为死代码。当前因 updateScores 会同步写 contestants.exam_score 而「结果碰巧一致」,属隐患,故删除并加注释说明。 ③ 同步两处注释口径:Word 阅卷分 → 综合大题阅卷分(getScores isExam 分支)。 不改动(保持契约):updateScores 入参名 wordScore、路由 /api/admin/submissions/:group/:id/word、contestants.word_score 列名。 (列名为历史沿用,语义已是「综合大题得分」,仅文案口径调整。) 影响面:仅中职/高职(isExam)分支;本科/教师组 CSV 与成绩口径不变。 验证:CSV 表头端到端实测 = 选手ID,身份证号,姓名,手机号,是否提交,客观题分,大题分,总分; verify_scoring_e2e.py 17/0;verify_big_question.py --cleanup 52/0;零回归。 --- app/service/admin.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/service/admin.js b/app/service/admin.js index 86ae9a6..e9145e4 100644 --- a/app/service/admin.js +++ b/app/service/admin.js @@ -442,9 +442,8 @@ class AdminService extends Service { answeredCount, totalQuestions: answeredCount, autoScore, - examScore: c.exam_score ?? 0, wordScore: c.word_score ?? 0, - // 总分 = 客观题自动评分合计 + Word 阅卷分(与卷面分/Word 分口径一致); + // 总分 = 客观题自动评分合计 + 综合大题阅卷分(与「卷面分 / 大题分」口径一致); // 不读 contestants.score(未人工评分时恒为 0,会导致"客观题有分但总分=0")。 totalScore: autoScore + (c.word_score ?? 0), hasWordFile: hasWord, @@ -452,7 +451,9 @@ class AdminService extends Service { wordFileName: (wordSub && wordSub.word_file_name) || null, submitted: !!formalSubmitTime || answeredCount > 0, submitTime: formalSubmitTime || (subs.length > 0 ? subs[0].created_at : null), - // 卷面分(客观分)统一取客观题自动评分合计,与成绩管理表口径一致 + // 卷面分(客观分)统一取客观题自动评分合计,与成绩管理表口径一致。 + // ⚠️ 此前本行与上方 `examScore: c.exam_score ?? 0` 重复定义(对象字面量重复键,后者静默胜出); + // 虽因 updateScores 会同步写 exam_score 而「结果碰巧一致」,但属隐患,故删除上方那条只留本条。 examScore: autoScore, }; }); @@ -629,8 +630,10 @@ class AdminService extends Service { let csvContent = ''; if (isExam) { - // 中职/高职组:客观题(系统) + Word(人工) - csvContent = '选手ID,身份证号,姓名,手机号,是否提交,客观题分,Word分,总分\n'; + // 中职/高职组:客观题(系统自动评分) + 综合大题(人工阅卷) + // 说明:大题分落库列名为 contestants.word_score(历史沿用,语义已变为「综合大题得分」), + // 故此处取 item.wordScore,仅表头文案按现行口径显示为「大题分」。 + csvContent = '选手ID,身份证号,姓名,手机号,是否提交,客观题分,大题分,总分\n'; for (const item of submissions) { csvContent += [ item.contestantId,