139 lines
6.8 KiB
Markdown
139 lines
6.8 KiB
Markdown
# RailwaySystem API 设计原则与规范
|
||||
|
|
|
|||
|
|
> **状态:** Phase 2 规范冻结 (Review Round 1 修订版)
|
|||
|
|
> **适用范围:** 所有 Controller、API 契约、DTO/VO 及前端调用
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. 业务驱动与工作台优先原则
|
|||
|
|
|
|||
|
|
### 1.1 拒绝单表 CRUD 堆砌
|
|||
|
|
本系统是面向铁路培训基地的**智慧培训业务系统**,不是 21 张数据库表的 CRUD 管理后台。严禁出现以下反模式:
|
|||
|
|
```text
|
|||
|
|
一张数据库表
|
|||
|
|
→ 一个单表 Controller
|
|||
|
|
→ 一个单表 Service
|
|||
|
|
→ 一套单表 CRUD 页面
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 1.2 业务工作台与聚合驱动
|
|||
|
|
业务人员在日常管理中是以“**开班计划**”为主线推进各阶段工作的。因此系统核心页面是以 **培训计划工作台 (Plan Workbench)** 为枢纽,通过聚合视图直观展示当前培训所处的阶段(筹备中、排课中、住宿分配中、报到中、培训进行中、已结束),并提供进入各业务动作的明确入口,而不是让用户在几十个左侧菜单栏来回跳转拼接数据。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. Resource API 与 Command API 区分
|
|||
|
|
|
|||
|
|
为了保持 API 语义清晰,明确操作意图与事务边界,所有接口严格区分 **资源查询 (Resource API)** 与 **业务动作 (Command API)**。
|
|||
|
|
|
|||
|
|
### 2.1 资源型 API (Resource API)
|
|||
|
|
- **定位:** 用于获取业务实体详情、列表、看板或特定维度的只读数据。
|
|||
|
|
- **HTTP 动词:** 纯 `GET`。
|
|||
|
|
- **特点:** 无副作用、幂等,不触发跨表业务状态跃迁。
|
|||
|
|
- **示例:**
|
|||
|
|
```text
|
|||
|
|
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 命名与路径规范
|
|||
|
|
|
|||
|
|
1. **统一前缀:** 所有培训业务接口统一以 `/train` 开头,兼容 RuoYi 路由机制与安全过滤器。
|
|||
|
|
2. **RESTful 资源层级:** 遵循“父资源/ID/子资源”层级表达从属关系:
|
|||
|
|
- `/train/plans/{planId}/courses`
|
|||
|
|
- `/train/plans/{planId}/lessons`
|
|||
|
|
- `/train/plans/{planId}/enrollments`
|
|||
|
|
3. **领域主键显式声明:** 路径变量统一使用数据库 V2 确立的领域 ID 名称:
|
|||
|
|
- `{planId}` (String, 32位)
|
|||
|
|
- `{planCourseId}` (Long)
|
|||
|
|
- `{enrollmentId}` (Long)
|
|||
|
|
- `{lessonId}` (Long)
|
|||
|
|
- `{accommodationId}` (Long)
|
|||
|
|
- `{checkinId}` (Long)
|
|||
|
|
- `{scoreItemId}` (Long)
|
|||
|
|
4. **禁止隐式复合参数替代主键:** 严禁在 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~10 门,成绩项为 3~6 项,数量可控 |
|
|||
|
|
| **统计与看板** | 统计概览 (`/overview`)、房态看板 (`/occupancy-board`) | **不分页** (结构化聚合看板) | 服务端完成聚合计算,返回统计指标及图表数据结构 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. 响应体规范 (RuoYi 体系兼容)
|
|||
|
|
|
|||
|
|
系统全面兼容若依现有的 `AjaxResult` 和 `TableDataInfo` 标准,前端不需要额外定制拦截器:
|
|||
|
|
|
|||
|
|
### 5.1 单一实体 / 命令响应 / 聚合 VO
|
|||
|
|
采用 `AjaxResult` 包装:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"msg": "操作成功",
|
|||
|
|
"data": {
|
|||
|
|
"planId": "PLAN202609001",
|
|||
|
|
"planName": "沈阳局2026年第1期高速铁路综合培训班"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.2 分页列表响应
|
|||
|
|
采用若依标准 `TableDataInfo` 包装:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"total": 45,
|
|||
|
|
"rows": [
|
|||
|
|
{ "enrollmentId": 1001, "studentName": "张三", "enrollmentStatus": 1 }
|
|||
|
|
],
|
|||
|
|
"code": 200,
|
|||
|
|
"msg": "查询成功"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.3 业务异常响应
|
|||
|
|
发生业务校验失败时返回标准 HTTP 200 或业务错误码(如 500),由全局异常捕获器统一封装:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"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 (依赖现场确认或非首轮必须):** 依赖现场硬件协议确认或面向学员端的次要门户接口,实现前需再次确认。
|