1
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
package com.yunhai.bschclassmanage.service;
|
||||
|
||||
import com.yunhai.bschclassmanage.entity.BaseDicGrade;
|
||||
import com.yunhai.bschclassmanage.enums.NodeType;
|
||||
import com.yunhai.bschclassmanage.model.tool.BaseGroup;
|
||||
import com.yunhai.bschclassmanage.model.tool.SyncGroupDTO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
@@ -10,7 +8,7 @@ import java.util.List;
|
||||
@Service
|
||||
public interface ISyncGroupService {
|
||||
|
||||
void syncAddOrUpdate(BaseGroup group);
|
||||
void addOrUpdateSchool(BaseGroup group);
|
||||
void syncAddOrUpdate(SyncGroupDTO group);
|
||||
void addOrUpdateSchool(SyncGroupDTO group);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package com.yunhai.bschclassmanage.service;
|
||||
|
||||
import com.yunhai.bschclassmanage.model.tool.BaseGroup;
|
||||
import com.yunhai.bschclassmanage.model.tool.BaseUser;
|
||||
import com.yunhai.bschclassmanage.model.tool.DeleteUser;
|
||||
import com.yunhai.bschclassmanage.model.tool.SyncUserDTO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
@@ -10,7 +9,7 @@ import java.util.List;
|
||||
@Service
|
||||
public interface ISyncUserService {
|
||||
|
||||
void syncAddOrUpdate(List<BaseUser> userList);
|
||||
void syncAddOrUpdate(List<SyncUserDTO> userList);
|
||||
|
||||
void deleteUser(List<DeleteUser> deleteUserList);
|
||||
}
|
||||
|
||||
+47
-69
@@ -5,119 +5,98 @@ import com.yunhai.bschclassmanage.entity.*;
|
||||
import com.yunhai.bschclassmanage.enums.SchType;
|
||||
import com.yunhai.bschclassmanage.model.tool.YearTerm;
|
||||
import com.yunhai.bschclassmanage.service.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SchClassUpgradeService {
|
||||
|
||||
@Autowired
|
||||
private SchClassCacheService schClassCacheService;
|
||||
|
||||
@Autowired
|
||||
private SchClassQueryService queryService;
|
||||
|
||||
@Autowired
|
||||
private SchClassRepository schClassRepository;
|
||||
|
||||
@Autowired
|
||||
private ISchBinSchsystemService schBinSchsystemService;
|
||||
|
||||
@Autowired
|
||||
private IBaseSchsystemGradeService baseSchsystemGradeService;
|
||||
|
||||
@Autowired
|
||||
private IBaseYearTermService baseYearTermService;
|
||||
|
||||
@Autowired
|
||||
private UpgradeLogRepository upgradeLogRepository;
|
||||
|
||||
@Autowired
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
private final SchClassCacheService schClassCacheService;
|
||||
private final SchClassRepository schClassRepository;
|
||||
private final ISchBinSchsystemService schBinSchsystemService;
|
||||
private final IBaseSchsystemGradeService baseSchsystemGradeService;
|
||||
private final IBaseYearTermService baseYearTermService;
|
||||
private final UpgradeLogRepository upgradeLogRepository;
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
|
||||
public void upgradeAllClasses() {
|
||||
Date now = new Date();
|
||||
// 获取当前学年学期
|
||||
YearTerm yearTerm = baseYearTermService.getCurrentYearTerm();
|
||||
if (yearTerm == null) {
|
||||
log.error("当前学年学期未配置,升级中止");
|
||||
return;
|
||||
}
|
||||
int currentYear = yearTerm.getYear();
|
||||
|
||||
List<Integer> schoolIds = schBinSchsystemService.getSchIds();
|
||||
|
||||
for (Integer schId : schoolIds) {
|
||||
// ----- 2. 获取该校所有学制 -----
|
||||
List<Integer> schsystemIds = schBinSchsystemService.getSchBinSchsystemIds(schId);
|
||||
// 学校类型在整个学校维度内不变,提升到学制循环外只查一次
|
||||
Integer schType = schBinSchsystemService.getSchType(schId);
|
||||
|
||||
// ----- 获取该校所有学制 -----
|
||||
List<Integer> schsystemIds = schBinSchsystemService.getSchBinSchsystemIds(schId);
|
||||
for (Integer sysId : schsystemIds) {
|
||||
Boolean status=true;
|
||||
if (upgradeLogRepository.existsBySchIdAndSysIdAndYearAndStatus(schId, sysId, currentYear,status)) {
|
||||
log.info("学校{}学制{}学年{}学期已升级,跳过", schId, sysId, currentYear);
|
||||
continue; // 直接返回,不做任何操作
|
||||
// 已成功升级过的(学年+学制)直接跳过,避免重复升级
|
||||
if (upgradeLogRepository.existsBySchIdAndSysIdAndYearAndStatus(schId, sysId, currentYear, true)) {
|
||||
log.info("学校{}学制{}学年{}已成功升级,跳过", schId, sysId, currentYear);
|
||||
continue;
|
||||
}
|
||||
boolean success = true;
|
||||
try {
|
||||
upgradeSingleSystem(schId,schType,sysId,now);
|
||||
upgradeSingleSystem(schId, schType, sysId, now);
|
||||
log.info("学校{} 学制{} 学年{} 升级执行成功", schId, sysId, currentYear);
|
||||
} catch (Exception e) {
|
||||
success = false;
|
||||
log.error("学校{}学制{}升级失败,已跳过,不影响其他学制", schId, sysId, e);
|
||||
status=false;
|
||||
}
|
||||
upgradeLogRepository.save(new UpgradeLog(schId, sysId, currentYear,now,status));
|
||||
// 无论成功失败都落升级日志,失败记录便于下次重试(existsBy...Status=true 不命中即可重跑)
|
||||
try {
|
||||
upgradeLogRepository.save(new UpgradeLog(schId, sysId, currentYear, now, success));
|
||||
} catch (Exception e) {
|
||||
log.error("学校{}学制{}升级结果日志写入失败", schId, sysId, e);
|
||||
}
|
||||
}
|
||||
// 清除该校缓存
|
||||
// 升级完成后清除该校班级缓存(含毕业缓存),避免脏数据
|
||||
schClassCacheService.clearClassCache(schId);
|
||||
schClassCacheService.clearGradeateClassCache(schId);
|
||||
}
|
||||
}
|
||||
|
||||
//升级业务逻辑
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
protected void upgradeSingleSystem(Integer schId,Integer schType, Integer sysId, Date now) {
|
||||
// 1. 检查是否已升级(利用数据库唯一索引防并发)
|
||||
// 2. 执行升级逻辑
|
||||
// 3. 插入升级日志
|
||||
|
||||
protected void upgradeSingleSystem(Integer schId, Integer schType, Integer sysId, Date now) {
|
||||
// 1. 获取该学制下的年级定义(轻量、带缓存),得到年级集合与最高年级
|
||||
Map<Integer, String> gradeMap = baseSchsystemGradeService.getGradeNameMap(schId, sysId, null);
|
||||
if (gradeMap == null || gradeMap.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<Integer> gradeIds = new ArrayList<>(gradeMap.keySet());
|
||||
Collections.sort(gradeIds);
|
||||
if (gradeIds.isEmpty()) return;
|
||||
|
||||
Integer maxGrade = gradeIds.get(gradeIds.size() - 1);
|
||||
|
||||
// ----- 3. 升级非最高年级 -----
|
||||
for (Integer gradeId : gradeIds) {
|
||||
if (gradeId.equals(maxGrade)) continue;
|
||||
List<SchClass> classList = queryService.getSchClassCacheFilter(schId, gradeId, null);
|
||||
if (classList.isEmpty()) continue;
|
||||
|
||||
// 执行升级
|
||||
for (SchClass clazz : classList) {
|
||||
if(schType.equals(SchType.BASICEDUCATION.getKey())) {
|
||||
clazz.setGradeId(gradeId + 1);//基础教育年级+1
|
||||
}
|
||||
clazz.setUpdateDate(now);
|
||||
clazz.setUpdateUserId(0);
|
||||
// 2. 非最高年级:基础教育整体升一级(SET 语义,单语句原子完成)
|
||||
if (SchType.BASICEDUCATION.getKey().equals(schType)) {
|
||||
List<Integer> nonMaxGrades = new ArrayList<>(gradeIds.subList(0, gradeIds.size() - 1));
|
||||
if (!nonMaxGrades.isEmpty()) {
|
||||
int updated = schClassRepository.batchUpgradeGrade(schId, nonMaxGrades, now);
|
||||
log.info("学校{}学制{} 非最高年级升一级,影响班级数={}", schId, sysId, updated);
|
||||
}
|
||||
schClassRepository.saveAll(classList);
|
||||
}
|
||||
|
||||
// ----- 4. 处理最高年级(毕业) -----
|
||||
List<SchClass> graduateClassList = queryService.getSchClassCacheFilter(schId, maxGrade, null);
|
||||
if (!graduateClassList.isEmpty()) {
|
||||
for (SchClass clazz : graduateClassList) {
|
||||
clazz.setGraduate(true);
|
||||
clazz.setUpdateDate(now);
|
||||
clazz.setUpdateUserId(0);
|
||||
}
|
||||
schClassRepository.saveAll(graduateClassList);
|
||||
}
|
||||
|
||||
// 3. 最高年级:毕业
|
||||
int graduated = schClassRepository.batchGraduate(schId, maxGrade, now);
|
||||
log.info("学校{}学制{} 最高年级(年级ID={})毕业,影响班级数={}", schId, sysId, maxGrade, graduated);
|
||||
}
|
||||
|
||||
|
||||
@@ -151,5 +130,4 @@ public class SchClassUpgradeService {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.yunhai.bschclassmanage.Repository.SchInfoRepository;
|
||||
import com.yunhai.bschclassmanage.entity.SchInfo;
|
||||
import com.yunhai.bschclassmanage.enums.NodeType;
|
||||
import com.yunhai.bschclassmanage.model.tool.BaseGroup;
|
||||
import com.yunhai.bschclassmanage.model.tool.SyncGroupDTO;
|
||||
import com.yunhai.bschclassmanage.service.ISyncGroupService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -19,7 +20,7 @@ public class SyncGroupService implements ISyncGroupService {
|
||||
private SchInfoRepository schInfoRepository;
|
||||
|
||||
|
||||
public void syncAddOrUpdate(BaseGroup group) {
|
||||
public void syncAddOrUpdate(SyncGroupDTO group) {
|
||||
|
||||
//学校组 年级组 班级组
|
||||
if(group.getType().equals(NodeType.SCHOOL.getId())){
|
||||
@@ -37,7 +38,7 @@ public class SyncGroupService implements ISyncGroupService {
|
||||
}
|
||||
|
||||
|
||||
public void addOrUpdateSchool(BaseGroup group)
|
||||
public void addOrUpdateSchool(SyncGroupDTO group)
|
||||
{
|
||||
Optional<SchInfo> schOpt=schInfoRepository.findBySchId(group.getId());
|
||||
if(schOpt.isPresent()){
|
||||
|
||||
@@ -1,33 +1,31 @@
|
||||
package com.yunhai.bschclassmanage.service.impl.sync;
|
||||
|
||||
import com.yunhai.bschclassmanage.Repository.SchInfoRepository;
|
||||
import com.yunhai.bschclassmanage.Repository.SchStudentRepository;
|
||||
import com.yunhai.bschclassmanage.Repository.SchTeacherGroupRepository;
|
||||
import com.yunhai.bschclassmanage.Repository.SchTeacherRepository;
|
||||
import com.yunhai.bschclassmanage.entity.SchInfo;
|
||||
import com.yunhai.bschclassmanage.entity.SchStudent;
|
||||
import com.yunhai.bschclassmanage.entity.SchTeacher;
|
||||
import com.yunhai.bschclassmanage.entity.SchTeacherGroup;
|
||||
import com.yunhai.bschclassmanage.enums.NodeType;
|
||||
import com.yunhai.bschclassmanage.enums.StuAbnormalStatus;
|
||||
import com.yunhai.bschclassmanage.enums.TransferStatus;
|
||||
import com.yunhai.bschclassmanage.enums.UserRole;
|
||||
import com.yunhai.bschclassmanage.model.tool.BaseGroup;
|
||||
import com.yunhai.bschclassmanage.model.tool.BaseUser;
|
||||
import com.yunhai.bschclassmanage.model.tool.DeleteUser;
|
||||
import com.yunhai.bschclassmanage.service.ISchTeacherService;
|
||||
import com.yunhai.bschclassmanage.model.tool.SyncUserDTO;
|
||||
import com.yunhai.bschclassmanage.model.tool.SyncUserGroupDTO;
|
||||
import com.yunhai.bschclassmanage.model.tool.SyncUserRoleDTO;
|
||||
import com.yunhai.bschclassmanage.service.ISyncUserService;
|
||||
import com.yunhai.bschclassmanage.service.impl.student.SchStudentCacheService;
|
||||
import com.yunhai.bschclassmanage.service.impl.teacher.SchTeacherCacheService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SyncUserService implements ISyncUserService {
|
||||
|
||||
@@ -47,18 +45,25 @@ public class SyncUserService implements ISyncUserService {
|
||||
private SchTeacherCacheService schTeacherCacheService;
|
||||
|
||||
// ==================== 同步入口 ====================
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void syncAddOrUpdate(List<BaseUser> userList) {
|
||||
public void syncAddOrUpdate(List<SyncUserDTO> userList) {
|
||||
if (userList == null || userList.isEmpty()) return;
|
||||
|
||||
// 按角色分组
|
||||
List<BaseUser> syncStudentList = new ArrayList<>();
|
||||
List<BaseUser> syncTeacherList = new ArrayList<>();
|
||||
// 按角色分组(每个用户只遍历一次 roleList)
|
||||
List<SyncUserDTO> syncStudentList = new ArrayList<>();
|
||||
List<SyncUserDTO> syncTeacherList = new ArrayList<>();
|
||||
|
||||
for (BaseUser user : userList) {
|
||||
if (isStudent(user)) syncStudentList.add(user);
|
||||
if (isTeacher(user)) syncTeacherList.add(user);
|
||||
for (SyncUserDTO user : userList) {
|
||||
Set<Integer> roleIds = collectRoleIds(user);
|
||||
if (isStudent(roleIds)) {
|
||||
syncStudentList.add(user);
|
||||
} else if (isTeacher(roleIds)) {
|
||||
syncTeacherList.add(user);
|
||||
} else {
|
||||
log.error("用户:{} 角色不符合同步要求!", user.getAccount());
|
||||
}
|
||||
}
|
||||
|
||||
Date now = new Date();
|
||||
@@ -71,124 +76,112 @@ public class SyncUserService implements ISyncUserService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteUser(List<DeleteUser> deleteUserList) {
|
||||
if (deleteUserList == null || deleteUserList.isEmpty()) return;
|
||||
|
||||
// 提取所有 userId
|
||||
List<Integer> allUserIds = deleteUserList.stream()
|
||||
.map(DeleteUser::getUserId)
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
if (allUserIds.isEmpty()) return;
|
||||
|
||||
// ---------- 1. 物理删除学生 ----------
|
||||
List<DeleteUser> studentDeletes = deleteUserList.stream()
|
||||
// 过滤出有效的 (userId, groupId) 条目,仅计算一次
|
||||
List<DeleteUser> validDeletes = deleteUserList.stream()
|
||||
.filter(du -> du.getUserId() != null && du.getGroupId() != null)
|
||||
.collect(Collectors.toList());
|
||||
if (!studentDeletes.isEmpty()) {
|
||||
// 批量查询学生
|
||||
List<SchStudent> allStudents = schStudentRepository.findByStuIdIn(allUserIds);
|
||||
Map<String, SchStudent> studentMap = allStudents.stream()
|
||||
.collect(Collectors.toMap(
|
||||
s -> buildStudentKey(s.getStuId(), s.getGroupId()),
|
||||
Function.identity()
|
||||
));
|
||||
List<SchStudent> toDelete = new ArrayList<>();
|
||||
for (DeleteUser du : studentDeletes) {
|
||||
String key = buildStudentKey(du.getUserId(), du.getGroupId());
|
||||
SchStudent stu = studentMap.get(key);
|
||||
if (stu != null) {
|
||||
toDelete.add(stu);
|
||||
if (validDeletes.isEmpty()) return;
|
||||
|
||||
List<Integer> allUserIds = validDeletes.stream()
|
||||
.map(DeleteUser::getUserId)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// ---------- 1. 物理删除学生 ----------
|
||||
List<SchStudent> toDeleteStudents = new ArrayList<>();
|
||||
Map<String, SchStudent> studentMap = schStudentRepository.findByStuIdIn(allUserIds).stream()
|
||||
.collect(Collectors.toMap(
|
||||
s -> buildStudentKey(s.getStuId(), s.getGroupId()),
|
||||
Function.identity()
|
||||
));
|
||||
for (DeleteUser du : validDeletes) {
|
||||
SchStudent stu = studentMap.get(buildStudentKey(du.getUserId(), du.getGroupId()));
|
||||
if (stu != null) {
|
||||
toDeleteStudents.add(stu);
|
||||
}
|
||||
}
|
||||
if (!toDeleteStudents.isEmpty()) {
|
||||
// 按 (schId, classId) 去重后清除缓存
|
||||
Map<Integer, Set<Integer>> classKeys = new HashMap<>();
|
||||
for (SchStudent stu : toDeleteStudents) {
|
||||
if (stu.getSchId() != null && stu.getGroupId() != null) {
|
||||
classKeys.computeIfAbsent(stu.getSchId(), k -> new HashSet<>()).add(stu.getGroupId());
|
||||
}
|
||||
}
|
||||
if (!toDelete.isEmpty()) {
|
||||
// 先清除缓存(需要 schId,可从学生实体获取或查询)
|
||||
for (SchStudent stu : toDelete) {
|
||||
// 假设 SchStudent 有 schId 字段,若没有则需通过 groupId 查询
|
||||
Integer schId = stu.getSchId(); // 若没有,调用 service 查询
|
||||
if (schId != null) {
|
||||
schStudentCacheService.clearClassStudentCache(schId, stu.getGroupId());
|
||||
}
|
||||
}
|
||||
// 物理删除
|
||||
schStudentRepository.deleteAll(toDelete);
|
||||
}
|
||||
classKeys.forEach((schId, classIds) -> schStudentCacheService.clearClassStudentCaches(schId, classIds));
|
||||
schStudentRepository.deleteAll(toDeleteStudents);
|
||||
}
|
||||
|
||||
// ---------- 2. 物理删除教师分组(不删教师主体) ----------
|
||||
List<DeleteUser> teacherDeletes = deleteUserList.stream()
|
||||
.filter(du -> du.getUserId() != null && du.getGroupId() != null)
|
||||
.collect(Collectors.toList());
|
||||
if (!teacherDeletes.isEmpty()) {
|
||||
// 查询所有涉及的分组
|
||||
List<SchTeacherGroup> allGroups = schTeacherGroupRepository.findByTeaIdIn(allUserIds);
|
||||
Map<String, SchTeacherGroup> groupMap = allGroups.stream()
|
||||
.collect(Collectors.toMap(
|
||||
g -> buildTeacherGroupKey(g.getTeaId(), g.getGroupId()),
|
||||
Function.identity()
|
||||
));
|
||||
List<SchTeacherGroup> toDeleteGroups = new ArrayList<>();
|
||||
for (DeleteUser du : teacherDeletes) {
|
||||
String key = buildTeacherGroupKey(du.getUserId(), du.getGroupId());
|
||||
SchTeacherGroup group = groupMap.get(key);
|
||||
if (group != null) {
|
||||
toDeleteGroups.add(group);
|
||||
}
|
||||
}
|
||||
|
||||
if (!toDeleteGroups.isEmpty()) {
|
||||
// 按学校维度分组,用于缓存清除和剩余分组检查
|
||||
Map<Integer, List<SchTeacherGroup>> groupsBySchool = toDeleteGroups.stream()
|
||||
.collect(Collectors.groupingBy(SchTeacherGroup::getSchId));
|
||||
|
||||
// 先清除缓存(针对每个分组所属学校)
|
||||
for (SchTeacherGroup group : toDeleteGroups) {
|
||||
schTeacherCacheService.clearTeacherCache(group.getSchId());
|
||||
}
|
||||
|
||||
// 物理删除分组
|
||||
schTeacherGroupRepository.deleteAll(toDeleteGroups);
|
||||
|
||||
// 同一 (teaId, groupId) 可能跨多所学校,用 List 收集避免重复键被丢弃
|
||||
Map<String, List<SchTeacherGroup>> groupMap = schTeacherGroupRepository.findByTeaIdIn(allUserIds).stream()
|
||||
.collect(Collectors.groupingBy(g -> buildTeacherGroupKey(g.getTeaId(), g.getGroupId())));
|
||||
List<SchTeacherGroup> toDeleteGroups = new ArrayList<>();
|
||||
for (DeleteUser du : validDeletes) {
|
||||
List<SchTeacherGroup> groups = groupMap.get(buildTeacherGroupKey(du.getUserId(), du.getGroupId()));
|
||||
if (groups != null) {
|
||||
toDeleteGroups.addAll(groups);
|
||||
}
|
||||
}
|
||||
if (!toDeleteGroups.isEmpty()) {
|
||||
// 按学校维度去重后清除缓存
|
||||
Set<Integer> schIds = toDeleteGroups.stream()
|
||||
.map(SchTeacherGroup::getSchId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
schTeacherCacheService.clearTeacherCaches(schIds);
|
||||
schTeacherGroupRepository.deleteAll(toDeleteGroups);
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 角色判断 ====================
|
||||
private boolean isStudent(BaseUser user) {
|
||||
if (user.getRoleList() == null) return false;
|
||||
|
||||
/**
|
||||
* 提取用户的角色 id 集合(去重、过滤空值),每个用户仅遍历一次。
|
||||
*/
|
||||
private Set<Integer> collectRoleIds(SyncUserDTO user) {
|
||||
if (user.getRoleList() == null) return Collections.emptySet();
|
||||
return user.getRoleList().stream()
|
||||
.anyMatch(r -> r.getRoleId() != null && r.getRoleId().equals(UserRole.STU_USER.getValue()));
|
||||
.filter(Objects::nonNull)
|
||||
.map(SyncUserRoleDTO::getRoleId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private boolean isTeacher(BaseUser user) {
|
||||
if (user.getRoleList() == null) return false;
|
||||
return user.getRoleList().stream()
|
||||
.anyMatch(r -> r.getRoleId() != null &&
|
||||
(r.getRoleId().equals(UserRole.TEACHER_USER.getValue()) ||
|
||||
r.getRoleId().equals(UserRole.SCH_LEADER_USER.getValue())));
|
||||
private boolean isStudent(Set<Integer> roleIds) {
|
||||
return roleIds.contains(UserRole.STU_USER.getValue());
|
||||
}
|
||||
|
||||
private boolean isTeacher(Set<Integer> roleIds) {
|
||||
return roleIds.contains(UserRole.TEACHER_USER.getValue())
|
||||
|| roleIds.contains(UserRole.SCH_LEADER_USER.getValue());
|
||||
}
|
||||
|
||||
// ==================== 学生同步 ====================
|
||||
private void syncStudents(List<BaseUser> studentUsers, Date now) {
|
||||
List<Integer> stuIds = studentUsers.stream().map(BaseUser::getId).distinct().collect(Collectors.toList());
|
||||
|
||||
private void syncStudents(List<SyncUserDTO> studentUsers, Date now) {
|
||||
List<Integer> stuIds = studentUsers.stream().map(SyncUserDTO::getId).distinct().collect(Collectors.toList());
|
||||
|
||||
// 已有学生记录 (stuId, groupId) -> SchStudent
|
||||
Map<String, SchStudent> studentMap = schStudentRepository.findByStuIdIn(stuIds)
|
||||
.stream()
|
||||
Map<String, SchStudent> studentMap = schStudentRepository.findByStuIdIn(stuIds).stream()
|
||||
.collect(Collectors.toMap(
|
||||
s -> buildStudentKey(s.getStuId(), s.getGroupId()),
|
||||
Function.identity()
|
||||
));
|
||||
|
||||
List<SchStudent> saveList = new ArrayList<>();
|
||||
// 受影响班级缓存键 (schId -> classId 集合),用于同步后失效
|
||||
Map<Integer, Set<Integer>> classKeys = new HashMap<>();
|
||||
|
||||
for (BaseUser user : studentUsers) {
|
||||
for (SyncUserDTO user : studentUsers) {
|
||||
if (user.getGroups() == null) continue;
|
||||
for (BaseUser.GroupInfo group : user.getGroups()) {
|
||||
|
||||
for (SyncUserGroupDTO group : user.getGroups()) {
|
||||
Integer groupId = group.getGroupId();
|
||||
Integer schId = group.getSchoolId();
|
||||
if (groupId == null || schId == null) continue;
|
||||
@@ -201,21 +194,18 @@ public class SyncUserService implements ISyncUserService {
|
||||
student = createStudent(user, group, now);
|
||||
}
|
||||
saveList.add(student);
|
||||
classKeys.computeIfAbsent(schId, k -> new HashSet<>()).add(groupId);
|
||||
}
|
||||
}
|
||||
|
||||
if (!saveList.isEmpty()) {
|
||||
schStudentRepository.saveAll(saveList);
|
||||
// 缓存:将学生加入班级缓存(Set结构)
|
||||
// for (SchStudent stu : saveList) {
|
||||
// if (stu.getSchId() != null && stu.getGroupId() != null) {
|
||||
// schStudentCacheService.addClassStudentCache(stu.getSchId(), stu.getGroupId(), stu.getStuId());
|
||||
// }
|
||||
// }
|
||||
// 同步后使受影响班级的学生缓存失效,避免读到旧数据
|
||||
classKeys.forEach((schId, classIds) -> schStudentCacheService.clearClassStudentCaches(schId, classIds));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStudent(SchStudent student, BaseUser user, BaseUser.GroupInfo group, Date now) {
|
||||
private void updateStudent(SchStudent student, SyncUserDTO user, SyncUserGroupDTO group, Date now) {
|
||||
student.setAccount(user.getAccount());
|
||||
student.setName(user.getName());
|
||||
student.setGender(user.getGender());
|
||||
@@ -228,7 +218,7 @@ public class SyncUserService implements ISyncUserService {
|
||||
student.setUpdateDate(now);
|
||||
}
|
||||
|
||||
private SchStudent createStudent(BaseUser user, BaseUser.GroupInfo group, Date now) {
|
||||
private SchStudent createStudent(SyncUserDTO user, SyncUserGroupDTO group, Date now) {
|
||||
SchStudent student = new SchStudent();
|
||||
student.setStuId(user.getId());
|
||||
student.setAccount(user.getAccount());
|
||||
@@ -248,17 +238,16 @@ public class SyncUserService implements ISyncUserService {
|
||||
}
|
||||
|
||||
// ==================== 教师同步 ====================
|
||||
private void syncTeachers(List<BaseUser> teacherUsers, Date now) {
|
||||
List<Integer> teaIds = teacherUsers.stream().map(BaseUser::getId).distinct().collect(Collectors.toList());
|
||||
|
||||
private void syncTeachers(List<SyncUserDTO> teacherUsers, Date now) {
|
||||
List<Integer> teaIds = teacherUsers.stream().map(SyncUserDTO::getId).distinct().collect(Collectors.toList());
|
||||
|
||||
// 教师主体(唯一)
|
||||
Map<Integer, SchTeacher> teacherMap = schTeacherRepository.findByTeaIdIn(teaIds)
|
||||
.stream()
|
||||
Map<Integer, SchTeacher> teacherMap = schTeacherRepository.findByTeaIdIn(teaIds).stream()
|
||||
.collect(Collectors.toMap(SchTeacher::getTeaId, Function.identity()));
|
||||
|
||||
// 教师分组 (teaId, groupId, schId) -> SchTeacherGroup
|
||||
Map<String, SchTeacherGroup> groupMap = schTeacherGroupRepository.findByTeaIdIn(teaIds)
|
||||
.stream()
|
||||
Map<String, SchTeacherGroup> groupMap = schTeacherGroupRepository.findByTeaIdIn(teaIds).stream()
|
||||
.collect(Collectors.toMap(
|
||||
g -> buildTeacherGroupKeyWithSchId(g.getTeaId(), g.getGroupId(), g.getSchId()),
|
||||
Function.identity()
|
||||
@@ -266,8 +255,10 @@ public class SyncUserService implements ISyncUserService {
|
||||
|
||||
List<SchTeacher> saveTeacherList = new ArrayList<>();
|
||||
List<SchTeacherGroup> saveGroupList = new ArrayList<>();
|
||||
// 受影响学校缓存键,用于同步后失效
|
||||
Set<Integer> schIds = new HashSet<>();
|
||||
|
||||
for (BaseUser user : teacherUsers) {
|
||||
for (SyncUserDTO user : teacherUsers) {
|
||||
// 教师主体(只存一条)
|
||||
SchTeacher teacher = teacherMap.get(user.getId());
|
||||
if (teacher != null) {
|
||||
@@ -279,7 +270,7 @@ public class SyncUserService implements ISyncUserService {
|
||||
|
||||
// 教师分组(遍历 groups)
|
||||
if (user.getGroups() == null) continue;
|
||||
for (BaseUser.GroupInfo group : user.getGroups()) {
|
||||
for (SyncUserGroupDTO group : user.getGroups()) {
|
||||
Integer groupId = group.getGroupId();
|
||||
Integer schId = group.getSchoolId();
|
||||
if (groupId == null || schId == null) continue;
|
||||
@@ -293,6 +284,7 @@ public class SyncUserService implements ISyncUserService {
|
||||
tg = createTeacherGroup(user, group, now);
|
||||
}
|
||||
saveGroupList.add(tg);
|
||||
schIds.add(schId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,18 +293,14 @@ public class SyncUserService implements ISyncUserService {
|
||||
}
|
||||
if (!saveGroupList.isEmpty()) {
|
||||
schTeacherGroupRepository.saveAll(saveGroupList);
|
||||
// // 缓存:更新教师缓存(学校维度)
|
||||
// // 为简单起见,清除每个涉及的学校缓存,然后重新添加该学校所有教师(但这里我们只添加本次更新的教师,因为Set可重复)
|
||||
// // 更稳健:清除后重建,但为了减少数据库查询,我们使用 add 方法
|
||||
// for (SchTeacherGroup g : saveGroupList) {
|
||||
// if (g.getSchId() != null) {
|
||||
// schTeacherCacheService.addSchoolTeacherCache(g.getSchId(), g.getTeaId());
|
||||
// }
|
||||
// }
|
||||
}
|
||||
// 同步后使受影响学校的教师缓存失效
|
||||
if (!schIds.isEmpty()) {
|
||||
schTeacherCacheService.clearTeacherCaches(schIds);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTeacher(SchTeacher teacher, BaseUser user, Date now) {
|
||||
private void updateTeacher(SchTeacher teacher, SyncUserDTO user, Date now) {
|
||||
teacher.setAccount(user.getAccount());
|
||||
teacher.setName(user.getName());
|
||||
teacher.setGender(user.getGender());
|
||||
@@ -322,7 +310,7 @@ public class SyncUserService implements ISyncUserService {
|
||||
teacher.setUpdateDate(now);
|
||||
}
|
||||
|
||||
private SchTeacher createTeacher(BaseUser user, Date now) {
|
||||
private SchTeacher createTeacher(SyncUserDTO user, Date now) {
|
||||
SchTeacher teacher = new SchTeacher();
|
||||
teacher.setTeaId(user.getId());
|
||||
teacher.setAccount(user.getAccount());
|
||||
@@ -336,7 +324,7 @@ public class SyncUserService implements ISyncUserService {
|
||||
return teacher;
|
||||
}
|
||||
|
||||
private SchTeacherGroup createTeacherGroup(BaseUser user, BaseUser.GroupInfo group, Date now) {
|
||||
private SchTeacherGroup createTeacherGroup(SyncUserDTO user, SyncUserGroupDTO group, Date now) {
|
||||
SchTeacherGroup tg = new SchTeacherGroup();
|
||||
tg.setTeaId(user.getId());
|
||||
tg.setGroupId(group.getGroupId());
|
||||
@@ -346,6 +334,7 @@ public class SyncUserService implements ISyncUserService {
|
||||
}
|
||||
|
||||
// ==================== 辅助键生成 ====================
|
||||
|
||||
private String buildStudentKey(Integer stuId, Integer groupId) {
|
||||
return stuId + "_" + groupId;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user