diff --git a/continew-admin-common/src/main/java/top/continew/admin/common/model/dto/LoginUser.java b/continew-admin-common/src/main/java/top/continew/admin/common/model/dto/LoginUser.java index 5f4b2c8e..76b24cf8 100644 --- a/continew-admin-common/src/main/java/top/continew/admin/common/model/dto/LoginUser.java +++ b/continew-admin-common/src/main/java/top/continew/admin/common/model/dto/LoginUser.java @@ -25,6 +25,7 @@ import java.io.Serial; import java.io.Serializable; import java.time.LocalDateTime; import java.util.Set; +import java.util.stream.Collectors; /** * 登录用户信息 @@ -109,16 +110,17 @@ public class LoginUser implements Serializable { */ private Integer passwordExpirationDays; - public LoginUser(Set permissions, - Set roleCodes, - Set roles, - Integer passwordExpirationDays) { + public LoginUser(Set permissions, Set roles, Integer passwordExpirationDays) { this.permissions = permissions; - this.roleCodes = roleCodes; - this.roles = roles; + this.setRoles(roles); this.passwordExpirationDays = passwordExpirationDays; } + public void setRoles(Set roles) { + this.roles = roles; + this.roleCodes = roles.stream().map(RoleDTO::getCode).collect(Collectors.toSet()); + } + /** * 是否为管理员 * diff --git a/continew-admin-common/src/main/java/top/continew/admin/common/util/helper/LoginHelper.java b/continew-admin-common/src/main/java/top/continew/admin/common/util/helper/LoginHelper.java index ba0b113b..aa0bcc07 100644 --- a/continew-admin-common/src/main/java/top/continew/admin/common/util/helper/LoginHelper.java +++ b/continew-admin-common/src/main/java/top/continew/admin/common/util/helper/LoginHelper.java @@ -69,6 +69,18 @@ public class LoginHelper { 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); + } + /** * 获取登录用户信息 * diff --git a/continew-admin-system/src/main/java/top/continew/admin/auth/model/query/OnlineUserQuery.java b/continew-admin-system/src/main/java/top/continew/admin/auth/model/query/OnlineUserQuery.java index aff46021..26a7ee7f 100644 --- a/continew-admin-system/src/main/java/top/continew/admin/auth/model/query/OnlineUserQuery.java +++ b/continew-admin-system/src/main/java/top/continew/admin/auth/model/query/OnlineUserQuery.java @@ -51,4 +51,16 @@ public class OnlineUserQuery implements Serializable { @Schema(description = "登录时间", example = "2023-08-08 00:00:00,2023-08-08 23:59:59") @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN) private List loginTime; + + /** + * 用户 ID + */ + @Schema(hidden = true) + private Long userId; + + /** + * 角色 ID + */ + @Schema(hidden = true) + private Long roleId; } diff --git a/continew-admin-system/src/main/java/top/continew/admin/auth/service/OnlineUserService.java b/continew-admin-system/src/main/java/top/continew/admin/auth/service/OnlineUserService.java index 5558b297..530efe12 100644 --- a/continew-admin-system/src/main/java/top/continew/admin/auth/service/OnlineUserService.java +++ b/continew-admin-system/src/main/java/top/continew/admin/auth/service/OnlineUserService.java @@ -59,16 +59,9 @@ public interface OnlineUserService { LocalDateTime getLastActiveTime(String token); /** - * 根据角色 ID 清除 - * - * @param roleId 角色 ID - */ - void cleanByRoleId(Long roleId); - - /** - * 根据用户 ID 清除登录 + * 踢出用户 * * @param userId 用户 ID */ - void cleanByUserId(Long userId); + void kickOut(Long userId); } diff --git a/continew-admin-system/src/main/java/top/continew/admin/auth/service/PermissionService.java b/continew-admin-system/src/main/java/top/continew/admin/auth/service/PermissionService.java deleted file mode 100644 index 5536870b..00000000 --- a/continew-admin-system/src/main/java/top/continew/admin/auth/service/PermissionService.java +++ /dev/null @@ -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 listPermissionByUserId(Long userId); - - /** - * 根据用户 ID 查询角色编码 - * - * @param userId 用户 ID - * @return 角色编码集合 - */ - Set listRoleCodeByUserId(Long userId); -} diff --git a/continew-admin-system/src/main/java/top/continew/admin/auth/service/impl/LoginServiceImpl.java b/continew-admin-system/src/main/java/top/continew/admin/auth/service/impl/LoginServiceImpl.java index da207c48..d040bad4 100644 --- a/continew-admin-system/src/main/java/top/continew/admin/auth/service/impl/LoginServiceImpl.java +++ b/continew-admin-system/src/main/java/top/continew/admin/auth/service/impl/LoginServiceImpl.java @@ -36,18 +36,17 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import top.continew.admin.auth.model.resp.RouteResp; 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.RegexConstants; import top.continew.admin.common.constant.SysConstants; import top.continew.admin.common.enums.DisEnableStatusEnum; 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.RoleDTO; 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.MessageTypeEnum; import top.continew.admin.system.enums.PasswordPolicyEnum; import top.continew.admin.system.model.entity.DeptDO; 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 { private final ProjectProperties projectProperties; + private final PasswordEncoder passwordEncoder; + private final ThreadPoolTaskExecutor threadPoolTaskExecutor; private final UserService userService; private final DeptService deptService; private final RoleService roleService; private final MenuService menuService; - private final PermissionService permissionService; private final UserRoleService userRoleService; private final UserSocialService userSocialService; - private final MessageService messageService; - private final PasswordEncoder passwordEncoder; private final OptionService optionService; - private final ThreadPoolTaskExecutor threadPoolTaskExecutor; + private final MessageService messageService; @Override public String accountLogin(String username, String password, HttpServletRequest request) { @@ -163,7 +161,7 @@ public class LoginServiceImpl implements LoginService { @Override public List buildRouteTree(Long userId) { - Set roleCodeSet = permissionService.listRoleCodeByUserId(userId); + Set roleCodeSet = roleService.listCodeByUserId(userId); if (CollUtil.isEmpty(roleCodeSet)) { return new ArrayList<>(0); } @@ -205,17 +203,15 @@ public class LoginServiceImpl implements LoginService { */ private String login(UserDO user) { Long userId = user.getId(); - CompletableFuture> permissionFuture = CompletableFuture.supplyAsync(() -> permissionService + CompletableFuture> permissionFuture = CompletableFuture.supplyAsync(() -> roleService .listPermissionByUserId(userId), threadPoolTaskExecutor); - CompletableFuture> roleCodeFuture = CompletableFuture.supplyAsync(() -> permissionService - .listRoleCodeByUserId(userId), threadPoolTaskExecutor); CompletableFuture> roleFuture = CompletableFuture.supplyAsync(() -> roleService .listByUserId(userId), threadPoolTaskExecutor); CompletableFuture passwordExpirationDaysFuture = CompletableFuture.supplyAsync(() -> optionService .getValueByCode2Int(PASSWORD_EXPIRATION_DAYS.name())); - CompletableFuture.allOf(permissionFuture, roleCodeFuture, roleFuture); - LoginUser loginUser = new LoginUser(permissionFuture.join(), roleCodeFuture.join(), roleFuture - .join(), passwordExpirationDaysFuture.join()); + CompletableFuture.allOf(permissionFuture, roleFuture, passwordExpirationDaysFuture); + LoginUser loginUser = new LoginUser(permissionFuture.join(), roleFuture.join(), passwordExpirationDaysFuture + .join()); BeanUtil.copyProperties(user, loginUser); return LoginHelper.login(loginUser); } diff --git a/continew-admin-system/src/main/java/top/continew/admin/auth/service/impl/OnlineUserServiceImpl.java b/continew-admin-system/src/main/java/top/continew/admin/auth/service/impl/OnlineUserServiceImpl.java index 9af1ec95..81ebc75c 100644 --- a/continew-admin-system/src/main/java/top/continew/admin/auth/service/impl/OnlineUserServiceImpl.java +++ b/continew-admin-system/src/main/java/top/continew/admin/auth/service/impl/OnlineUserServiceImpl.java @@ -18,12 +18,12 @@ package top.continew.admin.auth.service.impl; import cn.crane4j.annotation.AutoOperate; import cn.dev33.satoken.dao.SaTokenDao; -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.date.DateUtil; import cn.hutool.core.util.StrUtil; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import top.continew.admin.auth.model.query.OnlineUserQuery; import top.continew.admin.auth.model.resp.OnlineUserResp; @@ -44,10 +44,10 @@ import java.util.List; * 在线用户业务实现 * * @author Charles7c - * @author Lion Li(RuoYi-Vue-Plus) * @since 2023/3/25 22:49 */ @Service +@RequiredArgsConstructor public class OnlineUserServiceImpl implements OnlineUserService { @Override @@ -63,18 +63,18 @@ public class OnlineUserServiceImpl implements OnlineUserService { List loginUserList = new ArrayList<>(); // 查询所有登录用户 List tokenKeyList = StpUtil.searchTokenValue(StringConstants.EMPTY, 0, -1, false); - for (String tokenKey : tokenKeyList) { + tokenKeyList.parallelStream().forEach(tokenKey -> { String token = StrUtil.subAfter(tokenKey, StringConstants.COLON, true); // 忽略已过期或失效 Token if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < SaTokenDao.NEVER_EXPIRE) { - continue; + return; } // 检查是否符合查询条件 LoginUser loginUser = LoginHelper.getLoginUser(token); if (this.isMatchQuery(query, loginUser)) { loginUserList.add(loginUser); } - } + }); // 设置排序 CollUtil.sort(loginUserList, Comparator.comparing(LoginUser::getLoginTime).reversed()); return loginUserList; @@ -87,20 +87,7 @@ public class OnlineUserServiceImpl implements OnlineUserService { } @Override - public void cleanByRoleId(Long roleId) { - List 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) { + public void kickOut(Long userId) { if (!StpUtil.isLogin(userId)) { return; } @@ -121,13 +108,22 @@ public class OnlineUserServiceImpl implements OnlineUserService { flag1 = StrUtil.contains(loginUser.getUsername(), nickname) || StrUtil.contains(LoginHelper .getNickname(loginUser.getId()), nickname); } - boolean flag2 = true; List loginTime = query.getLoginTime(); if (CollUtil.isNotEmpty(loginTime)) { flag2 = DateUtil.isIn(DateUtil.date(loginUser.getLoginTime()).toJdkDate(), loginTime.get(0), loginTime .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; } } diff --git a/continew-admin-system/src/main/java/top/continew/admin/auth/service/impl/PermissionServiceImpl.java b/continew-admin-system/src/main/java/top/continew/admin/auth/service/impl/PermissionServiceImpl.java deleted file mode 100644 index c9aeff7b..00000000 --- a/continew-admin-system/src/main/java/top/continew/admin/auth/service/impl/PermissionServiceImpl.java +++ /dev/null @@ -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 listPermissionByUserId(Long userId) { - Set roleCodeSet = this.listRoleCodeByUserId(userId); - // 超级管理员赋予全部权限 - if (roleCodeSet.contains(SysConstants.ADMIN_ROLE_CODE)) { - return CollUtil.newHashSet(SysConstants.ALL_PERMISSION); - } - return menuService.listPermissionByUserId(userId); - } - - @Override - public Set listRoleCodeByUserId(Long userId) { - return roleService.listCodeByUserId(userId); - } -} diff --git a/continew-admin-system/src/main/java/top/continew/admin/system/service/RoleService.java b/continew-admin-system/src/main/java/top/continew/admin/system/service/RoleService.java index 04fd19e3..309568c0 100644 --- a/continew-admin-system/src/main/java/top/continew/admin/system/service/RoleService.java +++ b/continew-admin-system/src/main/java/top/continew/admin/system/service/RoleService.java @@ -36,6 +36,14 @@ import java.util.Set; */ public interface RoleService extends BaseService, IService { + /** + * 根据用户 ID 查询权限码 + * + * @param userId 用户 ID + * @return 权限码集合 + */ + Set listPermissionByUserId(Long userId); + /** * 根据 ID 列表查询 * diff --git a/continew-admin-system/src/main/java/top/continew/admin/system/service/impl/RoleServiceImpl.java b/continew-admin-system/src/main/java/top/continew/admin/system/service/impl/RoleServiceImpl.java index d8ff8f40..08e8d7bf 100644 --- a/continew-admin-system/src/main/java/top/continew/admin/system/service/impl/RoleServiceImpl.java +++ b/continew-admin-system/src/main/java/top/continew/admin/system/service/impl/RoleServiceImpl.java @@ -26,12 +26,15 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; 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.common.constant.CacheConstants; import top.continew.admin.common.constant.ContainerConstants; import top.continew.admin.common.constant.SysConstants; 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.util.helper.LoginHelper; import top.continew.admin.system.mapper.RoleMapper; import top.continew.admin.system.model.entity.RoleDO; import top.continew.admin.system.model.query.RoleQuery; @@ -57,10 +60,10 @@ import java.util.stream.Collectors; public class RoleServiceImpl extends BaseServiceImpl implements RoleService { private final MenuService menuService; - private final OnlineUserService onlineUserService; private final RoleMenuService roleMenuService; private final RoleDeptService roleDeptService; private final UserRoleService userRoleService; + private final OnlineUserService onlineUserService; @Override @Transactional(rollbackFor = Exception.class) @@ -92,16 +95,23 @@ public class RoleServiceImpl extends BaseServiceImpl 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 listPermissionByUserId(Long userId) { + Set roleCodeSet = this.listCodeByUserId(userId); + // 超级管理员赋予全部权限 + if (roleCodeSet.contains(SysConstants.ADMIN_ROLE_CODE)) { + return CollUtil.newHashSet(SysConstants.ALL_PERMISSION); + } + return menuService.listPermissionByUserId(userId); + } + @Override @ContainerMethod(namespace = ContainerConstants.USER_ROLE_NAME_LIST, type = MappingType.ORDER_OF_KEYS) public List listNameByIds(List ids) { diff --git a/continew-admin-system/src/main/java/top/continew/admin/system/service/impl/UserServiceImpl.java b/continew-admin-system/src/main/java/top/continew/admin/system/service/impl/UserServiceImpl.java index 8957c34b..1a34c97d 100644 --- a/continew-admin-system/src/main/java/top/continew/admin/system/service/impl/UserServiceImpl.java +++ b/continew-admin-system/src/main/java/top/continew/admin/system/service/impl/UserServiceImpl.java @@ -52,11 +52,13 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; 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.common.constant.CacheConstants; import top.continew.admin.common.constant.SysConstants; import top.continew.admin.common.enums.DisEnableStatusEnum; 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.helper.LoginHelper; import top.continew.admin.system.mapper.UserMapper; @@ -102,11 +104,11 @@ import static top.continew.admin.system.enums.PasswordPolicyEnum.*; @RequiredArgsConstructor public class UserServiceImpl extends BaseServiceImpl implements UserService, CommonUserService { - private final OnlineUserService onlineUserService; - private final UserRoleService userRoleService; private final PasswordEncoder passwordEncoder; - private final OptionService optionService; private final UserPasswordHistoryService userPasswordHistoryService; + private final OnlineUserService onlineUserService; + private final OptionService optionService; + private final UserRoleService userRoleService; private final RoleService roleService; @Resource @@ -324,9 +326,21 @@ public class UserServiceImpl extends BaseServiceImpl 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()); + }); } }