package com.rongyichuang.activity.service;
|
|
import com.rongyichuang.activity.dto.ActivityInput;
|
import com.rongyichuang.activity.dto.ActivityJudgeInput;
|
import com.rongyichuang.activity.dto.ActivityJudgeResponse;
|
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.judge.entity.Judge;
|
import com.rongyichuang.judge.repository.JudgeRepository;
|
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.ArrayList;
|
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 JudgeRepository judgeRepository;
|
|
@Autowired
|
private RatingSchemeRepository ratingSchemeRepository;
|
|
/**
|
* 分页查询比赛列表
|
*/
|
public PageResponse<ActivityResponse> findActivities(PageRequest pageRequest, String name) {
|
Pageable pageable = pageRequest.toPageable();
|
Page<Activity> page;
|
|
if (StringUtils.hasText(name)) {
|
page = activityRepository.findByPidAndStateAndNameContainingOrderByCreateTimeDesc(0L, 1, name, pageable);
|
} else {
|
page = activityRepository.findByPidAndStateOrderByCreateTimeDesc(0L, 1, pageable);
|
}
|
|
List<ActivityResponse> 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<Activity> activityOpt = activityRepository.findById(id);
|
if (activityOpt.isPresent()) {
|
Activity activity = activityOpt.get();
|
ActivityResponse response = new ActivityResponse(activity);
|
|
// 如果是比赛,加载其阶段
|
if (activity.isMainActivity()) {
|
List<Activity> stages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(id, 1);
|
List<ActivityResponse> stageResponses = stages.stream()
|
.map(ActivityResponse::new)
|
.collect(Collectors.toList());
|
response.setStages(stageResponses);
|
}
|
|
// 加载评委数据
|
List<ActivityJudgeResponse> judges = loadActivityJudges(id);
|
response.setJudges(judges);
|
|
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<Activity> 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<RatingScheme> schemeOpt = ratingSchemeRepository.findById(input.getRatingSchemeId());
|
if (!schemeOpt.isPresent()) {
|
throw new RuntimeException("评分模板不存在");
|
}
|
}
|
|
// 保存比赛
|
activity = activityRepository.save(activity);
|
|
// 如果是比赛且有阶段信息,保存阶段
|
if (input.isMainActivity() && input.getStages() != null && !input.getStages().isEmpty()) {
|
saveActivityStages(activity.getId(), input.getStages());
|
}
|
|
// 如果是比赛且有评委信息,保存评委
|
if (input.isMainActivity() && input.getJudges() != null && !input.getJudges().isEmpty()) {
|
saveActivityJudges(activity.getId(), input.getJudges());
|
}
|
|
// 重新查询完整的数据(包含关联的stages)
|
return findById(activity.getId());
|
}
|
|
/**
|
* 保存比赛阶段
|
*/
|
private void saveActivityStages(Long activityId, List<ActivityStageInput> stageInputs) {
|
// 获取现有的所有阶段
|
List<Activity> existingStages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(activityId, 1);
|
|
// 收集传入的阶段ID
|
List<Long> 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<Activity> activityOpt = activityRepository.findById(activityId);
|
if (!activityOpt.isPresent()) {
|
throw new RuntimeException("比赛不存在");
|
}
|
Activity activity = activityOpt.get();
|
|
// 处理传入的阶段(新增或更新)
|
for (ActivityStageInput stageInput : stageInputs) {
|
Activity stage;
|
|
if (stageInput.isNew()) {
|
// 新增阶段
|
stage = new Activity();
|
stage.setPid(activityId);
|
stage.setPath(generatePath(activityId));
|
} else {
|
// 编辑阶段
|
Optional<Activity> 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(activity.getSignupDeadline());
|
|
// 阶段的评分模板:如果指定了则使用指定的,否则继承比赛的评分模板
|
if (stageInput.getRatingSchemeId() != null) {
|
stage.setRatingSchemeId(stageInput.getRatingSchemeId());
|
} else {
|
stage.setRatingSchemeId(activity.getRatingSchemeId());
|
}
|
|
activityRepository.save(stage);
|
}
|
}
|
|
/**
|
* 保存比赛评委
|
*/
|
private void saveActivityJudges(Long activityId, List<ActivityJudgeInput> judgeInputs) {
|
if (judgeInputs == null || judgeInputs.isEmpty()) {
|
return;
|
}
|
|
// 获取比赛的所有阶段(如果有的话)
|
List<Activity> stages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(activityId, 1);
|
|
// 保存评委关联
|
for (ActivityJudgeInput judgeInput : judgeInputs) {
|
// 先删除该评委的现有关联
|
activityJudgeRepository.deleteByActivityIdAndJudgeId(activityId, judgeInput.getJudgeId());
|
|
if (judgeInput.getStageIds() == null || judgeInput.getStageIds().isEmpty()) {
|
// 如果没有指定阶段,创建关联到所有阶段(如果有阶段)或直接关联到比赛(如果没有阶段)
|
if (stages.isEmpty()) {
|
// 比赛没有阶段,直接关联到比赛(stage_id为null表示所有阶段)
|
ActivityJudge activityJudge = new ActivityJudge(activityId, judgeInput.getJudgeId(), null);
|
activityJudgeRepository.save(activityJudge);
|
} else {
|
// 为每个阶段创建关联
|
for (Activity stage : stages) {
|
ActivityJudge activityJudge = new ActivityJudge(activityId, judgeInput.getJudgeId(), stage.getId());
|
activityJudgeRepository.save(activityJudge);
|
}
|
}
|
} else {
|
// 为每个指定的阶段创建关联
|
for (Long stageId : judgeInput.getStageIds()) {
|
ActivityJudge activityJudge = new ActivityJudge(activityId, judgeInput.getJudgeId(), stageId);
|
activityJudgeRepository.save(activityJudge);
|
}
|
}
|
}
|
}
|
|
/**
|
* 删除比赛
|
*/
|
public boolean deleteActivity(Long id) {
|
Optional<Activity> activityOpt = activityRepository.findById(id);
|
if (activityOpt.isPresent()) {
|
Activity activity = activityOpt.get();
|
|
// 如果是比赛,先删除其所有阶段
|
if (activity.isMainActivity()) {
|
List<Activity> 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<ActivityResponse> findAllActivitiesForSelection() {
|
// 获取所有活动(包括比赛和阶段)
|
List<Activity> activities = activityRepository.findByStateOrderByPidAscNameAsc(1);
|
|
// 创建比赛ID到比赛对象的映射,用于快速查找父比赛
|
Map<Long, Activity> mainActivityMap = activities.stream()
|
.filter(activity -> activity.getPid() == 0)
|
.collect(Collectors.toMap(Activity::getId, activity -> activity));
|
|
// 转换为ActivityResponse并填充parent信息
|
List<ActivityResponse> result = activities.stream()
|
.map(activity -> {
|
ActivityResponse response = new ActivityResponse(activity);
|
// 如果是阶段(pid > 0),填充parent信息
|
if (activity.getPid() > 0) {
|
Activity parentActivity = mainActivityMap.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<ActivityResponse> findStagesByActivityId(Long activityId) {
|
List<Activity> stages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(activityId, 1);
|
return stages.stream()
|
.map(ActivityResponse::new)
|
.collect(Collectors.toList());
|
}
|
|
/**
|
* 统计比赛数量
|
*/
|
public long countActiveActivities() {
|
return activityRepository.countActiveActivities();
|
}
|
|
/**
|
* 获取进行中的比赛
|
*/
|
public List<ActivityResponse> findOngoingActivities() {
|
List<Activity> activities = activityRepository.findOngoingActivities();
|
return activities.stream()
|
.map(ActivityResponse::new)
|
.collect(Collectors.toList());
|
}
|
|
/**
|
* 生成路径
|
*/
|
private String generatePath(Long pid) {
|
if (pid == 0) {
|
return "/";
|
} else {
|
Optional<Activity> parentOpt = activityRepository.findById(pid);
|
if (parentOpt.isPresent()) {
|
return parentOpt.get().getPath() + pid + "/";
|
}
|
return "/" + pid + "/";
|
}
|
}
|
|
/**
|
* 加载活动的评委数据
|
*/
|
private List<ActivityJudgeResponse> loadActivityJudges(Long activityId) {
|
// 查询活动的评委关联
|
List<ActivityJudge> activityJudges = activityJudgeRepository.findByActivityId(activityId);
|
|
// 按评委ID分组,收集每个评委负责的阶段
|
Map<Long, List<Long>> judgeStageMap = activityJudges.stream()
|
.collect(Collectors.groupingBy(
|
ActivityJudge::getJudgeId,
|
Collectors.mapping(ActivityJudge::getStageId, Collectors.toList())
|
));
|
|
// 查询评委详细信息并构建响应
|
List<ActivityJudgeResponse> result = new ArrayList<>();
|
for (Map.Entry<Long, List<Long>> entry : judgeStageMap.entrySet()) {
|
Long judgeId = entry.getKey();
|
List<Long> stageIds = entry.getValue();
|
|
Optional<Judge> judgeOpt = judgeRepository.findById(judgeId);
|
if (judgeOpt.isPresent()) {
|
Judge judge = judgeOpt.get();
|
ActivityJudgeResponse judgeResponse = new ActivityJudgeResponse(
|
judge.getId(),
|
judge.getName(),
|
judge.getPhone(),
|
judge.getDescription(),
|
stageIds
|
);
|
result.add(judgeResponse);
|
}
|
}
|
|
return result;
|
}
|
}
|