package com.rongyichuang.player.service; import com.rongyichuang.activity.entity.Activity; import com.rongyichuang.activity.entity.ActivityPlayerRating; import com.rongyichuang.activity.repository.ActivityRepository; import com.rongyichuang.activity.repository.ActivityPlayerRatingRepository; import com.rongyichuang.common.entity.Media; import com.rongyichuang.common.repository.MediaRepository; import com.rongyichuang.message.service.MessageService; import com.rongyichuang.player.dto.*; import com.rongyichuang.player.entity.ActivityPlayer; import com.rongyichuang.player.repository.ActivityPlayerRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * 比赛晋级服务类 */ @Service public class PromotionService { @Autowired private ActivityRepository activityRepository; @Autowired private ActivityPlayerRepository activityPlayerRepository; @Autowired private ActivityPlayerRatingRepository activityPlayerRatingRepository; @Autowired private MediaRepository mediaRepository; @Autowired private MessageService messageService; /** * 获取比赛晋级列表 */ public List getPromotionCompetitions(String name, Integer page, Integer size) { List result = new ArrayList<>(); // 查询所有有效的主比赛(pid = 0) List competitions = activityRepository.findByPidAndStateOrderByCreateTimeAsc(0L, 1); // 如果有名称过滤条件,进行过滤 if (name != null && !name.trim().isEmpty()) { competitions = competitions.stream() .filter(comp -> comp.getName().contains(name.trim())) .collect(Collectors.toList()); } // 为每个比赛查询其阶段 for (Activity competition : competitions) { List stages = activityRepository.findByPidAndStateOrderByCreateTimeAsc(competition.getId(), 1); for (Activity stage : stages) { // 统计当前阶段的参赛人数 Long playerCountLong = activityPlayerRepository.countByStageIdAndState(stage.getId(), 1); Integer currentCount = playerCountLong != null ? playerCountLong.intValue() : 0; PromotionCompetitionResponse response = new PromotionCompetitionResponse(competition, stage, currentCount); result.add(response); } } // 简单分页处理(实际项目中建议使用数据库分页) if (page != null && size != null && page > 0 && size > 0) { int start = (page - 1) * size; int end = Math.min(start + size, result.size()); if (start < result.size()) { result = result.subList(start, end); } else { result = new ArrayList<>(); } } return result; } /** * 获取比赛参赛人员 */ public List getCompetitionParticipants(Long competitionId, Integer page, Integer size) { // 查询指定阶段的所有参赛者(已审核通过的) List participants = activityPlayerRepository.findByStageIdAndStateWithPlayerOrderByCreateTimeDesc(competitionId, 1); // 转换为响应对象 List result = participants.stream() .map(participant -> { // 这里可以添加评分次数的统计逻辑 Integer ratingCount = 0; // TODO: 从评分表中统计 return new CompetitionParticipantResponse(participant, ratingCount); }) .collect(Collectors.toList()); // 简单分页处理 if (page != null && size != null && page > 0 && size > 0) { int start = (page - 1) * size; int end = Math.min(start + size, result.size()); if (start < result.size()) { result = result.subList(start, end); } else { result = new ArrayList<>(); } } return result; } /** * 获取可晋级的参赛者列表 */ public PromotableParticipantsResponse getPromotableParticipants(Long currentStageId) { try { // 查询当前阶段信息 Activity currentStage = activityRepository.findById(currentStageId).orElse(null); if (currentStage == null) { return new PromotableParticipantsResponse(new ArrayList<>(), 0, 0, "", ""); } // 查找上一个阶段 Activity previousStage = findPreviousStage(currentStage); if (previousStage == null) { return new PromotableParticipantsResponse(new ArrayList<>(), 0, 0, "", currentStage.getName()); } // 查询上一阶段的所有有效参赛者 List previousParticipants = activityPlayerRepository .findByStageIdAndStateWithPlayerOrderByCreateTimeDesc(previousStage.getId(), 1); // 查询当前阶段已有的参赛者ID列表 List currentParticipants = activityPlayerRepository .findByStageIdAndStateWithPlayerOrderByCreateTimeDesc(currentStageId, 1); List currentPlayerIds = currentParticipants.stream() .map(ActivityPlayer::getPlayerId) .collect(Collectors.toList()); // 过滤掉已经在当前阶段的参赛者,并计算平均分 List promotableList = new ArrayList<>(); for (ActivityPlayer participant : previousParticipants) { // 排除已经在当前阶段的参赛者 if (!currentPlayerIds.contains(participant.getPlayerId())) { // 计算平均分 BigDecimal averageScore = calculateAverageScore(participant.getId()); // 只包含有评分的参赛者 if (averageScore != null && averageScore.compareTo(BigDecimal.ZERO) > 0) { // 统计评分次数 long ratingCount = activityPlayerRatingRepository .countCompletedRatingsByActivityPlayerId(participant.getId()); PromotableParticipantResponse response = new PromotableParticipantResponse( participant, averageScore, (int) ratingCount); promotableList.add(response); } } } // 按平均分降序排序 promotableList.sort((a, b) -> { if (a.getAverageScore() == null && b.getAverageScore() == null) return 0; if (a.getAverageScore() == null) return 1; if (b.getAverageScore() == null) return -1; return b.getAverageScore().compareTo(a.getAverageScore()); }); // 计算可选择人数(当前阶段最大人数 - 当前阶段已有人数) Integer maxParticipants = currentStage.getPlayerMax() != null ? currentStage.getPlayerMax() : 0; Integer selectableCount = Math.max(0, maxParticipants - currentParticipants.size()); return new PromotableParticipantsResponse( promotableList, selectableCount, promotableList.size(), previousStage.getName(), currentStage.getName() ); } catch (Exception e) { return new PromotableParticipantsResponse(new ArrayList<>(), 0, 0, "", ""); } } /** * 计算参赛者的平均分 */ private BigDecimal calculateAverageScore(Long activityPlayerId) { List ratings = activityPlayerRatingRepository .findCompletedRatingsByActivityPlayerId(activityPlayerId); if (ratings.isEmpty()) { return null; } BigDecimal totalScore = BigDecimal.ZERO; int count = 0; for (ActivityPlayerRating rating : ratings) { if (rating.getTotalScore() != null) { totalScore = totalScore.add(rating.getTotalScore()); count++; } } if (count == 0) { return null; } return totalScore.divide(BigDecimal.valueOf(count), 2, RoundingMode.HALF_UP); } /** * 查找上一个阶段 */ private Activity findPreviousStage(Activity currentStage) { // 查询同一比赛下的所有阶段,按排序顺序 List stages = activityRepository.findByPidAndStateOrderBySortOrderAsc(currentStage.getPid(), 1); // 找到当前阶段的位置,返回上一个阶段 for (int i = 0; i < stages.size(); i++) { if (stages.get(i).getId().equals(currentStage.getId()) && i > 0) { return stages.get(i - 1); } } return null; // 没有上一个阶段 } /** * 执行晋级操作 */ @Transactional public PromotionResult promoteParticipants(PromotionInput input) { try { if (input.getParticipantIds() == null || input.getParticipantIds().isEmpty()) { return PromotionResult.failure("请选择要晋级的参赛者"); } // 查询目标晋级阶段信息(用户点击的阶段就是要晋级到的阶段) Activity targetStage = activityRepository.findById(input.getCompetitionId()).orElse(null); if (targetStage == null) { return PromotionResult.failure("目标晋级阶段不存在"); } // 查询要晋级的参赛者 List participants = activityPlayerRepository.findAllById(input.getParticipantIds()); if (participants.isEmpty()) { return PromotionResult.failure("没有找到要晋级的参赛者"); } int promotedCount = 0; // 为每个参赛者创建目标阶段的报名记录 for (ActivityPlayer participant : participants) { // 检查是否已经在目标阶段报名 boolean alreadyPromoted = activityPlayerRepository.existsByStageIdAndPlayerId(targetStage.getId(), participant.getPlayerId()); if (!alreadyPromoted) { // 创建新的报名记录 ActivityPlayer newParticipant = new ActivityPlayer(); newParticipant.setActivityId(targetStage.getPid()); // 主比赛ID newParticipant.setStageId(targetStage.getId()); // 目标阶段ID newParticipant.setPlayerId(participant.getPlayerId()); newParticipant.setRegionId(participant.getRegionId()); newParticipant.setProjectName(participant.getProjectName()); newParticipant.setDescription(participant.getDescription()); newParticipant.setState(1); // 直接设为审核通过 ActivityPlayer savedParticipant = activityPlayerRepository.save(newParticipant); // 复制媒体文件 copyMediaFiles(participant.getId(), savedParticipant.getId()); // 创建晋级消息 messageService.createPromotionMessage( savedParticipant.getId(), savedParticipant.getPlayerId(), savedParticipant.getProjectName() ); promotedCount++; } } return PromotionResult.success( String.format("成功晋级 %d 名参赛者到 %s", promotedCount, targetStage.getName()), promotedCount ); } catch (Exception e) { return PromotionResult.failure("晋级操作失败:" + e.getMessage()); } } /** * 复制媒体文件 */ private void copyMediaFiles(Long sourceActivityPlayerId, Long targetActivityPlayerId) { try { // 获取源参赛者的所有媒体文件 (targetType=5 表示 ACTIVITY_PLAYER) List sourceMediaFiles = mediaRepository.findByTargetTypeAndTargetIdAndState(5, sourceActivityPlayerId, 1); for (Media sourceMedia : sourceMediaFiles) { // 创建新的媒体记录 Media newMedia = new Media(); newMedia.setName(sourceMedia.getName()); newMedia.setPath(sourceMedia.getPath()); newMedia.setFileSize(sourceMedia.getFileSize()); newMedia.setFileExt(sourceMedia.getFileExt()); newMedia.setMediaType(sourceMedia.getMediaType()); newMedia.setTargetType(5); // ACTIVITY_PLAYER newMedia.setTargetId(targetActivityPlayerId); newMedia.setThumbPath(sourceMedia.getThumbPath()); newMedia.setDuration(sourceMedia.getDuration()); newMedia.setDescription(sourceMedia.getDescription()); // 保存新的媒体记录 mediaRepository.save(newMedia); } } catch (Exception e) { // 记录错误但不中断晋级流程 System.err.println("复制媒体文件失败: " + e.getMessage()); } } /** * 查找下一个阶段 */ }