# Module C:住宿 / 门禁 / 考勤 API 契约 > **模块定位:** 培训执行过程中的关键生活与教学秩序支撑,涵盖“住宿预分配 → 住宿人工调整 → 门禁授权下发 → 课次班牌签到/签退 → 人工考勤修正”。 > **核心原则:** 房间级分配为主(床位可选)、住宿与外部门禁解耦、考勤严格基于具体课次 (`lesson_id`) 与参训档案 (`enrollment_id`)。轻量异步重试,不引入重型消息队列。 > **优先级统计:** 共 13 个 API (P0: 9个, P1: 4个, P2: 0个)。 --- ## 1. 住宿安排管理 (Accommodation) ### 1.1 批量住宿预分配 (UC-12) 【P0】【确认】 - **业务目的:** 名单确定后、报到之前,管理员一键对本班有住宿需求且尚未分配的学员进行自动化预分配。 - **HTTP Method:** `POST` - **Path:** `/train/plans/{planId}/accommodations/preallocate` - **Permission:** `train:accommodation:assign` - **Request (AccommodationPreallocateDTO):** `targetEnrollmentIds`, `preferredBuilding`, `genderSeparated`, `sameClassAdjacent` - **分配策略规则【默认/建议方案】:** 1. 严格遵守性别隔离(男学员进男寝,女学员进女寝); 2. 优先填满同房间剩余床位,同班同寝、相邻房间优先; 3. 房间级分配为主,`bed_no` 按序号顺编(可选填)。 - **并发与容量保护:** 对目标房间加行级排他锁 (`SELECT FOR UPDATE`),核验 `count < capacity`。 - **错误码:** `DORM_CAPACITY_EXCEEDED (40060)`, `DORM_GENDER_CONFLICT (40061)` ### 1.2 单人住宿调整 (UC-13) 【P0】【确认】 - **业务目的:** 报到前或培训期间,针对身体不适等特殊情况,管理员手动将某个学员调换到其他房间或指定床位。 - **HTTP Method:** `PUT` - **Path:** `/train/enrollments/{enrollmentId}/accommodation` - **Permission:** `train:accommodation:adjust` - **Request (AccommodationAdjustDTO):** `targetDormId`, `bedNo`, `reason` - **核心校验:** 目标房间存在且状态正常;性别匹配;容量未满。 - **错误码:** `DORM_ROOM_FULL (40062)`, `DORM_GENDER_MISMATCH (40063)` ### 1.3 设置走读 / 不住宿 【P0】【确认】 - **业务目的:** 本地或走读学员无需住宿,将其设置为不住宿,释放其可能已占用的房间床位。 - **HTTP Method:** `PUT` - **Path:** `/train/enrollments/{enrollmentId}/accommodation/day-student` - **Permission:** `train:accommodation:adjust` - **Request (JSON):** `{"isDayStudent": true, "remark": "本地职工申请走读"}` ### 1.4 查看计划住宿安排列表 (UC-14) 【P0】【确认】 - **HTTP Method:** `GET` - **Path:** `/train/plans/{planId}/accommodations` - **Permission:** `train:accommodation:list` - **Request (Query):** `building`, `floor`, `room`, `studentName`, `accommodationStatus` - **Response (TableDataInfo):** 包含学员姓名、单位、性别、入住楼栋、房间、床号、分配时间、门禁同步状态。 ### 1.5 查看实时宿舍房态看板 【P1】【确认】 - **业务目的:** 供宿管或管理员全局掌控全基地宿舍楼栋各房间的占用率与空余床位。 - **HTTP Method:** `GET` - **Path:** `/train/dormitory/occupancy-board` - **Permission:** `train:dormitory:list` - **Response (AjaxResult):** 按楼栋/楼层嵌套分组的房间网格列表。 --- ## 2. 门禁授权管理 (Dorm Auth) ### 2.1 手动触发 / 重试门禁授权同步 (UC-16) 【P0】【确认】 - **业务目的:** 住宿确定后系统自动触发门禁下发;若因外部网络或门锁离线导致同步失败,管理员可在此点击手动重试下发。 - **HTTP Method:** `POST` - **Path:** `/train/accommodations/{accommodationId}/auth/sync` - **Permission:** `train:dormauth:sync` - **事务与轻量解耦实现【默认/建议方案】:** 1. 数据库事务提交成功后,通过 `afterCommit` 触发后续 Adapter 调用; 2. 一期默认建议:`afterCommit` → 轻量异步执行器 → Adapter;如果未引入异步执行器,则为 `afterCommit` → 当前线程事务外调用 Adapter; 3. 两者都必须保证:外部调用失败不得回滚已经提交的本地数据库事务,而是独立更新同步状态 (`face_sync_status = 2`) 并记录 `last_error`,支持页面手动重试; 4. 明确:MQ / Outbox / 分布式事务 = 一期不引入【扩展】。 - **错误码:** `STUDENT_FACE_DATA_MISSING (40070)`, `DOOR_DEVICE_OFFLINE (40071)` ### 2.2 查询计划门禁授权下发状态 【P1】【确认】 - **HTTP Method:** `GET` - **Path:** `/train/plans/{planId}/dorm-auths` - **Permission:** `train:dormauth:list` --- ## 3. 课次考勤管理 (Attendance) ### 3.1 课次签到 (UC-17) 【P0】【确认】 - **业务目的:** 电子班牌人脸识别成功后回传签到事件,或管理员/教师代签到。 - **HTTP Method:** `POST` - **Path:** `/train/attendance/sign-in` - **Permission:** `train:attendance:checkin` - **Request (AttendanceSignInDTO):** `enrollmentId`, `lessonId`, `boardId`, `checkinWay`, `signInTime` - **核心校验:** - **业务不变量 1 强制校验:** `enrollment.plan_id == lesson.plan_course.plan_id`,防止跨班串签! - 幂等性:基于 `(enrollment_id, lesson_id)` 查重,存在已有签到记录时不重复覆盖。 - **错误码:** `ATTENDANCE_PLAN_MISMATCH (40080)`, `LESSON_NOT_FOUND (40081)` ### 3.2 课次签退 (UC-18) 【P0】【确认】 - **业务目的:** 课次结束后,学员刷班牌签退。 - **HTTP Method:** `POST` - **Path:** `/train/attendance/sign-out` - **Permission:** `train:attendance:checkin` - **Request (AttendanceSignOutDTO):** `enrollmentId`, `lessonId`, `signOutTime` ### 3.3 人工修正考勤 (UC-19) 【P0】【确认】 - **业务目的:** 针对因设备识别失败、公假外出、迟到等情形,任课教师或管理员手动调整考勤状态。 - **HTTP Method:** `PUT` - **Path:** `/train/attendance/{checkinId}` - **Permission:** `train:attendance:edit` - **Request (AttendanceAdjustDTO):** `attendanceStatus`, `manualFlag=1`, `remark` - **核心校验:** 强制标记 `manual_flag = 1` 留痕。 ### 3.4 人工补录课次考勤记录 【P1】【确认】 - **HTTP Method:** `POST` - **Path:** `/train/attendance/manual-add` - **Permission:** `train:attendance:edit` ### 3.5 查询指定课次的考勤名单 【P0】【确认】 - **业务目的:** 任课教师在上课时查看当前课次的应到人数、实到人数、缺勤名单与签到详情。 - **HTTP Method:** `GET` - **Path:** `/train/lessons/{lessonId}/attendance` - **Permission:** `train:attendance:list` - **Response (AjaxResult):** 聚合返回本班所有参训人员在该课次的打卡状态与时间列表。 ### 3.6 查询计划考勤统计概况 【P1】【确认】 - **HTTP Method:** `GET` - **Path:** `/train/plans/{planId}/attendance/summary` - **Permission:** `train:attendance:query`