Files
martial-web/doc/schedule/archive/schedule-backend-implementation-summary.md
宅房 5b806e29b7
Some checks failed
continuous-integration/drone/push Build is failing
fix bugs
2025-12-11 16:56:19 +08:00

9.5 KiB
Raw Blame History

赛程编排后端实现总结

实施概览

本次实现了赛程编排系统的三个核心后端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数据返回

关键代码:

// 检查编排状态
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. 使用事务确保数据一致性

关键代码:

@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. 使用事务确保数据一致性

关键代码:

@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

响应示例:

{
  "code": 200,
  "msg": "success",
  "data": {
    "isDraft": true,
    "isCompleted": false,
    "competitionGroups": [...]
  }
}
5.1.2 POST /martial/schedule/save-draft

功能: 保存编排草稿

请求体: SaveScheduleDraftDTO

响应示例:

{
  "code": 200,
  "msg": "草稿保存成功"
}
5.1.3 POST /martial/schedule/save-and-lock

功能: 完成编排并锁定

请求体: 包含competitionId的SaveScheduleDraftDTO

响应示例:

{
  "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 表中添加以下字段:

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):

// 获取赛程编排结果
GET /api/martial/schedule/result

// 保存编排草稿
POST /api/martial/schedule/save-draft

// 完成编排并锁定
POST /api/martial/schedule/save-and-lock

后端Controller路径 (MartialScheduleController.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文档注解

所有代码遵循项目现有的代码风格和架构规范,可以直接集成到现有系统中使用。