refactor: update controller to use MiniAuthService

Phase 1, Step 1.2.3: Delegate login to service layer
- Add IMiniAuthService dependency to controller
- Replace 95 lines of business logic with service call
- Controller now only handles HTTP layer
- All tests passing

Related to Phase 1 refactoring plan
This commit is contained in:
2026-01-17 18:04:57 +08:00
parent 070c1054cf
commit c9cd4d6e88
10 changed files with 55 additions and 93 deletions
Binary file not shown.
@@ -71,6 +71,7 @@ public class MartialMiniController extends BladeController {
private final IMartialScoreService scoreService;
private final BladeRedis bladeRedis;
private final IMartialResultService resultService;
private final IMiniAuthService miniAuthService;
private final IMartialRegistrationOrderService registrationOrderService;
private final MartialScheduleStatusMapper scheduleStatusMapper;
private final MartialScheduleGroupMapper scheduleGroupMapper;
@@ -86,100 +87,8 @@ public class MartialMiniController extends BladeController {
@PostMapping("/login")
@Operation(summary = "登录验证", description = "使用比赛编码和邀请码登录")
public R<MiniLoginVO> login(@RequestBody MiniLoginDTO dto) {
LambdaQueryWrapper<MartialJudgeInvite> inviteQuery = new LambdaQueryWrapper<>();
inviteQuery.eq(MartialJudgeInvite::getInviteCode, dto.getInviteCode());
inviteQuery.eq(MartialJudgeInvite::getIsDeleted, 0);
MartialJudgeInvite invite = judgeInviteService.getOne(inviteQuery);
if (invite == null) {
return R.fail("邀请码不存在");
}
if (invite.getExpireTime() != null && invite.getExpireTime().isBefore(LocalDateTime.now())) {
return R.fail("邀请码已过期");
}
MartialCompetition competition = competitionService.getById(invite.getCompetitionId());
if (competition == null) {
return R.fail("比赛不存在");
}
if (!competition.getCompetitionCode().equals(dto.getMatchCode())) {
return R.fail("比赛编码不匹配");
}
MartialJudge judge = judgeService.getById(invite.getJudgeId());
if (judge == null) {
return R.fail("评委信息不存在");
}
String token = UUID.randomUUID().toString().replace("-", "");
invite.setAccessToken(token);
invite.setTokenExpireTime(LocalDateTime.now().plusDays(7));
invite.setIsUsed(1);
invite.setUseTime(LocalDateTime.now());
invite.setLoginIp(dto.getLoginIp());
invite.setDeviceInfo(dto.getDeviceInfo());
judgeInviteService.updateById(invite);
// 从 martial_venue 表获取场地信息
MartialVenue martialVenue = null;
if (invite.getVenueId() != null) {
martialVenue = venueService.getById(invite.getVenueId());
}
// 获取项目列表:总裁判看所有项目,其他裁判根据场地获取项目
List<MiniLoginVO.ProjectInfo> projects = new ArrayList<>();
Integer refereeTypeVal = invite.getRefereeType();
String roleVal = invite.getRole();
boolean isGeneralJudge = (refereeTypeVal != null && refereeTypeVal == 3)
|| "general_judge".equals(roleVal) || "general".equals(roleVal);
if (isGeneralJudge) {
// 总裁判看所有项目
projects = getAllProjectsByCompetition(competition.getId());
} else if (Func.isNotEmpty(invite.getProjects())) {
projects = parseProjects(invite.getProjects());
} else if (invite.getVenueId() != null) {
// 未指定项目,根据场地获取项目;如果场地没有项目则返回空列表
projects = getProjectsByVenue(invite.getVenueId());
}
// 如果没有场地,projects保持为空列表
MiniLoginVO vo = new MiniLoginVO();
vo.setToken(token);
String role = invite.getRole();
Integer refereeType = invite.getRefereeType();
if ("general_judge".equals(role) || "general".equals(role) || (refereeType != null && refereeType == 3)) {
vo.setUserRole("general");
} else if ("chief_judge".equals(role) || (refereeType != null && refereeType == 1)) {
vo.setUserRole("admin");
} else {
vo.setUserRole("pub");
}
vo.setMatchId(competition.getId());
vo.setMatchName(competition.getCompetitionName());
vo.setMatchTime(competition.getCompetitionStartTime() != null ?
competition.getCompetitionStartTime().toString() : "");
vo.setJudgeId(judge.getId());
vo.setJudgeName(judge.getName());
vo.setVenueId(martialVenue != null ? martialVenue.getId() : null);
vo.setVenueName(martialVenue != null ? martialVenue.getVenueName() : null);
vo.setProjects(projects);
// 将登录信息缓存到Redis(服务重启后仍然有效)
String cacheKey = MINI_LOGIN_CACHE_PREFIX + token;
bladeRedis.setEx(cacheKey, vo, LOGIN_CACHE_EXPIRE);
return R.data(vo);
return miniAuthService.login(dto);
}
/**
* 提交评分(评委)
* 注意:ID字段使用String类型接收,避免JavaScript大数精度丢失问题
*/
@PostMapping("/score/submit")
@Operation(summary = "提交评分", description = "评委提交对选手的评分")
public R submitScore(@RequestBody org.springblade.modules.martial.pojo.dto.MiniScoreSubmitDTO dto) {
MartialScore score = new MartialScore();
@@ -0,0 +1,53 @@
package org.springblade.modules.martial.controller;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
/**
* MartialMiniController Integration Tests
* Phase 1, Step 1.1.1: Baseline integration tests
*/
@SpringBootTest
@AutoConfigureMockMvc
@Transactional
public class MartialMiniControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testLoginEndpoint() throws Exception {
String loginRequest = "{\"matchCode\":\"TEST001\",\"inviteCode\":\"INVITE001\"}";
mockMvc.perform(post("/mini/login")
.contentType(MediaType.APPLICATION_JSON)
.content(loginRequest))
.andExpect(status().isOk());
}
@Test
public void testScoreSubmitEndpoint() throws Exception {
String scoreRequest = "{\"athleteId\":\"1\",\"judgeId\":\"1\",\"score\":9.5}";
mockMvc.perform(post("/mini/score/submit")
.contentType(MediaType.APPLICATION_JSON)
.content(scoreRequest))
.andExpect(status().isOk());
}
@Test
public void testGetAthletesEndpoint() throws Exception {
mockMvc.perform(get("/mini/score/athletes")
.param("projectId", "1")
.param("venueId", "1"))
.andExpect(status().isOk());
}
}