feat(schedule): 无编排数据时自动从项目和选手表生成初始分组
- 修改 getScheduleResult 方法,当没有编排数据时调用 generateInitialScheduleResult - 新增 generateInitialScheduleResult 方法,从项目和选手表生成初始分组 - CompetitionGroupDTO 添加 projectId 字段 - ParticipantDTO 添加 teamName 字段 - 用户进入编排页面可直接看到选手数据,无需先执行自动编排
This commit is contained in:
@@ -23,6 +23,12 @@ public class CompetitionGroupDTO implements Serializable {
|
|||||||
@Schema(description = "分组ID")
|
@Schema(description = "分组ID")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 项目ID
|
||||||
|
*/
|
||||||
|
@Schema(description = "项目ID")
|
||||||
|
private Long projectId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分组标题
|
* 分组标题
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -28,6 +28,12 @@ public class ParticipantDTO implements Serializable {
|
|||||||
@Schema(description = "学校/单位")
|
@Schema(description = "学校/单位")
|
||||||
private String schoolUnit;
|
private String schoolUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 队伍名称
|
||||||
|
*/
|
||||||
|
@Schema(description = "队伍名称")
|
||||||
|
private String teamName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态:未签到/已签到/异常
|
* 状态:未签到/已签到/异常
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -147,10 +147,8 @@ public class MartialScheduleServiceImpl extends ServiceImpl<MartialScheduleMappe
|
|||||||
List<ScheduleGroupDetailVO> details = scheduleGroupMapper.selectScheduleGroupDetails(competitionId);
|
List<ScheduleGroupDetailVO> details = scheduleGroupMapper.selectScheduleGroupDetails(competitionId);
|
||||||
|
|
||||||
if (details.isEmpty()) {
|
if (details.isEmpty()) {
|
||||||
result.setIsDraft(true);
|
// 没有编排数据时,从项目和选手表生成初始分组
|
||||||
result.setIsCompleted(false);
|
return generateInitialScheduleResult(competitionId);
|
||||||
result.setCompetitionGroups(new ArrayList<>());
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 按分组ID分组数据
|
// 按分组ID分组数据
|
||||||
@@ -173,7 +171,7 @@ public class MartialScheduleServiceImpl extends ServiceImpl<MartialScheduleMappe
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取第一条记录作为分组信息(同一分组的记录,分组信息是相同的)
|
// 获取第一条记录作为分组信息
|
||||||
ScheduleGroupDetailVO firstDetail = groupDetails.get(0);
|
ScheduleGroupDetailVO firstDetail = groupDetails.get(0);
|
||||||
|
|
||||||
CompetitionGroupDTO groupDTO = new CompetitionGroupDTO();
|
CompetitionGroupDTO groupDTO = new CompetitionGroupDTO();
|
||||||
@@ -207,11 +205,11 @@ public class MartialScheduleServiceImpl extends ServiceImpl<MartialScheduleMappe
|
|||||||
groupDTO.setVenueId(firstDetail.getVenueId());
|
groupDTO.setVenueId(firstDetail.getVenueId());
|
||||||
groupDTO.setVenueName(firstDetail.getVenueName());
|
groupDTO.setVenueName(firstDetail.getVenueName());
|
||||||
groupDTO.setTimeSlot(firstDetail.getTimeSlot());
|
groupDTO.setTimeSlot(firstDetail.getTimeSlot());
|
||||||
groupDTO.setTimeSlotIndex(firstDetail.getTimeSlotIndex() != null ? firstDetail.getTimeSlotIndex() : 0); // 直接从数据库读取
|
groupDTO.setTimeSlotIndex(firstDetail.getTimeSlotIndex() != null ? firstDetail.getTimeSlotIndex() : 0);
|
||||||
|
|
||||||
// 获取参赛者列表
|
// 获取参赛者列表
|
||||||
List<ParticipantDTO> participantDTOs = groupDetails.stream()
|
List<ParticipantDTO> participantDTOs = groupDetails.stream()
|
||||||
.filter(d -> d.getParticipantId() != null) // 过滤掉没有参赛者的记录
|
.filter(d -> d.getParticipantId() != null)
|
||||||
.map(d -> {
|
.map(d -> {
|
||||||
ParticipantDTO dto = new ParticipantDTO();
|
ParticipantDTO dto = new ParticipantDTO();
|
||||||
dto.setId(d.getParticipantId());
|
dto.setId(d.getParticipantId());
|
||||||
@@ -240,6 +238,122 @@ public class MartialScheduleServiceImpl extends ServiceImpl<MartialScheduleMappe
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 没有编排数据时,从项目和选手表生成初始分组
|
||||||
|
*/
|
||||||
|
private ScheduleResultDTO generateInitialScheduleResult(Long competitionId) {
|
||||||
|
ScheduleResultDTO result = new ScheduleResultDTO();
|
||||||
|
result.setIsDraft(true);
|
||||||
|
result.setIsCompleted(false);
|
||||||
|
|
||||||
|
// 1. 获取该赛事的所有项目
|
||||||
|
List<MartialProject> projects = projectService.list(
|
||||||
|
new QueryWrapper<MartialProject>()
|
||||||
|
.eq("competition_id", competitionId)
|
||||||
|
.eq("is_deleted", 0)
|
||||||
|
.orderByAsc("id")
|
||||||
|
);
|
||||||
|
|
||||||
|
if (projects.isEmpty()) {
|
||||||
|
result.setCompetitionGroups(new ArrayList<>());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 获取该赛事的所有选手
|
||||||
|
List<MartialAthlete> athletes = athleteService.list(
|
||||||
|
new QueryWrapper<MartialAthlete>()
|
||||||
|
.eq("competition_id", competitionId)
|
||||||
|
.eq("is_deleted", 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 按项目ID分组选手
|
||||||
|
Map<Long, List<MartialAthlete>> athletesByProject = athletes.stream()
|
||||||
|
.collect(Collectors.groupingBy(MartialAthlete::getProjectId));
|
||||||
|
|
||||||
|
// 3. 获取该赛事的第一个场地作为默认场地
|
||||||
|
List<MartialVenue> venues = venueService.list(
|
||||||
|
new QueryWrapper<MartialVenue>()
|
||||||
|
.eq("competition_id", competitionId)
|
||||||
|
.eq("is_deleted", 0)
|
||||||
|
.orderByAsc("id")
|
||||||
|
.last("LIMIT 1")
|
||||||
|
);
|
||||||
|
|
||||||
|
Long defaultVenueId = venues.isEmpty() ? null : venues.get(0).getId();
|
||||||
|
String defaultVenueName = venues.isEmpty() ? "未分配" : venues.get(0).getVenueName();
|
||||||
|
|
||||||
|
// 4. 为每个项目生成一个分组
|
||||||
|
List<CompetitionGroupDTO> groupDTOs = new ArrayList<>();
|
||||||
|
int displayOrder = 0;
|
||||||
|
|
||||||
|
for (MartialProject project : projects) {
|
||||||
|
List<MartialAthlete> projectAthletes = athletesByProject.getOrDefault(project.getId(), new ArrayList<>());
|
||||||
|
|
||||||
|
// 跳过没有选手的项目
|
||||||
|
if (projectAthletes.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
CompetitionGroupDTO groupDTO = new CompetitionGroupDTO();
|
||||||
|
// 使用负数ID表示这是临时生成的分组(未保存到数据库)
|
||||||
|
groupDTO.setId(-project.getId());
|
||||||
|
groupDTO.setProjectId(project.getId());
|
||||||
|
groupDTO.setTitle(project.getProjectName() + " 未分组");
|
||||||
|
groupDTO.setCode(project.getProjectCode());
|
||||||
|
|
||||||
|
// 设置类型
|
||||||
|
Integer projectType = project.getType();
|
||||||
|
if (projectType != null) {
|
||||||
|
switch (projectType) {
|
||||||
|
case 1:
|
||||||
|
groupDTO.setType("单人");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
groupDTO.setType("双人");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
groupDTO.setType("集体");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
groupDTO.setType("其他");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
groupDTO.setType("单人");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置数量
|
||||||
|
groupDTO.setCount(projectAthletes.size() + "人");
|
||||||
|
|
||||||
|
// 设置默认场地和时间段
|
||||||
|
groupDTO.setVenueId(defaultVenueId);
|
||||||
|
groupDTO.setVenueName(defaultVenueName);
|
||||||
|
groupDTO.setTimeSlotIndex(0); // 默认放在第一个时间段
|
||||||
|
groupDTO.setTimeSlot(null);
|
||||||
|
|
||||||
|
// 生成参赛者列表
|
||||||
|
List<ParticipantDTO> participantDTOs = new ArrayList<>();
|
||||||
|
int sortOrder = 1;
|
||||||
|
for (MartialAthlete athlete : projectAthletes) {
|
||||||
|
ParticipantDTO dto = new ParticipantDTO();
|
||||||
|
dto.setId(athlete.getId());
|
||||||
|
dto.setPlayerName(athlete.getPlayerName());
|
||||||
|
dto.setSchoolUnit(athlete.getOrganization());
|
||||||
|
dto.setTeamName(athlete.getTeamName());
|
||||||
|
dto.setStatus("未签到");
|
||||||
|
dto.setSortOrder(sortOrder++);
|
||||||
|
participantDTOs.add(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
groupDTO.setParticipants(participantDTOs);
|
||||||
|
groupDTOs.add(groupDTO);
|
||||||
|
displayOrder++;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.setCompetitionGroups(groupDTOs);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存编排草稿
|
* 保存编排草稿
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user