# 赛程编排后端实现总结 ## 实施概览 本次实现了赛程编排系统的三个核心后端API接口,完全按照 `schedule-backend-api-spec.md` 文档的规范进行开发。 ## 实现的文件列表 ### 1. DTO类 (数据传输对象) #### 1.1 ScheduleResultDTO.java - **路径**: `martial-master/src/main/java/org/springblade/modules/martial/pojo/dto/ScheduleResultDTO.java` - **作用**: 赛程编排结果的响应数据结构 - **字段**: - `isDraft`: 是否为草稿状态 - `isCompleted`: 是否已完成编排 - `competitionGroups`: 竞赛分组列表 #### 1.2 CompetitionGroupDTO.java - **路径**: `martial-master/src/main/java/org/springblade/modules/martial/pojo/dto/CompetitionGroupDTO.java` - **作用**: 竞赛分组数据结构 - **字段**: - `id`: 分组ID - `title`: 分组标题 - `type`: 类型(集体/单人/双人) - `count`: 队伍数量 - `code`: 分组编号 - `venueId`: 场地ID - `venueName`: 场地名称 - `timeSlot`: 时间段 - `timeSlotIndex`: 时间段索引 - `participants`: 参赛人员列表 #### 1.3 ParticipantDTO.java - **路径**: `martial-master/src/main/java/org/springblade/modules/martial/pojo/dto/ParticipantDTO.java` - **作用**: 参赛人员数据结构 - **字段**: - `id`: 参赛人员ID - `schoolUnit`: 学校/单位 - `status`: 状态(未签到/已签到/异常) - `sortOrder`: 排序 #### 1.4 SaveScheduleDraftDTO.java - **路径**: `martial-master/src/main/java/org/springblade/modules/martial/pojo/dto/SaveScheduleDraftDTO.java` - **作用**: 保存编排草稿的请求数据结构 - **字段**: - `competitionId`: 赛事ID - `isDraft`: 是否为草稿 - `competitionGroups`: 竞赛分组数据 ### 2. 实体类修改 #### 2.1 MartialScheduleParticipant.java - **路径**: `martial-master/src/main/java/org/springblade/modules/martial/pojo/entity/MartialScheduleParticipant.java` - **修改内容**: 添加了两个新字段 - `status`: 参赛人员状态(未签到/已签到/异常) - `scheduleStatus`: 编排状态(draft/completed) ### 3. 服务接口 #### 3.1 IMartialScheduleService.java - **路径**: `martial-master/src/main/java/org/springblade/modules/martial/service/IMartialScheduleService.java` - **新增方法**: - `getScheduleResult(Long competitionId)`: 获取赛程编排结果 - `saveDraftSchedule(SaveScheduleDraftDTO dto)`: 保存编排草稿 - `saveAndLockSchedule(Long competitionId)`: 完成编排并锁定 ### 4. 服务实现 #### 4.1 MartialScheduleServiceImpl.java - **路径**: `martial-master/src/main/java/org/springblade/modules/martial/service/impl/MartialScheduleServiceImpl.java` - **新增依赖注入**: - `MartialScheduleGroupMapper`: 分组数据访问 - `MartialScheduleDetailMapper`: 编排明细数据访问 - `MartialScheduleParticipantMapper`: 参赛者数据访问 - **实现的方法**: ##### 4.1.1 getScheduleResult(Long competitionId) **功能**: 查询并返回赛事的编排结果 **实现逻辑**: 1. 查询所有竞赛分组(按display_order排序) 2. 查询所有编排明细 3. 查询所有参赛者(按performance_order排序) 4. 根据scheduleStatus判断是否已完成编排 5. 组装DTO数据返回 **关键代码**: ```java // 检查编排状态 boolean isCompleted = participants.stream() .anyMatch(p -> "completed".equals(p.getScheduleStatus())); boolean isDraft = !isCompleted; // 设置项目类型 switch (group.getProjectType()) { case 1: groupDTO.setType("单人"); break; case 2: groupDTO.setType("集体"); break; default: groupDTO.setType("其他"); break; } ``` ##### 4.1.2 saveDraftSchedule(SaveScheduleDraftDTO dto) **功能**: 保存编排草稿数据 **实现逻辑**: 1. 遍历所有竞赛分组 2. 更新或创建编排明细(MartialScheduleDetail) 3. 更新参赛者的状态和排序 4. 将scheduleStatus设置为"draft" 5. 使用事务确保数据一致性 **关键代码**: ```java @Transactional(rollbackFor = Exception.class) public boolean saveDraftSchedule(SaveScheduleDraftDTO dto) { // 更新编排明细 detail.setVenueId(groupDTO.getVenueId()); detail.setVenueName(groupDTO.getVenueName()); detail.setTimeSlot(groupDTO.getTimeSlot()); // 更新参赛者信息 participant.setStatus(participantDTO.getStatus()); participant.setPerformanceOrder(participantDTO.getSortOrder()); participant.setScheduleStatus("draft"); } ``` ##### 4.1.3 saveAndLockSchedule(Long competitionId) **功能**: 完成编排并锁定,不允许再次编辑 **实现逻辑**: 1. 查询赛事的所有分组 2. 查询所有参赛者 3. 将所有参赛者的scheduleStatus更新为"completed" 4. 使用事务确保数据一致性 **关键代码**: ```java @Transactional(rollbackFor = Exception.class) public boolean saveAndLockSchedule(Long competitionId) { for (MartialScheduleParticipant participant : participants) { participant.setScheduleStatus("completed"); scheduleParticipantMapper.updateById(participant); } } ``` ### 5. 控制器 #### 5.1 MartialScheduleController.java - **路径**: `martial-master/src/main/java/org/springblade/modules/martial/controller/MartialScheduleController.java` - **新增端点**: ##### 5.1.1 GET /martial/schedule/result **功能**: 获取赛程编排结果 **请求参数**: - `competitionId` (Long): 赛事ID **响应示例**: ```json { "code": 200, "msg": "success", "data": { "isDraft": true, "isCompleted": false, "competitionGroups": [...] } } ``` ##### 5.1.2 POST /martial/schedule/save-draft **功能**: 保存编排草稿 **请求体**: SaveScheduleDraftDTO **响应示例**: ```json { "code": 200, "msg": "草稿保存成功" } ``` ##### 5.1.3 POST /martial/schedule/save-and-lock **功能**: 完成编排并锁定 **请求体**: 包含competitionId的SaveScheduleDraftDTO **响应示例**: ```json { "code": 200, "msg": "编排已完成并锁定" } ``` ## 数据库设计说明 ### 涉及的表 1. **martial_schedule_group** (赛程编排分组) - 存储竞赛分组信息 - 字段: competition_id, group_name, project_type, display_order等 2. **martial_schedule_detail** (赛程编排明细) - 存储场地和时间段分配信息 - 字段: schedule_group_id, venue_id, venue_name, schedule_date, time_slot等 3. **martial_schedule_participant** (赛程编排参赛者关联) - 存储参赛者信息 - **新增字段**: - `status`: VARCHAR - 参赛人员状态(未签到/已签到/异常) - `schedule_status`: VARCHAR - 编排状态(draft/completed) ### 数据库迁移建议 需要在 `martial_schedule_participant` 表中添加以下字段: ```sql ALTER TABLE martial_schedule_participant ADD COLUMN status VARCHAR(20) DEFAULT '未签到' COMMENT '状态:未签到/已签到/异常', ADD COLUMN schedule_status VARCHAR(20) DEFAULT 'draft' COMMENT '编排状态:draft/completed'; ``` ## 业务逻辑说明 ### 编排状态管理 1. **草稿状态** (draft): - 用户可以多次保存和修改 - 不影响其他功能 - scheduleStatus = "draft" 2. **完成状态** (completed): - 编排锁定,前端禁用所有编辑功能 - 显示"导出"按钮 - scheduleStatus = "completed" ### 首次分配规则 根据API规范,后端需要按照"先集体,后个人"的顺序进行第一次场地分配: - 集体项目 (projectType = 2) 优先分配 - 个人项目 (projectType = 1) 后分配 - 使用 display_order 字段控制顺序 ### 状态字段说明 参赛人员状态 (status): - **未签到**: 默认状态 - **已签到**: 参赛人员已签到 - **异常**: 被标记为异常的参赛人员 ## 前后端对接说明 ### API路径映射 前端API配置 (`src/api/martial/activitySchedule.js`): ```javascript // 获取赛程编排结果 GET /api/martial/schedule/result // 保存编排草稿 POST /api/martial/schedule/save-draft // 完成编排并锁定 POST /api/martial/schedule/save-and-lock ``` 后端Controller路径 (`MartialScheduleController.java`): ```java @RequestMapping("/martial/schedule") @GetMapping("/result") @PostMapping("/save-draft") @PostMapping("/save-and-lock") ``` ### 数据格式兼容性 - 后端使用驼峰命名 (camelCase) - 前端已做兼容处理,同时支持驼峰和下划线命名 - DTO中的字段名与前端API规范完全一致 ## 测试建议 ### 单元测试 1. 测试getScheduleResult方法: - 测试空数据情况 - 测试草稿状态 - 测试完成状态 - 测试数据组装正确性 2. 测试saveDraftSchedule方法: - 测试新建编排明细 - 测试更新编排明细 - 测试参赛者状态更新 - 测试事务回滚 3. 测试saveAndLockSchedule方法: - 测试状态更新 - 测试锁定后的查询结果 ### 集成测试 1. 测试完整的编排流程: - 首次获取编排结果 - 多次保存草稿 - 完成编排并锁定 - 再次查询验证状态 2. 测试异常场景: - 赛事不存在 - 分组不存在 - 参赛者不存在 ## 后续优化建议 1. **性能优化**: - 对于大量参赛者的情况,考虑使用批量更新 - 添加缓存机制减少数据库查询 2. **功能增强**: - 添加编排历史记录 - 实现编排版本管理 - 添加编排冲突检测 3. **安全性**: - 添加权限验证 - 添加操作日志 - 实现并发控制 ## 总结 本次实现完全按照前端API规范进行开发,实现了: - ✅ 3个核心API接口 - ✅ 4个DTO类 - ✅ 实体类字段扩展 - ✅ 完整的服务层逻辑 - ✅ 事务管理 - ✅ Swagger文档注解 所有代码遵循项目现有的代码风格和架构规范,可以直接集成到现有系统中使用。