Files
competition-website/database/migrations/026-scores-decimal-two-places.sql
qubiaobiao 2ab0991310 fix(admin): 复核页选择题选项渲染修复 + 阅卷导出 Word + 评分两位小数(R28)
针对测试人员反馈的四项:
1) 复核明细「选择题大量空白」:options 为 text 列存 JSON 字符串,原先被原样透传,
   前端 v-for 对字符串逐字符迭代(op.key/op.text 皆 undefined)⇒ 每字符渲染一行。
   新增 parseOptions()(仅 string 才 JSON.parse,失败降级 null)。
2) 选项与答案不随机:仅题目用 RAND() 抽题,normalizeQuestion 无 shuffle,字母无歧义。
3) 评分精度:DECIMAL(6,1) -> DECIMAL(6,2),migration 026 覆盖 17 列(与 025 同范围),
   lib/decimal_score.js 与 11 个 model 注释同步;汇总收敛 round2(×100/100)。
4) 阅卷导出:GET /api/admin/big-answers/:group/export?ids=
   单选考生 -> 直接 .docx;多位/全部 -> 每位考生单独 .docx 打包 .zip。
   路由为 3 段,注册在 :group 通配段之前。

验证:verify_big_question 51 PASS/1 FAIL(唯一 FAIL=测试人员新数据,非本次改动)、
verify_score_leak_all_channels 24/24、verify_question_no_answer_leak 4/3/0/1。
2026-09-28 15:50:46 +08:00

