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 d8554d6..1695c51 100644 --- a/src/main/java/com/sztzjy/linkCommerce/controller/stu/TaskAllocationController.java +++ b/src/main/java/com/sztzjy/linkCommerce/controller/stu/TaskAllocationController.java @@ -1,8 +1,10 @@ package com.sztzjy.linkCommerce.controller.stu; import com.sztzjy.linkCommerce.annotation.AnonymousAccess; +import com.sztzjy.linkCommerce.entity.SchoolClass; import com.sztzjy.linkCommerce.entity.TaskAllocation; import com.sztzjy.linkCommerce.entity.TaskAllocationExample; +import com.sztzjy.linkCommerce.mapper.SchoolClassMapper; import com.sztzjy.linkCommerce.mapper.TaskAllocationMapper; import com.sztzjy.linkCommerce.util.ResultEntity; import io.swagger.annotations.Api; @@ -21,6 +23,8 @@ import java.util.UUID; public class TaskAllocationController { @Autowired TaskAllocationMapper taskAllocationMapper; + @Autowired + SchoolClassMapper schoolClassMapper; @PostMapping("/selectTaskAllocationByClassId") @ApiOperation("根据班级ID查询任务分配") @@ -43,10 +47,17 @@ public class TaskAllocationController { @ApiOperation("编辑任务分配") @AnonymousAccess @Transactional - public ResultEntity updateTaskAllocationByClassId(@RequestBody List taskAllocationList, @RequestParam String classId, @RequestParam String schoolId) { + public ResultEntity updateTaskAllocationByClassId(@RequestBody List taskAllocationList, + @RequestParam String classId, + @RequestParam String schoolId, + @RequestParam(required = false) String userId) { if ("999999999".equals(schoolId) || "999999999".equals(classId)) { return new ResultEntity<>(HttpStatus.BAD_REQUEST, "超管数据无法修改"); } + SchoolClass schoolClass = schoolClassMapper.selectByPrimaryKey(classId); + if (schoolClass == null || userId == null || !userId.equals(schoolClass.getCreatedBy())) { + return new ResultEntity<>(HttpStatus.BAD_REQUEST, "只能分配自己创建班级的任务"); + } TaskAllocationExample taskAllocationExample = new TaskAllocationExample(); taskAllocationExample.createCriteria().andClassIdEqualTo(classId); taskAllocationMapper.deleteByExample(taskAllocationExample); @@ -59,7 +70,5 @@ public class TaskAllocationController { taskAllocationMapper.insert(taskAllocation); } return new ResultEntity<>(HttpStatus.OK, "修改成功"); - } - } diff --git a/src/main/java/com/sztzjy/linkCommerce/controller/stu/UserController.java b/src/main/java/com/sztzjy/linkCommerce/controller/stu/UserController.java index 18467ba..7893d3c 100644 --- a/src/main/java/com/sztzjy/linkCommerce/controller/stu/UserController.java +++ b/src/main/java/com/sztzjy/linkCommerce/controller/stu/UserController.java @@ -366,7 +366,8 @@ public class UserController { public ResultEntity addSchoolClass(@ApiParam("学校ID") @RequestParam String schoolId, @ApiParam("院系ID") @RequestParam String schoolFacultyId, @ApiParam("专业ID") @RequestParam String schoolMajorId, - @ApiParam("班级名称") @RequestParam String className) { + @ApiParam("班级名称") @RequestParam String className, + @RequestParam(required = false) String userId) { //先根据schoolId进行查询 如果不存在则返回 School school = schoolMapper.selectByPrimaryKey(schoolId); if (school == null) { @@ -400,6 +401,7 @@ public class UserController { schoolClass.setClassSn(schoolNamePY + "_" + classNamePY); schoolClass.setCreateTime(new Date()); schoolClass.setSchoolId(schoolId); + schoolClass.setCreatedBy(userId); int insert = schoolClassMapper.insert(schoolClass); if (insert == 1) { @@ -462,6 +464,9 @@ public class UserController { public ResultEntity deleteSchoolClass(@ApiParam("班级ID") @RequestParam String schoolClassId, @RequestParam String userId) { //先查询useriD 是否够权限 Userinfo userInfo = userinfoMapper.selectByPrimaryKey(userId); + if (userInfo == null) { + return new ResultEntity<>(HttpStatus.BAD_REQUEST, "班级管理-删除失败-权限不足"); + } if (userInfo.getRole() == 1) { int i = schoolClassMapper.deleteByPrimaryKey(schoolClassId); if (i == 1) { @@ -471,9 +476,7 @@ public class UserController { } if (userInfo.getRole() == 3) { SchoolClass schoolClass = schoolClassMapper.selectByPrimaryKey(schoolClassId); - String schoolId = schoolClass.getSchoolId(); - String userInfoSchoolId = userInfo.getSchoolId(); - if (schoolId.equals(userInfoSchoolId)) { + if (isClassOwner(schoolClass, userId)) { int i = schoolClassMapper.deleteByPrimaryKey(schoolClassId); if (i == 1) { return new ResultEntity<>(HttpStatus.OK, "班级管理-删除成功"); @@ -494,22 +497,25 @@ public class UserController { } //先查询useriD 是否够权限 Userinfo userInfo = userinfoMapper.selectByPrimaryKey(userId); + if (userInfo == null) { + return new ResultEntity<>(HttpStatus.BAD_REQUEST, "班级管理-编辑失败-权限不足"); + } if (userInfo.getRole() == 1) { - int i = schoolClassMapper.updateByPrimaryKey(schoolClass); + int i = schoolClassMapper.updateByPrimaryKeySelective(schoolClass); if (i == 1) { return new ResultEntity<>(HttpStatus.OK, "班级管理-编辑成功"); } return new ResultEntity<>(HttpStatus.BAD_REQUEST, "班级管理-编辑成功"); } if (userInfo.getRole() == 3) { - String schoolId = userInfo.getSchoolId(); SchoolClass schoolClass1 = schoolClassMapper.selectByPrimaryKey(schoolClass.getSchoolClassId()); - if (schoolId.equals(schoolClass1.getSchoolId())) { - int i = schoolClassMapper.deleteByPrimaryKey(schoolClass.getSchoolClassId()); + if (isClassOwner(schoolClass1, userId)) { + schoolClass.setCreatedBy(userId); + int i = schoolClassMapper.updateByPrimaryKeySelective(schoolClass); if (i == 1) { - return new ResultEntity<>(HttpStatus.OK, "班级管理-删除成功"); + return new ResultEntity<>(HttpStatus.OK, "班级管理-编辑成功"); } - return new ResultEntity<>(HttpStatus.BAD_REQUEST, "班级管理-删除失败"); + return new ResultEntity<>(HttpStatus.BAD_REQUEST, "班级管理-编辑失败"); } } return new ResultEntity<>(HttpStatus.BAD_REQUEST, "班级管理-编辑失败-权限不足"); @@ -561,6 +567,7 @@ public class UserController { userInfo.setSchoolFacultyId(schoolFacultyId); userInfo.setSchoolMajorId(schoolMajorId); userInfo.setSchoolClassId(null); + userInfo.setTeacherAdmin(false); userInfo.setCodeFrom("添加"); int insert = userinfoMapper.insert(userInfo); @@ -731,7 +738,8 @@ public class UserController { @ApiParam("学生姓名") @RequestParam String name, @ApiParam("学号") @RequestParam String userName, @ApiParam("电话号码") @RequestParam(required = false) String phone, - @ApiParam("电子邮箱") @RequestParam(required = false) String email) { + @ApiParam("电子邮箱") @RequestParam(required = false) String email, + @RequestParam(required = false) String userId) { //先根据schoolId进行查询 如果不存在则返回 School school = schoolMapper.selectByPrimaryKey(schoolId); if (school == null) { @@ -751,6 +759,9 @@ public class UserController { if (schoolClass == null) { return new ResultEntity<>(HttpStatus.BAD_REQUEST, "该班级不存在"); } + if (StringUtils.isNotBlank(userId) && !canOperateClass(userId, schoolClassId)) { + return new ResultEntity<>(HttpStatus.BAD_REQUEST, "只能维护自己创建班级的学生"); + } //检查userName是否已经存在 boolean b = userInfoService.existsByUserName(userName); if (b) { @@ -853,7 +864,10 @@ public class UserController { @PostMapping("/deleteStudent") @ApiOperation("学生管理-删除") @AnonymousAccess - public ResultEntity deleteStudent(@RequestParam String userId) { + public ResultEntity deleteStudent(@RequestParam String userId, @RequestParam(required = false) String operatorId) { + if (StringUtils.isNotBlank(operatorId) && !canOperateStudent(operatorId, userId)) { + return new ResultEntity<>(HttpStatus.BAD_REQUEST, "只能维护自己创建班级的学生"); + } int i = userinfoMapper.deleteByPrimaryKey(userId); if (i == 1) { return new ResultEntity<>(HttpStatus.OK, "删除成功!"); @@ -1015,6 +1029,36 @@ public class UserController { return schoolClass == null ? "" : schoolClass.getClassName(); } + @ApiOperation("开放接口,自动同步学生信息") + private boolean isClassOwner(SchoolClass schoolClass, String userId) { + return schoolClass != null + && StringUtils.isNotBlank(userId) + && StringUtils.equals(schoolClass.getCreatedBy(), userId); + } + + private boolean canOperateClass(String operatorId, String schoolClassId) { + Userinfo operator = userinfoMapper.selectByPrimaryKey(operatorId); + if (operator == null) { + return false; + } + if (Integer.valueOf(1).equals(operator.getRole())) { + return true; + } + if (!Integer.valueOf(3).equals(operator.getRole())) { + return false; + } + SchoolClass schoolClass = schoolClassMapper.selectByPrimaryKey(schoolClassId); + return isClassOwner(schoolClass, operatorId); + } + + private boolean canOperateStudent(String operatorId, String studentId) { + Userinfo student = userinfoMapper.selectByPrimaryKey(studentId); + if (student == null || !Integer.valueOf(4).equals(student.getRole())) { + return false; + } + return canOperateClass(operatorId, student.getSchoolClassId()); + } + @ApiOperation("开放接口,自动同步学生信息") @PostMapping("synchronizationStudentInfoByAuto") @AnonymousAccess diff --git a/src/main/java/com/sztzjy/linkCommerce/service/impl/ImportServiceImpl.java b/src/main/java/com/sztzjy/linkCommerce/service/impl/ImportServiceImpl.java index 215480e..8917391 100644 --- a/src/main/java/com/sztzjy/linkCommerce/service/impl/ImportServiceImpl.java +++ b/src/main/java/com/sztzjy/linkCommerce/service/impl/ImportServiceImpl.java @@ -33,6 +33,7 @@ public class ImportServiceImpl implements ImportService { userInfo.setEmail(teacherImportDTO.getEmail()); userInfo.setCreateTime(new Date()); userInfo.setRole(3); + userInfo.setTeacherAdmin(false); userInfo.setSchoolId(schoolService.selectSchoolIdBySchoolName(teacherImportDTO.getSchoolName())); userInfo.setSchoolFacultyId(schoolService.selectFacultyIdBySchoolIdAndFacultyName(userInfo.getSchoolId(),teacherImportDTO.getSchoolFacultyName())); userInfo.setSchoolMajorId(schoolService.selectMajorIdByFacultyIdAndMajorName(userInfo.getSchoolFacultyId(),teacherImportDTO.getSchoolMajorName())); diff --git a/src/test/java/com/sztzjy/linkCommerce/controller/stu/TaskAllocationControllerTest.java b/src/test/java/com/sztzjy/linkCommerce/controller/stu/TaskAllocationControllerTest.java new file mode 100644 index 0000000..47ac061 --- /dev/null +++ b/src/test/java/com/sztzjy/linkCommerce/controller/stu/TaskAllocationControllerTest.java @@ -0,0 +1,35 @@ +package com.sztzjy.linkCommerce.controller.stu; + +import com.sztzjy.linkCommerce.entity.SchoolClass; +import com.sztzjy.linkCommerce.mapper.SchoolClassMapper; +import com.sztzjy.linkCommerce.mapper.TaskAllocationMapper; +import com.sztzjy.linkCommerce.util.ResultEntity; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; + +import java.util.Collections; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class TaskAllocationControllerTest { + + @Test + void teacherCannotUpdateTaskAllocationForClassCreatedByAnotherTeacher() { + TaskAllocationController controller = new TaskAllocationController(); + controller.taskAllocationMapper = mock(TaskAllocationMapper.class); + controller.schoolClassMapper = mock(SchoolClassMapper.class); + SchoolClass schoolClass = new SchoolClass(); + schoolClass.setSchoolClassId("class-1"); + schoolClass.setCreatedBy("teacher-2"); + when(controller.schoolClassMapper.selectByPrimaryKey("class-1")).thenReturn(schoolClass); + + ResultEntity result = controller.updateTaskAllocationByClassId(Collections.emptyList(), "class-1", "school-1", "teacher-1"); + + assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode()); + verify(controller.taskAllocationMapper, never()).deleteByExample(org.mockito.ArgumentMatchers.any()); + } +} diff --git a/src/test/java/com/sztzjy/linkCommerce/controller/stu/UserControllerTeacherAdminTest.java b/src/test/java/com/sztzjy/linkCommerce/controller/stu/UserControllerTeacherAdminTest.java new file mode 100644 index 0000000..cbb1385 --- /dev/null +++ b/src/test/java/com/sztzjy/linkCommerce/controller/stu/UserControllerTeacherAdminTest.java @@ -0,0 +1,167 @@ +package com.sztzjy.linkCommerce.controller.stu; + +import com.sztzjy.linkCommerce.entity.School; +import com.sztzjy.linkCommerce.entity.SchoolClass; +import com.sztzjy.linkCommerce.entity.SchoolFaculty; +import com.sztzjy.linkCommerce.entity.SchoolMajor; +import com.sztzjy.linkCommerce.entity.Userinfo; +import com.sztzjy.linkCommerce.mapper.SchoolClassMapper; +import com.sztzjy.linkCommerce.mapper.SchoolFacultyMapper; +import com.sztzjy.linkCommerce.mapper.SchoolMapper; +import com.sztzjy.linkCommerce.mapper.SchoolMajorMapper; +import com.sztzjy.linkCommerce.mapper.UserinfoMapper; +import com.sztzjy.linkCommerce.service.UserInfoService; +import com.sztzjy.linkCommerce.util.Pinyin4jUtil; +import com.sztzjy.linkCommerce.util.ResultEntity; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.springframework.http.HttpStatus; + +import java.util.Collections; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class UserControllerTeacherAdminTest { + + @Test + void addTeacherAccountAlwaysCreatesOrdinaryTeacher() { + UserController controller = controllerWithCommonMocks(); + when(controller.userInfoService.existsByUserName("t001")).thenReturn(false); + when(controller.userinfoMapper.insert(any(Userinfo.class))).thenReturn(1); + + ResultEntity result = controller.addTeacherAccount("school-1", "school", "faculty-1", "major-1", + "major", "张老师", "t001", null, null); + + ArgumentCaptor captor = ArgumentCaptor.forClass(Userinfo.class); + verify(controller.userinfoMapper).insert(captor.capture()); + assertEquals(HttpStatus.OK, result.getStatusCode()); + assertEquals(3, captor.getValue().getRole()); + assertFalse(captor.getValue().getTeacherAdmin()); + } + + @Test + void addSchoolClassStoresCreatorTeacher() { + UserController controller = controllerWithCommonMocks(); + when(controller.schoolClassMapper.selectByExample(any())).thenReturn(Collections.emptyList()); + when(controller.schoolClassMapper.insert(any(SchoolClass.class))).thenReturn(1); + when(controller.pinyin4jUtil.convertToPinyin(any())).thenReturn("py"); + + ResultEntity result = controller.addSchoolClass("school-1", "faculty-1", "major-1", "class-1", "teacher-1"); + + ArgumentCaptor captor = ArgumentCaptor.forClass(SchoolClass.class); + verify(controller.schoolClassMapper).insert(captor.capture()); + assertEquals(HttpStatus.OK, result.getStatusCode()); + assertEquals("teacher-1", captor.getValue().getCreatedBy()); + } + + @Test + void teacherCannotDeleteClassCreatedByAnotherTeacher() { + UserController controller = controllerWithCommonMocks(); + Userinfo teacher = teacher("teacher-1"); + SchoolClass schoolClass = classCreatedBy("teacher-2"); + when(controller.userinfoMapper.selectByPrimaryKey("teacher-1")).thenReturn(teacher); + when(controller.schoolClassMapper.selectByPrimaryKey("class-1")).thenReturn(schoolClass); + + ResultEntity result = controller.deleteSchoolClass("class-1", "teacher-1"); + + assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode()); + verify(controller.schoolClassMapper, never()).deleteByPrimaryKey("class-1"); + } + + @Test + void teacherUpdatesOnlyOwnedClass() { + UserController controller = controllerWithCommonMocks(); + Userinfo teacher = teacher("teacher-1"); + SchoolClass existing = classCreatedBy("teacher-1"); + SchoolClass update = new SchoolClass(); + update.setSchoolClassId("class-1"); + update.setClassName("new-class"); + when(controller.userinfoMapper.selectByPrimaryKey("teacher-1")).thenReturn(teacher); + when(controller.schoolClassMapper.selectByPrimaryKey("class-1")).thenReturn(existing); + when(controller.schoolClassMapper.updateByPrimaryKeySelective(any(SchoolClass.class))).thenReturn(1); + + ResultEntity result = controller.updateSchoolClass(update, "teacher-1"); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + verify(controller.schoolClassMapper).updateByPrimaryKeySelective(update); + verify(controller.schoolClassMapper, never()).deleteByPrimaryKey("class-1"); + } + + @Test + void teacherCannotDeleteStudentFromClassCreatedByAnotherTeacher() { + UserController controller = controllerWithCommonMocks(); + Userinfo teacher = teacher("teacher-1"); + Userinfo student = new Userinfo(); + student.setUserId("student-1"); + student.setRole(4); + student.setSchoolClassId("class-1"); + when(controller.userinfoMapper.selectByPrimaryKey("teacher-1")).thenReturn(teacher); + when(controller.userinfoMapper.selectByPrimaryKey("student-1")).thenReturn(student); + when(controller.schoolClassMapper.selectByPrimaryKey("class-1")).thenReturn(classCreatedBy("teacher-2")); + + ResultEntity result = controller.deleteStudent("student-1", "teacher-1"); + + assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode()); + verify(controller.userinfoMapper, never()).deleteByPrimaryKey("student-1"); + } + + @Test + void teacherCanAddStudentOnlyToOwnedClass() { + UserController controller = controllerWithCommonMocks(); + when(controller.schoolClassMapper.selectByPrimaryKey("class-1")).thenReturn(classCreatedBy("teacher-1")); + when(controller.userinfoMapper.selectByPrimaryKey("teacher-1")).thenReturn(teacher("teacher-1")); + when(controller.userInfoService.existsByUserName("s001")).thenReturn(false); + when(controller.userinfoMapper.insert(any(Userinfo.class))).thenReturn(1); + + ResultEntity result = controller.addStudentAccount("school-1", "school", "faculty-1", "major-1", + "major", "class-1", "class-1", "学生", "s001", null, null, "teacher-1"); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + } + + private UserController controllerWithCommonMocks() { + UserController controller = new UserController(); + controller.schoolMapper = mock(SchoolMapper.class); + controller.schoolFacultyMapper = mock(SchoolFacultyMapper.class); + controller.schoolMajorMapper = mock(SchoolMajorMapper.class); + controller.schoolClassMapper = mock(SchoolClassMapper.class); + controller.userinfoMapper = mock(UserinfoMapper.class); + controller.userInfoService = mock(UserInfoService.class); + controller.pinyin4jUtil = mock(Pinyin4jUtil.class); + + School school = new School(); + school.setSchoolId("school-1"); + school.setSchoolName("school"); + SchoolFaculty faculty = new SchoolFaculty(); + faculty.setSchoolFacultyId("faculty-1"); + SchoolMajor major = new SchoolMajor(); + major.setSchoolMajorId("major-1"); + + when(controller.schoolMapper.selectByPrimaryKey("school-1")).thenReturn(school); + when(controller.schoolFacultyMapper.selectByPrimaryKey("faculty-1")).thenReturn(faculty); + when(controller.schoolMajorMapper.selectByPrimaryKey("major-1")).thenReturn(major); + return controller; + } + + private Userinfo teacher(String userId) { + Userinfo teacher = new Userinfo(); + teacher.setUserId(userId); + teacher.setRole(3); + teacher.setSchoolId("school-1"); + return teacher; + } + + private SchoolClass classCreatedBy(String teacherId) { + SchoolClass schoolClass = new SchoolClass(); + schoolClass.setSchoolClassId("class-1"); + schoolClass.setSchoolId("school-1"); + schoolClass.setCreatedBy(teacherId); + return schoolClass; + } +} diff --git a/src/test/java/com/sztzjy/linkCommerce/service/impl/ImportServiceImplTest.java b/src/test/java/com/sztzjy/linkCommerce/service/impl/ImportServiceImplTest.java new file mode 100644 index 0000000..6952a71 --- /dev/null +++ b/src/test/java/com/sztzjy/linkCommerce/service/impl/ImportServiceImplTest.java @@ -0,0 +1,39 @@ +package com.sztzjy.linkCommerce.service.impl; + +import com.sztzjy.linkCommerce.entity.Userinfo; +import com.sztzjy.linkCommerce.entity.importDto.TeacherImportDTO; +import com.sztzjy.linkCommerce.mapper.UserinfoMapper; +import com.sztzjy.linkCommerce.service.SchoolService; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; + +import java.util.Collections; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +class ImportServiceImplTest { + + @Test + void teacherImportCreatesOrdinaryTeacher() { + ImportServiceImpl service = new ImportServiceImpl(); + service.schoolService = mock(SchoolService.class); + service.userInfoMapper = mock(UserinfoMapper.class); + when(service.schoolService.selectSchoolIdBySchoolName(any())).thenReturn("school-1"); + when(service.schoolService.selectFacultyIdBySchoolIdAndFacultyName(any(), any())).thenReturn("faculty-1"); + when(service.schoolService.selectMajorIdByFacultyIdAndMajorName(any(), any())).thenReturn("major-1"); + + TeacherImportDTO row = new TeacherImportDTO(); + row.setTeacherName("张老师"); + row.setUserName("t001"); + + service.processTeacherImport(Collections.singletonList(row)); + + ArgumentCaptor captor = ArgumentCaptor.forClass(Userinfo.class); + verify(service.userInfoMapper).insert(captor.capture()); + assertFalse(captor.getValue().getTeacherAdmin()); + } +}