fix(security): enforce mini token identity and score authorization
This commit is contained in:
+205
-32
@@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springblade.core.boot.ctrl.BladeController;
|
import org.springblade.core.boot.ctrl.BladeController;
|
||||||
import org.springblade.core.tool.api.R;
|
import org.springblade.core.tool.api.R;
|
||||||
import org.springblade.core.secure.utils.AuthUtil;
|
import org.springblade.core.secure.utils.AuthUtil;
|
||||||
@@ -57,6 +58,7 @@ import java.util.stream.Collectors;
|
|||||||
*
|
*
|
||||||
* @author BladeX
|
* @author BladeX
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@RequestMapping("/mini")
|
@RequestMapping("/mini")
|
||||||
@@ -96,7 +98,24 @@ public class MartialMiniController extends BladeController {
|
|||||||
}
|
}
|
||||||
@PostMapping("/score/submit")
|
@PostMapping("/score/submit")
|
||||||
@Operation(summary = "提交评分", description = "裁判员提交评分")
|
@Operation(summary = "提交评分", description = "裁判员提交评分")
|
||||||
public R submitScore(@RequestBody org.springblade.modules.martial.pojo.dto.MiniScoreSubmitDTO dto) {
|
public R submitScore(
|
||||||
|
@RequestHeader(value = "Authorization", required = false) String authorization,
|
||||||
|
@RequestHeader(value = "Blade-Auth", required = false) String bladeAuthToken,
|
||||||
|
@RequestBody org.springblade.modules.martial.pojo.dto.MiniScoreSubmitDTO dto
|
||||||
|
) {
|
||||||
|
if (dto == null) {
|
||||||
|
return R.fail("请求体不能为空");
|
||||||
|
}
|
||||||
|
JudgeAuthContext authContext = resolveJudgeAuthContext(authorization, bladeAuthToken);
|
||||||
|
if (authContext == null || authContext.getJudgeId() == null) {
|
||||||
|
return R.fail("登录状态无效或已过期");
|
||||||
|
}
|
||||||
|
Long payloadJudgeId = parseLong(dto.getJudgeId());
|
||||||
|
if (payloadJudgeId != null && !payloadJudgeId.equals(authContext.getJudgeId())) {
|
||||||
|
log.warn("评分提交身份字段不匹配,已忽略请求体judgeId,payloadJudgeId={}, authJudgeId={}", payloadJudgeId, authContext.getJudgeId());
|
||||||
|
}
|
||||||
|
// 向后兼容:保留 judgeId 字段,但强制覆盖为 token 身份
|
||||||
|
dto.setJudgeId(String.valueOf(authContext.getJudgeId()));
|
||||||
return miniScoringService.submitScore(dto);
|
return miniScoringService.submitScore(dto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,6 +250,64 @@ public class MartialMiniController extends BladeController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JudgeAuthContext resolveJudgeAuthContext(String authorization, String bladeAuthToken) {
|
||||||
|
String accessToken = resolveAccessToken(authorization, bladeAuthToken);
|
||||||
|
if (accessToken != null) {
|
||||||
|
MartialJudgeInvite invite = findValidInviteByAccessToken(accessToken);
|
||||||
|
if (invite != null && invite.getJudgeId() != null) {
|
||||||
|
return JudgeAuthContext.fromInvite(invite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BladeUser bladeUser = AuthUtil.getUser();
|
||||||
|
if (bladeUser == null || bladeUser.getUserId() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
MartialJudge judge = judgeService.getById(bladeUser.getUserId());
|
||||||
|
if (judge == null) {
|
||||||
|
log.warn("Blade-Auth用户未绑定评委信息,userId={}", bladeUser.getUserId());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return JudgeAuthContext.fromJudge(judge);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String resolveAccessToken(String authorization, String bladeAuthToken) {
|
||||||
|
String token = extractToken(authorization);
|
||||||
|
if (token != null) {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
return extractToken(bladeAuthToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String extractToken(String tokenHeader) {
|
||||||
|
if (Func.isEmpty(tokenHeader)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String token = tokenHeader.trim();
|
||||||
|
if (token.regionMatches(true, 0, "Bearer ", 0, 7)) {
|
||||||
|
token = token.substring(7).trim();
|
||||||
|
}
|
||||||
|
return Func.isEmpty(token) ? null : token;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MartialJudgeInvite findValidInviteByAccessToken(String accessToken) {
|
||||||
|
LambdaQueryWrapper<MartialJudgeInvite> inviteQuery = new LambdaQueryWrapper<>();
|
||||||
|
inviteQuery.eq(MartialJudgeInvite::getAccessToken, accessToken);
|
||||||
|
inviteQuery.eq(MartialJudgeInvite::getStatus, 1);
|
||||||
|
inviteQuery.eq(MartialJudgeInvite::getIsDeleted, 0);
|
||||||
|
MartialJudgeInvite invite = judgeInviteService.getOne(inviteQuery, false);
|
||||||
|
if (invite == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
if (invite.getTokenExpireTime() == null || !invite.getTokenExpireTime().isAfter(now)) {
|
||||||
|
log.warn("accessToken已过期或无效,token={}, tokenExpireTime={}", accessToken, invite.getTokenExpireTime());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return invite;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取选手列表(支持分页)
|
* 获取选手列表(支持分页)
|
||||||
* - 裁判员:获取所有选手,标记是否已评分
|
* - 裁判员:获取所有选手,标记是否已评分
|
||||||
@@ -443,10 +520,14 @@ public class MartialMiniController extends BladeController {
|
|||||||
*/
|
*/
|
||||||
@PostMapping("/logout")
|
@PostMapping("/logout")
|
||||||
@Operation(summary = "退出登录", description = "清除登录状态")
|
@Operation(summary = "退出登录", description = "清除登录状态")
|
||||||
public R logout(@RequestHeader(value = "Authorization", required = false) String token) {
|
public R logout(
|
||||||
|
@RequestHeader(value = "Authorization", required = false) String token,
|
||||||
|
@RequestHeader(value = "Blade-Auth", required = false) String bladeAuthToken
|
||||||
|
) {
|
||||||
// 从Redis删除登录缓存
|
// 从Redis删除登录缓存
|
||||||
if (token != null && !token.isEmpty()) {
|
String accessToken = resolveAccessToken(token, bladeAuthToken);
|
||||||
String cacheKey = MINI_LOGIN_CACHE_PREFIX + token;
|
if (accessToken != null) {
|
||||||
|
String cacheKey = MINI_LOGIN_CACHE_PREFIX + accessToken;
|
||||||
bladeRedis.del(cacheKey);
|
bladeRedis.del(cacheKey);
|
||||||
}
|
}
|
||||||
return R.success("退出成功");
|
return R.success("退出成功");
|
||||||
@@ -457,13 +538,23 @@ public class MartialMiniController extends BladeController {
|
|||||||
*/
|
*/
|
||||||
@GetMapping("/verify")
|
@GetMapping("/verify")
|
||||||
@Operation(summary = "Token验证", description = "验证token并返回登录信息,支持服务重启后恢复登录状态")
|
@Operation(summary = "Token验证", description = "验证token并返回登录信息,支持服务重启后恢复登录状态")
|
||||||
public R<MiniLoginVO> verify(@RequestHeader(value = "Authorization", required = false) String token) {
|
public R<MiniLoginVO> verify(
|
||||||
if (token == null || token.isEmpty()) {
|
@RequestHeader(value = "Authorization", required = false) String token,
|
||||||
|
@RequestHeader(value = "Blade-Auth", required = false) String bladeAuthToken
|
||||||
|
) {
|
||||||
|
String accessToken = resolveAccessToken(token, bladeAuthToken);
|
||||||
|
if (accessToken == null) {
|
||||||
return R.fail("Token不能为空");
|
return R.fail("Token不能为空");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MartialJudgeInvite invite = findValidInviteByAccessToken(accessToken);
|
||||||
|
if (invite == null) {
|
||||||
|
bladeRedis.del(MINI_LOGIN_CACHE_PREFIX + accessToken);
|
||||||
|
return R.fail("Token无效或已失效");
|
||||||
|
}
|
||||||
|
|
||||||
// 从Redis获取登录信息
|
// 从Redis获取登录信息
|
||||||
String cacheKey = MINI_LOGIN_CACHE_PREFIX + token;
|
String cacheKey = MINI_LOGIN_CACHE_PREFIX + accessToken;
|
||||||
MiniLoginVO loginInfo = bladeRedis.get(cacheKey);
|
MiniLoginVO loginInfo = bladeRedis.get(cacheKey);
|
||||||
|
|
||||||
if (loginInfo != null) {
|
if (loginInfo != null) {
|
||||||
@@ -472,23 +563,14 @@ public class MartialMiniController extends BladeController {
|
|||||||
return R.data(loginInfo);
|
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());
|
MartialCompetition competition = competitionService.getById(invite.getCompetitionId());
|
||||||
MartialJudge judge = judgeService.getById(invite.getJudgeId());
|
MartialJudge judge = judgeService.getById(invite.getJudgeId());
|
||||||
|
if (competition == null || judge == null) {
|
||||||
|
log.warn("Token验证失败:关联比赛或评委不存在,token={}, competitionId={}, judgeId={}",
|
||||||
|
accessToken, invite.getCompetitionId(), invite.getJudgeId());
|
||||||
|
return R.fail("登录信息不存在");
|
||||||
|
}
|
||||||
MartialVenue martialVenue = invite.getVenueId() != null ? venueService.getById(invite.getVenueId()) : null;
|
MartialVenue martialVenue = invite.getVenueId() != null ? venueService.getById(invite.getVenueId()) : null;
|
||||||
// 获取项目列表:总裁判看所有项目,其他裁判根据场地获取项目
|
// 获取项目列表:总裁判看所有项目,其他裁判根据场地获取项目
|
||||||
List<MiniLoginVO.ProjectInfo> projects = new ArrayList<>();
|
List<MiniLoginVO.ProjectInfo> projects = new ArrayList<>();
|
||||||
@@ -509,7 +591,7 @@ public class MartialMiniController extends BladeController {
|
|||||||
// 如果没有场地,projects保持为空列表
|
// 如果没有场地,projects保持为空列表
|
||||||
|
|
||||||
MiniLoginVO vo = new MiniLoginVO();
|
MiniLoginVO vo = new MiniLoginVO();
|
||||||
vo.setToken(token);
|
vo.setToken(accessToken);
|
||||||
String role = invite.getRole();
|
String role = invite.getRole();
|
||||||
Integer refereeType = invite.getRefereeType();
|
Integer refereeType = invite.getRefereeType();
|
||||||
if ("general_judge".equals(role) || "general".equals(role) || (refereeType != null && refereeType == 3)) {
|
if ("general_judge".equals(role) || "general".equals(role) || (refereeType != null && refereeType == 3)) {
|
||||||
@@ -718,13 +800,33 @@ public class MartialMiniController extends BladeController {
|
|||||||
*/
|
*/
|
||||||
@PostMapping("/chief/confirm")
|
@PostMapping("/chief/confirm")
|
||||||
@Operation(summary = "主裁判确认分数", description = "主裁判确认或修改选手分数")
|
@Operation(summary = "主裁判确认分数", description = "主裁判确认或修改选手分数")
|
||||||
public R confirmByChiefJudge(@RequestBody ChiefJudgeConfirmDTO dto) {
|
public R confirmByChiefJudge(
|
||||||
Long resultId = parseLong(dto.getResultId());
|
@RequestHeader(value = "Authorization", required = false) String authorization,
|
||||||
Long chiefJudgeId = parseLong(dto.getChiefJudgeId());
|
@RequestHeader(value = "Blade-Auth", required = false) String bladeAuthToken,
|
||||||
if (resultId == null || chiefJudgeId == null) {
|
@RequestBody ChiefJudgeConfirmDTO dto
|
||||||
|
) {
|
||||||
|
if (dto == null) {
|
||||||
return R.fail("参数错误");
|
return R.fail("参数错误");
|
||||||
}
|
}
|
||||||
boolean success = resultService.confirmByChiefJudge(resultId, chiefJudgeId, dto.getScore(), dto.getNote());
|
JudgeAuthContext authContext = resolveJudgeAuthContext(authorization, bladeAuthToken);
|
||||||
|
if (authContext == null || authContext.getJudgeId() == null) {
|
||||||
|
return R.fail("登录状态无效或已过期");
|
||||||
|
}
|
||||||
|
if (!authContext.isChiefJudge()) {
|
||||||
|
log.warn("主裁判确认拒绝:无主裁判权限,judgeId={}, role={}, refereeType={}",
|
||||||
|
authContext.getJudgeId(), authContext.getRole(), authContext.getRefereeType());
|
||||||
|
return R.fail("无主裁判权限");
|
||||||
|
}
|
||||||
|
Long resultId = parseLong(dto.getResultId());
|
||||||
|
if (resultId == null) {
|
||||||
|
return R.fail("参数错误");
|
||||||
|
}
|
||||||
|
Long payloadChiefJudgeId = parseLong(dto.getChiefJudgeId());
|
||||||
|
if (payloadChiefJudgeId != null && !payloadChiefJudgeId.equals(authContext.getJudgeId())) {
|
||||||
|
log.warn("主裁判确认身份字段不匹配,已忽略请求体chiefJudgeId,payloadChiefJudgeId={}, authJudgeId={}",
|
||||||
|
payloadChiefJudgeId, authContext.getJudgeId());
|
||||||
|
}
|
||||||
|
boolean success = resultService.confirmByChiefJudge(resultId, authContext.getJudgeId(), dto.getScore(), dto.getNote());
|
||||||
return success ? R.success("确认成功") : R.fail("确认失败");
|
return success ? R.success("确认成功") : R.fail("确认失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -733,13 +835,33 @@ public class MartialMiniController extends BladeController {
|
|||||||
*/
|
*/
|
||||||
@PostMapping("/general/confirm")
|
@PostMapping("/general/confirm")
|
||||||
@Operation(summary = "总裁确认分数", description = "总裁确认或修改选手分数")
|
@Operation(summary = "总裁确认分数", description = "总裁确认或修改选手分数")
|
||||||
public R confirmByGeneralJudge(@RequestBody GeneralJudgeConfirmDTO dto) {
|
public R confirmByGeneralJudge(
|
||||||
Long resultId = parseLong(dto.getResultId());
|
@RequestHeader(value = "Authorization", required = false) String authorization,
|
||||||
Long generalJudgeId = parseLong(dto.getGeneralJudgeId());
|
@RequestHeader(value = "Blade-Auth", required = false) String bladeAuthToken,
|
||||||
if (resultId == null || generalJudgeId == null) {
|
@RequestBody GeneralJudgeConfirmDTO dto
|
||||||
|
) {
|
||||||
|
if (dto == null) {
|
||||||
return R.fail("参数错误");
|
return R.fail("参数错误");
|
||||||
}
|
}
|
||||||
boolean success = resultService.confirmByGeneralJudge(resultId, generalJudgeId, dto.getScore(), dto.getNote());
|
JudgeAuthContext authContext = resolveJudgeAuthContext(authorization, bladeAuthToken);
|
||||||
|
if (authContext == null || authContext.getJudgeId() == null) {
|
||||||
|
return R.fail("登录状态无效或已过期");
|
||||||
|
}
|
||||||
|
if (!authContext.isGeneralJudge()) {
|
||||||
|
log.warn("总裁确认拒绝:无总裁权限,judgeId={}, role={}, refereeType={}",
|
||||||
|
authContext.getJudgeId(), authContext.getRole(), authContext.getRefereeType());
|
||||||
|
return R.fail("无总裁权限");
|
||||||
|
}
|
||||||
|
Long resultId = parseLong(dto.getResultId());
|
||||||
|
if (resultId == null) {
|
||||||
|
return R.fail("参数错误");
|
||||||
|
}
|
||||||
|
Long payloadGeneralJudgeId = parseLong(dto.getGeneralJudgeId());
|
||||||
|
if (payloadGeneralJudgeId != null && !payloadGeneralJudgeId.equals(authContext.getJudgeId())) {
|
||||||
|
log.warn("总裁确认身份字段不匹配,已忽略请求体generalJudgeId,payloadGeneralJudgeId={}, authJudgeId={}",
|
||||||
|
payloadGeneralJudgeId, authContext.getJudgeId());
|
||||||
|
}
|
||||||
|
boolean success = resultService.confirmByGeneralJudge(resultId, authContext.getJudgeId(), dto.getScore(), dto.getNote());
|
||||||
return success ? R.success("确认成功") : R.fail("确认失败");
|
return success ? R.success("确认成功") : R.fail("确认失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -976,6 +1098,57 @@ public class MartialMiniController extends BladeController {
|
|||||||
return R.data(result);
|
return R.data(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class JudgeAuthContext {
|
||||||
|
private final Long judgeId;
|
||||||
|
private final String role;
|
||||||
|
private final Integer refereeType;
|
||||||
|
|
||||||
|
private JudgeAuthContext(Long judgeId, String role, Integer refereeType) {
|
||||||
|
this.judgeId = judgeId;
|
||||||
|
this.role = role;
|
||||||
|
this.refereeType = refereeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JudgeAuthContext fromInvite(MartialJudgeInvite invite) {
|
||||||
|
return new JudgeAuthContext(invite.getJudgeId(), invite.getRole(), invite.getRefereeType());
|
||||||
|
}
|
||||||
|
|
||||||
|
static JudgeAuthContext fromJudge(MartialJudge judge) {
|
||||||
|
Integer refereeType = judge.getRefereeType();
|
||||||
|
String role;
|
||||||
|
if (refereeType != null && refereeType == 3) {
|
||||||
|
role = "general_judge";
|
||||||
|
} else if (refereeType != null && refereeType == 1) {
|
||||||
|
role = "chief_judge";
|
||||||
|
} else {
|
||||||
|
role = "judge";
|
||||||
|
}
|
||||||
|
return new JudgeAuthContext(judge.getId(), role, refereeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
Long getJudgeId() {
|
||||||
|
return judgeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer getRefereeType() {
|
||||||
|
return refereeType;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isChiefJudge() {
|
||||||
|
return "chief_judge".equals(role) || (refereeType != null && refereeType == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isGeneralJudge() {
|
||||||
|
return "general_judge".equals(role)
|
||||||
|
|| "general".equals(role)
|
||||||
|
|| (refereeType != null && refereeType == 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String generateTableNo(ScheduleGroupDetailVO detail) {
|
private String generateTableNo(ScheduleGroupDetailVO detail) {
|
||||||
// 场地编号(简单取第一个数字或默认1)
|
// 场地编号(简单取第一个数字或默认1)
|
||||||
int venueNo = 1;
|
int venueNo = 1;
|
||||||
|
|||||||
+9
-6
@@ -79,15 +79,18 @@ public class MartialScoreServiceImpl extends ServiceImpl<MartialScoreMapper, Mar
|
|||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean save(MartialScore score) {
|
public boolean save(MartialScore score) {
|
||||||
|
if (score == null) {
|
||||||
|
throw new ServiceException("评分数据不能为空");
|
||||||
|
}
|
||||||
|
if (score.getJudgeId() == null || score.getProjectId() == null) {
|
||||||
|
throw new ServiceException("评分缺少裁判或项目信息");
|
||||||
|
}
|
||||||
|
|
||||||
// Task 2.5: 权限验证 - 裁判只能给被分配的项目打分
|
// Task 2.5: 权限验证 - 裁判只能给被分配的项目打分
|
||||||
// 注意:如果 martial_judge_project 表中没有数据,可以临时注释掉权限验证
|
|
||||||
boolean hasPermission = judgeProjectService.hasPermission(score.getJudgeId(), score.getProjectId());
|
boolean hasPermission = judgeProjectService.hasPermission(score.getJudgeId(), score.getProjectId());
|
||||||
if (!hasPermission) {
|
if (!hasPermission) {
|
||||||
log.warn("⚠️ 权限验证失败 - 裁判ID:{}, 项目ID:{} (如果是测试环境,请在 martial_judge_project 表中添加关联记录)",
|
log.warn("权限验证失败,拒绝评分提交,judgeId={}, projectId={}", score.getJudgeId(), score.getProjectId());
|
||||||
score.getJudgeId(), score.getProjectId());
|
throw new ServiceException("您没有权限给该项目打分");
|
||||||
// 临时允许通过,但记录警告日志
|
|
||||||
// 生产环境请取消注释下面这行
|
|
||||||
// throw new ServiceException("您没有权限给该项目打分");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Task 2.2: 验证分数范围
|
// Task 2.2: 验证分数范围
|
||||||
|
|||||||
@@ -35,16 +35,20 @@ public class MiniAuthServiceImpl implements IMiniAuthService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<MiniLoginVO> login(MiniLoginDTO dto) {
|
public R<MiniLoginVO> login(MiniLoginDTO dto) {
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
LambdaQueryWrapper<MartialJudgeInvite> inviteQuery = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<MartialJudgeInvite> inviteQuery = new LambdaQueryWrapper<>();
|
||||||
inviteQuery.eq(MartialJudgeInvite::getInviteCode, dto.getInviteCode());
|
inviteQuery.eq(MartialJudgeInvite::getInviteCode, dto.getInviteCode());
|
||||||
inviteQuery.eq(MartialJudgeInvite::getIsDeleted, 0);
|
inviteQuery.eq(MartialJudgeInvite::getIsDeleted, 0);
|
||||||
|
inviteQuery.eq(MartialJudgeInvite::getStatus, 1);
|
||||||
MartialJudgeInvite invite = judgeInviteService.getOne(inviteQuery);
|
MartialJudgeInvite invite = judgeInviteService.getOne(inviteQuery);
|
||||||
|
|
||||||
if (invite == null) {
|
if (invite == null) {
|
||||||
return R.fail("邀请码不存在");
|
log.warn("小程序登录失败:邀请码不存在或已禁用,inviteCode={}", dto.getInviteCode());
|
||||||
|
return R.fail("邀请码不存在或已失效");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invite.getExpireTime() != null && invite.getExpireTime().isBefore(LocalDateTime.now())) {
|
if (invite.getExpireTime() == null || !invite.getExpireTime().isAfter(now)) {
|
||||||
|
log.warn("小程序登录失败:邀请码已过期,inviteCode={}, expireTime={}", dto.getInviteCode(), invite.getExpireTime());
|
||||||
return R.fail("邀请码已过期");
|
return R.fail("邀请码已过期");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,9 +68,9 @@ public class MiniAuthServiceImpl implements IMiniAuthService {
|
|||||||
|
|
||||||
String token = UUID.randomUUID().toString().replace("-", "");
|
String token = UUID.randomUUID().toString().replace("-", "");
|
||||||
invite.setAccessToken(token);
|
invite.setAccessToken(token);
|
||||||
invite.setTokenExpireTime(LocalDateTime.now().plusDays(7));
|
invite.setTokenExpireTime(now.plusDays(7));
|
||||||
invite.setIsUsed(1);
|
invite.setIsUsed(1);
|
||||||
invite.setUseTime(LocalDateTime.now());
|
invite.setUseTime(now);
|
||||||
invite.setLoginIp(dto.getLoginIp());
|
invite.setLoginIp(dto.getLoginIp());
|
||||||
invite.setDeviceInfo(dto.getDeviceInfo());
|
invite.setDeviceInfo(dto.getDeviceInfo());
|
||||||
judgeInviteService.updateById(invite);
|
judgeInviteService.updateById(invite);
|
||||||
|
|||||||
+34
-15
@@ -36,15 +36,43 @@ public class MiniScoringServiceImpl implements IMiniScoringService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public R<String> submitScore(MiniScoreSubmitDTO dto) {
|
public R<String> submitScore(MiniScoreSubmitDTO dto) {
|
||||||
|
if (dto == null) {
|
||||||
|
return R.fail("评分参数不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
Long athleteId = parseLong(dto.getAthleteId());
|
||||||
|
Long judgeId = parseLong(dto.getJudgeId());
|
||||||
|
Long projectId = parseLong(dto.getProjectId());
|
||||||
|
Long competitionId = parseLong(dto.getCompetitionId());
|
||||||
|
Long venueId = parseLong(dto.getVenueId());
|
||||||
|
Long scheduleId = parseLong(dto.getScheduleId());
|
||||||
|
if (athleteId == null || judgeId == null || projectId == null || competitionId == null || dto.getScore() == null) {
|
||||||
|
log.warn("评分提交参数缺失,athleteId={}, judgeId={}, projectId={}, competitionId={}",
|
||||||
|
dto.getAthleteId(), dto.getJudgeId(), dto.getProjectId(), dto.getCompetitionId());
|
||||||
|
return R.fail("评分参数不完整");
|
||||||
|
}
|
||||||
|
|
||||||
|
MartialJudge judge = judgeService.getById(judgeId);
|
||||||
|
if (judge == null) {
|
||||||
|
log.warn("评分提交失败:评委不存在,judgeId={}", judgeId);
|
||||||
|
return R.fail("评委信息不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
MartialAthlete athlete = athleteService.getById(athleteId);
|
||||||
|
if (athlete == null) {
|
||||||
|
log.warn("评分提交失败:选手不存在,athleteId={}", athleteId);
|
||||||
|
return R.fail("选手信息不存在");
|
||||||
|
}
|
||||||
|
|
||||||
MartialScore score = new MartialScore();
|
MartialScore score = new MartialScore();
|
||||||
|
|
||||||
score.setAthleteId(parseLong(dto.getAthleteId()));
|
score.setAthleteId(athleteId);
|
||||||
score.setJudgeId(parseLong(dto.getJudgeId()));
|
score.setJudgeId(judgeId);
|
||||||
score.setScore(dto.getScore());
|
score.setScore(dto.getScore());
|
||||||
score.setProjectId(parseLong(dto.getProjectId()));
|
score.setProjectId(projectId);
|
||||||
score.setCompetitionId(parseLong(dto.getCompetitionId()));
|
score.setCompetitionId(competitionId);
|
||||||
score.setVenueId(parseLong(dto.getVenueId()));
|
score.setVenueId(venueId);
|
||||||
score.setScheduleId(parseLong(dto.getScheduleId()));
|
score.setScheduleId(scheduleId);
|
||||||
score.setNote(dto.getNote());
|
score.setNote(dto.getNote());
|
||||||
score.setScoreTime(LocalDateTime.now());
|
score.setScoreTime(LocalDateTime.now());
|
||||||
|
|
||||||
@@ -56,20 +84,11 @@ public class MiniScoringServiceImpl implements IMiniScoringService {
|
|||||||
score.setDeductionItems(com.alibaba.fastjson.JSON.toJSONString(deductionIds));
|
score.setDeductionItems(com.alibaba.fastjson.JSON.toJSONString(deductionIds));
|
||||||
}
|
}
|
||||||
|
|
||||||
Long judgeId = parseLong(dto.getJudgeId());
|
|
||||||
if (judgeId != null) {
|
|
||||||
MartialJudge judge = judgeService.getById(judgeId);
|
|
||||||
if (judge != null) {
|
|
||||||
score.setJudgeName(judge.getName());
|
score.setJudgeName(judge.getName());
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean success = scoreService.save(score);
|
boolean success = scoreService.save(score);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
Long athleteId = parseLong(dto.getAthleteId());
|
|
||||||
Long projectId = parseLong(dto.getProjectId());
|
|
||||||
Long venueId = parseLong(dto.getVenueId());
|
|
||||||
if (athleteId != null && projectId != null) {
|
if (athleteId != null && projectId != null) {
|
||||||
updateAthleteTotalScore(athleteId, projectId, venueId);
|
updateAthleteTotalScore(athleteId, projectId, venueId);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user