日期:2026-07-03
本次工作应按“功能迁移”处理:旧系统是功能验收基线,Kaola 需要重新实现同等业务能力,让新用户可以在 Kaola 中完整使用现场考评流程;不迁移旧系统历史数据,不围绕旧库做数据兼容,也不把旧表结构一比一搬进新系统。
目标业务是线下/现场操作技能考评,例如医护操作、设备操作、实验实训等。考生在现场完成实际操作,考评员使用手机端按评分表打分。它不是 Kaola 当前在线考试中的元实操题、云环境实操题或交互题,不接入虚拟机环境、考生在线作答、答案文件回收、open-meta 等链路。
迁入 Kaola 后应作为独立的 Practical 模块建设。基础试卷结构仍使用 Kaola 现有 content.Form 和大 JSON 结构表达;现场考评自己的活动、考生、考评员、任务、评分记录、最终得分由 app/practical 管理,不依赖 enrollment、schedule、exam.Entry、outcome.Result 作为业务主链路。
旧项目中的 kp、kao、B216、T37120 是旧系统的业务命名和承载方式。迁入 Kaola 后,不沿用旧表设计和旧接口契约,但必须覆盖这些命名背后承担的活动管理、评分表、评分任务、现场打分和成绩导出能力。
整体边界:
| 功能域 | 目标能力 |
|---|---|
| 实操考评活动 | 创建、编辑、发布、关闭现场考评活动 |
| 评分表 | 创建评分表、配置评分项、分值、评分维度、扣分点和说明 |
| 考生管理 | 导入/维护考生名单,绑定到实操考评活动和评分任务 |
| 考评员管理 | 导入/维护考评员,配置手机号、证件、照片、角色和登录方式 |
| 评分规则 | 配置一评/双评/多评、算分方式、盲评、备注、签字确认、评分限制 |
| 评分任务 | 创建评分任务,绑定评分表、评分项、考评员、考生范围和时间 |
| 手机端评分 | 考评员登录、查看任务、领取/查看考生、现场打分、备注、提交 |
| 签字确认 | 启用后考评员对评分结果进行签字确认 |
| 人脸核验 | 支持考评员人脸比对,可按活动配置开启 |
| 进度与成绩 | 管理端查看评分进度、评分详情、最终分、导出成绩 |
| 外部接口 | 纳入易考现有 /tenant/api/ 对外接口体系,用于创建活动、考评员、规则、任务、获取任务入口 |
| 不做 | 说明 |
|---|---|
| 旧历史数据迁移 | 新系统面向新用户,从空数据开始使用 |
| 旧库数据兼容 | 不需要旧 id 映射表来支持历史查询 |
| 旧表结构照搬 | 新表按 Kaola 租户隔离、分层架构、审计和扩展要求重新设计 |
| 旧开放接口兼容 | 外部开放 API 不要求保留旧 kp 路径、旧参数名、旧响应结构 |
| 元实操题整合 | 不接入 Kaola 现有在线实操题、云环境、答案回收链路 |
| Yii/PHP 页面迁移 | 管理端按 Kaola client/manager 风格重建,但功能范围需要覆盖旧管理端 |
| 仲裁流程 | 本期不实现双评差异触发仲裁、仲裁任务和仲裁评分,仅保留后续扩展空间 |
功能一致不是复制旧页面、旧接口或旧数据结构,而是在 Kaola 中重新实现旧实操考评的完整业务闭环。这里的“一致”指用户可见表现和业务结果一致:
不要求一致的是历史数据、旧主键、旧表名、旧 PHP/Yii 实现方式、旧数据库查询方式、旧开放接口路径和旧开放接口参数格式。考评员 H5 端属于前端复用目标,优先复用页面、组件、交互和样式;允许对网络层、入口路由、字段映射、上传鉴权和少量状态逻辑做受控改造。
产品流程以 Kaola 侧新原型为准。旧项目流程用于确认能力范围、业务规则和可复用交互,不作为管理端或考评员端最终页面流程的唯一依据;目前技术方案在这个前提下仍然可行。
旧项目中“实操考评”分布在以下功能块,这些功能块共同构成迁移后的验收范围:
| 旧位置 | 功能含义 | 迁入 Kaola 后的归属 |
|---|---|---|
yj-company/modules/kp/ |
管理端:活动、考生、考评员、评分任务、成绩、导出 | client/manager + /dapi/practical/ |
yj-company/modules/exam/ |
创建实操考评入口 | 管理端实操考评创建向导 |
yj-examiner/ |
考评员手机 H5 | 一期优先复用,可做受控改造 |
yj-api-examiner/api/v1/ |
考评员端 API | app/practical 考评员端适配 API |
yj-api-open/api/exam/v5/std/kp/ |
外部创建考评员、规则、任务等 API | /tenant/api/practical/ 对外接口 |
common/models/WebPlan.php |
评分规则、几评制、签字、盲评等逻辑 | PracticalRuleService |
common/models/Exam2Manage.php |
识别 kao 模式、计划与任务关系 |
PracticalAssessmentService |
旧系统借用了考试内容模型表达评分表:
B216 表示实操考评类评分表库。T37120 表示实操考评评分项。TkPaper 实际承担评分表。TkPaperItem 实际承担评分项。迁入 Kaola 时不应继续把它们当作在线考试试卷/试题,也不应接入在线考试场次链路。基础试卷结构可以继续用 Kaola 现有 Form 大 JSON 表达;app/practical 负责现场考评上下文、考生、考评员、任务、评分和最终得分。
旧到新归属:
新增模块:
app/practical/
├── models/
├── repositories/
├── services/
├── views/
├── value_objects/
├── jobs/
├── utils/
├── urls.py
└── AGENTS.md
分层遵循 Drill 模式:
View -> Service -> Repository -> Model
路由建议:
/dapi/practical/ 管理端 API
/dapi/practical/examiner/ 考评员手机端 API,使用独立认证模块
/tenant/api/practical/ 易考对外接口,走现有 tenant APIView 鉴权
/dapi 在这里只表示 Kaola 后端 API 路由前缀,不等同于管理端认证。路由注册时应拆成两个入口:/dapi/practical/ include 管理端 API,使用管理端 Session 和 DapiTenantBaseView;/dapi/practical/examiner/ include 考评员手机端 API,使用 PracticalExaminerAuthBaseView 和模块自己的登录态,不复用管理端 Session 或权限基类。
目标后端分层:
| Kaola 模块 | 使用方式 |
|---|---|
tenant |
所有实操考评数据按租户隔离 |
content.Form |
基础试卷/评分表结构使用现有 Form 大 JSON 表达 |
progressbar |
导入导出和批量任务进度 |
logs |
管理端操作日志,可补充 practical 专用评分日志 |
oss_storage |
签字、照片、附件使用现有存储抽象 |
以下模块不作为实操考评主链路依赖:
enrollment:实操考评有自己的 PracticalCandidate,不复用报名批次。schedule:实操考评有自己的活动时间、任务时间和现场组织字段,不复用考试场次。exam.Entry:实操考评考生不是在线考试 Entry。outcome.Result:实操考评有自己的最终得分对象,不写入在线考试成绩结果。| 模型 | 说明 |
|---|---|
PracticalAssessment |
实操考评活动,关联租户、活动时间、评分表、状态、发布时间 |
PracticalSubject |
活动下的科目/试卷分组,用于支持一个考评活动配置多个科目、多张考评试卷;没有明确科目时使用默认分组 |
PracticalRubric |
现场评分表,关联 content.Form,保存评分表版本和 JSON 快照 |
PracticalCandidate |
实操考评考生,维护姓名、准考证号、证件、手机号、照片、现场评分状态 |
PracticalExaminer |
考评员账号,手机号、姓名、证件、照片、角色、登录配置 |
PracticalTask |
评分任务,绑定活动、评分表、评分范围、时间和规则 |
PracticalTaskExaminer |
任务与考评员绑定 |
PracticalTaskItem |
任务包含的评分项范围,使用评分表 JSON 中的 item key/path |
PracticalAssignment |
考生分配或领取记录 |
PracticalScoreRecord |
某考评员对某考生在某任务下的一次评分记录 |
PracticalScoreItem |
单个评分项/维度的得分明细 |
PracticalScoreResult |
考生在活动下的最终得分和终态 |
PracticalSignature |
签字确认记录 |
PracticalFaceRecord |
考评员人脸核验记录 |
PracticalScoreLog |
改分、清分、提交、终态重算等评分审计 |
PracticalApiLog |
手机端和外部接口调用日志 |
模型关系:
本节状态不是远鉴状态枚举的原样迁移。远鉴实操考评相关状态分散在 PLAN_PUBLISH_STATUS、SCORE_TASK_STATUS、JUDGE_SCORE_STATUS、CANDIDATE_STATUS、MAN_STATUS 等数字字典中,并且有一部分状态由时间、任务分配记录和评分记录共同推导。Kaola 新模块应在内部使用更明确的语义化字符串,降低前后端、接口文档和人工排查的理解成本。
产品原型中的考评活动状态由三个概念共同决定,不能只用一个简单的 draft -> published -> closed 解释:
| 维度 | 状态 | 业务含义 |
|---|---|---|
| 配置状态 | draft |
配置还没完成,或者只是保存草稿。产品原型中点击“创建完成”后默认发布,因此正常完成创建后不应停留在 draft。 |
| 发布状态 | published |
“发布考评”开关开启,考评员手机端可以看到自己关联的活动和任务。接近远鉴发布后的 PLAN_PUBLISH_STATUS:S1/S2/S3。 |
| 发布状态 | unpublished |
管理端关闭“发布考评”开关。活动仍存在,管理端可编辑和查看,但考评员手机端不可见。 |
| 归档状态 | closed |
管理端主动关闭或归档。原则上不再允许考评员继续评分,只允许查询、导出和审计。接近远鉴 PLAN_PUBLISH_STATUS:S4 的业务效果。 |
| 时间状态 | not_started |
当前时间早于活动开始时间,产品列表展示为“未开始”。 |
| 时间状态 | active |
当前时间在活动开始和结束之间,产品列表展示为“考评中”。 |
| 时间状态 | expired |
当前时间晚于活动结束时间,产品列表展示为“已过期”。 |
建议落库时把“是否发布/是否关闭”作为活动自身状态或字段,把“未开始/考评中/已过期”作为根据活动时间计算出的展示状态。活动状态只表达活动整体生命周期,不表达某个考生是否已经被评分,也不表达某个考评员任务是否到期。
任务状态记录某个考评员或考评员组在指定时间和范围内是否可以执行评分,对应模型 PracticalTask.status。
| 状态 | 业务含义 | 典型进入条件 | 远鉴参考 |
|---|---|---|---|
pending |
任务已经配置好,但还没有到可评分时间,或活动尚未发布。考评员手机端不应进入正式评分。 | 管理端创建任务后默认进入;发布时间或任务开始时间未到。 | 远鉴没有单独字段,通常由任务时间和活动发布状态推导。 |
active |
任务当前可评分。考评员可以领取或打开分配给自己的考生,并保存草稿或提交评分。 | 活动已发布,任务未停止,且当前时间在任务有效期内。 | 接近 SCORE_TASK_STATUS:S1 且 endTime >= time()。 |
ended |
任务自然结束。通常是到达结束时间,或后续规则要求全部考生评分完成后结束。结束后不允许继续提交评分。 | 当前时间超过任务结束时间,或系统按完成条件结束。 | 远鉴主要通过 endTime < time() 判断。 |
stopped |
管理端主动中止任务。与 ended 的区别是它不是自然到期,而是人工或异常处理导致的停止。 |
管理端停止任务,或出现需要强制终止的业务场景。 | 接近 SCORE_TASK_STATUS:S2。 |
任务状态只表达任务是否可执行,不直接表示考生评分进度。
考生评分状态记录某个现场考评考生在活动内的评分推进程度,对应模型 PracticalCandidate.score_status。它不是在线考试的 Entry 状态,也不复用远鉴的候选人考试状态。
| 状态 | 业务含义 | 典型进入条件 | 远鉴参考 |
|---|---|---|---|
pending |
考生已导入活动,但尚未分配给具体任务或考评员,也没有评分记录。产品界面通常展示为待评分。 | 导入考生后默认进入。 | 远鉴没有单一对应字段,需要由分配记录和评分记录反推。 |
assigned |
考生已经进入某个任务范围,或已经预分配给某个考评员,但尚未加入考评员当前评分界面。该状态偏内部使用,产品界面通常仍归入待评分。 | 管理端预分配考生,或系统按任务范围生成可领取关系。 | 接近远鉴 ArrangeScoreExaminer 等任务分配关系。 |
scoring |
考生已经被考评员加入评分界面,但还没有完成全部要求的评分。即使尚未保存扣分草稿,只要已被加入当前评分界面,也应视为评分中。 | 考评员领取/添加考生到评分界面,或创建有效的评分占用记录。 | 由任务分配关系、有效评分记录草稿和 JudgeScore.status = JUDGE_SCORE_STATUS:S0 共同体现。 |
scored |
满足该活动/任务要求的评分记录已经提交,并生成或更新最终得分;启用签字确认时,需要签字确认后才计入最终成绩。 | 必要考评员提交完成,且签字等发布条件满足后,系统计算最终分。 | 由 JudgeScore.status = JUDGE_SCORE_STATUS:S1、评分数量、签字状态和最终算分结果共同体现。 |
产品侧常见展示可以简化为“待评分、评分中、已评分”。其中 pending 和部分尚未进入评分界面的 assigned 都可归入“待评分”。该状态是业务汇总状态,不应把远鉴 CANDIDATE_STATUS:S5 直接照搬为 scored;远鉴的 S5 更多表示候选人考试流程完成,和 Kaola 新实操考评的评分完成不是同一个概念。
评分记录状态记录某个考评员对某个考生在某个任务下的一次评分是否已经正式提交,对应模型 PracticalScoreRecord.status。
| 状态 | 业务含义 | 典型进入条件 | 远鉴参考 |
|---|---|---|---|
draft |
考评员已经进入评分页面,可能保存了部分扣分项、否定项、备注、照片或签字,但还没有最终提交。 | 创建评分记录后默认进入;手机端保存草稿时保持该状态。 | 对应 JUDGE_SCORE_STATUS:S0。 |
submitted |
考评员确认完成评分。提交后原则上不能由考评员自行修改,只能通过管理端清分、重评或审计流程处理。 | 手机端完成全部必填项校验并提交评分。 | 对应 JUDGE_SCORE_STATUS:S1。 |
评分记录状态是最细粒度的提交状态。考生 scored 必须由一个或多个 submitted 评分记录按活动规则汇总后产生。
状态流:
状态内部使用语义化字符串。对外 API 如需返回枚举值,应按易考新接口文档定义,不受旧系统数字状态约束。
评分表是现场考评的核心,但进入 Kaola 后至少应使用现有试卷结构表达。也就是说,评分表的基本层级、题目/步骤组织、分值配置应落在 content.Form 的大 JSON 结构中,Practical 模块保存现场考评所需的版本、快照和任务绑定信息。
建议采用混合方案:
| 方案点 | 决策 |
|---|---|
| 基础结构 | 使用 content.Form 表达评分表的章节、题组、评分项、分值和展示内容 |
| 评分表版本 | PracticalRubric 关联 Form,发布时保存一份 rubric_snapshot JSON,保证评分过程中结构稳定 |
| 评分项定义 | 一期不单独建立评分项主表,以 JSON 中的稳定 item_key / path 表示 |
| 评分明细 | 使用 PracticalScoreItem 表记录每个考生、考评员、任务、评分项的实际得分 |
| 查询优化 | 若后续需要按评分项维度做大量统计,再增加评分项索引表或 JSON 展开表 |
这个选择保留了易考现有大 JSON 的灵活性,也避免为评分表定义复制一套与 Form 平行的主数据结构;实际评分结果仍落表,方便进度、明细、导出和审计查询。
评分表应支持:
评分项建议结构:
{
"title": "无菌操作准备",
"score": 10,
"description": "检查物品、手卫生、环境准备",
"dimensions": [
{ "name": "物品准备", "score": 3 },
{ "name": "手卫生", "score": 4 },
{ "name": "环境检查", "score": 3 }
],
"deductions": [
{ "name": "未核对物品", "score": 2 }
]
}
需要支持旧模块已有能力:
| 规则 | 说明 |
|---|---|
| 评分人次 | 一评、双评、三评,最多可支持十评 |
| 任务上限 | 单个考评员可评分人数上限 |
| 同时评分限制 | 考评员端同时持有的未完成考生数量 |
| 盲评 | 手机端隐藏考生敏感信息 |
| 备注 | 考评员可对考生写备注 |
| 签字确认 | 启用后签字未完成时成绩不发布 |
| 提交后改分限制 | 控制提交后是否允许修改评分 |
| 算分方式 | 平均分、去最高最低平均、不算分 |
| 仲裁 | 本期不做;后续如需要,再扩展双评差异触发、仲裁任务和仲裁评分 |
最终分计算建议放在 PracticalScoreFinalizeService:
PracticalCandidate.status。PracticalScoreResult。前缀:
/dapi/practical/
接口组:
| 接口组 | 能力 |
|---|---|
/assessments/ |
活动列表、创建、详情、编辑、发布、关闭 |
/rubrics/ |
评分表列表、创建、编辑、复制、启停 |
/rubrics/{id}/items/ |
评分项增删改查、排序 |
/assessments/{id}/candidates/ |
考生导入、列表、删除、状态查看 |
/examiners/ |
考评员导入、列表、编辑、删除、重置验证码 |
/tasks/ |
任务创建、编辑、停止、绑定考评员、绑定评分项 |
/assignments/ |
考生分配、回收、重新分配 |
/scores/ |
评分进度、评分详情、改分、清分、终态重算 |
/exports/ |
成绩导出、评分明细导出 |
/settings/ |
模块级默认规则 |
认证使用管理端 Session + DapiTenantBaseView,响应遵循 Kaola:
{ "data": { "...": "..." } }
/rubrics/{id}/items/ 操作的是 Form 大 JSON 或 rubric_snapshot 中的评分项结构,不表示一期必须建立独立评分项主表。
考评员手机端一期应优先复用旧项目 yj-examiner。这里的“复用”是尽量保留旧 H5 的页面、组件、交互、样式和现场评分流程,不代表复用旧数据、旧表或旧后端实现,也不把旧 H5 完全不改作为硬约束。允许对旧 H5 的网络层、接口字段映射、入口路由、上传鉴权、错误处理和少量状态管理做受控改造。
内部服务仍按新模块设计:
yj-examiner H5 -> /dapi/practical/examiner/ -> PracticalExaminerAuthBaseView -> app/practical/services -> app/practical/models
手机端接口迁移采用“改造旧 H5 请求层,接入 Practical 手机端接口”的方式。旧 H5 中页面组件尽量保留,src/api/ 和 src/utils/request.js 负责完成接口路径、请求字段、登录态和响应结构的转换。后端提供 /dapi/practical/examiner/ 接口,但该接口只复用 /dapi 路由命名,不复用管理端认证;它使用自己的认证基类和登录态,也不把旧 /v1/* 作为新系统目标接口。
迁移规则:
baseURL 指向 Kaola 当前域名,所有手机端请求统一加 /dapi/practical/examiner/ 前缀。Authorization 携带,不再沿用旧端硬编码签名。uid/tuid/cuid/iuid 等旧字段映射为 examiner_id/task_id/candidate_id/item_key 或由 token 隐式表达。{ "data": ... } 格式;旧 H5 若不想大改页面,可在请求封装层把响应转换成页面当前需要的对象结构。迁移后的手机端 API 统一前缀:
/dapi/practical/examiner/
下表同时作为旧端能力迁移映射和一期手机端接口清单:
| 旧端能力 | 新接口 | 新服务归属 |
|---|---|---|
| 获取验证码 | POST /auth/code/ |
PracticalExaminerAuthService |
| 考评员登录 | POST /auth/login/ |
PracticalExaminerAuthService |
| 退出登录 | POST /auth/logout/ |
PracticalExaminerAuthService |
| 获取任务列表 | GET /tasks/ |
PracticalTaskService |
| 获取任务详情 | GET /tasks/{task_id}/ |
PracticalTaskService |
| 获取待评分考生 | GET /tasks/{task_id}/candidates/?status=pending |
PracticalAssignmentService |
| 领取/添加待评分考生 | POST /tasks/{task_id}/assignments/ |
PracticalAssignmentService |
| 获取评分中考生 | GET /tasks/{task_id}/candidates/?status=scoring |
PracticalAssignmentService |
| 移除未评分考生 | DELETE /assignments/{assignment_id}/ |
PracticalAssignmentService |
| 获取任务评分项 | GET /tasks/{task_id}/rubric/ |
PracticalRubricService |
| 获取评分草稿/明细 | GET /tasks/{task_id}/candidates/{candidate_id}/score-record/ |
PracticalScoreService |
| 保存评分项得分 | PATCH /score-records/{score_record_id}/items/{item_key}/ |
PracticalScoreService |
| 提交考生评分 | POST /score-records/{score_record_id}/submit/ |
PracticalScoreService |
| 清空评分 | POST /score-records/{score_record_id}/clear/ |
PracticalScoreService |
| 获取备注 | GET /score-records/{score_record_id}/note/ |
PracticalScoreService |
| 保存备注 | PUT /score-records/{score_record_id}/note/ |
PracticalScoreService |
| 获取上传凭证 | POST /uploads/policy/ |
PracticalUploadService |
| 考评员人脸核验 | POST /face-records/verify/ |
PracticalFaceService |
| 获取签字配置 | GET /signatures/config/?task_id={task_id} |
PracticalSignatureService |
| 获取待签字考生 | GET /signatures/pending/?task_id={task_id} |
PracticalSignatureService |
| 提交签字 | POST /signatures/ |
PracticalSignatureService |
| 获取已评分考生 | GET /tasks/{task_id}/candidates/?status=scored |
PracticalAssignmentService |
手机端 API 使用独立的 PracticalExaminerAuthBaseView,不继承管理端 DapiTenantBaseView,也不依赖管理端 Django Session。登录态存 Redis,认证对象是 PracticalExaminer 和其绑定的任务、租户上下文。响应格式遵循 Kaola 新接口风格:
{ "data": { "...": "..." } }
外部接口应纳入易考现有对外接口体系,挂在 /tenant/api/practical/... 下,并使用 app.tenant.tenant_api.APIView 作为基类。这样可以复用现有 Authorization: Key <api_key>、集团租户 Key <key> Tid <tid>、租户注入、加密解析、日志记录等能力。
API 认证边界:
| 能力 | 接口建议 |
|---|---|
| 创建/更新活动 | POST /tenant/api/practical/assessments/ |
| 获取活动详情 | GET /tenant/api/practical/assessments/{id}/ |
| 创建/更新考评员 | POST /tenant/api/practical/examiners/ |
| 导入/更新考生 | POST /tenant/api/practical/assessments/{id}/candidates/ |
| 设置评分规则 | POST /tenant/api/practical/assessments/{id}/rules/ |
| 绑定评分表 | POST /tenant/api/practical/assessments/{id}/rubric/ |
| 创建评分任务 | POST /tenant/api/practical/tasks/ |
| 追加任务考评员 | POST /tenant/api/practical/tasks/{id}/examiners/ |
| 删除任务 | DELETE /tenant/api/practical/tasks/{id}/ |
| 获取任务入口 | GET /tenant/api/practical/assessments/{id}/task-url/ |
| 获取成绩 | GET /tenant/api/practical/assessments/{id}/results/ |
实现位置可以放在 app/practical/tenant_api.py,再由 app/tenant/api_url.py 注册路由,避免继续膨胀 app/tenant/tenant_api.py。接口契约按易考新文档定义,不需要保留旧 kp 路径。
管理端应重建在 client/manager,使用 Vue 3 + Ant Design Vue。
页面建议:
| 页面 | 能力 |
|---|---|
| 实操考评列表 | 查看活动、状态、考生数、评分进度 |
| 创建实操考评 | 基础信息、活动时间、评分表、规则 |
| 评分表/试卷编辑 | 在现有试卷/试卷编辑入口维护评分表、评分项、维度、分值、说明 |
| 考生管理 | 导入、编辑、删除、状态 |
| 考评员管理 | 导入、编辑、验证码、照片、角色 |
| 任务管理 | 任务、考评员、评分表、评分范围、时间 |
| 评分进度 | 待评分、评分中、已完成、未签字 |
| 成绩管理 | 最终分、明细、导出、重算 |
一期考评员端前端应迁入 Kaola 的 client/practical-examiner,仍保持前后端分离。迁入时以旧项目 yj-examiner 为基础复用页面、组件、样式和现场评分交互,同时按 Kaola 前端目录、构建、模板和部署方式接入当前项目。为了接入 Kaola 后端,可以改造 baseURL、环境变量、接口域名、请求封装、字段映射、上传鉴权、入口路由和必要的页面状态逻辑。
建议新增:
client/practical-examiner/ 考评员手机端前端
templates/index-practical-examiner.html
/practical-examiner/ 考评员手机端页面入口
核心页面:
| 页面 | 能力 |
|---|---|
| 登录 | 项目/活动入口、手机号、验证码 |
| 任务列表 | 展示可评分任务、剩余数量、时间状态 |
| 任务详情 | 评分规则、评分表、考生状态统计 |
| 考生列表 | 待评分、评分中、已完成、待签字 |
| 评分页 | 按评分表逐项打分、备注、保存草稿、提交 |
| 签字页 | 对需要确认的评分结果签字 |
| 人脸核验 | 按活动配置触发考评员核验 |
管理端:
request.tenant 和 request.operator。考评员端:
PracticalExaminerAuthBaseView。PracticalExaminerAuthBaseView 的登录态和 PracticalExaminer 会话。关键校验:
| 场景 | 建议 |
|---|---|
| 考评员登录态 | 新增 practical_session Redis alias,或复用专属缓存配置 |
| 评分草稿 | 一期可直接写 MySQL;如现场高并发明显,再引入 Redis 草稿 |
| 批量导入 | 复用 progressbar 和 import_export_file 队列 |
| 成绩导出 | 异步生成文件 |
| 签字和照片 | 使用 Kaola 现有 OSS/本地存储抽象 |
| 人脸核验 | 先封装服务接口,供应商实现可替换 |
app/practical。Form 评分表绑定、活动、考生、考评员、任务、评分服务。/dapi/practical/examiner/ API,覆盖旧 yj-examiner 的现场评分能力。PracticalScoreResult。client/manager 增加实操考评菜单。yj-examiner 迁入 client/practical-examiner,复用页面和核心交互,并按 Kaola 原型调整产品流程。/dapi/practical/examiner/,完成字段映射、登录态、上传凭证和响应结构迁移。/tenant/api/practical/... 下提供外部 API。APIView 鉴权、加密解析和日志。后端测试:
/dapi/practical/examiner/ API、外部 API。yj-examiner 请求层到新手机端 API 的字段映射、响应转换和错误处理。端到端验收:
Practical 模块负责绑定、快照和评分上下文。yj-examiner 迁入 Kaola client 时,必要情况下可以修改页面状态逻辑。建议按独立 app/practical 模块建设,不复用 Kaola 现有元实操题链路,也不复用 enrollment、schedule、exam.Entry、outcome.Result 主链路。迁移目标是表现一致:旧系统中“活动、评分表、考生、考评员、任务、手机评分、签字/人脸、进度、成绩导出、外部创建任务”等能力,需要在 Kaola 中重新实现;旧数据不迁移,旧表不照搬。评分表基础结构使用现有 content.Form 大 JSON 表达,评分表入口放在试卷/试卷编辑侧,Practical 模块负责现场考评自己的考生、任务、评分记录和最终得分。考评员端一期迁入 client/practical-examiner,复用旧 yj-examiner 的页面和核心交互,按 Kaola 原型调整流程,并通过 /dapi/practical/examiner/ 接入独立认证的手机端 API;外部开放接口不兼容旧 kp,统一放到 /tenant/api/practical/...,并复用易考现有 APIView 鉴权体系。