From ac18366bfb764e950666beda5645f39c9f251846 Mon Sep 17 00:00:00 2001 From: wanghu Date: Thu, 27 Aug 2026 14:28:08 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AD=A6=E5=8F=B7=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bschclassmanage/enums/SyncDataType.java | 8 +- .../model/dto/StuTransferClassDTO.java | 11 ++- .../model/dto/TeaTransferInGroupDTO.java | 4 +- .../service/ISendUserBaseService.java | 8 ++ .../service/impl/com/SendUserBaseService.java | 73 ++++++++++++---- .../student/SchStudentTransferService.java | 66 +++++++------- .../teacher/SchTeacherRelationService.java | 85 +++++++++---------- 7 files changed, 155 insertions(+), 100 deletions(-) diff --git a/src/main/java/com/yunhai/bschclassmanage/enums/SyncDataType.java b/src/main/java/com/yunhai/bschclassmanage/enums/SyncDataType.java index 4b3fc2c..be0ca5e 100644 --- a/src/main/java/com/yunhai/bschclassmanage/enums/SyncDataType.java +++ b/src/main/java/com/yunhai/bschclassmanage/enums/SyncDataType.java @@ -40,7 +40,13 @@ public enum SyncDataType SEND_MOVE_TEACHER("Send-MoveTeacher","教师移组"), SEND_MOVE_STUDENT("Send-MoveStudent","学生调班"), SEND_BATCH_TEACHER("Send-BatchAddTeacher","批量添加教师"), - SEND_BATCH_STUDENT("Send-BatchAddStudent","批量添加学生"); + SEND_BATCH_STUDENT("Send-BatchAddStudent","批量添加学生"), + + SEND_TRANSFER_OUT("Send-TransferOut","用户转出"), + SEND_TRANSFER_IN("Send-TransferIn","用户转入"), + + SEND_USEER_STATUS("Send-UserStatus","用户状态"); + private String key; private String name; diff --git a/src/main/java/com/yunhai/bschclassmanage/model/dto/StuTransferClassDTO.java b/src/main/java/com/yunhai/bschclassmanage/model/dto/StuTransferClassDTO.java index c06165d..32ed67e 100644 --- a/src/main/java/com/yunhai/bschclassmanage/model/dto/StuTransferClassDTO.java +++ b/src/main/java/com/yunhai/bschclassmanage/model/dto/StuTransferClassDTO.java @@ -7,13 +7,14 @@ import lombok.NoArgsConstructor; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; import java.util.List; /** * @Author wanghu * @Date 2026-6-10 15:09 (可以根据需要修改) - * @Description: + * @Description:学生转班/转入共用DTO + * - stuId:单个学生ID(转入 setTransferIn 使用) + * - stuIds:批量学生ID列表(批量转班 transferClass 使用) */ @Data @Builder @@ -21,8 +22,10 @@ import java.util.List; @AllArgsConstructor public class StuTransferClassDTO { - @NotNull(message = "学生ID列表不能为空") - @Size(min = 1, message = "至少选择一个学生") + /** 转入单个学生ID(setTransferIn 使用) */ + private Integer stuId; + + /** 批量转班学生ID列表(transferClass 使用) */ private List stuIds; @NotNull(message = "目标班级ID不能为空") diff --git a/src/main/java/com/yunhai/bschclassmanage/model/dto/TeaTransferInGroupDTO.java b/src/main/java/com/yunhai/bschclassmanage/model/dto/TeaTransferInGroupDTO.java index cc63c28..aff3694 100644 --- a/src/main/java/com/yunhai/bschclassmanage/model/dto/TeaTransferInGroupDTO.java +++ b/src/main/java/com/yunhai/bschclassmanage/model/dto/TeaTransferInGroupDTO.java @@ -22,7 +22,9 @@ import java.util.List; public class TeaTransferInGroupDTO { @NotNull(message = "教师ID列表不能为空") @Size(min = 1, message = "至少选择一个教师") - private List schTeaIds; + private Integer teaId; + + private Integer schId; @NotNull(message = "目标组ID不能为空") @Min(value=0, message = "至少选择一个组") diff --git a/src/main/java/com/yunhai/bschclassmanage/service/ISendUserBaseService.java b/src/main/java/com/yunhai/bschclassmanage/service/ISendUserBaseService.java index a78d89c..cf869e3 100644 --- a/src/main/java/com/yunhai/bschclassmanage/service/ISendUserBaseService.java +++ b/src/main/java/com/yunhai/bschclassmanage/service/ISendUserBaseService.java @@ -51,4 +51,12 @@ public interface ISendUserBaseService { List batchAddStudent(List stuList); List batchAddTeacher(List teacherList); + + /** 学生转出:将平台用户状态置为转出(state=1) */ + void setUserGroupState(Integer userId, Integer groupId, Integer schoolId); + + /** 学生转入:将用户转移到目标学校/班级,返回平台用户信息 */ + BoaUser transferUserToSchool(Integer userId, Integer fromSchoolId, Integer schoolId, Integer groupId); + + void changeUserStatus(Integer userId,boolean disabled); } diff --git a/src/main/java/com/yunhai/bschclassmanage/service/impl/com/SendUserBaseService.java b/src/main/java/com/yunhai/bschclassmanage/service/impl/com/SendUserBaseService.java index 5a076e3..c9d1481 100644 --- a/src/main/java/com/yunhai/bschclassmanage/service/impl/com/SendUserBaseService.java +++ b/src/main/java/com/yunhai/bschclassmanage/service/impl/com/SendUserBaseService.java @@ -11,6 +11,8 @@ import com.yunhai.bschclassmanage.model.dto.SchTeacherDTO; import com.yunhai.bschclassmanage.model.dto.SendMoveGroupUserDTO; import com.yunhai.bschclassmanage.service.IComSchTreeService; import com.yunhai.bschclassmanage.service.ISendUserBaseService; +import com.yunhai.platform.openapi.client.OpenApiGroupClient; +import com.yunhai.platform.openapi.client.OpenApiUserClient; import com.yunhai.platform.openapi.client.YschBaseOpenApi; import com.yunhai.platform.openapi.model.*; import com.yunhai.platform.utils.exception.DException; @@ -32,9 +34,18 @@ import java.util.List; @Service public class SendUserBaseService implements ISendUserBaseService { + private static final Logger log = LoggerFactory.getLogger(SendUserBaseService.class); + @Autowired private IComSchTreeService comSchTreeService; + @Autowired + private OpenApiUserClient openApiUserClient; + + @Autowired + private OpenApiGroupClient openApiGroupClient; + + @SyncOpLog(SyncDataType.SEND_ADD_GROUP) public BoaGroup addGroup(String name, Integer parentId, Integer sort, NodeType type,Integer schId){ comSchTreeService.clearCache(); @@ -43,7 +54,7 @@ public class SendUserBaseService implements ISendUserBaseService { group.setParentId(parentId); group.setSort(sort); group.setType(type.getId()); - return YschBaseOpenApi.addGroup(group); + return openApiGroupClient.addGroup(group); } @@ -55,7 +66,7 @@ public class SendUserBaseService implements ISendUserBaseService { group.setParentId(parentId); group.setSort(sort); group.setType(type.getId()); - YschBaseOpenApi.editGroup(id,group); + openApiGroupClient.editGroup(id,group); } @SyncOpLog(SyncDataType.SEND_MOVE_GROUP) @@ -64,7 +75,7 @@ public class SendUserBaseService implements ISendUserBaseService { SysGroupMoveRequest group=new SysGroupMoveRequest(); group.setMoveId(moveId); group.setPid(pid); - YschBaseOpenApi.moveGroup(schId,group); + openApiGroupClient.moveGroup(schId,group); } @SyncOpLog(SyncDataType.SEND_DELETE_GROUP) @@ -74,7 +85,7 @@ public class SendUserBaseService implements ISendUserBaseService { BoaGroup group= YschBaseOpenApi.getGroupById(id,false); if(group!=null) { - YschBaseOpenApi.deleteGroup(id,schId); + openApiGroupClient.deleteGroup(id,schId); } }finally { @@ -96,7 +107,7 @@ public class SendUserBaseService implements ISendUserBaseService { sysUser.setPassword(pwd); sysUser.setConfirmPassword(pwd); } - return YschBaseOpenApi.addUser(sysUser); + return openApiUserClient.addUser(sysUser); } @SyncOpLog(SyncDataType.SEND_ADD_STUDENT) @@ -112,7 +123,7 @@ public class SendUserBaseService implements ISendUserBaseService { sysUser.setPassword(pwd); sysUser.setConfirmPassword(pwd); } - return YschBaseOpenApi.addUser(sysUser); + return openApiUserClient.addUser(sysUser); } @SyncOpLog(SyncDataType.SEND_EDIT_TEACHER) @@ -131,7 +142,7 @@ public class SendUserBaseService implements ISendUserBaseService { if (StringUtils.isNotBlank(pwd)) { user.setPassword(pwd); } - return YschBaseOpenApi.editUser(teacher.getTeaId(),user); + return openApiUserClient.editUser(teacher.getTeaId(),user); } @SyncOpLog(SyncDataType.SEND_EDIT_STUDENT) @@ -149,7 +160,7 @@ public class SendUserBaseService implements ISendUserBaseService { if (StringUtils.isNotBlank(pwd)) { user.setPassword(pwd); } - return YschBaseOpenApi.editUser(student.getStuId(),user); + return openApiUserClient.editUser(student.getStuId(),user); } @@ -165,7 +176,7 @@ public class SendUserBaseService implements ISendUserBaseService { } if(deletes!=null&&deletes.size()>0) { - YschBaseOpenApi.deleteUsers(deletes); + openApiUserClient.deleteUsers(deletes); } } @@ -181,7 +192,7 @@ public class SendUserBaseService implements ISendUserBaseService { } if(deletes!=null&&deletes.size()>0) { - YschBaseOpenApi.deleteUsers(deletes); + openApiUserClient.deleteUsers(deletes); } } @@ -227,7 +238,7 @@ public class SendUserBaseService implements ISendUserBaseService { } } - private static final Logger log = LoggerFactory.getLogger(SendUserBaseService.class); + /** * 导入失败回滚:删除已成功推送到平台的组(年级组/班级组/学段组),避免留下孤儿组。 @@ -257,7 +268,7 @@ public class SendUserBaseService implements ISendUserBaseService { SysUserMoveRequest move=new SysUserMoveRequest(); move.setUserId(teacher.getUserId()); move.setGroupId(teacher.getGroupId()); - YschBaseOpenApi.moveUserToGroup(move); + openApiUserClient.moveUserToGroup(move); } } @@ -269,7 +280,7 @@ public class SendUserBaseService implements ISendUserBaseService { move.setUserId(stuId); move.setGroupId(classId); move.setSchoolId(schId); - YschBaseOpenApi.moveUserToGroup(move); + openApiUserClient.moveUserToGroup(move); } } @@ -294,7 +305,7 @@ public class SendUserBaseService implements ISendUserBaseService { } requests.add(sysUser); } - return YschBaseOpenApi.batchAddUsers(requests); + return openApiUserClient.batchAddUsers(requests); } @SyncOpLog(SyncDataType.SEND_BATCH_TEACHER) @@ -320,8 +331,40 @@ public class SendUserBaseService implements ISendUserBaseService { } requests.add(sysUser); } - return YschBaseOpenApi.batchAddUsers(requests); + return openApiUserClient.batchAddUsers(requests); } + @SyncOpLog(SyncDataType.SEND_TRANSFER_OUT) + @Override + public void setUserGroupState(Integer userId,Integer groupId,Integer schoolId) + { + //状态设置成1(转出) + SysUserGroupStateRequest request = new SysUserGroupStateRequest(); + request.setUserId(userId); + request.setGroupId(groupId); + request.setSchoolId(schoolId); + request.setState(1); + openApiUserClient.setUserGroupState(request); + } + + @SyncOpLog(SyncDataType.SEND_TRANSFER_IN) + @Override + public BoaUser transferUserToSchool(Integer userId,Integer fromSchoolId,Integer schoolId,Integer groupId) + { + SysUserTransferSchoolRequest request = new SysUserTransferSchoolRequest(); + request.setUserId(userId); + request.setFromSchoolId(fromSchoolId); + request.setSchoolId(schoolId); + request.setGroupId(groupId); + return openApiUserClient.transferUserToSchool(request); + } + + @SyncOpLog(SyncDataType.SEND_USEER_STATUS) + @Override + public void changeUserStatus(Integer userId,boolean disabled) + { + openApiUserClient.changeUserStatus(userId,disabled); + } + } diff --git a/src/main/java/com/yunhai/bschclassmanage/service/impl/student/SchStudentTransferService.java b/src/main/java/com/yunhai/bschclassmanage/service/impl/student/SchStudentTransferService.java index 47a73a9..bdf7b6e 100644 --- a/src/main/java/com/yunhai/bschclassmanage/service/impl/student/SchStudentTransferService.java +++ b/src/main/java/com/yunhai/bschclassmanage/service/impl/student/SchStudentTransferService.java @@ -54,6 +54,9 @@ public class SchStudentTransferService { Integer targetClassId = model.getTransferClassId(); List stuIds = model.getStuIds(); + if (stuIds == null || stuIds.isEmpty()) { + throw new DException("学生ID列表不能为空"); + } Date now = new Date(); // 校验目标班级是否存在且属于该校 @@ -136,6 +139,8 @@ public class SchStudentTransferService { throw new DException("以下学生不存在或不属于该校: " + missing); } + List syncStuIds=students.stream().map(s->s.getStuId()).collect(Collectors.toList()); + // 收集受影响的班级ID Set classIds = students.stream() .map(SchStudent::getClassId) @@ -159,69 +164,61 @@ public class SchStudentTransferService { // 异步记录操作日志 logService.setTransferOutLog(user, students, classIds); + + for (SchStudent stu:students) + { + sendUserBaseService.setUserGroupState(stu.getStuId(),stu.getGroupId(),stu.getSchId()); + } + } // ==================== 转入 ==================== /** - * 批量转入学生(将学生从其他学校/班级转入到目标班级) + * 转入学生(将学生从其他学校/班级转入到目标班级) */ public void setTransferIn(UserContext.UserInfo user, StuTransferClassDTO model) { Integer targetSchId = user.getSchId(); Integer targetClassId = model.getTransferClassId(); - List stuIds = model.getStuIds(); Date now = new Date(); // 校验目标班级是否属于本校 schClassRepository.findByClassIdAndSchId(targetClassId, targetSchId) .orElseThrow(() -> new DException("目标班级不存在")); - // 全局查询所有学生(必须用 findAllById,因为要跨校查) - List students = schStudentRepository.findAllById(stuIds); - if (students.size() != stuIds.size()) { - Set foundIds = students.stream().map(SchStudent::getId).collect(Collectors.toSet()); - List missing = stuIds.stream().filter(id -> !foundIds.contains(id)).collect(Collectors.toList()); - throw new DException("以下学生不存在: " + missing); + // 全局查询学生(必须跨校查,学生可能在其他学校) + if (model.getStuId() == null) { + throw new DException("学生ID不能为空"); } - // 过滤出真正需要更新的学生:排除已在目标学校且已在目标班级的学生 - List toUpdateStudents = students.stream() - .filter(s -> !(s.getSchId().equals(targetSchId) && targetClassId.equals(s.getClassId()))) - .collect(Collectors.toList()); + SchStudent student = schStudentRepository.findById(model.getStuId()) + .orElseThrow(() -> new DException("学生不存在!")); - if (toUpdateStudents.isEmpty()) { - // 所有学生已在本校目标班级,无需操作 - return; + // 已在目标学校且已在目标班级的学生无需操作 + if (student.getSchId().equals(targetSchId) && targetClassId.equals(student.getClassId())) { + throw new DException("已在目标学校且已在目标班级的学生无需操作!"); } // 收集受影响的缓存Key(旧班级 + 新班级) Set cacheKeysToDelete = new HashSet<>(); - for (SchStudent student : toUpdateStudents) { - if (student.getClassId() != null) { - String oldCacheKey = RedisConstants.SCHOOL_CLASS_STUDENT + "_" - + student.getSchId() + "_" + student.getClassId(); - cacheKeysToDelete.add(oldCacheKey); - } + if (student.getClassId() != null) { + cacheKeysToDelete.add(RedisConstants.SCHOOL_CLASS_STUDENT + "_" + + student.getSchId() + "_" + student.getClassId()); } // 新班级缓存(目标学校+目标班级) - String newCacheKey = RedisConstants.SCHOOL_CLASS_STUDENT + "_" - + targetSchId + "_" + targetClassId; - cacheKeysToDelete.add(newCacheKey); - - // 执行批量更新(更新学校和班级) - List idsToUpdate = toUpdateStudents.stream() - .map(SchStudent::getId) - .collect(Collectors.toList()); + cacheKeysToDelete.add(RedisConstants.SCHOOL_CLASS_STUDENT + "_" + + targetSchId + "_" + targetClassId); + // 执行批量更新(更新学校和班级,transferStatus 置为转入 0) int updated = schStudentRepository.batchUpdateSchIdAndClassId( - idsToUpdate, + Collections.singletonList(student.getId()), targetSchId, targetClassId, now, user.getUserId() ); - if (updated != idsToUpdate.size()) { - throw new DException("批量更新失败,可能部分学生已被删除或修改,请刷新后重试"); + if (updated != 1) { + throw new DException("批量更新失败,可能学生已被删除或修改,请刷新后重试"); } // 清除缓存(直接按Key删除) @@ -229,7 +226,10 @@ public class SchStudentTransferService { redisUtil.del(cacheKey); } + // 平台同步:转入目标学校/班级(fromSchoolId 取转入前的原学校) + sendUserBaseService.transferUserToSchool(student.getStuId(), student.getSchId(), targetSchId, targetClassId); + // 异步记录操作日志 - logService.setTransferInLog(user, toUpdateStudents, targetSchId, targetClassId); + logService.setTransferInLog(user, Collections.singletonList(student), targetSchId, targetClassId); } } \ No newline at end of file diff --git a/src/main/java/com/yunhai/bschclassmanage/service/impl/teacher/SchTeacherRelationService.java b/src/main/java/com/yunhai/bschclassmanage/service/impl/teacher/SchTeacherRelationService.java index dd0dffb..d7a91cf 100644 --- a/src/main/java/com/yunhai/bschclassmanage/service/impl/teacher/SchTeacherRelationService.java +++ b/src/main/java/com/yunhai/bschclassmanage/service/impl/teacher/SchTeacherRelationService.java @@ -111,6 +111,12 @@ public class SchTeacherRelationService { throw new DException("转出失败"); } + for (SchTeacher tea: teachers) + { + Integer groupId=tea.getGroupList().stream().map(s->s.getGroupId()).findFirst().get(); + sendUserBaseService.setUserGroupState(tea.getTeaId(),groupId,schId); + } + // 5. 异步日志 logService.setTransferOutLogs(user, teachers); @@ -122,11 +128,15 @@ public class SchTeacherRelationService { public void setTransferIn(UserContext.UserInfo user, TeaTransferInGroupDTO model) { Integer targetSchId = user.getSchId(); - List schTeaIds = model.getSchTeaIds(); Integer targetGroupId = model.getTransferGroupId(); + Integer teaId = model.getTeaId(); + Integer fromSchId = model.getSchId(); - if (schTeaIds == null || schTeaIds.isEmpty()) { - throw new DException("教师关联列表不能为空"); + if (teaId == null || teaId <= 0) { + throw new DException("教师ID不能为空"); + } + if (fromSchId == null || fromSchId <= 0) { + throw new DException("原学校ID不能为空"); } if (targetGroupId == null || targetGroupId <= 0) { throw new DException("目标组ID不合法"); @@ -135,60 +145,43 @@ public class SchTeacherRelationService { // 校验目标组属于当前学校 comSchTreeService.validateGroupsBelongToSchool(targetSchId, Collections.singletonList(targetGroupId)); - // 解析 schTeaIds - List oldRelations = new ArrayList<>(); - List teaIdList = new ArrayList<>(); - - for (String item : schTeaIds) { - String[] parts = item.split("_"); - if (parts.length != 2) { - throw new DException("无效的教师关联格式: " + item + ",应为 'schId_teaId'"); - } - Integer schId, teaId; - try { - schId = Integer.parseInt(parts[0]); - teaId = Integer.parseInt(parts[1]); - } catch (NumberFormatException e) { - throw new DException("教师关联包含非数字字符: " + item); - } - - List relations = schTeacherGroupRepository.findByTeaIdAndSchId(teaId, schId); - if (relations.isEmpty()) { - throw new DException("教师 teaId=" + teaId + " 在学校 schId=" + schId + " 下无关联记录"); - } - oldRelations.addAll(relations); - teaIdList.add(teaId); + // 查询教师在原学校的关联记录(可跨校) + List oldRelations = schTeacherGroupRepository.findByTeaIdAndSchId(teaId, fromSchId); + if (oldRelations.isEmpty()) { + throw new DException("教师 teaId=" + teaId + " 在学校 schId=" + fromSchId + " 下无关联记录"); } - teaIdList = teaIdList.stream().distinct().collect(Collectors.toList()); - - // 删除所有旧关联 - if (!oldRelations.isEmpty()) { - schTeacherGroupRepository.deleteAll(oldRelations); + // 已在目标学校且已在目标组,无需操作 + boolean alreadyInTarget = oldRelations.stream() + .anyMatch(r -> targetSchId.equals(r.getSchId()) && targetGroupId.equals(r.getGroupId())); + if (alreadyInTarget) { + return; } - // 插入新关联 - List newRelations = new ArrayList<>(); - for (Integer teaId : teaIdList) { - SchTeacherGroup newRel = new SchTeacherGroup(); - newRel.setTeaId(teaId); - newRel.setGroupId(targetGroupId); - newRel.setSchId(targetSchId); - newRel.setTransferStatus(TransferStatus.IN.getId()); - newRelations.add(newRel); - } + // 删除原学校旧关联 + schTeacherGroupRepository.deleteAll(oldRelations); - if (!newRelations.isEmpty()) { - List teachers = schTeacherRepository.findByTeaIdIn(teaIdList); - logService.setTransferInLogs(user, teachers, targetGroupId); - schTeacherGroupRepository.saveAll(newRelations); - } + // 插入目标学校/目标组新关联(transferStatus 置为转入 0) + SchTeacherGroup newRel = new SchTeacherGroup(); + newRel.setTeaId(teaId); + newRel.setGroupId(targetGroupId); + newRel.setSchId(targetSchId); + newRel.setTransferStatus(TransferStatus.IN.getId()); + schTeacherGroupRepository.save(newRel); + + // 平台同步:转入目标学校/目标组 + sendUserBaseService.transferUserToSchool(teaId, fromSchId, targetSchId, targetGroupId); + + // 异步记录操作日志 + schTeacherRepository.findByTeaId(teaId).ifPresent(teacher -> + logService.setTransferInLogs(user, Collections.singletonList(teacher), targetGroupId)); // 清除所有涉及学校的缓存 Set involvedSchIds = new HashSet<>(); involvedSchIds.add(targetSchId); oldRelations.forEach(r -> involvedSchIds.add(r.getSchId())); cacheService.clearTeacherCaches(involvedSchIds); + } // ==================== 移动组 ====================