From 2b00d63a05f2abb34d2a661aebd58f2c4dc73ff6 Mon Sep 17 00:00:00 2001 From: chenyuan Date: Thu, 30 Jul 2026 13:27:57 +0800 Subject: [PATCH] feat: manage school default task allocations --- .../stu/SchoolDefaultTaskController.java | 81 +++++++++++++++++++ .../stu/TaskAllocationController.java | 6 ++ .../service/SchoolDefaultTaskService.java | 2 + .../impl/SchoolDefaultTaskServiceImpl.java | 5 ++ .../stu/SchoolDefaultTaskControllerTest.java | 80 ++++++++++++++++++ .../stu/TaskAllocationControllerTest.java | 17 ++++ 6 files changed, 191 insertions(+) create mode 100644 src/main/java/com/sztzjy/linkCommerce/controller/stu/SchoolDefaultTaskController.java create mode 100644 src/test/java/com/sztzjy/linkCommerce/controller/stu/SchoolDefaultTaskControllerTest.java diff --git a/src/main/java/com/sztzjy/linkCommerce/controller/stu/SchoolDefaultTaskController.java b/src/main/java/com/sztzjy/linkCommerce/controller/stu/SchoolDefaultTaskController.java new file mode 100644 index 0000000..09ba607 --- /dev/null +++ b/src/main/java/com/sztzjy/linkCommerce/controller/stu/SchoolDefaultTaskController.java @@ -0,0 +1,81 @@ +package com.sztzjy.linkCommerce.controller.stu; + +import com.sztzjy.linkCommerce.config.exception.UnAuthorizedException; +import com.sztzjy.linkCommerce.config.security.JwtUser; +import com.sztzjy.linkCommerce.config.security.TokenProvider; +import com.sztzjy.linkCommerce.entity.SchoolDefaultTaskInitialization; +import com.sztzjy.linkCommerce.entity.TaskAllocation; +import com.sztzjy.linkCommerce.entity.Userinfo; +import com.sztzjy.linkCommerce.mapper.UserinfoMapper; +import com.sztzjy.linkCommerce.service.SchoolDefaultTaskService; +import com.sztzjy.linkCommerce.util.ResultEntity; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Api(tags = "学校默认实训任务") +@RequestMapping("api/school-default-tasks") +@RestController +public class SchoolDefaultTaskController { + @Autowired + SchoolDefaultTaskService schoolDefaultTaskService; + @Autowired + UserinfoMapper userinfoMapper; + + @GetMapping + @ApiOperation("查询学校默认实训任务") + public ResultEntity> get(HttpServletRequest request) { + Userinfo operator = requireManagerTeacher(request); + SchoolDefaultTaskInitialization initialization = schoolDefaultTaskService.getInitialization(operator.getSchoolId()); + List tasks = schoolDefaultTaskService.getSchoolDefault(operator.getSchoolId()); + String status = initialization == null ? (tasks.isEmpty() ? "INITIALIZING" : "READY") : initialization.getStatus(); + if (tasks.isEmpty()) { + tasks = schoolDefaultTaskService.getPlatformDefault(); + } + Map data = new HashMap<>(); + data.put("status", status); + data.put("tasks", tasks); + data.put("lastError", initialization == null ? null : initialization.getLastError()); + return new ResultEntity<>(HttpStatus.OK, "查询成功", data); + } + + @PutMapping + @ApiOperation("保存学校默认实训任务") + public ResultEntity replace(@RequestBody List tasks, HttpServletRequest request) { + Userinfo operator = requireManagerTeacher(request); + SchoolDefaultTaskInitialization initialization = schoolDefaultTaskService.getInitialization(operator.getSchoolId()); + if (initialization != null && !"READY".equals(initialization.getStatus())) { + return new ResultEntity<>(HttpStatus.BAD_REQUEST, "默认实训任务尚未初始化完成"); + } + schoolDefaultTaskService.replaceSchoolDefault(operator.getSchoolId(), tasks); + return new ResultEntity<>(HttpStatus.OK, "保存成功"); + } + + @PostMapping("/retry") + @ApiOperation("重试初始化学校默认实训任务") + public ResultEntity retry(HttpServletRequest request) { + Userinfo operator = requireManagerTeacher(request); + schoolDefaultTaskService.enqueueInitialization(operator.getSchoolId()); + return new ResultEntity<>(HttpStatus.OK, "已提交初始化任务"); + } + + private Userinfo requireManagerTeacher(HttpServletRequest request) { + JwtUser currentUser = TokenProvider.getJWTUser(request); + if (currentUser == null || currentUser.getUserId() == null) { + throw new UnAuthorizedException("身份认证失败"); + } + Userinfo operator = userinfoMapper.selectByPrimaryKey(currentUser.getUserId()); + if (operator == null || !Integer.valueOf(3).equals(operator.getRole()) + || !Boolean.TRUE.equals(operator.getTeacherAdmin())) { + throw new UnAuthorizedException("仅管理员教师可维护学校默认实训任务"); + } + return operator; + } +} diff --git a/src/main/java/com/sztzjy/linkCommerce/controller/stu/TaskAllocationController.java b/src/main/java/com/sztzjy/linkCommerce/controller/stu/TaskAllocationController.java index 0076e17..afd43e2 100644 --- a/src/main/java/com/sztzjy/linkCommerce/controller/stu/TaskAllocationController.java +++ b/src/main/java/com/sztzjy/linkCommerce/controller/stu/TaskAllocationController.java @@ -8,6 +8,7 @@ import com.sztzjy.linkCommerce.entity.TeachingClassStudent; import com.sztzjy.linkCommerce.mapper.SchoolClassMapper; import com.sztzjy.linkCommerce.mapper.TaskAllocationMapper; import com.sztzjy.linkCommerce.mapper.TeachingClassStudentMapper; +import com.sztzjy.linkCommerce.service.SchoolDefaultTaskService; import com.sztzjy.linkCommerce.util.ResultEntity; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -30,11 +31,16 @@ public class TaskAllocationController { SchoolClassMapper schoolClassMapper; @Autowired TeachingClassStudentMapper teachingClassStudentMapper; + @Autowired(required = false) + SchoolDefaultTaskService schoolDefaultTaskService; @PostMapping("/selectTaskAllocationByClassId") @ApiOperation("根据班级ID查询任务分配") @AnonymousAccess public ResultEntity> selectTaskAllocationByClassId(@RequestParam String classId) { + if (schoolDefaultTaskService != null && !"999999999".equals(classId)) { + return new ResultEntity<>(HttpStatus.OK, "查询成功", schoolDefaultTaskService.resolveForTeachingClass(classId)); + } TaskAllocationExample taskAllocationExample = new TaskAllocationExample(); taskAllocationExample.createCriteria().andClassIdEqualTo(classId); taskAllocationExample.setOrderByClause("sort asc"); diff --git a/src/main/java/com/sztzjy/linkCommerce/service/SchoolDefaultTaskService.java b/src/main/java/com/sztzjy/linkCommerce/service/SchoolDefaultTaskService.java index a301da2..3561852 100644 --- a/src/main/java/com/sztzjy/linkCommerce/service/SchoolDefaultTaskService.java +++ b/src/main/java/com/sztzjy/linkCommerce/service/SchoolDefaultTaskService.java @@ -12,6 +12,8 @@ public interface SchoolDefaultTaskService { List getSchoolDefault(String schoolId); + List getPlatformDefault(); + SchoolDefaultTaskInitialization getInitialization(String schoolId); void enqueueInitialization(String schoolId); diff --git a/src/main/java/com/sztzjy/linkCommerce/service/impl/SchoolDefaultTaskServiceImpl.java b/src/main/java/com/sztzjy/linkCommerce/service/impl/SchoolDefaultTaskServiceImpl.java index 4220f42..c01b274 100644 --- a/src/main/java/com/sztzjy/linkCommerce/service/impl/SchoolDefaultTaskServiceImpl.java +++ b/src/main/java/com/sztzjy/linkCommerce/service/impl/SchoolDefaultTaskServiceImpl.java @@ -61,6 +61,11 @@ public class SchoolDefaultTaskServiceImpl implements SchoolDefaultTaskService { return listByClassId(schoolDefaultClassId(schoolId)); } + @Override + public List getPlatformDefault() { + return listByClassId(PLATFORM_DEFAULT_CLASS_ID); + } + @Override public SchoolDefaultTaskInitialization getInitialization(String schoolId) { return initializationMapper == null || StringUtils.isBlank(schoolId) diff --git a/src/test/java/com/sztzjy/linkCommerce/controller/stu/SchoolDefaultTaskControllerTest.java b/src/test/java/com/sztzjy/linkCommerce/controller/stu/SchoolDefaultTaskControllerTest.java new file mode 100644 index 0000000..2086935 --- /dev/null +++ b/src/test/java/com/sztzjy/linkCommerce/controller/stu/SchoolDefaultTaskControllerTest.java @@ -0,0 +1,80 @@ +package com.sztzjy.linkCommerce.controller.stu; + +import com.sztzjy.linkCommerce.config.exception.UnAuthorizedException; +import com.sztzjy.linkCommerce.config.security.JwtUser; +import com.sztzjy.linkCommerce.config.security.TokenProvider; +import com.sztzjy.linkCommerce.entity.TaskAllocation; +import com.sztzjy.linkCommerce.entity.Userinfo; +import com.sztzjy.linkCommerce.entity.SchoolDefaultTaskInitialization; +import com.sztzjy.linkCommerce.mapper.UserinfoMapper; +import com.sztzjy.linkCommerce.service.SchoolDefaultTaskService; +import org.junit.jupiter.api.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.test.util.ReflectionTestUtils; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +class SchoolDefaultTaskControllerTest { + + @Test + void managerTeacherCanSaveDefaultsForOwnSchool() { + SchoolDefaultTaskController controller = new SchoolDefaultTaskController(); + SchoolDefaultTaskService service = mock(SchoolDefaultTaskService.class); + UserinfoMapper userinfoMapper = mock(UserinfoMapper.class); + ReflectionTestUtils.setField(controller, "schoolDefaultTaskService", service); + ReflectionTestUtils.setField(controller, "userinfoMapper", userinfoMapper); + when(userinfoMapper.selectByPrimaryKey("teacher-1")).thenReturn(teacher("teacher-1", "school-1", true)); + SchoolDefaultTaskInitialization ready = new SchoolDefaultTaskInitialization(); + ready.setStatus("READY"); + when(service.getInitialization("school-1")).thenReturn(ready); + + controller.replace(List.of(task("学校默认任务")), requestFor("teacher-1", "school-1")); + + verify(service).replaceSchoolDefault(eq("school-1"), anyList()); + } + + @Test + void ordinaryTeacherCannotSaveDefaults() { + SchoolDefaultTaskController controller = new SchoolDefaultTaskController(); + UserinfoMapper userinfoMapper = mock(UserinfoMapper.class); + ReflectionTestUtils.setField(controller, "userinfoMapper", userinfoMapper); + when(userinfoMapper.selectByPrimaryKey("teacher-2")).thenReturn(teacher("teacher-2", "school-1", false)); + + assertThrows(UnAuthorizedException.class, + () -> controller.replace(List.of(task("学校默认任务")), requestFor("teacher-2", "school-1"))); + } + + private Userinfo teacher(String userId, String schoolId, boolean teacherAdmin) { + Userinfo user = new Userinfo(); + user.setUserId(userId); + user.setSchoolId(schoolId); + user.setRole(3); + user.setTeacherAdmin(teacherAdmin); + return user; + } + + private TaskAllocation task(String module) { + TaskAllocation task = new TaskAllocation(); + task.setModule(module); + task.setDisabledStatus((byte) 0); + return task; + } + + private MockHttpServletRequest requestFor(String userId, String schoolId) { + JwtUser user = new JwtUser(); + user.setUserId(userId); + user.setSchoolId(schoolId); + user.setRoleId(3); + user.setUsername(userId); + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setUserPrincipal(new UsernamePasswordAuthenticationToken(user, null)); + request.addHeader("Authorization", "Bearer " + TokenProvider.createToken(user)); + return request; + } +} diff --git a/src/test/java/com/sztzjy/linkCommerce/controller/stu/TaskAllocationControllerTest.java b/src/test/java/com/sztzjy/linkCommerce/controller/stu/TaskAllocationControllerTest.java index dcb8a96..18c2f16 100644 --- a/src/test/java/com/sztzjy/linkCommerce/controller/stu/TaskAllocationControllerTest.java +++ b/src/test/java/com/sztzjy/linkCommerce/controller/stu/TaskAllocationControllerTest.java @@ -4,12 +4,15 @@ import com.sztzjy.linkCommerce.entity.SchoolClass; import com.sztzjy.linkCommerce.entity.TaskAllocation; import com.sztzjy.linkCommerce.mapper.SchoolClassMapper; import com.sztzjy.linkCommerce.mapper.TaskAllocationMapper; +import com.sztzjy.linkCommerce.service.SchoolDefaultTaskService; import com.sztzjy.linkCommerce.util.ResultEntity; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.springframework.http.HttpStatus; +import org.springframework.test.util.ReflectionTestUtils; import java.util.Collections; +import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -75,6 +78,20 @@ class TaskAllocationControllerTest { assertEquals("school-1", captor.getValue().getSchoolId()); } + @Test + void taskLookupUsesSchoolDefaultResolverForTeachingClass() { + TaskAllocationController controller = controllerWithMocks(); + SchoolDefaultTaskService defaultTaskService = mock(SchoolDefaultTaskService.class); + ReflectionTestUtils.setField(controller, "schoolDefaultTaskService", defaultTaskService); + TaskAllocation allocation = new TaskAllocation(); + allocation.setModule("学校默认任务"); + when(defaultTaskService.resolveForTeachingClass("teaching-1")).thenReturn(List.of(allocation)); + + ResultEntity> result = controller.selectTaskAllocationByClassId("teaching-1"); + + assertEquals(List.of(allocation), result.getBody().getData()); + } + private TaskAllocationController controllerWithMocks() { TaskAllocationController controller = new TaskAllocationController(); controller.taskAllocationMapper = mock(TaskAllocationMapper.class);