按题评切换试题方案

按题评:评分页内直接切换试题

实操考评 · 考评员端 v4 · 2026-11-12 状态:待产品确认

结论:能做。后端加 3 个考评员端接口和 1 个租户开关字段,主要改考评员端的评分页面。数据结构不动。

开工前要产品确认 5 个问题,最关键的是备注、签字和"提交全部时未打完的题怎么办",见待确认问题。

标 v4 的是本次新增或改动:加到所有题、提交全部、租户开关。

1. 需求原文

背景:在考评现场,一个考评员可能负责整个项目中的某几道题。目前考评员需要退出当前考评界面,再点击其他任务卡片来切换试题,对考生进行不同题的打分,操作重复繁琐。

需求:评阅规则为按题阅时,在考评界面左侧展示他关联的所有试题,可在考评界面直接切换。提交评分时,仍按不同的试题分别提交。

产品已确定:按"题"切换,即左边选题,顶部考生跟着这道题变。

v4 2026-11-12 补充的要求:

2. 先说清楚一件事:一道题就是一个任务

按题评时,系统在发布活动时会给每道题单独建一个任务。考评员小王负责第 1、3、5 题,系统里就是 3 个任务,首页就有 3 张卡片。

任务:第 1 题
  • 领取的考生
  • 每个考生的分数
  • 每个考生的备注
  • 签字、提交状态
任务:第 3 题
  • 领取的考生
  • 每个考生的分数
  • 每个考生的备注
  • 签字、提交状态
任务:第 5 题
  • 领取的考生
  • 每个考生的分数
  • 每个考生的备注
  • 签字、提交状态

评分页上几乎所有东西都按"这道题 + 这个考生 + 这个考评员"各存一份。唯一的例外是新加的考生签到状态:它存在考生身上,整场活动只有一份(见第 4 节)。

这带来两个结论:

3. 现在和改完后的样子

现在(按题评)
‹ 返回XX 考评-第3题签字
张三李四+ 添加
试题 1
得分 --
备注
试题 1. 心肺复苏
考核项 / 考核要求 / 打分……
总分:--移除 提交评分

左边永远只有一题,题号也永远是"试题 1"。要换题只能返回首页点另一张卡片。

改完后(开关开启)
‹ 返回XX 考评-第3题签字 ●
张三王五+ 添加
第 1 题
待评 2 人 · 张三 ✓
第 3 题
待评 2 人 · 张三 --
第 5 题
待评 1 人 · 张三 未领
第 3 题备注
第 3 题. 心肺复苏
考核项 / 考核要求 / 打分……
本题得分:--移除 提交本题 提交全部

虚线框:切题时会跟着变的部分。

4. 每个功能切题后怎么处理

把评分页上能点、能看的东西都过了一遍。黄色行需要产品拍板。

功能现在按什么存切题后怎么处理需确认
顶部考生条按题换成新题已领取的考生。原来选中的考生在新题里也有,就继续选中他。无
添加考生 v4按题一次加到左边列出的所有题,只加同科目的题。"一次最多领几人"是活动级配置,各题一样;"单人最多评几人"是任务级,每道题分别算。某道题加不上(已被别人领走、超过上限、未签到)时按题列出原因,其他题照常加。已定
移除考生按题只从当前这道题移除,其他题不受影响。弹窗写明"从第 3 题移除"。无
打分、否定项按题每次点"保存"、勾否定项都会马上存到服务器,切走不会丢。无
底部"总分"当前题按题评时它其实就是本题得分。左边出现多道题后,容易被理解成几道题的合计,改叫"本题得分"。无
提交评分 v4按题"提交全部":提交当前考生在我负责的所有题里已打完的评分,没打完或没领取的题跳过。确认弹窗先列出"将提交第 1、3 题;第 5 题未评完不提交"。每道题仍是独立的一份提交,后台成绩、签字都不变。问题 6
"提交后不可修改"勾选按题(各题配置一样)提交全部时勾一次对所有被提交的题生效。无
考生签到状态按考生(整场活动一份)切题时不变。开启考生拍照签到后,未签到的考生在任何一道题都不能添加、不能提交:添加考生页不能勾选,提交时弹"还未拍照签到"提示,和现在一样。无
试卷变更重评提示按评分记录(按题)跟着新题刷新。提示比较的是整份试卷,试卷改动后,已评过分的各题都会出现提示。无
备注按题看到和保存的都是当前这道题的备注。第 1 题写的备注,切到第 3 题看不到。问题 1
签字按题右上角"签字"入口和红点跟着换。签字时只能签当前这道题。问题 2
人脸核验从首页进入每道题时核验一次页内切题不会触发核验。问题 4
多科目每个科目一套题和考生切到别的科目的题时,顶部考生会整个换掉。"加到所有题"只加同科目的题。问题 5
模式开关 v4新增,租户级Django admin 按租户开。开着:按题评活动的评分页显示多题列表、批量添加、提交全部。关着:和现在完全一样。开关不改任何数据,活动进行中开或关都安全。已定
页面标题按题换成新题的名称。无
返回按钮回任务详情页回到当前切到的那道题的任务详情页。无
盲评按题(各题配置一样)跟着新题配置走,实际不会变。无
仲裁员按题仲裁也是按题分任务的,一样可以切题。批量添加、提交全部对仲裁员同样按题循环,领取规则走仲裁那一套。无
已评分列表、查看试题、首页卡片按题不在本次需求里,保持不变。无

