فهرست منبع

# feat: 比赛删除按创建者校验、开始后禁止修改、题目分类仅管理员可增改

yangyi 2 ماه پیش
والد
کامیت
3b54c835ec

+ 2 - 2
src/main/java/space/anyi/serve/controller/CategoryController.java

@@ -38,14 +38,14 @@ public class CategoryController {
     }
 
     @Operation(summary = "新增分类", security = @SecurityRequirement(name = "openApiSecurityScheme"))
-    @PreAuthorize("hasAnyRole('ROLE_coach', 'ROLE_admin')")
+    @PreAuthorize("hasRole('ROLE_admin')")
     @PostMapping
     public Response<Boolean> add(@Valid @RequestBody CategoryDto dto) {
         return Response.ok(categoryService.insert(dto));
     }
 
     @Operation(summary = "修改分类", security = @SecurityRequirement(name = "openApiSecurityScheme"))
-    @PreAuthorize("hasAnyRole('ROLE_coach', 'ROLE_admin')")
+    @PreAuthorize("hasRole('ROLE_admin')")
     @PutMapping
     public Response<Boolean> edit(@Valid @RequestBody CategoryDto dto) {
         return Response.ok(categoryService.update(dto));

+ 1 - 1
src/main/java/space/anyi/serve/controller/ContestController.java

@@ -94,7 +94,7 @@ public class ContestController {
     }
 
     @Operation(summary = "批量删除比赛", security = @SecurityRequirement(name = "openApiSecurityScheme"))
-    @PreAuthorize("hasRole('ROLE_admin')")
+    @PreAuthorize("hasAnyRole('ROLE_coach', 'ROLE_admin')")
     @DeleteMapping
     public Response<Boolean> deleteByIds(@NotEmpty(message = "ID列表不能为空") @RequestParam List<Long> ids) {
         return Response.ok(contestService.deleteByIds(ids));

+ 32 - 0
src/main/java/space/anyi/serve/service/impl/ContestServiceImpl.java

@@ -18,6 +18,7 @@ import space.anyi.serve.mapper.SubmissionMapper;
 import space.anyi.serve.service.ContestService;
 import space.anyi.serve.service.ProblemService;
 import space.anyi.serve.service.UserService;
+import space.anyi.serve.util.SecurityUtils;
 
 import java.time.LocalDateTime;
 import java.util.List;
@@ -139,6 +140,7 @@ public class ContestServiceImpl extends ServiceImpl<ContestMapper, Contest> impl
         if (contest == null) {
             throw new IllegalArgumentException("比赛不存在");
         }
+        assertNotStarted(contest);
         contest.setTitle(dto.getTitle());
         contest.setDescription(dto.getDescription());
         contest.setType(dto.getType());
@@ -154,6 +156,19 @@ public class ContestServiceImpl extends ServiceImpl<ContestMapper, Contest> impl
         if (ids == null || ids.isEmpty()) {
             return false;
         }
+        String role = SecurityUtils.getCurrentRole();
+        Long userId = SecurityUtils.getCurrentUserId();
+        if (User.ROLE_COACH.equals(role)) {
+            for (Long id : ids) {
+                Contest contest = getById(id);
+                if (contest == null) {
+                    throw new IllegalArgumentException("比赛不存在");
+                }
+                if (!Objects.equals(contest.getCreatedBy(), userId)) {
+                    throw new IllegalArgumentException("教练只能删除自己创建的比赛");
+                }
+            }
+        }
         contestProblemMapper.delete(new LambdaQueryWrapper<ContestProblem>()
                 .in(ContestProblem::getContestId, ids));
         contestRegistrationMapper.delete(new LambdaQueryWrapper<ContestRegistration>()
@@ -167,6 +182,7 @@ public class ContestServiceImpl extends ServiceImpl<ContestMapper, Contest> impl
         if (contest == null) {
             throw new IllegalArgumentException("比赛不存在");
         }
+        assertNotStarted(contest);
         Problem problem = problemService.getById(dto.getProblemId());
         if (problem == null) {
             throw new IllegalArgumentException("题目不存在");
@@ -181,6 +197,11 @@ public class ContestServiceImpl extends ServiceImpl<ContestMapper, Contest> impl
 
     @Override
     public Boolean updateProblem(Long contestId, ContestProblemDto dto) {
+        Contest contest = getById(contestId);
+        if (contest == null) {
+            throw new IllegalArgumentException("比赛不存在");
+        }
+        assertNotStarted(contest);
         ContestProblem contestProblem = new ContestProblem();
         contestProblem.setContestId(contestId);
         contestProblem.setProblemId(dto.getProblemId());
@@ -193,6 +214,11 @@ public class ContestServiceImpl extends ServiceImpl<ContestMapper, Contest> impl
 
     @Override
     public Boolean removeProblem(Long contestId, Long problemId) {
+        Contest contest = getById(contestId);
+        if (contest == null) {
+            throw new IllegalArgumentException("比赛不存在");
+        }
+        assertNotStarted(contest);
         return contestProblemMapper.delete(new LambdaQueryWrapper<ContestProblem>()
                 .eq(ContestProblem::getContestId, contestId)
                 .eq(ContestProblem::getProblemId, problemId)) > 0;
@@ -246,4 +272,10 @@ public class ContestServiceImpl extends ServiceImpl<ContestMapper, Contest> impl
             updateById(contest);
         }
     }
+
+    private void assertNotStarted(Contest contest) {
+        if (!Contest.STATUS_PENDING.equals(contest.getStatus())) {
+            throw new IllegalArgumentException("比赛已开始,无法修改");
+        }
+    }
 }