mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-04 04:08:43 +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