From 261f06168e27e8db8721fe3d7bdf13552784e136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=85=E6=88=BF?= Date: Sat, 24 Jan 2026 11:54:59 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=AE=9E=E7=8E=B0MiniScoringServiceImpl?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E6=80=BB=E5=88=86=E8=AE=A1=E7=AE=97=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 评分提交后自动计算选手总分: - 获取场地需要的裁判数量 - 排除主裁判评分 - 去掉最高最低分取平均(不足3人直接平均) Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> --- .../controller/MartialAthleteController.java | 4 +- .../martial/mapper/MartialAthleteMapper.java | 3 +- .../martial/mapper/MartialAthleteMapper.xml | 16 +-- .../service/IMartialAthleteService.java | 10 ++ .../impl/MartialAthleteServiceImpl.java | 7 +- .../service/impl/MiniScoringServiceImpl.java | 109 +++++++++++++++++- 6 files changed, 136 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/springblade/modules/martial/controller/MartialAthleteController.java b/src/main/java/org/springblade/modules/martial/controller/MartialAthleteController.java index 1b1dead..3157029 100644 --- a/src/main/java/org/springblade/modules/martial/controller/MartialAthleteController.java +++ b/src/main/java/org/springblade/modules/martial/controller/MartialAthleteController.java @@ -53,8 +53,8 @@ public class MartialAthleteController extends BladeController { */ @GetMapping("/list") @Operation(summary = "分页列表", description = "分页查询") - public R> list(MartialAthlete athlete, Query query) { - IPage pages = athleteService.selectAthleteVOPage(Condition.getPage(query), athlete); + public R> list(MartialAthlete athlete, Query query, @RequestParam(required = false, defaultValue = "false") Boolean includeTeamRecords) { + IPage pages = athleteService.selectAthleteVOPage(Condition.getPage(query), athlete, includeTeamRecords); return R.data(pages); } diff --git a/src/main/java/org/springblade/modules/martial/mapper/MartialAthleteMapper.java b/src/main/java/org/springblade/modules/martial/mapper/MartialAthleteMapper.java index 22eefc3..f63cfc6 100644 --- a/src/main/java/org/springblade/modules/martial/mapper/MartialAthleteMapper.java +++ b/src/main/java/org/springblade/modules/martial/mapper/MartialAthleteMapper.java @@ -18,9 +18,10 @@ public interface MartialAthleteMapper extends BaseMapper { * * @param page 分页对象 * @param athlete 查询条件 + * @param includeTeamRecords 是否包含集体项目的团队记录 * @return 参赛选手VO分页数据 */ - IPage selectAthleteVOPage(IPage page, @Param("athlete") MartialAthlete athlete); + IPage selectAthleteVOPage(IPage page, @Param("athlete") MartialAthlete athlete, @Param("includeTeamRecords") Boolean includeTeamRecords); /** * Count distinct participants by id_card for a competition diff --git a/src/main/java/org/springblade/modules/martial/mapper/MartialAthleteMapper.xml b/src/main/java/org/springblade/modules/martial/mapper/MartialAthleteMapper.xml index dd03f80..f03c1f5 100644 --- a/src/main/java/org/springblade/modules/martial/mapper/MartialAthleteMapper.xml +++ b/src/main/java/org/springblade/modules/martial/mapper/MartialAthleteMapper.xml @@ -12,13 +12,15 @@ LEFT JOIN martial_competition c ON a.competition_id = c.id AND c.is_deleted = 0 LEFT JOIN martial_project p ON a.project_id = p.id AND p.is_deleted = 0 WHERE a.is_deleted = 0 - - AND NOT ( - (a.id_card IS NULL OR a.id_card = '') - AND a.player_name = a.team_name - AND a.team_name IS NOT NULL - AND a.team_name != '' - ) + + + AND NOT ( + (a.id_card IS NULL OR a.id_card = '') + AND a.player_name = a.team_name + AND a.team_name IS NOT NULL + AND a.team_name != '' + ) + AND a.competition_id = #{athlete.competitionId} diff --git a/src/main/java/org/springblade/modules/martial/service/IMartialAthleteService.java b/src/main/java/org/springblade/modules/martial/service/IMartialAthleteService.java index 45e5c95..fd4b798 100644 --- a/src/main/java/org/springblade/modules/martial/service/IMartialAthleteService.java +++ b/src/main/java/org/springblade/modules/martial/service/IMartialAthleteService.java @@ -26,6 +26,16 @@ public interface IMartialAthleteService extends IService { */ IPage selectAthleteVOPage(IPage page, MartialAthlete athlete); + /** + * 分页查询参赛选手(包含关联字段) + * + * @param page 分页对象 + * @param athlete 查询条件 + * @param includeTeamRecords 是否包含集体项目的团队记录 + * @return 参赛选手VO分页数据 + */ + IPage selectAthleteVOPage(IPage page, MartialAthlete athlete, Boolean includeTeamRecords); + /** * Task 2.1: 运动员签到 */ diff --git a/src/main/java/org/springblade/modules/martial/service/impl/MartialAthleteServiceImpl.java b/src/main/java/org/springblade/modules/martial/service/impl/MartialAthleteServiceImpl.java index 3d287e2..543c558 100644 --- a/src/main/java/org/springblade/modules/martial/service/impl/MartialAthleteServiceImpl.java +++ b/src/main/java/org/springblade/modules/martial/service/impl/MartialAthleteServiceImpl.java @@ -61,7 +61,12 @@ public class MartialAthleteServiceImpl extends ServiceImpl selectAthleteVOPage(IPage page, MartialAthlete athlete) { - return baseMapper.selectAthleteVOPage(page, athlete); + return baseMapper.selectAthleteVOPage(page, athlete, false); + } + + @Override + public IPage selectAthleteVOPage(IPage page, MartialAthlete athlete, Boolean includeTeamRecords) { + return baseMapper.selectAthleteVOPage(page, athlete, includeTeamRecords); } /** diff --git a/src/main/java/org/springblade/modules/martial/service/impl/MiniScoringServiceImpl.java b/src/main/java/org/springblade/modules/martial/service/impl/MiniScoringServiceImpl.java index 4845042..70197d2 100644 --- a/src/main/java/org/springblade/modules/martial/service/impl/MiniScoringServiceImpl.java +++ b/src/main/java/org/springblade/modules/martial/service/impl/MiniScoringServiceImpl.java @@ -7,15 +7,21 @@ import org.springblade.core.tool.api.R; import org.springblade.modules.martial.pojo.dto.MiniScoreSubmitDTO; import org.springblade.modules.martial.pojo.entity.MartialAthlete; import org.springblade.modules.martial.pojo.entity.MartialJudge; +import org.springblade.modules.martial.pojo.entity.MartialJudgeInvite; import org.springblade.modules.martial.pojo.entity.MartialScore; import org.springblade.modules.martial.service.IMartialAthleteService; import org.springblade.modules.martial.service.IMartialJudgeService; +import org.springblade.modules.martial.service.IMartialJudgeInviteService; import org.springblade.modules.martial.service.IMartialScoreService; import org.springblade.modules.martial.service.IMiniScoringService; import org.springframework.stereotype.Service; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; @Slf4j @@ -26,6 +32,7 @@ public class MiniScoringServiceImpl implements IMiniScoringService { private final IMartialScoreService scoreService; private final IMartialJudgeService judgeService; private final IMartialAthleteService athleteService; + private final IMartialJudgeInviteService judgeInviteService; @Override public R submitScore(MiniScoreSubmitDTO dto) { @@ -72,8 +79,106 @@ public class MiniScoringServiceImpl implements IMiniScoringService { } private void updateAthleteTotalScore(Long athleteId, Long projectId, Long venueId) { - // TODO: Implement score calculation logic - // This will be extracted to a separate service in later refactoring + try { + int requiredJudgeCount = getRequiredJudgeCount(venueId); + List chiefJudgeIds = getChiefJudgeIds(venueId); + + LambdaQueryWrapper scoreQuery = new LambdaQueryWrapper<>(); + scoreQuery.eq(MartialScore::getAthleteId, athleteId); + scoreQuery.eq(MartialScore::getProjectId, projectId); + scoreQuery.eq(MartialScore::getIsDeleted, 0); + if (!chiefJudgeIds.isEmpty()) { + scoreQuery.notIn(MartialScore::getJudgeId, chiefJudgeIds); + } + List scores = scoreService.list(scoreQuery); + + if (scores == null || scores.isEmpty()) { + return; + } + + if (requiredJudgeCount > 0 && scores.size() < requiredJudgeCount) { + MartialAthlete athlete = athleteService.getById(athleteId); + if (athlete != null && athlete.getTotalScore() != null) { + athlete.setTotalScore(null); + athleteService.updateById(athlete); + } + return; + } + + BigDecimal totalScore = calculateTotalScore(scores); + + if (totalScore != null) { + MartialAthlete athlete = athleteService.getById(athleteId); + if (athlete != null) { + athlete.setTotalScore(totalScore); + athleteService.updateById(athlete); + } + } + } catch (Exception e) { + log.error("计算总分失败: athleteId={}, projectId={}", athleteId, projectId, e); + } + } + + private int getRequiredJudgeCount(Long venueId) { + if (venueId == null || venueId <= 0) { + return 0; + } + LambdaQueryWrapper judgeQuery = new LambdaQueryWrapper<>(); + judgeQuery.eq(MartialJudgeInvite::getIsDeleted, 0); + judgeQuery.eq(MartialJudgeInvite::getVenueId, venueId); + judgeQuery.eq(MartialJudgeInvite::getRefereeType, 2); + List judges = judgeInviteService.list(judgeQuery); + return (int) judges.stream() + .map(MartialJudgeInvite::getJudgeId) + .filter(Objects::nonNull) + .distinct() + .count(); + } + + private List getChiefJudgeIds(Long venueId) { + List chiefJudgeIds = new ArrayList<>(); + if (venueId == null) { + return chiefJudgeIds; + } + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(MartialJudgeInvite::getVenueId, venueId); + query.eq(MartialJudgeInvite::getRefereeType, 1); + query.eq(MartialJudgeInvite::getIsDeleted, 0); + List invites = judgeInviteService.list(query); + for (MartialJudgeInvite invite : invites) { + if (invite.getJudgeId() != null) { + chiefJudgeIds.add(invite.getJudgeId()); + } + } + return chiefJudgeIds; + } + + private BigDecimal calculateTotalScore(List scores) { + if (scores == null || scores.isEmpty()) { + return null; + } + + List scoreValues = scores.stream() + .map(MartialScore::getScore) + .filter(Objects::nonNull) + .sorted() + .collect(Collectors.toList()); + + int count = scoreValues.size(); + if (count == 0) { + return null; + } + + if (count < 3) { + BigDecimal sum = scoreValues.stream() + .reduce(BigDecimal.ZERO, BigDecimal::add); + return sum.divide(new BigDecimal(count), 3, RoundingMode.HALF_UP); + } + + List middleScores = scoreValues.subList(1, count - 1); + BigDecimal sum = middleScores.stream() + .reduce(BigDecimal.ZERO, BigDecimal::add); + return sum.divide(new BigDecimal(middleScores.size()), 3, RoundingMode.HALF_UP); } private Long parseLong(String str) {