5. 需要产品确认的问题

问题 1:备注是每道题各写一份,还是一个考生只写一份?

现在备注跟着"这道题的评分"一起存。管理端的成绩详情、导出的成绩 Excel、考评表 PDF 里,备注也都是按题分别显示的。

建议 每道题各一份:后端不用改。界面上"备注"改叫"第 3 题备注",避免误会。
一个考生一份,各题共用:要新增存储方式,管理端成绩详情、成绩导出、考评表 PDF 三处都要改,还要定共用备注在管理端放哪里显示。
产品结论:待确认

问题 2:签字是每道题分别签,还是一次签完多道题?

现在签字按题算。负责 3 道题就要在 3 道题里各签一次(每次可以同时签多个考生)。

建议一期 每道题分别签:后端不用改,签字入口跟着切题刷新即可。
一次签完我负责的所有题:后端要加批量签字接口,把同一张签名写到多道题上;签字列表页也要改成跨题显示。
产品结论:待确认

问题 3:添加考生时,要不要"同时加到我负责的其他题"?已定

现在每道题要分别领考生。现场一个考生连着考第 1、3、5 题时,考评员要在 3 道题里各领一次。

产品结论(2026-11-12):加到当前显示的所有题。实现上只加同科目的题;某道题领不上时按题提示原因,其他题照常。详见 6.1。

问题 4:页内切题时要不要重新做人脸核验?

现在每次从首页点进一道题都会核验,核验记录也是按题存的。页内切题不会经过这一步。

建议 同一活动核验一次就够:各题的核验规则都从活动复制而来,本来一样。原来的代价是管理端"人脸核验记录"里只有进入的那道题有记录;现在后端已经支持按活动存核验记录(不挂具体任务,目前只给签到员进入签到前用),放开给考评员后就能按活动存一条,这个代价可以去掉。
每切一题都重新核验:现场体验很差,不建议。
产品结论:待确认

问题 5:一个活动有多个科目时,左边怎么显示?

每个科目有自己的试卷和考生。切到别的科目的题时,顶部考生条会整个换掉。

建议 全部显示,按科目分组:考评员负责的题一目了然。"加到所有题"只加当前科目这一组。
只显示当前科目的题:换科目仍需回首页。
产品结论:待确认

问题 6:提交全部时,有的题还没打完怎么办?要不要保留"只提交本题"?v4

提交全部是把当前考生在我负责的每道题上的评分各提交一次。某道题没打完、或这个考生在那道题还没领取,这道题就提交不了。

建议 打完的提交,没打完的跳过并列出来:弹窗先显示"将提交第 1、3 题;第 5 题未评完不提交",确认后提交。同时保留"提交本题",考评员只想提一题时不用等其他题。
所有题都打完才能提交全部:现场一个考生各题不一定连着考,会经常被卡住,不建议。
只保留"提交全部",去掉"提交本题":界面更简单,但失去按题单独提交的能力。
产品结论:待确认

问题 7:开关放租户级还是活动级?由谁来开?已定

产品结论(2026-11-12):租户级,Django admin 后台开关,按租户开启。不做管理端界面。

6. 技术方案

以下按"每个问题都选建议项"来写。

