Pre Merge pull request !720 from AprilWind/dev-role

This commit is contained in:
AprilWind 2025-07-04 02:21:08 +00:00 committed by Gitee
commit e12b51afc3
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
4 changed files with 50 additions and 61 deletions

View File

@ -23,6 +23,7 @@ import org.dromara.system.service.ISysUserService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
/**
@ -144,7 +145,7 @@ public class SysRoleController extends BaseController {
@Log(title = "角色管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{roleIds}")
public R<Void> remove(@PathVariable Long[] roleIds) {
return toAjax(roleService.deleteRoleByIds(roleIds));
return toAjax(roleService.deleteRoleByIds(Arrays.asList(roleIds)));
}
/**

View File

@ -1,5 +1,6 @@
package org.dromara.system.mapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.system.domain.SysUserRole;
@ -20,4 +21,14 @@ public interface SysUserRoleMapper extends BaseMapperPlus<SysUserRole, SysUserRo
*/
List<Long> selectUserIdsByRoleId(Long roleId);
/**
* 根据角色ID统计关联的用户数量
*
* @param roleId 角色ID
* @return 绑定该角色的用户数量
*/
default long countUserByRoleId(Long roleId) {
return selectCount(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getRoleId, roleId));
}
}

View File

@ -167,7 +167,7 @@ public interface ISysRoleService {
* @param roleIds 需要删除的角色ID
* @return 结果
*/
int deleteRoleByIds(Long[] roleIds);
int deleteRoleByIds(List<Long> roleIds);
/**
* 取消授权用户角色
@ -195,8 +195,18 @@ public interface ISysRoleService {
*/
int insertAuthUsers(Long roleId, Long[] userIds);
/**
* 根据角色ID强制下线所有拥有该角色的在线用户
*
* @param roleId 角色ID
*/
void cleanOnlineUserByRole(Long roleId);
/**
* 强制下线指定用户ID列表中的所有在线用户
*
* @param userIds 用户ID列表
*/
void cleanOnlineUser(List<Long> userIds);
}

View File

@ -1,6 +1,5 @@
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;
@ -15,7 +14,7 @@ import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.CacheNames;
import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.constant.TenantConstants;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.enums.UserType;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.service.RoleService;
import org.dromara.common.core.utils.MapstructUtils;
@ -267,7 +266,7 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService {
*/
@Override
public long countUserRoleByRoleId(Long roleId) {
return userRoleMapper.selectCount(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getRoleId, roleId));
return userRoleMapper.countUserByRoleId(roleId);
}
/**
@ -412,21 +411,20 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService {
@CacheEvict(cacheNames = CacheNames.SYS_ROLE_CUSTOM, allEntries = true)
@Override
@Transactional(rollbackFor = Exception.class)
public int deleteRoleByIds(Long[] roleIds) {
for (Long roleId : roleIds) {
SysRole role = baseMapper.selectById(roleId);
public int deleteRoleByIds(List<Long> roleIds) {
List<SysRole> list = baseMapper.selectByIds(roleIds);
for (SysRole role : list) {
checkRoleAllowed(BeanUtil.toBean(role, SysRoleBo.class));
checkRoleDataScope(roleId);
if (countUserRoleByRoleId(roleId) > 0) {
checkRoleDataScope(role.getRoleId());
if (countUserRoleByRoleId(role.getRoleId()) > 0) {
throw new ServiceException(String.format("%1$s已分配不能删除!", role.getRoleName()));
}
}
List<Long> ids = Arrays.asList(roleIds);
// 删除角色与菜单关联
roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, ids));
roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, roleIds));
// 删除角色与部门关联
roleDeptMapper.delete(new LambdaQueryWrapper<SysRoleDept>().in(SysRoleDept::getRoleId, ids));
return baseMapper.deleteByIds(ids);
roleDeptMapper.delete(new LambdaQueryWrapper<SysRoleDept>().in(SysRoleDept::getRoleId, roleIds));
return baseMapper.deleteByIds(roleIds);
}
/**
@ -492,61 +490,30 @@ public class SysRoleServiceImpl implements ISysRoleService, RoleService {
return rows;
}
/**
* 根据角色ID强制下线所有拥有该角色的在线用户
*
* @param roleId 角色ID
*/
@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 (ObjectUtil.isNull(loginUser) || CollUtil.isEmpty(loginUser.getRoles())) {
return;
}
if (loginUser.getRoles().stream().anyMatch(r -> r.getRoleId().equals(roleId))) {
try {
StpUtil.logoutByTokenValue(token);
} catch (NotLoginException ignored) {
}
}
});
List<Long> userIds = userRoleMapper.selectUserIdsByRoleId(roleId);
this.cleanOnlineUser(userIds);
}
/**
* 强制下线指定用户ID列表中的所有在线用户
*
* @param userIds 用户ID列表
*/
@Override
public void cleanOnlineUser(List<Long> userIds) {
List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
if (CollUtil.isEmpty(keys)) {
if (CollUtil.isEmpty(userIds)) {
return;
}
// 角色关联的在线用户量过大会导致redis阻塞卡顿 谨慎操作
keys.parallelStream().forEach(key -> {
String token = StringUtils.substringAfterLast(key, ":");
// 如果已经过期则跳过
if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < -1) {
return;
}
LoginUser loginUser = LoginHelper.getLoginUser(token);
if (ObjectUtil.isNull(loginUser)) {
return;
}
if (userIds.contains(loginUser.getUserId())) {
try {
StpUtil.logoutByTokenValue(token);
} catch (NotLoginException ignored) {
}
}
});
for (Long userId : userIds) {
StpUtil.kickout(UserType.SYS_USER.getUserType() + ":" + userId);
}
}
/**