学年 学校 获取 年级
build / build-push (push) Successful in 1m12s

This commit is contained in:
wanghu
2026-10-21 14:43:27 +08:00
parent a0c6a27f55
commit 3fa52f21af
4 changed files with 190 additions and 1 deletions
@@ -5,7 +5,10 @@ import com.yunhai.bschclassmanage.Repository.SchInfoRepository;
import com.yunhai.bschclassmanage.config.Config;
import com.yunhai.bschclassmanage.entity.SchClass;
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.IBaseSchsystemService;
import com.yunhai.bschclassmanage.service.ISchBinSchsystemService;
import com.yunhai.bschclassmanage.service.ISchClassService;
import com.yunhai.bschclassmanage.service.ISchTeacherService;
import io.swagger.v3.oas.annotations.Operation;
@@ -33,6 +36,10 @@ public class OapiSchClassController {
private ISchTeacherService schTeacherService;
@Autowired
private IBaseSchsystemGradeService baseSchsystemGradeService;
@Autowired
private ISchBinSchsystemService schBinSchsystemService;
@Autowired
private IBaseSchsystemService baseSchsystemService;
@GetMapping("getClassInfo")
@Operation(summary = "获取班级信息", description = "按班级ID(班级组ID)查询班级信息,含班主任/副班主任ID与姓名;可传 schId 精确到学校")
@@ -77,6 +84,53 @@ public class OapiSchClassController {
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:按学校分组后统一回填学校名/年级名/班主任姓名 */
private List<OapiClassVO> toVOList(List<SchClass> classes) {
if (classes == null || classes.isEmpty()) {
@@ -32,7 +32,8 @@ public class SyncClassDTO {
/** 班号 1..N(=aca_assign_class.sort_order,决定 code 尾号与 sch_class.sort) */
private Integer sort;
/** 分班侧班名(可空;非空时写 cname 别名,name 统一按规则生成 sort+"班") */
/** 分班侧班名(可空;非空时写 cname 别名,name 统一按规则生成 sort+"班")。
* 分班侧口径(2026-10-21):仅语义班名(阳光班/苹果班)才传,序号生成的班名(1班/2班)不传,cname 留空 */
private String name;
/** 班主任(平台教师 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;
}
@@ -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());
}
}