移动组

This commit is contained in:
2026-08-24 11:33:04 +08:00
parent f69a5c2182
commit af7d17c9c5
11 changed files with 505 additions and 12 deletions
@@ -16,5 +16,15 @@ import java.util.Optional;
@Repository
public interface SchClassHistoryRepository extends JpaRepository<SchClassHistory, Integer>, JpaSpecificationExecutor<SchClassHistory> {
/**
* 按学校、班级组(classId=group_class_id)、学年、学期查询班级历史快照
* 历史任教统一取第二学期(term=2)
*/
List<SchClassHistory> findBySchIdAndClassIdAndYearAndTerm(Integer schId, Integer classId, Integer year, Integer term);
/**
* 取某班级最新学年的第二学期(term=2)历史快照,用于“历史学生”页班级头信息
*/
SchClassHistory findTopBySchIdAndClassIdAndTermOrderByYearDesc(Integer schId, Integer classId, Integer term);
}
@@ -6,7 +6,15 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface SchClassTeachHistoryRepository extends JpaRepository<SchClassTeachHistory, Integer>, JpaSpecificationExecutor<SchClassTeachHistory> {
/**
* 按学校、班级组(classId=group_class_id)、学年、学期查询班级任教历史
* 历史任教统一取第二学期(term=2)
*/
List<SchClassTeachHistory> findBySchIdAndClassIdAndYearAndTerm(Integer schId, Integer classId, Integer year, Integer term);
}
@@ -6,7 +6,18 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface SchStudentHistoryRepository extends JpaRepository<SchStudentHistory, Integer>, JpaSpecificationExecutor<SchStudentHistory> {
/**
* 按学校、班级、学年、学期查询历史学生(term=2 为学年快照)
*/
List<SchStudentHistory> findBySchIdAndClassIdAndYearAndTerm(Integer schId, Integer classId, Integer year, Integer term);
/**
* 按学校、学生(stuId)查询历史学生记录,用于解析学生所属班级
*/
List<SchStudentHistory> findBySchIdAndStuId(Integer schId, Integer stuId);
}
@@ -1,7 +1,9 @@
package com.yunhai.bschclassmanage.controller.api;
import com.yunhai.bschclassmanage.config.Config;
import com.yunhai.bschclassmanage.model.vo.HistoryClassTeachVO;
import com.yunhai.bschclassmanage.model.vo.HistorySchClassVO;
import com.yunhai.bschclassmanage.model.vo.HistorySchStudentVO;
import com.yunhai.bschclassmanage.model.vo.SelectIntVO;
import com.yunhai.bschclassmanage.service.IBaseSchsystemGradeService;
import com.yunhai.bschclassmanage.service.IStudentClassHistoryService;
@@ -10,6 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@RestController
@@ -25,6 +28,22 @@ public class SchHistoryController {
return studentClassHistoryService.GetClassFirst(UserContext.getSchId(),classId);
}
//获取历史学生信息(逐年倒序)
@GetMapping("getHistoryClassStudent")
public List<HistorySchStudentVO> getHistoryClassStudent(Integer classId) {
return studentClassHistoryService.getHistoryClassStudent(UserContext.getSchId(),classId);
}
//获取历史任教信息
@GetMapping("getHistoryClassTeach")
public List<HistoryClassTeachVO> getHistoryClassTeach(Integer classId) {
return studentClassHistoryService.getHistoryClassTeach(UserContext.getSchId(),classId);
}
//通过学生stuId获取历史任教信息
@GetMapping("getHistoryClassTeachByStuId")
public Map<String, Object> getHistoryClassTeachByStuId(Integer stuId) {
return studentClassHistoryService.getHistoryClassTeachByStuId(UserContext.getSchId(),stuId);
}
}
@@ -110,6 +110,12 @@ public class SchClass extends BaseEntity {
@Column(name = "graduate")
private Boolean graduate;
/**
* 毕业日期
*/
@Column(name = "graduate_date")
private Date graduateDate;
/**
* 序号 K12班 根据 sort 定位 职业 班 sort 排序
*/
@@ -82,6 +82,41 @@ public class SchClassHistory extends BaseEntity {
@Column(name = "second_teacher_id")
private Integer secondTeacherId;
/**
* 班主任名称(冗余字段)
*/
@Size(max = 255, message = "班主任名称长度不能超过255")
@Column(name = "first_teacher_name", length = 255)
private String firstTeacherName;
/**
* 副班主任名称(冗余字段)
*/
@Size(max = 255, message = "副班主任名称长度不能超过255")
@Column(name = "second_teacher_name", length = 255)
private String secondTeacherName;
/**
* 校区名称(冗余字段)
*/
@Size(max = 255, message = "校区名称长度不能超过255")
@Column(name = "campus_name", length = 255)
private String campusName;
/**
* 系部名称(冗余字段)
*/
@Size(max = 255, message = "系部名称长度不能超过255")
@Column(name = "division_name", length = 255)
private String divisionName;
/**
* 专业名称(冗余字段)
*/
@Size(max = 255, message = "专业名称长度不能超过255")
@Column(name = "majors_name", length = 255)
private String majorsName;
/**
@@ -115,13 +150,6 @@ public class SchClassHistory extends BaseEntity {
private Integer enrollYear;
/**
* 是否毕业(默认0)
*/
@Column(name = "graduate")
private Boolean graduate;
/**
* 序号 K12班 根据 sort 定位 职业 班 sort 排序
*/
@@ -56,6 +56,20 @@ public class SchClassTeachHistory extends BaseEntity {
@Column(name = "tea_id")
private Integer teaId;
/**
* 学科名称(冗余字段)
*/
@Size(max = 255, message = "学科名称长度不能超过255")
@Column(name = "sub_name", length = 255)
private String subName;
/**
* 教师名称(冗余字段)
*/
@Size(max = 255, message = "教师名称长度不能超过255")
@Column(name = "tea_name", length = 255)
private String teaName;
/**
* 更新校验分组
@@ -0,0 +1,38 @@
package com.yunhai.bschclassmanage.model.vo;
import lombok.Data;
import java.util.List;
@Data
public class HistoryClassTeachVO {
private Integer gradeId;
private String gradeName;
private String yearDate;
/** 班主任名称(冗余) */
private String headTeacherName;
/** 副班主任名称(冗余) */
private String deputyHeadTeacherName;
/** 校区名称(冗余) */
private String campusName;
/** 系部名称(冗余) */
private String divisionName;
/** 专业名称(冗余) */
private String majorName;
private String schName;
/** 当前班级是否毕业 */
private Boolean graduate;
private List<SchTeachMapIdVO> teach;
}
@@ -0,0 +1,37 @@
package com.yunhai.bschclassmanage.model.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import javax.persistence.Column;
import java.util.Date;
import java.util.List;
/**
* @Author wanghu
* @Date 2026-6-10 15:09 (可以根据需要修改)
* @Description:
*/
@Data
public class HistorySchStudentVO {
private Integer gradeId;
private String gradeName;
private String yearDate;
//学生数量
private Integer count;
/** 班级所在学校名称 */
private String schName;
/** 当前学生姓名(byStuId 入口时填充,classId 入口为 null) */
private String studentName;
/** 当前班级是否毕业 */
private Boolean graduate;
private List<SelectIntVO> student;
}
@@ -1,13 +1,21 @@
package com.yunhai.bschclassmanage.service;
import com.yunhai.bschclassmanage.entity.BaseDicGrade;
import com.yunhai.bschclassmanage.model.vo.HistoryClassTeachVO;
import com.yunhai.bschclassmanage.model.vo.HistorySchClassVO;
import com.yunhai.bschclassmanage.model.vo.HistorySchStudentVO;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public interface IStudentClassHistoryService {
HistorySchClassVO GetClassFirst(Integer schId, Integer classId);
List<HistoryClassTeachVO> getHistoryClassTeach(Integer schId, Integer classId);
Map<String, Object> getHistoryClassTeachByStuId(Integer schId, Integer stuId);
List<HistorySchStudentVO> getHistoryClassStudent(Integer schId, Integer classId);
}
@@ -1,8 +1,24 @@
package com.yunhai.bschclassmanage.service.impl;
import com.yunhai.bschclassmanage.Repository.SchClassHistoryRepository;
import com.yunhai.bschclassmanage.Repository.SchClassTeachHistoryRepository;
import com.yunhai.bschclassmanage.Repository.SchClassTeachRepository;
import com.yunhai.bschclassmanage.Repository.SchStudentHistoryRepository;
import com.yunhai.bschclassmanage.Repository.SchStudentRepository;
import com.yunhai.bschclassmanage.entity.BaseYearTerm;
import com.yunhai.bschclassmanage.entity.SchClass;
import com.yunhai.bschclassmanage.entity.SchClassHistory;
import com.yunhai.bschclassmanage.entity.SchClassTeach;
import com.yunhai.bschclassmanage.entity.SchClassTeachHistory;
import com.yunhai.bschclassmanage.entity.SchStudent;
import com.yunhai.bschclassmanage.entity.SchStudentHistory;
import com.yunhai.bschclassmanage.enums.SchType;
import com.yunhai.bschclassmanage.model.tool.YearTerm;
import com.yunhai.bschclassmanage.model.vo.HistoryClassTeachVO;
import com.yunhai.bschclassmanage.model.vo.HistorySchClassVO;
import com.yunhai.bschclassmanage.model.vo.HistorySchStudentVO;
import com.yunhai.bschclassmanage.model.vo.SelectIntVO;
import com.yunhai.bschclassmanage.model.vo.SchTeachMapIdVO;
import com.yunhai.bschclassmanage.service.*;
import com.yunhai.bschclassmanage.utils.ModelMapperUtil;
import com.yunhai.bschclassmanage.utils.RedisUtil;
@@ -10,13 +26,25 @@ import com.yunhai.platform.utils.exception.DException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class StudentClassHistoryService implements IStudentClassHistoryService {
/** 班主任在任教列表中的 subId 标识 */
private static final String SUB_BZR = "SUBBZR";
/** 副班主任在任教列表中的 subId 标识 */
private static final String SUB_FBZR = "SUBFBZR";
private static final String NAME_BZR = "班主任";
private static final String NAME_FBZR = "副班主任";
/** 历史任教统一取第二学期 */
private static final int SECOND_TERM = 2;
/** 日期格式化:yyyy-MM-dd */
private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ISO_LOCAL_DATE;
@Autowired
private ISchClassService schClassService;
@@ -38,6 +66,30 @@ public class StudentClassHistoryService implements IStudentClassHistoryService {
@Autowired
private ISchTeacherService schTeacherService;
@Autowired
private IBaseYearTermService baseYearTermService;
@Autowired
private ISchDicSubjectService schDicSubjectService;
@Autowired
private SchClassTeachRepository schClassTeachRepository;
@Autowired
private SchClassHistoryRepository schClassHistoryRepository;
@Autowired
private SchClassTeachHistoryRepository schClassTeachHistoryRepository;
@Autowired
private SchStudentHistoryRepository schStudentHistoryRepository;
@Autowired
private SchStudentRepository schStudentRepository;
@Autowired
private IComSchTreeService comSchTreeService;
@Autowired
private RedisUtil redisUtil;
@@ -46,7 +98,7 @@ public class StudentClassHistoryService implements IStudentClassHistoryService {
public HistorySchClassVO GetClassFirst(Integer schId,Integer classId) {
Integer schType=schBinSchsystemService.getSchType(schId);
Integer gradeId=null;
Optional<SchClass> classInfo= schClassService.getSchClassCacheFilter(schId,gradeId,classId).stream().findFirst();
Optional<SchClass> classInfo= schClassService.getSchAllClassCacheFilter(schId,gradeId,classId).stream().findFirst();
if(!classInfo.isPresent()) throw new DException("班级未找到!");
HistorySchClassVO vo = ModelMapperUtil.map(classInfo.get(), HistorySchClassVO.class);
vo.setSchType(schType);
@@ -59,5 +111,267 @@ public class StudentClassHistoryService implements IStudentClassHistoryService {
return vo;
}
/**
* 获取班级历史学生信息(逐年倒序,类比 getHistoryClassTeach)
* yearList:未毕业 year..enrollYear(含当前学年,当前学年用实时表 sch_student);
* 已毕业 全部用历史表 sch_student_history。历史表固定 term=2。
* 每学年组装一个 HistorySchStudentVO:student(id=stuId, name=姓名)、gradeId、gradeName、yearDate、count。
*/
public List<HistorySchStudentVO> getHistoryClassStudent(Integer schId, Integer classId) {
// 1. 当前学年(依据学年开始日期-结束日期匹配)
YearTerm yearTerm = baseYearTermService.getCurrentYearTerm();
int currentYear = yearTerm.getYear();
// 2. 当前班级 & 是否毕业(缓存)
SchClass schClass = schClassService.getSchAllClassCacheFilter(schId, (Integer) null, classId)
.stream().findFirst().orElseThrow(() -> new DException("班级未找到!"));
Integer enrollYear = schClass.getEnrollYear() != null ? schClass.getEnrollYear() : currentYear;
boolean graduated = Boolean.TRUE.equals(schClass.getGraduate());
// 班级所在学校名称
String schName = comSchTreeService.getSchoolName(schId);
// 学年学期 Map:year -> BaseYearTerm(含开始/结束日期),用于 yearDate
Map<Integer, BaseYearTerm> yearTermMap = baseYearTermService.getAllYearTerm().stream()
.filter(t -> t.getYear() != null)
.collect(Collectors.toMap(BaseYearTerm::getYear, t -> t, (a, b) -> a));
boolean k12=Objects.equals( schBinSchsystemService.getSchType(schId),SchType.BASICEDUCATION.getKey());
Map<Integer, String> getGradeNameMap=baseSchsystemGradeService.getGradeNameMap(schId,null,schClass.getGradeId());
// 3. 年份区间(倒序)
List<Integer> yearList = new ArrayList<>();
for (int y = currentYear; y >= enrollYear; y--) yearList.add(y);
// 4. 逐学年组装
List<HistorySchStudentVO> result = new ArrayList<>();
for (Integer y : yearList) {
boolean isLive = (y == currentYear) && !graduated;
List<SelectIntVO> studentList;
if (isLive) {
// 当前学年:实时表 sch_student
List<SchStudent> live = schStudentRepository.findBySchIdAndClassId(schId, classId);
studentList = live.stream()
.filter(s -> s.getStuId() != null)
.map(s -> new SelectIntVO(s.getStuId(), s.getName()))
.collect(Collectors.toList());
} else {
// 历史表:固定取第二学期(term=2)
List<SchStudentHistory> hist = schStudentHistoryRepository
.findBySchIdAndClassIdAndYearAndTerm(schId, classId, y, SECOND_TERM);
studentList = hist.stream()
.filter(s -> s.getStuId() != null)
.map(s -> new SelectIntVO(s.getStuId(), s.getName()))
.collect(Collectors.toList());
}
HistorySchStudentVO vo = new HistorySchStudentVO();
vo.setGradeId(schClass.getGradeId());
vo.setGradeName(k12?getGradeNameMap.get(schClass.getGradeId()):( schClass.getEnrollYear() != null ? schClass.getEnrollYear() + "级" : null));
vo.setYearDate(buildYearDate(y, yearTermMap.get(y)));
vo.setCount(studentList.size());
vo.setSchName(schName);
vo.setGraduate(graduated);
vo.setStudent(studentList);
result.add(vo);
}
return result;
}
/**
* 获取班级历史任教信息
* 年份区间 yearList 倒序:
* - 未毕业:year, year-1, ..., enrollYear(含当前学年,当前学年用实时表 sch_class+sch_class_teach,其余用历史表)
* - 已毕业:year ... enrollYear(全部用历史表 sch_class_history+sch_class_teach_history)
* 历史表查询固定取第二学期(term=2)。
* 班主任(SUBBZR)/副班主任(SUBFBZR) 作为特殊任教条目并入 teache 列表。
*/
public List<HistoryClassTeachVO> getHistoryClassTeach(Integer schId, Integer classId)
{
// 1. 当前学年(依据学年开始日期-结束日期匹配)
YearTerm yearTerm = baseYearTermService.getCurrentYearTerm();
int currentYear = yearTerm.getYear();
// 2. 当前班级 & 是否毕业(缓存)
SchClass schClass = schClassService.getSchAllClassCacheFilter(schId, (Integer)null, classId)
.stream().findFirst().orElseThrow(() -> new DException("班级未找到!"));
Integer enrollYear = schClass.getEnrollYear() != null ? schClass.getEnrollYear() : currentYear;
boolean graduated = Boolean.TRUE.equals(schClass.getGraduate());
boolean k12=Objects.equals( schBinSchsystemService.getSchType(schId),SchType.BASICEDUCATION.getKey());
// 班级所在学校名称
String schName = comSchTreeService.getSchoolName(schId);
// 3. 一次性名称映射,避免循环查库
Map<Integer, String> teacherNameMap = Optional
.ofNullable(schTeacherService.toIdAndNameMap(schId)).orElse(Collections.emptyMap());
Integer schsystemId = baseSchsystemGradeService.getSchsystemIdByGradeId(schId, schClass.getGradeId());
Map<String, String> subjectNameMap = Optional
.ofNullable(schDicSubjectService.toIdAndNameMap(schId, schsystemId)).orElse(Collections.emptyMap());
Map<Integer, String> gradeNameMap = Optional
.ofNullable(baseSchsystemGradeService.getGradeNameMap(schId, schsystemId, null)).orElse(Collections.emptyMap());
// 学年学期 Map:year -> BaseYearTerm(含开始/结束日期),用于 yearDate
Map<Integer, BaseYearTerm> yearTermMap = baseYearTermService.getAllYearTerm().stream()
.filter(t -> t.getYear() != null)
.collect(Collectors.toMap(BaseYearTerm::getYear, t -> t, (a, b) -> a));
// 4. 年份区间(倒序):未毕业含当前学年(实时表),已毕业全部历史表
List<Integer> yearList = new ArrayList<>();
for (int y = currentYear; y >= enrollYear; y--) yearList.add(y);
// 5. 逐学年组装
List<HistoryClassTeachVO> result = new ArrayList<>();
for (Integer y : yearList) {
boolean isLive = (y == currentYear) && !graduated;
Integer gradeId;
Integer firstTeacherId;
Integer secondTeacherId;
// 班主任/副班主任 + 学科任教(按 sub_id 合并)
Map<String, SchTeachMapIdVO> subMap = new LinkedHashMap<>();
if (isLive) {
gradeId = schClass.getGradeId();
firstTeacherId = schClass.getFirstTeacherId();
secondTeacherId = schClass.getSecondTeacherId();
for (SchClassTeach t : schClassTeachRepository.findBySchIdAndClassId(schId, classId)) {
if (t.getSubId() == null) continue;
subMap.put(t.getSubId(), buildSubjectVO(t.getSubId(), t.getTeaId(), subjectNameMap, teacherNameMap));
}
} else {
// 历史表:固定取第二学期(term=2)
SchClassHistory histClass = schClassHistoryRepository
.findBySchIdAndClassIdAndYearAndTerm(schId, classId, y, SECOND_TERM).stream().findFirst().orElse(null);
if (histClass != null) {
gradeId = histClass.getGradeId();
firstTeacherId = histClass.getFirstTeacherId();
secondTeacherId = histClass.getSecondTeacherId();
} else {
gradeId = schClass.getGradeId();
firstTeacherId = null;
secondTeacherId = null;
}
schClassTeachHistoryRepository
.findBySchIdAndClassIdAndYearAndTerm(schId, classId, y, SECOND_TERM).stream()
.filter(t -> t.getSubId() != null)
.forEach(t -> subMap.put(t.getSubId(),
buildSubjectVO(t.getSubId(), t.getTeaId(), subjectNameMap, teacherNameMap)));
}
// 组装 teache:班主任 -> 副班主任 -> 学科任教
List<SchTeachMapIdVO> teache = new ArrayList<>();
teache.add(buildBzrVO(SUB_BZR, NAME_BZR, firstTeacherId, teacherNameMap));
teache.add(buildBzrVO(SUB_FBZR, NAME_FBZR, secondTeacherId, teacherNameMap));
teache.addAll(subMap.values());
HistoryClassTeachVO vo = new HistoryClassTeachVO();
vo.setGradeId(gradeId);
// 年级显示按 schType 区分:K12(基础教育)用年级名(逐年变化),职业教育用入学年份级(固定)
vo.setGradeName(k12 ? gradeNameMap.get(gradeId)
: (schClass.getEnrollYear() != null ? schClass.getEnrollYear() + "级" : null));
vo.setYearDate(buildYearDate(y, yearTermMap.get(y)));
// 冗余字段
vo.setHeadTeacherName(firstTeacherId != null ? teacherNameMap.get(firstTeacherId) : null);
vo.setDeputyHeadTeacherName(secondTeacherId != null ? teacherNameMap.get(secondTeacherId) : null);
vo.setSchName(schName);
vo.setGraduate(graduated);
vo.setTeach(teache);
result.add(vo);
}
return result;
}
/**
* 通过学生 stuId 获取其历史班级任教信息。
* 先由 stuId 解析学生所属班级(classId):
* - 优先取实时表 sch_student(且属于当前学校 schId)的 classId;
* - 否则取历史表 sch_student_history,按学年最大的一条作为最近班级。
* 再复用 getHistoryClassTeach(schId, classId) 返回逐年任教历史。
*/
public Map<String, Object> getHistoryClassTeachByStuId(Integer schId, Integer stuId) {
// 1. 解析学生所属班级 & 姓名
Integer classId = null;
String studentName = null;
Optional<SchStudent> live = schStudentRepository.findByStuId(stuId);
if (live.isPresent() && live.get().getClassId() != null
&& Objects.equals(live.get().getSchId(), schId)) {
classId = live.get().getClassId();
studentName = live.get().getName();
} else {
List<SchStudentHistory> hist = schStudentHistoryRepository.findBySchIdAndStuId(schId, stuId);
if (hist.isEmpty()) {
throw new DException("学生未找到!");
}
SchStudentHistory latest = hist.stream()
.max(Comparator.comparingInt(SchStudentHistory::getYear))
.orElse(null);
classId = latest != null ? latest.getClassId() : null;
studentName = latest != null ? latest.getName() : null;
}
if (classId == null) {
throw new DException("学生未找到!");
}
// 2. 班级名称
SchClass schClass = schClassService.getSchAllClassCacheFilter(schId, (Integer) null, classId)
.stream().findFirst().orElseThrow(() -> new DException("班级未找到!"));
String className = schClass.getName();
// 3. 复用班级历史任教逻辑(年级按 schType 显示:基础教育显示年级名,职业教育显示入学年份级)
List<HistoryClassTeachVO> classTeachs = getHistoryClassTeach(schId, classId);
// 4. 用 Map 包裹返回:stuName / className / classTeachs
Map<String, Object> result = new LinkedHashMap<>();
result.put("stuName", studentName);
result.put("className", className);
result.put("classTeachs", classTeachs);
return result;
}
/** 构建一个学科任教条目 VO */
private SchTeachMapIdVO buildSubjectVO(String subId, Integer teaId,
Map<String, String> subjectNameMap,
Map<Integer, String> teacherNameMap) {
SchTeachMapIdVO vo = new SchTeachMapIdVO();
vo.setSubId(subId);
vo.setSubName(subjectNameMap.get(subId));
vo.setTeacherId(teaId);
vo.setTeacherName(teaId != null ? teacherNameMap.get(teaId) : null);
return vo;
}
/** 构建班主任/副班主任条目 VO */
private SchTeachMapIdVO buildBzrVO(String subId, String subName, Integer teacherId,
Map<Integer, String> teacherNameMap) {
SchTeachMapIdVO vo = new SchTeachMapIdVO();
vo.setSubId(subId);
vo.setSubName(subName);
vo.setTeacherId(teacherId);
vo.setTeacherName(teacherId != null ? teacherNameMap.get(teacherId) : null);
return vo;
}
/**
* 根据 base 学年学期 构建 yearDate:取该学年的 开始日期 ~ 结束日期;
* 若该年无学期配置或日期缺失,则回退为 year-(year+1)。
*/
private String buildYearDate(Integer year, BaseYearTerm term) {
if (term == null || term.getYearStartDate() == null || term.getYearEndDate() == null) {
return year + "-" + (year + 1);
}
String start = term.getYearStartDate().toInstant()
.atZone(ZoneId.systemDefault()).toLocalDate().format(DATE_FMT);
String end = term.getYearEndDate().toInstant()
.atZone(ZoneId.systemDefault()).toLocalDate().format(DATE_FMT);
return start + " ~ " + end;
}
}