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<PromotionCompetitionResponse> getPromotionCompetitions(String name, Integer page, Integer size) {
|
List<PromotionCompetitionResponse> result = new ArrayList<>();
|
|
// 查询所有有效的主比赛(pid = 0)
|
List<Activity> 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<Activity> 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<CompetitionParticipantResponse> getCompetitionParticipants(Long competitionId, Integer page, Integer size) {
|
// 查询指定阶段的所有参赛者(已审核通过的)
|
List<ActivityPlayer> participants = activityPlayerRepository.findByStageIdAndStateWithPlayerOrderByCreateTimeDesc(competitionId, 1);
|
|
// 转换为响应对象
|
List<CompetitionParticipantResponse> 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<ActivityPlayer> previousParticipants = activityPlayerRepository
|
.findByStageIdAndStateWithPlayerOrderByCreateTimeDesc(previousStage.getId(), 1);
|
|
// 查询当前阶段已有的参赛者ID列表
|
List<ActivityPlayer> currentParticipants = activityPlayerRepository
|
.findByStageIdAndStateWithPlayerOrderByCreateTimeDesc(currentStageId, 1);
|
List<Long> currentPlayerIds = currentParticipants.stream()
|
.map(ActivityPlayer::getPlayerId)
|
.collect(Collectors.toList());
|
|
// 过滤掉已经在当前阶段的参赛者,并计算平均分
|
List<PromotableParticipantResponse> 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<ActivityPlayerRating> 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<Activity> 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<ActivityPlayer> 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<Media> 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());
|
}
|
}
|
|
/**
|
* 查找下一个阶段
|
*/
|
|
}
|