跨校身份修订
ci-userbase-service / build-and-push (push) Successful in 44s

This commit is contained in:
chenxing
2026-08-27 20:14:12 +08:00
parent ebbaeee181
commit c588dedea7
31 changed files with 1811 additions and 328 deletions
@@ -1,6 +1,8 @@
package com.yunhai.userbase.service.impl;
import com.yunhai.platform.utils.enums.IEnum;
import com.yunhai.platform.utils.model.BoaGroup;
import com.yunhai.platform.utils.model.BoaRoleInfo;
import com.yunhai.platform.utils.model.BoaUser;
import com.yunhai.userbase.entity.SysGroup;
import com.yunhai.userbase.entity.SysUser;
@@ -9,11 +11,14 @@ import com.yunhai.userbase.entity.SysUserGroupRel;
import com.yunhai.userbase.entity.SysUserRoleRel;
import com.yunhai.userbase.enums.GroupTypeEnum;
import com.yunhai.userbase.enums.StatusEnum;
import com.yunhai.userbase.enums.SysRoleEnum;
import com.yunhai.userbase.repository.SysGroupRepository;
import com.yunhai.userbase.repository.SysUserGroupRelRepository;
import com.yunhai.userbase.repository.SysUserRepository;
import com.yunhai.userbase.repository.SysUserRoleRelRepository;
import com.yunhai.userbase.repository.SysUserCurrentRoleRepository;
import com.yunhai.userbase.service.impl.IdentityService;
import com.yunhai.userbase.service.resolve.MainGroupResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -23,6 +28,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 用户中心核心服务:把 UserBase 自身的 sys_user / sys_group 组装成基础平台统一的
@@ -47,6 +53,10 @@ public class UserCenterService {
private SysUserRoleRelRepository sysUserRoleRelRepository;
@Autowired
private SysUserCurrentRoleRepository sysUserCurrentRoleRepository;
@Autowired
private MainGroupResolver mainGroupResolver;
@Autowired
private IdentityService identityService;
public BoaUser getUserInfoWithDeptByAccount(String account) {
if (account == null) {
@@ -101,7 +111,7 @@ public class UserCenterService {
}
/**
* 组装用户组织链:取主归属组(isMain=1,否则首个关联),沿 parentId 向上回溯到根,
* 组装用户组织链:取主归属组(isMain=1 取 id 最小,无主兜底 id 最小),沿 parentId 向上回溯到根,
* 顺序为「主组 -> ... -> 根方向」(近 -> 远)。
*/
private List<BoaGroup> buildGroups(Integer userId) {
@@ -109,11 +119,8 @@ public class UserCenterService {
if (rels == null || rels.isEmpty()) {
return new ArrayList<>();
}
SysUserGroupRel mainRel = rels.stream()
.filter(r -> r.getIsMain() != null && r.getIsMain() == 1)
.findFirst()
.orElse(rels.get(0));
Integer groupId = mainRel.getGroupId();
SysUserGroupRel mainRel = mainGroupResolver.resolve(rels);
Integer groupId = mainRel != null ? mainRel.getGroupId() : null;
if (groupId == null) {
return new ArrayList<>();
}
@@ -161,23 +168,29 @@ public class UserCenterService {
/**
* 从身份关联推导当前激活身份与可选学校。school 字段语义=当前激活学校:<br>
* ① 优先读 {@code sys_user_current_role}(用户主动切换后的状态);<br>
* ② 无切换记录时兜底取 {@code sys_user_role_rel.is_main=1} 的整条记录(保证是合法存在的身份,
* 避免「主组+主角色」组合出 B 学校老师的非法身份);<br>
* ③ schools:用户在全部学校下的可选身份去重 schoolId(>0)集合。
* ② 无切换记录时兜底取主身份整条记录(动态解析:主组 → 主校 → 该校 sortNo/id 最小行,
* 保证是合法存在的身份,避免「主组+主角色」组合出 B 学校老师的非法身份);<br>
* ③ currentRoleId:优先当前激活记录 roleId,兜底主身份行 roleId(本期补码,此前从未填充);<br>
* ④ schools:用户在全部学校下的可选身份去重 schoolId(&gt;0)集合组装 BoaGroup 列表(本期补码)。<br>
* school 类型守卫:仅当身份 schoolId 对应组类型=SCHOOL_GROUP 时回填 boa.school,
* 区域组/根直属用户保持 null——等价旧约定「填 0 不回填」的行为,避免子应用读到 school=区域组 对象。
*/
private void deriveIdentity(Integer userId, BoaUser boa) {
Integer currentRoleId = null;
Integer currentSchoolId = null;
String currentSchoolName = null;
SysUserCurrentRole current = sysUserCurrentRoleRepository.findByUserId(userId).orElse(null);
if (current != null && current.getRoleId() != null) {
currentRoleId = current.getRoleId();
currentSchoolId = current.getSchoolId();
currentSchoolName = current.getSchoolName();
} else {
// 兜底:直接取主身份整条记录(isMain=1),而不是「主组+主角色」组合
SysUserRoleRel mainRel = sysUserRoleRelRepository
.findByUserIdAndIsMain(userId, 1).orElse(null);
// 兜底:主身份整条记录(动态解析:主组 → 主校 → 该校 sortNo/id 最小行),
// 而不是「主组+主角色」组合(避免组合出 B 学校老师的非法身份)
SysUserRoleRel mainRel = identityService.resolveMainIdentity(userId);
if (mainRel != null) {
currentRoleId = mainRel.getRoleId();
currentSchoolId = mainRel.getSchoolId();
if (currentSchoolId != null && currentSchoolId > 0) {
SysGroup sch = sysGroupRepository.findById(currentSchoolId).orElse(null);
@@ -186,9 +199,43 @@ public class UserCenterService {
}
}
if (currentSchoolId != null && currentSchoolId > 0) {
// 当前激活学校:仅当对应组为学校组时回填(区域组/根直属保持 null)
if (currentSchoolId != null && currentSchoolId > 0 && isSchoolGroup(currentSchoolId)) {
boa.setSchool(toBoaGroup(currentSchoolId, currentSchoolName));
}
// 当前激活身份(优先切换记录,兜底主身份)——组装为 BoaRoleInfo 富对象(childId/childName 本期不做,恒空)
BoaRoleInfo currentRole = new BoaRoleInfo();
currentRole.setRoleId(currentRoleId);
currentRole.setRoleName(resolveRoleName(currentRoleId));
currentRole.setSchId(currentSchoolId);
currentRole.setSchName(currentSchoolName);
boa.setCurrentRole(currentRole);
// 可选学校集合:全部正常态身份行的 schoolId 去重(>0 过滤,恒为真实组 id)
List<Integer> schoolIds = sysUserRoleRelRepository
.findDistinctSchoolIdsByUserIdAndStatus(userId, StatusEnum.NORMAL);
if (schoolIds != null && !schoolIds.isEmpty()) {
List<BoaGroup> schools = schoolIds.stream()
.filter(sid -> sid != null && sid > 0)
.map(sid -> toBoaGroup(sid, null))
.collect(Collectors.toList());
boa.setSchools(schools);
}
}
/** 该组是否为学校组(SCHOOL_GROUP);组不存在视为 false。 */
private boolean isSchoolGroup(Integer groupId) {
SysGroup g = sysGroupRepository.findById(groupId).orElse(null);
return g != null && g.getType() == GroupTypeEnum.SCHOOL_GROUP;
}
/** 由角色 id 反查角色名(SysRoleEnum.value);未知角色返回 null。 */
private String resolveRoleName(Integer roleId) {
if (roleId == null) {
return null;
}
SysRoleEnum role = IEnum.getByKey(SysRoleEnum.class, roleId);
return role != null ? role.getValue() : null;
}
/** 组装一个 BoaGroup(仅填充 id 与 name;name 为 null 时回源查 sys_group) */