feat: 添加三级裁判评分系统(裁判员→主裁判→总裁)
- 新增总裁(裁判长)角色支持,referee_type=3 - MartialResult实体添加主裁判/总裁确认字段和score_status状态 - MartialJudgeInvite实体添加角色常量和判断方法 - MartialMiniController添加三级确认API和登录角色判断 - MartialResultServiceImpl实现三级确认业务逻辑 - MartialScoreServiceImpl主裁判确认时同步martial_result表 Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
@@ -21,8 +21,11 @@ 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.dto.ChiefJudgeConfirmDTO;
|
||||||
|
import org.springblade.modules.martial.pojo.dto.GeneralJudgeConfirmDTO;
|
||||||
import org.springblade.modules.martial.pojo.entity.MtVenue;
|
import org.springblade.modules.martial.pojo.entity.MtVenue;
|
||||||
import org.springblade.modules.martial.pojo.entity.MartialVenue;
|
import org.springblade.modules.martial.pojo.entity.MartialVenue;
|
||||||
|
import org.springblade.modules.martial.pojo.entity.MartialResult;
|
||||||
import org.springblade.core.redis.cache.BladeRedis;
|
import org.springblade.core.redis.cache.BladeRedis;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@@ -56,6 +59,7 @@ public class MartialMiniController extends BladeController {
|
|||||||
private final IMartialAthleteService athleteService;
|
private final IMartialAthleteService athleteService;
|
||||||
private final IMartialScoreService scoreService;
|
private final IMartialScoreService scoreService;
|
||||||
private final BladeRedis bladeRedis;
|
private final BladeRedis bladeRedis;
|
||||||
|
private final IMartialResultService resultService;
|
||||||
|
|
||||||
// Redis缓存key前缀
|
// Redis缓存key前缀
|
||||||
private static final String MINI_LOGIN_CACHE_PREFIX = "mini:login:";
|
private static final String MINI_LOGIN_CACHE_PREFIX = "mini:login:";
|
||||||
@@ -121,7 +125,15 @@ public class MartialMiniController extends BladeController {
|
|||||||
|
|
||||||
MiniLoginVO vo = new MiniLoginVO();
|
MiniLoginVO vo = new MiniLoginVO();
|
||||||
vo.setToken(token);
|
vo.setToken(token);
|
||||||
vo.setUserRole("chief_judge".equals(invite.getRole()) ? "admin" : "pub");
|
String role = invite.getRole();
|
||||||
|
Integer refereeType = invite.getRefereeType();
|
||||||
|
if ("general_judge".equals(role) || (refereeType != null && refereeType == 3)) {
|
||||||
|
vo.setUserRole("general");
|
||||||
|
} else if ("chief_judge".equals(role) || (refereeType != null && refereeType == 2)) {
|
||||||
|
vo.setUserRole("admin");
|
||||||
|
} else {
|
||||||
|
vo.setUserRole("pub");
|
||||||
|
}
|
||||||
vo.setMatchId(competition.getId());
|
vo.setMatchId(competition.getId());
|
||||||
vo.setMatchName(competition.getCompetitionName());
|
vo.setMatchName(competition.getCompetitionName());
|
||||||
vo.setMatchTime(competition.getCompetitionStartTime() != null ?
|
vo.setMatchTime(competition.getCompetitionStartTime() != null ?
|
||||||
@@ -517,7 +529,15 @@ public class MartialMiniController extends BladeController {
|
|||||||
|
|
||||||
MiniLoginVO vo = new MiniLoginVO();
|
MiniLoginVO vo = new MiniLoginVO();
|
||||||
vo.setToken(token);
|
vo.setToken(token);
|
||||||
vo.setUserRole("chief_judge".equals(invite.getRole()) ? "admin" : "pub");
|
String role = invite.getRole();
|
||||||
|
Integer refereeType = invite.getRefereeType();
|
||||||
|
if ("general_judge".equals(role) || (refereeType != null && refereeType == 3)) {
|
||||||
|
vo.setUserRole("general");
|
||||||
|
} else if ("chief_judge".equals(role) || (refereeType != null && refereeType == 2)) {
|
||||||
|
vo.setUserRole("admin");
|
||||||
|
} else {
|
||||||
|
vo.setUserRole("pub");
|
||||||
|
}
|
||||||
vo.setMatchId(competition != null ? competition.getId() : null);
|
vo.setMatchId(competition != null ? competition.getId() : null);
|
||||||
vo.setMatchName(competition != null ? competition.getCompetitionName() : null);
|
vo.setMatchName(competition != null ? competition.getCompetitionName() : null);
|
||||||
vo.setMatchTime(competition != null && competition.getCompetitionStartTime() != null ?
|
vo.setMatchTime(competition != null && competition.getCompetitionStartTime() != null ?
|
||||||
@@ -679,4 +699,71 @@ public class MartialMiniController extends BladeController {
|
|||||||
return projects;
|
return projects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ========== 三级裁判评分流程 API ==========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主裁判确认/修改分数
|
||||||
|
*/
|
||||||
|
@PostMapping("/chief/confirm")
|
||||||
|
@Operation(summary = "主裁判确认分数", description = "主裁判确认或修改选手分数")
|
||||||
|
public R confirmByChiefJudge(@RequestBody ChiefJudgeConfirmDTO dto) {
|
||||||
|
Long resultId = parseLong(dto.getResultId());
|
||||||
|
Long chiefJudgeId = parseLong(dto.getChiefJudgeId());
|
||||||
|
if (resultId == null || chiefJudgeId == null) {
|
||||||
|
return R.fail("参数错误");
|
||||||
|
}
|
||||||
|
boolean success = resultService.confirmByChiefJudge(resultId, chiefJudgeId, dto.getScore(), dto.getNote());
|
||||||
|
return success ? R.success("确认成功") : R.fail("确认失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总裁确认/修改分数
|
||||||
|
*/
|
||||||
|
@PostMapping("/general/confirm")
|
||||||
|
@Operation(summary = "总裁确认分数", description = "总裁确认或修改选手分数")
|
||||||
|
public R confirmByGeneralJudge(@RequestBody GeneralJudgeConfirmDTO dto) {
|
||||||
|
Long resultId = parseLong(dto.getResultId());
|
||||||
|
Long generalJudgeId = parseLong(dto.getGeneralJudgeId());
|
||||||
|
if (resultId == null || generalJudgeId == null) {
|
||||||
|
return R.fail("参数错误");
|
||||||
|
}
|
||||||
|
boolean success = resultService.confirmByGeneralJudge(resultId, generalJudgeId, dto.getScore(), dto.getNote());
|
||||||
|
return success ? R.success("确认成功") : R.fail("确认失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取待主裁判确认的成绩列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/chief/pending")
|
||||||
|
@Operation(summary = "待主裁判确认列表", description = "获取待主裁判确认的成绩列表")
|
||||||
|
public R<List<MartialResult>> getPendingChiefConfirmList(@RequestParam Long venueId) {
|
||||||
|
List<MartialResult> list = resultService.getPendingChiefConfirmList(venueId);
|
||||||
|
return R.data(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取待总裁确认的成绩列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/general/pending")
|
||||||
|
@Operation(summary = "待总裁确认列表", description = "获取待总裁确认的成绩列表(所有场地)")
|
||||||
|
public R<List<MartialResult>> getPendingGeneralConfirmList(@RequestParam Long competitionId) {
|
||||||
|
List<MartialResult> list = resultService.getPendingGeneralConfirmList(competitionId);
|
||||||
|
return R.data(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有场地列表(总裁用)
|
||||||
|
*/
|
||||||
|
@GetMapping("/general/venues")
|
||||||
|
@Operation(summary = "获取所有场地", description = "总裁获取比赛的所有场地列表")
|
||||||
|
public R<List<MartialVenue>> getAllVenues(@RequestParam Long competitionId) {
|
||||||
|
LambdaQueryWrapper<MartialVenue> wrapper = new LambdaQueryWrapper<>();
|
||||||
|
wrapper.eq(MartialVenue::getCompetitionId, competitionId);
|
||||||
|
wrapper.eq(MartialVenue::getIsDeleted, 0);
|
||||||
|
wrapper.orderByAsc(MartialVenue::getVenueName);
|
||||||
|
List<MartialVenue> venues = venueService.list(wrapper);
|
||||||
|
return R.data(venues);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package org.springblade.modules.martial.pojo.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主裁判确认评分DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "主裁判确认评分DTO")
|
||||||
|
public class ChiefJudgeConfirmDTO {
|
||||||
|
|
||||||
|
@Schema(description = "成绩ID")
|
||||||
|
private String resultId;
|
||||||
|
|
||||||
|
@Schema(description = "主裁判ID")
|
||||||
|
private String chiefJudgeId;
|
||||||
|
|
||||||
|
@Schema(description = "确认/修改后的分数(null表示直接确认原分数)")
|
||||||
|
private BigDecimal score;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
private String note;
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package org.springblade.modules.martial.pojo.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总裁确认评分DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Schema(description = "总裁确认评分DTO")
|
||||||
|
public class GeneralJudgeConfirmDTO {
|
||||||
|
|
||||||
|
@Schema(description = "成绩ID")
|
||||||
|
private String resultId;
|
||||||
|
|
||||||
|
@Schema(description = "总裁ID")
|
||||||
|
private String generalJudgeId;
|
||||||
|
|
||||||
|
@Schema(description = "确认/修改后的分数(null表示直接确认原分数)")
|
||||||
|
private BigDecimal score;
|
||||||
|
|
||||||
|
@Schema(description = "备注")
|
||||||
|
private String note;
|
||||||
|
}
|
||||||
@@ -37,6 +37,14 @@ public class MartialJudgeInvite extends TenantEntity {
|
|||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// ========== 角色常量 ==========
|
||||||
|
/** 裁判员 */
|
||||||
|
public static final String ROLE_JUDGE = "judge";
|
||||||
|
/** 主裁判 */
|
||||||
|
public static final String ROLE_CHIEF_JUDGE = "chief_judge";
|
||||||
|
/** 总裁(裁判长) */
|
||||||
|
public static final String ROLE_GENERAL_JUDGE = "general_judge";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 赛事ID
|
* 赛事ID
|
||||||
*/
|
*/
|
||||||
@@ -56,13 +64,13 @@ public class MartialJudgeInvite extends TenantEntity {
|
|||||||
private String inviteCode;
|
private String inviteCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色(judge-裁判员,chief_judge-主裁判)
|
* 角色(judge-裁判员, chief_judge-主裁判, general_judge-总裁)
|
||||||
*/
|
*/
|
||||||
@Schema(description = "角色")
|
@Schema(description = "角色")
|
||||||
private String role;
|
private String role;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分配场地ID
|
* 分配场地ID (总裁时为null,表示负责所有场地)
|
||||||
*/
|
*/
|
||||||
@Schema(description = "分配场地ID")
|
@Schema(description = "分配场地ID")
|
||||||
private Long venueId;
|
private Long venueId;
|
||||||
@@ -169,4 +177,25 @@ public class MartialJudgeInvite extends TenantEntity {
|
|||||||
@Schema(description = "裁判类型")
|
@Schema(description = "裁判类型")
|
||||||
private Integer refereeType;
|
private Integer refereeType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为裁判员
|
||||||
|
*/
|
||||||
|
public boolean isJudge() {
|
||||||
|
return ROLE_JUDGE.equals(this.role);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为主裁判
|
||||||
|
*/
|
||||||
|
public boolean isChiefJudge() {
|
||||||
|
return ROLE_CHIEF_JUDGE.equals(this.role);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为总裁
|
||||||
|
*/
|
||||||
|
public boolean isGeneralJudge() {
|
||||||
|
return ROLE_GENERAL_JUDGE.equals(this.role);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,14 @@ public class MartialResult extends TenantEntity {
|
|||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
// ========== 评分状态常量 ==========
|
||||||
|
/** 评分状态:裁判员评分中 */
|
||||||
|
public static final int SCORE_STATUS_JUDGING = 0;
|
||||||
|
/** 评分状态:主裁判已确认 */
|
||||||
|
public static final int SCORE_STATUS_CHIEF_CONFIRMED = 1;
|
||||||
|
/** 评分状态:总裁已确认 */
|
||||||
|
public static final int SCORE_STATUS_GENERAL_CONFIRMED = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 赛事ID
|
* 赛事ID
|
||||||
*/
|
*/
|
||||||
@@ -158,4 +166,62 @@ public class MartialResult extends TenantEntity {
|
|||||||
@Schema(description = "发布时间")
|
@Schema(description = "发布时间")
|
||||||
private LocalDateTime publishTime;
|
private LocalDateTime publishTime;
|
||||||
|
|
||||||
|
// ========== 主裁判确认相关字段 ==========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主裁判确认/修改后的分数
|
||||||
|
*/
|
||||||
|
@Schema(description = "主裁判确认/修改后的分数")
|
||||||
|
private BigDecimal chiefJudgeScore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主裁判ID
|
||||||
|
*/
|
||||||
|
@Schema(description = "主裁判ID")
|
||||||
|
private Long chiefJudgeId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主裁判确认时间
|
||||||
|
*/
|
||||||
|
@Schema(description = "主裁判确认时间")
|
||||||
|
private LocalDateTime chiefJudgeTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主裁判备注
|
||||||
|
*/
|
||||||
|
@Schema(description = "主裁判备注")
|
||||||
|
private String chiefJudgeNote;
|
||||||
|
|
||||||
|
// ========== 总裁确认相关字段 ==========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总裁确认/修改后的分数
|
||||||
|
*/
|
||||||
|
@Schema(description = "总裁确认/修改后的分数")
|
||||||
|
private BigDecimal generalJudgeScore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总裁ID
|
||||||
|
*/
|
||||||
|
@Schema(description = "总裁ID")
|
||||||
|
private Long generalJudgeId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总裁确认时间
|
||||||
|
*/
|
||||||
|
@Schema(description = "总裁确认时间")
|
||||||
|
private LocalDateTime generalJudgeTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总裁备注
|
||||||
|
*/
|
||||||
|
@Schema(description = "总裁备注")
|
||||||
|
private String generalJudgeNote;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 评分状态: 0-裁判员评分中, 1-主裁判已确认, 2-总裁已确认
|
||||||
|
*/
|
||||||
|
@Schema(description = "评分状态: 0-裁判员评分中, 1-主裁判已确认, 2-总裁已确认")
|
||||||
|
private Integer scoreStatus;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,4 +70,27 @@ public interface IMartialResultService extends IService<MartialResult> {
|
|||||||
*/
|
*/
|
||||||
List<CertificateVO> batchGenerateCertificates(Long projectId);
|
List<CertificateVO> batchGenerateCertificates(Long projectId);
|
||||||
|
|
||||||
|
|
||||||
|
// ========== 三级裁判评分流程方法 ==========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主裁判确认/修改分数
|
||||||
|
*/
|
||||||
|
boolean confirmByChiefJudge(Long resultId, Long chiefJudgeId, BigDecimal score, String note);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总裁确认/修改分数
|
||||||
|
*/
|
||||||
|
boolean confirmByGeneralJudge(Long resultId, Long generalJudgeId, BigDecimal score, String note);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取待主裁判确认的成绩列表
|
||||||
|
*/
|
||||||
|
List<MartialResult> getPendingChiefConfirmList(Long venueId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取待总裁确认的成绩列表
|
||||||
|
*/
|
||||||
|
List<MartialResult> getPendingGeneralConfirmList(Long competitionId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -559,4 +559,158 @@ public class MartialResultServiceImpl extends ServiceImpl<MartialResultMapper, M
|
|||||||
return certificates;
|
return certificates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ========== 三级裁判评分流程方法 ==========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主裁判确认/修改分数
|
||||||
|
*
|
||||||
|
* @param resultId 成绩ID
|
||||||
|
* @param chiefJudgeId 主裁判ID
|
||||||
|
* @param score 确认/修改后的分数(null表示直接确认原分数)
|
||||||
|
* @param note 备注
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public boolean confirmByChiefJudge(Long resultId, Long chiefJudgeId, BigDecimal score, String note) {
|
||||||
|
MartialResult result = this.getById(resultId);
|
||||||
|
if (result == null) {
|
||||||
|
throw new ServiceException("成绩记录不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查状态:只有裁判员评分完成后才能确认
|
||||||
|
if (result.getScoreStatus() != null && result.getScoreStatus() >= MartialResult.SCORE_STATUS_CHIEF_CONFIRMED) {
|
||||||
|
throw new ServiceException("该成绩已被主裁判确认,无法重复操作");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确定最终分数
|
||||||
|
BigDecimal finalScore = score != null ? score : result.getTotalScore();
|
||||||
|
|
||||||
|
// 验证分数范围(如果有修改)
|
||||||
|
if (score != null && result.getTotalScore() != null) {
|
||||||
|
BigDecimal minAllowed = result.getTotalScore().subtract(new BigDecimal("0.050"));
|
||||||
|
BigDecimal maxAllowed = result.getTotalScore().add(new BigDecimal("0.050"));
|
||||||
|
if (score.compareTo(minAllowed) < 0 || score.compareTo(maxAllowed) > 0) {
|
||||||
|
throw new ServiceException("修改分数只能在原始总分±0.050范围内");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新主裁判确认信息
|
||||||
|
result.setChiefJudgeScore(finalScore);
|
||||||
|
result.setChiefJudgeId(chiefJudgeId);
|
||||||
|
result.setChiefJudgeTime(LocalDateTime.now());
|
||||||
|
result.setChiefJudgeNote(note);
|
||||||
|
result.setScoreStatus(MartialResult.SCORE_STATUS_CHIEF_CONFIRMED);
|
||||||
|
|
||||||
|
// 更新最终得分
|
||||||
|
result.setFinalScore(finalScore);
|
||||||
|
|
||||||
|
boolean success = this.updateById(result);
|
||||||
|
|
||||||
|
log.info("主裁判确认成绩 - 成绩ID:{}, 主裁判ID:{}, 原分数:{}, 确认分数:{}, 备注:{}",
|
||||||
|
resultId, chiefJudgeId, result.getTotalScore(), finalScore, note);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总裁确认/修改分数
|
||||||
|
*
|
||||||
|
* @param resultId 成绩ID
|
||||||
|
* @param generalJudgeId 总裁ID
|
||||||
|
* @param score 确认/修改后的分数(null表示直接确认原分数)
|
||||||
|
* @param note 备注
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public boolean confirmByGeneralJudge(Long resultId, Long generalJudgeId, BigDecimal score, String note) {
|
||||||
|
MartialResult result = this.getById(resultId);
|
||||||
|
if (result == null) {
|
||||||
|
throw new ServiceException("成绩记录不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查状态:必须主裁判已确认
|
||||||
|
if (result.getScoreStatus() == null || result.getScoreStatus() < MartialResult.SCORE_STATUS_CHIEF_CONFIRMED) {
|
||||||
|
throw new ServiceException("主裁判尚未确认,总裁无法操作");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.getScoreStatus() >= MartialResult.SCORE_STATUS_GENERAL_CONFIRMED) {
|
||||||
|
throw new ServiceException("该成绩已被总裁确认,无法重复操作");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确定最终分数(基于主裁判确认的分数)
|
||||||
|
BigDecimal baseScore = result.getChiefJudgeScore() != null ? result.getChiefJudgeScore() : result.getTotalScore();
|
||||||
|
BigDecimal finalScore = score != null ? score : baseScore;
|
||||||
|
|
||||||
|
// 验证分数范围(如果有修改)
|
||||||
|
if (score != null && baseScore != null) {
|
||||||
|
BigDecimal minAllowed = baseScore.subtract(new BigDecimal("0.050"));
|
||||||
|
BigDecimal maxAllowed = baseScore.add(new BigDecimal("0.050"));
|
||||||
|
if (score.compareTo(minAllowed) < 0 || score.compareTo(maxAllowed) > 0) {
|
||||||
|
throw new ServiceException("修改分数只能在主裁判确认分数±0.050范围内");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新总裁确认信息
|
||||||
|
result.setGeneralJudgeScore(finalScore);
|
||||||
|
result.setGeneralJudgeId(generalJudgeId);
|
||||||
|
result.setGeneralJudgeTime(LocalDateTime.now());
|
||||||
|
result.setGeneralJudgeNote(note);
|
||||||
|
result.setScoreStatus(MartialResult.SCORE_STATUS_GENERAL_CONFIRMED);
|
||||||
|
|
||||||
|
// 更新最终得分
|
||||||
|
result.setFinalScore(finalScore);
|
||||||
|
|
||||||
|
boolean success = this.updateById(result);
|
||||||
|
|
||||||
|
log.info("总裁确认成绩 - 成绩ID:{}, 总裁ID:{}, 主裁判分数:{}, 确认分数:{}, 备注:{}",
|
||||||
|
resultId, generalJudgeId, baseScore, finalScore, note);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取待主裁判确认的成绩列表
|
||||||
|
*
|
||||||
|
* @param venueId 场地ID
|
||||||
|
* @return 成绩列表
|
||||||
|
*/
|
||||||
|
public List<MartialResult> getPendingChiefConfirmList(Long venueId) {
|
||||||
|
QueryWrapper<MartialResult> wrapper = new QueryWrapper<>();
|
||||||
|
wrapper.eq("venue_id", venueId);
|
||||||
|
wrapper.eq("is_deleted", 0);
|
||||||
|
wrapper.and(w -> w.isNull("score_status").or().eq("score_status", MartialResult.SCORE_STATUS_JUDGING));
|
||||||
|
wrapper.orderByAsc("create_time");
|
||||||
|
return this.list(wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取待总裁确认的成绩列表
|
||||||
|
*
|
||||||
|
* @param competitionId 比赛ID(总裁可以看所有场地)
|
||||||
|
* @return 成绩列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<MartialResult> getPendingGeneralConfirmList(Long competitionId) {
|
||||||
|
QueryWrapper<MartialResult> wrapper = new QueryWrapper<>();
|
||||||
|
wrapper.eq("competition_id", competitionId);
|
||||||
|
wrapper.eq("is_deleted", 0);
|
||||||
|
wrapper.eq("score_status", MartialResult.SCORE_STATUS_CHIEF_CONFIRMED);
|
||||||
|
wrapper.orderByAsc("create_time");
|
||||||
|
List<MartialResult> results = this.list(wrapper);
|
||||||
|
|
||||||
|
// 填充选手信息
|
||||||
|
for (MartialResult result : results) {
|
||||||
|
if (result.getAthleteId() != null) {
|
||||||
|
MartialAthlete athlete = athleteService.getById(result.getAthleteId());
|
||||||
|
if (athlete != null) {
|
||||||
|
result.setPlayerName(athlete.getPlayerName());
|
||||||
|
result.setTeamName(athlete.getTeamName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import org.springblade.modules.martial.service.IMartialAthleteService;
|
|||||||
import org.springblade.modules.martial.service.IMartialJudgeProjectService;
|
import org.springblade.modules.martial.service.IMartialJudgeProjectService;
|
||||||
import org.springblade.modules.martial.service.IMartialJudgeService;
|
import org.springblade.modules.martial.service.IMartialJudgeService;
|
||||||
import org.springblade.modules.martial.service.IMartialScoreService;
|
import org.springblade.modules.martial.service.IMartialScoreService;
|
||||||
|
import org.springblade.modules.martial.service.IMartialResultService;
|
||||||
|
import org.springblade.modules.martial.pojo.entity.MartialResult;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -43,6 +45,9 @@ public class MartialScoreServiceImpl extends ServiceImpl<MartialScoreMapper, Mar
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IMartialJudgeService judgeService;
|
private IMartialJudgeService judgeService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IMartialResultService resultService;
|
||||||
|
|
||||||
/** 最低分 */
|
/** 最低分 */
|
||||||
private static final BigDecimal MIN_SCORE = new BigDecimal("5.000");
|
private static final BigDecimal MIN_SCORE = new BigDecimal("5.000");
|
||||||
/** 最高分 */
|
/** 最高分 */
|
||||||
@@ -403,7 +408,39 @@ public class MartialScoreServiceImpl extends ServiceImpl<MartialScoreMapper, Mar
|
|||||||
athlete.getId(), athlete.getPlayerName(), originalCalculatedScore, dto.getModifiedScore(), dto.getNote());
|
athlete.getId(), athlete.getPlayerName(), originalCalculatedScore, dto.getModifiedScore(), dto.getNote());
|
||||||
}
|
}
|
||||||
|
|
||||||
return athleteUpdated && recordSaved;
|
|
||||||
|
// 8. 同步更新 martial_result 表(三级裁判系统)
|
||||||
|
// 查找或创建该选手的成绩记录
|
||||||
|
LambdaQueryWrapper<MartialResult> resultQuery = new LambdaQueryWrapper<>();
|
||||||
|
resultQuery.eq(MartialResult::getAthleteId, athlete.getId())
|
||||||
|
.eq(MartialResult::getProjectId, athlete.getProjectId())
|
||||||
|
.eq(MartialResult::getIsDeleted, 0);
|
||||||
|
MartialResult result = resultService.getOne(resultQuery);
|
||||||
|
|
||||||
|
if (result == null) {
|
||||||
|
// 创建新的成绩记录
|
||||||
|
result = new MartialResult();
|
||||||
|
result.setCompetitionId(athlete.getCompetitionId());
|
||||||
|
result.setAthleteId(athlete.getId());
|
||||||
|
result.setProjectId(athlete.getProjectId());
|
||||||
|
result.setVenueId(dto.getVenueId());
|
||||||
|
result.setOriginalScore(originalCalculatedScore);
|
||||||
|
result.setFinalScore(dto.getModifiedScore());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新主裁判确认信息
|
||||||
|
result.setChiefJudgeScore(dto.getModifiedScore());
|
||||||
|
result.setChiefJudgeId(dto.getModifierId());
|
||||||
|
result.setChiefJudgeTime(LocalDateTime.now());
|
||||||
|
result.setChiefJudgeNote(dto.getNote());
|
||||||
|
result.setScoreStatus(MartialResult.SCORE_STATUS_CHIEF_CONFIRMED);
|
||||||
|
result.setFinalScore(dto.getModifiedScore());
|
||||||
|
|
||||||
|
boolean resultSaved = resultService.saveOrUpdate(result);
|
||||||
|
log.info("主裁判确认成绩 - 选手ID:{}, 成绩ID:{}, 分数:{}, score_status:{}",
|
||||||
|
athlete.getId(), result.getId(), dto.getModifiedScore(), result.getScoreStatus());
|
||||||
|
|
||||||
|
return athleteUpdated && recordSaved && resultSaved;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user