状态修改
This commit is contained in:
@@ -25,9 +25,18 @@ public interface SchStudentRepository extends JpaRepository<SchStudent, Integer>
|
||||
|
||||
Optional<SchStudent> findByIdAndSchId(Integer Id, Integer schId);
|
||||
|
||||
@Query("SELECT s FROM SchStudent s WHERE s.schId = :schId AND s.classId = :classId AND s.abnormalStatus = 1 AND s.transferStatus=1 AND s.status = 1")
|
||||
@Query("SELECT s FROM SchStudent s WHERE s.schId = :schId AND s.classId = :classId AND s.abnormalStatus = 0 AND s.transferStatus= 0 AND s.status = 0")
|
||||
List<SchStudent> findBySchIdAndClassId(@Param("schId") Integer schId, @Param("classId") Integer classId);
|
||||
|
||||
/**
|
||||
* 根据学校、班级和转入状态查询学生实体
|
||||
* 适用场景:同步回收时定位某班当前“转入/转出”的学生,用于把用户中心已移除的学生标记为转出
|
||||
*/
|
||||
@Query("SELECT s FROM SchStudent s WHERE s.schId = :schId AND s.classId = :classId AND s.transferStatus = :transferStatus")
|
||||
List<SchStudent> findBySchIdAndClassIdAndTransferStatus(@Param("schId") Integer schId,
|
||||
@Param("classId") Integer classId,
|
||||
@Param("transferStatus") Integer transferStatus);
|
||||
|
||||
List<SchStudent> findAllByIdInAndSchId(List<Integer> ids, Integer schId);
|
||||
|
||||
|
||||
@@ -45,7 +54,7 @@ public interface SchStudentRepository extends JpaRepository<SchStudent, Integer>
|
||||
@Param("updateUserId") Integer updateUserId);
|
||||
|
||||
@Modifying
|
||||
@Query("UPDATE SchStudent s SET s.schId = :schId, s.classId = :newClassId,s.groupId = :newClassId, s.updateDate = :updateDate, s.updateUserId = :updateUserId , s.transferStatus =1 WHERE s.id IN :ids")
|
||||
@Query("UPDATE SchStudent s SET s.schId = :schId, s.classId = :newClassId,s.groupId = :newClassId, s.updateDate = :updateDate, s.updateUserId = :updateUserId , s.transferStatus = 0 WHERE s.id IN :ids")
|
||||
int batchUpdateSchIdAndClassId(@Param("ids") List<Integer> ids,
|
||||
@Param("schId") Integer schId, // 目标学校ID
|
||||
@Param("newClassId") Integer newClassId,
|
||||
@@ -104,11 +113,11 @@ public interface SchStudentRepository extends JpaRepository<SchStudent, Integer>
|
||||
|
||||
/**
|
||||
* 获取所有转出学生的学校ID(去重)
|
||||
* 转出条件:transfer_status = 0
|
||||
* 转出条件:transfer_status = 1
|
||||
* 关联:s.class_id = c.group_class_id
|
||||
*/
|
||||
@Query(value = "SELECT DISTINCT c.sch_id FROM sch_student s " +
|
||||
"INNER JOIN sch_class c ON s.class_id = c.group_class_id " +
|
||||
"WHERE s.transfer_status = 0 AND s.sch_id = c.sch_id AND s.status=1 ", nativeQuery = true)
|
||||
"WHERE s.transfer_status = 0 AND s.sch_id = c.sch_id AND s.status= 0 ", nativeQuery = true)
|
||||
List<Integer> findDistinctSchIdsByTransferOut();
|
||||
}
|
||||
|
||||
@@ -35,10 +35,16 @@ public interface SchTeacherGroupRepository extends JpaRepository<SchTeacherGroup
|
||||
|
||||
/**
|
||||
* 根据 teaId 列表、学校 ID 和转入状态查询组关联
|
||||
* 适用场景:只查询转入状态的记录(transferStatus = 1)
|
||||
* 适用场景:只查询转入状态的记录(transferStatus = 0)
|
||||
*/
|
||||
List<SchTeacherGroup> findByTeaIdInAndSchIdAndTransferStatus(List<Integer> teaIds, Integer schId, Integer transferStatus);
|
||||
|
||||
/**
|
||||
* 根据学校 ID 和转入状态查询教师分组实体
|
||||
* 适用场景:同步回收时定位某校当前“转入/转出”的教师分组,用于把用户中心已移除的教师标记为转出
|
||||
*/
|
||||
List<SchTeacherGroup> findBySchIdAndTransferStatus(Integer schId, Integer transferStatus);
|
||||
|
||||
/**
|
||||
* 根据学校 ID 查询该学校所有教师的 teaId(去重)
|
||||
* 适用场景:获取该校所有教师列表
|
||||
|
||||
@@ -26,13 +26,13 @@ public interface SchTeacherRepository extends JpaRepository<SchTeacher, Integer>
|
||||
@Query(value = "SELECT DISTINCT t.* FROM sch_teacher t " +
|
||||
"INNER JOIN sch_teacher_group g ON t.tea_id = g.tea_id " +
|
||||
"WHERE g.sch_id = :schId " +
|
||||
"AND g.transfer_status = 1 " + // 只查转入状态的教师
|
||||
"AND g.transfer_status = 0 " + // 只查转入状态的教师
|
||||
"AND (:groupId IS NULL OR g.group_id = :groupId) " +
|
||||
"AND (:keyword IS NULL OR t.name LIKE CONCAT('%', :keyword, '%') OR t.account LIKE CONCAT('%', :keyword, '%')) " ,
|
||||
countQuery = "SELECT COUNT(DISTINCT t.id) FROM sch_teacher t " +
|
||||
"INNER JOIN sch_teacher_group g ON t.tea_id = g.tea_id " +
|
||||
"WHERE g.sch_id = :schId " +
|
||||
"AND g.transfer_status = 1 " +
|
||||
"AND g.transfer_status = 0 " +
|
||||
"AND (:groupId IS NULL OR g.group_id = :groupId) " +
|
||||
"AND (:keyword IS NULL OR t.name LIKE CONCAT('%', :keyword, '%') OR t.account LIKE CONCAT('%', :keyword, '%'))",
|
||||
nativeQuery = true)
|
||||
@@ -45,8 +45,8 @@ public interface SchTeacherRepository extends JpaRepository<SchTeacher, Integer>
|
||||
@Query(value = "SELECT DISTINCT g.tea_id AS teaId, g.sch_id AS schId, t.name AS teaName, t.id_card AS idCard " +
|
||||
"FROM sch_teacher_group g " +
|
||||
"INNER JOIN sch_teacher t ON t.tea_id = g.tea_id " +
|
||||
"WHERE g.transfer_status = 0 " +
|
||||
"AND t.status = 1 " +
|
||||
"WHERE g.transfer_status = 1 " +
|
||||
"AND t.status = 0 " +
|
||||
"AND (:schId IS NULL OR g.sch_id = :schId) " +
|
||||
"AND (:groupId IS NULL OR g.group_id = :groupId) " +
|
||||
"AND (:keyword IS NULL OR t.name LIKE CONCAT('%', :keyword, '%') OR t.account LIKE CONCAT('%', :keyword, '%')) " +
|
||||
@@ -54,8 +54,8 @@ public interface SchTeacherRepository extends JpaRepository<SchTeacher, Integer>
|
||||
countQuery = "SELECT COUNT(DISTINCT CONCAT(g.tea_id, '_', g.sch_id)) " +
|
||||
"FROM sch_teacher_group g " +
|
||||
"INNER JOIN sch_teacher t ON t.tea_id = g.tea_id " +
|
||||
"WHERE g.transfer_status = 0 " +
|
||||
"AND t.status = 1 " +
|
||||
"WHERE g.transfer_status = 1 " +
|
||||
"AND t.status = 0 " +
|
||||
"AND (:schId IS NULL OR g.sch_id = :schId) " +
|
||||
"AND (:groupId IS NULL OR g.group_id = :groupId) " +
|
||||
"AND (:keyword IS NULL OR t.name LIKE CONCAT('%', :keyword, '%') OR t.account LIKE CONCAT('%', :keyword, '%'))",
|
||||
|
||||
@@ -38,6 +38,7 @@ public class SyncGroupController {
|
||||
@PostMapping("DeleteGroup")
|
||||
public void DeleteGroup(@RequestBody String jsonString) {
|
||||
log.info("DeleteGroup jsonString="+jsonString);
|
||||
|
||||
}
|
||||
|
||||
@PostMapping("SyncGroup")
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
package com.yunhai.bschclassmanage.enums;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public enum Question
|
||||
{
|
||||
I(1, "单选题"),
|
||||
II(2, "多选题"),
|
||||
III(3, "判断题"),
|
||||
IV(4, "解答题"),
|
||||
V(6, "组合题"),
|
||||
VI(5, "填空题"),
|
||||
VII(7, "英语题");
|
||||
|
||||
private int id;
|
||||
private String name;
|
||||
|
||||
Question(int id, String name)
|
||||
{
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static List<Question> list()
|
||||
{
|
||||
return new ArrayList<>(EnumSet.allOf(Question.class));
|
||||
}
|
||||
|
||||
public static Map<Integer, Question> map()
|
||||
{
|
||||
return list().stream().collect(Collectors.toMap(Question::getId, QuestionType->QuestionType));
|
||||
}
|
||||
|
||||
public static String nameById(int id) {
|
||||
for (Question type : list()) {
|
||||
if (type.getId() == id) return type.getName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static Integer getIdByName(String name) {
|
||||
for (Question type : list()) {
|
||||
if (type.getName().equals(name)) return type.getId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static Question getById(int id)
|
||||
{
|
||||
for (Question na : list())
|
||||
{
|
||||
if (na.getId() == id)
|
||||
{
|
||||
return na;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -14,15 +14,15 @@ import java.util.stream.Collectors;
|
||||
@NoArgsConstructor
|
||||
public enum StuAbnormalStatus
|
||||
{
|
||||
NORMAL(1,"正常"),
|
||||
SUSPEND_SCHOOLING(2,"休学"),
|
||||
GO_ABROAD(3,"出国"),
|
||||
STUDY_ABROAD(4,"留学"),
|
||||
RESUME_SCHOOLING(5,"复学"),
|
||||
STOP_SCHOOLING(6,"停学"),
|
||||
VOLUNTARY_RETREAT_SCHOOLING(7,"自愿退学"),
|
||||
VOLUNTARY_REPEAT_GRADE(8,"自愿留级"),
|
||||
VOLUNTARY_DROP_GRADE(9,"自愿降级"),
|
||||
NORMAL(0,"正常"),
|
||||
SUSPEND_SCHOOLING(1,"休学"),
|
||||
GO_ABROAD(2,"出国"),
|
||||
STUDY_ABROAD(3,"留学"),
|
||||
RESUME_SCHOOLING(4,"复学"),
|
||||
STOP_SCHOOLING(5,"停学"),
|
||||
VOLUNTARY_RETREAT_SCHOOLING(6,"自愿退学"),
|
||||
VOLUNTARY_REPEAT_GRADE(7,"自愿留级"),
|
||||
VOLUNTARY_DROP_GRADE(8,"自愿降级"),
|
||||
ELSE(99,"其他");
|
||||
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ import java.util.stream.Collectors;
|
||||
@AllArgsConstructor
|
||||
public enum TransferStatus
|
||||
{
|
||||
OUT(0,"转出"),
|
||||
IN(1,"转入");
|
||||
IN(0,"转入"),
|
||||
OUT(1,"转出");
|
||||
|
||||
private Integer id;
|
||||
private String name;
|
||||
|
||||
@@ -16,6 +16,7 @@ public enum UserRole {
|
||||
BUSINESS(6,"工作号"),
|
||||
GENERAL_USER(8,"普通用户");
|
||||
|
||||
|
||||
private Integer value;
|
||||
private String name;
|
||||
|
||||
|
||||
@@ -16,10 +16,9 @@ import java.util.stream.Collectors;
|
||||
@AllArgsConstructor
|
||||
public enum UserStatus
|
||||
{
|
||||
//状态 0禁用 1 正常 2休学 3出国 4留学 5复学 6停学 7退学 8留级 9其他
|
||||
|
||||
DISABLED(0,"禁用"),
|
||||
NORMAL(1,"正常");
|
||||
//状态 0 正常 1禁用 2休学 3出国 4留学 5复学 6停学 7退学 8留级 9其他
|
||||
NORMAL(0,"正常"),
|
||||
DISABLED(1,"禁用");
|
||||
|
||||
private Integer id;
|
||||
private String name;
|
||||
|
||||
@@ -21,6 +21,8 @@ public class UserContextInterceptor implements HandlerInterceptor {
|
||||
UserContext.setUserId(currentUser.getId());
|
||||
UserContext.setUserName(currentUser.getName());
|
||||
UserContext.setType(currentUser.getType());
|
||||
UserContext.setSchId(currentUser.getSchool()==null?null:currentUser.getSchool().getId());
|
||||
UserContext.setRoleId(currentUser.getRoleIds().get(0));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -22,11 +24,11 @@ public class SyncGroupService implements ISyncGroupService {
|
||||
|
||||
public void syncAddOrUpdate(SyncGroupDTO group) {
|
||||
|
||||
//学校组 年级组 班级组
|
||||
if(group.getType().equals(NodeType.SCHOOL.getId())){
|
||||
//学校组-年级组-班级组
|
||||
if(Objects.equals(group.getType(),NodeType.SCHOOL.getId())){
|
||||
addOrUpdateSchool(group);
|
||||
}
|
||||
if(group.getType().equals(NodeType.CLASS.getId())){
|
||||
if(Objects.equals(group.getType(),NodeType.CLASS.getId())){
|
||||
|
||||
|
||||
//添加班级组 202406
|
||||
@@ -57,6 +59,11 @@ public class SyncGroupService implements ISyncGroupService {
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteGroup(List<Integer> Ids)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -177,6 +177,8 @@ public class SyncUserService implements ISyncUserService {
|
||||
List<SchStudent> saveList = new ArrayList<>();
|
||||
// 受影响班级缓存键 (schId -> classId 集合),用于同步后失效
|
||||
Map<Integer, Set<Integer>> classKeys = new HashMap<>();
|
||||
// 本次同步下发的学生分组键(stuId_classId),用于回收对账
|
||||
Set<String> incomingStudentKeys = new HashSet<>();
|
||||
|
||||
for (SyncUserDTO user : studentUsers) {
|
||||
if (user.getGroups() == null) continue;
|
||||
@@ -195,16 +197,52 @@ public class SyncUserService implements ISyncUserService {
|
||||
}
|
||||
saveList.add(student);
|
||||
classKeys.computeIfAbsent(schId, k -> new HashSet<>()).add(groupId);
|
||||
incomingStudentKeys.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
if (!saveList.isEmpty()) {
|
||||
schStudentRepository.saveAll(saveList);
|
||||
// 同步后使受影响班级的学生缓存失效,避免读到旧数据
|
||||
}
|
||||
|
||||
// 清理用户中心不存在的学生(与教师相同逻辑:标记转出,可逆向恢复)
|
||||
Set<Integer> schIds = classKeys.keySet();
|
||||
setTransferStudent(schIds, classKeys, incomingStudentKeys);
|
||||
|
||||
// 同步后使受影响班级的学生缓存失效,避免读到旧数据
|
||||
if (!classKeys.isEmpty()) {
|
||||
classKeys.forEach((schId, classIds) -> schStudentCacheService.clearClassStudentCaches(schId, classIds));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理用户中心不存在的学生:学校/班级已存在、但用户中心(incomingStudentKeys)已不存在的学生,
|
||||
* 标记为转出(OUT),从活跃名单中清理;同时保留转出记录,可随下次同步逆向恢复(重新 IN)。
|
||||
* 仅针对本次同步覆盖的学校/班级,避免误删未参与本批次的其他班级学生。
|
||||
*/
|
||||
private void setTransferStudent(Set<Integer> schIds, Map<Integer, Set<Integer>> classKeys, Set<String> incomingStudentKeys) {
|
||||
for (Integer schId : schIds) {
|
||||
Set<Integer> classIds = classKeys.get(schId);
|
||||
if (classIds == null) continue;
|
||||
for (Integer classId : classIds) {
|
||||
if (classId == null) continue;
|
||||
List<SchStudent> currentIn = schStudentRepository.findBySchIdAndClassIdAndTransferStatus(schId, classId, TransferStatus.IN.getId());
|
||||
List<SchStudent> toTransferOut = new ArrayList<>();
|
||||
for (SchStudent s : currentIn) {
|
||||
String key = buildStudentKey(s.getStuId(), s.getClassId());
|
||||
if (!incomingStudentKeys.contains(key)) {
|
||||
s.setTransferStatus(TransferStatus.OUT.getId());
|
||||
toTransferOut.add(s);
|
||||
}
|
||||
}
|
||||
if (!toTransferOut.isEmpty()) {
|
||||
schStudentRepository.saveAll(toTransferOut);
|
||||
log.info("清理用户中心不存在的学生:schId={}, classId={}, 转出学生数={}", schId, classId, toTransferOut.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStudent(SchStudent student, SyncUserDTO user, SyncUserGroupDTO group, Date now) {
|
||||
student.setAccount(user.getAccount());
|
||||
student.setName(user.getName());
|
||||
@@ -240,6 +278,7 @@ public class SyncUserService implements ISyncUserService {
|
||||
// ==================== 教师同步 ====================
|
||||
|
||||
private void syncTeachers(List<SyncUserDTO> teacherUsers, Date now) {
|
||||
|
||||
List<Integer> teaIds = teacherUsers.stream().map(SyncUserDTO::getId).distinct().collect(Collectors.toList());
|
||||
|
||||
// 教师主体(唯一)
|
||||
@@ -257,6 +296,8 @@ public class SyncUserService implements ISyncUserService {
|
||||
List<SchTeacherGroup> saveGroupList = new ArrayList<>();
|
||||
// 受影响学校缓存键,用于同步后失效
|
||||
Set<Integer> schIds = new HashSet<>();
|
||||
// 本次同步下发的教师分组键(teaId_groupId_schId),用于回收对账
|
||||
Set<String> incomingGroupKeys = new HashSet<>();
|
||||
|
||||
for (SyncUserDTO user : teacherUsers) {
|
||||
// 教师主体(只存一条)
|
||||
@@ -285,6 +326,7 @@ public class SyncUserService implements ISyncUserService {
|
||||
}
|
||||
saveGroupList.add(tg);
|
||||
schIds.add(schId);
|
||||
incomingGroupKeys.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,12 +336,40 @@ public class SyncUserService implements ISyncUserService {
|
||||
if (!saveGroupList.isEmpty()) {
|
||||
schTeacherGroupRepository.saveAll(saveGroupList);
|
||||
}
|
||||
|
||||
// 清理用户中心不存在的教师:
|
||||
// 学校已存在、但用户中心(teacherUsers)已不存在的教师,需从活跃名单中清理。
|
||||
// 对本次同步涉及的每所学校,将「当前为转入状态、但不在本次下发分组列表」的教师分组标记为转出(OUT)。
|
||||
// 这样既把已从用户中心移除/调离的教师清理出活跃名单,又保留转出记录、可随下次同步逆向恢复(重新 IN)。
|
||||
// 仅针对本次同步覆盖的学校,避免误删未参与本批次的其他学校教师。
|
||||
setTransferTeacher(schIds,incomingGroupKeys);
|
||||
|
||||
// 同步后使受影响学校的教师缓存失效
|
||||
if (!schIds.isEmpty()) {
|
||||
schTeacherCacheService.clearTeacherCaches(schIds);
|
||||
}
|
||||
}
|
||||
|
||||
private void setTransferTeacher( Set<Integer> schIds,Set<String> incomingGroupKeys)
|
||||
{
|
||||
for (Integer schId : schIds) {
|
||||
List<SchTeacherGroup> currentInGroups = schTeacherGroupRepository.findBySchIdAndTransferStatus(schId, TransferStatus.IN.getId());
|
||||
List<SchTeacherGroup> toTransferOut = new ArrayList<>();
|
||||
for (SchTeacherGroup g : currentInGroups) {
|
||||
String key = buildTeacherGroupKeyWithSchId(g.getTeaId(), g.getGroupId(), g.getSchId());
|
||||
if (!incomingGroupKeys.contains(key)) {
|
||||
g.setTransferStatus(TransferStatus.OUT.getId());
|
||||
toTransferOut.add(g);
|
||||
}
|
||||
}
|
||||
if (!toTransferOut.isEmpty()) {
|
||||
schTeacherGroupRepository.saveAll(toTransferOut);
|
||||
log.info("清理用户中心不存在的教师:schId={}, 转出教师分组数={}", schId, toTransferOut.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void updateTeacher(SchTeacher teacher, SyncUserDTO user, Date now) {
|
||||
teacher.setAccount(user.getAccount());
|
||||
teacher.setName(user.getName());
|
||||
|
||||
Reference in New Issue
Block a user