This commit is contained in:
@@ -69,6 +69,9 @@ public class SysUserService implements ISysUserService {
|
||||
/** 主归属标识:1=本职主学校/部门 */
|
||||
private static final int IS_MAIN = 1;
|
||||
|
||||
/** 开放接口/oapi 写操作无登录态时使用的审计人哨兵值(非真实用户ID),用于兜底 create_user/update_user 的 NOT NULL 约束。 */
|
||||
private static final int SYSTEM_USER_ID = 0;
|
||||
|
||||
/** 系统内置超级管理员账号(与 sys_user_init.sql 种子账号保持一致) */
|
||||
private static final Set<String> SUPER_ADMIN_ACCOUNTS =
|
||||
new HashSet<>(Arrays.asList("yunhaisch", "yunhaisch2", "yunhaisch3"));
|
||||
@@ -136,6 +139,9 @@ public class SysUserService implements ISysUserService {
|
||||
// disabled 用枚举存储:不传时默认 NORMAL(正常/未禁用)
|
||||
entity.setDisabled(request.getDisabled() != null ? resolveStatus(request.getDisabled()) : StatusEnum.NORMAL);
|
||||
entity.setExpired(request.getExpired() != null ? request.getExpired() : false);
|
||||
// oapi 写操作无登录态时,用系统哨兵值兜底 create_user/update_user(NOT NULL 约束)
|
||||
entity.setCreateUser(SYSTEM_USER_ID);
|
||||
entity.setUpdateUser(SYSTEM_USER_ID);
|
||||
SysUser saved = sysUserRepository.save(entity);
|
||||
publishUserEvent(PushInterfaceType.ADD_USER, saved.getId());
|
||||
|
||||
@@ -183,22 +189,23 @@ public class SysUserService implements ISysUserService {
|
||||
if (request.getExpired() != null) {
|
||||
entity.setExpired(request.getExpired());
|
||||
}
|
||||
entity.setUpdateUser(SYSTEM_USER_ID);
|
||||
sysUserRepository.save(entity);
|
||||
publishUserEvent(PushInterfaceType.UPDATE_USER, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void delete(Integer id) {
|
||||
if (!sysUserRepository.existsById(id)) {
|
||||
throw new DException("系统用户不存在");
|
||||
public List<Integer> batchAdd(List<SysUserRequest> requests) {
|
||||
if (requests == null || requests.isEmpty()) {
|
||||
throw new DException("批量新增用户列表不能为空");
|
||||
}
|
||||
// 先清理组用户关联、用户-角色绑定,再删除用户
|
||||
sysUserGroupRelRepository.deleteByUserId(id);
|
||||
// AI-FIX(角色授权): 删除用户时级联清理用户-业务角色绑定(逻辑外键无物理 FK,避免残留孤儿数据)
|
||||
sysUserAppRoleRelRepository.deleteByUserIdBulk(id);
|
||||
sysUserRepository.deleteById(id);
|
||||
publishUserEvent(PushInterfaceType.DELETE_USER, id);
|
||||
// 批量新增与单条一致:强制密码强度校验(每条需携带 password + confirmPassword)
|
||||
List<Integer> ids = new ArrayList<>();
|
||||
for (SysUserRequest request : requests) {
|
||||
ids.add(createUser(request, true));
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -384,6 +391,46 @@ public class SysUserService implements ISysUserService {
|
||||
publishUserEvent(PushInterfaceType.UPDATE_USER, userIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void moveUserWithinSchool(Integer userId, Integer groupId, Integer schoolId) {
|
||||
if (userId == null) {
|
||||
throw new DException("用户ID不能为空");
|
||||
}
|
||||
if (groupId == null) {
|
||||
throw new DException("目标组ID不能为空");
|
||||
}
|
||||
if (schoolId == null) {
|
||||
throw new DException("学校ID不能为空");
|
||||
}
|
||||
if (!sysUserRepository.existsById(userId)) {
|
||||
throw new DException("系统用户不存在");
|
||||
}
|
||||
if (!sysGroupRepository.existsById(groupId)) {
|
||||
throw new DException("目标分组不存在");
|
||||
}
|
||||
if (!sysGroupRepository.existsById(schoolId)) {
|
||||
throw new DException("学校分组不存在");
|
||||
}
|
||||
|
||||
// 学校子树范围(含学校自身):用户与目标组都必须落在此范围内,否则视为跨校移动
|
||||
List<Integer> schoolScope = sysGroupService.listSelfAndDescendantIds(schoolId);
|
||||
|
||||
// ① 用户当前必须已在该学校内(至少一个组归属落在 schoolScope)
|
||||
List<Integer> userGroupIds = findGroupIdsByUserId(userId);
|
||||
boolean userInSchool = userGroupIds.stream().anyMatch(schoolScope::contains);
|
||||
if (!userInSchool) {
|
||||
throw new DException("用户不在该学校范围内,禁止跨校移动");
|
||||
}
|
||||
// ② 目标组必须也在该学校内
|
||||
if (!schoolScope.contains(groupId)) {
|
||||
throw new DException("目标组不属于该学校范围,禁止跨校移动");
|
||||
}
|
||||
|
||||
// 复用覆盖式改组逻辑(目标设为主组)
|
||||
changeGroups(Collections.singletonList(userId), Collections.singletonList(groupId));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public BatchImportResult batchImport(MultipartFile file) {
|
||||
|
||||
Reference in New Issue
Block a user