其他
2025/5/19大约 2 分钟
用户排名接口
@Override
public List<MonthRankVO> monthRank() {
List<Long> list = submissionService.lambdaQuery().select(Submission::getUserId)
.ge(Submission::getCreateTime, LocalDate.now().minusDays(29))
.list().stream().map(Submission::getUserId).toList();
Map<Long, Long> collect = list.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
ArrayList<Map.Entry<Long, Long>> entries = new ArrayList<>(collect.entrySet());
entries.sort((e1, e2) -> e2.getValue().compareTo(e1.getValue()));
List<Long> ids = entries.stream().map(Map.Entry::getKey).toList();
List<MonthRankVO> result = new ArrayList<>();
for (int i = 0; i < ids.size(); i++) {
User user = lambdaQuery()
.eq(User::getId, ids.get(i))
.one();
result.add(MonthRankVO.builder()
.rankNumber(i + 1)
.subNumber(entries.get(i).getValue())
.nickname(user.getNickname())
.build());
}
return result;
}
过去一周提交数查询接口
@Override
public LastWeekQueryVO lastWeek() {
Long id = CurrentIdUtils.getCurrentId();
List<Submission> list = submissionService.lambdaQuery()
.eq(Submission::getUserId, id)
.ge(Submission::getCreateTime, LocalDate.now().minusDays(6))
.orderByDesc(Submission::getCreateTime)
.list();
LastWeekQueryVO queryVO = LastWeekQueryVO.builder()
.date(new ArrayList<>())
.AcNumber(null)
.subNumber(null)
.build();
Integer[] acNumber = {0, 0, 0, 0, 0, 0, 0};
Integer[] subNumber = {0, 0, 0, 0, 0, 0, 0};
for (Submission submission : list) {
LocalDate judTime = submission.getCreateTime().toLocalDate();
LocalDate now = LocalDate.now();
int between = (int) ChronoUnit.DAYS.between(judTime, now);
if (submission.getJudgeResult().equals(JudgeResultConstant.Accepted)) {
acNumber[6 - between]++;
}
subNumber[6 - between]++;
}
for (int i = 6; i >= 0; i--) {
String[] time = LocalDate.now().minusDays(i).toString().split("-");
queryVO.getDate().add(time[1] + "-" + time[2]);
}
queryVO.setAcNumber(Arrays.asList(acNumber));
queryVO.setSubNumber(Arrays.asList(subNumber));
return queryVO;
}
对分页查询大小的限制
创建常量类
public class MaxPageSizeConstant {
public static final Integer MAX_PAGE_SIZE = 50;
}
添加限制
if (problemQueryDTO.getPageSize() > MaxPageSizeConstant.MAX_PAGE_SIZE) {
problemQueryDTO.setPageSize(MaxPageSizeConstant.MAX_PAGE_SIZE);
}
比赛密码校验接口
逻辑很简单,所以我直接写到Controller层了
@Operation(summary = "竞赛密码检验")
@PostMapping("/contest/password")
public Result verify(@RequestBody ContestPasswordDTO dto) {
Contest contest = contestService.getById(dto.getId());
if (contest.getPassword().equals(dto.getPassword())) {
contestUserService.save(ContestUser.builder()
.contestId(contest.getId())
.userId(CurrentIdUtils.getCurrentId())
.build());
return Result.success();
} else {
return Result.error("密码错误");
}
}
最近比赛查询接口
@Override
public List<LatelyContestVO> lately() {
List<Contest> list = contestMapper.lately();
ArrayList<LatelyContestVO> vos = new ArrayList<>();
for (Contest contest : list) {
LatelyContestVO build = LatelyContestVO.builder()
.startTime(contest.getStartTime())
.endTime(contest.getEndTime())
.name(contest.getName())
.status(status(contest.getStartTime(), contest.getEndTime()))
.build();
if (build.getStatus().equals(ContestConstant.RACE_IS_ON)) {
build.setEndDays(
ChronoUnit.DAYS.between(LocalDateTime.now(),
build.getEndTime()));
}
if (!build.getStatus().equals(ContestConstant.RACE_NOT_START)) {
Long count = contestUserService.lambdaQuery()
.eq(ContestUser::getContestId, contest.getId())
.count();
build.setNumber(count);
}
vos.add(build);
}
return vos;
}
@Select("select * from contest order by end_time desc limit 0,2")
List<Contest> lately();
判题后对比赛题目的处理
//判断是否是比赛题目
if (problem.getStatus().equals(ProblemStatusConstant.ONLY_CONTEST)) {
//获取相关的比赛ID
List<Long> contestIds = contestProblemService.lambdaQuery()
.select(ContestProblem::getContestId)
.eq(ContestProblem::getProblemId, problem.getId())
.list()
.stream().map(ContestProblem::getContestId).toList();
//健壮性判断
if (contestIds.isEmpty()) {
return submission.getId();
}
for (Long contestId : contestIds) {
//判断这个用户是否在比赛用户表中
boolean exists = contestUserService.lambdaQuery()
.eq(ContestUser::getContestId, contestId)
.eq(ContestUser::getUserId, CurrentIdUtils.getCurrentId())
.exists();
//获取这个比赛
Contest contest = contestService.getById(contestId);
//判断比赛时间
if (contest.getEndTime().isBefore(LocalDateTime.now())) {
continue;
}
if (exists) {
//根据比赛ID和用户ID获取相关的比赛用户
ContestUser user = contestUserService.lambdaQuery()
.eq(ContestUser::getContestId, contestId)
.eq(ContestUser::getUserId, CurrentIdUtils.getCurrentId())
.one();
//查询这个比赛的这个题目的提交记录(比赛时间判定)
List<Submission> submissions = submissionService.lambdaQuery()
.eq(Submission::getProblemId, problem.getId())
.gt(Submission::getCreateTime, contest.getStartTime())
.lt(Submission::getCreateTime, contest.getEndTime())
.notIn(Submission::getId,submission.getId())
.list();
//获取以前提交记录的最大分数
int i = 0;
for (Submission sub : submissions) {
i = Integer.max(i, sub.getJudgeScore());
}
//更新比赛用户的分数
if (submission.getJudgeScore() > i) {
user.setScore(user.getScore() + (submission.getJudgeScore() - i));
}
//更新AC数
if (submission.getJudgeScore() == 100 && i != 100) {
user.setAcNumber(user.getAcNumber() + 1);
}
//更新数据库
user.setUpdateTime(LocalDateTime.now());
contestUserService.updateById(user);
} else {
//判断比赛是否进行
if (contest.getEndTime().isAfter(LocalDateTime.now())) {
//加入该用户,更新分数
contestUserService.save(ContestUser.builder()
.userId(CurrentIdUtils.getCurrentId())
.contestId(contestId)
.acNumber(submission.getJudgeScore() == 100 ? 1 : 0)
.status(1)
.score(submission.getJudgeScore())
.build());
}
}
}
}