188 lines
7.3 KiB
Markdown
188 lines
7.3 KiB
Markdown
# RailwaySystem 自助服务接口体系设计 (Self-Service API Design)
|
|||
|
|
|
||
|
|
- **设计版本**: R.2A Design Freeze
|
||
|
|
- **设计日期**: 2026-09-15
|
||
|
|
- **核心目标**: 建立专属的 Teacher 和 Student 自服务 API 契约(`/train/me/**`),彻底切断客户端参数越权可能性,确保后端 100% 服务端自主推导身份。
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 1. API 设计原则与边界
|
||
|
|
|
||
|
|
1. **禁止复用 Admin 全量管理接口**:
|
||
|
|
- 严禁让教师或学员调用 `/train/student/list` 或 `/train/plans/{id}/timetable` 并寄希望于前端过滤。
|
||
|
|
- 前端代码可被逆向、调试或通过 Postman 直接调用,任何客户端过滤均等于零安全防护。
|
||
|
|
2. **专属 `/train/me/**` 统一前缀**:
|
||
|
|
- 所有自服务请求均指向当前登录人上下文。
|
||
|
|
- 接口入参完全不接收 `studentId`、`teacherId` 等身份主键,参数只允许包含时间范围(如 `startDate`, `endDate`)或分页标记。
|
||
|
|
3. **严格对应真实业务能力 (No Fictional APIs)**:
|
||
|
|
- 仅设计当前数据库与领域服务已真实支撑的业务模块(课表、入班名单、报到、考勤、学时、画像)。
|
||
|
|
- 当前一期暂未实现正式闭环的成绩填报或复杂选课,一律不虚构开放。
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. 教师自服务接口规格 (Teacher Self-Service APIs)
|
||
|
|
|
||
|
|
### 2.1 获取教师本人档案信息
|
||
|
|
- **端点**: `GET /train/me/teacher`
|
||
|
|
- **鉴权要求**: `@PreAuthorize("@ss.hasRole('train_teacher')")`
|
||
|
|
- **响应示例**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"code": 200,
|
||
|
|
"msg": "操作成功",
|
||
|
|
"data": {
|
||
|
|
"tId": "1540e76a34c54596b0e365ae8804ef68",
|
||
|
|
"tName": "DEMO_E2E_20260915_122800_王老师",
|
||
|
|
"tGender": "1",
|
||
|
|
"tPhone": "13900000000",
|
||
|
|
"tEmail": "wang@railway.cn",
|
||
|
|
"orgName": "机务段技能实训中心",
|
||
|
|
"jobTitle": "高级讲师",
|
||
|
|
"status": 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2.2 获取我参与任课的培训班列表
|
||
|
|
- **端点**: `GET /train/me/plans`
|
||
|
|
- **逻辑**: 通过 `train_timetable_lesson` 与 `train_plan_course` 逆向查出教师受聘的全部有效培训班。
|
||
|
|
- **参数**: `pageNum`, `pageSize`, `planStatus` (可选)
|
||
|
|
- **响应示例**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"code": 200,
|
||
|
|
"rows": [
|
||
|
|
{
|
||
|
|
"planId": "613b316621e5466c9039650ced299aa1",
|
||
|
|
"planName": "DEMO_E2E_20260915_122800_铁路综合培训第一期",
|
||
|
|
"startDate": "2026-09-15",
|
||
|
|
"endDate": "2026-09-20",
|
||
|
|
"planStatus": 0,
|
||
|
|
"myCourseCount": 2,
|
||
|
|
"myLessonCount": 2
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"total": 1
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2.3 获取我的授课课表日程
|
||
|
|
- **端点**: `GET /train/me/timetable`
|
||
|
|
- **参数**: `startDate` (如 `2026-09-15`), `endDate` (如 `2026-09-21`)
|
||
|
|
- **逻辑**: 仅查询 `teacher_id = #{currentTeacherId}` 的已排课次。
|
||
|
|
- **响应示例**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"code": 200,
|
||
|
|
"data": [
|
||
|
|
{
|
||
|
|
"lessonId": 97,
|
||
|
|
"planId": "613b316621e5466c9039650ced299aa1",
|
||
|
|
"planName": "铁路综合培训第一期",
|
||
|
|
"cId": "f4a28c4079fe47a1a542d3a34768f9fd",
|
||
|
|
"courseName": "铁路安全理论",
|
||
|
|
"venueType": 2,
|
||
|
|
"venueName": "实训区A",
|
||
|
|
"startTime": "2026-09-15 08:30:00",
|
||
|
|
"endTime": "2026-09-15 10:00:00",
|
||
|
|
"status": 1
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2.4 获取我所带班级学员花名册 (敏感信息脱敏)
|
||
|
|
- **端点**: `GET /train/me/students`
|
||
|
|
- **参数**: `planId` (必填,后端校验教师是否有该班任教关系)
|
||
|
|
- **安全保障**: 身份证号脱敏为后四位,手机号中间四位脱敏。
|
||
|
|
- **响应示例**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"code": 200,
|
||
|
|
"rows": [
|
||
|
|
{
|
||
|
|
"studentId": "f1b524da49da4a54a6d832ab22c2d092",
|
||
|
|
"studentName": "张三",
|
||
|
|
"maskedPhone": "138****0001",
|
||
|
|
"maskedIdCard": "************1234",
|
||
|
|
"orgName": "车辆段检修一车间",
|
||
|
|
"reportStatus": 1,
|
||
|
|
"enrollmentStatus": 0
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"total": 2
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2.5 获取我授课课次的学员出勤情况
|
||
|
|
- **端点**: `GET /train/me/lessons/{lessonId}/attendance`
|
||
|
|
- **逻辑**: 后端严格核验 `lessonId` 的授课教师是否为当前登录人,然后输出该课次应到学员的打卡流水。
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. 学员自服务接口规格 (Student Self-Service APIs)
|
||
|
|
|
||
|
|
### 3.1 获取学员个人档案
|
||
|
|
- **端点**: `GET /train/me/student`
|
||
|
|
- **鉴权要求**: `@PreAuthorize("@ss.hasRole('train_student')")`
|
||
|
|
- **响应字段**: 学员工号、姓名、性别、联系电话、所属单位、照片凭证引用。身份证号仅向本人展示后四位。
|
||
|
|
|
||
|
|
### 3.2 获取我的参训班级与生命周期状态
|
||
|
|
- **端点**: `GET /train/me/enrollments`
|
||
|
|
- **逻辑**: 从 `train_training_enrollment` 查询 `student_id = #{currentStudentId}`。
|
||
|
|
- **状态字段**:
|
||
|
|
- `enrollmentStatus`: `0 (待报到)`, `1 (已报到)`, `2 (请假)`, `3 (退训)`, `4 (已完成)`。
|
||
|
|
- `planId`, `planName`, `startTime`, `endTime`, `reportDeadline`。
|
||
|
|
|
||
|
|
### 3.3 获取我的参训课表
|
||
|
|
- **端点**: `GET /train/me/timetable`
|
||
|
|
- **参数**: `startDate`, `endDate`, `viewType` (`day`/`week`)
|
||
|
|
- **逻辑**: 关联当前学员所在有效班级(`enrollmentStatus IN (0, 1, 4)`),汇总返回所有授课课次、场地位置与任课教师姓名。
|
||
|
|
|
||
|
|
### 3.4 获取我的报到凭据与状态
|
||
|
|
- **端点**: `GET /train/me/report`
|
||
|
|
- **逻辑**: 查询当前学员在最新培训计划中的报到记录(`train_class_report`),返回报到时间、分配教室、分配场地与当前报到状态。
|
||
|
|
|
||
|
|
### 3.5 获取我的考勤打卡流水
|
||
|
|
- **端点**: `GET /train/me/attendance`
|
||
|
|
- **参数**: `planId` (可选), `month` (可选)
|
||
|
|
- **逻辑**: 查询 `train_student_checkin WHERE student_id = #{currentStudentId}`。
|
||
|
|
- **响应示例**:
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"code": 200,
|
||
|
|
"rows": [
|
||
|
|
{
|
||
|
|
"checkinId": 10,
|
||
|
|
"lessonId": 97,
|
||
|
|
"courseName": "铁路安全理论",
|
||
|
|
"checkinTime": "2026-09-15 08:28:10",
|
||
|
|
"checkoutTime": "2026-09-15 12:48:42",
|
||
|
|
"attendanceStatus": 2,
|
||
|
|
"statusLabel": "迟到",
|
||
|
|
"manualFlag": 1,
|
||
|
|
"adjustReason": "因列车调度交接延误10分钟"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3.6 获取我的累计学习时长
|
||
|
|
- **端点**: `GET /train/me/duration`
|
||
|
|
- **逻辑**: 归集 `train_study_duration`,按理论课时与实训课时分别统计有效累计秒数与达标折算学时。
|
||
|
|
|
||
|
|
### 3.7 获取我的多维成长画像雷达
|
||
|
|
- **端点**: `GET /train/me/portrait`
|
||
|
|
- **逻辑**: 查询 `train_student_portrait WHERE student_id = #{currentStudentId}`,返回出勤率、测评平均分、技能掌握度等 5 维雷达数据。
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. 身份异常与边界错误码规范
|
||
|
|
|
||
|
|
| HTTP 状态码 | 业务错误代码 (Code) | 错误提示说明 (Message) | 触发边界与处理方式 |
|
||
|
|
| :---: | :---: | :--- | :--- |
|
||
|
|
| `401` | `401` | "认证凭据无效或会话已过期" | Token 缺失、伪造或 Redis 缓存失效,引导至登录页 |
|
||
|
|
| `403` | `403` | "非教师身份,禁止访问教师专属工作台" | 学员账号或非授课管理员访问 `/train/me/teacher/**` |
|
||
|
|
| `403` | `403` | "非学员身份,禁止访问学员个人培训中心" | 教师或管理员账号访问 `/train/me/student/**` |
|
||
|
|
| `400` | `40041` | "当前登录账号未绑定任何业务档案,请联系管理员" | 存在 `sys_user` 账号,但 `train_teacher/student` 表中未关联对应主体 |
|
||
|
|
| `403` | `40042` | "您并非该班级或课次的任课教师,无权查看学员信息" | 教师尝试横向探测试图读取无关班级名册 |
|