mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-11-04 09:01:37 +08:00 
			
		
		
		
	refactor: 重构权限变更逻辑,修改角色、变更用户角色不再下线用户
This commit is contained in:
		@@ -25,6 +25,7 @@ import java.io.Serial;
 | 
				
			|||||||
import java.io.Serializable;
 | 
					import java.io.Serializable;
 | 
				
			||||||
import java.time.LocalDateTime;
 | 
					import java.time.LocalDateTime;
 | 
				
			||||||
import java.util.Set;
 | 
					import java.util.Set;
 | 
				
			||||||
 | 
					import java.util.stream.Collectors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * 登录用户信息
 | 
					 * 登录用户信息
 | 
				
			||||||
@@ -109,16 +110,17 @@ public class LoginUser implements Serializable {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    private Integer passwordExpirationDays;
 | 
					    private Integer passwordExpirationDays;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public LoginUser(Set<String> permissions,
 | 
					    public LoginUser(Set<String> permissions, Set<RoleDTO> roles, Integer passwordExpirationDays) {
 | 
				
			||||||
                     Set<String> roleCodes,
 | 
					 | 
				
			||||||
                     Set<RoleDTO> roles,
 | 
					 | 
				
			||||||
                     Integer passwordExpirationDays) {
 | 
					 | 
				
			||||||
        this.permissions = permissions;
 | 
					        this.permissions = permissions;
 | 
				
			||||||
        this.roleCodes = roleCodes;
 | 
					        this.setRoles(roles);
 | 
				
			||||||
        this.roles = roles;
 | 
					 | 
				
			||||||
        this.passwordExpirationDays = passwordExpirationDays;
 | 
					        this.passwordExpirationDays = passwordExpirationDays;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void setRoles(Set<RoleDTO> roles) {
 | 
				
			||||||
 | 
					        this.roles = roles;
 | 
				
			||||||
 | 
					        this.roleCodes = roles.stream().map(RoleDTO::getCode).collect(Collectors.toSet());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 是否为管理员
 | 
					     * 是否为管理员
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -69,6 +69,18 @@ public class LoginHelper {
 | 
				
			|||||||
        return tokenValue;
 | 
					        return tokenValue;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 更新登录用户信息
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param loginUser
 | 
				
			||||||
 | 
					     *                  登录用户信息
 | 
				
			||||||
 | 
					     * @param token     令牌
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static void updateLoginUser(LoginUser loginUser, String token) {
 | 
				
			||||||
 | 
					        SaHolder.getStorage().delete(CacheConstants.LOGIN_USER_KEY);
 | 
				
			||||||
 | 
					        StpUtil.getTokenSessionByToken(token).set(CacheConstants.LOGIN_USER_KEY, loginUser);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 获取登录用户信息
 | 
					     * 获取登录用户信息
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,4 +51,16 @@ public class OnlineUserQuery implements Serializable {
 | 
				
			|||||||
    @Schema(description = "登录时间", example = "2023-08-08 00:00:00,2023-08-08 23:59:59")
 | 
					    @Schema(description = "登录时间", example = "2023-08-08 00:00:00,2023-08-08 23:59:59")
 | 
				
			||||||
    @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
 | 
					    @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
 | 
				
			||||||
    private List<Date> loginTime;
 | 
					    private List<Date> loginTime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 用户 ID
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @Schema(hidden = true)
 | 
				
			||||||
 | 
					    private Long userId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 角色 ID
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @Schema(hidden = true)
 | 
				
			||||||
 | 
					    private Long roleId;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,16 +59,9 @@ public interface OnlineUserService {
 | 
				
			|||||||
    LocalDateTime getLastActiveTime(String token);
 | 
					    LocalDateTime getLastActiveTime(String token);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 根据角色 ID 清除
 | 
					     * 踢出用户
 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param roleId 角色 ID
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    void cleanByRoleId(Long roleId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 根据用户 ID 清除登录
 | 
					 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param userId 用户 ID
 | 
					     * @param userId 用户 ID
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    void cleanByUserId(Long userId);
 | 
					    void kickOut(Long userId);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,44 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
 * you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
 * You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
 * See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
 * limitations under the License.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package top.continew.admin.auth.service;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import java.util.Set;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * 权限业务接口
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @author Charles7c
 | 
					 | 
				
			||||||
 * @since 2023/3/2 20:40
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
public interface PermissionService {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 根据用户 ID 查询权限码
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param userId 用户 ID
 | 
					 | 
				
			||||||
     * @return 权限码集合
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    Set<String> listPermissionByUserId(Long userId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * 根据用户 ID 查询角色编码
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param userId 用户 ID
 | 
					 | 
				
			||||||
     * @return 角色编码集合
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    Set<String> listRoleCodeByUserId(Long userId);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -36,18 +36,17 @@ import org.springframework.stereotype.Service;
 | 
				
			|||||||
import org.springframework.transaction.annotation.Transactional;
 | 
					import org.springframework.transaction.annotation.Transactional;
 | 
				
			||||||
import top.continew.admin.auth.model.resp.RouteResp;
 | 
					import top.continew.admin.auth.model.resp.RouteResp;
 | 
				
			||||||
import top.continew.admin.auth.service.LoginService;
 | 
					import top.continew.admin.auth.service.LoginService;
 | 
				
			||||||
import top.continew.admin.auth.service.PermissionService;
 | 
					 | 
				
			||||||
import top.continew.admin.common.constant.CacheConstants;
 | 
					import top.continew.admin.common.constant.CacheConstants;
 | 
				
			||||||
import top.continew.admin.common.constant.RegexConstants;
 | 
					import top.continew.admin.common.constant.RegexConstants;
 | 
				
			||||||
import top.continew.admin.common.constant.SysConstants;
 | 
					import top.continew.admin.common.constant.SysConstants;
 | 
				
			||||||
import top.continew.admin.common.enums.DisEnableStatusEnum;
 | 
					import top.continew.admin.common.enums.DisEnableStatusEnum;
 | 
				
			||||||
import top.continew.admin.common.enums.GenderEnum;
 | 
					import top.continew.admin.common.enums.GenderEnum;
 | 
				
			||||||
import top.continew.admin.system.enums.MenuTypeEnum;
 | 
					 | 
				
			||||||
import top.continew.admin.system.enums.MessageTypeEnum;
 | 
					 | 
				
			||||||
import top.continew.admin.common.model.dto.LoginUser;
 | 
					import top.continew.admin.common.model.dto.LoginUser;
 | 
				
			||||||
import top.continew.admin.common.model.dto.RoleDTO;
 | 
					import top.continew.admin.common.model.dto.RoleDTO;
 | 
				
			||||||
import top.continew.admin.common.util.helper.LoginHelper;
 | 
					import top.continew.admin.common.util.helper.LoginHelper;
 | 
				
			||||||
 | 
					import top.continew.admin.system.enums.MenuTypeEnum;
 | 
				
			||||||
import top.continew.admin.system.enums.MessageTemplateEnum;
 | 
					import top.continew.admin.system.enums.MessageTemplateEnum;
 | 
				
			||||||
 | 
					import top.continew.admin.system.enums.MessageTypeEnum;
 | 
				
			||||||
import top.continew.admin.system.enums.PasswordPolicyEnum;
 | 
					import top.continew.admin.system.enums.PasswordPolicyEnum;
 | 
				
			||||||
import top.continew.admin.system.model.entity.DeptDO;
 | 
					import top.continew.admin.system.model.entity.DeptDO;
 | 
				
			||||||
import top.continew.admin.system.model.entity.RoleDO;
 | 
					import top.continew.admin.system.model.entity.RoleDO;
 | 
				
			||||||
@@ -81,17 +80,16 @@ import static top.continew.admin.system.enums.PasswordPolicyEnum.PASSWORD_EXPIRA
 | 
				
			|||||||
public class LoginServiceImpl implements LoginService {
 | 
					public class LoginServiceImpl implements LoginService {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final ProjectProperties projectProperties;
 | 
					    private final ProjectProperties projectProperties;
 | 
				
			||||||
 | 
					    private final PasswordEncoder passwordEncoder;
 | 
				
			||||||
 | 
					    private final ThreadPoolTaskExecutor threadPoolTaskExecutor;
 | 
				
			||||||
    private final UserService userService;
 | 
					    private final UserService userService;
 | 
				
			||||||
    private final DeptService deptService;
 | 
					    private final DeptService deptService;
 | 
				
			||||||
    private final RoleService roleService;
 | 
					    private final RoleService roleService;
 | 
				
			||||||
    private final MenuService menuService;
 | 
					    private final MenuService menuService;
 | 
				
			||||||
    private final PermissionService permissionService;
 | 
					 | 
				
			||||||
    private final UserRoleService userRoleService;
 | 
					    private final UserRoleService userRoleService;
 | 
				
			||||||
    private final UserSocialService userSocialService;
 | 
					    private final UserSocialService userSocialService;
 | 
				
			||||||
    private final MessageService messageService;
 | 
					 | 
				
			||||||
    private final PasswordEncoder passwordEncoder;
 | 
					 | 
				
			||||||
    private final OptionService optionService;
 | 
					    private final OptionService optionService;
 | 
				
			||||||
    private final ThreadPoolTaskExecutor threadPoolTaskExecutor;
 | 
					    private final MessageService messageService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public String accountLogin(String username, String password, HttpServletRequest request) {
 | 
					    public String accountLogin(String username, String password, HttpServletRequest request) {
 | 
				
			||||||
@@ -163,7 +161,7 @@ public class LoginServiceImpl implements LoginService {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public List<RouteResp> buildRouteTree(Long userId) {
 | 
					    public List<RouteResp> buildRouteTree(Long userId) {
 | 
				
			||||||
        Set<String> roleCodeSet = permissionService.listRoleCodeByUserId(userId);
 | 
					        Set<String> roleCodeSet = roleService.listCodeByUserId(userId);
 | 
				
			||||||
        if (CollUtil.isEmpty(roleCodeSet)) {
 | 
					        if (CollUtil.isEmpty(roleCodeSet)) {
 | 
				
			||||||
            return new ArrayList<>(0);
 | 
					            return new ArrayList<>(0);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -205,17 +203,15 @@ public class LoginServiceImpl implements LoginService {
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    private String login(UserDO user) {
 | 
					    private String login(UserDO user) {
 | 
				
			||||||
        Long userId = user.getId();
 | 
					        Long userId = user.getId();
 | 
				
			||||||
        CompletableFuture<Set<String>> permissionFuture = CompletableFuture.supplyAsync(() -> permissionService
 | 
					        CompletableFuture<Set<String>> permissionFuture = CompletableFuture.supplyAsync(() -> roleService
 | 
				
			||||||
            .listPermissionByUserId(userId), threadPoolTaskExecutor);
 | 
					            .listPermissionByUserId(userId), threadPoolTaskExecutor);
 | 
				
			||||||
        CompletableFuture<Set<String>> roleCodeFuture = CompletableFuture.supplyAsync(() -> permissionService
 | 
					 | 
				
			||||||
            .listRoleCodeByUserId(userId), threadPoolTaskExecutor);
 | 
					 | 
				
			||||||
        CompletableFuture<Set<RoleDTO>> roleFuture = CompletableFuture.supplyAsync(() -> roleService
 | 
					        CompletableFuture<Set<RoleDTO>> roleFuture = CompletableFuture.supplyAsync(() -> roleService
 | 
				
			||||||
            .listByUserId(userId), threadPoolTaskExecutor);
 | 
					            .listByUserId(userId), threadPoolTaskExecutor);
 | 
				
			||||||
        CompletableFuture<Integer> passwordExpirationDaysFuture = CompletableFuture.supplyAsync(() -> optionService
 | 
					        CompletableFuture<Integer> passwordExpirationDaysFuture = CompletableFuture.supplyAsync(() -> optionService
 | 
				
			||||||
            .getValueByCode2Int(PASSWORD_EXPIRATION_DAYS.name()));
 | 
					            .getValueByCode2Int(PASSWORD_EXPIRATION_DAYS.name()));
 | 
				
			||||||
        CompletableFuture.allOf(permissionFuture, roleCodeFuture, roleFuture);
 | 
					        CompletableFuture.allOf(permissionFuture, roleFuture, passwordExpirationDaysFuture);
 | 
				
			||||||
        LoginUser loginUser = new LoginUser(permissionFuture.join(), roleCodeFuture.join(), roleFuture
 | 
					        LoginUser loginUser = new LoginUser(permissionFuture.join(), roleFuture.join(), passwordExpirationDaysFuture
 | 
				
			||||||
            .join(), passwordExpirationDaysFuture.join());
 | 
					            .join());
 | 
				
			||||||
        BeanUtil.copyProperties(user, loginUser);
 | 
					        BeanUtil.copyProperties(user, loginUser);
 | 
				
			||||||
        return LoginHelper.login(loginUser);
 | 
					        return LoginHelper.login(loginUser);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,12 +18,12 @@ package top.continew.admin.auth.service.impl;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import cn.crane4j.annotation.AutoOperate;
 | 
					import cn.crane4j.annotation.AutoOperate;
 | 
				
			||||||
import cn.dev33.satoken.dao.SaTokenDao;
 | 
					import cn.dev33.satoken.dao.SaTokenDao;
 | 
				
			||||||
import cn.dev33.satoken.exception.NotLoginException;
 | 
					 | 
				
			||||||
import cn.dev33.satoken.stp.StpUtil;
 | 
					import cn.dev33.satoken.stp.StpUtil;
 | 
				
			||||||
import cn.hutool.core.bean.BeanUtil;
 | 
					import cn.hutool.core.bean.BeanUtil;
 | 
				
			||||||
import cn.hutool.core.collection.CollUtil;
 | 
					import cn.hutool.core.collection.CollUtil;
 | 
				
			||||||
import cn.hutool.core.date.DateUtil;
 | 
					import cn.hutool.core.date.DateUtil;
 | 
				
			||||||
import cn.hutool.core.util.StrUtil;
 | 
					import cn.hutool.core.util.StrUtil;
 | 
				
			||||||
 | 
					import lombok.RequiredArgsConstructor;
 | 
				
			||||||
import org.springframework.stereotype.Service;
 | 
					import org.springframework.stereotype.Service;
 | 
				
			||||||
import top.continew.admin.auth.model.query.OnlineUserQuery;
 | 
					import top.continew.admin.auth.model.query.OnlineUserQuery;
 | 
				
			||||||
import top.continew.admin.auth.model.resp.OnlineUserResp;
 | 
					import top.continew.admin.auth.model.resp.OnlineUserResp;
 | 
				
			||||||
@@ -44,10 +44,10 @@ import java.util.List;
 | 
				
			|||||||
 * 在线用户业务实现
 | 
					 * 在线用户业务实现
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @author Charles7c
 | 
					 * @author Charles7c
 | 
				
			||||||
 * @author Lion Li(<a href="https://gitee.com/dromara/RuoYi-Vue-Plus">RuoYi-Vue-Plus</a>)
 | 
					 | 
				
			||||||
 * @since 2023/3/25 22:49
 | 
					 * @since 2023/3/25 22:49
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@Service
 | 
					@Service
 | 
				
			||||||
 | 
					@RequiredArgsConstructor
 | 
				
			||||||
public class OnlineUserServiceImpl implements OnlineUserService {
 | 
					public class OnlineUserServiceImpl implements OnlineUserService {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
@@ -63,18 +63,18 @@ public class OnlineUserServiceImpl implements OnlineUserService {
 | 
				
			|||||||
        List<LoginUser> loginUserList = new ArrayList<>();
 | 
					        List<LoginUser> loginUserList = new ArrayList<>();
 | 
				
			||||||
        // 查询所有登录用户
 | 
					        // 查询所有登录用户
 | 
				
			||||||
        List<String> tokenKeyList = StpUtil.searchTokenValue(StringConstants.EMPTY, 0, -1, false);
 | 
					        List<String> tokenKeyList = StpUtil.searchTokenValue(StringConstants.EMPTY, 0, -1, false);
 | 
				
			||||||
        for (String tokenKey : tokenKeyList) {
 | 
					        tokenKeyList.parallelStream().forEach(tokenKey -> {
 | 
				
			||||||
            String token = StrUtil.subAfter(tokenKey, StringConstants.COLON, true);
 | 
					            String token = StrUtil.subAfter(tokenKey, StringConstants.COLON, true);
 | 
				
			||||||
            // 忽略已过期或失效 Token
 | 
					            // 忽略已过期或失效 Token
 | 
				
			||||||
            if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < SaTokenDao.NEVER_EXPIRE) {
 | 
					            if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < SaTokenDao.NEVER_EXPIRE) {
 | 
				
			||||||
                continue;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            // 检查是否符合查询条件
 | 
					            // 检查是否符合查询条件
 | 
				
			||||||
            LoginUser loginUser = LoginHelper.getLoginUser(token);
 | 
					            LoginUser loginUser = LoginHelper.getLoginUser(token);
 | 
				
			||||||
            if (this.isMatchQuery(query, loginUser)) {
 | 
					            if (this.isMatchQuery(query, loginUser)) {
 | 
				
			||||||
                loginUserList.add(loginUser);
 | 
					                loginUserList.add(loginUser);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        });
 | 
				
			||||||
        // 设置排序
 | 
					        // 设置排序
 | 
				
			||||||
        CollUtil.sort(loginUserList, Comparator.comparing(LoginUser::getLoginTime).reversed());
 | 
					        CollUtil.sort(loginUserList, Comparator.comparing(LoginUser::getLoginTime).reversed());
 | 
				
			||||||
        return loginUserList;
 | 
					        return loginUserList;
 | 
				
			||||||
@@ -87,20 +87,7 @@ public class OnlineUserServiceImpl implements OnlineUserService {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void cleanByRoleId(Long roleId) {
 | 
					    public void kickOut(Long userId) {
 | 
				
			||||||
        List<LoginUser> loginUserList = this.list(new OnlineUserQuery());
 | 
					 | 
				
			||||||
        loginUserList.parallelStream().forEach(u -> {
 | 
					 | 
				
			||||||
            if (u.getRoles().stream().anyMatch(r -> r.getId().equals(roleId))) {
 | 
					 | 
				
			||||||
                try {
 | 
					 | 
				
			||||||
                    StpUtil.logoutByTokenValue(u.getToken());
 | 
					 | 
				
			||||||
                } catch (NotLoginException ignored) {
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public void cleanByUserId(Long userId) {
 | 
					 | 
				
			||||||
        if (!StpUtil.isLogin(userId)) {
 | 
					        if (!StpUtil.isLogin(userId)) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -121,13 +108,22 @@ public class OnlineUserServiceImpl implements OnlineUserService {
 | 
				
			|||||||
            flag1 = StrUtil.contains(loginUser.getUsername(), nickname) || StrUtil.contains(LoginHelper
 | 
					            flag1 = StrUtil.contains(loginUser.getUsername(), nickname) || StrUtil.contains(LoginHelper
 | 
				
			||||||
                .getNickname(loginUser.getId()), nickname);
 | 
					                .getNickname(loginUser.getId()), nickname);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        boolean flag2 = true;
 | 
					        boolean flag2 = true;
 | 
				
			||||||
        List<Date> loginTime = query.getLoginTime();
 | 
					        List<Date> loginTime = query.getLoginTime();
 | 
				
			||||||
        if (CollUtil.isNotEmpty(loginTime)) {
 | 
					        if (CollUtil.isNotEmpty(loginTime)) {
 | 
				
			||||||
            flag2 = DateUtil.isIn(DateUtil.date(loginUser.getLoginTime()).toJdkDate(), loginTime.get(0), loginTime
 | 
					            flag2 = DateUtil.isIn(DateUtil.date(loginUser.getLoginTime()).toJdkDate(), loginTime.get(0), loginTime
 | 
				
			||||||
                .get(1));
 | 
					                .get(1));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return flag1 && flag2;
 | 
					        boolean flag3 = true;
 | 
				
			||||||
 | 
					        Long userId = query.getUserId();
 | 
				
			||||||
 | 
					        if (null != userId) {
 | 
				
			||||||
 | 
					            flag3 = userId.equals(loginUser.getId());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        boolean flag4 = true;
 | 
				
			||||||
 | 
					        Long roleId = query.getRoleId();
 | 
				
			||||||
 | 
					        if (null != roleId) {
 | 
				
			||||||
 | 
					            flag4 = loginUser.getRoles().stream().anyMatch(r -> r.getId().equals(roleId));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return flag1 && flag2 && flag3 && flag4;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,56 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
 * you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
 * You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
 * See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
 * limitations under the License.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package top.continew.admin.auth.service.impl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import cn.hutool.core.collection.CollUtil;
 | 
					 | 
				
			||||||
import lombok.RequiredArgsConstructor;
 | 
					 | 
				
			||||||
import org.springframework.stereotype.Service;
 | 
					 | 
				
			||||||
import top.continew.admin.auth.service.PermissionService;
 | 
					 | 
				
			||||||
import top.continew.admin.common.constant.SysConstants;
 | 
					 | 
				
			||||||
import top.continew.admin.system.service.MenuService;
 | 
					 | 
				
			||||||
import top.continew.admin.system.service.RoleService;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import java.util.Set;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * 权限业务实现
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @author Charles7c
 | 
					 | 
				
			||||||
 * @since 2023/3/2 20:40
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
@Service
 | 
					 | 
				
			||||||
@RequiredArgsConstructor
 | 
					 | 
				
			||||||
public class PermissionServiceImpl implements PermissionService {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private final MenuService menuService;
 | 
					 | 
				
			||||||
    private final RoleService roleService;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public Set<String> listPermissionByUserId(Long userId) {
 | 
					 | 
				
			||||||
        Set<String> roleCodeSet = this.listRoleCodeByUserId(userId);
 | 
					 | 
				
			||||||
        // 超级管理员赋予全部权限
 | 
					 | 
				
			||||||
        if (roleCodeSet.contains(SysConstants.ADMIN_ROLE_CODE)) {
 | 
					 | 
				
			||||||
            return CollUtil.newHashSet(SysConstants.ALL_PERMISSION);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return menuService.listPermissionByUserId(userId);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public Set<String> listRoleCodeByUserId(Long userId) {
 | 
					 | 
				
			||||||
        return roleService.listCodeByUserId(userId);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -36,6 +36,14 @@ import java.util.Set;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
public interface RoleService extends BaseService<RoleResp, RoleDetailResp, RoleQuery, RoleReq>, IService<RoleDO> {
 | 
					public interface RoleService extends BaseService<RoleResp, RoleDetailResp, RoleQuery, RoleReq>, IService<RoleDO> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 根据用户 ID 查询权限码
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param userId 用户 ID
 | 
				
			||||||
 | 
					     * @return 权限码集合
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Set<String> listPermissionByUserId(Long userId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 根据 ID 列表查询
 | 
					     * 根据 ID 列表查询
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,12 +26,15 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 | 
				
			|||||||
import lombok.RequiredArgsConstructor;
 | 
					import lombok.RequiredArgsConstructor;
 | 
				
			||||||
import org.springframework.stereotype.Service;
 | 
					import org.springframework.stereotype.Service;
 | 
				
			||||||
import org.springframework.transaction.annotation.Transactional;
 | 
					import org.springframework.transaction.annotation.Transactional;
 | 
				
			||||||
 | 
					import top.continew.admin.auth.model.query.OnlineUserQuery;
 | 
				
			||||||
import top.continew.admin.auth.service.OnlineUserService;
 | 
					import top.continew.admin.auth.service.OnlineUserService;
 | 
				
			||||||
import top.continew.admin.common.constant.CacheConstants;
 | 
					import top.continew.admin.common.constant.CacheConstants;
 | 
				
			||||||
import top.continew.admin.common.constant.ContainerConstants;
 | 
					import top.continew.admin.common.constant.ContainerConstants;
 | 
				
			||||||
import top.continew.admin.common.constant.SysConstants;
 | 
					import top.continew.admin.common.constant.SysConstants;
 | 
				
			||||||
import top.continew.admin.common.enums.DataScopeEnum;
 | 
					import top.continew.admin.common.enums.DataScopeEnum;
 | 
				
			||||||
 | 
					import top.continew.admin.common.model.dto.LoginUser;
 | 
				
			||||||
import top.continew.admin.common.model.dto.RoleDTO;
 | 
					import top.continew.admin.common.model.dto.RoleDTO;
 | 
				
			||||||
 | 
					import top.continew.admin.common.util.helper.LoginHelper;
 | 
				
			||||||
import top.continew.admin.system.mapper.RoleMapper;
 | 
					import top.continew.admin.system.mapper.RoleMapper;
 | 
				
			||||||
import top.continew.admin.system.model.entity.RoleDO;
 | 
					import top.continew.admin.system.model.entity.RoleDO;
 | 
				
			||||||
import top.continew.admin.system.model.query.RoleQuery;
 | 
					import top.continew.admin.system.model.query.RoleQuery;
 | 
				
			||||||
@@ -57,10 +60,10 @@ import java.util.stream.Collectors;
 | 
				
			|||||||
public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleResp, RoleDetailResp, RoleQuery, RoleReq> implements RoleService {
 | 
					public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleResp, RoleDetailResp, RoleQuery, RoleReq> implements RoleService {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final MenuService menuService;
 | 
					    private final MenuService menuService;
 | 
				
			||||||
    private final OnlineUserService onlineUserService;
 | 
					 | 
				
			||||||
    private final RoleMenuService roleMenuService;
 | 
					    private final RoleMenuService roleMenuService;
 | 
				
			||||||
    private final RoleDeptService roleDeptService;
 | 
					    private final RoleDeptService roleDeptService;
 | 
				
			||||||
    private final UserRoleService userRoleService;
 | 
					    private final UserRoleService userRoleService;
 | 
				
			||||||
 | 
					    private final OnlineUserService onlineUserService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    @Transactional(rollbackFor = Exception.class)
 | 
					    @Transactional(rollbackFor = Exception.class)
 | 
				
			||||||
@@ -92,16 +95,23 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleRes
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        // 更新信息
 | 
					        // 更新信息
 | 
				
			||||||
        super.update(req, id);
 | 
					        super.update(req, id);
 | 
				
			||||||
        // 更新关联信息
 | 
					        if (SysConstants.ADMIN_ROLE_CODE.equals(req.getCode())) {
 | 
				
			||||||
        if (!SysConstants.ADMIN_ROLE_CODE.equals(oldRole.getCode())) {
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        // 保存角色和菜单关联
 | 
					        // 保存角色和菜单关联
 | 
				
			||||||
        boolean isSaveMenuSuccess = roleMenuService.add(req.getMenuIds(), id);
 | 
					        boolean isSaveMenuSuccess = roleMenuService.add(req.getMenuIds(), id);
 | 
				
			||||||
        // 保存角色和部门关联
 | 
					        // 保存角色和部门关联
 | 
				
			||||||
        boolean isSaveDeptSuccess = roleDeptService.add(req.getDeptIds(), id);
 | 
					        boolean isSaveDeptSuccess = roleDeptService.add(req.getDeptIds(), id);
 | 
				
			||||||
            // 如果功能权限或数据权限有变更,则清除关联的在线用户(重新登录以获取最新角色权限)
 | 
					        // 如果功能权限或数据权限有变更,则更新在线用户权限信息
 | 
				
			||||||
        if (ObjectUtil.notEqual(req.getDataScope(), oldDataScope) || isSaveMenuSuccess || isSaveDeptSuccess) {
 | 
					        if (ObjectUtil.notEqual(req.getDataScope(), oldDataScope) || isSaveMenuSuccess || isSaveDeptSuccess) {
 | 
				
			||||||
                onlineUserService.cleanByRoleId(id);
 | 
					            OnlineUserQuery query = new OnlineUserQuery();
 | 
				
			||||||
            }
 | 
					            query.setRoleId(id);
 | 
				
			||||||
 | 
					            List<LoginUser> loginUserList = onlineUserService.list(query);
 | 
				
			||||||
 | 
					            loginUserList.parallelStream().forEach(loginUser -> {
 | 
				
			||||||
 | 
					                loginUser.setRoles(this.listByUserId(loginUser.getId()));
 | 
				
			||||||
 | 
					                loginUser.setPermissions(this.listPermissionByUserId(loginUser.getId()));
 | 
				
			||||||
 | 
					                LoginHelper.updateLoginUser(loginUser, loginUser.getToken());
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -136,6 +146,16 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleRes
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public Set<String> listPermissionByUserId(Long userId) {
 | 
				
			||||||
 | 
					        Set<String> roleCodeSet = this.listCodeByUserId(userId);
 | 
				
			||||||
 | 
					        // 超级管理员赋予全部权限
 | 
				
			||||||
 | 
					        if (roleCodeSet.contains(SysConstants.ADMIN_ROLE_CODE)) {
 | 
				
			||||||
 | 
					            return CollUtil.newHashSet(SysConstants.ALL_PERMISSION);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return menuService.listPermissionByUserId(userId);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    @ContainerMethod(namespace = ContainerConstants.USER_ROLE_NAME_LIST, type = MappingType.ORDER_OF_KEYS)
 | 
					    @ContainerMethod(namespace = ContainerConstants.USER_ROLE_NAME_LIST, type = MappingType.ORDER_OF_KEYS)
 | 
				
			||||||
    public List<String> listNameByIds(List<Long> ids) {
 | 
					    public List<String> listNameByIds(List<Long> ids) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,11 +52,13 @@ import org.springframework.security.crypto.password.PasswordEncoder;
 | 
				
			|||||||
import org.springframework.stereotype.Service;
 | 
					import org.springframework.stereotype.Service;
 | 
				
			||||||
import org.springframework.transaction.annotation.Transactional;
 | 
					import org.springframework.transaction.annotation.Transactional;
 | 
				
			||||||
import org.springframework.web.multipart.MultipartFile;
 | 
					import org.springframework.web.multipart.MultipartFile;
 | 
				
			||||||
 | 
					import top.continew.admin.auth.model.query.OnlineUserQuery;
 | 
				
			||||||
import top.continew.admin.auth.service.OnlineUserService;
 | 
					import top.continew.admin.auth.service.OnlineUserService;
 | 
				
			||||||
import top.continew.admin.common.constant.CacheConstants;
 | 
					import top.continew.admin.common.constant.CacheConstants;
 | 
				
			||||||
import top.continew.admin.common.constant.SysConstants;
 | 
					import top.continew.admin.common.constant.SysConstants;
 | 
				
			||||||
import top.continew.admin.common.enums.DisEnableStatusEnum;
 | 
					import top.continew.admin.common.enums.DisEnableStatusEnum;
 | 
				
			||||||
import top.continew.admin.common.enums.GenderEnum;
 | 
					import top.continew.admin.common.enums.GenderEnum;
 | 
				
			||||||
 | 
					import top.continew.admin.common.model.dto.LoginUser;
 | 
				
			||||||
import top.continew.admin.common.util.SecureUtils;
 | 
					import top.continew.admin.common.util.SecureUtils;
 | 
				
			||||||
import top.continew.admin.common.util.helper.LoginHelper;
 | 
					import top.continew.admin.common.util.helper.LoginHelper;
 | 
				
			||||||
import top.continew.admin.system.mapper.UserMapper;
 | 
					import top.continew.admin.system.mapper.UserMapper;
 | 
				
			||||||
@@ -102,11 +104,11 @@ import static top.continew.admin.system.enums.PasswordPolicyEnum.*;
 | 
				
			|||||||
@RequiredArgsConstructor
 | 
					@RequiredArgsConstructor
 | 
				
			||||||
public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserResp, UserDetailResp, UserQuery, UserReq> implements UserService, CommonUserService {
 | 
					public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserResp, UserDetailResp, UserQuery, UserReq> implements UserService, CommonUserService {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final OnlineUserService onlineUserService;
 | 
					 | 
				
			||||||
    private final UserRoleService userRoleService;
 | 
					 | 
				
			||||||
    private final PasswordEncoder passwordEncoder;
 | 
					    private final PasswordEncoder passwordEncoder;
 | 
				
			||||||
    private final OptionService optionService;
 | 
					 | 
				
			||||||
    private final UserPasswordHistoryService userPasswordHistoryService;
 | 
					    private final UserPasswordHistoryService userPasswordHistoryService;
 | 
				
			||||||
 | 
					    private final OnlineUserService onlineUserService;
 | 
				
			||||||
 | 
					    private final OptionService optionService;
 | 
				
			||||||
 | 
					    private final UserRoleService userRoleService;
 | 
				
			||||||
    private final RoleService roleService;
 | 
					    private final RoleService roleService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Resource
 | 
					    @Resource
 | 
				
			||||||
@@ -324,9 +326,21 @@ public class UserServiceImpl extends BaseServiceImpl<UserMapper, UserDO, UserRes
 | 
				
			|||||||
        baseMapper.updateById(newUser);
 | 
					        baseMapper.updateById(newUser);
 | 
				
			||||||
        // 保存用户和角色关联
 | 
					        // 保存用户和角色关联
 | 
				
			||||||
        boolean isSaveUserRoleSuccess = userRoleService.add(req.getRoleIds(), id);
 | 
					        boolean isSaveUserRoleSuccess = userRoleService.add(req.getRoleIds(), id);
 | 
				
			||||||
        // 如果功能权限或数据权限有变更,则清除关联的在线用户(重新登录以获取最新角色权限)
 | 
					        // 如果禁用用户,则踢出在线用户
 | 
				
			||||||
        if (DisEnableStatusEnum.DISABLE.equals(newStatus) || isSaveUserRoleSuccess) {
 | 
					        if (DisEnableStatusEnum.DISABLE.equals(newStatus)) {
 | 
				
			||||||
            onlineUserService.cleanByUserId(id);
 | 
					            onlineUserService.kickOut(id);
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // 如果角色有变更,则更新在线用户权限信息
 | 
				
			||||||
 | 
					        if (isSaveUserRoleSuccess) {
 | 
				
			||||||
 | 
					            OnlineUserQuery query = new OnlineUserQuery();
 | 
				
			||||||
 | 
					            query.setUserId(id);
 | 
				
			||||||
 | 
					            List<LoginUser> loginUserList = onlineUserService.list(query);
 | 
				
			||||||
 | 
					            loginUserList.parallelStream().forEach(loginUser -> {
 | 
				
			||||||
 | 
					                loginUser.setRoles(roleService.listByUserId(loginUser.getId()));
 | 
				
			||||||
 | 
					                loginUser.setPermissions(roleService.listPermissionByUserId(loginUser.getId()));
 | 
				
			||||||
 | 
					                LoginHelper.updateLoginUser(loginUser, loginUser.getToken());
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user