6.1 后端

(a) 租户开关 v4:Tenant 加布尔字段 practical_item_switch(默认关)+ migration,Django admin 可改。考评员端任务列表/详情返回 item_switch_enabled(按题评 且 开关开)。下面三个接口在后端也校验开关,关着拒绝。

(b) 关联任务查询:GET /dapi/practical/examiner/tasks/{task_id}/related/

(c) 批量添加考生 v4:POST .../tasks/{task_id}/candidates/batch/,body 带 candidate_ids、task_ids。

必须补的校验:可添加列表按科目过滤了,但添加校验(_validate_candidate_for_add)只看活动不看科目。加到"所有题"后,多科目活动会把考生加进别科目的题。批量接口先按考生科目过滤任务。

(d) 批量提交评分 v4:POST .../tasks/{task_id}/candidates/{candidate_id}/score/submit-all/,body 带 task_ids。

打分、单题提交、备注、签字、移除接口不用改。

6.2 前端

坑:现在"提交评分"前会检查左边列表的题是否都打完。切题列表必须单独一份,不能塞进这个列表,否则变成"所有题打完才能提交"。"提交全部"打没打完由后端逐题判断,前端不做前置拦截。

6.3 测试要点

7. 与近期改动的兼容性 v4

v3 之后(11-09 至 11-11)实操考评 13 个提交已逐个对照,方案不用推翻:添加考生的任务行锁通过按题循环直接复用;签到照片、管理端性能优化、权限拆分与本需求无关;考评员前端只改了签到页一行样式。第 9 节列的方法全部仍在。

8. 不在本次范围

9. 附:代码依据(给开发看)

展开
结论位置
按题评时每道题建一个任务,名称"活动名-第N题"app/practical/services/management_assessment_service.py _create_tasks / _create_item_task
领取记录唯一键 (任务, 考生, 考评员)app/practical/models/assignment.py
评分记录唯一键 (任务, 考生, 考评员, 第几次);备注存在评分记录上app/practical/models/score.py、task_repository.update_score_record_note
备注在管理端成绩详情、成绩导出、考评表 PDF 中按评分记录展示management_score_service.py、management_import_export_service.py、management_sheet_export_service.py
签字配置、未签字数按任务统计task_service.get_signature_config
移除考生只释放当前任务的领取记录task_service.remove_candidate_from_task
添加考生:锁任务行 → 领取上限按活动、单人上限按任务 → 逐个考生校验单评/多评 v4task_service.add_candidates_to_task、_validate_add_candidates_limit、_add_single_candidate
可添加列表按科目过滤,但添加校验不校验科目 v4task_repository.query_available_candidates_for_task vs task_service._validate_candidate_for_add
提交评分按任务:锁任务+考生、签到校验、本任务评分项完整性、仲裁对账、完成状态同步;所有失败统一返回 None v4task_service.submit_candidate_score
租户级开关先例:布尔字段 + 管理端"考试定制"页读写 v4app/tenant/models.py hide_course / auto_add_room、app/tenant/views.py customize 接口、client/manager/src/views/manage/ExamCustomize.vue
考评员端任务配置从任务列表/详情接口取 v4task_service.get_examiner_tasks、client/practical-examiner/src/api/index.js mapTask
人脸核验在首页点卡片时触发,记录按任务存,评分接口不校验client/practical-examiner/src/views/HomeView.vue toDetail、task_service.record_face_verification
签到状态存在考生上;考生按 (活动, 准考证号) 唯一,整场一份app/practical/models/candidate.py checkin_status
未签到考生不能添加、不能提交(均按当前任务调用)task_service._validate_candidate_for_add、task_service.submit_candidate_score
人脸核验支持按活动存档(task 为空),目前仅签到员使用task_service._record_assessment_face_verification
重评提示按评分记录计算,比较整份试卷题目及满分task_service._calculate_rubric_changed
任务配置只在任务详情页写入全局状态client/practical-examiner/src/views/TaskDetail.vue getData
提交前检查左侧列表全部打完client/practical-examiner/src/components/TeskItems.vue submit
打分"保存"、勾否定项立即调用保存接口TeskItems.vue scoreOk / checkChange → ScoreView.vue defaultData
添加考生、签字页依赖全局当前任务 ID,并返回评分页AddExam.vue、SignList.vue、Sign.vue

修订记录