lrj
4 天以前 4fa9591629721797386fc11836e3a9deb69cd58c
backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerRatingService.java
@@ -1,7 +1,19 @@
package com.rongyichuang.player.service;
import com.rongyichuang.activity.entity.ActivityPlayerRating;
import com.rongyichuang.activity.entity.ActivityPlayerRatingItem;
import com.rongyichuang.activity.repository.ActivityPlayerRatingRepository;
import com.rongyichuang.activity.repository.ActivityPlayerRatingItemRepository;
import com.rongyichuang.common.util.UserContextUtil;
import com.rongyichuang.judge.entity.Judge;
import com.rongyichuang.judge.repository.JudgeRepository;
import com.rongyichuang.player.dto.input.ActivityPlayerRatingInput;
import com.rongyichuang.player.dto.input.ActivityPlayerRatingItemInput;
import com.rongyichuang.player.dto.response.JudgeRatingStatusResponse;
import com.rongyichuang.player.dto.response.CurrentJudgeRatingResponse;
import com.rongyichuang.player.dto.response.CurrentJudgeInfoResponse;
import com.rongyichuang.rating.entity.RatingItem;
import com.rongyichuang.rating.repository.RatingItemRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -9,7 +21,11 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@Service
public class ActivityPlayerRatingService {
@@ -18,44 +34,263 @@
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private ActivityPlayerRatingRepository activityPlayerRatingRepository;
    @Autowired
    private ActivityPlayerRatingItemRepository activityPlayerRatingItemRepository;
    @Autowired
    private RatingItemRepository ratingItemRepository;
    @Autowired
    private JudgeRepository judgeRepository;
    @Autowired
    private UserContextUtil userContextUtil;
    @Transactional
    public boolean saveRating(ActivityPlayerRatingInput input) {
        try {
            log.info("开始保存评分,activityPlayerId: {}", input.getActivityPlayerId());
            log.info("开始保存多评委评分,activityPlayerId: {}", input.getActivityPlayerId());
            
            // 先删除已有的评分记录(如果存在)
            String deleteSql = "DELETE FROM t_activity_player_rating_item WHERE activity_player_id = ?";
            int deletedCount = jdbcTemplate.update(deleteSql, input.getActivityPlayerId());
            log.info("删除已有评分记录: {} 条", deletedCount);
            // 插入新的评分记录
            String insertSql = "INSERT INTO t_activity_player_rating_item " +
                    "(activity_player_id, rating_item_id, score, comment, create_time, update_time) " +
                    "VALUES (?, ?, ?, ?, ?, ?)";
            LocalDateTime now = LocalDateTime.now();
            int totalInserted = 0;
            for (ActivityPlayerRatingItemInput ratingItem : input.getRatings()) {
                int inserted = jdbcTemplate.update(insertSql,
                        input.getActivityPlayerId(),
                        ratingItem.getItemId(),
                        ratingItem.getScore(),
                        input.getComment(),
                        now,
                        now
                );
                totalInserted += inserted;
                log.info("保存评分项目: itemId={}, score={}", ratingItem.getItemId(), ratingItem.getScore());
            // 获取当前评委信息
            Long currentJudgeId = userContextUtil.getCurrentJudgeId();
            if (currentJudgeId == null) {
                throw new RuntimeException("当前用户不是评委,无法进行评分");
            }
            
            log.info("评分保存完成,共插入 {} 条记录", totalInserted);
            Long activityPlayerId = input.getActivityPlayerId();
            // 查询 activity_id, player_id
            String queryPlayerSql = "SELECT activity_id, player_id FROM t_activity_player WHERE id = ?";
            Map<String, Object> playerData = jdbcTemplate.queryForMap(queryPlayerSql, activityPlayerId);
            Long activityId = (Long) playerData.get("activity_id");
            Long playerId = (Long) playerData.get("player_id");
            log.info("查询到的数据 - activityId: {}, playerId: {}, judgeId: {}", activityId, playerId, currentJudgeId);
            // 验证评委是否有权限评分此活动
            if (!userContextUtil.isCurrentUserJudgeForActivity(activityId)) {
                throw new RuntimeException("当前评委无权限评分此活动");
            }
            // 查询活动的评分模板ID
            String queryActivitySql = "SELECT rating_scheme_id FROM t_activity WHERE id = ?";
            Long ratingSchemeId = jdbcTemplate.queryForObject(queryActivitySql, Long.class, activityId);
            log.info("查询到的ratingSchemeId: {}", ratingSchemeId);
            if (ratingSchemeId == null) {
                throw new RuntimeException("活动未配置评分模板,activityId: " + activityId);
            }
            // 查找或创建ActivityPlayerRating记录
            Optional<ActivityPlayerRating> existingRating = activityPlayerRatingRepository
                    .findByActivityPlayerIdAndJudgeId(activityPlayerId, currentJudgeId);
            ActivityPlayerRating rating;
            if (existingRating.isPresent()) {
                rating = existingRating.get();
                log.info("找到已有评分记录,ID: {}", rating.getId());
                // 删除已有的评分项
                activityPlayerRatingItemRepository.deleteByActivityPlayerRatingId(rating.getId());
            } else {
                // 创建新的评分记录
                rating = new ActivityPlayerRating(activityId, activityPlayerId, playerId, currentJudgeId, ratingSchemeId);
                rating = activityPlayerRatingRepository.save(rating);
                log.info("创建新的评分记录,ID: {}", rating.getId());
            }
            // 保存评分项
            BigDecimal totalScore = BigDecimal.ZERO;
            for (ActivityPlayerRatingItemInput ratingItemInput : input.getRatings()) {
                Long itemId = ratingItemInput.getItemId();
                BigDecimal score = BigDecimal.valueOf(ratingItemInput.getScore());
                // 查询评分项信息
                Optional<RatingItem> ratingItemOpt = ratingItemRepository.findById(itemId);
                if (ratingItemOpt.isEmpty()) {
                    log.warn("评分项不存在,itemId: {}", itemId);
                    continue;
                }
                RatingItem ratingItem = ratingItemOpt.get();
                // 创建评分项记录
                ActivityPlayerRatingItem ratingItemEntity = new ActivityPlayerRatingItem(
                        rating.getId(),
                        itemId,
                        ratingItem.getName(),
                        BigDecimal.ONE, // 默认权重为1
                        BigDecimal.valueOf(ratingItem.getMaxScore()),
                        score
                );
                ratingItemEntity.setRemark(input.getComment());
                activityPlayerRatingItemRepository.save(ratingItemEntity);
                // 累加加权得分
                if (ratingItemEntity.getWeightedScore() != null) {
                    totalScore = totalScore.add(ratingItemEntity.getWeightedScore());
                }
                log.info("保存评分项目: itemId={}, score={}, weightedScore={}",
                        itemId, score, ratingItemEntity.getWeightedScore());
            }
            // 更新总分和状态
            rating.setTotalScore(totalScore);
            rating.setStatus(1); // 已评分
            rating.setRemark(input.getComment());
            activityPlayerRatingRepository.save(rating);
            log.info("评分保存完成,总分: {}", totalScore);
            return true;
            
        } catch (Exception e) {
            log.error("保存评分失败", e);
            throw new RuntimeException("保存评分失败: " + e.getMessage());
            log.error("保存评分失败,异常类型: {}, 异常信息: {}", e.getClass().getSimpleName(), e.getMessage(), e);
            e.printStackTrace();
            throw new RuntimeException("保存评分失败: " + e.getClass().getSimpleName() + " - " + e.getMessage(), e);
        }
    }
    /**
     * 获取指定活动选手的所有评委评分
     */
    public List<ActivityPlayerRating> getAllRatingsForPlayer(Long activityPlayerId) {
        return activityPlayerRatingRepository.findByActivityPlayerId(activityPlayerId);
    }
    /**
     * 获取指定活动选手的平均分
     */
    public BigDecimal getAverageScoreForPlayer(Long activityPlayerId) {
        List<ActivityPlayerRating> ratings = activityPlayerRatingRepository
                .findCompletedRatingsByActivityPlayerId(activityPlayerId);
        if (ratings.isEmpty()) {
            return BigDecimal.ZERO;
        }
        BigDecimal totalScore = ratings.stream()
                .map(ActivityPlayerRating::getTotalScore)
                .filter(score -> score != null)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        return totalScore.divide(BigDecimal.valueOf(ratings.size()), 2, BigDecimal.ROUND_HALF_UP);
    }
    /**
     * 获取当前评委对指定选手的评分
     */
    public CurrentJudgeRatingResponse getCurrentJudgeRating(Long activityPlayerId) {
        Long currentJudgeId = userContextUtil.getCurrentJudgeId();
        if (currentJudgeId == null) {
            return null;
        }
        Optional<ActivityPlayerRating> ratingOpt = activityPlayerRatingRepository
                .findByActivityPlayerIdAndJudgeId(activityPlayerId, currentJudgeId);
        if (!ratingOpt.isPresent()) {
            return null;
        }
        ActivityPlayerRating rating = ratingOpt.get();
        CurrentJudgeRatingResponse response = new CurrentJudgeRatingResponse();
        response.setId(rating.getId());
        response.setTotalScore(rating.getTotalScore());
        response.setStatus(rating.getStatus());
        response.setRemark(rating.getRemark());
        // 获取评分项
        List<ActivityPlayerRatingItem> items = activityPlayerRatingItemRepository
                .findByActivityPlayerRatingId(rating.getId());
        List<CurrentJudgeRatingResponse.CurrentJudgeRatingItemResponse> itemResponses = items.stream()
                .map(item -> new CurrentJudgeRatingResponse.CurrentJudgeRatingItemResponse(
                        item.getRatingItemId(),
                        item.getRatingItemName(),
                        item.getScore(),
                        item.getWeightedScore()
                ))
                .collect(java.util.stream.Collectors.toList());
        response.setItems(itemResponses);
        return response;
    }
    /**
     * 检查当前评委是否已对指定选手评分
     */
    public boolean hasCurrentJudgeRated(Long activityPlayerId) {
        Long currentJudgeId = userContextUtil.getCurrentJudgeId();
        if (currentJudgeId == null) {
            return false;
        }
        return activityPlayerRatingRepository.existsByActivityPlayerIdAndJudgeId(activityPlayerId, currentJudgeId);
    }
    /**
     * 获取指定选手的所有评委评分状态
     */
    public List<JudgeRatingStatusResponse> getAllJudgeRatingsForPlayer(Long activityPlayerId) {
        // 首先获取活动ID
        String activitySql = "SELECT activity_id FROM t_activity_player WHERE id = ?";
        Long activityId = jdbcTemplate.queryForObject(activitySql, Long.class, activityPlayerId);
        if (activityId == null) {
            throw new RuntimeException("未找到活动选手记录,activityPlayerId: " + activityPlayerId);
        }
        // 获取活动的所有评委
        String judgesSql = "SELECT j.id, j.name FROM t_judge j " +
                          "JOIN t_activity_judge aj ON j.id = aj.judge_id " +
                          "WHERE aj.activity_id = ? ORDER BY j.name";
        List<Map<String, Object>> judgeRows = jdbcTemplate.queryForList(judgesSql, activityId);
        Long currentJudgeId = userContextUtil.getCurrentJudgeId();
        return judgeRows.stream().map(row -> {
            Long judgeId = ((Number) row.get("id")).longValue();
            String judgeName = (String) row.get("name");
            // 查找该评委的评分
            Optional<ActivityPlayerRating> ratingOpt = activityPlayerRatingRepository
                    .findByActivityPlayerIdAndJudgeId(activityPlayerId, judgeId);
            BigDecimal totalScore = null;
            Integer status = 0;
            if (ratingOpt.isPresent()) {
                ActivityPlayerRating rating = ratingOpt.get();
                totalScore = rating.getTotalScore();
                status = rating.getStatus();
            }
            Boolean isCurrentJudge = judgeId.equals(currentJudgeId);
            return new JudgeRatingStatusResponse(judgeId, judgeName, totalScore, status, isCurrentJudge);
        }).collect(java.util.stream.Collectors.toList());
    }
    /**
     * 获取当前评委信息
     */
    public CurrentJudgeInfoResponse getCurrentJudgeInfo() {
        Optional<Judge> currentJudgeOpt = userContextUtil.getCurrentJudge();
        if (!currentJudgeOpt.isPresent()) {
            return null;
        }
        Judge currentJudge = currentJudgeOpt.get();
        return new CurrentJudgeInfoResponse(
                currentJudge.getId(),
                currentJudge.getName(),
                currentJudge.getPhone(),
                currentJudge.getDescription()
        );
    }
}