+54
@@ -5,7 +5,10 @@ import com.yunhai.bschclassmanage.Repository.SchInfoRepository;
|
|||||||
import com.yunhai.bschclassmanage.config.Config;
|
import com.yunhai.bschclassmanage.config.Config;
|
||||||
import com.yunhai.bschclassmanage.entity.SchClass;
|
import com.yunhai.bschclassmanage.entity.SchClass;
|
||||||
import com.yunhai.bschclassmanage.model.vo.sch.OapiClassVO;
|
import com.yunhai.bschclassmanage.model.vo.sch.OapiClassVO;
|
||||||
|
import com.yunhai.bschclassmanage.model.vo.sch.OapiGradeNameVO;
|
||||||
import com.yunhai.bschclassmanage.service.IBaseSchsystemGradeService;
|
import com.yunhai.bschclassmanage.service.IBaseSchsystemGradeService;
|
||||||
|
import com.yunhai.bschclassmanage.service.IBaseSchsystemService;
|
||||||
|
import com.yunhai.bschclassmanage.service.ISchBinSchsystemService;
|
||||||
import com.yunhai.bschclassmanage.service.ISchClassService;
|
import com.yunhai.bschclassmanage.service.ISchClassService;
|
||||||
import com.yunhai.bschclassmanage.service.ISchTeacherService;
|
import com.yunhai.bschclassmanage.service.ISchTeacherService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@@ -33,6 +36,10 @@ public class OapiSchClassController {
|
|||||||
private ISchTeacherService schTeacherService;
|
private ISchTeacherService schTeacherService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private IBaseSchsystemGradeService baseSchsystemGradeService;
|
private IBaseSchsystemGradeService baseSchsystemGradeService;
|
||||||
|
@Autowired
|
||||||
|
private ISchBinSchsystemService schBinSchsystemService;
|
||||||
|
@Autowired
|
||||||
|
private IBaseSchsystemService baseSchsystemService;
|
||||||
|
|
||||||
@GetMapping("getClassInfo")
|
@GetMapping("getClassInfo")
|
||||||
@Operation(summary = "获取班级信息", description = "按班级ID(班级组ID)查询班级信息,含班主任/副班主任ID与姓名;可传 schId 精确到学校")
|
@Operation(summary = "获取班级信息", description = "按班级ID(班级组ID)查询班级信息,含班主任/副班主任ID与姓名;可传 schId 精确到学校")
|
||||||
@@ -77,6 +84,53 @@ public class OapiSchClassController {
|
|||||||
return ResponseEntity.ok(toVOList(classes));
|
return ResponseEntity.ok(toVOList(classes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("getGradeName")
|
||||||
|
@Operation(summary = "获取年级名称", description = "按学校ID+入学年份+学段(1小学/2初中/3高中)查询学校年级字典名称(gradeNickname);"
|
||||||
|
+ "年份按当前学年与年级序换算(与班级导入同口径),无匹配学制/年级返回 null,由调用方自行降级")
|
||||||
|
public ResponseEntity<OapiGradeNameVO> getGradeName(@RequestParam("schId") Integer schId,
|
||||||
|
@RequestParam("year") Integer year,
|
||||||
|
@RequestParam(value = "stage", required = false) Integer stage) {
|
||||||
|
if (schId == null || year == null) {
|
||||||
|
return ResponseEntity.ok(null);
|
||||||
|
}
|
||||||
|
// 学段 → 学制:按学校各学制记录的学段名(小学/初中/高中)匹配;不传 stage 时不限学段
|
||||||
|
String stageName = stage == null ? null
|
||||||
|
: stage == 1 ? "小学" : stage == 2 ? "初中" : stage == 3 ? "高中" : null;
|
||||||
|
List<Integer> targetSystems = new ArrayList<>();
|
||||||
|
if (stageName == null) {
|
||||||
|
targetSystems.addAll(schBinSchsystemService.getSchBinSchsystemIds(schId));
|
||||||
|
} else {
|
||||||
|
for (Integer schsystemId : schBinSchsystemService.getSchBinSchsystemIds(schId)) {
|
||||||
|
try {
|
||||||
|
String name = baseSchsystemService.getAcademicStageName(schsystemId);
|
||||||
|
if (name != null && name.contains(stageName)) {
|
||||||
|
targetSystems.add(schsystemId);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 单个学制学段名缺失(学制未找到等)跳过,不影响其余学制
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Integer schsystemId : targetSystems) {
|
||||||
|
// 年级→入学年份(当前学年-年级偏移,与班级导入 getNowYearGradeMap 同口径);再查字典别称
|
||||||
|
Map<Integer, Integer> yearMap = baseSchsystemGradeService.getNowYearGradeMap(schId, schsystemId);
|
||||||
|
if (yearMap == null || yearMap.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Map<Integer, String> nameMap = baseSchsystemGradeService.getGradeNameMap(schId, schsystemId, null);
|
||||||
|
for (Map.Entry<Integer, Integer> e : yearMap.entrySet()) {
|
||||||
|
if (year.equals(e.getValue()) && nameMap.get(e.getKey()) != null) {
|
||||||
|
OapiGradeNameVO vo = new OapiGradeNameVO();
|
||||||
|
vo.setGradeId(e.getKey());
|
||||||
|
vo.setGradeName(nameMap.get(e.getKey()));
|
||||||
|
vo.setYear(year);
|
||||||
|
return ResponseEntity.ok(vo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ResponseEntity.ok(null);
|
||||||
|
}
|
||||||
|
|
||||||
/** 批量转 VO:按学校分组后统一回填学校名/年级名/班主任姓名 */
|
/** 批量转 VO:按学校分组后统一回填学校名/年级名/班主任姓名 */
|
||||||
private List<OapiClassVO> toVOList(List<SchClass> classes) {
|
private List<OapiClassVO> toVOList(List<SchClass> classes) {
|
||||||
if (classes == null || classes.isEmpty()) {
|
if (classes == null || classes.isEmpty()) {
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ public class SyncClassDTO {
|
|||||||
/** 班号 1..N(=aca_assign_class.sort_order,决定 code 尾号与 sch_class.sort) */
|
/** 班号 1..N(=aca_assign_class.sort_order,决定 code 尾号与 sch_class.sort) */
|
||||||
private Integer sort;
|
private Integer sort;
|
||||||
|
|
||||||
/** 分班侧班名(可空;非空时写 cname 别名,name 统一按规则生成 sort+"班") */
|
/** 分班侧班名(可空;非空时写 cname 别名,name 统一按规则生成 sort+"班")。
|
||||||
|
* 分班侧口径(2026-10-21):仅语义班名(阳光班/苹果班)才传,序号生成的班名(1班/2班)不传,cname 留空 */
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
/** 班主任(平台教师 UserTeaSerID,可空)→ first_teacher_id */
|
/** 班主任(平台教师 UserTeaSerID,可空)→ first_teacher_id */
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.yunhai.bschclassmanage.model.vo.sch;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 年级名称 VO(开放接口 getGradeName 返回):学校年级字典名称 + 对应年级编码与入学年份。
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class OapiGradeNameVO {
|
||||||
|
|
||||||
|
@Schema(description = "年级编码(K12 年级ID)")
|
||||||
|
private Integer gradeId;
|
||||||
|
|
||||||
|
@Schema(description = "年级名称(学校年级字典别称,如 小一/一年级/初一)")
|
||||||
|
private String gradeName;
|
||||||
|
|
||||||
|
@Schema(description = "入学年份")
|
||||||
|
private Integer year;
|
||||||
|
}
|
||||||
+114
@@ -0,0 +1,114 @@
|
|||||||
|
package com.yunhai.bschclassmanage.controller.oapi.sch;
|
||||||
|
|
||||||
|
import com.yunhai.bschclassmanage.model.vo.sch.OapiGradeNameVO;
|
||||||
|
import com.yunhai.bschclassmanage.service.IBaseSchsystemGradeService;
|
||||||
|
import com.yunhai.bschclassmanage.service.IBaseSchsystemService;
|
||||||
|
import com.yunhai.bschclassmanage.service.ISchBinSchsystemService;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
/** getGradeName 开放接口单测:学段→学制匹配、学年反查年级字典名、无匹配返回 null */
|
||||||
|
class OapiGetGradeNameTest {
|
||||||
|
|
||||||
|
private OapiSchClassController controller;
|
||||||
|
private ISchBinSchsystemService schBinSchsystemService;
|
||||||
|
private IBaseSchsystemService baseSchsystemService;
|
||||||
|
private IBaseSchsystemGradeService baseSchsystemGradeService;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
controller = new OapiSchClassController();
|
||||||
|
schBinSchsystemService = Mockito.mock(ISchBinSchsystemService.class);
|
||||||
|
baseSchsystemService = Mockito.mock(IBaseSchsystemService.class);
|
||||||
|
baseSchsystemGradeService = Mockito.mock(IBaseSchsystemGradeService.class);
|
||||||
|
ReflectionTestUtils.setField(controller, "schClassRepository",
|
||||||
|
Mockito.mock(com.yunhai.bschclassmanage.Repository.SchClassRepository.class));
|
||||||
|
ReflectionTestUtils.setField(controller, "schInfoRepository",
|
||||||
|
Mockito.mock(com.yunhai.bschclassmanage.Repository.SchInfoRepository.class));
|
||||||
|
ReflectionTestUtils.setField(controller, "schClassService",
|
||||||
|
Mockito.mock(com.yunhai.bschclassmanage.service.ISchClassService.class));
|
||||||
|
ReflectionTestUtils.setField(controller, "schTeacherService",
|
||||||
|
Mockito.mock(com.yunhai.bschclassmanage.service.ISchTeacherService.class));
|
||||||
|
ReflectionTestUtils.setField(controller, "schBinSchsystemService", schBinSchsystemService);
|
||||||
|
ReflectionTestUtils.setField(controller, "baseSchsystemService", baseSchsystemService);
|
||||||
|
ReflectionTestUtils.setField(controller, "baseSchsystemGradeService", baseSchsystemGradeService);
|
||||||
|
|
||||||
|
// 云海小学:双学段(小学+初中),各自年级字典与入学年份映射
|
||||||
|
when(schBinSchsystemService.getSchBinSchsystemIds(27)).thenReturn(Arrays.asList(5, 9));
|
||||||
|
when(baseSchsystemService.getAcademicStageName(5)).thenReturn("小学");
|
||||||
|
when(baseSchsystemService.getAcademicStageName(9)).thenReturn("初中");
|
||||||
|
|
||||||
|
Map<Integer, Integer> primaryYears = new LinkedHashMap<>();
|
||||||
|
primaryYears.put(1, 2026);
|
||||||
|
primaryYears.put(2, 2025);
|
||||||
|
primaryYears.put(3, 2024);
|
||||||
|
when(baseSchsystemGradeService.getNowYearGradeMap(27, 5)).thenReturn(primaryYears);
|
||||||
|
Map<Integer, String> primaryNames = new HashMap<>();
|
||||||
|
primaryNames.put(1, "小一");
|
||||||
|
primaryNames.put(2, "小二");
|
||||||
|
primaryNames.put(3, "小三");
|
||||||
|
when(baseSchsystemGradeService.getGradeNameMap(27, 5, null)).thenReturn(primaryNames);
|
||||||
|
|
||||||
|
Map<Integer, Integer> juniorYears = new LinkedHashMap<>();
|
||||||
|
juniorYears.put(7, 2026);
|
||||||
|
juniorYears.put(8, 2025);
|
||||||
|
when(baseSchsystemGradeService.getNowYearGradeMap(27, 9)).thenReturn(juniorYears);
|
||||||
|
Map<Integer, String> juniorNames = new HashMap<>();
|
||||||
|
juniorNames.put(7, "初一");
|
||||||
|
juniorNames.put(8, "初二");
|
||||||
|
when(baseSchsystemGradeService.getGradeNameMap(27, 9, null)).thenReturn(juniorNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void resolvesGradeNameByStageAndYear() {
|
||||||
|
// 小学 2026 级入学 → 小一(学校字典真实名称)
|
||||||
|
OapiGradeNameVO vo = controller.getGradeName(27, 2026, 1).getBody();
|
||||||
|
assertEquals(1, vo.getGradeId());
|
||||||
|
assertEquals("小一", vo.getGradeName());
|
||||||
|
assertEquals(2026, vo.getYear());
|
||||||
|
|
||||||
|
// 初中 2026 → 初一(同校多学段按 stage 区分)
|
||||||
|
assertEquals("初一", controller.getGradeName(27, 2026, 2).getBody().getGradeName());
|
||||||
|
|
||||||
|
// 低年级已升学:2024 入学的小学年级 → 小三
|
||||||
|
assertEquals("小三", controller.getGradeName(27, 2024, 1).getBody().getGradeName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void returnsNullWhenNoMatch() {
|
||||||
|
// 年份无对应年级(超出字典范围)
|
||||||
|
assertNull(controller.getGradeName(27, 2020, 1).getBody());
|
||||||
|
// 学段在学校未开设(高中不存在)
|
||||||
|
assertNull(controller.getGradeName(27, 2026, 3).getBody());
|
||||||
|
// 参数缺失
|
||||||
|
assertNull(controller.getGradeName(null, 2026, 1).getBody());
|
||||||
|
assertNull(controller.getGradeName(27, null, 1).getBody());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void skipsBrokenSchsystemAndContinues() {
|
||||||
|
// 单个学制学段名缺失(学制未找到等)跳过,不影响其余学制匹配
|
||||||
|
when(baseSchsystemService.getAcademicStageName(5)).thenThrow(new RuntimeException("学制未找到!"));
|
||||||
|
assertEquals("初一", controller.getGradeName(27, 2026, 2).getBody().getGradeName());
|
||||||
|
assertNull(controller.getGradeName(27, 2026, 1).getBody());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void emptyYearMapReturnsNull() {
|
||||||
|
when(baseSchsystemGradeService.getNowYearGradeMap(eq(27), anyInt())).thenReturn(new HashMap<>());
|
||||||
|
assertNull(controller.getGradeName(27, 2026, 1).getBody());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user