diff --git a/src/main/java/com/youlai/boot/system/service/UserRoleService.java b/src/main/java/com/youlai/boot/system/service/UserRoleService.java index 697b86ca..e1d8c033 100644 --- a/src/main/java/com/youlai/boot/system/service/UserRoleService.java +++ b/src/main/java/com/youlai/boot/system/service/UserRoleService.java @@ -11,11 +11,11 @@ public interface UserRoleService extends IService { /** * 保存用户角色 * - * @param userId - * @param roleIds + * @param userId 用户ID + * @param roleIds 角色ID集合 * @return */ - boolean saveUserRoles(Long userId, List roleIds); + void saveUserRoles(Long userId, List roleIds); /** * 判断角色是否存在绑定的用户 diff --git a/src/main/java/com/youlai/boot/system/service/impl/UserRoleServiceImpl.java b/src/main/java/com/youlai/boot/system/service/impl/UserRoleServiceImpl.java index ce747648..d40c75c8 100644 --- a/src/main/java/com/youlai/boot/system/service/impl/UserRoleServiceImpl.java +++ b/src/main/java/com/youlai/boot/system/service/impl/UserRoleServiceImpl.java @@ -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 implements UserRoleService { + + private final TokenManager tokenManager; + /** * 保存用户角色 * - * @param userId - * @param roleIds + * @param userId 用户ID + * @param roleIds 选择的角色ID集合 * @return */ @Override - public boolean saveUserRoles(Long userId, List roleIds) { - + public void saveUserRoles(Long userId, List roleIds) { if (userId == null || CollectionUtil.isEmpty(roleIds)) { - return false; + return ; } - // 用户原角色ID集合 + // 获取现有角色 List userRoleIds = this.list(new LambdaQueryWrapper() + .select(UserRole::getRoleId) .eq(UserRole::getUserId, userId)) - .stream() + .parallelStream() .map(UserRole::getRoleId) - .collect(Collectors.toList()); + .toList(); - // 新增用户角色 - List saveRoleIds; - if (CollectionUtil.isEmpty(userRoleIds)) { - saveRoleIds = roleIds; - } else { - saveRoleIds = roleIds.stream() - .filter(roleId -> !userRoleIds.contains(roleId)) - .collect(Collectors.toList()); + // 使用Set提升对比效率 + Set oldRoles = new HashSet<>(userRoleIds); + Set newRoles = new HashSet<>(roleIds); + + // 计算变更集 + Set addedRoles = new HashSet<>(newRoles); + addedRoles.removeAll(oldRoles); + + Set 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 saveUserRoles = saveRoleIds - .stream() - .map(roleId -> new UserRole(userId, roleId)) - .collect(Collectors.toList()); - this.saveBatch(saveUserRoles); - - // 删除用户角色 - if (CollectionUtil.isNotEmpty(userRoleIds)) { - List removeRoleIds = userRoleIds.stream() - .filter(roleId -> !roleIds.contains(roleId)) - .collect(Collectors.toList()); - - if (CollectionUtil.isNotEmpty(removeRoleIds)) { - this.remove(new LambdaQueryWrapper() - .eq(UserRole::getUserId, userId) - .in(UserRole::getRoleId, removeRoleIds) - ); - } + // 删除废弃角色 + if (!removedRoles.isEmpty()) { + this.remove(new LambdaQueryWrapper() + .eq(UserRole::getUserId, userId) + .in(UserRole::getRoleId, removedRoles)); } - return true; + // 当权限变更时清除登录态 + if (rolesChanged) { + // 获取用户所有有效token(根据实际token存储实现) + String accessToken = SecurityUtils.getTokenFromRequest(); + tokenManager.invalidateToken(accessToken); + } } /** diff --git a/src/main/java/com/youlai/boot/system/service/impl/UserServiceImpl.java b/src/main/java/com/youlai/boot/system/service/impl/UserServiceImpl.java index d950ffa9..b67d66d0 100644 --- a/src/main/java/com/youlai/boot/system/service/impl/UserServiceImpl.java +++ b/src/main/java/com/youlai/boot/system/service/impl/UserServiceImpl.java @@ -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 implements UserService { private final PasswordEncoder passwordEncoder; @@ -436,9 +438,9 @@ public class UserServiceImpl extends ServiceImpl 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 templateParams = new HashMap<>(); templateParams.put("code", code); @@ -500,9 +502,9 @@ public class UserServiceImpl extends ServiceImpl 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分钟有效,用于更换邮箱校验