99 lines
6.3 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- ============================================================================
-- 026 两位小数评分支持:分数列 DECIMAL(6,1) → DECIMAL(6,2)
--
-- 背景(2026-09-28 测试人员反馈)
-- 需求:中职 / 高职「综合大题」的人工评分需精确到**小数点后两位**(如 8.25)。
-- 现状:025 已把得分列由 INT(11) 放宽为 DECIMAL(6,1),但仍只有 1 位小数
-- ⇒ 8.25 会被静默收敛为 8.3 / 8.2,测试人员的评分意图落不了库。
--
-- 范围(17 列,与 025 完全一致,仅精度 1 → 2 位)
-- 大题作答:big_question_answers.score_1 / score_2 / score_3 / total_score
-- 大题配置:big_questions.score_per_sub / total_score(随评分口径)
-- 选手成绩:contestants.exam_score / word_score / ppt_score / score
-- 账号分: accounts.score
-- 提交表: zhongzhi_submissions.score / gaozhi_submissions.score /
-- exam_submissions.score / benke_submissions.score /
-- jiaoshi_submissions.score / work_submissions.score
-- 不改: choice_questions.score / judge_questions.score
-- —— 客观题口径已固定每题 1 分(service/admin.js OBJECTIVE_SCORE_PER_QUESTION),
-- 且 scripts/check_question_bank_health.py 门禁断言其恒为 1。
--
-- 兼容性
-- DECIMAL(6,1) → DECIMAL(6,2) 是**放宽**:既有值原样保留(7.5 读出来仍是 7.5),
-- 读写语义不变。取值范围 [−9999.99, 9999.99],足够覆盖总分 / 单题分。
-- ⚠️ 应用侧必须同步(本次已改):
-- ① lib/decimal_score.js → DECIMAL(6,2)(否则 Sequelize 会把 8.25 按 (6,1) 截断)
-- ② service/bigQuestion.js 的逐问校验与合计收敛 = ×100 / 100
-- ③ service/admin.js 的复核汇总收敛 = ×100 / 100
-- ④ 前端 Admin.vue 评分输入 :precision="2" :step="0.25"
--
-- 执行(在 database/ 目录下):
-- mysql -uroot -p competition_db < migrations/026-scores-decimal-two-places.sql
-- 幂等:MODIFY 到同一类型可重复执行。
-- ============================================================================
-- ---------------------------------------------------------------- 大题作答
ALTER TABLE `big_question_answers`
MODIFY COLUMN `score_1` DECIMAL(6,2) NULL DEFAULT NULL COMMENT '第 1 小问得分(可含 2 位小数)',
MODIFY COLUMN `score_2` DECIMAL(6,2) NULL DEFAULT NULL COMMENT '第 2 小问得分(可含 2 位小数)',
MODIFY COLUMN `score_3` DECIMAL(6,2) NULL DEFAULT NULL COMMENT '第 3 小问得分(可含 2 位小数)',
MODIFY COLUMN `total_score` DECIMAL(6,2) NULL DEFAULT NULL COMMENT '大题合计得分(可含 2 位小数)';
-- ---------------------------------------------------------------- 大题配置
ALTER TABLE `big_questions`
MODIFY COLUMN `score_per_sub` DECIMAL(6,2) NOT NULL DEFAULT 10 COMMENT '每小题分值',
MODIFY COLUMN `total_score` DECIMAL(6,2) NOT NULL DEFAULT 30 COMMENT '大题总分 = 每小题分值 × 小问数';
-- ---------------------------------------------------------------- 选手成绩
ALTER TABLE `contestants`
MODIFY COLUMN `exam_score` DECIMAL(6,2) NULL DEFAULT NULL COMMENT '卷面考试成绩',
MODIFY COLUMN `word_score` DECIMAL(6,2) NULL DEFAULT NULL COMMENT 'Word题/综合大题得分(可含 2 位小数)',
MODIFY COLUMN `ppt_score` DECIMAL(6,2) NULL DEFAULT NULL COMMENT 'PPT得分(本科/教师组,可含 2 位小数)',
MODIFY COLUMN `score` DECIMAL(6,2) NULL DEFAULT NULL COMMENT '选手总分(exam_score + word_score / word_score + ppt_score)';
-- ---------------------------------------------------------------- 账号分(历史兼容)
ALTER TABLE `accounts`
MODIFY COLUMN `score` DECIMAL(6,2) NULL DEFAULT NULL COMMENT '总分(历史兼容字段)';
-- ---------------------------------------------------------------- 提交表分项
ALTER TABLE `zhongzhi_submissions`
MODIFY COLUMN `score` DECIMAL(6,2) NULL DEFAULT NULL COMMENT '本题得分';
ALTER TABLE `gaozhi_submissions`
MODIFY COLUMN `score` DECIMAL(6,2) NULL DEFAULT NULL COMMENT '本题得分';
ALTER TABLE `exam_submissions`
MODIFY COLUMN `score` DECIMAL(6,2) NULL DEFAULT NULL COMMENT '卷面得分';
ALTER TABLE `benke_submissions`
MODIFY COLUMN `score` DECIMAL(6,2) NULL DEFAULT NULL COMMENT '作品得分';
ALTER TABLE `jiaoshi_submissions`
MODIFY COLUMN `score` DECIMAL(6,2) NULL DEFAULT NULL COMMENT '作品得分';
ALTER TABLE `work_submissions`
MODIFY COLUMN `score` DECIMAL(6,2) NULL DEFAULT NULL COMMENT '作品得分';
-- ============================================================================
-- 回滚(DECIMAL(6,2) → DECIMAL(6,1) 会**丢失**第 2 位小数,执行前须确认:
-- SELECT COUNT(*) FROM big_question_answers
-- WHERE score_1 <> ROUND(score_1,1) OR score_2 <> ROUND(score_2,1)
-- OR score_3 <> ROUND(score_3,1) OR total_score <> ROUND(total_score,1); -- 应为 0)
--
-- ALTER TABLE `big_question_answers`
-- MODIFY COLUMN `score_1` DECIMAL(6,1) NULL DEFAULT NULL,
-- MODIFY COLUMN `score_2` DECIMAL(6,1) NULL DEFAULT NULL,
-- MODIFY COLUMN `score_3` DECIMAL(6,1) NULL DEFAULT NULL,
-- MODIFY COLUMN `total_score` DECIMAL(6,1) NULL DEFAULT NULL;
-- ALTER TABLE `big_questions`
-- MODIFY COLUMN `score_per_sub` DECIMAL(6,1) NOT NULL DEFAULT 10,
-- MODIFY COLUMN `total_score` DECIMAL(6,1) NOT NULL DEFAULT 30;
-- ALTER TABLE `contestants`
-- MODIFY COLUMN `exam_score` DECIMAL(6,1) NULL DEFAULT NULL,
-- MODIFY COLUMN `word_score` DECIMAL(6,1) NULL DEFAULT NULL,
-- MODIFY COLUMN `ppt_score` DECIMAL(6,1) NULL DEFAULT NULL,
-- MODIFY COLUMN `score` DECIMAL(6,1) NULL DEFAULT NULL;
-- ALTER TABLE `accounts` MODIFY COLUMN `score` DECIMAL(6,1) NULL DEFAULT NULL;
-- ALTER TABLE `zhongzhi_submissions` MODIFY COLUMN `score` DECIMAL(6,1) NULL DEFAULT NULL;
-- ALTER TABLE `gaozhi_submissions` MODIFY COLUMN `score` DECIMAL(6,1) NULL DEFAULT NULL;
-- ALTER TABLE `exam_submissions` MODIFY COLUMN `score` DECIMAL(6,1) NULL DEFAULT NULL;
-- ALTER TABLE `benke_submissions` MODIFY COLUMN `score` DECIMAL(6,1) NULL DEFAULT NULL;
-- ALTER TABLE `jiaoshi_submissions` MODIFY COLUMN `score` DECIMAL(6,1) NULL DEFAULT NULL;
-- ALTER TABLE `work_submissions` MODIFY COLUMN `score` DECIMAL(6,1) NULL DEFAULT NULL;
-- ============================================================================