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

6.2 KiB
Raw Blame History

赛程编排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

2.1 添加依赖注入

private final IMartialScheduleArrangeService scheduleArrangeService;
private final IMartialScheduleService scheduleService; // 新增

2.2 更新 GET /result 端点

修改前:

public R<Map<String, Object>> getScheduleResult(@RequestParam Long competitionId) {
    Map<String, Object> result = scheduleArrangeService.getScheduleResult(competitionId);
    return R.data(result);
}

修改后:

public R<ScheduleResultDTO> getScheduleResult(@RequestParam Long competitionId) {
    ScheduleResultDTO result = scheduleService.getScheduleResult(competitionId);
    return R.data(result);
}

改进:

  • 使用结构化的DTO替代Map
  • 返回类型更加明确
  • 符合前端API规范

2.3 新增 POST /save-draft 端点

@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 端点

修改前:

public R saveAndLock(@RequestBody Map<String, Object> params) {
    Long competitionId = Long.valueOf(String.valueOf(params.get("competitionId")));
    scheduleArrangeService.saveAndLock(competitionId, userId);
    return R.success("编排已保存并锁定");
}

修改后:

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

字段冲突修复

问题

实体类 MartialScheduleParticipantstatus 字段与基础类 TenantEntity 冲突。

解决方案

status 字段重命名为 checkInStatus(签到状态):

文件: MartialScheduleParticipant.java:86-90

/**
 * 签到状态:未签到/已签到/异常
 */
@Schema(description = "签到状态:未签到/已签到/异常")
private String checkInStatus;

相应更新

Service层 (MartialScheduleServiceImpl.java):

  1. 读取时:
dto.setStatus(p.getCheckInStatus() != null ? p.getCheckInStatus() : "未签到");
  1. 保存时:
participant.setCheckInStatus(participantDTO.getStatus());

前端仍然使用 status 字段在Service层进行映射转换。

数据库字段名建议

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配置无需修改仍然使用原有路径

// 获取赛程编排结果
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端点清晰明确没有冲突。