diff --git a/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/JYSController.java b/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/JYSController.java index fb76d9d92..1ecc7bec9 100644 --- a/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/JYSController.java +++ b/backend/roomroot-admin/src/main/java/com/roomroot/web/controller/jwgl/JYSController.java @@ -1,5 +1,6 @@ package com.roomroot.web.controller.jwgl; +import com.roomroot.common.core.domain.entity.SysUser; import com.roomroot.common.utils.StringUtils; import com.roomroot.jwgl.dto.faculty.AddTeacherDTO; import com.roomroot.jwgl.dto.jys.ElectiveCourseBatchDTO; @@ -225,7 +226,13 @@ public class JYSController { if (entity == null) { return Result.error("教员不存在:" + jybh); } - return Result.success(orgSyncService.ensureTeacherUser(entity, loginName, password, roleId)); + SysUser user = orgSyncService.ensureTeacherUser(entity, loginName, password, roleId); + String expected = StringUtils.hasText(loginName) ? loginName.trim() : jybh; + if (!expected.equals(user.getUserName())) { + return Result.success("登录名 " + expected + " 已被无关账号占用,已自动改用 " + + user.getUserName(), user.getUserId()); + } + return Result.success(user.getUserId()); } /** diff --git a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/OrgSyncService.java b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/OrgSyncService.java index 46b446cb1..3b73458fa 100644 --- a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/OrgSyncService.java +++ b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/OrgSyncService.java @@ -57,9 +57,10 @@ public interface OrgSyncService { * @param loginName 登录名(空则取教员编号) * @param password 初始密码明文(空则取统一初始值) * @param roleId 角色ID(空则取默认教员角色 101) - * @return 用户编号 USER_ID + * @return 创建/认领到的用户实体(含实际登录名,供调用方提示改名) */ - Long ensureTeacherUser(JYB jyb, String loginName, String password, Long roleId); + com.roomroot.common.core.domain.entity.SysUser ensureTeacherUser( + JYB jyb, String loginName, String password, Long roleId); /** * 教员信息变更后同步账号(调教研室迁移部门、改名、改手机号、离职禁用/复职启用)。 diff --git a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/impl/OrgSyncServiceImpl.java b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/impl/OrgSyncServiceImpl.java index b6f734107..c71a64841 100644 --- a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/impl/OrgSyncServiceImpl.java +++ b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/service/impl/OrgSyncServiceImpl.java @@ -55,6 +55,9 @@ public class OrgSyncServiceImpl implements OrgSyncService { if (jysb == null || StringUtils.isBlank(jysb.getJysdh())) { throw new BusinessException("教研室信息不完整,无法同步组织部门"); } + if (jysb.getTy() != null && jysb.getTy() == 1) { + throw new BusinessException("教研室「" + jysb.getJysmc() + "」已停用,不创建组织部门"); + } // 已映射:校验部门仍存在(被手工删除则重建) if (jysb.getBmbh() != null) { SysDept mapped = deptService.selectDeptById(jysb.getBmbh()); @@ -140,7 +143,7 @@ public class OrgSyncServiceImpl implements OrgSyncService { @Override @Transactional(rollbackFor = Exception.class) - public Long ensureTeacherUser(JYB jyb, String loginName, String password, Long roleId) { + public SysUser ensureTeacherUser(JYB jyb, String loginName, String password, Long roleId) { if (jyb == null || StringUtils.isBlank(jyb.getJybh())) { throw new BusinessException("教员信息不完整,无法创建账号"); } @@ -148,7 +151,7 @@ public class OrgSyncServiceImpl implements OrgSyncService { if (jyb.getYhbh() != null) { SysUser mapped = userService.selectUserById(jyb.getYhbh()); if (mapped != null && !"2".equals(mapped.getDelFlag())) { - return jyb.getYhbh(); + return mapped; } } if (jyb.getLzzt() != null && jyb.getLzzt() == 1) { @@ -160,13 +163,17 @@ public class OrgSyncServiceImpl implements OrgSyncService { String name = StringUtils.isBlank(loginName) ? jyb.getJybh() : loginName.trim(); SysUser existing = userService.selectUserByUserName(name); if (existing != null) { - // 孤儿账号(账号在、映射丢失):复用并回填锚点,不重复建号 - JYB relink = new JYB(); - relink.setJybh(jyb.getJybh()); - relink.setYhbh(existing.getUserId()); - relink.setBmbh(existing.getDeptId() != null ? existing.getDeptId() : deptId); - jybMapper.updateById(relink); - return existing.getUserId(); + if (canClaim(jyb, existing)) { + // 身份吻合(自动建号备注含教员编号,或昵称=教员姓名)→ 认领并回填锚点 + JYB relink = new JYB(); + relink.setJybh(jyb.getJybh()); + relink.setYhbh(existing.getUserId()); + relink.setBmbh(existing.getDeptId() != null ? existing.getDeptId() : deptId); + jybMapper.updateById(relink); + return existing; + } + // 身份不符:自动改用 原名_2 后缀,由返回的 SysUser.userName 告知调用方 + name = nextAvailableLoginName(name); } SysUser user = new SysUser(); user.setUserName(name); @@ -190,7 +197,27 @@ public class OrgSyncServiceImpl implements OrgSyncService { upd.setYhbh(user.getUserId()); upd.setBmbh(deptId); jybMapper.updateById(upd); - return user.getUserId(); + return user; + } + + /** 同名账号能否认领:自动建号的备注含教员编号,或账号昵称与教员姓名一致 */ + private boolean canClaim(JYB jyb, SysUser existing) { + if (existing.getRemark() != null && existing.getRemark().contains(jyb.getJybh())) { + return true; + } + return StringUtils.isNotBlank(jyb.getJyxm()) + && jyb.getJyxm().equals(existing.getNickName()); + } + + /** 登录名冲突时自动派生可用名:base_2、base_3…… */ + private String nextAvailableLoginName(String base) { + for (int i = 2; i <= 99; i++) { + String candidate = base + "_" + i; + if (userService.selectUserByUserName(candidate) == null) { + return candidate; + } + } + throw new BusinessException("登录名 " + base + " 冲突且自动后缀已用尽,请手工指定登录名"); } @Override @@ -299,6 +326,8 @@ public class OrgSyncServiceImpl implements OrgSyncService { wrapper.in(JYB::getJybh, jybhList); } List list = jybMapper.selectList(wrapper); + // 教研室状态缓存,避免逐行回表 + java.util.Map officeCache = new java.util.HashMap<>(); for (JYB jyb : list) { try { if (jyb.getYhbh() != null) { @@ -312,8 +341,42 @@ public class OrgSyncServiceImpl implements OrgSyncService { result.addSkip(jyb.getJyxm() + "(" + jyb.getJybh() + "):已离职,不建账号"); continue; } - Long userId = ensureTeacherUser(jyb, null, null, null); - result.addCreate(jyb.getJyxm() + "(" + jyb.getJybh() + "):新建账号 " + jyb.getJybh() + " #" + userId); + // 教研室前置校验:缺失/不存在/停用统一跳过,与 alignDepts 口径一致 + if (StringUtils.isBlank(jyb.getJysdh())) { + result.addSkip(jyb.getJyxm() + "(" + jyb.getJybh() + "):缺教研室代号,未建账号"); + continue; + } + JYSB office = officeCache.computeIfAbsent(jyb.getJysdh(), + jysbMapper::selectById); + if (office == null) { + result.addSkip(jyb.getJyxm() + "(" + jyb.getJybh() + "):教研室不存在 " + jyb.getJysdh() + ",未建账号"); + continue; + } + if (office.getTy() != null && office.getTy() == 1) { + result.addSkip(jyb.getJyxm() + "(" + jyb.getJybh() + "):所属教研室「" + + office.getJysmc() + "」已停用,未建账号"); + continue; + } + // 手机号冲突降级为跳过:教员档案保留,修正/清空号码后可再次对齐 + if (StringUtils.isNotBlank(jyb.getSjh())) { + SysUser probe = new SysUser(); + probe.setPhonenumber(jyb.getSjh()); + if (!userService.checkPhoneUnique(probe)) { + result.addSkip(jyb.getJyxm() + "(" + jyb.getJybh() + "):手机号 " + + jyb.getSjh() + " 已被其它账号占用,请先在教员档案中修改或清空该号码后重新对齐"); + continue; + } + } + SysUser user = ensureTeacherUser(jyb, null, null, null); + String actual = user.getUserName(); + if (jyb.getJybh().equals(actual)) { + result.addCreate(jyb.getJyxm() + "(" + jyb.getJybh() + "):新建账号 " + + actual + " #" + user.getUserId()); + } else { + result.addCreate(jyb.getJyxm() + "(" + jyb.getJybh() + "):登录名 " + + jyb.getJybh() + " 被无关账号占用,已自动改用 " + actual + + " #" + user.getUserId()); + } } catch (Exception e) { result.addFail(jyb.getJyxm() + "(" + jyb.getJybh() + "):" + e.getMessage()); } @@ -333,6 +396,10 @@ public class OrgSyncServiceImpl implements OrgSyncService { if (jysb == null) { throw new BusinessException("教研室不存在:" + jyb.getJysdh()); } + // 停用教研室不建部门:与 alignDepts 同一口径,必须在降级兜底之前拦截 + if (jysb.getTy() != null && jysb.getTy() == 1) { + throw new BusinessException("教研室「" + jysb.getJysmc() + "」已停用,不创建组织部门"); + } try { return ensureOfficeDept(jysb); } catch (Exception e) { diff --git a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/unit/PageQuery.java b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/unit/PageQuery.java index ea01a2f2a..efdad31d9 100644 --- a/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/unit/PageQuery.java +++ b/backend/roomroot-jwgl/src/main/java/com/roomroot/jwgl/unit/PageQuery.java @@ -23,7 +23,7 @@ public class PageQuery extends BaseQuery { */ @NotNull(message = "页码不能为空") @Min(value = 1, message = "页码最小为1") - private Integer pageNum; + private Integer pageNum = 1; /** * 每页记录数,默认20条,最小1条,最大100条 @@ -31,7 +31,7 @@ public class PageQuery extends BaseQuery { @NotNull(message = "每页大小不能为空") @Min(value = 1, message = "每页最小为1条") @Max(value = 100, message = "每页最大为100条") - private Integer pageSize; + private Integer pageSize = 10; public PageQuery() {}