移动组
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
+318
-4
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user