Bladeren bron

# feat: 题目列表/详情非staff仅可见公开内容,教练仅可管理自己创建的题目及用例

yangyi 2 maanden geleden
bovenliggende
commit
0d211e39f1

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

@@ -18,7 +18,6 @@ import org.springframework.web.bind.annotation.*;
 import space.anyi.serve.entity.PageVo;
 import space.anyi.serve.entity.Response;
 import space.anyi.serve.entity.problem.*;
-import space.anyi.serve.entity.user.User;
 import space.anyi.serve.service.ProblemService;
 import space.anyi.serve.util.SecurityUtils;
 
@@ -56,7 +55,7 @@ public class ProblemController {
             @NotNull(message = "页码不能为null") @RequestParam(defaultValue = "1") Integer pageNum,
             @Parameter(description = "分页大小")
             @NotNull(message = "分页大小不能为null") @RequestParam(defaultValue = "10") Integer pageSize) {
-        boolean onlyPublic = SecurityUtils.isAnonymous();
+        boolean onlyPublic = !SecurityUtils.isStaff();
         Page<Problem> page = Page.of(pageNum, pageSize);
         Page<ProblemVo> result = problemService.queryByPage(title, difficulty, categoryId, isPublic, onlyPublic, page);
         return Response.ok(new PageVo<>(result.getTotal(), result.getRecords()));
@@ -66,9 +65,7 @@ public class ProblemController {
     @GetMapping("{id}")
     public Response<ProblemDetailVo> getDetail(@Parameter(description = "题目ID") @PathVariable Long id) {
         ProblemDetailVo detail = problemService.getDetail(id);
-        String role = SecurityUtils.getCurrentRole();
-        boolean staff = User.ROLE_COACH.equals(role) || User.ROLE_ADMIN.equals(role);
-        if (detail.getIsPublic() != null && detail.getIsPublic() == Problem.IS_PUBLIC_NO && !staff) {
+        if (detail.getIsPublic() != null && detail.getIsPublic() == Problem.IS_PUBLIC_NO && !SecurityUtils.isStaff()) {
             return Response.error("无权限查看该题目");
         }
         return Response.ok(detail);

+ 37 - 1
src/main/java/space/anyi/serve/service/impl/ProblemServiceImpl.java

@@ -15,8 +15,10 @@ import space.anyi.serve.mapper.ProblemMapper;
 import space.anyi.serve.mapper.ProblemTestMapper;
 import space.anyi.serve.service.ProblemService;
 import space.anyi.serve.service.UserService;
+import space.anyi.serve.util.SecurityUtils;
 
 import java.util.List;
+import java.util.Objects;
 
 @Service
 public class ProblemServiceImpl extends ServiceImpl<ProblemMapper, Problem> implements ProblemService {
@@ -42,10 +44,11 @@ public class ProblemServiceImpl extends ServiceImpl<ProblemMapper, Problem> impl
         LambdaQueryWrapper<Problem> wrapper = new LambdaQueryWrapper<Problem>()
                 .like(StringUtils.hasText(title), Problem::getTitle, title)
                 .eq(StringUtils.hasText(difficulty), Problem::getDifficulty, difficulty)
-                .eq(isPublic != null, Problem::getIsPublic, isPublic)
                 .orderByDesc(Problem::getId);
         if (onlyPublic) {
             wrapper.eq(Problem::getIsPublic, Problem.IS_PUBLIC_YES);
+        } else if (isPublic != null) {
+            wrapper.eq(Problem::getIsPublic, isPublic);
         }
         if (categoryId != null) {
             List<ProblemCategoryRel> rels = problemCategoryRelMapper.selectList(
@@ -108,6 +111,7 @@ public class ProblemServiceImpl extends ServiceImpl<ProblemMapper, Problem> impl
         if (problem == null) {
             throw new IllegalArgumentException("题目不存在");
         }
+        assertCoachOwner(problem);
         problem.setTitle(dto.getTitle());
         problem.setDescription(dto.getDescription());
         problem.setTimeLimitMs(dto.getTimeLimitMs());
@@ -142,6 +146,7 @@ public class ProblemServiceImpl extends ServiceImpl<ProblemMapper, Problem> impl
 
     @Override
     public Boolean addCase(ProblemCaseDto dto) {
+        assertCoachCanManage(dto.getProblemId());
         ProblemCase problemCase = new ProblemCase();
         BeanUtils.copyProperties(dto, problemCase);
         return problemCaseMapper.insert(problemCase) > 0;
@@ -149,6 +154,7 @@ public class ProblemServiceImpl extends ServiceImpl<ProblemMapper, Problem> impl
 
     @Override
     public Boolean updateCase(ProblemCaseDto dto) {
+        assertCoachCanManage(dto.getProblemId());
         ProblemCase problemCase = new ProblemCase();
         BeanUtils.copyProperties(dto, problemCase);
         return problemCaseMapper.updateById(problemCase) > 0;
@@ -156,11 +162,17 @@ public class ProblemServiceImpl extends ServiceImpl<ProblemMapper, Problem> impl
 
     @Override
     public Boolean deleteCase(Long id) {
+        ProblemCase problemCase = problemCaseMapper.selectById(id);
+        if (problemCase == null) {
+            throw new IllegalArgumentException("样例不存在");
+        }
+        assertCoachCanManage(problemCase.getProblemId());
         return problemCaseMapper.deleteById(id) > 0;
     }
 
     @Override
     public Boolean addTest(ProblemTestDto dto) {
+        assertCoachCanManage(dto.getProblemId());
         ProblemTest problemTest = new ProblemTest();
         BeanUtils.copyProperties(dto, problemTest);
         return problemTestMapper.insert(problemTest) > 0;
@@ -168,6 +180,7 @@ public class ProblemServiceImpl extends ServiceImpl<ProblemMapper, Problem> impl
 
     @Override
     public Boolean updateTest(ProblemTestDto dto) {
+        assertCoachCanManage(dto.getProblemId());
         ProblemTest problemTest = new ProblemTest();
         BeanUtils.copyProperties(dto, problemTest);
         return problemTestMapper.updateById(problemTest) > 0;
@@ -175,15 +188,38 @@ public class ProblemServiceImpl extends ServiceImpl<ProblemMapper, Problem> impl
 
     @Override
     public Boolean deleteTest(Long id) {
+        ProblemTest problemTest = problemTestMapper.selectById(id);
+        if (problemTest == null) {
+            throw new IllegalArgumentException("评测用例不存在");
+        }
+        assertCoachCanManage(problemTest.getProblemId());
         return problemTestMapper.deleteById(id) > 0;
     }
 
     @Override
     public List<ProblemTestVo> queryTests(Long problemId) {
+        assertCoachCanManage(problemId);
         List<ProblemTest> tests = problemTestMapper.selectList(
                 new LambdaQueryWrapper<ProblemTest>()
                         .eq(ProblemTest::getProblemId, problemId)
                         .orderByAsc(ProblemTest::getSortOrder));
         return ProblemTestVo.from(tests);
     }
+
+    private void assertCoachOwner(Problem problem) {
+        if (User.ROLE_COACH.equals(SecurityUtils.getCurrentRole())) {
+            Long userId = SecurityUtils.getCurrentUserId();
+            if (!Objects.equals(problem.getCreatedBy(), userId)) {
+                throw new IllegalArgumentException("教练只能管理自己创建的题目");
+            }
+        }
+    }
+
+    private void assertCoachCanManage(Long problemId) {
+        Problem problem = getById(problemId);
+        if (problem == null) {
+            throw new IllegalArgumentException("题目不存在");
+        }
+        assertCoachOwner(problem);
+    }
 }