1. 修复 updateAthleteTotalScore 方法,使用 getChiefJudgeIds() 排除裁判长的所有评分 2. 修复 getRequiredJudgeCount 方法,使用 distinct 去重统计普通裁判数量 3. 新增 scoringComplete、scoredJudgeCount、requiredJudgeCount 字段 4. 总分只在所有普通裁判评分完成后才显示 5. 总分算法:去掉最高最低分取平均,裁判数<3时直接取平均 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,13 +21,17 @@ import org.springblade.modules.martial.pojo.vo.MiniLoginVO;
|
|||||||
import org.springblade.modules.martial.pojo.vo.MiniScoreDetailVO;
|
import org.springblade.modules.martial.pojo.vo.MiniScoreDetailVO;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import org.springblade.modules.martial.service.*;
|
import org.springblade.modules.martial.service.*;
|
||||||
|
import org.springblade.modules.martial.pojo.entity.MtVenue;
|
||||||
|
import org.springblade.core.redis.cache.BladeRedis;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -46,9 +50,16 @@ public class MartialMiniController extends BladeController {
|
|||||||
private final IMartialJudgeService judgeService;
|
private final IMartialJudgeService judgeService;
|
||||||
private final IMartialCompetitionService competitionService;
|
private final IMartialCompetitionService competitionService;
|
||||||
private final IMartialVenueService venueService;
|
private final IMartialVenueService venueService;
|
||||||
|
private final IMtVenueService mtVenueService;
|
||||||
private final IMartialProjectService projectService;
|
private final IMartialProjectService projectService;
|
||||||
private final IMartialAthleteService athleteService;
|
private final IMartialAthleteService athleteService;
|
||||||
private final IMartialScoreService scoreService;
|
private final IMartialScoreService scoreService;
|
||||||
|
private final BladeRedis bladeRedis;
|
||||||
|
|
||||||
|
// Redis缓存key前缀
|
||||||
|
private static final String MINI_LOGIN_CACHE_PREFIX = "mini:login:";
|
||||||
|
// 登录缓存过期时间(7天)
|
||||||
|
private static final Duration LOGIN_CACHE_EXPIRE = Duration.ofDays(7);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录验证
|
* 登录验证
|
||||||
@@ -92,9 +103,10 @@ public class MartialMiniController extends BladeController {
|
|||||||
invite.setDeviceInfo(dto.getDeviceInfo());
|
invite.setDeviceInfo(dto.getDeviceInfo());
|
||||||
judgeInviteService.updateById(invite);
|
judgeInviteService.updateById(invite);
|
||||||
|
|
||||||
MartialVenue venue = null;
|
// 从 mt_venue 表获取场地信息
|
||||||
|
MtVenue mtVenue = null;
|
||||||
if (invite.getVenueId() != null) {
|
if (invite.getVenueId() != null) {
|
||||||
venue = venueService.getById(invite.getVenueId());
|
mtVenue = mtVenueService.getById(invite.getVenueId());
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MiniLoginVO.ProjectInfo> projects = parseProjects(invite.getProjects());
|
List<MiniLoginVO.ProjectInfo> projects = parseProjects(invite.getProjects());
|
||||||
@@ -108,10 +120,14 @@ public class MartialMiniController extends BladeController {
|
|||||||
competition.getCompetitionStartTime().toString() : "");
|
competition.getCompetitionStartTime().toString() : "");
|
||||||
vo.setJudgeId(judge.getId());
|
vo.setJudgeId(judge.getId());
|
||||||
vo.setJudgeName(judge.getName());
|
vo.setJudgeName(judge.getName());
|
||||||
vo.setVenueId(venue != null ? venue.getId() : null);
|
vo.setVenueId(mtVenue != null ? mtVenue.getId() : null);
|
||||||
vo.setVenueName(venue != null ? venue.getVenueName() : null);
|
vo.setVenueName(mtVenue != null ? mtVenue.getVenueName() : null);
|
||||||
vo.setProjects(projects);
|
vo.setProjects(projects);
|
||||||
|
|
||||||
|
// 将登录信息缓存到Redis(服务重启后仍然有效)
|
||||||
|
String cacheKey = MINI_LOGIN_CACHE_PREFIX + token;
|
||||||
|
bladeRedis.setEx(cacheKey, vo, LOGIN_CACHE_EXPIRE);
|
||||||
|
|
||||||
return R.data(vo);
|
return R.data(vo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,8 +174,9 @@ public class MartialMiniController extends BladeController {
|
|||||||
if (success) {
|
if (success) {
|
||||||
Long athleteId = parseLong(dto.getAthleteId());
|
Long athleteId = parseLong(dto.getAthleteId());
|
||||||
Long projectId = parseLong(dto.getProjectId());
|
Long projectId = parseLong(dto.getProjectId());
|
||||||
|
Long venueId = parseLong(dto.getVenueId());
|
||||||
if (athleteId != null && projectId != null) {
|
if (athleteId != null && projectId != null) {
|
||||||
updateAthleteTotalScore(athleteId, projectId);
|
updateAthleteTotalScore(athleteId, projectId, venueId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,33 +185,53 @@ public class MartialMiniController extends BladeController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算并更新选手总分
|
* 计算并更新选手总分
|
||||||
* 总分 = 所有裁判评分的平均值(保留3位小数)
|
* 总分算法:去掉一个最高分和一个最低分,取剩余分数的平均值
|
||||||
|
* 特殊情况:裁判数量<3时,直接取平均分
|
||||||
|
* 只有所有裁判都评分完成后才更新总分
|
||||||
*/
|
*/
|
||||||
private void updateAthleteTotalScore(Long athleteId, Long projectId) {
|
private void updateAthleteTotalScore(Long athleteId, Long projectId, Long venueId) {
|
||||||
try {
|
try {
|
||||||
// 查询该选手在该项目的所有评分
|
// 1. 查询该场地的普通裁判数量
|
||||||
|
int requiredJudgeCount = getRequiredJudgeCount(venueId);
|
||||||
|
|
||||||
|
// 2. 获取裁判长ID列表
|
||||||
|
List<Long> chiefJudgeIds = getChiefJudgeIds(venueId);
|
||||||
|
|
||||||
|
// 3. 查询该选手在该项目的所有评分(排除裁判长的评分)
|
||||||
LambdaQueryWrapper<MartialScore> scoreQuery = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<MartialScore> scoreQuery = new LambdaQueryWrapper<>();
|
||||||
scoreQuery.eq(MartialScore::getAthleteId, athleteId);
|
scoreQuery.eq(MartialScore::getAthleteId, athleteId);
|
||||||
scoreQuery.eq(MartialScore::getProjectId, projectId);
|
scoreQuery.eq(MartialScore::getProjectId, projectId);
|
||||||
scoreQuery.eq(MartialScore::getIsDeleted, 0);
|
scoreQuery.eq(MartialScore::getIsDeleted, 0);
|
||||||
|
// 排除裁判长的所有评分(包括普通评分和修改记录)
|
||||||
|
if (!chiefJudgeIds.isEmpty()) {
|
||||||
|
scoreQuery.notIn(MartialScore::getJudgeId, chiefJudgeIds);
|
||||||
|
}
|
||||||
List<MartialScore> scores = scoreService.list(scoreQuery);
|
List<MartialScore> scores = scoreService.list(scoreQuery);
|
||||||
|
|
||||||
if (scores != null && !scores.isEmpty()) {
|
// 4. 判断是否所有裁判都已评分
|
||||||
// 计算平均分
|
if (scores == null || scores.isEmpty()) {
|
||||||
BigDecimal totalScore = scores.stream()
|
return;
|
||||||
.map(MartialScore::getScore)
|
}
|
||||||
.filter(s -> s != null)
|
|
||||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
||||||
BigDecimal avgScore = totalScore.divide(
|
|
||||||
new BigDecimal(scores.size()),
|
|
||||||
3,
|
|
||||||
RoundingMode.HALF_UP
|
|
||||||
);
|
|
||||||
|
|
||||||
// 更新选手总分
|
// 如果配置了裁判数量,检查是否评分完成
|
||||||
|
if (requiredJudgeCount > 0 && scores.size() < requiredJudgeCount) {
|
||||||
|
// 未完成评分,清空总分
|
||||||
|
MartialAthlete athlete = athleteService.getById(athleteId);
|
||||||
|
if (athlete != null && athlete.getTotalScore() != null) {
|
||||||
|
athlete.setTotalScore(null);
|
||||||
|
athleteService.updateById(athlete);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 计算总分(去掉最高最低分取平均)
|
||||||
|
BigDecimal totalScore = calculateTotalScore(scores);
|
||||||
|
|
||||||
|
// 5. 更新选手总分
|
||||||
|
if (totalScore != null) {
|
||||||
MartialAthlete athlete = athleteService.getById(athleteId);
|
MartialAthlete athlete = athleteService.getById(athleteId);
|
||||||
if (athlete != null) {
|
if (athlete != null) {
|
||||||
athlete.setTotalScore(avgScore);
|
athlete.setTotalScore(totalScore);
|
||||||
athleteService.updateById(athlete);
|
athleteService.updateById(athlete);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,6 +241,65 @@ public class MartialMiniController extends BladeController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取场地应评分的裁判数量(普通裁判,不包括裁判长)
|
||||||
|
* 注意:使用 DISTINCT judge_id 来避免重复计数
|
||||||
|
*/
|
||||||
|
private int getRequiredJudgeCount(Long venueId) {
|
||||||
|
if (venueId == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
LambdaQueryWrapper<MartialJudgeInvite> judgeQuery = new LambdaQueryWrapper<>();
|
||||||
|
judgeQuery.eq(MartialJudgeInvite::getVenueId, venueId);
|
||||||
|
judgeQuery.eq(MartialJudgeInvite::getIsDeleted, 0);
|
||||||
|
judgeQuery.ne(MartialJudgeInvite::getRole, "chief_judge"); // 排除裁判长
|
||||||
|
List<MartialJudgeInvite> judges = judgeInviteService.list(judgeQuery);
|
||||||
|
// 使用 distinct judge_id 来计算不重复的裁判数量
|
||||||
|
return (int) judges.stream()
|
||||||
|
.map(MartialJudgeInvite::getJudgeId)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.distinct()
|
||||||
|
.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算总分
|
||||||
|
* 算法:去掉一个最高分和一个最低分,取剩余分数的平均值
|
||||||
|
* 特殊情况:裁判数量<3时,直接取平均分
|
||||||
|
*/
|
||||||
|
private BigDecimal calculateTotalScore(List<MartialScore> scores) {
|
||||||
|
if (scores == null || scores.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取所有分数并排序
|
||||||
|
List<BigDecimal> 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) {
|
||||||
|
// 裁判数量<3,直接取平均分
|
||||||
|
BigDecimal sum = scoreValues.stream()
|
||||||
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
|
return sum.divide(new BigDecimal(count), 3, RoundingMode.HALF_UP);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去掉最高分和最低分(已排序,去掉第一个和最后一个)
|
||||||
|
List<BigDecimal> 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);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 安全地将String转换为Long
|
* 安全地将String转换为Long
|
||||||
*/
|
*/
|
||||||
@@ -221,7 +317,7 @@ public class MartialMiniController extends BladeController {
|
|||||||
/**
|
/**
|
||||||
* 获取选手列表(支持分页)
|
* 获取选手列表(支持分页)
|
||||||
* - 普通裁判:获取所有选手,标记是否已评分
|
* - 普通裁判:获取所有选手,标记是否已评分
|
||||||
* - 裁判长:获取已有评分的选手列表
|
* - 裁判长:获取所有普通裁判都评分完成的选手列表
|
||||||
*/
|
*/
|
||||||
@GetMapping("/score/athletes")
|
@GetMapping("/score/athletes")
|
||||||
@Operation(summary = "获取选手列表", description = "根据裁判类型获取选手列表(支持分页)")
|
@Operation(summary = "获取选手列表", description = "根据裁判类型获取选手列表(支持分页)")
|
||||||
@@ -245,35 +341,56 @@ public class MartialMiniController extends BladeController {
|
|||||||
|
|
||||||
List<MartialAthlete> athletes = athleteService.list(athleteQuery);
|
List<MartialAthlete> athletes = athleteService.list(athleteQuery);
|
||||||
|
|
||||||
// 2. 获取所有评分记录
|
// 2. 获取该场地所有裁判长的judge_id列表
|
||||||
|
List<Long> chiefJudgeIds = getChiefJudgeIds(venueId);
|
||||||
|
|
||||||
|
// 3. 获取所有评分记录(排除裁判长的评分)
|
||||||
LambdaQueryWrapper<MartialScore> scoreQuery = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<MartialScore> scoreQuery = new LambdaQueryWrapper<>();
|
||||||
scoreQuery.eq(MartialScore::getIsDeleted, 0);
|
scoreQuery.eq(MartialScore::getIsDeleted, 0);
|
||||||
|
if (projectId != null) {
|
||||||
|
scoreQuery.eq(MartialScore::getProjectId, projectId);
|
||||||
|
}
|
||||||
|
// 排除裁判长的评分
|
||||||
|
if (!chiefJudgeIds.isEmpty()) {
|
||||||
|
scoreQuery.notIn(MartialScore::getJudgeId, chiefJudgeIds);
|
||||||
|
}
|
||||||
List<MartialScore> allScores = scoreService.list(scoreQuery);
|
List<MartialScore> allScores = scoreService.list(scoreQuery);
|
||||||
|
|
||||||
// 按选手ID分组统计评分
|
// 按选手ID分组统计评分
|
||||||
java.util.Map<Long, List<MartialScore>> scoresByAthlete = allScores.stream()
|
java.util.Map<Long, List<MartialScore>> scoresByAthlete = allScores.stream()
|
||||||
.collect(java.util.stream.Collectors.groupingBy(MartialScore::getAthleteId));
|
.collect(java.util.stream.Collectors.groupingBy(MartialScore::getAthleteId));
|
||||||
|
|
||||||
// 3. 根据裁判类型处理选手列表
|
// 4. 获取该场地的应评裁判数量
|
||||||
|
int requiredJudgeCount = getRequiredJudgeCount(venueId);
|
||||||
|
|
||||||
|
// 5. 根据裁判类型处理选手列表
|
||||||
List<org.springblade.modules.martial.pojo.vo.MiniAthleteListVO> filteredList;
|
List<org.springblade.modules.martial.pojo.vo.MiniAthleteListVO> filteredList;
|
||||||
|
|
||||||
if (refereeType == 1) {
|
if (refereeType == 1) {
|
||||||
// 裁判长:返回已有评分的选手
|
// 裁判长:返回所有普通裁判都评分完成的选手
|
||||||
|
final int finalRequiredCount = requiredJudgeCount;
|
||||||
|
|
||||||
|
// 只返回评分数量等于普通裁判数量的选手
|
||||||
filteredList = athletes.stream()
|
filteredList = athletes.stream()
|
||||||
.filter(athlete -> {
|
.filter(athlete -> {
|
||||||
List<MartialScore> scores = scoresByAthlete.get(athlete.getId());
|
List<MartialScore> scores = scoresByAthlete.get(athlete.getId());
|
||||||
return scores != null && !scores.isEmpty();
|
if (scores == null || scores.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 评分数量必须等于该场地的普通裁判数量
|
||||||
|
// 如果没有配置场地或裁判数量为0,则只要有评分就显示
|
||||||
|
return finalRequiredCount == 0 || scores.size() >= finalRequiredCount;
|
||||||
})
|
})
|
||||||
.map(athlete -> convertToAthleteListVO(athlete, scoresByAthlete.get(athlete.getId()), judgeId))
|
.map(athlete -> convertToAthleteListVO(athlete, scoresByAthlete.get(athlete.getId()), judgeId, requiredJudgeCount))
|
||||||
.collect(java.util.stream.Collectors.toList());
|
.collect(java.util.stream.Collectors.toList());
|
||||||
} else {
|
} else {
|
||||||
// 普通裁判:返回所有选手,标记是否已评分
|
// 普通裁判:返回所有选手,标记是否已评分
|
||||||
filteredList = athletes.stream()
|
filteredList = athletes.stream()
|
||||||
.map(athlete -> convertToAthleteListVO(athlete, scoresByAthlete.get(athlete.getId()), judgeId))
|
.map(athlete -> convertToAthleteListVO(athlete, scoresByAthlete.get(athlete.getId()), judgeId, requiredJudgeCount))
|
||||||
.collect(java.util.stream.Collectors.toList());
|
.collect(java.util.stream.Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 手动分页
|
// 6. 手动分页
|
||||||
int total = filteredList.size();
|
int total = filteredList.size();
|
||||||
int fromIndex = (current - 1) * size;
|
int fromIndex = (current - 1) * size;
|
||||||
int toIndex = Math.min(fromIndex + size, total);
|
int toIndex = Math.min(fromIndex + size, total);
|
||||||
@@ -285,13 +402,31 @@ public class MartialMiniController extends BladeController {
|
|||||||
pageRecords = filteredList.subList(fromIndex, toIndex);
|
pageRecords = filteredList.subList(fromIndex, toIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. 构建分页结果
|
// 7. 构建分页结果
|
||||||
IPage<org.springblade.modules.martial.pojo.vo.MiniAthleteListVO> page = new Page<>(current, size, total);
|
IPage<org.springblade.modules.martial.pojo.vo.MiniAthleteListVO> page = new Page<>(current, size, total);
|
||||||
page.setRecords(pageRecords);
|
page.setRecords(pageRecords);
|
||||||
|
|
||||||
return R.data(page);
|
return R.data(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取场地所有裁判长的judge_id列表
|
||||||
|
*/
|
||||||
|
private List<Long> getChiefJudgeIds(Long venueId) {
|
||||||
|
if (venueId == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
LambdaQueryWrapper<MartialJudgeInvite> judgeQuery = new LambdaQueryWrapper<>();
|
||||||
|
judgeQuery.eq(MartialJudgeInvite::getVenueId, venueId);
|
||||||
|
judgeQuery.eq(MartialJudgeInvite::getIsDeleted, 0);
|
||||||
|
judgeQuery.eq(MartialJudgeInvite::getRole, "chief_judge");
|
||||||
|
List<MartialJudgeInvite> chiefJudges = judgeInviteService.list(judgeQuery);
|
||||||
|
return chiefJudges.stream()
|
||||||
|
.map(MartialJudgeInvite::getJudgeId)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取评分详情
|
* 获取评分详情
|
||||||
*/
|
*/
|
||||||
@@ -317,26 +452,83 @@ public class MartialMiniController extends BladeController {
|
|||||||
*/
|
*/
|
||||||
@PostMapping("/logout")
|
@PostMapping("/logout")
|
||||||
@Operation(summary = "退出登录", description = "清除登录状态")
|
@Operation(summary = "退出登录", description = "清除登录状态")
|
||||||
public R logout() {
|
public R logout(@RequestHeader(value = "Authorization", required = false) String token) {
|
||||||
|
// 从Redis删除登录缓存
|
||||||
|
if (token != null && !token.isEmpty()) {
|
||||||
|
String cacheKey = MINI_LOGIN_CACHE_PREFIX + token;
|
||||||
|
bladeRedis.del(cacheKey);
|
||||||
|
}
|
||||||
return R.success("退出成功");
|
return R.success("退出成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Token验证
|
* Token验证(从Redis恢复登录状态)
|
||||||
*/
|
*/
|
||||||
@GetMapping("/verify")
|
@GetMapping("/verify")
|
||||||
@Operation(summary = "Token验证", description = "验证当前token是否有效")
|
@Operation(summary = "Token验证", description = "验证token并返回登录信息,支持服务重启后恢复登录状态")
|
||||||
public R verify() {
|
public R<MiniLoginVO> verify(@RequestHeader(value = "Authorization", required = false) String token) {
|
||||||
return R.success("Token有效");
|
if (token == null || token.isEmpty()) {
|
||||||
|
return R.fail("Token不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从Redis获取登录信息
|
||||||
|
String cacheKey = MINI_LOGIN_CACHE_PREFIX + token;
|
||||||
|
MiniLoginVO loginInfo = bladeRedis.get(cacheKey);
|
||||||
|
|
||||||
|
if (loginInfo != null) {
|
||||||
|
// 刷新缓存过期时间
|
||||||
|
bladeRedis.setEx(cacheKey, loginInfo, LOGIN_CACHE_EXPIRE);
|
||||||
|
return R.data(loginInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redis中没有,尝试从数据库恢复
|
||||||
|
LambdaQueryWrapper<MartialJudgeInvite> inviteQuery = new LambdaQueryWrapper<>();
|
||||||
|
inviteQuery.eq(MartialJudgeInvite::getAccessToken, token);
|
||||||
|
inviteQuery.eq(MartialJudgeInvite::getIsDeleted, 0);
|
||||||
|
MartialJudgeInvite invite = judgeInviteService.getOne(inviteQuery);
|
||||||
|
|
||||||
|
if (invite == null) {
|
||||||
|
return R.fail("Token无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invite.getTokenExpireTime() != null && invite.getTokenExpireTime().isBefore(LocalDateTime.now())) {
|
||||||
|
return R.fail("Token已过期");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重建登录信息
|
||||||
|
MartialCompetition competition = competitionService.getById(invite.getCompetitionId());
|
||||||
|
MartialJudge judge = judgeService.getById(invite.getJudgeId());
|
||||||
|
MtVenue mtVenue = invite.getVenueId() != null ? mtVenueService.getById(invite.getVenueId()) : null;
|
||||||
|
List<MiniLoginVO.ProjectInfo> projects = parseProjects(invite.getProjects());
|
||||||
|
|
||||||
|
MiniLoginVO vo = new MiniLoginVO();
|
||||||
|
vo.setToken(token);
|
||||||
|
vo.setUserRole("chief_judge".equals(invite.getRole()) ? "admin" : "pub");
|
||||||
|
vo.setMatchId(competition != null ? competition.getId() : null);
|
||||||
|
vo.setMatchName(competition != null ? competition.getCompetitionName() : null);
|
||||||
|
vo.setMatchTime(competition != null && competition.getCompetitionStartTime() != null ?
|
||||||
|
competition.getCompetitionStartTime().toString() : "");
|
||||||
|
vo.setJudgeId(judge != null ? judge.getId() : null);
|
||||||
|
vo.setJudgeName(judge != null ? judge.getName() : null);
|
||||||
|
vo.setVenueId(mtVenue != null ? mtVenue.getId() : null);
|
||||||
|
vo.setVenueName(mtVenue != null ? mtVenue.getVenueName() : null);
|
||||||
|
vo.setProjects(projects);
|
||||||
|
|
||||||
|
// 重新缓存到Redis
|
||||||
|
bladeRedis.setEx(cacheKey, vo, LOGIN_CACHE_EXPIRE);
|
||||||
|
|
||||||
|
return R.data(vo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换选手实体为VO
|
* 转换选手实体为VO
|
||||||
|
* 新增:只有评分完成时才显示总分
|
||||||
*/
|
*/
|
||||||
private org.springblade.modules.martial.pojo.vo.MiniAthleteListVO convertToAthleteListVO(
|
private org.springblade.modules.martial.pojo.vo.MiniAthleteListVO convertToAthleteListVO(
|
||||||
MartialAthlete athlete,
|
MartialAthlete athlete,
|
||||||
List<MartialScore> scores,
|
List<MartialScore> scores,
|
||||||
Long currentJudgeId) {
|
Long currentJudgeId,
|
||||||
|
int requiredJudgeCount) {
|
||||||
org.springblade.modules.martial.pojo.vo.MiniAthleteListVO vo = new org.springblade.modules.martial.pojo.vo.MiniAthleteListVO();
|
org.springblade.modules.martial.pojo.vo.MiniAthleteListVO vo = new org.springblade.modules.martial.pojo.vo.MiniAthleteListVO();
|
||||||
vo.setAthleteId(athlete.getId());
|
vo.setAthleteId(athlete.getId());
|
||||||
vo.setName(athlete.getPlayerName());
|
vo.setName(athlete.getPlayerName());
|
||||||
@@ -345,7 +537,9 @@ public class MartialMiniController extends BladeController {
|
|||||||
vo.setTeam(athlete.getTeamName());
|
vo.setTeam(athlete.getTeamName());
|
||||||
vo.setOrderNum(athlete.getOrderNum());
|
vo.setOrderNum(athlete.getOrderNum());
|
||||||
vo.setCompetitionStatus(athlete.getCompetitionStatus());
|
vo.setCompetitionStatus(athlete.getCompetitionStatus());
|
||||||
vo.setTotalScore(athlete.getTotalScore());
|
|
||||||
|
// 设置应评分裁判数量
|
||||||
|
vo.setRequiredJudgeCount(requiredJudgeCount);
|
||||||
|
|
||||||
// 设置项目名称
|
// 设置项目名称
|
||||||
if (athlete.getProjectId() != null) {
|
if (athlete.getProjectId() != null) {
|
||||||
@@ -356,8 +550,10 @@ public class MartialMiniController extends BladeController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 设置评分状态
|
// 设置评分状态
|
||||||
|
int scoredCount = 0;
|
||||||
if (scores != null && !scores.isEmpty()) {
|
if (scores != null && !scores.isEmpty()) {
|
||||||
vo.setScoredJudgeCount(scores.size());
|
scoredCount = scores.size();
|
||||||
|
vo.setScoredJudgeCount(scoredCount);
|
||||||
|
|
||||||
// 查找当前裁判的评分
|
// 查找当前裁判的评分
|
||||||
MartialScore myScore = scores.stream()
|
MartialScore myScore = scores.stream()
|
||||||
@@ -376,6 +572,23 @@ public class MartialMiniController extends BladeController {
|
|||||||
vo.setScoredJudgeCount(0);
|
vo.setScoredJudgeCount(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 判断评分是否完成(所有裁判都已评分)
|
||||||
|
boolean scoringComplete = false;
|
||||||
|
if (requiredJudgeCount > 0) {
|
||||||
|
scoringComplete = scoredCount >= requiredJudgeCount;
|
||||||
|
} else {
|
||||||
|
// 如果没有配置裁判数量,只要有评分就算完成
|
||||||
|
scoringComplete = scoredCount > 0;
|
||||||
|
}
|
||||||
|
vo.setScoringComplete(scoringComplete);
|
||||||
|
|
||||||
|
// 只有评分完成时才显示总分
|
||||||
|
if (scoringComplete) {
|
||||||
|
vo.setTotalScore(athlete.getTotalScore());
|
||||||
|
} else {
|
||||||
|
vo.setTotalScore(null);
|
||||||
|
}
|
||||||
|
|
||||||
return vo;
|
return vo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,14 +62,22 @@ public class MiniAthleteListVO implements Serializable {
|
|||||||
@JsonProperty("myScore")
|
@JsonProperty("myScore")
|
||||||
private BigDecimal myScore;
|
private BigDecimal myScore;
|
||||||
|
|
||||||
@Schema(description = "总分")
|
@Schema(description = "总分(只有所有裁判评分完成后才显示)")
|
||||||
@JsonProperty("totalScore")
|
@JsonProperty("totalScore")
|
||||||
private BigDecimal totalScore;
|
private BigDecimal totalScore;
|
||||||
|
|
||||||
@Schema(description = "已评分裁判数量(裁判长可见)")
|
@Schema(description = "已评分裁判数量")
|
||||||
@JsonProperty("scoredJudgeCount")
|
@JsonProperty("scoredJudgeCount")
|
||||||
private Integer scoredJudgeCount;
|
private Integer scoredJudgeCount;
|
||||||
|
|
||||||
|
@Schema(description = "应评分裁判总数")
|
||||||
|
@JsonProperty("requiredJudgeCount")
|
||||||
|
private Integer requiredJudgeCount;
|
||||||
|
|
||||||
|
@Schema(description = "评分是否完成(所有裁判都已评分)")
|
||||||
|
@JsonProperty("scoringComplete")
|
||||||
|
private Boolean scoringComplete = false;
|
||||||
|
|
||||||
@Schema(description = "比赛状态(0-待出场,1-进行中,2-已完成)")
|
@Schema(description = "比赛状态(0-待出场,1-进行中,2-已完成)")
|
||||||
@JsonProperty("competitionStatus")
|
@JsonProperty("competitionStatus")
|
||||||
private Integer competitionStatus;
|
private Integer competitionStatus;
|
||||||
|
|||||||
Reference in New Issue
Block a user