Files
UserbaseService/src/main/java/com/yunhai/userbase/service/impl/IdentityService.java
T
2026-08-18 21:51:18 +08:00

147 lines
5.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.yunhai.userbase.service.impl;
import com.yunhai.platform.utils.exception.DException;
import com.yunhai.userbase.entity.SysGroup;
import com.yunhai.userbase.entity.SysUserCurrentRole;
import com.yunhai.userbase.entity.SysUserRoleRel;
import com.yunhai.userbase.enums.IEnum;
import com.yunhai.userbase.enums.StatusEnum;
import com.yunhai.userbase.enums.SysRoleEnum;
import com.yunhai.userbase.model.identity.IdentityCurrentVo;
import com.yunhai.userbase.model.identity.IdentityOptionVo;
import com.yunhai.userbase.model.identity.IdentitySwitchRequest;
import com.yunhai.userbase.repository.SysGroupRepository;
import com.yunhai.userbase.repository.SysUserCurrentRoleRepository;
import com.yunhai.userbase.repository.SysUserRoleRelRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
/**
* 用户身份服务:管理「平台身份角色 × 学校」维度的当前激活状态与可选清单。<br><br>
* 身份 = (userId, roleId, schoolId) 三元组,权威源为 {@code sys_user_role_rel};<br>
* 当前激活状态存 {@code sys_user_current_role}(1:1,每用户一条)。<br>
* 本服务不处理业务权限角色(sys_app_role),那套与学校维度无关。
*
* @author chenx
* @date 2026/8/18
*/
@Service
public class IdentityService {
@Autowired
private SysUserRoleRelRepository sysUserRoleRelRepository;
@Autowired
private SysUserCurrentRoleRepository sysUserCurrentRoleRepository;
@Autowired
private SysGroupRepository sysGroupRepository;
/**
* 用户全部可选身份(正常态),用于「切换身份」页渲染。
*/
public List<IdentityOptionVo> listAvailable(Integer userId) {
List<SysUserRoleRel> rels = sysUserRoleRelRepository
.findByUserIdAndStatus(userId, StatusEnum.NORMAL);
List<IdentityOptionVo> result = new ArrayList<>(rels.size());
for (SysUserRoleRel rel : rels) {
IdentityOptionVo vo = new IdentityOptionVo();
vo.setRoleId(rel.getRoleId());
vo.setRoleName(roleName(rel.getRoleId()));
vo.setSchoolId(rel.getSchoolId());
vo.setSchoolName(schoolName(rel.getSchoolId()));
vo.setIsMain(rel.getIsMain() != null && rel.getIsMain() == 1);
result.add(vo);
}
return result;
}
/**
* 当前激活身份:优先读 sys_user_current_role;无切换记录时兜底主身份(isMain=1)。
*/
public IdentityCurrentVo getCurrent(Integer userId) {
Optional<SysUserCurrentRole> currentOpt = sysUserCurrentRoleRepository.findByUserId(userId);
IdentityCurrentVo vo = new IdentityCurrentVo();
if (currentOpt.isPresent()) {
SysUserCurrentRole current = currentOpt.get();
vo.setRoleId(current.getRoleId());
vo.setRoleName(roleName(current.getRoleId()));
vo.setSchoolId(current.getSchoolId());
vo.setSchoolName(current.getSchoolName());
vo.setFallback(false);
return vo;
}
// 兜底:主身份整条记录(isMain=1)
SysUserRoleRel mainRel = sysUserRoleRelRepository.findByUserIdAndIsMain(userId, 1).orElse(null);
if (mainRel != null) {
vo.setRoleId(mainRel.getRoleId());
vo.setRoleName(roleName(mainRel.getRoleId()));
vo.setSchoolId(mainRel.getSchoolId());
vo.setSchoolName(schoolName(mainRel.getSchoolId()));
vo.setFallback(true);
return vo;
}
// 连主身份都没有(测试期初数据尚未建立):返回空对象,前端引导创建身份
vo.setFallback(true);
return vo;
}
/**
* 切换身份:校验 (userId, roleId, schoolId) 在 sys_user_role_rel 正常态中存在,
* 再 UPSERT sys_user_current_role(按 userId 唯一)。
*/
public IdentityCurrentVo switchIdentity(Integer userId, IdentitySwitchRequest request) {
Integer roleId = request.getRoleId();
Integer schoolId = request.getSchoolId();
// 校验目标身份确属该用户且正常态,防越权切换
SysUserRoleRel rel = sysUserRoleRelRepository
.findByUserIdAndSchoolIdAndStatus(userId, schoolId, StatusEnum.NORMAL)
.stream()
.filter(r -> Objects.equals(r.getRoleId(), roleId))
.findFirst()
.orElse(null);
if (rel == null) {
throw new DException("目标身份不存在或非正常态,无法切换");
}
SysUserCurrentRole current = sysUserCurrentRoleRepository.findByUserId(userId).orElse(null);
if (current == null) {
current = new SysUserCurrentRole();
current.setUserId(userId);
}
current.setRoleId(roleId);
current.setSchoolId(schoolId);
current.setSchoolName(schoolName(schoolId));
current.setSwitchTime(LocalDateTime.now());
sysUserCurrentRoleRepository.save(current);
IdentityCurrentVo vo = new IdentityCurrentVo();
vo.setRoleId(roleId);
vo.setRoleName(roleName(roleId));
vo.setSchoolId(schoolId);
vo.setSchoolName(current.getSchoolName());
vo.setFallback(false);
return vo;
}
private String roleName(Integer roleId) {
if (roleId == null) {
return null;
}
SysRoleEnum e = IEnum.getByKey(SysRoleEnum.class, roleId);
return e != null ? e.getValue() : null;
}
private String schoolName(Integer schoolId) {
if (schoolId == null || schoolId <= 0) {
return null;
}
SysGroup g = sysGroupRepository.findById(schoolId).orElse(null);
return g != null ? g.getName() : null;
}
}