mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-08-08 07:11:53 +08:00
去除 LoginUser 的 roleIds、deptId 字段,简化
This commit is contained in:
@@ -26,12 +26,13 @@ import org.springframework.web.bind.annotation.*;
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
|
||||
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getUserAgent;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserRoleIds;
|
||||
import static java.util.Collections.singleton;
|
||||
|
||||
@Api(tags = "管理后台 - 认证")
|
||||
@RestController
|
||||
@@ -69,12 +70,12 @@ public class AuthController {
|
||||
return null;
|
||||
}
|
||||
// 获得角色列表
|
||||
List<RoleDO> roleList = roleService.getRolesFromCache(getLoginUserRoleIds());
|
||||
Set<Long> roleIds = permissionService.getUserRoleIds(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
List<RoleDO> roleList = roleService.getRolesFromCache(roleIds);
|
||||
// 获得菜单列表
|
||||
List<MenuDO> menuList = permissionService.getRoleMenuListFromCache(
|
||||
getLoginUserRoleIds(), // 注意,基于登录的角色,因为后续的权限判断也是基于它
|
||||
List<MenuDO> menuList = permissionService.getRoleMenuListFromCache(roleIds,
|
||||
SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType(), MenuTypeEnum.BUTTON.getType()),
|
||||
SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus()));
|
||||
singleton(CommonStatusEnum.ENABLE.getStatus())); // 只要开启的
|
||||
// 拼接结果返回
|
||||
return success(AuthConvert.INSTANCE.convert(user, roleList, menuList));
|
||||
}
|
||||
@@ -82,11 +83,12 @@ public class AuthController {
|
||||
@GetMapping("/list-menus")
|
||||
@ApiOperation("获得登录用户的菜单列表")
|
||||
public CommonResult<List<AuthMenuRespVO>> getMenus() {
|
||||
// 获得角色列表
|
||||
Set<Long> roleIds = permissionService.getUserRoleIds(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
// 获得用户拥有的菜单列表
|
||||
List<MenuDO> menuList = permissionService.getRoleMenuListFromCache(
|
||||
getLoginUserRoleIds(), // 注意,基于登录的角色,因为后续的权限判断也是基于它
|
||||
List<MenuDO> menuList = permissionService.getRoleMenuListFromCache(roleIds,
|
||||
SetUtils.asSet(MenuTypeEnum.DIR.getType(), MenuTypeEnum.MENU.getType()), // 只要目录和菜单类型
|
||||
SetUtils.asSet(CommonStatusEnum.ENABLE.getStatus())); // 只要开启的
|
||||
singleton(CommonStatusEnum.ENABLE.getStatus())); // 只要开启的
|
||||
// 转换成 Tree 结构返回
|
||||
return success(AuthConvert.INSTANCE.buildMenuTree(menuList));
|
||||
}
|
||||
|
@@ -1,15 +1,16 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.auth;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.session.UserSessionPageItemRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.auth.vo.session.UserSessionPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.convert.auth.UserSessionConvert;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.auth.UserSessionDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.service.auth.UserSessionService;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.module.system.service.auth.UserSessionService;
|
||||
import cn.iocoder.yudao.module.system.service.dept.DeptService;
|
||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||
import io.swagger.annotations.Api;
|
||||
@@ -49,7 +50,8 @@ public class UserSessionController {
|
||||
|
||||
// 获得拼接需要的数据
|
||||
Map<Long, AdminUserDO> userMap = userService.getUserMap(
|
||||
convertList(pageResult.getList(), UserSessionDO::getUserId));
|
||||
convertList(pageResult.getList(), UserSessionDO::getUserId,
|
||||
session -> session.getUserType().equals(UserTypeEnum.ADMIN.getValue())));
|
||||
Map<Long, DeptDO> deptMap = deptService.getDeptMap(
|
||||
convertList(userMap.values(), AdminUserDO::getDeptId));
|
||||
// 拼接结果返回
|
||||
|
@@ -17,7 +17,6 @@ import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
|
||||
import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
|
||||
import cn.iocoder.yudao.module.system.service.common.CaptchaService;
|
||||
import cn.iocoder.yudao.module.system.service.logger.LoginLogService;
|
||||
import cn.iocoder.yudao.module.system.service.permission.PermissionService;
|
||||
import cn.iocoder.yudao.module.system.service.social.SocialUserService;
|
||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -36,12 +35,10 @@ import org.springframework.util.Assert;
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Validator;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
import static java.util.Collections.singleton;
|
||||
|
||||
/**
|
||||
* Auth Service 实现类
|
||||
@@ -60,8 +57,6 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
||||
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") // UserService 存在重名
|
||||
private AdminUserService userService;
|
||||
@Resource
|
||||
private PermissionService permissionService;
|
||||
@Resource
|
||||
private CaptchaService captchaService;
|
||||
@Resource
|
||||
private LoginLogService loginLogService;
|
||||
@@ -211,16 +206,6 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得 User 拥有的角色编号数组
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @return 角色编号数组
|
||||
*/
|
||||
private Set<Long> getUserRoleIds(Long userId) {
|
||||
return permissionService.getUserRoleIds(userId, singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String socialQuickLogin(AuthSocialQuickLoginReqVO reqVO, String userIp, String userAgent) {
|
||||
// 使用 code 授权码,进行登录。然后,获得到绑定的用户编号
|
||||
@@ -318,17 +303,13 @@ public class AdminAuthServiceImpl implements AdminAuthService {
|
||||
}
|
||||
|
||||
// 刷新 LoginUser 缓存
|
||||
LoginUser newLoginUser= this.buildLoginUser(user);
|
||||
LoginUser newLoginUser= buildLoginUser(user);
|
||||
userSessionService.refreshUserSession(token, newLoginUser);
|
||||
return newLoginUser;
|
||||
}
|
||||
|
||||
private LoginUser buildLoginUser(AdminUserDO user) {
|
||||
LoginUser loginUser = AuthConvert.INSTANCE.convert(user);
|
||||
// 补全字段
|
||||
loginUser.setDeptId(user.getDeptId());
|
||||
loginUser.setRoleIds(this.getUserRoleIds(loginUser.getId()));
|
||||
return loginUser;
|
||||
return AuthConvert.INSTANCE.convert(user);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -3,12 +3,12 @@ package cn.iocoder.yudao.module.system.service.permission;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
|
||||
import cn.iocoder.yudao.framework.datapermission.core.dept.service.dto.DeptDataPermissionRespDTO;
|
||||
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
|
||||
@@ -22,6 +22,8 @@ import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
|
||||
import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum;
|
||||
import cn.iocoder.yudao.module.system.mq.producer.permission.PermissionProducer;
|
||||
import cn.iocoder.yudao.module.system.service.dept.DeptService;
|
||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
@@ -36,6 +38,10 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
import static java.util.Collections.singleton;
|
||||
|
||||
/**
|
||||
* 权限 Service 实现类
|
||||
@@ -46,11 +52,6 @@ import java.util.*;
|
||||
@Slf4j
|
||||
public class PermissionServiceImpl implements PermissionService {
|
||||
|
||||
/**
|
||||
* LoginUser 的 Context 缓存 Key
|
||||
*/
|
||||
public static final String CONTEXT_KEY = PermissionServiceImpl.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* 定时执行 {@link #schedulePeriodicRefresh()} 的周期
|
||||
* 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
|
||||
@@ -93,6 +94,8 @@ public class PermissionServiceImpl implements PermissionService {
|
||||
private MenuService menuService;
|
||||
@Resource
|
||||
private DeptService deptService;
|
||||
@Resource
|
||||
private AdminUserService userService;
|
||||
|
||||
@Resource
|
||||
private PermissionProducer permissionProducer;
|
||||
@@ -319,7 +322,7 @@ public class PermissionServiceImpl implements PermissionService {
|
||||
}
|
||||
|
||||
// 获得当前登录的角色。如果为空,说明没有权限
|
||||
Set<Long> roleIds = SecurityFrameworkUtils.getLoginUserRoleIds();
|
||||
Set<Long> roleIds = getUserRoleIds(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
if (CollUtil.isEmpty(roleIds)) {
|
||||
return false;
|
||||
}
|
||||
@@ -354,7 +357,7 @@ public class PermissionServiceImpl implements PermissionService {
|
||||
}
|
||||
|
||||
// 获得当前登录的角色。如果为空,说明没有权限
|
||||
Set<Long> roleIds = SecurityFrameworkUtils.getLoginUserRoleIds();
|
||||
Set<Long> roleIds = getUserRoleIds(getLoginUserId(), singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
if (CollUtil.isEmpty(roleIds)) {
|
||||
return false;
|
||||
}
|
||||
@@ -368,16 +371,18 @@ public class PermissionServiceImpl implements PermissionService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeptDataPermissionRespDTO getDeptDataPermission(LoginUser loginUser) {
|
||||
// 判断是否 context 已经缓存
|
||||
DeptDataPermissionRespDTO result = loginUser.getContext(CONTEXT_KEY, DeptDataPermissionRespDTO.class);
|
||||
if (result != null) {
|
||||
@DataPermission(enable = false) // 关闭数据权限,不然就会出现递归获取数据权限的问题
|
||||
public DeptDataPermissionRespDTO getDeptDataPermission(Long userId) {
|
||||
DeptDataPermissionRespDTO result = new DeptDataPermissionRespDTO();
|
||||
// 获得用户的角色
|
||||
Set<Long> roleIds = getUserRoleIds(userId, singleton(CommonStatusEnum.ENABLE.getStatus()));
|
||||
if (CollUtil.isEmpty(roleIds)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// 创建 DeptDataPermissionRespDTO 对象
|
||||
result = new DeptDataPermissionRespDTO();
|
||||
List<RoleDO> roles = roleService.getRolesFromCache(loginUser.getRoleIds());
|
||||
List<RoleDO> roles = roleService.getRolesFromCache(roleIds);
|
||||
// 获得用户的部门编号的缓存,通过 Guava 的 Suppliers 惰性求值,即有且仅有第一次发起 DB 的查询
|
||||
Supplier<Long> userDeptIdCache = Suppliers.memoize(() -> userService.getUser(userId).getDeptId());
|
||||
// 遍历每个角色,计算
|
||||
for (RoleDO role : roles) {
|
||||
// 为空时,跳过
|
||||
if (role.getDataScope() == null) {
|
||||
@@ -393,20 +398,20 @@ public class PermissionServiceImpl implements PermissionService {
|
||||
CollUtil.addAll(result.getDeptIds(), role.getDataScopeDeptIds());
|
||||
// 自定义可见部门时,保证可以看到自己所在的部门。否则,一些场景下可能会有问题。
|
||||
// 例如说,登录时,基于 t_user 的 username 查询会可能被 dept_id 过滤掉
|
||||
CollUtil.addAll(result.getDeptIds(), loginUser.getDeptId());
|
||||
CollUtil.addAll(result.getDeptIds(), userDeptIdCache.get());
|
||||
continue;
|
||||
}
|
||||
// 情况三,DEPT_ONLY
|
||||
if (Objects.equals(role.getDataScope(), DataScopeEnum.DEPT_ONLY.getScope())) {
|
||||
CollectionUtils.addIfNotNull(result.getDeptIds(), loginUser.getDeptId());
|
||||
CollectionUtils.addIfNotNull(result.getDeptIds(), userDeptIdCache.get());
|
||||
continue;
|
||||
}
|
||||
// 情况四,DEPT_DEPT_AND_CHILD
|
||||
if (Objects.equals(role.getDataScope(), DataScopeEnum.DEPT_AND_CHILD.getScope())) {
|
||||
List<DeptDO> depts = deptService.getDeptsByParentIdFromCache(loginUser.getDeptId(), true);
|
||||
List<DeptDO> depts = deptService.getDeptsByParentIdFromCache(userDeptIdCache.get(), true);
|
||||
CollUtil.addAll(result.getDeptIds(), CollectionUtils.convertList(depts, DeptDO::getId));
|
||||
//添加本身部门id
|
||||
CollUtil.addAll(result.getDeptIds(), loginUser.getDeptId());
|
||||
// 添加本身部门编号
|
||||
CollUtil.addAll(result.getDeptIds(), userDeptIdCache.get());
|
||||
continue;
|
||||
}
|
||||
// 情况五,SELF
|
||||
@@ -415,11 +420,8 @@ public class PermissionServiceImpl implements PermissionService {
|
||||
continue;
|
||||
}
|
||||
// 未知情况,error log 即可
|
||||
log.error("[getDeptDataPermission][LoginUser({}) role({}) 无法处理]", loginUser.getId(), JsonUtils.toJsonString(result));
|
||||
log.error("[getDeptDataPermission][LoginUser({}) role({}) 无法处理]", userId, JsonUtils.toJsonString(result));
|
||||
}
|
||||
|
||||
// 添加到缓存,并返回
|
||||
loginUser.setContext(CONTEXT_KEY, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@@ -81,6 +81,7 @@ public class TenantServiceImpl implements TenantService {
|
||||
@Getter
|
||||
private volatile Date maxUpdateTime;
|
||||
|
||||
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
|
||||
@Autowired(required = false) // 由于 yudao.tenant.enable 配置项,可以关闭多租户的功能,所以这里只能不强制注入
|
||||
private TenantProperties tenantProperties;
|
||||
|
||||
|
@@ -25,6 +25,7 @@ import cn.iocoder.yudao.module.system.service.tenant.TenantService;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -61,6 +62,7 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
@Resource
|
||||
private PasswordEncoder passwordEncoder;
|
||||
@Resource
|
||||
@Lazy // 延迟,避免循环依赖报错
|
||||
private TenantService tenantService;
|
||||
|
||||
@Resource
|
||||
|
Reference in New Issue
Block a user