本地工作区快照:恢复 .git 仓库(合并远端 main 前基线)
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
package com.yunhai.userbase.service.impl;
|
||||
|
||||
import com.yunhai.platform.utils.model.BoaGroup;
|
||||
import com.yunhai.platform.utils.model.BoaUser;
|
||||
import com.yunhai.userbase.entity.SysGroup;
|
||||
import com.yunhai.userbase.entity.SysUser;
|
||||
import com.yunhai.userbase.entity.SysUserCurrentRole;
|
||||
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.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 org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 用户中心核心服务:把 UserBase 自身的 sys_user / sys_group 组装成基础平台统一的
|
||||
* {@link BoaUser}(含部门/学校/教育局多级组织)。<br><br>
|
||||
* 这是「UserBase 由子应用升级为用户中心」的关键:平台侧 {@code UserDetailsProvider}
|
||||
* ({@code UserBaseUserDetailsProvider})与开放接口({@code OpenBaseController})都复用本服务,
|
||||
* 保证 CAS 会话流与签名开放流返回的 BoaUser 结构完全一致。
|
||||
*/
|
||||
@Service
|
||||
public class UserCenterService {
|
||||
|
||||
/** 虚拟根节点 parentId(与 SysGroupService 约定一致)。 */
|
||||
private static final int ROOT_PARENT_ID = 0;
|
||||
|
||||
@Autowired
|
||||
private SysUserRepository sysUserRepository;
|
||||
@Autowired
|
||||
private SysUserGroupRelRepository sysUserGroupRelRepository;
|
||||
@Autowired
|
||||
private SysGroupRepository sysGroupRepository;
|
||||
@Autowired
|
||||
private SysUserRoleRelRepository sysUserRoleRelRepository;
|
||||
@Autowired
|
||||
private SysUserCurrentRoleRepository sysUserCurrentRoleRepository;
|
||||
|
||||
public BoaUser getUserInfoWithDeptByAccount(String account) {
|
||||
if (account == null) {
|
||||
return null;
|
||||
}
|
||||
return resolve(sysUserRepository.findByAccount(account.trim()));
|
||||
}
|
||||
|
||||
public BoaUser getUserInfoWithDeptByPhone(String phone) {
|
||||
if (phone == null) {
|
||||
return null;
|
||||
}
|
||||
return resolve(sysUserRepository.findByPhone(phone.trim()));
|
||||
}
|
||||
|
||||
public BoaUser getUserInfoWithDeptById(Integer id) {
|
||||
if (id == null) {
|
||||
return null;
|
||||
}
|
||||
return resolve(sysUserRepository.findById(id).orElse(null));
|
||||
}
|
||||
|
||||
private BoaUser resolve(SysUser user) {
|
||||
if (user == null) {
|
||||
return null;
|
||||
}
|
||||
BoaUser boa = new BoaUser();
|
||||
boa.setId(user.getId());
|
||||
boa.setAccount(user.getAccount());
|
||||
boa.setName(user.getRealName());
|
||||
boa.setIdcard(user.getIdcard());
|
||||
boa.setPhone(user.getPhone());
|
||||
boa.setProfilePicture(user.getProfilePicture());
|
||||
// 用户表无 email / gender 列,置 null
|
||||
boa.setEmail(null);
|
||||
boa.setGender(null);
|
||||
boa.setType(user.getType() != null ? user.getType().getKey() : null);
|
||||
// 状态语义对齐:本表 disabled(NORMAL=0 正常 / DISABLED=1 禁用) -> BoaUser(1 正常 / 0 禁用)
|
||||
boa.setStatus(user.getDisabled() == StatusEnum.NORMAL ? 1 : 0);
|
||||
// 角色列表:从 sys_user_role_rel(平台身份角色权威源)取正常态 roleId 去重,不再读 sys_user.roles
|
||||
List<Integer> roleIds = sysUserRoleRelRepository
|
||||
.findDistinctRoleIdsByUserIdAndStatus(user.getId(), StatusEnum.NORMAL);
|
||||
boa.setRoleIds(roleIds);
|
||||
|
||||
List<BoaGroup> groups = buildGroups(user.getId());
|
||||
boa.setGroups(groups);
|
||||
// 部门/教育局:仍从组织链推导(与主组/区域组语义绑定)
|
||||
deriveOrg(groups, boa);
|
||||
// 学校/当前激活身份/可选学校:从身份关联表推导(school 语义=当前激活学校)
|
||||
deriveIdentity(user.getId(), boa);
|
||||
return boa;
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装用户组织链:取主归属组(isMain=1,否则首个关联),沿 parentId 向上回溯到根,
|
||||
* 顺序为「主组 -> ... -> 根方向」(近 -> 远)。
|
||||
*/
|
||||
private List<BoaGroup> buildGroups(Integer userId) {
|
||||
List<SysUserGroupRel> rels = sysUserGroupRelRepository.findByUserId(userId);
|
||||
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();
|
||||
if (groupId == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<BoaGroup> chain = new ArrayList<>();
|
||||
Integer cursor = groupId;
|
||||
Set<Integer> seen = new HashSet<>();
|
||||
while (cursor != null && cursor != ROOT_PARENT_ID && seen.add(cursor)) {
|
||||
SysGroup g = sysGroupRepository.findById(cursor).orElse(null);
|
||||
if (g == null) {
|
||||
break;
|
||||
}
|
||||
BoaGroup bg = new BoaGroup();
|
||||
bg.setId(g.getId());
|
||||
bg.setName(g.getName());
|
||||
bg.setParentId(g.getParentId());
|
||||
bg.setType(g.getType() != null ? g.getType().getKey() : null);
|
||||
chain.add(bg);
|
||||
cursor = g.getParentId();
|
||||
}
|
||||
return chain;
|
||||
}
|
||||
|
||||
/** 从组织链推导 school / bureau / dept。 */
|
||||
private void deriveOrg(List<BoaGroup> groups, BoaUser boa) {
|
||||
if (groups == null || groups.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
BoaGroup school = null;
|
||||
BoaGroup bureau = null;
|
||||
for (BoaGroup g : groups) {
|
||||
if (school == null && Objects.equals(g.getType(), GroupTypeEnum.SCHOOL_GROUP.getKey())) {
|
||||
school = g;
|
||||
}
|
||||
if (bureau == null && Objects.equals(g.getType(), GroupTypeEnum.AREA_GROUP.getKey())) {
|
||||
bureau = g;
|
||||
}
|
||||
}
|
||||
boa.setSchool(school);
|
||||
boa.setBureau(bureau);
|
||||
// 部门:主组(链的近端第一个);若主组本身为学校,则部门即学校
|
||||
boa.setDept(groups.get(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* 从身份关联推导当前激活身份与可选学校。school 字段语义=当前激活学校:<br>
|
||||
* ① 优先读 {@code sys_user_current_role}(用户主动切换后的状态);<br>
|
||||
* ② 无切换记录时兜底取 {@code sys_user_role_rel.is_main=1} 的整条记录(保证是合法存在的身份,
|
||||
* 避免「主组+主角色」组合出 B 学校老师的非法身份);<br>
|
||||
* ③ schools:用户在全部学校下的可选身份去重 schoolId(>0)集合。
|
||||
*/
|
||||
private void deriveIdentity(Integer userId, BoaUser boa) {
|
||||
Integer currentSchoolId = null;
|
||||
String currentSchoolName = null;
|
||||
|
||||
SysUserCurrentRole current = sysUserCurrentRoleRepository.findByUserId(userId).orElse(null);
|
||||
if (current != null && current.getRoleId() != null) {
|
||||
currentSchoolId = current.getSchoolId();
|
||||
currentSchoolName = current.getSchoolName();
|
||||
} else {
|
||||
// 兜底:直接取主身份整条记录(isMain=1),而不是「主组+主角色」组合
|
||||
SysUserRoleRel mainRel = sysUserRoleRelRepository
|
||||
.findByUserIdAndIsMain(userId, 1).orElse(null);
|
||||
if (mainRel != null) {
|
||||
currentSchoolId = mainRel.getSchoolId();
|
||||
if (currentSchoolId != null && currentSchoolId > 0) {
|
||||
SysGroup sch = sysGroupRepository.findById(currentSchoolId).orElse(null);
|
||||
currentSchoolName = sch != null ? sch.getName() : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentSchoolId != null && currentSchoolId > 0) {
|
||||
boa.setSchool(toBoaGroup(currentSchoolId, currentSchoolName));
|
||||
}
|
||||
}
|
||||
|
||||
/** 组装一个 BoaGroup(仅填充 id 与 name;name 为 null 时回源查 sys_group) */
|
||||
private BoaGroup toBoaGroup(Integer groupId, String fallbackName) {
|
||||
BoaGroup bg = new BoaGroup();
|
||||
bg.setId(groupId);
|
||||
if (fallbackName != null) {
|
||||
bg.setName(fallbackName);
|
||||
} else {
|
||||
SysGroup g = sysGroupRepository.findById(groupId).orElse(null);
|
||||
bg.setName(g != null ? g.getName() : null);
|
||||
}
|
||||
return bg;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user