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

202 lines
6.2 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冲突修复说明
## 问题描述
在实现赛程编排后端API时发现项目中已经存在 `MartialScheduleArrangeController` 控制器,该控制器已经定义了相同的路径:
- `GET /martial/schedule/result`
- `POST /martial/schedule/save-and-lock`
这导致Spring Boot启动时报错
```
Ambiguous mapping. Cannot map 'martialScheduleController' method to {POST [/martial/schedule/save-and-lock]}:
There is already 'martialScheduleArrangeController' bean method mapped.
```
## 解决方案
### 1. 删除重复的控制器端点
从新创建的 `MartialScheduleController` 中删除了冲突的3个端点
- `/result`
- `/save-draft`
- `/save-and-lock`
保留原有的基础CRUD端点detail, list, submit, remove
### 2. 更新现有控制器
修改 `MartialScheduleArrangeController`使其使用新创建的Service和DTO
**文件**: [MartialScheduleArrangeController.java](d:\workspace\31.比赛项目\project\martial-master\src\main\java\org\springblade\modules\martial\controller\MartialScheduleArrangeController.java)
#### 2.1 添加依赖注入
```java
private final IMartialScheduleArrangeService scheduleArrangeService;
private final IMartialScheduleService scheduleService; // 新增
```
#### 2.2 更新 GET /result 端点
**修改前**:
```java
public R<Map<String, Object>> getScheduleResult(@RequestParam Long competitionId) {
Map<String, Object> result = scheduleArrangeService.getScheduleResult(competitionId);
return R.data(result);
}
```
**修改后**:
```java
public R<ScheduleResultDTO> getScheduleResult(@RequestParam Long competitionId) {
ScheduleResultDTO result = scheduleService.getScheduleResult(competitionId);
return R.data(result);
}
```
**改进**:
- 使用结构化的DTO替代Map
- 返回类型更加明确
- 符合前端API规范
#### 2.3 新增 POST /save-draft 端点
```java
@PostMapping("/save-draft")
@Operation(summary = "保存编排草稿", description = "传入编排草稿数据")
public R saveDraftSchedule(@RequestBody SaveScheduleDraftDTO dto) {
try {
boolean success = scheduleService.saveDraftSchedule(dto);
return success ? R.success("草稿保存成功") : R.fail("草稿保存失败");
} catch (Exception e) {
log.error("保存编排草稿失败", e);
return R.fail("保存编排草稿失败: " + e.getMessage());
}
}
```
#### 2.4 更新 POST /save-and-lock 端点
**修改前**:
```java
public R saveAndLock(@RequestBody Map<String, Object> params) {
Long competitionId = Long.valueOf(String.valueOf(params.get("competitionId")));
scheduleArrangeService.saveAndLock(competitionId, userId);
return R.success("编排已保存并锁定");
}
```
**修改后**:
```java
public R saveAndLock(@RequestBody SaveScheduleDraftDTO dto) {
BladeUser user = AuthUtil.getUser();
String userId = user != null ? user.getUserName() : "system";
boolean success = scheduleService.saveAndLockSchedule(dto.getCompetitionId());
if (success) {
// 调用原有的锁定逻辑
scheduleArrangeService.saveAndLock(dto.getCompetitionId(), userId);
return R.success("编排已完成并锁定");
} else {
return R.fail("编排锁定失败");
}
}
```
**改进**:
1. 使用DTO替代Map类型安全
2. 结合新旧两个Service的功能
3. 先更新参赛者状态,再执行原有的锁定逻辑
## 最终API结构
### MartialScheduleArrangeController
**基础路径**: `/martial/schedule`
| 方法 | 路径 | 功能 | 请求类型 | 响应类型 |
|------|------|------|----------|----------|
| GET | `/result` | 获取编排结果 | competitionId | ScheduleResultDTO |
| POST | `/save-draft` | 保存编排草稿 | SaveScheduleDraftDTO | R |
| POST | `/save-and-lock` | 完成编排并锁定 | SaveScheduleDraftDTO | R |
| POST | `/auto-arrange` | 手动触发自动编排 | Map | R |
### MartialScheduleController
**基础路径**: `/martial/schedule`
| 方法 | 路径 | 功能 | 请求类型 | 响应类型 |
|------|------|------|----------|----------|
| GET | `/detail` | 获取详情 | id | MartialSchedule |
| GET | `/list` | 分页列表 | MartialSchedule, Query | IPage |
| POST | `/submit` | 新增或修改 | MartialSchedule | R |
| POST | `/remove` | 删除 | ids | R |
## 字段冲突修复
### 问题
实体类 `MartialScheduleParticipant``status` 字段与基础类 `TenantEntity` 冲突。
### 解决方案
`status` 字段重命名为 `checkInStatus`(签到状态):
**文件**: [MartialScheduleParticipant.java:86-90](d:\workspace\31.比赛项目\project\martial-master\src\main\java\org\springblade\modules\martial\pojo\entity\MartialScheduleParticipant.java#L86-L90)
```java
/**
* 签到状态:未签到/已签到/异常
*/
@Schema(description = "签到状态:未签到/已签到/异常")
private String checkInStatus;
```
### 相应更新
**Service层** ([MartialScheduleServiceImpl.java](d:\workspace\31.比赛项目\project\martial-master\src\main\java\org\springblade\modules\martial\service\impl\MartialScheduleServiceImpl.java)):
1. **读取时**:
```java
dto.setStatus(p.getCheckInStatus() != null ? p.getCheckInStatus() : "未签到");
```
2. **保存时**:
```java
participant.setCheckInStatus(participantDTO.getStatus());
```
前端仍然使用 `status` 字段在Service层进行映射转换。
## 数据库字段名建议
```sql
ALTER TABLE martial_schedule_participant
ADD COLUMN check_in_status VARCHAR(20) DEFAULT '未签到' COMMENT '签到状态:未签到/已签到/异常',
ADD COLUMN schedule_status VARCHAR(20) DEFAULT 'draft' COMMENT '编排状态draft/completed';
```
## 前后端对接
前端API配置无需修改仍然使用原有路径
```javascript
// 获取赛程编排结果
GET /api/martial/schedule/result
// 保存编排草稿
POST /api/martial/schedule/save-draft
// 完成编排并锁定
POST /api/martial/schedule/save-and-lock
```
所有端点都通过 `MartialScheduleArrangeController` 处理。
## 总结
通过以下措施解决了API冲突问题
1. ✅ 删除重复的控制器端点
2. ✅ 更新现有控制器使用新的DTO和Service
3. ✅ 修复字段名冲突
4. ✅ 保持前端API路径不变
5. ✅ 结合新旧Service功能确保业务逻辑完整
现在系统可以正常启动API端点清晰明确没有冲突。