getstutree
build / build-push (push) Successful in 2m11s

This commit is contained in:
wanghu
2026-09-09 10:00:51 +08:00
parent 1b45924003
commit d9604b3798
4 changed files with 134 additions and 0 deletions
@@ -37,6 +37,17 @@ public class SchGroupController {
return comSchTreeService.getSchTeaTree(resolvedSchId);
}
@GetMapping("GetStuTree")
@Operation(summary = "获取学校学生树:学校→学段→年级→班级→学生(SchSerID 与 schId 二选一)")
public List<TeaTreeVO> getStuTree(@RequestParam(value = "SchSerID", required = false) String SchSerID,
@RequestParam(value = "schId", required = false) Integer schId) {
Integer resolvedSchId = resolveSchId(schId, SchSerID);
if (resolvedSchId == null) {
return Collections.emptyList();
}
return comSchTreeService.getSchStuTree(resolvedSchId);
}
/**
* 解析学校ID:支持直接传 schId,或传 SchSerID 反查 schId,二者至少提供一个。
*
@@ -20,6 +20,8 @@ public class StuInfoController {
@Autowired private SchStudentRepository studentRepository;
@Autowired private SchInfoRepository schoolRepository;
@Autowired private SchStudentHistoryRepository historyRepository;
@Autowired private SchClassRepository classRepository;
@Autowired private BaseSchsystemGradeRepository baseSchsystemGradeRepository;
@GetMapping("GetAllStulist")
@Operation(summary = "GetAllStulist")
@@ -58,6 +60,39 @@ public class StuInfoController {
Set<Integer> ids = new HashSet<>(OaCompatSupport.ints(stuids));
return ResponseEntity.ok(students(studentRepository.findAll().stream().filter(s -> ids.contains(s.getStuId())).collect(Collectors.toList()), null));
}
/** 按学校+年级直查学生(CampusNotice 推送范围圈人:免逐班聚合) */
@GetMapping("GetGradeStulist")
@Operation(summary = "GetGradeStulist", description = "按学校+年级查询在校学生(不含已毕业班级)")
public ResponseEntity<List<Map<String,Object>>> GetGradeStulist(@RequestParam(required=false) String SchSerID, @RequestParam(required=false) Integer GradeId) {
Integer schId = SchSerID == null ? null : schoolRepository.findBySchSerId(SchSerID).map(SchInfo::getSchId).orElse(null);
if (schId == null) return ResponseEntity.ok(Collections.emptyList());
Set<Integer> classIds = activeClassIds(schId, null, GradeId == null ? null : Collections.singleton(GradeId));
if (classIds.isEmpty()) return ResponseEntity.ok(Collections.emptyList());
return ResponseEntity.ok(students(studentRepository.findAll().stream().filter(s -> classIds.contains(s.getClassId())).collect(Collectors.toList()), SchSerID));
}
/** 按学校+学段(学制)直查学生(CampusNotice「学部」级范围一键展开) */
@GetMapping("GetSubStulist")
@Operation(summary = "GetSubStulist", description = "按学校+学段查询在校学生(不含已毕业班级)")
public ResponseEntity<List<Map<String,Object>>> GetSubStulist(@RequestParam(required=false) String SchSerID, @RequestParam(required=false) Integer SchSystemId) {
Integer schId = SchSerID == null ? null : schoolRepository.findBySchSerId(SchSerID).map(SchInfo::getSchId).orElse(null);
if (schId == null || SchSystemId == null) return ResponseEntity.ok(Collections.emptyList());
Set<Integer> gradeIds = baseSchsystemGradeRepository.findBySchSystemId(SchSystemId).stream()
.map(BaseSchsystemGrade::getGradeId).filter(Objects::nonNull).collect(Collectors.toSet());
Set<Integer> classIds = activeClassIds(schId, gradeIds, null);
if (classIds.isEmpty()) return ResponseEntity.ok(Collections.emptyList());
return ResponseEntity.ok(students(studentRepository.findAll().stream().filter(s -> classIds.contains(s.getClassId())).collect(Collectors.toList()), SchSerID));
}
/** 学校在读班级 class_id 集合:gradeIds 非空按年级集合过滤,单个 gradeId 传 singleton */
private Set<Integer> activeClassIds(Integer schId, Set<Integer> gradeIds, Set<Integer> singleGrade) {
return classRepository.findAll().stream()
.filter(c -> Objects.equals(c.getSchId(), schId) && !Boolean.TRUE.equals(c.getGraduate()))
.filter(c -> (gradeIds == null || gradeIds.contains(c.getGradeId())) && (singleGrade == null || singleGrade.contains(c.getGradeId())))
.map(SchClass::getClassId).filter(Objects::nonNull).collect(Collectors.toSet());
}
@GetMapping("GetEleStuIdslist")
@Operation(summary = "GetEleStuIdslist")
public ResponseEntity<List<Map<String,Object>>> GetEleStuIdslist(@RequestParam(required=false) String stuids) { return GetStuIdslist(stuids); }
@@ -31,6 +31,8 @@ public interface IComSchTreeService {
List<TeaTreeVO> getSchTeaTree(Integer schId);
List<TeaTreeVO> getSchStuTree(Integer schId);
List<SelectIntVO> getSchoolList();
BoaGroup getTeaTree(Integer schId, Boolean withSub);
@@ -58,6 +58,10 @@ public class ComSchTreeService implements IComSchTreeService {
@Lazy
private ISchTeacherService schTeacherService;
@Autowired
@Lazy
private ISchStudentService schStudentService;
@Autowired
private SchTeacherGroupRepository schTeacherGroupRepository;
@@ -578,6 +582,88 @@ public class ComSchTreeService implements IComSchTreeService {
}
}
/**
* 学生树(SchGroup/GetStuTree 输出):学校 → 学段 → 年级 → 班级 → 学生。
* 层级数据链与 getGradeClassTree 一致(学段=base_sch_system、年级=base_sch_system_grade(no=主键 id)、
* 班级=sch_class(id=group_class_id,名称 cname 优先,no=sort,不含毕业班),
* 学生仅取在读正常状态(复用按班缓存查询,已过滤休学/转出/禁用并按 sort 排序)。
* 节点契约与 getSchTeaTree 相同:组织节点 type=1、isParent=true;学生叶子 type=2、isParent=false、children=null。
* 返回单元素列表(学校根节点)。
*/
public List<TeaTreeVO> getSchStuTree(Integer schId) {
TeaTreeVO rootVo = new TeaTreeVO();
rootVo.setId(schId);
rootVo.setName(getSchoolName(schId));
rootVo.setPid(0);
rootVo.setNo(0);
rootVo.setType(1);
rootVo.setIsParent(true);
rootVo.setChildren(new ArrayList<>());
List<SelectIntVO> systemList = schBinSchsystemService.selectSchBinSchsystem(schId);
if (CollectionUtils.isEmpty(systemList)) {
return Collections.singletonList(rootVo);
}
for (SelectIntVO system : systemList) {
TeaTreeVO systemVo = newGroupNode(system.getId(), system.getName(), schId, null);
rootVo.getChildren().add(systemVo);
List<BaseSchsystemGrade> gradeList = baseSchsystemGradeService.getSchGradeCacheList(schId, system.getId(), null);
if (CollectionUtils.isEmpty(gradeList)) {
continue;
}
List<Integer> gradeIds = gradeList.stream()
.map(BaseSchsystemGrade::getGradeId)
.filter(Objects::nonNull)
.collect(Collectors.toList());
Map<Integer, List<SchClass>> classGroupMap = schClassService.getSchClassCacheFilter(schId, gradeIds, null)
.stream()
.collect(Collectors.groupingBy(SchClass::getGradeId));
for (BaseSchsystemGrade grade : gradeList) {
if (grade.getGradeId() == null) {
continue;
}
TeaTreeVO gradeVo = newGroupNode(grade.getGradeId(), grade.getGradeNickname(), system.getId(), grade.getId());
systemVo.getChildren().add(gradeVo);
for (SchClass clazz : classGroupMap.getOrDefault(grade.getGradeId(), Collections.emptyList())) {
if (clazz.getClassId() == null) {
continue;
}
TeaTreeVO classVo = newGroupNode(clazz.getClassId(),
StringUtils.isBlank(clazz.getCname()) ? clazz.getName() : clazz.getCname(),
grade.getGradeId(), clazz.getSort());
gradeVo.getChildren().add(classVo);
List<SchStudent> students = schStudentService.getSchGradeClassStudentCacheList(schId, null, null, clazz.getClassId());
for (SchStudent student : students) {
if (student.getStuId() == null) {
continue;
}
classVo.getChildren().add(newStudentNode(student, clazz.getClassId()));
}
}
}
}
sortChildrenByNo(rootVo);
return Collections.singletonList(rootVo);
}
/** 学生叶子 VO(type=2,isParent=false,no 固定 0,children=null → JSON 省略) */
private TeaTreeVO newStudentNode(SchStudent student, Integer pid) {
TeaTreeVO vo = new TeaTreeVO();
vo.setId(student.getStuId());
vo.setName(student.getName());
vo.setPid(pid);
vo.setNo(0);
vo.setType(2);
vo.setIsParent(false);
return vo;
}
/**
* 递归确保所有节点的 children 不为 null,若为 null 则设置为空列表 []
*/