package com.rongyichuang.activity.service; import com.rongyichuang.activity.dto.ActivityInput; import com.rongyichuang.activity.dto.ActivityJudgeInput; import com.rongyichuang.activity.dto.ActivityResponse; import com.rongyichuang.activity.dto.ActivityStageInput; import com.rongyichuang.activity.entity.Activity; import com.rongyichuang.activity.entity.ActivityJudge; import com.rongyichuang.activity.repository.ActivityJudgeRepository; import com.rongyichuang.activity.repository.ActivityRepository; import com.rongyichuang.common.dto.PageRequest; import com.rongyichuang.common.dto.PageResponse; import com.rongyichuang.rating.entity.RatingScheme; import com.rongyichuang.rating.repository.RatingSchemeRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @Service @Transactional public class ActivityService { @Autowired private ActivityRepository activityRepository; @Autowired private ActivityJudgeRepository activityJudgeRepository; @Autowired private RatingSchemeRepository ratingSchemeRepository; /** * 分页查询比赛列表 */ public PageResponse findCompetitions(PageRequest pageRequest, String name) { Pageable pageable = pageRequest.toPageable(); Page page; if (StringUtils.hasText(name)) { page = activityRepository.findByPidAndStateAndNameContainingOrderByCreateTimeDesc(0L, 1, name, pageable); } else { page = activityRepository.findByPidAndStateOrderByCreateTimeDesc(0L, 1, pageable); } List content = page.getContent().stream() .map(ActivityResponse::new) .collect(Collectors.toList()); return new PageResponse<>(content, page.getTotalElements(), page.getNumber(), page.getSize()); } /** * 获取比赛详情 */ public ActivityResponse findById(Long id) { Optional activityOpt = activityRepository.findById(id); if (activityOpt.isPresent()) { Activity activity = activityOpt.get(); ActivityResponse response = new ActivityResponse(activity); // 如果是比赛,加载其阶段 if (activity.isCompetition()) { List stages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(id, 1); List stageResponses = stages.stream() .map(ActivityResponse::new) .collect(Collectors.toList()); response.setStages(stageResponses); } return response; } return null; } /** * 保存比赛(新增或编辑) */ public ActivityResponse saveActivity(ActivityInput input) { Activity activity; if (input.isNew()) { // 新增比赛 activity = new Activity(); activity.setPid(input.getPid()); activity.setPath(generatePath(input.getPid())); } else { // 编辑比赛 Optional existingOpt = activityRepository.findById(input.getId()); if (!existingOpt.isPresent()) { throw new RuntimeException("比赛不存在"); } activity = existingOpt.get(); } // 设置基本信息 activity.setName(input.getName()); activity.setDescription(input.getDescription()); activity.setSignupDeadline(input.getSignupDeadline()); activity.setMatchTime(input.getMatchTime()); activity.setAddress(input.getAddress()); activity.setRatingSchemeId(input.getRatingSchemeId()); activity.setPlayerMax(input.getPlayerMax()); activity.setState(input.getState()); // 验证评分模板是否存在 if (input.getRatingSchemeId() != null) { Optional schemeOpt = ratingSchemeRepository.findById(input.getRatingSchemeId()); if (!schemeOpt.isPresent()) { throw new RuntimeException("评分模板不存在"); } } // 保存比赛 activity = activityRepository.save(activity); // 如果是比赛且有阶段信息,保存阶段 if (input.isCompetition() && input.getStages() != null && !input.getStages().isEmpty()) { saveActivityStages(activity.getId(), input.getStages()); } // 如果是比赛且有评委信息,保存评委 if (input.isCompetition() && input.getJudges() != null && !input.getJudges().isEmpty()) { saveActivityJudges(activity.getId(), input.getJudges()); } // 重新查询完整的数据(包含关联的stages) return findById(activity.getId()); } /** * 保存比赛阶段 */ private void saveActivityStages(Long competitionId, List stageInputs) { // 获取现有的所有阶段 List existingStages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(competitionId, 1); // 收集传入的阶段ID List inputStageIds = stageInputs.stream() .filter(input -> !input.isNew()) .map(ActivityStageInput::getId) .collect(Collectors.toList()); // 删除不在传入列表中的现有阶段(软删除) for (Activity existingStage : existingStages) { if (!inputStageIds.contains(existingStage.getId())) { existingStage.setState(0); // 软删除 activityRepository.save(existingStage); } } // 获取比赛信息,用于继承报名截止时间和评分模板 Optional competitionOpt = activityRepository.findById(competitionId); if (!competitionOpt.isPresent()) { throw new RuntimeException("比赛不存在"); } Activity competition = competitionOpt.get(); // 处理传入的阶段(新增或更新) for (ActivityStageInput stageInput : stageInputs) { Activity stage; if (stageInput.isNew()) { // 新增阶段 stage = new Activity(); stage.setPid(competitionId); stage.setPath(generatePath(competitionId)); } else { // 编辑阶段 Optional existingOpt = activityRepository.findById(stageInput.getId()); if (!existingOpt.isPresent()) { continue; // 跳过不存在的阶段 } stage = existingOpt.get(); } // 设置阶段信息 stage.setName(stageInput.getName()); stage.setDescription(stageInput.getDescription()); stage.setMatchTime(stageInput.getMatchTime()); stage.setAddress(stageInput.getAddress()); stage.setPlayerMax(stageInput.getPlayerMax()); stage.setState(stageInput.getState()); // 阶段继承比赛的报名截止时间 stage.setSignupDeadline(competition.getSignupDeadline()); // 阶段的评分模板:如果指定了则使用指定的,否则继承比赛的评分模板 if (stageInput.getRatingSchemeId() != null) { stage.setRatingSchemeId(stageInput.getRatingSchemeId()); } else { stage.setRatingSchemeId(competition.getRatingSchemeId()); } activityRepository.save(stage); } } /** * 保存比赛评委 */ private void saveActivityJudges(Long competitionId, List judgeInputs) { if (judgeInputs == null || judgeInputs.isEmpty()) { return; } // 获取比赛的所有阶段(如果有的话) List stages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(competitionId, 1); // 保存评委关联 for (ActivityJudgeInput judgeInput : judgeInputs) { // 先删除该评委的现有关联 activityJudgeRepository.deleteByActivityIdAndJudgeId(competitionId, judgeInput.getJudgeId()); if (judgeInput.getStageIds() == null || judgeInput.getStageIds().isEmpty()) { // 如果没有指定阶段,创建关联到所有阶段(如果有阶段)或直接关联到比赛(如果没有阶段) if (stages.isEmpty()) { // 比赛没有阶段,直接关联到比赛(stage_id为null表示所有阶段) ActivityJudge activityJudge = new ActivityJudge(competitionId, judgeInput.getJudgeId(), null); activityJudgeRepository.save(activityJudge); } else { // 为每个阶段创建关联 for (Activity stage : stages) { ActivityJudge activityJudge = new ActivityJudge(competitionId, judgeInput.getJudgeId(), stage.getId()); activityJudgeRepository.save(activityJudge); } } } else { // 为每个指定的阶段创建关联 for (Long stageId : judgeInput.getStageIds()) { ActivityJudge activityJudge = new ActivityJudge(competitionId, judgeInput.getJudgeId(), stageId); activityJudgeRepository.save(activityJudge); } } } } /** * 删除比赛 */ public boolean deleteActivity(Long id) { Optional activityOpt = activityRepository.findById(id); if (activityOpt.isPresent()) { Activity activity = activityOpt.get(); // 如果是比赛,先删除其所有阶段 if (activity.isCompetition()) { List stages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(id, 1); for (Activity stage : stages) { stage.setState(0); // 软删除 activityRepository.save(stage); } } // 软删除比赛 activity.setState(0); activityRepository.save(activity); return true; } return false; } /** * 获取所有有效比赛和阶段(用于下拉选择) */ public List findAllActivitiesForSelection() { // 获取所有活动(包括比赛和阶段) List activities = activityRepository.findByStateOrderByPidAscNameAsc(1); // 创建比赛ID到比赛对象的映射,用于快速查找父比赛 Map competitionMap = activities.stream() .filter(activity -> activity.getPid() == 0) .collect(Collectors.toMap(Activity::getId, activity -> activity)); // 转换为ActivityResponse并填充parent信息 List result = activities.stream() .map(activity -> { ActivityResponse response = new ActivityResponse(activity); // 如果是阶段(pid > 0),填充parent信息 if (activity.getPid() > 0) { Activity parentActivity = competitionMap.get(activity.getPid()); if (parentActivity != null) { response.setParent(new ActivityResponse(parentActivity)); } } return response; }) .collect(Collectors.toList()); // 自定义排序:比赛和其阶段放在一起 result.sort((a, b) -> { // 如果都是比赛(pid=0),按名称排序 if (a.getPid() == 0 && b.getPid() == 0) { return a.getName().compareTo(b.getName()); } // 如果都是阶段,先按父比赛名称排序,再按阶段名称排序 if (a.getPid() > 0 && b.getPid() > 0) { String aParentName = a.getParent() != null ? a.getParent().getName() : ""; String bParentName = b.getParent() != null ? b.getParent().getName() : ""; int parentCompare = aParentName.compareTo(bParentName); if (parentCompare != 0) { return parentCompare; } return a.getName().compareTo(b.getName()); } // 如果一个是比赛,一个是阶段 if (a.getPid() == 0 && b.getPid() > 0) { String bParentName = b.getParent() != null ? b.getParent().getName() : ""; int compare = a.getName().compareTo(bParentName); return compare <= 0 ? -1 : 1; // 比赛排在其阶段前面 } if (a.getPid() > 0 && b.getPid() == 0) { String aParentName = a.getParent() != null ? a.getParent().getName() : ""; int compare = aParentName.compareTo(b.getName()); return compare < 0 ? -1 : 1; // 阶段排在其比赛后面 } return 0; }); return result; } /** * 获取比赛的所有阶段 */ public List findStagesByCompetitionId(Long competitionId) { List stages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(competitionId, 1); return stages.stream() .map(ActivityResponse::new) .collect(Collectors.toList()); } /** * 统计比赛数量 */ public long countActiveCompetitions() { return activityRepository.countActiveCompetitions(); } /** * 获取进行中的比赛 */ public List findOngoingCompetitions() { List activities = activityRepository.findOngoingCompetitions(); return activities.stream() .map(ActivityResponse::new) .collect(Collectors.toList()); } /** * 生成路径 */ private String generatePath(Long pid) { if (pid == 0) { return "/"; } else { Optional parentOpt = activityRepository.findById(pid); if (parentOpt.isPresent()) { return parentOpt.get().getPath() + pid + "/"; } return "/" + pid + "/"; } } }