@@ -15,7 +15,11 @@ import java.util.Optional;
|
|||||||
@Repository
|
@Repository
|
||||||
public interface SchStudentRepository extends JpaRepository<SchStudent, Integer>, JpaSpecificationExecutor<SchStudent> {
|
public interface SchStudentRepository extends JpaRepository<SchStudent, Integer>, JpaSpecificationExecutor<SchStudent> {
|
||||||
|
|
||||||
Optional<SchStudent> findByStuId(Integer stuId);
|
/**
|
||||||
|
* stu_id 是用户中心用户ID(非本表主键),学生在多所学校各有一条就学记录,
|
||||||
|
* 同一 stu_id 可能存在多行,必须返回 List;返回 Optional 会在多行时抛 NonUniqueResultException
|
||||||
|
*/
|
||||||
|
List<SchStudent> findByStuId(Integer stuId);
|
||||||
|
|
||||||
List<SchStudent> findByStuIdIn(List<Integer> stuIds);
|
List<SchStudent> findByStuIdIn(List<Integer> stuIds);
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,11 @@ public interface SchTeacherRepository extends JpaRepository<SchTeacher, Integer>
|
|||||||
|
|
||||||
List<SchTeacher> findByTeaIdIn(List<Integer> teaIds);
|
List<SchTeacher> findByTeaIdIn(List<Integer> teaIds);
|
||||||
|
|
||||||
Optional<SchTeacher> findByTeaId(Integer teaId);
|
/**
|
||||||
|
* tea_id 是用户中心用户ID(非本表主键),教师在多所学校各有一条记录,
|
||||||
|
* 同一 tea_id 可能存在多行,必须返回 List;返回 Optional 会在多行时抛 NonUniqueResultException
|
||||||
|
*/
|
||||||
|
List<SchTeacher> findByTeaId(Integer teaId);
|
||||||
|
|
||||||
|
|
||||||
@Query(value = "SELECT DISTINCT t.* FROM sch_teacher t " +
|
@Query(value = "SELECT DISTINCT t.* FROM sch_teacher t " +
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ public class TeainfoController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. 鐩存帴浣跨敤 uid 鏌ヨ
|
// 2. 鐩存帴浣跨敤 uid 鏌ヨ
|
||||||
return schTeacherRepository.findByTeaId(uid) // 鍋囪 findByTeaId 杩斿洖 Optional<SchTeacher>
|
return schTeacherRepository.findByTeaId(uid).stream()
|
||||||
|
.findFirst()
|
||||||
.map(teacher -> {
|
.map(teacher -> {
|
||||||
fillGroupList(Collections.singletonList(teacher), null);
|
fillGroupList(Collections.singletonList(teacher), null);
|
||||||
return teacher;
|
return teacher;
|
||||||
|
|||||||
@@ -160,7 +160,8 @@ public class UserInfoController {
|
|||||||
return ResponseEntity.ok(new ArrayList<>());
|
return ResponseEntity.ok(new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<SchTeacher> teacherOpt = schTeacherRepository.findByTeaId(userid);
|
// 同一 teaId/stuId 可能在多所学校各有记录,取第一条即可(不能按唯一查询)
|
||||||
|
Optional<SchTeacher> teacherOpt = schTeacherRepository.findByTeaId(userid).stream().findFirst();
|
||||||
if (teacherOpt.isPresent()) {
|
if (teacherOpt.isPresent()) {
|
||||||
UserInfoVO vo = convertToUserInfoVO(teacherOpt.get());
|
UserInfoVO vo = convertToUserInfoVO(teacherOpt.get());
|
||||||
if (vo != null) {
|
if (vo != null) {
|
||||||
@@ -168,7 +169,7 @@ public class UserInfoController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<SchStudent> studentOpt = schStudentRepository.findByStuId(userid);
|
Optional<SchStudent> studentOpt = schStudentRepository.findByStuId(userid).stream().findFirst();
|
||||||
if (studentOpt.isPresent()) {
|
if (studentOpt.isPresent()) {
|
||||||
UserInfoVO vo = convertToUserInfoVO(studentOpt.get());
|
UserInfoVO vo = convertToUserInfoVO(studentOpt.get());
|
||||||
if (vo != null) {
|
if (vo != null) {
|
||||||
|
|||||||
+96
-1
@@ -12,6 +12,9 @@ import com.yunhai.bschclassmanage.entity.SchTeacherCustomGroupInSubject;
|
|||||||
import com.yunhai.bschclassmanage.entity.SchTeacherCustomGroupInTeacher;
|
import com.yunhai.bschclassmanage.entity.SchTeacherCustomGroupInTeacher;
|
||||||
import com.yunhai.bschclassmanage.enums.CustomGroupType;
|
import com.yunhai.bschclassmanage.enums.CustomGroupType;
|
||||||
import com.yunhai.bschclassmanage.model.oa.TeaTreeVO;
|
import com.yunhai.bschclassmanage.model.oa.TeaTreeVO;
|
||||||
|
import com.yunhai.bschclassmanage.model.vo.SelectIntVO;
|
||||||
|
import com.yunhai.bschclassmanage.model.vo.SelectStrVO;
|
||||||
|
import com.yunhai.bschclassmanage.model.vo.sch.OapiGroupVO;
|
||||||
import com.yunhai.bschclassmanage.model.vo.sch.TeaCustomGroupTreeVO;
|
import com.yunhai.bschclassmanage.model.vo.sch.TeaCustomGroupTreeVO;
|
||||||
import com.yunhai.bschclassmanage.service.IBaseSchsystemGradeService;
|
import com.yunhai.bschclassmanage.service.IBaseSchsystemGradeService;
|
||||||
import com.yunhai.bschclassmanage.service.IComSchTreeService;
|
import com.yunhai.bschclassmanage.service.IComSchTreeService;
|
||||||
@@ -74,7 +77,7 @@ public class OapiSchGroupController {
|
|||||||
description = "不传 groupType 时返回三层:类型根节点(id=-1年级组/-2教研组/-3备课组)→ 组节点 → 教师叶子;"
|
description = "不传 groupType 时返回三层:类型根节点(id=-1年级组/-2教研组/-3备课组)→ 组节点 → 教师叶子;"
|
||||||
+ "传 groupType(1年级组 2教研组 3备课组,教研组即教师学科组)时直接返回该类型组节点列表(两层)。"
|
+ "传 groupType(1年级组 2教研组 3备课组,教研组即教师学科组)时直接返回该类型组节点列表(两层)。"
|
||||||
+ "组节点携带组长、关联年级、关联学科;教师叶子携带 isLeader")
|
+ "组节点携带组长、关联年级、关联学科;教师叶子携带 isLeader")
|
||||||
public ResponseEntity<List<TeaCustomGroupTreeVO>> getTeaCustomGroupTree(@RequestParam(value = "schId", required = false) Integer schId,
|
public ResponseEntity<List<TeaCustomGroupTreeVO>> getTeaCustomGroupTree(@RequestParam(value = "schId") Integer schId,
|
||||||
@RequestParam(value = "groupType", required = false) Integer groupType) {
|
@RequestParam(value = "groupType", required = false) Integer groupType) {
|
||||||
if (schId == null) {
|
if (schId == null) {
|
||||||
return ResponseEntity.ok(Collections.emptyList());
|
return ResponseEntity.ok(Collections.emptyList());
|
||||||
@@ -91,6 +94,98 @@ public class OapiSchGroupController {
|
|||||||
return ResponseEntity.ok(buildTree(schId, groups, groupType != null));
|
return ResponseEntity.ok(buildTree(schId, groups, groupType != null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("getTeaCustomGroupList")
|
||||||
|
@Operation(summary = "获取教师分组列表(组/组员/组长合一)",
|
||||||
|
description = "按学校查教师分组列表:组id、组名称、学科集合、年级集合、组员集合、组长集合;"
|
||||||
|
+ "groupType 可选(1年级组 2教研组 3备课组,不传返回全部类型)。"
|
||||||
|
+ "组长取关系表 group_type=1 的全部教师(取不到时兜底组记录 leader_id 字段),组员取 group_type=2 且排除组长")
|
||||||
|
public ResponseEntity<List<OapiGroupVO>> getTeaCustomGroupList(@RequestParam(value = "schId") Integer schId,
|
||||||
|
@RequestParam(value = "groupType", required = false) Integer groupType) {
|
||||||
|
if (schId == null) {
|
||||||
|
return ResponseEntity.ok(Collections.emptyList());
|
||||||
|
}
|
||||||
|
List<SchTeacherCustomGroup> groups = (groupType != null)
|
||||||
|
? customGroupRepository.findBySchIdAndGroupType(schId, groupType)
|
||||||
|
: customGroupRepository.findBySchId(schId);
|
||||||
|
if (groups == null || groups.isEmpty()) {
|
||||||
|
return ResponseEntity.ok(Collections.emptyList());
|
||||||
|
}
|
||||||
|
groups = groups.stream()
|
||||||
|
.sorted(Comparator.comparing(SchTeacherCustomGroup::getSort, Comparator.nullsLast(Integer::compareTo)))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
List<Integer> groupIds = groups.stream().map(SchTeacherCustomGroup::getId).collect(Collectors.toList());
|
||||||
|
Map<Integer, List<SchTeacherCustomGroupInGrade>> groupIdToGrades = groupInGradeRepository.findByCgGroupIdIn(groupIds).stream()
|
||||||
|
.collect(Collectors.groupingBy(SchTeacherCustomGroupInGrade::getCgGroupId));
|
||||||
|
Map<Integer, List<SchTeacherCustomGroupInSubject>> groupIdToSubjects = groupInSubjectRepository.findByCgGroupIdIn(groupIds).stream()
|
||||||
|
.collect(Collectors.groupingBy(SchTeacherCustomGroupInSubject::getCgGroupId));
|
||||||
|
// relationType:1组长 2组员
|
||||||
|
Map<Integer, List<SchTeacherCustomGroupInTeacher>> groupIdToTeachers = groupInTeacherRepository.findByCgGroupIdIn(groupIds).stream()
|
||||||
|
.filter(r -> r.getTeaId() != null)
|
||||||
|
.collect(Collectors.groupingBy(SchTeacherCustomGroupInTeacher::getCgGroupId));
|
||||||
|
|
||||||
|
Map<Integer, SchTeacher> teacherMap = schTeacherService.getSchTeacherCacheList(schId).stream()
|
||||||
|
.filter(t -> t.getTeaId() != null)
|
||||||
|
.collect(Collectors.toMap(SchTeacher::getTeaId, t -> t, (a, b) -> a));
|
||||||
|
Map<Integer, String> gradeNameMap = baseSchsystemGradeService.getGradeNameMap(schId, null, null);
|
||||||
|
Map<String, String> subjectNameMap = schDicSubjectService.toIdAndNameMap(schId, null);
|
||||||
|
|
||||||
|
List<OapiGroupVO> result = new ArrayList<>(groups.size());
|
||||||
|
for (SchTeacherCustomGroup group : groups) {
|
||||||
|
List<SchTeacherCustomGroupInTeacher> relations = groupIdToTeachers.getOrDefault(group.getId(), Collections.emptyList());
|
||||||
|
List<Integer> leaderIds = resolveLeaders(group, relations);
|
||||||
|
|
||||||
|
OapiGroupVO vo = new OapiGroupVO();
|
||||||
|
vo.setGroupId(group.getId());
|
||||||
|
vo.setGroupName(group.getGroupName());
|
||||||
|
vo.setGroupType(group.getGroupType());
|
||||||
|
vo.setGroupTypeName(group.getGroupType() == null ? null : CustomGroupType.nameById(group.getGroupType()));
|
||||||
|
vo.setSubjects(groupIdToSubjects.getOrDefault(group.getId(), Collections.emptyList()).stream()
|
||||||
|
.map(SchTeacherCustomGroupInSubject::getSubId)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.distinct()
|
||||||
|
.map(subId -> new SelectStrVO(subId, subjectNameMap.get(subId)))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
vo.setGrades(groupIdToGrades.getOrDefault(group.getId(), Collections.emptyList()).stream()
|
||||||
|
.map(SchTeacherCustomGroupInGrade::getGradeId)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.distinct()
|
||||||
|
.map(gradeId -> new SelectIntVO(gradeId, gradeNameMap.get(gradeId)))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
vo.setLeaders(toIdNameList(leaderIds, teacherMap));
|
||||||
|
vo.setMembers(toIdNameList(relations.stream()
|
||||||
|
.filter(r -> Integer.valueOf(2).equals(r.getGroupType()))
|
||||||
|
.map(SchTeacherCustomGroupInTeacher::getTeaId)
|
||||||
|
.filter(id -> !leaderIds.contains(id))
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList()), teacherMap));
|
||||||
|
result.add(vo);
|
||||||
|
}
|
||||||
|
return ResponseEntity.ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 组长ID集合:关系表 group_type=1 的全部教师,取不到时兜底组记录 leader_id 字段(与 getSchCustomGroup 语义一致) */
|
||||||
|
private List<Integer> resolveLeaders(SchTeacherCustomGroup group, List<SchTeacherCustomGroupInTeacher> relations) {
|
||||||
|
List<Integer> leaderIds = relations.stream()
|
||||||
|
.filter(r -> Integer.valueOf(1).equals(r.getGroupType()))
|
||||||
|
.map(SchTeacherCustomGroupInTeacher::getTeaId)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (leaderIds.isEmpty() && group.getLeaderId() != null) {
|
||||||
|
leaderIds = Collections.singletonList(group.getLeaderId());
|
||||||
|
}
|
||||||
|
return leaderIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 教师ID集合 → [{id,姓名}],按入参顺序;姓名取不到时与 getSchCustomGroup 一致回退"未知教师" */
|
||||||
|
private List<SelectIntVO> toIdNameList(List<Integer> teaIds, Map<Integer, SchTeacher> teacherMap) {
|
||||||
|
return teaIds.stream()
|
||||||
|
.map(teaId -> new SelectIntVO(teaId,
|
||||||
|
Optional.ofNullable(teacherMap.get(teaId)).map(SchTeacher::getName).orElse("未知教师")))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
/** 组装类型节点→组节点→教师叶子树(flatTypeRoot=true 时不建类型根,组节点直接作为顶层) */
|
/** 组装类型节点→组节点→教师叶子树(flatTypeRoot=true 时不建类型根,组节点直接作为顶层) */
|
||||||
private List<TeaCustomGroupTreeVO> buildTree(Integer schId, List<SchTeacherCustomGroup> groups, boolean flatTypeRoot) {
|
private List<TeaCustomGroupTreeVO> buildTree(Integer schId, List<SchTeacherCustomGroup> groups, boolean flatTypeRoot) {
|
||||||
List<Integer> groupIds = groups.stream().map(SchTeacherCustomGroup::getId).collect(Collectors.toList());
|
List<Integer> groupIds = groups.stream().map(SchTeacherCustomGroup::getId).collect(Collectors.toList());
|
||||||
|
|||||||
+3
-1
@@ -44,7 +44,9 @@ public class OapiSchStudentController {
|
|||||||
if (stuId == null) {
|
if (stuId == null) {
|
||||||
return ResponseEntity.ok(null);
|
return ResponseEntity.ok(null);
|
||||||
}
|
}
|
||||||
return ResponseEntity.ok(schStudentRepository.findByStuId(stuId)
|
// 同一 stu_id 可能在多所学校各有记录,取第一条即可(不能按唯一查询)
|
||||||
|
return ResponseEntity.ok(schStudentRepository.findByStuId(stuId).stream()
|
||||||
|
.findFirst()
|
||||||
.map(stu -> toVOList(stu.getSchId(), Collections.singletonList(stu)).get(0))
|
.map(stu -> toVOList(stu.getSchId(), Collections.singletonList(stu)).get(0))
|
||||||
.orElse(null));
|
.orElse(null));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -329,7 +329,7 @@ public class SchDicSubjectService implements ISchDicSubjectService {
|
|||||||
public List<SelectStrVO> select(Integer schId, Integer schsystemId) {
|
public List<SelectStrVO> select(Integer schId, Integer schsystemId) {
|
||||||
List<SchDicSubject> list = getSchDicSubjectCacheList(schId, schsystemId);
|
List<SchDicSubject> list = getSchDicSubjectCacheList(schId, schsystemId);
|
||||||
// 按 code 去重,保留顺序(若需要保持原顺序,可用 LinkedHashSet 包装)
|
// 按 code 去重,保留顺序(若需要保持原顺序,可用 LinkedHashSet 包装)
|
||||||
list = list.stream()
|
list = list.stream().filter(s -> Boolean.TRUE.equals(s.getEnable()))
|
||||||
.collect(Collectors.collectingAndThen(
|
.collect(Collectors.collectingAndThen(
|
||||||
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SchDicSubject::getCode))),
|
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SchDicSubject::getCode))),
|
||||||
ArrayList::new
|
ArrayList::new
|
||||||
|
|||||||
+7
-5
@@ -300,13 +300,15 @@ public class StudentClassHistoryService implements IStudentClassHistoryService {
|
|||||||
*/
|
*/
|
||||||
public Map<String, Object> getHistoryClassTeachByStuId(Integer schId, Integer stuId) {
|
public Map<String, Object> getHistoryClassTeachByStuId(Integer schId, Integer stuId) {
|
||||||
// 1. 解析学生所属班级 & 姓名
|
// 1. 解析学生所属班级 & 姓名
|
||||||
|
// stu_id 是用户中心用户ID,学生在多所学校各有就学记录(同一 stu_id 多行),需按当前学校过滤后取一条
|
||||||
Integer classId = null;
|
Integer classId = null;
|
||||||
String studentName = null;
|
String studentName = null;
|
||||||
Optional<SchStudent> live = schStudentRepository.findByStuId(stuId);
|
SchStudent liveMatch = schStudentRepository.findByStuId(stuId).stream()
|
||||||
if (live.isPresent() && live.get().getClassId() != null
|
.filter(s -> s.getClassId() != null && Objects.equals(s.getSchId(), schId))
|
||||||
&& Objects.equals(live.get().getSchId(), schId)) {
|
.findFirst().orElse(null);
|
||||||
classId = live.get().getClassId();
|
if (liveMatch != null) {
|
||||||
studentName = live.get().getName();
|
classId = liveMatch.getClassId();
|
||||||
|
studentName = liveMatch.getName();
|
||||||
} else {
|
} else {
|
||||||
List<SchStudentHistory> hist = schStudentHistoryRepository.findBySchIdAndStuId(schId, stuId);
|
List<SchStudentHistory> hist = schStudentHistoryRepository.findBySchIdAndStuId(schId, stuId);
|
||||||
if (hist.isEmpty()) {
|
if (hist.isEmpty()) {
|
||||||
|
|||||||
+1
-1
@@ -191,7 +191,7 @@ public class SchTeacherRelationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 异步记录操作日志
|
// 异步记录操作日志
|
||||||
schTeacherRepository.findByTeaId(teaId).ifPresent(teacher ->
|
schTeacherRepository.findByTeaId(teaId).stream().findFirst().ifPresent(teacher ->
|
||||||
logService.setTransferInLogs(user, Collections.singletonList(teacher), targetGroupId));
|
logService.setTransferInLogs(user, Collections.singletonList(teacher), targetGroupId));
|
||||||
|
|
||||||
// 清除所有涉及学校的缓存
|
// 清除所有涉及学校的缓存
|
||||||
|
|||||||
Reference in New Issue
Block a user