6.8 KiB
6.8 KiB
RailwaySystem API 设计原则与规范
状态: Phase 2 规范冻结 (Review Round 1 修订版) 适用范围: 所有 Controller、API 契约、DTO/VO 及前端调用
1. 业务驱动与工作台优先原则
1.1 拒绝单表 CRUD 堆砌
本系统是面向铁路培训基地的智慧培训业务系统,不是 21 张数据库表的 CRUD 管理后台。严禁出现以下反模式:
flowchart TD
A["一张数据库表"] --> B["一个单表 Controller"]
B --> C["一个单表 Service"]
C --> D["一套单表 CRUD 页面"]
1.2 业务工作台与聚合驱动
业务人员在日常管理中是以“开班计划”为主线推进各阶段工作的。因此系统核心页面是以 培训计划工作台 (Plan Workbench) 为枢纽,通过聚合视图直观展示当前培训所处的阶段(筹备中、排课中、住宿分配中、报到中、培训进行中、已结束),并提供进入各业务动作的明确入口,而不是让用户在几十个左侧菜单栏来回跳转拼接数据。
2. Resource API 与 Command API 区分
为了保持 API 语义清晰,明确操作意图与事务边界,所有接口严格区分 资源查询 (Resource API) 与 业务动作 (Command API)。
2.1 资源型 API (Resource API)
- 定位: 用于获取业务实体详情、列表、看板或特定维度的只读数据。
- HTTP 动词: 纯
GET。 - 特点: 无副作用、幂等,不触发跨表业务状态跃迁。
- 示例:
GET /train/plans/{planId} // 获取计划详情 GET /train/plans/{planId}/courses // 查询计划本期课程列表 GET /train/plans/{planId}/timetable // 获取完整课程表 GET /train/enrollments/{id} // 查询参训档案详情 GET /train/dormitory/occupancy-board // 获取宿舍房态看板
2.2 命令型 API (Command API)
- 定位: 用于驱动业务流程流转、触发状态机跃迁、执行跨表批量操作或外部协作。
- HTTP 动词: 业务动作用名词或动宾短语结尾(如
/complete,/preallocate,/sign-in)。 - 与普通 CRUD 更新的区分:
- 普通的字段修改(如改教师电话、改教室容量)属于标准资源更新 (
PUT /train/teacher/{id}); - 真正业务 Command(如
POST /train/plans/{id}/complete,POST /train/plans/{id}/accommodations/preallocate,POST /train/attendance/sign-in)必须具有跨表状态推动语义,受严格事务保护与不变量拦截。
- 普通的字段修改(如改教师电话、改教室容量)属于标准资源更新 (
3. URL 命名与路径规范
- 统一前缀: 所有培训业务接口统一以
/train开头,兼容 RuoYi 路由机制与安全过滤器。 - RESTful 资源层级: 遵循“父资源/ID/子资源”层级表达从属关系:
/train/plans/{planId}/courses/train/plans/{planId}/lessons/train/plans/{planId}/enrollments
- 领域主键显式声明: 路径变量统一使用数据库 V2 确立的领域 ID 名称:
{planId}(String, 32位){planCourseId}(Long){enrollmentId}(Long){lessonId}(Long){accommodationId}(Long){checkinId}(Long){scoreItemId}(Long)
- 禁止隐式复合参数替代主键: 严禁在 URL 或 RequestBody 中反复退化为
plan_id + student_id + c_id + time查找记录。
4. 分页与列表控制规范
严禁前端通过 pageSize=99999 获取全量业务数据,必须严格划分分页接口与专用聚合接口:
| 分类 | 典型接口 | 控制策略 | 说明 |
|---|---|---|---|
| 常规主数据列表 | 教师、学员、公共课程库、教学资源、教室、场地、电子班牌 | 必须分页 (pageNum, pageSize) |
默认 pageSize=10,最大允许 pageSize=100 |
| 大型业务流列表 | 培训计划列表、参训学员名单、课次列表、学习记录流水 | 必须分页 (pageNum, pageSize) |
参训学员按计划筛选时分页呈现,提供按状态过滤 |
| 业务聚合视图 | 培训计划工作台 (/workbench)、完整课程表 (/timetable) |
不分页 (专用聚合 VO 返回) | 课程表按时间周期或开班全程以结构化日历网格返回 |
| 业务配置项 | 本期成绩项目配置 (/score-items)、本期课程清单 (/courses) |
不分页 (全量返回) | 一个培训班课程通常为 3 |
| 统计与看板 | 统计概览 (/overview)、房态看板 (/occupancy-board) |
不分页 (结构化聚合看板) | 服务端完成聚合计算,返回统计指标及图表数据结构 |
5. 响应体规范 (RuoYi 体系兼容)
系统全面兼容若依现有的 AjaxResult 和 TableDataInfo 标准,前端不需要额外定制拦截器:
5.1 单一实体 / 命令响应 / 聚合 VO
采用 AjaxResult 包装:
{
"code": 200,
"msg": "操作成功",
"data": {
"planId": "PLAN202609001",
"planName": "沈阳局2026年第1期高速铁路综合培训班"
}
}
5.2 分页列表响应
采用若依标准 TableDataInfo 包装:
{
"total": 45,
"rows": [
{ "enrollmentId": 1001, "studentName": "张三", "enrollmentStatus": 1 }
],
"code": 200,
"msg": "查询成功"
}
5.3 业务异常响应
发生业务校验失败时返回标准 HTTP 200 或业务错误码(如 500),由全局异常捕获器统一封装:
{
"code": 40901,
"msg": "排课冲突:王老师在该时段已有授课任务(安全理论基础 09:00-11:00)",
"data": {
"conflictType": "TEACHER",
"conflictLessonId": 801
}
}
6. 确定性标记与 API 优先级规范
6.1 需求确定性分级
- 【确认】: PRD V1.0 与第二次项目会议纪要已明确冻结的业务需求与规则,不可随意擅改。
- 【默认/建议方案(待现场确认)】: 设计层给出的标准工程实现方案,若现场验证后甲方有微调,可平滑变更。
- 【待现场确认】: 明确属于 PRD V-01 ~ V-14 范围的事项(如及格线判定、学员画像标签、超期报到处理策略),API 契约保持高弹性,严禁硬编码。
- 【扩展】: 一期不开发、仅在模型或契约层预留扩展兼容能力(如分布式事务、Kafka、Outbox模式、复杂证书体系),严禁过度设计。
6.2 API 优先级分级 (P0 / P1 / P2)
- P0 (一期核心闭环必须实现): 支撑培训班从立项、选课、入班、排课、住宿、报到、上课打卡、打分、统计到结训的最小可用闭环接口。后续 Issue 拆分优先以此作为开发基线。
- P1 (一期辅助管理能力): 在主链路畅通后实现的辅助运维、人工修正、主档维护与报表查询接口。
- P2 (依赖现场确认或非首轮必须): 依赖现场硬件协议确认或面向学员端的次要门户接口,实现前需再次确认。