| | |
| | | package org.dromara.system.service.impl; |
| | | |
| | | import cn.dev33.satoken.exception.NotLoginException; |
| | | import cn.dev33.satoken.stp.StpUtil; |
| | | import cn.hutool.core.bean.BeanUtil; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.Wrapper; |
| | |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.dromara.common.core.constant.TenantConstants; |
| | | import org.dromara.common.core.constant.UserConstants; |
| | | import org.dromara.common.core.domain.model.LoginUser; |
| | | import org.dromara.common.core.exception.ServiceException; |
| | | import org.dromara.common.core.utils.MapstructUtils; |
| | | import org.dromara.common.core.utils.StreamUtils; |
| | |
| | | import org.dromara.system.mapper.SysRoleMenuMapper; |
| | | import org.dromara.system.mapper.SysUserRoleMapper; |
| | | import org.dromara.system.service.ISysRoleService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | |
| | | .like(StringUtils.isNotBlank(bo.getRoleKey()), "r.role_key", bo.getRoleKey()) |
| | | .between(params.get("beginTime") != null && params.get("endTime") != null, |
| | | "r.create_time", params.get("beginTime"), params.get("endTime")) |
| | | .orderByAsc("r.role_sort").orderByAsc("r.create_time");; |
| | | .orderByAsc("r.role_sort").orderByAsc("r.create_time"); |
| | | return wrapper; |
| | | } |
| | | |
| | |
| | | */ |
| | | @Override |
| | | public List<SysRoleVo> selectRolesByUserId(Long userId) { |
| | | List<SysRoleVo> userRoles = baseMapper.selectRolePermissionByUserId(userId); |
| | | return baseMapper.selectRolesByUserId(userId); |
| | | } |
| | | |
| | | /** |
| | | * 根据用户ID查询角色列表(包含被授权状态) |
| | | * |
| | | * @param userId 用户ID |
| | | * @return 角色列表 |
| | | */ |
| | | @Override |
| | | public List<SysRoleVo> selectRolesAuthByUserId(Long userId) { |
| | | List<SysRoleVo> userRoles = baseMapper.selectRolesByUserId(userId); |
| | | List<SysRoleVo> roles = selectRoleAll(); |
| | | // 使用HashSet提高查找效率 |
| | | Set<Long> userRoleIds = StreamUtils.toSet(userRoles, SysRoleVo::getRoleId); |
| | | for (SysRoleVo role : roles) { |
| | | for (SysRoleVo userRole : userRoles) { |
| | | if (role.getRoleId().longValue() == userRole.getRoleId().longValue()) { |
| | | role.setFlag(true); |
| | | break; |
| | | } |
| | | if (userRoleIds.contains(role.getRoleId())) { |
| | | role.setFlag(true); |
| | | } |
| | | } |
| | | return roles; |
| | |
| | | */ |
| | | @Override |
| | | public Set<String> selectRolePermissionByUserId(Long userId) { |
| | | List<SysRoleVo> perms = baseMapper.selectRolePermissionByUserId(userId); |
| | | List<SysRoleVo> perms = baseMapper.selectRolesByUserId(userId); |
| | | Set<String> permsSet = new HashSet<>(); |
| | | for (SysRoleVo perm : perms) { |
| | | if (ObjectUtil.isNotNull(perm)) { |
| | |
| | | */ |
| | | @Override |
| | | public List<Long> selectRoleListByUserId(Long userId) { |
| | | return baseMapper.selectRoleListByUserId(userId); |
| | | List<SysRoleVo> list = baseMapper.selectRolesByUserId(userId); |
| | | return StreamUtils.toList(list, SysRoleVo::getRoleId); |
| | | } |
| | | |
| | | /** |
| | |
| | | @Override |
| | | public SysRoleVo selectRoleById(Long roleId) { |
| | | return baseMapper.selectRoleById(roleId); |
| | | } |
| | | |
| | | /** |
| | | * 通过角色ID串查询角色 |
| | | * |
| | | * @param roleIds 角色ID串 |
| | | * @return 角色列表信息 |
| | | */ |
| | | @Override |
| | | public List<SysRoleVo> selectRoleByIds(List<Long> roleIds) { |
| | | return baseMapper.selectRoleList(new QueryWrapper<SysRole>() |
| | | .eq("r.status", UserConstants.ROLE_NORMAL) |
| | | .in(CollUtil.isNotEmpty(roleIds), "r.role_id", roleIds)); |
| | | } |
| | | |
| | | /** |
| | |
| | | /** |
| | | * 校验角色是否允许操作 |
| | | * |
| | | * @param roleId 角色ID |
| | | * @param role 角色信息 |
| | | */ |
| | | @Override |
| | | public void checkRoleAllowed(Long roleId) { |
| | | if (ObjectUtil.isNotNull(roleId) && LoginHelper.isSuperAdmin(roleId)) { |
| | | public void checkRoleAllowed(SysRoleBo role) { |
| | | if (ObjectUtil.isNotNull(role.getRoleId()) && LoginHelper.isSuperAdmin(role.getRoleId())) { |
| | | throw new ServiceException("不允许操作超级管理员角色"); |
| | | } |
| | | String[] keys = new String[]{TenantConstants.SUPER_ADMIN_ROLE_KEY, TenantConstants.TENANT_ADMIN_ROLE_KEY}; |
| | | // 新增不允许使用 管理员标识符 |
| | | if (ObjectUtil.isNull(role.getRoleId()) |
| | | && StringUtils.equalsAny(role.getRoleKey(), keys)) { |
| | | throw new ServiceException("不允许使用系统内置管理员角色标识符!"); |
| | | } |
| | | // 修改不允许修改 管理员标识符 |
| | | if (ObjectUtil.isNotNull(role.getRoleId())) { |
| | | SysRole sysRole = baseMapper.selectById(role.getRoleId()); |
| | | // 如果标识符不相等 判断为修改了管理员标识符 |
| | | if (!StringUtils.equals(sysRole.getRoleKey(), role.getRoleKey())) { |
| | | if (StringUtils.equalsAny(sysRole.getRoleKey(), keys)) { |
| | | throw new ServiceException("不允许修改系统内置管理员角色标识符!"); |
| | | } else if (StringUtils.equalsAny(role.getRoleKey(), keys)) { |
| | | throw new ServiceException("不允许使用系统内置管理员角色标识符!"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int updateRole(SysRoleBo bo) { |
| | | SysRole role = MapstructUtils.convert(bo, SysRole.class); |
| | | |
| | | if (UserConstants.ROLE_DISABLE.equals(role.getStatus()) && this.countUserRoleByRoleId(role.getRoleId()) > 0) { |
| | | throw new ServiceException("角色已分配,不能禁用!"); |
| | | } |
| | | // 修改角色信息 |
| | | baseMapper.updateById(role); |
| | | // 删除角色与菜单关联 |
| | |
| | | */ |
| | | @Override |
| | | public int updateRoleStatus(Long roleId, String status) { |
| | | if (UserConstants.ROLE_DISABLE.equals(status) && this.countUserRoleByRoleId(roleId) > 0) { |
| | | throw new ServiceException("角色已分配,不能禁用!"); |
| | | } |
| | | return baseMapper.update(null, |
| | | new LambdaUpdateWrapper<SysRole>() |
| | | .set(SysRole::getStatus, status) |
| | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int deleteRoleByIds(Long[] roleIds) { |
| | | for (Long roleId : roleIds) { |
| | | checkRoleAllowed(roleId); |
| | | checkRoleDataScope(roleId); |
| | | SysRole role = baseMapper.selectById(roleId); |
| | | checkRoleAllowed(BeanUtil.toBean(role, SysRoleBo.class)); |
| | | checkRoleDataScope(roleId); |
| | | if (countUserRoleByRoleId(roleId) > 0) { |
| | | throw new ServiceException(String.format("%1$s已分配,不能删除", role.getRoleName())); |
| | | throw new ServiceException(String.format("%1$s已分配,不能删除!", role.getRoleName())); |
| | | } |
| | | } |
| | | List<Long> ids = Arrays.asList(roleIds); |
| | |
| | | roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, ids)); |
| | | // 删除角色与部门关联 |
| | | roleDeptMapper.delete(new LambdaQueryWrapper<SysRoleDept>().in(SysRoleDept::getRoleId, ids)); |
| | | return baseMapper.deleteBatchIds(ids); |
| | | return baseMapper.deleteByIds(ids); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @Override |
| | | public int deleteAuthUser(SysUserRole userRole) { |
| | | return userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>() |
| | | int rows = userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>() |
| | | .eq(SysUserRole::getRoleId, userRole.getRoleId()) |
| | | .eq(SysUserRole::getUserId, userRole.getUserId())); |
| | | if (rows > 0) { |
| | | cleanOnlineUserByRole(userRole.getRoleId()); |
| | | } |
| | | return rows; |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @Override |
| | | public int deleteAuthUsers(Long roleId, Long[] userIds) { |
| | | return userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>() |
| | | int rows = userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>() |
| | | .eq(SysUserRole::getRoleId, roleId) |
| | | .in(SysUserRole::getUserId, Arrays.asList(userIds))); |
| | | if (rows > 0) { |
| | | cleanOnlineUserByRole(roleId); |
| | | } |
| | | return rows; |
| | | } |
| | | |
| | | /** |
| | |
| | | if (CollUtil.isNotEmpty(list)) { |
| | | rows = userRoleMapper.insertBatch(list) ? list.size() : 0; |
| | | } |
| | | if (rows > 0) { |
| | | cleanOnlineUserByRole(roleId); |
| | | } |
| | | return rows; |
| | | } |
| | | |
| | | @Override |
| | | public void cleanOnlineUserByRole(Long roleId) { |
| | | // 如果角色未绑定用户 直接返回 |
| | | Long num = userRoleMapper.selectCount(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getRoleId, roleId)); |
| | | if (num == 0) { |
| | | return; |
| | | } |
| | | List<String> keys = StpUtil.searchTokenValue("", 0, -1, false); |
| | | if (CollUtil.isEmpty(keys)) { |
| | | return; |
| | | } |
| | | // 角色关联的在线用户量过大会导致redis阻塞卡顿 谨慎操作 |
| | | keys.parallelStream().forEach(key -> { |
| | | String token = StringUtils.substringAfterLast(key, ":"); |
| | | // 如果已经过期则跳过 |
| | | if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < -1) { |
| | | return; |
| | | } |
| | | LoginUser loginUser = LoginHelper.getLoginUser(token); |
| | | if (loginUser.getRoles().stream().anyMatch(r -> r.getRoleId().equals(roleId))) { |
| | | try { |
| | | StpUtil.logoutByTokenValue(token); |
| | | } catch (NotLoginException ignored) { |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | } |