fix: 用户角色变化强制用户退出
This commit is contained in:
@@ -11,11 +11,11 @@ public interface UserRoleService extends IService<UserRole> {
|
||||
/**
|
||||
* 保存用户角色
|
||||
*
|
||||
* @param userId
|
||||
* @param roleIds
|
||||
* @param userId 用户ID
|
||||
* @param roleIds 角色ID集合
|
||||
* @return
|
||||
*/
|
||||
boolean saveUserRoles(Long userId, List<Long> roleIds);
|
||||
void saveUserRoles(Long userId, List<Long> roleIds);
|
||||
|
||||
/**
|
||||
* 判断角色是否存在绑定的用户
|
||||
|
||||
@@ -3,69 +3,81 @@ package com.youlai.boot.system.service.impl;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.youlai.boot.core.security.token.TokenManager;
|
||||
import com.youlai.boot.core.security.util.SecurityUtils;
|
||||
import com.youlai.boot.system.mapper.UserRoleMapper;
|
||||
import com.youlai.boot.system.model.entity.UserRole;
|
||||
import com.youlai.boot.system.service.UserRoleService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> implements UserRoleService {
|
||||
|
||||
|
||||
private final TokenManager tokenManager;
|
||||
|
||||
/**
|
||||
* 保存用户角色
|
||||
*
|
||||
* @param userId
|
||||
* @param roleIds
|
||||
* @param userId 用户ID
|
||||
* @param roleIds 选择的角色ID集合
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean saveUserRoles(Long userId, List<Long> roleIds) {
|
||||
|
||||
public void saveUserRoles(Long userId, List<Long> roleIds) {
|
||||
if (userId == null || CollectionUtil.isEmpty(roleIds)) {
|
||||
return false;
|
||||
return ;
|
||||
}
|
||||
|
||||
// 用户原角色ID集合
|
||||
// 获取现有角色
|
||||
List<Long> userRoleIds = this.list(new LambdaQueryWrapper<UserRole>()
|
||||
.select(UserRole::getRoleId)
|
||||
.eq(UserRole::getUserId, userId))
|
||||
.stream()
|
||||
.parallelStream()
|
||||
.map(UserRole::getRoleId)
|
||||
.collect(Collectors.toList());
|
||||
.toList();
|
||||
|
||||
// 新增用户角色
|
||||
List<Long> saveRoleIds;
|
||||
if (CollectionUtil.isEmpty(userRoleIds)) {
|
||||
saveRoleIds = roleIds;
|
||||
} else {
|
||||
saveRoleIds = roleIds.stream()
|
||||
.filter(roleId -> !userRoleIds.contains(roleId))
|
||||
.collect(Collectors.toList());
|
||||
// 使用Set提升对比效率
|
||||
Set<Long> oldRoles = new HashSet<>(userRoleIds);
|
||||
Set<Long> newRoles = new HashSet<>(roleIds);
|
||||
|
||||
// 计算变更集
|
||||
Set<Long> addedRoles = new HashSet<>(newRoles);
|
||||
addedRoles.removeAll(oldRoles);
|
||||
|
||||
Set<Long> removedRoles = new HashSet<>(oldRoles);
|
||||
removedRoles.removeAll(newRoles);
|
||||
|
||||
boolean rolesChanged = !addedRoles.isEmpty() || !removedRoles.isEmpty();
|
||||
|
||||
// 批量保存新增角色
|
||||
if (!addedRoles.isEmpty()) {
|
||||
this.saveBatch(addedRoles.stream()
|
||||
.map(roleId -> new UserRole(userId, roleId))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
List<UserRole> saveUserRoles = saveRoleIds
|
||||
.stream()
|
||||
.map(roleId -> new UserRole(userId, roleId))
|
||||
.collect(Collectors.toList());
|
||||
this.saveBatch(saveUserRoles);
|
||||
|
||||
// 删除用户角色
|
||||
if (CollectionUtil.isNotEmpty(userRoleIds)) {
|
||||
List<Long> removeRoleIds = userRoleIds.stream()
|
||||
.filter(roleId -> !roleIds.contains(roleId))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (CollectionUtil.isNotEmpty(removeRoleIds)) {
|
||||
this.remove(new LambdaQueryWrapper<UserRole>()
|
||||
.eq(UserRole::getUserId, userId)
|
||||
.in(UserRole::getRoleId, removeRoleIds)
|
||||
);
|
||||
}
|
||||
// 删除废弃角色
|
||||
if (!removedRoles.isEmpty()) {
|
||||
this.remove(new LambdaQueryWrapper<UserRole>()
|
||||
.eq(UserRole::getUserId, userId)
|
||||
.in(UserRole::getRoleId, removedRoles));
|
||||
}
|
||||
return true;
|
||||
|
||||
// 当权限变更时清除登录态
|
||||
if (rolesChanged) {
|
||||
// 获取用户所有有效token(根据实际token存储实现)
|
||||
String accessToken = SecurityUtils.getTokenFromRequest();
|
||||
tokenManager.invalidateToken(accessToken);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.youlai.boot.system.model.vo.UserPageVO;
|
||||
import com.youlai.boot.system.model.vo.UserProfileVO;
|
||||
import com.youlai.boot.system.service.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -51,6 +52,7 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
|
||||
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
@@ -436,9 +438,9 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
@Override
|
||||
public boolean sendMobileCode(String mobile) {
|
||||
|
||||
// String code = String.valueOf((int) ((Math.random() * 9 + 1) * 1000));
|
||||
// TODO 为了方便测试,验证码固定为 1234,实际开发中在配置了厂商短信服务后,可以使用上面的随机验证码
|
||||
String code = "1234";
|
||||
String code = String.valueOf((int) ((Math.random() * 9 + 1) * 1000));
|
||||
|
||||
log.info("【调试模式】手机号 {} 的验证码为:{}", mobile, code);
|
||||
|
||||
Map<String, String> templateParams = new HashMap<>();
|
||||
templateParams.put("code", code);
|
||||
@@ -500,9 +502,9 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
|
||||
@Override
|
||||
public void sendEmailCode(String email) {
|
||||
|
||||
// String code = String.valueOf((int) ((Math.random() * 9 + 1) * 1000));
|
||||
// TODO 为了方便测试,验证码固定为 1234,实际开发中在配置了邮箱服务后,可以使用上面的随机验证码
|
||||
String code = "1234";
|
||||
String code = String.valueOf((int) ((Math.random() * 9 + 1) * 1000));
|
||||
|
||||
log.info("【调试模式】邮箱 {} 的验证码为:{}", email, code);
|
||||
|
||||
mailService.sendMail(email, "邮箱验证码", "您的验证码为:" + code + ",请在5分钟内使用");
|
||||
// 缓存验证码,5分钟有效,用于更换邮箱校验
|
||||
|
||||
Reference in New Issue
Block a user