86 KiB
智慧培训系统一期详细开发说明书
版本:V1.0 设计评审稿
日期:2026年9月10日
适用范围:现有若依前后端分离原型、同一个若依后端、Kingbase数据库、模拟设备及学习系统数据。
本文把一期需求转化为可分工的开发方案:用户从哪里操作,前端调用哪个HTTP接口,后端由哪个Service处理,读写什么数据,影响哪些模块,以及怎样验收。现有14组训练业务CRUD属于可复用基础,尚未经过本次代码审计。本文的路径、方法、字段和表名是建议契约,不表示已在工程中存在,也不直接构成可执行迁移脚本。
阅读顺序
- 产品和实施人员先看第1至4章,理解系统边界、角色和操作主线。
- 前端、后端开发共同看第5章及第6章九模块说明,按业务动作协作。
- 后端和数据库开发重点看第7至10章,落实关联、状态、事务和接口细节。
- 测试和交付人员看第11至13章,建立可复现部署与验收清单。
1 设计依据与边界
1.1 已确认的项目条件
- 在现有若依系统内完善一期业务,前后端分离,各业务模块在同一个后端进程中。
- 已有14组训练业务CRUD及Kingbase数据库;数据库迁移、权限、接口和业务联动尚未闭环。
- 前端和后端最终部署在指定内网机器;实际端口、运行环境、若依分支、驱动和数据库兼容模式待工程盘点确认。
- 第一版使用模拟人员、设备及学习数据,保存、查询、权限和状态处理按真实业务实现。
- 一期原始范围包括课程资源、开班、报到、宿舍授权、签到、成绩、学习时长及画像;功能分析进一步明确九个模块的详细要求。
- 二期平板控制、智慧照明、数字孪生监测、工具箱控制、摄像机调阅不在本文实施范围内。
1.2 文中的三类标记
| 标记 | 含义 | 处理原则 |
|---|---|---|
| 原始要求 | 来源于一期需求或用户提供的功能分析 | 必须在需求清单中保留,未实现要明确标识 |
| 建议实现 | 为实现要求补充的数据结构、页面、接口或处理机制 | 可按现有工程调整,保持业务语义和验收结果 |
| 待定规则 | 原文尚未规定具体取值或边界 | 不宣称已确认;演示值写入独立配置,正式验收前确认 |
人员与参训状态分离、参训表、课次表、入住表、持久化待执行命令、请求幂等、资源引用保护属于建议实现。超额报名、报到请假例外、成绩权重、结业门槛和退宿时机属于待定规则。
2 系统架构与代码职责
2.1 两种调用边界
前端通过HTTP调用后端Controller;同一后端内,Controller调用Service,Service之间通过Java方法协作。Mapper只负责数据库访问。业务模块互相协作时不发送绕回本机的HTTP请求。
模拟或真实外部系统通过独立的接入适配器通信。后台任务也直接调用内部服务,而不是模拟用户登录后请求页面。
flowchart TD
U["管理员、教师、学员的浏览器"] --> V["前端页面和API请求函数"]
V --> C["Controller:认证、权限、参数及响应"]
C --> B["业务Service:状态、规则及事务"]
B --> O["其他模块的内部Service"]
B --> M["Mapper与统计查询"]
O --> M
M --> D[("Kingbase")]
J["后台任务"] --> B
B --> A["设备接入适配器"]
A --> X["模拟门锁及学习系统"]
X --> I["受控接入入口"]
I --> B
2.2 建议代码组织
保留现有项目结构,在培训业务目录下按业务包组织,不要求重建整个工程。
| 位置 | 职责 | 示例 |
|---|---|---|
| 前端 views/training | 页面、表单、详情、按钮及状态显示 | class、report、dorm、score等页面 |
| 前端 api/training | HTTP方法、路径、参数及响应处理 | confirmReport、publishScore |
| 后端 training/*/controller | 接收外部请求、参数校验、功能权限、统一返回 | ReportController |
| 后端 training/*/service | 业务规则、数据权限、跨模块调用及事务边界 | ReportService、StayService |
| 后端 training/*/mapper | SQL及持久化操作 | ReportMapper、StayMapper |
| 后端 training/*/dto | 操作请求对象,限制前端可提交字段 | ReportConfirmRequest |
| 后端 training/*/vo | 页面响应对象及联动结果 | ReportResult |
| 后端 training/*/domain | 存储实体 | Enrollment、Lesson |
| 后端 training/integration | 外部标识映射、事件接收及适配器 | MockDoorAdapter |
| 后端 training/job | 到期检查、下发重试、快照和导出任务 | DoorCommandJob |
| 数据库版本脚本目录 | 基线、升级、基础配置和演示数据 | 编号有序的迁移文件 |
Service负责模块写入规则。其他模块应通过所属模块Service修改其业务数据;统计模块可以使用专门的跨表只读查询。禁止前端用多个普通CRUD请求拼成一个需要事务保障的业务动作。
3 谁使用系统
以下是建议角色分工,不等于原型已配置完成。管理员、教师、学员为原文要求的预置角色,细分权限使用现有若依自定义角色承载。
| 使用者 | 登录和入口 | 主要操作 | 数据范围 |
|---|---|---|---|
| 管理员 | 若依后台 | 基础资料、开班、名单、报到、住宿、发布审批、规则及统计 | 按授权范围,演示管理员可管理演示业务 |
| 教师 | 同一个若依前端 | 课程维护、本人授课安排、所带班级签到和成绩、统计画像 | 通过账号与教师及授课关系限定 |
| 学员 | 同一前端中的个人菜单 | 本人课表、报到结果、住宿、已发布成绩、学习记录和画像 | 仅本人;是否开放全部个人菜单为建议实现 |
| 报到一体机 | 模拟控制台或后续设备界面 | 身份核验、报到、分配信息查询 | 设备授权的班次和操作;不获得管理员通用权限 |
| 电子班牌、学习及实训系统 | 接入接口 | 上报签到、学习使用和成绩 | 各自设备或系统的数据范围 |
| 门锁系统 | 被后端适配器调用 | 接收下发、撤销等命令并返回结果 | 指定设备和授权 |
| 后台任务 | 后端调度器 | 证书预警、报到超期、门锁到期与重试、画像快照、异步导出 | 服务内置范围,保留任务身份和执行记录 |
教师具备某个功能权限,还必须满足班级数据权限。学员查看接口从登录身份确定studentId,不直接信任前端传入的其他学员ID。是否由教师担任发布者或审批者通过权限分配控制;第一版建议管理员审批,避免默认让申请人审批自己。
3.1 前端菜单与业务入口
| 菜单 | 页面与主要按钮 | 主要使用者 |
|---|---|---|
| 人员管理 | 教师列表、证书、授课履历;学员列表、导入、人脸、状态、轨迹 | 管理员;教师只读授权范围 |
| 课程管理 | 课程列表、编辑、资源、版本、提交审核、发布及归档 | 管理员、获授权教师 |
| 培训班管理 | 开班列表、复制、名单、课表、报名计数、状态与结业 | 管理员;教师查询所带班级 |
| 报到管理 | 选择班次、识别模拟、人工核验、住宿确认、完成报到 | 管理员、报到终端 |
| 宿舍管理 | 房间床位、预分配、入住、换宿、退宿、授权、重试、临时密码 | 管理员 |
| 签到管理 | 课次名单、自动签到结果、补签、编辑、异常及补采入口 | 管理员、所带班级教师 |
| 成绩管理 | 考核项目、录入、导入、提交、发布、变更审批、历史、导出 | 管理员、授权教师 |
| 数据接入 | 模拟事件、接入批次、失败记录、映射修复、重处理 | 管理员或专门接口运维角色 |
| 学习记录 | 使用明细、来源、时间、异常审核 | 管理员、授权教师;本人只读 |
| 统计与画像 | 时间筛选、班级及课程统计、明细下钻、导出任务、个人画像 | 管理员、授权教师、本人 |
| 系统管理 | 用户、角色、权限、配置、任务、审计 | 管理员 |
这些菜单是页面组织建议,九模块是需求分组;例如签到既有课程业务维护,又有数据接入入口,不应因此保存两套互不关联的最终考勤数据。
4 从浏览器操作到数据库的整条流转
演示对象:张三参加钢结构实训第一期。以下采用“报到办理页内确认住宿后完成报到”的建议实现,兼容提前分配宿舍。
| 顺序 | 用户操作 | 前端请求 | 后端处理与内部协作 | 数据库变化 | 页面联动 |
|---|---|---|---|---|---|
| 1 | 登录 | 现有若依登录接口 | 认证并读取功能权限 | 会话及适用日志;读取用户角色关系 | 展示允许的菜单 |
| 2 | 准备教师、学员、课程和场地 | 对应基础资料接口 | 校验并保存;资源预览与保护按规则 | 基础表、资源关联 | 开班表单能选择这些对象 |
| 3 | 创建培训班 | POST /training/class-plans | 课程教师校验、时间冲突告警、保存计划 | class_plan | 班次列表、教师授课关联 |
| 4 | 将张三加入本期 | POST /training/class-plans/{planId}/enrollments | 检查名单重复与报名规则、计数提醒 | enrollment | 班级名单、学员参训轨迹 |
| 5 | 新增课次 | POST /training/class-plans/{planId}/lessons | 保存时间、教师、教室、实训场地关联 | lesson | 课表、报到查询、签到选择 |
| 6 | 模拟身份识别 | POST /training/reports/identify | MockIdentityAdapter核验并生成短期识别凭据;有效人脸按规则同步 | 可追溯核验记录、人脸档案 | 展示匹配学员和报到状态 |
| 7 | 确认住宿并完成报到 | POST /training/reports/confirm | ReportService校验资格;StayService确认分配;DoorAuthService生成待下发记录 | 报到、入住、授权及命令在本地事务中保存 | 已报到、住宿信息、授权待处理、课表 |
| 8 | 后台执行模拟授权 | 无需页面再次请求 | 命令任务读取待执行记录,调用MockDoorAdapter,保存结果 | 命令结果、尝试记录、授权状态 | 前端刷新显示成功或失败可重试 |
| 9 | 模拟签到或人工补签 | 接入事件接口或签到业务接口 | 验证身份与课次,设备事件去重,保存记录 | 原始接入事件及签到记录 | 课次名单、出勤统计 |
| 10 | 录入或导入成绩 | 成绩录入、导入、提交、发布接口 | ScoreService归属校验、计算、状态校验、发布锁定 | 成绩、项目、历史和导入批次 | 分项成绩及按口径形成的统计 |
| 11 | 生成模拟学习记录 | 接入事件接口 | 保存来源、开始结束时间、关联和异常状态 | 使用明细与接入事件 | 学习时长及异常列表 |
| 12 | 查看统计与画像 | GET统计及画像接口 | 统计读取统一口径;画像应用规则,明细可追溯 | 当前画像按策略保存;历史快照由任务生成 | 图表、标签、推荐清单 |
| 13 | 办理本期结业 | POST /training/class-plans/{planId}/completion-batches | CompletionService只处理选定的有效参训关系;联动相应权限 | 参训状态、状态历史、权限命令;退宿条件满足才结束入住 | 已结业、权限处理状态、历史档案 |
4.1 页面更新方式
变更接口返回后,前端刷新受影响列表或详情;不要求同时修改所有已打开页面。授权等异步动作通过任务状态查询轮询或手动刷新展示。第一版不强制引入WebSocket。报表默认从当前业务数据按口径查询;若使用缓存,成绩发布、签到修订等动作必须失效相关缓存。历史画像快照不会被当前数据变更直接覆盖。
4.2 同一个后端的处理边界
sequenceDiagram
participant U as 报到页面
participant R as ReportService
participant S as StayService与DoorAuthService
participant D as Kingbase
participant J as 授权执行任务
U->>R: 确认本次参训报到及床位
R->>D: 锁定并检查资格及现有报到
R->>S: 内部调用确认入住和待授权
S->>D: 保存入住、授权和待执行命令
R->>D: 保存报到并提交事务
R-->>U: 已报到、住宿安排、授权待处理
J->>D: 领取已提交的待执行命令
J->>J: 调用模拟适配器
J->>D: 保存结果和重试信息
U->>R: 刷新报到结果
R-->>U: 返回最新授权状态
5 接口约定与权限规则
5.1 对外与内部的含义
“对外HTTP接口”表示后端提供给浏览器、受控终端或接入系统的入口,不表示互联网公开或匿名可用。内部Service方法仅供本后端其他服务和后台任务调用。查询与业务命令分离,GET不得触发发布、冻结或补采等变更。
本文以 /training 为业务API前缀。列表用GET,创建及业务动作通常用POST,普通资料编辑用PUT;DELETE仅用于明确允许删除的数据。已报到、已发布、已授权等关键状态不得通过通用编辑接口任意改写。
5.2 通用输入输出
| 项目 | 建议契约 |
|---|---|
| 登录身份 | 复用现有若依会话或令牌;actorId、教师和学员账号映射由后端取得 |
| 分页 | pageNum、pageSize;列表返回rows、total,适配现有前端封装 |
| 单对象响应 | code、msg、data,优先兼容现有若依响应包装 |
| 标识 | API将业务ID作为字符串传递,具体生成方式和数据库长度与现有工程统一 |
| 时间 | 对外使用带时区偏移的ISO 8601;基地时区集中配置;实际持久化按数据库类型转换 |
| 枚举 | 本文使用语义化状态码;若现有库用数值,应建立明确映射,不混用 |
| 并发版本 | 可编辑的关键对象携带version;更新冲突返回可识别业务码 |
| 重复请求 | 报到、分床、发布、结业和设备事件采用业务唯一约束及幂等标识 |
| 错误 | msg为用户可理解说明,businessCode区分原因;具体HTTP与code映射统一到现有拦截器 |
| 文件 | 导入走multipart;模板、反馈报告和导出下载执行同等权限检查;返回受控文件标识或链接 |
| 批量操作 | 返回成功项、失败项及原因;不得只返回“成功”而吞掉部分失败 |
建议业务码:INVALID_STATE、ENROLLMENT_NOT_FOUND、ALREADY_ENROLLED、REPORT_EXPIRED、BED_CONFLICT、SCORE_LOCKED、VERSION_CONFLICT、EVENT_CONFLICT、DATA_OUT_OF_SCOPE。重复且内容一致的幂等请求返回已保存结果;同一幂等键但内容不同返回冲突。未登录与越权由统一安全机制处理,前端不能只根据按钮是否可见判断授权。
5.3 权限码和数据范围
各模块使用 training:{resource}:{action} 形式,例如 training:report:confirm、training:score:publish。菜单、按钮和Controller按同一权限码配置;Service仍检查班级、学员和设备范围。
所有批量操作、导入、导出、详情、统计、画像及任务下载都要落实数据范围。教师的班级范围由账号→教师档案→有效授课关系取得;“本人数据”由账号→学员档案取得;不能将若依部门权限直接视为培训班权限已完成。
5.4 模拟入口
第一版可让管理员在“数据接入模拟控制台”选择事件类型,调用 /training/mock/events,由MockAdapter生成可信的模拟系统身份,再复用正式事件处理服务。/training/integration/* 保留为受控系统接入契约,必须完成相应认证后才启用,不能为便于演示而设为公开接口。
模拟设备返回成功、失败和重复事件,可配置用于验收。真实人脸识别质量、硬件联通和设备实际撤销效果不属于模拟结果能证明的事项。
6 九个模块的详细开发契约
模块表中A表示获授权管理员,T表示获授权且处于数据范围内的教师,S表示本人学员,D表示经过认证且限定范围的设备或接入系统,J表示后台任务。角色列是建议分工;实际赋权可通过自定义角色调整,不改变数据范围检查。接口路径按本说明书统一建议,实际工程若已有等价接口,应映射复用并更新文档。
6.1 人员管理
**模块责任:**维护人的基础档案;参训、报到和成绩不在人员表中重复维护。
**前端操作:**教师列表→详情中的授课履历与证书;学员列表→导入或详情,详情中集中展示参训、报到、住宿、签到、成绩和画像。编辑只提交允许修改的基础字段;状态使用专门动作。
对应原始需求
| 需求ID | 具体要求 |
|---|---|
| P01 | 教师信息查看和编辑,包含个人基本情况及授课信息 |
| P02 | 教师授课履历按学期或年份筛选并用时间轴展示 |
| P03 | 教师资质证书有效期预警,到期前自动提醒 |
| P04 | 离职教师逻辑删除并冻结账号,保留历史数据 |
| P05 | 记录教师所有编辑行为 |
| P06 | 学员基本情况、人脸、课程和学习信息查询编辑;支持多张底库照片 |
| P07 | 学员基础资料Excel模板下载与批量导入 |
| P08 | 在读、休学、结业、退学等状态流转,按范围联动门禁及签到权限 |
| P09 | 身份证等指定敏感字段加密存储 |
| P10 | 学员全生命周期学习轨迹时间线 |
提供的HTTP接口
| 接口ID | 方法 | 路径或复用入口 | 调用者 | 输入与结果 | 需求ID |
|---|---|---|---|---|---|
| P-API01 | GET | /training/teachers | A/T | 筛选姓名、工号、状态→分页教师资料 | P01 |
| P-API02 | GET | /training/teachers/{teacherId} | A/T | 教师ID→基础资料与允许查看的授课摘要 | P01 |
| P-API03 | POST | /training/teachers | A | 基本资料、可选userId→teacherId | P01 |
| P-API04 | PUT | /training/teachers/{teacherId} | A | 可编辑字段、version→更新版本 | P01,P05 |
| P-API05 | GET | /training/teachers/{teacherId}/teaching-history | A/T | semester/year→开班及授课时间轴 | P02 |
| P-API06 | GET | /training/teachers/{teacherId}/certificates | A/T | 教师ID→证书及到期情况 | P03 |
| P-API07 | POST | /training/teachers/{teacherId}/certificates | A | 证书、有效期及提醒规则→certificateId | P03 |
| P-API08 | PUT | /training/teachers/{teacherId}/certificates/{certificateId} | A | 证书变更、version→结果 | P03,P05 |
| P-API09 | POST | /training/teachers/{teacherId}/departure | A | 生效时间、原因、version→档案及账号处理结果 | P04,P05 |
| P-API10 | GET | /training/students | A/T | 筛选姓名、学号、班次→范围内学员分页 | P06 |
| P-API11 | GET | /training/students/{studentId} | A/T | 学员ID→脱敏基础资料及允许查看的关联摘要 | P06 |
| P-API12 | POST | /training/students | A | 基本资料→studentId | P06,P09 |
| P-API13 | PUT | /training/students/{studentId} | A | 允许编辑的基础字段、version→结果 | P06,P09 |
| P-API14 | GET | /training/students/import-template | A | 无业务输入→Excel模板 | P07 |
| P-API15 | POST | /training/students/imports | A | multipart文件→导入批次、逐行成功和错误反馈 | P07,P09 |
| P-API16 | GET | /training/students/{studentId}/faces | A | 学员ID→授权可见照片引用及采集来源 | P06 |
| P-API17 | POST | /training/students/{studentId}/faces | A | 图片或受控文件引用、来源→faceId | P06 |
| P-API18 | DELETE | /training/students/{studentId}/faces/{faceId} | A | 原因→照片停用及关联重检结果 | P06 |
| P-API19 | POST | /training/students/{studentId}/status-transitions | A | 目标状态、影响范围、原因、version→状态及权限任务 | P08 |
| P-API20 | GET | /training/students/{studentId}/timeline | A/T | 时间范围、事件类型→业务轨迹 | P10 |
| P-API21 | GET | /training/me/profile | S | 从登录身份解析学员→本人档案及脱敏信息 | P06 |
| P-API22 | GET | /training/me/timeline | S | 时间范围→本人轨迹 | P10 |
内部Service及调用方
| 方法契约 | 由谁调用 | 处理责任 |
|---|---|---|
| PersonQueryService.requireStudent(studentId) | 班次、报到、签到、成绩服务 | 返回存在且满足人员基础可用条件的档案;本期资格由EnrollmentService判断 |
| TeacherQueryService.requireTeacher(teacherId) | ClassPlanService、LessonService | 返回教师信息,用于授课校验 |
| FaceService.storeVerifiedFaces(studentId,files,source) | ReportService | 验证文件归属和核验来源,新增或去重照片引用 |
| FaceService.getActiveFaces(studentId) | DoorAuthService、IdentityAdapter | 返回授权范围内的有效照片引用 |
| StudentStatusService.transition(command) | Controller、CompletionService | 保存状态历史;仅按明确范围产生权限处理,不将单期结业自动变成全局停用 |
| CertificateReminderJob.run(now) | 调度器 | 检查提醒条件并幂等生成提醒,供教师或管理员查看 |
数据库与联动
读写train_teacher、train_student;新增或复用教师证书、人脸档案、状态历史、账号关联和通知记录。轨迹从参训、报到、入住、签到、学习、成绩及画像历史查询,不在学员表保存整条重复轨迹。
教师离职后历史授课仍可查询;未来开班的教师冲突或可用性重新检查。人脸变更对已下发设备如何同步需形成重下发策略;停用照片不等于设备端自动删除。
6.2 课程管理
**模块责任:**管理可复用课程、资源、版本与状态,并承接人工签到业务。
**前端操作:**课程列表→编辑→资源上传和预览→版本记录→提交审核;发布后供开班选择。签到页面按班次和课次显示应到名单,人工新增、补签、编辑、删除保留原因。
对应原始需求
| 需求ID | 具体要求 |
|---|---|
| C01 | 课程创建、编辑、删除、查看;唯一业务编码、名称、类型、时长、目标和内容 |
| C02 | 关联文档、视频、3D拆解模型和实训场景资源 |
| C03 | 课程版本管理 |
| C04 | 草稿、待审核、已发布、已归档状态 |
| C05 | 配套资料预览及格式、大小校验 |
| C06 | 热门、初级、进阶等课程标签 |
| C07 | 课程签到创建、编辑、删除和查看,人工维护与自动采集互补 |
提供的HTTP接口
| 接口ID | 方法 | 路径或复用入口 | 调用者 | 输入与结果 | 需求ID |
|---|---|---|---|---|---|
| C-API01 | GET | /training/courses | A/T | 编码、名称、类型、状态、标签→课程分页 | C01,C06 |
| C-API02 | GET | /training/courses/{courseId} | A/T | 课程ID→内容、资源、状态、当前版本 | C01,C02,C03 |
| C-API03 | POST | /training/courses | A/T | 课程基本内容→courseId和草稿版本 | C01,C04 |
| C-API04 | PUT | /training/courses/{courseId} | A/T | 草稿内容、version→新版本或编辑结果 | C01,C03 |
| C-API05 | DELETE | /training/courses/{courseId} | A/T | 原因、引用检查→允许时删除或明确拒绝 | C01 |
| C-API06 | POST | /training/courses/{courseId}/resources | A/T | 文件或资源链接、资源类型→resourceId | C02,C05 |
| C-API07 | DELETE | /training/courses/{courseId}/resources/{resourceId} | A/T | 课程资源关联→移除结果 | C02 |
| C-API08 | GET | /training/resources/{resourceId}/preview | A/T/S | 资源ID及访问范围→受控预览信息 | C05 |
| C-API09 | GET | /training/courses/{courseId}/versions | A/T | 课程ID→版本列表及变化 | C03 |
| C-API10 | POST | /training/courses/{courseId}/submit | A/T | version→待审核 | C04 |
| C-API11 | POST | /training/courses/{courseId}/reviews | A | approve/reject、意见、version→已发布或退回草稿 | C04 |
| C-API12 | POST | /training/courses/{courseId}/archive | A/T | 原因、version→已归档 | C04 |
| C-API13 | PUT | /training/courses/{courseId}/tags | A/T | 标签集合→更新后的标签 | C06 |
| C-API14 | GET | /training/checkins | A/T | planId、lessonId、学员、状态→签到分页 | C07 |
| C-API15 | POST | /training/checkins/manual | A/T | enrollmentId、lessonId、考勤结果、原因→checkinId | C07 |
| C-API16 | PUT | /training/checkins/{checkinId} | A/T | 允许的人工更正、原因、version→更正结果 | C07 |
| C-API17 | DELETE | /training/checkins/{checkinId} | A/T | 原因、version→业务作废结果 | C07 |
| C-API18 | GET | /training/me/checkins | S | 时间或本期筛选→本人考勤 | C07 |
内部Service及调用方
| 方法契约 | 由谁调用 | 处理责任 |
|---|---|---|
| CourseService.requirePublishedVersion(courseId,versionId) | ClassPlanService | 建议绑定发布版本,后续课程修改不改变历史班次内容 |
| ResourceService.getAuthorizedPreview(resourceId,actor) | 课程及画像查询 | 验证使用范围,返回可预览资源 |
| AttendanceService.acceptEvent(event) | IntegrationService | 执行业务去重并形成签到记录,与人工维护共用数据 |
| AttendanceService.revise(command) | 签到Controller | 校验班次权限、课次、人工更正原因并留痕 |
| AttendanceQueryService.calculate(scope) | StatisticsService | 按应到范围、请假等口径计算出勤,并可追溯明细 |
数据库与联动
读写train_course、train_student_checkin;新增课程版本、资源和课程资源关系、课次;标签可采用标签关系表。原始设备流水与最终考勤业务记录分离保存,人工更正不篡改原始事件。
发布课程可被开班绑定;归档不删除历史关系。签到更正后相关当前统计重新计算或清除缓存,画像月度快照保留当时版本。
6.3 学习班管理
**模块责任:**组织一次培训:课程教师、参训名单、课次、报到和时效。
**前端操作:**管理员在班次工作台操作“基本信息、参训名单、课表、报到、成绩、统计、结业”页签。该工作台调用各模块已有接口,不复制其业务规则。
对应原始需求
| 需求ID | 具体要求 |
|---|---|
| B01 | 开班计划创建编辑删除查看,包含课程、时间、地点、教师、人数和报名条件 |
| B02 | 计划状态未开始、报名中、进行中、已结束、已取消 |
| B03 | 报名实时计数,达到招生人数90%时提醒教师 |
| B04 | 支持复制开班计划 |
| B05 | 同一时间同一教师冲突自动告警 |
| B06 | 一体机身份证或人脸报到,完成后获取宿舍、教室、实训场地和课表 |
| B07 | 人脸同步学员模块,分配结果同步宿舍模块并触发授权 |
| B08 | 报到状态未报到、已报到、请假、放弃 |
| B09 | 开班后X日未报到按规则取消资格并释放宿舍资源 |
| B10 | 人脸识别失败进入管理员人工核验 |
提供的HTTP接口
| 接口ID | 方法 | 路径或复用入口 | 调用者 | 输入与结果 | 需求ID |
|---|---|---|---|---|---|
| B-API01 | GET | /training/class-plans | A/T | 名称、状态、时间→可见班次 | B01,B02 |
| B-API02 | GET | /training/class-plans/{planId} | A/T | 班次ID→基本资料、计数、状态、允许动作 | B01,B03 |
| B-API03 | POST | /training/class-plans | A | 课程版本、教师、起止时间、人数及条件→计划ID及告警 | B01,B05 |
| B-API04 | PUT | /training/class-plans/{planId} | A | 允许字段、version→变更结果及冲突告警 | B01,B05 |
| B-API05 | DELETE | /training/class-plans/{planId} | A | 原因→仅无业务引用等允许条件下删除 | B01 |
| B-API06 | POST | /training/class-plans/{planId}/copy | A | 新名称和新时间等→新计划草稿 | B04 |
| B-API07 | POST | /training/class-plans/{planId}/transitions | A | 目标状态、原因、version→状态及联动摘要 | B02 |
| B-API08 | GET | /training/class-plans/{planId}/enrollments | A/T | 学员和状态筛选→名单及计数 | B03,B06 |
| B-API09 | POST | /training/class-plans/{planId}/enrollments | A | studentIds、幂等键→逐项加入结果及人数提醒 | B03 |
| B-API10 | POST | /training/enrollments/{enrollmentId}/transitions | A | 目标状态、原因、范围、version→参训变更及权限任务 | B08,B09 |
| B-API11 | GET | /training/class-plans/{planId}/lessons | A/T | 时间筛选→课表及教室实训场地 | B06 |
| B-API12 | POST | /training/class-plans/{planId}/lessons | A | 时间、教师、教室、场地→课次ID及告警 | B05,B06 |
| B-API13 | PUT | /training/lessons/{lessonId} | A | 安排变更、version→更新及关联重检结果 | B05,B06 |
| B-API14 | POST | /training/lessons/{lessonId}/cancel | A | 原因、version→课次取消及考勤范围更新 | B06 |
| B-API15 | POST | /training/reports/identify | A/D | planId、识别方式及模拟身份输入→核验结果或待人工核验ID | B06,B10 |
| B-API16 | POST | /training/reports/verifications/{verificationId}/decision | A | 通过/拒绝、原因→可用核验凭据或拒绝结果 | B10 |
| B-API17 | POST | /training/reports/confirm | A/D | enrollmentId、核验凭据、住宿选择、幂等键→报到及分配结果 | B06,B07,B08 |
| B-API18 | GET | /training/reports | A/T | planId、状态、学员→报到分页 | B08 |
| B-API19 | GET | /training/reports/by-enrollment/{enrollmentId} | A/T/D | 参训ID→报到、住宿、场地、课表和授权状态 | B06 |
| B-API20 | POST | /training/reports/{reportId}/status-transitions | A | 请假/放弃等目标、原因、version→状态及适用联动 | B08 |
| B-API21 | POST | /training/class-plans/{planId}/completion-batches | A | enrollmentIds、原因、幂等键→结业批次及逐项结果 | B02 |
| B-API22 | GET | /training/me/class-plans | S | 本人身份→本人参训班次及报到结果 | B06 |
| B-API23 | GET | /training/me/timetable | S | 时间范围→本人的课表和场地 | B06 |
内部Service及调用方
| 方法契约 | 由谁调用 | 处理责任 |
|---|---|---|
| EnrollmentService.requireReportableForUpdate(enrollmentId) | ReportService | 先锁参训并确认范围;已成功报到的幂等重放应返回现有结果,首次办理再检查时效 |
| ClassPlanService.validateSchedule(command) | 开班及课次Controller | 查教师冲突并返回告警;是否允许继续按配置,不擅自将告警变成强制阻断 |
| ReportService.confirm(command) | 报到Controller | 协调核验、参训、入住及授权任务,在本地事务内保存业务结果 |
| ReportQueryService.result(enrollmentId,actor) | 报到Controller、工作台 | 聚合已有记录返回宿舍、教室、场地和课表,不另存多份事实 |
| ReportDeadlineJob.run(now) | 调度器 | 按截止时间和请假例外锁定复核对象,取消不合规资格并释放相应预占 |
| CompletionService.completeBatch(command) | 班次Controller | 逐参训执行结业,明确每项事务和结果,权限任务失败不伪装为整批回滚 |
数据库与联动
读写train_class_plan、train_class_report;新增train_enrollment、train_lesson、核验记录和结业批次记录。住宿事实由StayService维护,报到表只引用入住或展示快照。报名计数从有效参训关系计算,必要缓存需同步失效。
新增名单影响人数、应到名单和轨迹;课次取消影响考勤分母。开班延期需识别授权期限变更并生成设备更新任务,不能只改计划结束时间。计划取消对已报到、已入住人员的处理必须通过业务服务,不是直接批量删表。
6.4 宿舍管理
**模块责任:**独立管理宿舍资源、入住分配和开门权限,供报到及结业服务调用。
**前端操作:**宿舍页面展示四级资源、床位和入住;分配页可建议床位或人工调整。权限页显示业务有效期与设备执行状态两个维度,并提供重试、撤销、临时授权及历史查询。
对应原始需求
| 需求ID | 具体要求 |
|---|---|
| D01 | 宿舍信息查看编辑,楼栋楼层房间床位四级编码 |
| D02 | 宿舍状态空置、部分入住、已满、维修中 |
| D03 | 按性别和培训班配置自动分配规则,优先同班同寝 |
| D04 | 开门权限查看编辑,按分配结果自动下发人脸至对应智能锁 |
| D05 | 下发记录包含时间、成功失败结果及失败重试次数 |
| D06 | 授权有效期与开班结束时间联动,结业后自动过期失效 |
| D07 | 管理员短期开门密码临时授权 |
| D08 | 权限审计日志 |
提供的HTTP接口
| 接口ID | 方法 | 路径或复用入口 | 调用者 | 输入与结果 | 需求ID |
|---|---|---|---|---|---|
| D-API01 | GET | /training/dormitories | A | 楼栋、楼层、状态→房间与占用情况 | D01,D02 |
| D-API02 | POST | /training/dormitories | A | 楼栋、楼层、房间及设备→dormId | D01 |
| D-API03 | PUT | /training/dormitories/{dormId} | A | 资料、维修状态、version→结果 | D01,D02 |
| D-API04 | GET | /training/dormitories/{dormId}/beds | A | 时间区间→床位和有效占用 | D01,D02 |
| D-API05 | POST | /training/dormitories/{dormId}/beds | A | 床位编码及可用状态→bedId | D01 |
| D-API06 | PUT | /training/beds/{bedId} | A | 可维护字段、version→资源结果 | D01,D02 |
| D-API07 | GET | /training/dorm-allocation-rules | A | 无→匹配规则 | D03 |
| D-API08 | PUT | /training/dorm-allocation-rules | A | 性别、同班优先等规则→配置版本 | D03 |
| D-API09 | POST | /training/stays/suggestions | A | enrollmentIds、入住区间→建议分配,不占用床位 | D03 |
| D-API10 | POST | /training/stays | A | enrollmentId、bedId、区间、幂等键→分配结果及授权任务 | D03,D04 |
| D-API11 | GET | /training/stays | A | 学员、班次、房间、状态→入住分页 | D01,D02 |
| D-API12 | POST | /training/stays/{stayId}/transfer | A | 新bedId、时间、原因、version→新旧入住及授权处理 | D03,D04 |
| D-API13 | POST | /training/stays/{stayId}/checkout | A | 退宿时间、原因、version→资源释放及权限任务 | D02,D06 |
| D-API14 | GET | /training/door-authorizations | A | 班次、学员、房间、状态→授权分页 | D04 |
| D-API15 | POST | /training/door-authorizations/{authId}/changes | A | 允许的期限等变更、原因、version→更新命令 | D04,D06 |
| D-API16 | POST | /training/door-authorizations/{authId}/revoke | A | 原因、幂等键→撤销任务 | D06,D08 |
| D-API17 | POST | /training/door-authorizations/temporary | A | 设备、对象、有效期→受控临时凭据及授权记录 | D07 |
| D-API18 | GET | /training/door-authorizations/{authId}/attempts | A | authId→各次下发时间、结果、失败及次数 | D05,D08 |
| D-API19 | POST | /training/door-commands/{commandId}/retry | A | 原因→重新排队或已有任务状态 | D05 |
| D-API20 | GET | /training/me/accommodation | S | 本人及所选有效参训→住宿与本人权限摘要 | D04 |
内部Service及调用方
| 方法契约 | 由谁调用 | 处理责任 |
|---|---|---|
| StayService.ensureAllocation(enrollment,choice) | ReportService | 锁定相关床位及参训;复用已有有效分配或新建,建议结果必须在提交时重新校验 |
| StayService.releaseReservation(enrollmentId,reason) | ReportDeadlineJob | 只释放对应预占资源,不误结束其他班次的有效入住 |
| DoorAuthService.ensurePendingAuthorization(enrollment,stay) | ReportService、StayService | 创建唯一授权及待执行命令,与入住业务同事务提交 |
| DoorAuthService.endForEnrollment(enrollmentId,reason) | CompletionService、状态服务 | 按有效范围重新计算设备权限并产生撤销或更新命令 |
| DoorCommandExecutor.execute(commandId) | 任务或重试入口 | 领取任务→校验当前期望状态→外部调用→记录结果;不重复创建入住 |
| DoorExpiryJob.run(now) | 调度器 | 到期独立处理,不能依赖用户先查看画像 |
数据库与联动
保留train_dormitory_info、train_dorm_auth;新增train_dorm_bed、train_dorm_stay、门锁命令及每次执行尝试。资源维护状态与占用计算分开。一个人员同一门锁存在多个有效业务依据时,需要按有效依据合并设备权限,撤销单个班次不能误删其他有效权限。
分配→授权待执行;下发成功→状态页面更新;换宿→旧新关系及命令;到期或结业→权限处理。字段authEnd变化应产生设备更新任务。临时密码避免写入普通审计明文,审计保留操作及期限。
6.5 成绩管理
**模块责任:**保存成绩事实、来源和版本,负责提交发布、修改审批及计算口径。
**前端操作:**教师进入所带班级成绩页,选择考核项目录入或导入。提交后由具备发布权限者发布。已发布记录只显示“申请更正”,审批后形成新版本并重算相关结果。
对应原始需求
| 需求ID | 具体要求 |
|---|---|
| G01 | 课程、实训和考核等多类型成绩查看编辑 |
| G02 | 成绩草稿、已提交、已发布状态 |
| G03 | 发布后锁定,修改需审批 |
| G04 | 按权重自动计算综合成绩 |
| G05 | 每次修改保存历史版本及前后差值 |
| G06 | Excel批量导入导出 |
| G07 | 导入模板校验表头字段格式和学号,错误数据提供下载反馈 |
提供的HTTP接口
| 接口ID | 方法 | 路径或复用入口 | 调用者 | 输入与结果 | 需求ID |
|---|---|---|---|---|---|
| G-API01 | GET | /training/class-plans/{planId}/assessment-items | A/T | 班次→考核项目、满分、权重及采用规则 | G01,G04 |
| G-API02 | POST | /training/class-plans/{planId}/assessment-items | A/T | 项目、类型、满分、权重→itemId | G01,G04 |
| G-API03 | PUT | /training/assessment-items/{itemId} | A/T | 允许配置、version→新配置及重算影响 | G04 |
| G-API04 | GET | /training/scores | A/T | 班次、学员、项目、状态→成绩分页 | G01,G02 |
| G-API05 | POST | /training/scores | A/T | enrollmentId、itemId、分数、次数→scoreId及草稿 | G01,G02,G04 |
| G-API06 | PUT | /training/scores/{scoreId} | A/T | 草稿分数、原因、version→成绩及历史 | G01,G05 |
| G-API07 | POST | /training/scores/submissions | A/T | 同班scoreIds、预期版本→已提交结果 | G02 |
| G-API08 | POST | /training/scores/publications | A或获发布权限T | 同班scoreIds、预期版本→发布批次、综合成绩 | G02,G03,G04 |
| G-API09 | POST | /training/scores/{scoreId}/change-requests | A/T | 新值、原因、基准版本→changeRequestId | G03,G05 |
| G-API10 | POST | /training/score-change-requests/{requestId}/decisions | A或指定审批角色 | approve/reject、意见→审批及更正结果 | G03,G05 |
| G-API11 | GET | /training/scores/{scoreId}/history | A/T | scoreId→历史版本及差值 | G05 |
| G-API12 | GET | /training/scores/import-template | A/T | planId→可用Excel模板 | G06,G07 |
| G-API13 | POST | /training/scores/imports | A/T | planId、multipart文件→批次、逐行结果、错误报告 | G06,G07 |
| G-API14 | GET | /training/score-imports/{batchId} | A/T | 批次→处理状态、摘要、受控反馈下载标识 | G07 |
| G-API15 | GET | /training/scores/export | A/T | 与查询相同的筛选和范围→Excel或受控任务 | G06 |
| G-API16 | GET | /training/me/scores | S | 本人、班次→本人已发布成绩 | G01,G02 |
内部Service及调用方
| 方法契约 | 由谁调用 | 处理责任 |
|---|---|---|
| ScoreService.upsertDraft(command) | 人工Controller、导入、IntegrationService | 统一归属和分数校验;重复外部事件不能覆盖已发布成绩 |
| ScorePublishService.publish(command) | 发布Controller | 建议同班批次全部校验通过后事务发布;保存计算采用的规则版本 |
| ScoreChangeService.decide(command) | 审批Controller | 基准版本冲突则拒绝;审批通过保存前后值并触发重算 |
| ScoreCalculationService.calculate(enrollmentId,ruleVersion) | 发布、更正和统计 | 校验项目、权重、满分及缺考策略,不将未知权重写死 |
| ScoreQueryService.forStatistics(scope) | StatisticsService | 按明确的已发布或过程成绩口径读取 |
数据库与联动
train_score_info建议改为一名参训学员的一次考核项目成绩一条记录;新增考核项目、成绩历史、变更申请和审批记录、导入批次。权重或项目定义修改涉及已发布结果时生成新规则版本或受控修订,不静默重写历史。
录入→草稿;提交→待发布;发布→锁定并进入正式统计;审批更正→新版本、重算、当前画像刷新;已保存月度快照保持历史可解释。
6.6 数据接入
**模块责任:**接收原始事件、匹配业务对象、执行去重及异常处理,再交给业务模块维护最终记录。
**前端操作:**模拟控制台选择来源、学员、班次、事件类型及成功/重复/错误场景。接入日志显示接收、匹配、处理和失败原因;管理员修复映射后重处理,而非直接把失败行改成成功。
对应原始需求
| 需求ID | 具体要求 |
|---|---|
| I01 | 电子班牌人脸或二维码签到自动采集与存储 |
| I02 | 同一学员同一课程1分钟内重复签到只取第一条 |
| I03 | 对接失败时管理员手动拉取最近1小时签到 |
| I04 | 阅览室一体机、听书机、VR、3D拆解和巡检等使用明细,记录开始结束及关联学员 |
| I05 | VR、3D巡检和实操成绩支持批量汇缴或实时采集 |
| I06 | 异常告警,例如单次时长超过课程总时长2倍,标记并通知管理员审核 |
| I07 | 自动签到及成绩与人工维护共同构成完整业务数据源 |
提供的HTTP接口
| 接口ID | 方法 | 路径或复用入口 | 调用者 | 输入与结果 | 需求ID |
|---|---|---|---|---|---|
| I-API01 | POST | /training/mock/events | A或模拟操作角色 | 事件类型、模拟参数→接入事件ID及处理结果 | I01,I04,I05 |
| I-API02 | POST | /training/integration/checkin-events | D | 来源事件ID、人员/课程标识、时间、设备→接收和处理结果 | I01,I02,I07 |
| I-API03 | POST | /training/integration/study-events | D | 来源事件ID、人员标识、开始结束、系统→事件及异常状态 | I04,I06 |
| I-API04 | POST | /training/integration/score-events | D | 来源事件ID、人员/项目标识、分数→接入及草稿结果 | I05,I07 |
| I-API05 | POST | /training/integration/score-batches | D | 来源批次及事件列表→批次与逐项结果 | I05 |
| I-API06 | GET | /training/integration-events | A | 来源、类型、状态、时间→原始事件摘要 | I01,I04,I05 |
| I-API07 | GET | /training/integration-events/{eventId} | A | 事件ID→原始载荷、映射、业务结果及错误 | I01,I04,I05 |
| I-API08 | POST | /training/integration-events/{eventId}/reprocess | A | 修复原因→重新处理或已有结果 | I01,I04,I05 |
| I-API09 | POST | /training/checkin-collections | A | 来源及设备范围→最近1小时补采任务 | I03 |
| I-API10 | GET | /training/external-mappings | A | 来源及对象类型→标识映射 | I01,I04,I05 |
| I-API11 | PUT | /training/external-mappings | A | 来源外部ID及内部ID→映射结果与审计 | I01,I04,I05 |
| I-API12 | GET | /training/study-records | A/T | 学员、来源、时间、异常状态→学习明细 | I04,I06 |
| I-API13 | POST | /training/study-records/{recordId}/reviews | A | 审核结论、原因、version→异常处理结果 | I06 |
| I-API14 | GET | /training/me/study-records | S | 本人、时间及来源→本人学习明细 | I04 |
内部Service及调用方
| 方法契约 | 由谁调用 | 处理责任 |
|---|---|---|
| IntegrationService.acceptEvent(source,event) | 接入Controller、MockEventService | 先记录可信来源和唯一事件,匹配对象后调用业务服务;保存逐项结果 |
| ExternalMappingService.resolve(source,type,externalId) | 各事件处理器 | 映射到有效内部对象,不相信事件任意指定其他来源身份 |
| AttendanceService.acceptEvent(event) | 签到事件处理器 | 同人同课程一分钟窗口业务去重;首次事件与重放结果一致 |
| StudyRecordService.accept(event) | 学习事件处理器 | 保留原始明细,计算时长并检查异常,课程无法匹配时不强行归班 |
| ScoreService.upsertDraft(command) | 成绩事件处理器 | 与人工导入共用校验和发布保护 |
| CheckinCollectionJob.execute(task) | 手动补采入口 | 读取最近1小时范围并复用接入管道;失败可继续查日志 |
数据库与联动
新增接入事件、外部标识映射、采集批次;业务结果写签到、学习明细、成绩表。来源系统和eventId联合唯一;载荷摘要用于检测同键不同内容。学习事件中的planId/courseId可以在无法确定时为空,并保留未归属状态。
原始事件存储与业务处理可以分阶段事务执行;业务写入与事件处理完成标记需要同一事务或可验证幂等策略,避免崩溃后重复入账。时长超过课程总时长两倍的规则作用于使用明细,不错误作用于成绩数值。
6.7 学习情况统计分析
**模块责任:**按统一口径读取业务数据,提供指标、比较、下钻和导出。
**前端操作:**班级工作台或统计菜单设置范围,查看人数、考勤、学习时长、成绩分布;点击指标带着同一筛选条件进入明细;导出超过阈值进入任务中心。
对应原始需求
| 需求ID | 具体要求 |
|---|---|
| S01 | 基于原始使用明细统计每位学员各系统总学习时长并可视化 |
| S02 | 学员各课程签到自动统计 |
| S03 | 学员各课程成绩统计分析 |
| S04 | 各课程学员成绩统计分析 |
| S05 | 全部统计报表支持日周月和自定义时间筛选及一键导出 |
| S06 | 图表下钻明细及同比环比 |
| S07 | 大数据量异步统计,完成后消息提醒下载 |
提供的HTTP接口
| 接口ID | 方法 | 路径或复用入口 | 调用者 | 输入与结果 | 需求ID |
|---|---|---|---|---|---|
| S-API01 | GET | /training/statistics/overview | A/T | planId/courseId/studentId、时间→汇总指标和口径 | S01,S02,S03,S04 |
| S-API02 | GET | /training/statistics/study-duration | A/T | 学员、系统、班次、时间→时长分布 | S01,S05 |
| S-API03 | GET | /training/statistics/attendance | A/T | 班次、课程、学员、时间→应到与实到及比率 | S02,S05 |
| S-API04 | GET | /training/statistics/student-scores | A/T | 学员、课程、时间、口径→学员成绩分析 | S03,S05 |
| S-API05 | GET | /training/statistics/course-scores | A/T | 课程、班次、时间、口径→学员成绩分布 | S04,S05 |
| S-API06 | GET | /training/statistics/comparisons | A/T | 指标、当前区间、比较方式→同比或环比及计算基数 | S06 |
| S-API07 | GET | /training/statistics/details | A/T | 指标类型及完全相同的范围→明细分页 | S06 |
| S-API08 | POST | /training/statistics/exports | A/T | 报表类型、筛选、输出格式→文件或异步taskId | S05,S07 |
| S-API09 | GET | /training/tasks/{taskId} | A/T | 本人或获授权任务→状态、进度、结果标识 | S07 |
| S-API10 | GET | /training/tasks/{taskId}/download | A/T | 任务ID→重新校验权限后下载 | S07 |
| S-API11 | POST | /training/tasks/{taskId}/retry | A/T | 失败任务、原因→重新排队 | S07 |
| S-API12 | GET | /training/me/statistics | S | 本人及时间范围→本人统计 | S01,S02,S03 |
内部Service及调用方
| 方法契约 | 由谁调用 | 处理责任 |
|---|---|---|
| StatisticsService.query(scope,metric) | 统计Controller、PortraitService | 校验范围,返回结果、规则版本及明细查询条件 |
| AttendanceQueryService.expectedAndActual(scope) | StatisticsService | 应到来自有效名单及课次;迟到、请假等按确认口径 |
| ExportTaskService.create(actor,query) | 统计导出Controller | 保存条件、权限范围及任务拥有者,不只保存最终SQL字符串 |
| ExportJob.execute(taskId) | 任务执行器 | 重新执行允许范围的查询,生成文件和完成通知 |
| TaskAccessService.authorizeDownload(taskId,actor) | 下载Controller | 任务归属与当前权限均检查,权限被撤销后不得仅凭旧链接下载 |
数据库与联动
以参训、课次、签到、成绩、学习记录为事实来源;新增或复用导出任务和通知记录。避免在多个模块维护不同口径的累计值。缓存或汇总表作为派生数据,要明确失效及重建机制。
接口返回分母、样本数和时间范围,便于解释结果。同比环比基期为零或数据不足返回空值及原因,不伪造百分比。历史快照与实时统计分别标明计算时间。
6.8 学员画像
**模块责任:**消费统计指标,生成规则标签、雷达图、历史和资料推荐,不直接修改成绩事实。
**前端操作:**学员详情的画像页展示当前计算时间、维度、标签依据和历史快照;管理员维护受限规则;教师在所带班级按标签筛选后生成推荐清单。
对应原始需求
| 需求ID | 具体要求 |
|---|---|
| U01 | 根据学习情况展示和管理学员画像 |
| U02 | 管理员配置动态标签规则,例如签到率大于90%标记勤勉 |
| U03 | 雷达图覆盖考勤、理论成绩、实操能力、学习时长 |
| U04 | 每月1日自动保存历史快照,支持成长比较 |
| U05 | 按画像标签筛选并生成定向补习资料推荐清单 |
提供的HTTP接口
| 接口ID | 方法 | 路径或复用入口 | 调用者 | 输入与结果 | 需求ID |
|---|---|---|---|---|---|
| U-API01 | GET | /training/portraits | A/T | 班次、标签、时间→画像名单 | U01,U05 |
| U-API02 | GET | /training/portraits/students/{studentId} | A/T | 学员、可选班次→当前画像、口径和计算时间 | U01,U03 |
| U-API03 | GET | /training/portraits/students/{studentId}/snapshots | A/T | 月份区间及班次→快照和成长比较 | U04 |
| U-API04 | GET | /training/portrait-rules | A | 无→规则、状态及版本 | U02 |
| U-API05 | POST | /training/portrait-rules | A | 指标、操作符、阈值、标签→规则草稿 | U02 |
| U-API06 | PUT | /training/portrait-rules/{ruleId} | A | 规则变更、version→规则新版本 | U02 |
| U-API07 | POST | /training/portrait-rules/{ruleId}/activation | A | 启用/停用、version→生效规则 | U02 |
| U-API08 | POST | /training/portrait-recomputations | A | 范围、规则版本→重算taskId | U01,U02,U03 |
| U-API09 | POST | /training/recommendation-lists | A/T | 范围、标签、资源选择策略→清单ID与匹配项 | U05 |
| U-API10 | GET | /training/recommendation-lists/{listId} | A/T | 清单ID→范围内学员和推荐资料 | U05 |
| U-API11 | GET | /training/me/portrait | S | 本人、可选班次→本人画像 | U01,U03 |
| U-API12 | GET | /training/me/recommendations | S | 本人→关联的推荐清单 | U05 |
内部Service及调用方
| 方法契约 | 由谁调用 | 处理责任 |
|---|---|---|
| PortraitService.calculate(scope,ruleVersion) | 查询或重算任务 | 读取StatisticsService结果并换算维度,保存计算时间和口径 |
| PortraitRuleService.evaluate(metrics,ruleVersion) | PortraitService | 受限规则字段与操作符,不执行管理员任意SQL或代码 |
| PortraitSnapshotJob.run(month) | 月度任务 | 每月1日幂等生成上一统计周期或约定时点的快照,具体口径待确认 |
| RecommendationService.generate(scope,labels) | 推荐Controller | 匹配授权可见教学资源,生成清单及理由,不自动增加未确认推送渠道 |
数据库与联动
调整train_student_portrait以区分当前画像和历史快照;新增规则及版本、画像标签、推荐清单及资源关联。快照唯一键包含学员、统计范围、周期和明确的版本策略。
当前签到或成绩变更后画像按刷新策略更新;历史快照不得被覆盖。标签有规则解释,雷达维度有换算规则。资料推荐返回清单,短信等外部推送不在当前已确认范围。
6.9 系统权限管理
**模块责任:**复用并补齐若依安全基础,提供跨模块权限、数据范围及审计。
**前端操作:**系统管理维护账号、角色、菜单和数据范围;业务页面按权限显示操作,后端执行同样校验。日志查询支持按业务对象追溯。
对应原始需求
| 需求ID | 具体要求 |
|---|---|
| A01 | 用户角色权限三层模型,预置管理员教师学员并支持自定义角色 |
| A02 | 数据行权限,例如教师只看所带班级成绩 |
| A03 | 核心增删改导出记录操作人时间IP及变更前后JSON快照 |
| A04 | 密码复杂度、登录失败锁定、超时自动退出 |
提供的HTTP接口
| 接口ID | 方法 | 路径或复用入口 | 调用者 | 输入与结果 | 需求ID |
|---|---|---|---|---|---|
| A-API01 | 复用 | 现有若依登录和退出接口 | A/T/S | 登录凭据→会话及允许菜单;退出清理会话 | A04 |
| A-API02 | 复用 | 现有若依用户角色菜单权限接口 | A | 用户角色权限配置→授权结果 | A01 |
| A-API03 | GET | /training/data-scope/teachers/{teacherId}/class-plans | A | 教师ID→授课关联及可访问范围预览 | A02 |
| A-API04 | GET | /training/audits | A或审计角色 | 对象、操作人、时间、动作→脱敏审计分页 | A03 |
| A-API05 | GET | /training/audits/{auditId} | A或审计角色 | 审计ID→允许查看的前后快照及结果 | A03 |
| A-API06 | 复用或扩展 | 现有安全配置入口 | A | 密码、失败锁定、会话时效策略→配置结果 | A04 |
内部Service及调用方
| 方法契约 | 由谁调用 | 处理责任 |
|---|---|---|
| TrainingAccessService.checkPlan(actor,planId,action) | 全部相关Service | 根据角色和有效授课范围校验;参数不能绕过范围 |
| TrainingAccessService.resolveSelfStudent(actor) | 本人查询Controller | 取得本人学生标识,不接受任意studentId替代 |
| AuditService.record(change) | 全部变更服务及导出任务 | 记录操作身份、对象、时间、IP、动作和脱敏前后差异 |
| AccountLifecycleService.freezeLinkedAccount(personId) | 教师离职、人员状态服务 | 检查账号关联与作用范围,保留历史审计 |
| IntegrationAuthService.authenticate(request) | 接入Controller | 确定可信设备或系统身份与范围,模拟入口仍需管理员权限 |
数据库与联动
复用现有sys_user、角色、权限关系及可用日志任务能力;是否缺少完整前后快照必须代码核实。必要时增加培训业务审计扩展表,不能把create_user和update_time当完整审计。
权限覆盖列表、详情、导入、导出、统计、画像及异步任务下载。日志对密码、人脸文件凭据和加密敏感字段执行适当脱敏;保持可追溯的业务变更信息。
7 数据库调整与数据归属
7.1 关键标识
| 标识 | 含义 | 关联用途 |
|---|---|---|
| studentId | 学员本人 | 基本档案、人脸、账号、跨期学习记录 |
| teacherId | 教师本人 | 授课、证书、账号 |
| courseId / courseVersionId | 课程及所采用的内容版本 | 开班依据与历史教学资源 |
| planId | 一次具体开班 | 时间、课程、招生、参训及统计范围 |
| enrollmentId | 某学员参加某一期 | 报到、入住、成绩、单期状态 |
| lessonId | 某一期的一次具体上课安排 | 时间、场地、应到和签到 |
| stayId / bedId | 一次分配关系及床位资源 | 住宿、换宿、退宿和授权 |
| authId / commandId | 权限依据及执行命令 | 生效范围与设备处理结果 |
| assessmentItemId / scoreId | 考核定义及一次成绩 | 权重、分数、来源和历史 |
| sourceSystem / externalEventId | 外部事件身份 | 幂等、防重复计入及追溯 |
第一版沿用已有结构的“一个开班计划对应一门课程和主要教师”,课次可指定实际授课教师。是否扩展一个班次多门课程属于后续模型决策,不在此默默变更。教师数据范围需包含已授权的主讲或课次授课关系。
7.2 现有14张表的调整方向
下表根据此前提供的表设计整理;实际工程中的14组CRUD必须逐组与数据库核对,不能假定与文档完全一致。
| 已有表 | 调整重点 | 主要写入者 |
|---|---|---|
| train_teacher | 账号关联、在职状态、逻辑删除;证书和履历另关联 | TeacherService |
| train_student | 账号关联、加密身份信息、全局人员状态;本期状态放参训表 | StudentService |
| train_course | 唯一业务编码、状态、版本及资源关系 | CourseService |
| train_class_plan | 完整状态、课程版本、报到期限及规则关联 | ClassPlanService |
| train_dormitory_info | 楼层、维修状态、设备关联;占用从入住计算 | DormitoryService |
| train_dorm_auth | 引用入住或临时依据、业务状态、有效期、期望设备版本 | DoorAuthService |
| train_classroom_info | 资源启停及容量;某时段占用由课次查询 | VenueService |
| train_training_site | 资源启停、容量、设备信息;占用由课次查询 | VenueService |
| train_class_report | enrollmentId、完整报到状态、核验及操作信息 | ReportService |
| train_electronic_board | 设备序列号唯一、教室绑定、在线状态与播放配置分开 | DeviceService |
| train_student_checkin | enrollmentId、lessonId、来源、人工修订及业务状态 | AttendanceService |
| train_score_info | 按考核项目和次数拆记录、来源、状态、版本 | ScoreService |
| train_study_duration | 明细语义、来源事件、异常审核、可空课程班次关联 | StudyRecordService |
| train_student_portrait | 当前/快照、范围、规则版本、计算时间、分项维度 | PortraitService |
7.3 新增或复用的数据结构
| 数据结构 | 建议关键字段 | 规则 |
|---|---|---|
| train_enrollment | id、plan_id、student_id、status、joined_at、completed_at、version | plan_id+student_id唯一;退出后重新加入采用明确的状态复用或历史策略 |
| train_lesson | id、plan_id、teacher_id、classroom_id、site_id、start_at、end_at、status | start早于end;取消课次保留历史 |
| train_dorm_bed | id、dorm_id、bed_no、maintenance_status | dorm_id+bed_no唯一 |
| train_dorm_stay | id、enrollment_id、bed_id、planned_start/end、actual_start/end、status、version | 有效预占或入住时段不得重叠 |
| train_student_face | id、student_id、file_id、source、captured_at、status | 多照片关联;文件受控访问 |
| train_door_command | id、auth_id、action、desired_version、status、next_attempt_at、idempotency_key | 期望权限版本去重;旧命令执行前重检当前有效状态 |
| train_door_attempt | id、command_id、attempt_no、sent_at、finished_at、result、error | 每次尝试留存;失败重试不改写历史 |
| train_assessment_item | id、plan_id、type、full_score、weight、attempt_policy、rule_version | 权重与采用规则校验;已发布规则不可静默改写 |
| train_score_history | id、score_id、version、before/after、reason、operator、time | 每次编辑或审批更正可追溯 |
| train_score_change_request | id、score_id、base_version、proposed_value、reason、status、reviewer | 申请与当前成绩版本匹配;角色分离按审批策略 |
| train_status_history | object_type/id、before/after、scope、reason、operator、time | 记录人员与参训范围 |
| train_integration_event | source、event_id、type、payload_hash、payload、received_at、status、business_id | source+event_id唯一;同键不同载荷冲突 |
| train_external_mapping | source、object_type、external_id、internal_id、status | 同来源同类型外部ID唯一 |
| train_course_version及资源关系 | course_id、version、content、resource_id、status | 历史引用可恢复 |
| train_teacher_certificate | teacher_id、certificate_no、valid_until、remind_before、status | 到期提醒幂等 |
| train_portrait_rule及快照 | 字段、操作符、阈值、标签、版本、生效状态 | 受限规则结构,不执行任意脚本 |
| train_recommendation及明细 | scope、student_id、resource_id、reason、created_by | 范围和资源权限一致 |
| 导入/导出/重算/结业批次 | 类型、拥有者、筛选、状态、逐项结果、文件引用 | 任务结果可追溯和授权下载 |
| 通知及读取记录 | 接收者、类型、业务引用、幂等键、已读时间 | 定向提醒不同于公共公告,现有能力不足时补充 |
| 审计扩展 | 操作人、时间、IP、对象、前后脱敏快照、结果 | 与现有日志能力核对后复用或扩展 |
不按“一个界面一个表”或“一张表一个界面”机械设计。一个报到页面可以操作多张表,一张接入事件表可以服务多个设备入口。
7.4 数据库保护与迁移
- 主外键的长度和类型统一。此前教师、学员主键20位与部分引用32位不一致,需要在实际模式中统一。
- 保留现有稳定主键及历史引用。拆成绩表时建立旧记录到新项目成绩的映射,不根据空字段随意创建假成绩。
- 重复报到、重复参训、同一事件重复入账由唯一约束与事务共同保护。
- 床位分配时锁定床位记录,并查询有效区间冲突;多床位批量操作按固定顺序加锁。只锁已存在入住行不能防止两个事务同时插入第一个占用。
- 按实际Kingbase版本、兼容模式和驱动生成DDL;确认自增/序列、更新时间、分页、大小写、布尔和JSON类型等行为。本文不直接提供未经环境验证的SQL。
- 基线结构、升级迁移、菜单权限字典、演示数据分别管理。演示数据重建只能作用于明确的演示范围,不能混入生产升级步骤。
- 唯一约束、外键、必要索引和状态字典随迁移版本交付。常用索引包括参训plan/student、课次plan/time、签到lesson/enrollment、成绩enrollment/item、使用记录student/time、任务status/nextAttempt。
8 状态转换与联动规则
下列转换方式属于落实状态要求的建议设计。原文列出的状态必须保留;未定义的转换条件需要通过配置及评审明确。任何通用PUT接口都不得绕过专用状态服务。
| 对象 | 状态与建议转换 | 执行者 | 重要联动 |
|---|---|---|---|
| 课程 | DRAFT→PENDING_REVIEW→PUBLISHED→ARCHIVED;审核拒绝回DRAFT | 教师/管理员提交,获授权者审核 | 发布版本供开班引用;新修改不覆盖历史版本 |
| 开班计划 | NOT_STARTED→ENROLLING→IN_PROGRESS→ENDED;允许条件下→CANCELLED | 管理员及明确配置的任务 | 计数、报到期限、课表、授权时效重检 |
| 参训关系 | ACTIVE、ON_LEAVE、COMPLETED、WITHDRAWN、CANCELLED等建议状态 | 管理员、期限任务、结业服务 | 与人员全局状态分离;仅联动本期范围 |
| 报到 | NOT_REPORTED→REPORTED;LEAVE、ABANDONED按规则转换 | 报到终端或管理员 | 核验、资源及人脸同步;状态更正留痕 |
| 住宿 | RESERVED→CHECKED_IN→CHECKED_OUT;预占可CANCELLED | 管理员、报到或相关任务 | 分床、换宿、释放和授权依据变化 |
| 门锁业务授权 | PENDING、ACTIVE、SUSPENDED、EXPIRED、REVOKED等 | 授权服务 | 业务期望状态与设备执行结果分离 |
| 门锁命令 | PENDING→PROCESSING→SUCCEEDED;失败→RETRY_WAIT或FAILED;过时→CANCELLED | 执行任务及获授权重试者 | 保存所有尝试;程序崩溃后通过超时领取恢复 |
| 成绩 | DRAFT→SUBMITTED→PUBLISHED | 教师、发布者 | PUBLISHED锁定;普通编辑拒绝 |
| 成绩更正申请 | PENDING→APPROVED或REJECTED | 审批者 | APPROVED生成新成绩版本并重算;基准版本变化需重审 |
| 接入事件 | RECEIVED→PROCESSING→PROCESSED;失败→FAILED;重复请求返回原结果 | 接入服务及重处理任务 | 失败可重处理,不能重复写业务事实 |
| 导出任务 | PENDING→RUNNING→SUCCEEDED或FAILED | 后台任务 | 成功通知,失败可重试,下载重新校验权限 |
| 画像规则 | DRAFT/ACTIVE/INACTIVE及规则版本 | 管理员 | 当前画像按新规则重算,历史快照保留规则依据 |
8.1 需要特别避免的错误联动
- 某一期结业不能默认把学员全局账号停用。
- 报到超时任务只取消符合规则且在最终事务检查时仍未报到的资格,避免与现场报到并发误取消。
- 设备命令失败不重新执行完整报到或分床。
- 旧的授权下发命令在学员已退训后重试,必须被取消或改为最新期望操作,避免重新开通权限。
- 同一学员通过两个班次或临时授权获得同一门锁权限,撤销一个依据前需要检查其他有效依据。
- 成绩更正不直接修改已经保存的历史快照;当前统计与历史快照分别显示时点。
- 课次取消或参训变动后,应到范围要按生效时间及口径计算,不能用当前名单覆盖全部历史考勤。
9 核心业务接口的输入输出与事务
第6章是全接口目录。本章细化实现最先使用的接口。所有示例ID、日期、分数和状态是演示值,不是现有数据库真实数据。
9.1 创建培训班
POST /training/class-plans
必填:planName、courseId、teacherId、startTime、endTime、recruitNum;可选:courseVersionId、trainAddress、applyCondition、reportDeadline或规则引用。operator由后端身份取得。
处理:校验字段和课程教师→检测时间冲突→按冲突处理策略返回告警或待处理结果→保存计划→返回planId、status、version、warnings。不能因为检测到冲突就擅自强制阻断,是否确认后继续需配置。
9.2 添加参训名单
POST /training/class-plans/{planId}/enrollments
输入:studentIds数组、idempotencyKey。输出:成功enrollmentIds、重复项、失败项及原因、有效人数、90%阈值提醒。批量添加建议逐项事务,响应明确逐项结果。唯一约束保护重复加入,提醒按班次和阈值跨越事件幂等产生。
9.3 安排课次
POST /training/class-plans/{planId}/lessons
输入:lessonName、startTime、endTime、teacherId、classroomId或siteId等。输出:lessonId、version、warnings。教师冲突按原文告警;场地冲突、同班课次重叠和跨班教师范围等建议实现规则需确认。更新已有课次时若已产生签到,应保护原课次历史并受控调整。
9.4 核验与报到
POST /training/reports/identify:输入planId、identityType和模拟身份资料;输出matchedStudent、verificationId、verificationStatus、needsManualReview。核验凭据有有效期并绑定班次和学员,不能由前端随意填写verified=true冒充核验通过。
POST /training/reports/confirm 示例:
{
"enrollmentId": "ENR_DEMO_001",
"verificationId": "VERIFY_DEMO_001",
"accommodation": {
"mode": "USE_SELECTED_BED",
"bedId": "BED_A_201_01"
},
"idempotencyKey": "demo-report-001"
}
mode可建议支持USE_EXISTING、USE_SELECTED_BED;是否允许不住宿按业务规则配置,不默认每名学员都必须分床。实际报到方式和操作人从核验记录及登录身份取值。
处理顺序:
- 校验操作人与本次参训的数据范围,锁定参训记录。
- 检查同一幂等键及已报到结果。相同已完成请求返回原结果,不重新分配,不因现在超过截止时间而拒绝已完成请求的重放。
- 首次办理检查身份核验、人员基础状态、参训资格、报到期限和请假规则。
- 查询已有住宿,或由StayService锁床位、检查区间冲突、保存分配。
- 保存报到及有效人脸引用,创建待授权记录和持久化命令。
- 提交本地事务,返回报到、住宿、课表和授权当前状态。
- 任务提交后读取命令执行设备调用,不在数据库事务内等待设备。
响应示例:
{
"code": 200,
"msg": "报到完成,门锁授权待处理",
"data": {
"enrollmentId": "ENR_DEMO_001",
"reportStatus": "REPORTED",
"stay": {"bedId": "BED_A_201_01", "roomName": "A楼201室"},
"doorAuthorization": {"status": "PENDING", "commandId": "CMD_DEMO_001"},
"classroom": {"name": "201教室"},
"trainingSite": {"name": "钢结构实训区"},
"lessons": []
}
}
lessons实际返回已有安排;示例空数组只说明响应结构,不应在已有课表时漏返回。
9.5 独立分床或换宿
POST /training/stays:输入enrollmentId、bedId、startTime、endTime、idempotencyKey。锁床位行→检查有效区间→保存入住依据和待授权。建议查询可用床位不产生占用,最终提交必须重检。
POST /training/stays/{stayId}/transfer:输入newBedId、effectiveTime、reason、version。固定顺序锁旧新床位,检查新床冲突,结束或调整旧占用并建立新占用,记录关联授权的撤销/更新/下发命令。只更新student表中的宿舍文本无法支撑此流程。
9.6 接收签到
POST /training/integration/checkin-events 输入示例:
{
"externalEventId": "BOARD_EVENT_001",
"externalPersonId": "DEVICE_PERSON_001",
"externalCourseId": "DEVICE_COURSE_001",
"lessonId": "LESSON_DEMO_001",
"deviceSn": "BOARD_DEMO_001",
"checkinWay": "FACE",
"occurredAt": "2026-09-15T09:00:00+08:00"
}
sourceSystem从认证身份确定,deviceSn和lessonId还需校验范围。先以可信来源+事件ID判重,再执行同学员同课程一分钟取首条业务规则。响应包含eventId、processingStatus、checkinId或duplicateOf;重复记录不能伪装成新签到。窗口边界、乱序到达时“第一条”指事件时间还是接收时间需明确;实现不应用简单“自然分钟分桶”替代滚动一分钟而不说明。
9.7 成绩录入和发布
POST /training/scores:enrollmentId、assessmentItemId、attemptNo、scoreValue、reason。满分、权重、采用规则来自后端考核项目。人工请求不能伪造第三方来源;适配器内部设置来源字段。
POST /training/scores/publications:planId、scoreIds、expectedVersions、idempotencyKey。建议同班批次事务内全部校验通过再发布;任一成绩未提交、版本冲突或缺少规则,则明确失败,不部分发布后仍返回整批成功。发布后普通PUT返回SCORE_LOCKED。
POST /training/scores/{scoreId}/change-requests 保存申请,不立即改变当前分数。审批事务内重新检查基准版本和审批权限,写入历史、新值和计算结果。通知申请人或相关教师,现有账号不因分数更正而改变。
9.8 接收学习记录
POST /training/integration/study-events:externalEventId、externalPersonId、deviceSn、startTime、endTime,可附外部课程或班次引用。后端计算studySeconds,不以未经验证的前端累计时长为准;end早于start等格式/时间错误必须有可识别反馈。可确定课程时应用“超过课程总时长2倍”异常示例,记录异常并通知管理员,审核状态与原始事实分开。
9.9 统计与画像
统计接口输入planId/courseId/studentId及timeFrom/timeTo等筛选。范围由后端取交集并检查;响应建议包含metrics、sampleSize、definitions、calculatedAt、detailsFilter。未有有效分母时返回null及说明,不把未计算的比率写成0%。
画像响应包含dimensions、labels及命中依据、ruleVersion、calculatedAt和统计范围。快照接口返回对应周期的数据和规则版本。定向推荐只生成清单;真实消息推送渠道未确认时不自行接入外部发送服务。
9.10 办理结业
POST /training/class-plans/{planId}/completion-batches:enrollmentIds、reason、idempotencyKey。先检查操作者、班次和目标名单。逐参训事务更新本期状态、历史和权限期望;返回每项结果和异步命令状态。
是否有成绩或考勤门槛是待定规则。演示建议使用管理员显式确认,但必须标记为演示规则。退宿仅在确定的释放条件满足时执行,不将“结业”硬编码为立即删除入住。班级ENDED与部分学员COMPLETED分开,不能以结业一名学员自动结束整个班。
9.11 共用支持接口
| 接口 | 调用者 | 用途 |
|---|---|---|
| GET /training/notifications | 登录用户 | 本人的证书预警、人数提醒、异常及任务完成消息 |
| POST /training/notifications/{id}/read | 通知接收者 | 标记已读,不能修改其他人的通知 |
| GET /training/files/{fileId}/download | 获授权用户 | 模板、反馈、资料及报表下载的统一受控入口,可适配现有文件服务 |
| GET /training/venues/classrooms | A/T | 教室选择及查询 |
| GET /training/venues/training-sites | A/T | 实训场地选择及查询 |
| POST或PUT 对应资源管理接口 | A | 复用已有教室、场地、电子班牌CRUD并校验引用关系,具体路径以工程清单补齐 |
这些是共用能力,不必把每个提醒都做成独立业务系统。现有若依公告、文件或任务功能是否等价需要核对,不能将公共公告直接视为定向完成通知。
10 事务与异步任务实现要求
10.1 事务表
| 操作 | 同一数据库事务内 | 事务外或后续任务 |
|---|---|---|
| 报到 | 锁参训、首次校验、确认分配、报到记录、权限依据和待命令 | 设备下发、完成提醒 |
| 换宿 | 锁旧新资源、更新入住、生成新旧权限期望及命令 | 设备更新,失败单独重试 |
| 成绩发布 | 锁版本、状态校验、计算、发布及审计 | 重算缓存/当前画像或通知 |
| 成绩更正 | 审批、基准版本校验、前后历史、新成绩和计算结果 | 当前画像更新及通知 |
| 事件处理 | 业务写入与PROCESSED结果保持一致或可幂等恢复 | 初次接收日志可先独立保存;失败重处理 |
| 结业 | 单参训状态、历史、有效范围、命令依据 | 权限执行及按规则退宿任务 |
同一Spring事务需要通过代理调用生效,不能只在同类内部自调用的方法上添加注解并假定事务存在。项目若采用不同框架分支,以实际事务配置核实。服务之间避免循环依赖:由ReportService或CompletionService作为业务动作的协调者,基础查询和权限服务保持单向依赖。
10.2 后台任务清单
| 任务 | 触发 | 输入 | 输出及幂等依据 |
|---|---|---|---|
| 教师证书提醒 | 配置周期 | 当前时间及证书规则 | 按证书、提醒窗口去重通知 |
| 报到超期 | 配置周期 | 班次截止时间及状态 | 最终锁定复核后取消和释放;重复执行无重复联动 |
| 门锁命令执行 | 周期轮询或提交后唤醒 | 待命令ID | 领取租期/超时恢复、每次尝试结果 |
| 权限到期检查 | 配置周期 | 当前时间、有效授权依据 | 生成到期操作,更新/撤销期望版本去重 |
| 电子班牌补采 | 管理员触发 | 来源、设备、最近1小时窗口 | 采集批次和逐事件结果 |
| 异步统计导出 | 用户触发 | 持久化筛选和权限范围 | 文件、状态及接收者通知 |
| 当前画像重算 | 管理员或确认的刷新策略 | 范围和规则版本 | 更新当前画像,不覆盖历史 |
| 月度画像快照 | 每月1日 | 明确的统计时点/周期 | 周期和范围唯一;保留规则版本 |
任务频率、重试上限、退避时间、锁定阈值和导出阈值均为配置,不在多个Service中硬编码不同数值。对于下发超时但设备可能已执行的情况,使用稳定命令ID、查询设备结果或支持幂等的适配器,不能简单认定没有执行。
10.3 模拟与真实适配器
定义IdentityAdapter、DoorAdapter、CheckinSourceAdapter、StudySourceAdapter、ScoreSourceAdapter等必要边界。演示配置启用Mock实现,结果使用固定种子或可选择场景,便于复现。业务Service依赖接口而不是Mock类;切换真实系统时替换适配器、映射和认证,保留业务状态、幂等及记录方式。真实设备协议、终端授权和网络联调另行验收。
11 开发任务与分工
11.1 按模块放代码 按业务动作完成开发
一个任务必须包含前端、Controller、Service、Mapper/迁移、权限和验收案例。代码生成器产出的CRUD可以加快基础维护,不能替代业务命令和状态保护。
| 任务包 | 前端 | 后端与数据库 | 完成门槛 |
|---|---|---|---|
| T0 工程基线 | 固定依赖和启动配置 | 固定代码、驱动、数据库基线、迁移和账号配置 | 新环境按文档可登录并访问已有功能 |
| T1 基础对象 | 教师学员课程资源及场地选择 | 修复CRUD映射、账号关联、资源和状态字段 | 页面与数据库一致,权限入口可用 |
| T2 开班名单课表 | 班次工作台、名单、课表 | enrollment、lesson、冲突和人数规则 | 同一班次名单课表可查询,重复加入受控 |
| T3 报到住宿授权 | 核验、分配、结果和重试 | 事务、床位冲突、授权命令、模拟适配器 | 重复报到与授权失败可正确处理 |
| T4 签到与学习 | 签到、补签、模拟事件和学习明细 | 接入去重、身份映射、异常审核 | 原始事件到业务到统计可追溯 |
| T5 成绩 | 录入导入提交发布审批历史 | 项目权重、版本、发布保护 | 普通接口不能修改已发布成绩 |
| T6 统计画像 | 图表、下钻、标签、快照、推荐及任务下载 | 统一口径、受限规则、任务和通知 | 结果能回到明细,教师范围不泄漏 |
| T7 结业及补齐详细项 | 结业、证书提醒、课程版本等 | 状态范围、时效及剩余详细需求 | 65项需求有明确验收结果或未完项 |
| T8 部署交付 | 构建资源和访问验证 | 空库初始化、原型升级、配置、启动和恢复说明 | 指定版本可复现部署并跑通全流程 |
权限、审计、数据库迁移随各任务包一起交付,不等到T7再补。T7用于完成剩余详细项,不表示证书或课程版本等需求可被取消。
11.2 角色分工
| 开发角色 | 主要产出 | 与谁对齐 |
|---|---|---|
| 需求负责人 | 需求ID、待定规则、演示及验收范围 | 前后端、测试、项目负责人 |
| 前端 | 页面、字段、按钮、API函数、状态和错误反馈 | 接口契约及后端VO |
| 后端 | Controller、Service、事务、幂等、权限和任务 | 需求、数据库与前端 |
| 数据库负责人 | 版本迁移、约束、索引、数据映射和核对 | 后端实体与SQL |
| 测试或实施 | 可复现数据、主流程、异常、权限、部署验证 | 各业务动作完成标准 |
一个人可以承担多个角色,但每个业务动作的输入输出、数据库变化和验收证据必须统一。
11.3 单个开发任务的记录模板
任务:确认报到并安排住宿
需求:B06、B07、B08、B10、D03、D04、D05
页面:报到管理/本期办理页面
调用者:管理员或获授权报到终端
HTTP:POST /training/reports/confirm
请求:参训ID、核验凭据、住宿选择、幂等键
返回:报到结果、分配信息、课表、授权任务状态
服务:ReportService → EnrollmentService、StayService、DoorAuthService
数据:参训、核验、报到、入住、床位、授权、命令、审计
事务:数据库内关联写入;设备调用在提交后执行
失败:资格无效、核验无效、截止、床位冲突、版本冲突
验收:正常、重复、并发抢床、设备失败重试、断点恢复、越权
迁移:本任务使用的表字段约束和初始化权限脚本
证据:接口请求响应、页面结果、数据库核对及操作日志
12 验收清单
| 编号 | 场景 | 预期结果 | 关联需求 |
|---|---|---|---|
| V01 | 教师编辑、授课筛选、证书将到期 | 履历可查、提醒可见、编辑有日志 | P01-P05 |
| V02 | 学员导入及多照片管理 | 模板可用,资料正确,人脸受控关联,敏感身份加密 | P06-P09 |
| V03 | 同一学员参加两期 | 两条参训关系,各期状态和轨迹正确 | P08,P10,B06 |
| V04 | 课程资源不合规或审核不通过 | 校验反馈,版本可查,状态合法,历史资源不丢失 | C01-C06 |
| V05 | 创建和复制开班、达到90%人数、教师冲突 | 新计划正确、提醒可见、冲突告警而非未知策略 | B01-B05 |
| V06 | 模拟识别失败后人工核验 | 未通过不完成报到;通过后可继续 | B06,B10 |
| V07 | 重复提交成功报到 | 返回已有结果,无重复入住或授权任务 | B06-B08,D04 |
| V08 | 两请求竞争同一床位同一时段 | 只能一个成功,失败有明确提示 | D01-D04 |
| V09 | 授权失败及程序重启后重试 | 下发时间和每次结果可查,不重建入住 | D04,D05,D08 |
| V10 | 报到期限任务与现场报到并发 | 最终检查准确,不取消已成功报到者 | B09 |
| V11 | 授权到期和临时密码到期 | 独立任务处理并留下结果,权限摘要更新 | D06-D08 |
| V12 | 同事件重放及一分钟重复签到 | 幂等事件不重写;业务窗口按规则只取首条 | I01-I03,C07 |
| V13 | 最近1小时补采 | 复用校验去重,日志和结果可追溯 | I03 |
| V14 | 学习记录超课程总时长2倍 | 保留明细、异常标记、管理员提醒和审核 | I04,I06 |
| V15 | 成绩人工导入接口三来源 | 归属和来源正确,错误行可下载 | G01,G06,G07,I05,I07 |
| V16 | 成绩发布后普通编辑、审批更正、版本冲突 | 普通修改拒绝;审批留历史;旧版本不能覆盖新结果 | G02-G05 |
| V17 | 统计下钻和同比环比 | 明细与汇总范围一致,零基期等边界有说明 | S01-S06 |
| V18 | 大报表后台生成与权限撤销后下载 | 状态及通知可见,下载重新检查权限 | S07,A02 |
| V19 | 画像规则变化和月度任务重复执行 | 当前画像按规则变化,快照不重复且保留依据 | U01-U04 |
| V20 | 标签筛选与推荐 | 仅范围内学员,资源可访问,推荐理由可查 | U05 |
| V21 | 教师访问其他班级详情、修改、导出、统计 | 全部后端拒绝或严格限定,不能仅隐藏按钮 | A01,A02 |
| V22 | 登录失败、超时及敏感审计 | 安全策略生效,核心日志完整且适当脱敏 | A03,A04 |
| V23 | 本期结业但另一期仍有效 | 本期状态更新;有效的其他权限不被误撤销 | P08,D06及演示路径 |
| V24 | 旧授权命令在退训后重试 | 检查当前期望版本,不能重新开通过期权限 | D06,D08 |
| V25 | 全新环境和已有原型升级 | 迁移、权限、文件、任务均能复现;主流程可跑 | 工程交付 |
测试不要求为每个自动生成getter等低价值代码单独编写用例,重点验证状态、事务、并发、权限和故障恢复。第6章每条原始需求仍需在实际验收记录中标注通过、未通过或尚未实现,不能只以本表25个场景替代全部需求验收。
13 待定规则与部署交付
13.1 需要登记的业务决策
| 决策ID | 待定问题 | 建议处理,不代表已确认 |
|---|---|---|
| DEC01 | 若依分支、数据库版本及兼容模式 | 先盘点,固定到环境说明,不臆定Vue或Spring版本 |
| DEC02 | 教师冲突告警后能否继续保存 | 配置并返回明确warnings,不悄悄强制禁止 |
| DEC03 | 90%提醒后的超额报名规则 | 将提醒与人数上限分开配置 |
| DEC04 | 报到X日、请假例外及截止边界 | 统一基地时区,明确包含截止时刻与否 |
| DEC05 | 是否人人住宿、预分配及入住时间 | 演示明确选定模式;无住宿需求不伪造入住 |
| DEC06 | 结业门槛和退宿时点 | 演示可管理员确认;正式门槛与退宿分别配置 |
| DEC07 | 全局人员状态影响范围 | 与本期参训状态分开,明确每类状态及恢复条件 |
| DEC08 | 成绩权重、多次取值、缺考及发布者 | 保存可解释的规则版本;审批角色明确 |
| DEC09 | 出勤率、请假、迟到、取消课次及名单变化口径 | 以生效时间计算历史应到范围 |
| DEC10 | 一分钟窗口、乱序签到的首条定义 | 使用清晰的事件/接收时间规则并验证边界 |
| DEC11 | 异常时长审核前后如何统计 | 显示审核状态;不静默删除或随意计入 |
| DEC12 | 雷达图换算、月度快照统计周期 | 统一尺度和规则版本,明确快照截止时间 |
| DEC13 | 教师和学员开放哪些前端菜单 | 自定义角色赋权,接口仍校验数据范围 |
| DEC14 | 通知渠道、导出阈值及任务频率 | 第一版建议站内通知和受控下载;外发另行确认 |
| DEC15 | 课程删除和发布版本修改 | 保护被开班引用的版本;明确修订流程 |
这些决策可以由项目方在开发评审中逐项确定。为演示临时采用的取值应写进seed配置和说明,不能伪装成原始需求。
13.2 可复现交付清单
- 指定版本的前后端源码、依赖锁定和构建命令。
- Kingbase实际版本、兼容模式、驱动、schema及连接配置模板,不在源码中放真实密码。
- 空库初始化、已有原型升级、角色菜单权限字典、可重复演示数据的脚本与执行顺序。
- 前端构建产物、后端包、实际运行依赖、网站/API代理和内网访问配置。
- 文件上传和预览目录或服务配置,确保重启及重新部署后资源引用有效。
- 定时任务注册、启停、幂等及失败恢复说明,避免部署后重复注册多个执行器。
- 管理员、教师、学员演示账号的准备方式及权限矩阵。
- 核心流程正常、异常、并发和越权验收记录。
- 数据迁移前备份、升级失败恢复和指定代码版本回退说明。
13.3 文档维护方式
本说明书是需求到开发的基线。实际实施时为每个接口补充实现状态、代码位置和实际OpenAPI/接口测试链接;路径变化同步更新前端API文件及本说明书。数据库章节落成对应迁移文件;需求ID关联任务、提交和验收记录。
“143项模块接口目录”包含复用入口与建议端点,是职责清单,不表示必须从零编写143个Controller,也不意味着要一次全部上线。基础CRUD能复用就映射,关键业务动作补专用方法,内部协作保持在同一后端服务层。
14 来源与适用限制
需求依据为本次会话提供的《学员管理系统相关需求》《学员管理系统功能分析 20260831》《学员管理系统数据表设计_20260907》及后续人员和业务表资料。用户已确认同一若依后端、Kingbase、模拟数据及完整一期演示路径。
参考框架能力说明:若依后台手册、若依环境部署。具体工程版本和数据库兼容性必须以现有代码和实例核验,本文不声称已审查源码、执行迁移、完成接口开发或验证上线。