From 4fa9591629721797386fc11836e3a9deb69cd58c Mon Sep 17 00:00:00 2001 From: lrj <owen.stl@gmail.com> Date: 星期三, 24 九月 2025 17:00:37 +0800 Subject: [PATCH] 修改评分逻辑,支持多个评委 --- backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerRatingService.java | 291 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 263 insertions(+), 28 deletions(-) diff --git a/backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerRatingService.java b/backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerRatingService.java index 80845c9..24ca43f 100644 --- a/backend/src/main/java/com/rongyichuang/player/service/ActivityPlayerRatingService.java +++ b/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("寮�濮嬩繚瀛樺璇勫璇勫垎锛宎ctivityPlayerId: {}", 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("褰撳墠璇勫鏃犳潈闄愯瘎鍒嗘娲诲姩"); + } + + // 鏌ヨ娲诲姩鐨勮瘎鍒嗘ā鏉縄D + 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); + } + + // 鏌ユ壘鎴栧垱寤篈ctivityPlayerRating璁板綍 + Optional<ActivityPlayerRating> existingRating = activityPlayerRatingRepository + .findByActivityPlayerIdAndJudgeId(activityPlayerId, currentJudgeId); + + ActivityPlayerRating rating; + if (existingRating.isPresent()) { + rating = existingRating.get(); + log.info("鎵惧埌宸叉湁璇勫垎璁板綍锛孖D: {}", rating.getId()); + // 鍒犻櫎宸叉湁鐨勮瘎鍒嗛」 + activityPlayerRatingItemRepository.deleteByActivityPlayerRatingId(rating.getId()); + } else { + // 鍒涘缓鏂扮殑璇勫垎璁板綍 + rating = new ActivityPlayerRating(activityId, activityPlayerId, playerId, currentJudgeId, ratingSchemeId); + rating = activityPlayerRatingRepository.save(rating); + log.info("鍒涘缓鏂扮殑璇勫垎璁板綍锛孖D: {}", 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("璇勫垎椤逛笉瀛樺湪锛宨temId: {}", 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("鏈壘鍒版椿鍔ㄩ�夋墜璁板綍锛宎ctivityPlayerId: " + 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() + ); + } } \ No newline at end of file -- Gitblit v1.8.0