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

348 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 赛程编排后端实现总结
## 实施概览
本次实现了赛程编排系统的三个核心后端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文档注解
所有代码遵循项目现有的代码风格和架构规范,可以直接集成到现有系统中使用。