diff --git a/src/main/java/com/sztzjy/linkCommerce/controller/stu/TeaScoreController.java b/src/main/java/com/sztzjy/linkCommerce/controller/stu/TeaScoreController.java index 285a6d6..e3174c3 100644 --- a/src/main/java/com/sztzjy/linkCommerce/controller/stu/TeaScoreController.java +++ b/src/main/java/com/sztzjy/linkCommerce/controller/stu/TeaScoreController.java @@ -33,6 +33,7 @@ import java.math.BigDecimal; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -72,6 +73,16 @@ public class TeaScoreController { } } + @GetMapping("/accessibleTeachingClasses") + @ApiOperation("成绩中心可查看的教学班列表") + public ResultEntity> accessibleTeachingClasses(HttpServletRequest request) { + try { + return new ResultEntity<>(HttpStatus.OK, "查询成功", teacherScoreService.listAccessibleClasses(currentUser(request))); + } catch (com.sztzjy.linkCommerce.config.exception.handler.ServiceException e) { + return new ResultEntity<>(e.getCode(), e.getMessage()); + } + } + @PostMapping("/selectTeachingClassWeight") @ApiOperation("查询本人教学班六模块权重") public ResultEntity selectTeachingClassWeight(@RequestParam String teachingClassId, @@ -121,13 +132,12 @@ public class TeaScoreController { @RequestParam Integer index, @RequestParam Integer size, HttpServletRequest request) { JwtUser teacher = currentUser(request); - PageHelper.startPage(index, size); StuRankExample stuRankExample = new StuRankExample(); StuRankExample.Criteria criteria = stuRankExample.createCriteria(); criteria.andSchoolIdEqualTo(teacher.getSchoolId()); String nowDate = scoreRankService.getNowDate(); criteria.andUpdateTimeEqualTo(nowDate); - applyOwnedTeacherClassCriteria(criteria, teacher, classId); + applyAccessibleTeacherClassCriteria(criteria, teacher, classId); if(StringUtil.isNotEmpty(userName)){ criteria.andUsernameEqualTo(userName); } @@ -135,6 +145,7 @@ public class TeaScoreController { criteria.andNameEqualTo(name); } stuRankExample.setOrderByClause("stu_rank asc"); + PageHelper.startPage(index, size); List stuRankList = stuRankMapper.selectByExample(stuRankExample); enrichTrainingProgress(stuRankList, classId); PageInfo rankPageInfo = new PageInfo<>(stuRankList); @@ -144,7 +155,6 @@ public class TeaScoreController { // Retained for existing direct controller tests; HTTP requests always use the JWT-scoped overload above. public ResultEntity> selectStuRankAndScore(String classId, String userName, String name, String schoolId, Integer index, Integer size) { - PageHelper.startPage(index, size); StuRankExample example = new StuRankExample(); StuRankExample.Criteria criteria = example.createCriteria(); criteria.andSchoolIdEqualTo(schoolId); @@ -157,6 +167,7 @@ public class TeaScoreController { criteria.andNameEqualTo(name); } example.setOrderByClause("stu_rank asc"); + PageHelper.startPage(index, size); List rows = stuRankMapper.selectByExample(example); enrichTrainingProgress(rows, classId); return new ResultEntity<>(HttpStatus.OK, "查询学生成绩和排名成功", new PageInfo<>(rows)); @@ -170,7 +181,7 @@ public class TeaScoreController { @RequestParam(required = false) String classId, HttpServletRequest request) { JwtUser teacher = currentUser(request); - SchoolClass teachingClass = teacherScoreService.requireOwnedClass(teacher, classId); + SchoolClass teachingClass = teacherScoreService.requireAccessibleClass(teacher, classId); if (teachingClassStudentMapper.countByStudentUserIdAndTeachingClassId(userId, teachingClass.getSchoolClassId()) == 0) { return new ResultEntity<>(HttpStatus.FORBIDDEN, "无权查看该学生成绩"); } @@ -299,7 +310,7 @@ public class TeaScoreController { criteria.andSchoolIdEqualTo(teacher.getSchoolId()); String nowDate = scoreRankService.getNowDate(); criteria.andUpdateTimeEqualTo(nowDate); - applyOwnedTeacherClassCriteria(criteria, teacher, classId); + applyAccessibleTeacherClassCriteria(criteria, teacher, classId); if(StringUtil.isNotEmpty(userName)){ criteria.andUsernameEqualTo(userName); } @@ -312,10 +323,10 @@ public class TeaScoreController { //导出的表名 String title = "学生成绩"; //表中第一行表头字段 - String[] headers = {"学号", "学生姓名", "班级名称", "排名", "参考成绩", "实训进度"}; + String[] headers = {"学号", "学生姓名", "班级名称", "排名", "参考成绩", "老师评分", "实训进度"}; //具体需要写入excel需要哪些字段,这些字段取自UserReward类,也就是上面的实际数据结果集的泛型 - List listColumn = Arrays.asList("username", "name", "className", "stuRank", "score", "trainingProgress"); + List listColumn = Arrays.asList("username", "name", "className", "stuRank", "score", "teacherScore", "trainingProgress"); try { FilePortUtil.exportExcel(response, title, headers, stuRankList, listColumn); } catch (Exception e) { @@ -346,9 +357,22 @@ public class TeaScoreController { if (ranks == null || ranks.isEmpty()) { return; } + Map classTeacherScores = Collections.emptyMap(); + if (teacherScoreService != null && StringUtils.isNotBlank(requestedClassId)) { + Map loadedScores = teacherScoreService.getTeacherScores(requestedClassId, ranks.stream() + .map(StuRank::getUserId) + .filter(StringUtils::isNotBlank) + .distinct() + .collect(Collectors.toList())); + if (loadedScores != null) { + classTeacherScores = loadedScores; + } + } for (StuRank rank : ranks) { String classId = StringUtils.isNotBlank(requestedClassId) ? requestedClassId : rank.getSchoolClassId(); - rank.setTeacherScore(teacherScoreService.getTeacherScore(classId, rank.getUserId())); + rank.setTeacherScore(StringUtils.isNotBlank(requestedClassId) + ? classTeacherScores.get(rank.getUserId()) + : teacherScoreService == null ? null : teacherScoreService.getTeacherScore(classId, rank.getUserId())); Set enabledModules = resolveEnabledTaskModules(classId); int totalTaskCount = enabledModules.size(); rank.setTotalTaskCount(totalTaskCount); @@ -429,14 +453,14 @@ public class TeaScoreController { } } - private void applyOwnedTeacherClassCriteria(StuRankExample.Criteria criteria, JwtUser teacher, String classId) { - List ownedClasses; + private void applyAccessibleTeacherClassCriteria(StuRankExample.Criteria criteria, JwtUser teacher, String classId) { + List accessibleClasses; if (StringUtils.isNotBlank(classId)) { - ownedClasses = Collections.singletonList(teacherScoreService.requireOwnedClass(teacher, classId)); + accessibleClasses = Collections.singletonList(teacherScoreService.requireAccessibleClass(teacher, classId)); } else { - ownedClasses = teacherScoreService.listOwnedClasses(teacher); + accessibleClasses = teacherScoreService.listAccessibleClasses(teacher); } - List studentIds = ownedClasses.stream() + List studentIds = accessibleClasses.stream() .flatMap(schoolClass -> teachingClassStudentMapper.selectByTeachingClassId(schoolClass.getSchoolClassId()).stream()) .map(TeachingClassStudent::getStudentUserId) .filter(StringUtils::isNotBlank) diff --git a/src/main/java/com/sztzjy/linkCommerce/mapper/TeachingClassTeacherScoreMapper.java b/src/main/java/com/sztzjy/linkCommerce/mapper/TeachingClassTeacherScoreMapper.java index 1d26b85..2c4bcd0 100644 --- a/src/main/java/com/sztzjy/linkCommerce/mapper/TeachingClassTeacherScoreMapper.java +++ b/src/main/java/com/sztzjy/linkCommerce/mapper/TeachingClassTeacherScoreMapper.java @@ -4,9 +4,13 @@ import com.sztzjy.linkCommerce.entity.TeachingClassTeacherScore; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; +import java.util.List; + @Mapper public interface TeachingClassTeacherScoreMapper { TeachingClassTeacherScore selectByClassAndStudent(@Param("teachingClassId") String teachingClassId, @Param("studentUserId") String studentUserId); + List selectByClassAndStudents(@Param("teachingClassId") String teachingClassId, + @Param("studentUserIds") List studentUserIds); int upsert(TeachingClassTeacherScore record); } diff --git a/src/main/java/com/sztzjy/linkCommerce/service/TeacherScoreService.java b/src/main/java/com/sztzjy/linkCommerce/service/TeacherScoreService.java index e3b5acd..b16ae7d 100644 --- a/src/main/java/com/sztzjy/linkCommerce/service/TeacherScoreService.java +++ b/src/main/java/com/sztzjy/linkCommerce/service/TeacherScoreService.java @@ -7,13 +7,17 @@ import com.sztzjy.linkCommerce.entity.TeachingClassTeacherScore; import java.math.BigDecimal; import java.util.List; +import java.util.Map; public interface TeacherScoreService { List listOwnedClasses(JwtUser teacher); + List listAccessibleClasses(JwtUser teacher); SchoolClass requireOwnedClass(JwtUser teacher, String teachingClassId); + SchoolClass requireAccessibleClass(JwtUser teacher, String teachingClassId); TeachingClassScoreWeight getOrCreateWeight(JwtUser teacher, String teachingClassId); TeachingClassScoreWeight saveWeight(JwtUser teacher, String teachingClassId, TeachingClassScoreWeight weight); BigDecimal getTeacherScore(String teachingClassId, String studentUserId); + Map getTeacherScores(String teachingClassId, List studentUserIds); TeachingClassTeacherScore saveTeacherScore(JwtUser teacher, String teachingClassId, String studentUserId, BigDecimal score); } diff --git a/src/main/java/com/sztzjy/linkCommerce/service/impl/TeacherScoreServiceImpl.java b/src/main/java/com/sztzjy/linkCommerce/service/impl/TeacherScoreServiceImpl.java index c94d3ae..b2c5280 100644 --- a/src/main/java/com/sztzjy/linkCommerce/service/impl/TeacherScoreServiceImpl.java +++ b/src/main/java/com/sztzjy/linkCommerce/service/impl/TeacherScoreServiceImpl.java @@ -6,10 +6,12 @@ import com.sztzjy.linkCommerce.entity.SchoolClass; import com.sztzjy.linkCommerce.entity.SchoolClassExample; import com.sztzjy.linkCommerce.entity.TeachingClassScoreWeight; import com.sztzjy.linkCommerce.entity.TeachingClassTeacherScore; +import com.sztzjy.linkCommerce.entity.Userinfo; import com.sztzjy.linkCommerce.mapper.SchoolClassMapper; import com.sztzjy.linkCommerce.mapper.TeachingClassScoreWeightMapper; import com.sztzjy.linkCommerce.mapper.TeachingClassStudentMapper; import com.sztzjy.linkCommerce.mapper.TeachingClassTeacherScoreMapper; +import com.sztzjy.linkCommerce.mapper.UserinfoMapper; import com.sztzjy.linkCommerce.service.TeacherScoreService; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -19,7 +21,9 @@ import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; @Service public class TeacherScoreServiceImpl implements TeacherScoreService { @@ -31,6 +35,8 @@ public class TeacherScoreServiceImpl implements TeacherScoreService { TeachingClassTeacherScoreMapper teacherScoreMapper; @Autowired TeachingClassStudentMapper teachingClassStudentMapper; + @Autowired + UserinfoMapper userinfoMapper; @Override public List listOwnedClasses(JwtUser teacher) { @@ -38,6 +44,20 @@ public class TeacherScoreServiceImpl implements TeacherScoreService { SchoolClassExample example = new SchoolClassExample(); example.createCriteria().andSchoolIdEqualTo(teacher.getSchoolId()) .andCreatedByEqualTo(teacher.getUserId()).andClassTypeEqualTo("TEACHING"); + example.setOrderByClause("create_time desc"); + List rows = schoolClassMapper.selectByExample(example); + return rows == null ? Collections.emptyList() : rows; + } + + @Override + public List listAccessibleClasses(JwtUser teacher) { + requireTeacher(teacher); + if (!isTeacherAdmin(teacher)) { + return listOwnedClasses(teacher); + } + SchoolClassExample example = new SchoolClassExample(); + example.createCriteria().andSchoolIdEqualTo(teacher.getSchoolId()).andClassTypeEqualTo("TEACHING"); + example.setOrderByClause("create_time desc"); List rows = schoolClassMapper.selectByExample(example); return rows == null ? Collections.emptyList() : rows; } @@ -57,6 +77,23 @@ public class TeacherScoreServiceImpl implements TeacherScoreService { return schoolClass; } + @Override + public SchoolClass requireAccessibleClass(JwtUser teacher, String teachingClassId) { + requireTeacher(teacher); + if (StringUtils.isBlank(teachingClassId)) { + throw new ServiceException(HttpStatus.BAD_REQUEST, "请选择教学班"); + } + SchoolClass schoolClass = schoolClassMapper.selectByPrimaryKey(teachingClassId); + boolean sameSchoolTeachingClass = schoolClass != null + && "TEACHING".equals(schoolClass.getClassType()) + && StringUtils.equals(teacher.getSchoolId(), schoolClass.getSchoolId()); + if (!sameSchoolTeachingClass || (!isTeacherAdmin(teacher) + && !StringUtils.equals(teacher.getUserId(), schoolClass.getCreatedBy()))) { + throw new ServiceException(HttpStatus.FORBIDDEN, "无权访问该教学班成绩"); + } + return schoolClass; + } + @Override public TeachingClassScoreWeight getOrCreateWeight(JwtUser teacher, String teachingClassId) { requireOwnedClass(teacher, teachingClassId); @@ -98,6 +135,21 @@ public class TeacherScoreServiceImpl implements TeacherScoreService { return stored == null ? null : stored.getTeacherScore(); } + @Override + public Map getTeacherScores(String teachingClassId, List studentUserIds) { + if (StringUtils.isBlank(teachingClassId) || studentUserIds == null || studentUserIds.isEmpty()) { + return Collections.emptyMap(); + } + List rows = teacherScoreMapper + .selectByClassAndStudents(teachingClassId, studentUserIds); + Map scores = new LinkedHashMap<>(); + for (TeachingClassTeacherScore row : rows == null + ? Collections.emptyList() : rows) { + scores.put(row.getStudentUserId(), row.getTeacherScore()); + } + return scores; + } + @Override public TeachingClassTeacherScore saveTeacherScore(JwtUser teacher, String teachingClassId, String studentUserId, BigDecimal score) { @@ -145,4 +197,13 @@ public class TeacherScoreServiceImpl implements TeacherScoreService { throw new ServiceException(HttpStatus.FORBIDDEN, "仅教师可访问成绩中心"); } } + + private boolean isTeacherAdmin(JwtUser teacher) { + if (teacher == null || userinfoMapper == null) { + return false; + } + Userinfo userinfo = userinfoMapper.selectByPrimaryKey(teacher.getUserId()); + return userinfo != null && Boolean.TRUE.equals(userinfo.getTeacherAdmin()) + && StringUtils.equals(teacher.getSchoolId(), userinfo.getSchoolId()); + } } diff --git a/src/main/resources/mappers/TeachingClassTeacherScoreMapper.xml b/src/main/resources/mappers/TeachingClassTeacherScoreMapper.xml index 041d1fc..531ac49 100644 --- a/src/main/resources/mappers/TeachingClassTeacherScoreMapper.xml +++ b/src/main/resources/mappers/TeachingClassTeacherScoreMapper.xml @@ -16,6 +16,16 @@ and student_user_id = #{studentUserId} + + insert into teaching_class_teacher_score (teaching_class_id, student_user_id, teacher_score, scored_by, update_time) diff --git a/src/test/java/com/sztzjy/linkCommerce/config/TeachingClassTeacherScoreSchemaInitializerTest.java b/src/test/java/com/sztzjy/linkCommerce/config/TeachingClassTeacherScoreSchemaInitializerTest.java new file mode 100644 index 0000000..c0ff713 --- /dev/null +++ b/src/test/java/com/sztzjy/linkCommerce/config/TeachingClassTeacherScoreSchemaInitializerTest.java @@ -0,0 +1,27 @@ +package com.sztzjy.linkCommerce.config; + +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.springframework.jdbc.core.JdbcTemplate; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +class TeachingClassTeacherScoreSchemaInitializerTest { + @Test + void createsClassStudentTeacherScoreTable() { + JdbcTemplate jdbcTemplate = mock(JdbcTemplate.class); + TeachingClassTeacherScoreSchemaInitializer initializer = + new TeachingClassTeacherScoreSchemaInitializer(jdbcTemplate); + + initializer.initialize(); + + ArgumentCaptor statement = ArgumentCaptor.forClass(String.class); + verify(jdbcTemplate).execute(statement.capture()); + String ddl = statement.getValue(); + assertTrue(ddl.startsWith("CREATE TABLE IF NOT EXISTS teaching_class_teacher_score")); + assertTrue(ddl.contains("teacher_score decimal(5,2) NOT NULL")); + assertTrue(ddl.contains("PRIMARY KEY (teaching_class_id, student_user_id)")); + } +} diff --git a/src/test/java/com/sztzjy/linkCommerce/controller/stu/TeaScoreControllerScopeTest.java b/src/test/java/com/sztzjy/linkCommerce/controller/stu/TeaScoreControllerScopeTest.java index 346b913..23e91cc 100644 --- a/src/test/java/com/sztzjy/linkCommerce/controller/stu/TeaScoreControllerScopeTest.java +++ b/src/test/java/com/sztzjy/linkCommerce/controller/stu/TeaScoreControllerScopeTest.java @@ -13,8 +13,7 @@ import java.util.Collections; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; class TeaScoreControllerScopeTest { @Test @@ -38,5 +37,32 @@ class TeaScoreControllerScopeTest { ResultEntity result = controller.ownedTeachingClasses(new MockHttpServletRequest()); assertEquals(HttpStatus.OK, result.getStatusCode()); + verify(service).listOwnedClasses(any()); + } + + @Test + void accessibleTeachingClassesUsesAuthenticatedTeacherScope() { + TeaScoreController controller = controllerForTeacher(); + TeacherScoreService service = mock(TeacherScoreService.class); + ReflectionTestUtils.setField(controller, "teacherScoreService", service); + when(service.listAccessibleClasses(any())).thenReturn(Collections.emptyList()); + + ResultEntity result = controller.accessibleTeachingClasses(new MockHttpServletRequest()); + + assertEquals(HttpStatus.OK, result.getStatusCode()); + verify(service).listAccessibleClasses(any()); + } + + private TeaScoreController controllerForTeacher() { + return new TeaScoreController() { + @Override + protected JwtUser currentUser(javax.servlet.http.HttpServletRequest request) { + JwtUser teacher = new JwtUser(); + teacher.setUserId("teacher-1"); + teacher.setSchoolId("school-1"); + teacher.setRoleId(3); + return teacher; + } + }; } } diff --git a/src/test/java/com/sztzjy/linkCommerce/service/impl/TeacherScoreServiceImplTest.java b/src/test/java/com/sztzjy/linkCommerce/service/impl/TeacherScoreServiceImplTest.java index a500be4..e9ad581 100644 --- a/src/test/java/com/sztzjy/linkCommerce/service/impl/TeacherScoreServiceImplTest.java +++ b/src/test/java/com/sztzjy/linkCommerce/service/impl/TeacherScoreServiceImplTest.java @@ -5,10 +5,12 @@ import com.sztzjy.linkCommerce.config.security.JwtUser; import com.sztzjy.linkCommerce.entity.SchoolClass; import com.sztzjy.linkCommerce.entity.TeachingClassScoreWeight; import com.sztzjy.linkCommerce.entity.TeachingClassTeacherScore; +import com.sztzjy.linkCommerce.entity.Userinfo; import com.sztzjy.linkCommerce.mapper.SchoolClassMapper; import com.sztzjy.linkCommerce.mapper.TeachingClassScoreWeightMapper; import com.sztzjy.linkCommerce.mapper.TeachingClassStudentMapper; import com.sztzjy.linkCommerce.mapper.TeachingClassTeacherScoreMapper; +import com.sztzjy.linkCommerce.mapper.UserinfoMapper; import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; import org.springframework.test.util.ReflectionTestUtils; @@ -16,6 +18,7 @@ import org.springframework.test.util.ReflectionTestUtils; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -55,15 +58,39 @@ class TeacherScoreServiceImplTest { } @Test - void savesTeacherScoreForStudentInOwnedTeachingClass() { + void teacherAdminListsAndCanReadAllTeachingClassesInSameSchool() { + TeacherScoreServiceImpl service = new TeacherScoreServiceImpl(); + SchoolClassMapper classMapper = mock(SchoolClassMapper.class); + UserinfoMapper userinfoMapper = mock(UserinfoMapper.class); + ReflectionTestUtils.setField(service, "schoolClassMapper", classMapper); + ReflectionTestUtils.setField(service, "userinfoMapper", userinfoMapper); + JwtUser manager = teacher("teacher-admin", "school-1"); + Userinfo managerInfo = new Userinfo(); + managerInfo.setUserId("teacher-admin"); + managerInfo.setSchoolId("school-1"); + managerInfo.setTeacherAdmin(true); + SchoolClass otherTeacherClass = classRow("class-2", "teacher-2", "school-1"); + when(userinfoMapper.selectByPrimaryKey("teacher-admin")).thenReturn(managerInfo); + when(classMapper.selectByExample(any())).thenReturn(java.util.Collections.singletonList(otherTeacherClass)); + when(classMapper.selectByPrimaryKey("class-2")).thenReturn(otherTeacherClass); + + assertEquals(1, service.listAccessibleClasses(manager).size()); + assertEquals("class-2", service.requireAccessibleClass(manager, "class-2").getSchoolClassId()); + } + + @Test + void classOwnerCanSaveTeacherScoreButManagerCannotScoreAnotherTeachersClass() { TeacherScoreServiceImpl service = new TeacherScoreServiceImpl(); SchoolClassMapper classMapper = mock(SchoolClassMapper.class); TeachingClassStudentMapper memberMapper = mock(TeachingClassStudentMapper.class); TeachingClassTeacherScoreMapper scoreMapper = mock(TeachingClassTeacherScoreMapper.class); + UserinfoMapper userinfoMapper = mock(UserinfoMapper.class); ReflectionTestUtils.setField(service, "schoolClassMapper", classMapper); ReflectionTestUtils.setField(service, "teachingClassStudentMapper", memberMapper); ReflectionTestUtils.setField(service, "teacherScoreMapper", scoreMapper); - when(classMapper.selectByPrimaryKey("class-1")).thenReturn(classRow("class-1", "teacher-1", "school-1")); + ReflectionTestUtils.setField(service, "userinfoMapper", userinfoMapper); + SchoolClass ownerClass = classRow("class-1", "teacher-1", "school-1"); + when(classMapper.selectByPrimaryKey("class-1")).thenReturn(ownerClass); when(memberMapper.countByStudentUserIdAndTeachingClassId("student-1", "class-1")).thenReturn(1L); TeachingClassTeacherScore saved = service.saveTeacherScore( @@ -72,6 +99,15 @@ class TeacherScoreServiceImplTest { assertEquals(new java.math.BigDecimal("88.13"), saved.getTeacherScore()); assertEquals("teacher-1", saved.getScoredBy()); verify(scoreMapper).upsert(saved); + + Userinfo managerInfo = new Userinfo(); + managerInfo.setUserId("teacher-admin"); + managerInfo.setSchoolId("school-1"); + managerInfo.setTeacherAdmin(true); + when(userinfoMapper.selectByPrimaryKey("teacher-admin")).thenReturn(managerInfo); + ServiceException error = assertThrows(ServiceException.class, () -> service.saveTeacherScore( + teacher("teacher-admin", "school-1"), "class-1", "student-1", new java.math.BigDecimal("90"))); + assertEquals(HttpStatus.FORBIDDEN, error.getCode()); } @Test