diff --git a/orion-visor-launch/src/main/resources/application-dev.yaml b/orion-visor-launch/src/main/resources/application-dev.yaml index d5a313c7..c6aab04f 100644 --- a/orion-visor-launch/src/main/resources/application-dev.yaml +++ b/orion-visor-launch/src/main/resources/application-dev.yaml @@ -1,18 +1,18 @@ spring: datasource: druid: - url: jdbc:mysql://127.0.0.1:3306/orion_visor?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true + url: jdbc:mysql://116.62.194.246:3306/orion_visor?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Shanghai&autoReconnect=true username: root - password: Data@123456 + password: Orionsec@0379 initial-size: 0 min-idle: 1 max-active: 5 stat-view-servlet: enabled: false redis: - host: 127.0.0.1 + host: 116.62.194.246 port: 6379 - password: Data@123456 + password: Orionsec@0379 redisson: threads: 2 netty-threads: 2 diff --git a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/controller/SystemMenuController.java b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/controller/SystemMenuController.java index 3cde8f96..47edfc35 100644 --- a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/controller/SystemMenuController.java +++ b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/controller/SystemMenuController.java @@ -31,6 +31,7 @@ import org.dromara.visor.module.infra.entity.request.menu.SystemMenuUpdateReques import org.dromara.visor.module.infra.entity.request.menu.SystemMenuUpdateStatusRequest; import org.dromara.visor.module.infra.entity.vo.SystemMenuVO; import org.dromara.visor.module.infra.service.SystemMenuService; +import org.dromara.visor.module.infra.service.UserPermissionService; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -56,6 +57,9 @@ public class SystemMenuController { @Resource private SystemMenuService systemMenuService; + @Resource + private UserPermissionService userPermissionService; + @DemoDisableApi @OperatorLog(SystemMenuOperatorType.CREATE) @PostMapping("/create") @@ -110,5 +114,13 @@ public class SystemMenuController { return systemMenuService.deleteSystemMenu(id); } + @PutMapping("/refresh-cache") + @Operation(summary = "刷新角色权限缓存") + @PreAuthorize("@ss.hasPermission('infra:system-menu:management:refresh-cache')") + public Boolean refreshCache() { + userPermissionService.initPermissionCache(); + return true; + } + } diff --git a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/controller/UserAggregateController.java b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/controller/UserAggregateController.java new file mode 100644 index 00000000..90ebef8a --- /dev/null +++ b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/controller/UserAggregateController.java @@ -0,0 +1,52 @@ +package org.dromara.visor.module.infra.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.dromara.visor.framework.log.core.annotation.IgnoreLog; +import org.dromara.visor.framework.log.core.enums.IgnoreLogMode; +import org.dromara.visor.framework.web.core.annotation.RestWrapper; +import org.dromara.visor.module.infra.entity.vo.SystemMenuVO; +import org.dromara.visor.module.infra.entity.vo.UserAggregateVO; +import org.dromara.visor.module.infra.service.UserAggregateService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 用户聚合服务 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/7/14 11:20 + */ +@Tag(name = "infra - 用户聚合服务") +@Slf4j +@Validated +@RestWrapper +@RestController +@RequestMapping("/infra/user-aggregate") +public class UserAggregateController { + + @Resource + private UserAggregateService userAggregateService; + + @IgnoreLog(IgnoreLogMode.RET) + @GetMapping("/menu") + @Operation(summary = "获取用户菜单") + public List getUserMenuList() { + return userAggregateService.getUserMenuList(); + } + + @IgnoreLog(IgnoreLogMode.RET) + @GetMapping("/user") + @Operation(summary = "获取用户权限聚合信息") + public UserAggregateVO getUserAggregateInfo() { + return userAggregateService.getUserAggregateInfo(); + } + +} diff --git a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/controller/UserPermissionController.java b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/controller/UserPermissionController.java deleted file mode 100644 index f915238f..00000000 --- a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/controller/UserPermissionController.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2023 - present Jiahang Li (visor.orionsec.cn ljh1553488six@139.com). - * - * 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 org.dromara.visor.module.infra.controller; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.extern.slf4j.Slf4j; -import org.dromara.visor.framework.log.core.annotation.IgnoreLog; -import org.dromara.visor.framework.log.core.enums.IgnoreLogMode; -import org.dromara.visor.framework.web.core.annotation.RestWrapper; -import org.dromara.visor.module.infra.entity.vo.SystemMenuVO; -import org.dromara.visor.module.infra.entity.vo.UserPermissionVO; -import org.dromara.visor.module.infra.service.UserPermissionService; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.annotation.Resource; -import java.util.List; - -/** - * 权限服务 - * - * @author Jiahang Li - * @version 1.0.0 - * @since 2023/7/14 11:20 - */ -@Tag(name = "infra - 用户权限服务") -@Slf4j -@Validated -@RestWrapper -@RestController -@RequestMapping("/infra/user-permission") -public class UserPermissionController { - - @Resource - private UserPermissionService userPermissionService; - - @PutMapping("/refresh-cache") - @Operation(summary = "刷新角色权限缓存") - @PreAuthorize("@ss.hasPermission('infra:system-menu:management:refresh-cache')") - public Boolean refreshCache() { - userPermissionService.initPermissionCache(); - return true; - } - - @IgnoreLog(IgnoreLogMode.RET) - @GetMapping("/menu") - @Operation(summary = "获取用户菜单") - public List getUserMenuList() { - return userPermissionService.getUserMenuList(); - } - - @IgnoreLog(IgnoreLogMode.RET) - @GetMapping("/user") - @Operation(summary = "获取用户权限聚合信息") - public UserPermissionVO getUserPermission() { - return userPermissionService.getUserPermission(); - } - -} diff --git a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/entity/domain/SystemUserDO.java b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/entity/domain/SystemUserDO.java index 7e395333..c211f918 100644 --- a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/entity/domain/SystemUserDO.java +++ b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/entity/domain/SystemUserDO.java @@ -77,11 +77,11 @@ public class SystemUserDO extends BaseDO { @Schema(description = "修改密码状态") @TableField("update_password_status") - private Integer passwordUpdateStatus; + private Integer updatePasswordStatus; @Schema(description = "修改密码原因") @TableField("update_password_reason") - private String passwordUpdateReason; + private String updatePasswordReason; @Schema(description = "最后登录时间") @TableField("last_login_time") diff --git a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/entity/vo/SystemUserBaseVO.java b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/entity/vo/SystemUserBaseVO.java index 608e52fe..032bd86e 100644 --- a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/entity/vo/SystemUserBaseVO.java +++ b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/entity/vo/SystemUserBaseVO.java @@ -47,10 +47,4 @@ public class SystemUserBaseVO { @Schema(description = "头像地址") private String avatar; - @Schema(description = "修改密码状态") - private Integer passwordUpdateStatus; - - @Schema(description = "修改密码原因") - private String passwordUpdateReason; - } diff --git a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/entity/vo/UserPermissionVO.java b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/entity/vo/UserAggregateVO.java similarity index 52% rename from orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/entity/vo/UserPermissionVO.java rename to orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/entity/vo/UserAggregateVO.java index e587e499..6427995d 100644 --- a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/entity/vo/UserPermissionVO.java +++ b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/entity/vo/UserAggregateVO.java @@ -1,18 +1,3 @@ -/* - * Copyright (c) 2023 - present Jiahang Li (visor.orionsec.cn ljh1553488six@139.com). - * - * 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 org.dromara.visor.module.infra.entity.vo; import io.swagger.v3.oas.annotations.media.Schema; @@ -26,7 +11,7 @@ import java.util.List; import java.util.Map; /** - * 用户权限 视图响应对象 + * 用户 聚合响应对象 * * @author Jiahang Li * @version 1.0.0 @@ -36,8 +21,8 @@ import java.util.Map; @Builder @NoArgsConstructor @AllArgsConstructor -@Schema(name = "UserPermissionVO", description = "用户权限 视图响应对象") -public class UserPermissionVO { +@Schema(name = "UserAggregateVO", description = "用户 聚合响应对象") +public class UserAggregateVO { @Schema(description = "用户信息") private SystemUserBaseVO user; @@ -48,6 +33,9 @@ public class UserPermissionVO { @Schema(description = "该用户已启用的权限") private List permissions; + @Schema(description = "更新密码") + private UserUpdatePasswordVO updatePassword; + @Schema(description = "系统偏好") private Map systemPreference; diff --git a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/entity/vo/UserUpdatePasswordVO.java b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/entity/vo/UserUpdatePasswordVO.java new file mode 100644 index 00000000..93d9de1f --- /dev/null +++ b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/entity/vo/UserUpdatePasswordVO.java @@ -0,0 +1,29 @@ +package org.dromara.visor.module.infra.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 用户更新密码 响应对象 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/12/16 11:37 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "UserUpdatePasswordVO", description = "用户更新密码 响应对象") +public class UserUpdatePasswordVO { + + @Schema(description = "修改密码状态") + private Integer updatePasswordStatus; + + @Schema(description = "修改密码原因") + private String updatePasswordReason; + +} diff --git a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/UserAggregateService.java b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/UserAggregateService.java new file mode 100644 index 00000000..9c3f7354 --- /dev/null +++ b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/UserAggregateService.java @@ -0,0 +1,31 @@ +package org.dromara.visor.module.infra.service; + +import org.dromara.visor.module.infra.entity.vo.SystemMenuVO; +import org.dromara.visor.module.infra.entity.vo.UserAggregateVO; + +import java.util.List; + +/** + * 用户聚合服务 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/12/16 14:41 + */ +public interface UserAggregateService { + + /** + * 获取用户菜单 + * + * @return menu + */ + List getUserMenuList(); + + /** + * 获取用户权限聚合信息 + * + * @return UserAggregate + */ + UserAggregateVO getUserAggregateInfo(); + +} diff --git a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/UserPermissionService.java b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/UserPermissionService.java index 50e28a7f..312a15e0 100644 --- a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/UserPermissionService.java +++ b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/UserPermissionService.java @@ -17,8 +17,6 @@ package org.dromara.visor.module.infra.service; import org.dromara.visor.module.infra.entity.domain.SystemRoleDO; import org.dromara.visor.module.infra.entity.dto.SystemMenuCacheDTO; -import org.dromara.visor.module.infra.entity.vo.SystemMenuVO; -import org.dromara.visor.module.infra.entity.vo.UserPermissionVO; import java.util.List; import java.util.Map; @@ -32,27 +30,6 @@ import java.util.Map; */ public interface UserPermissionService { - /** - * 获取 角色缓存 - * - * @return cache - */ - Map getRoleCache(); - - /** - * 获取 菜单缓存 以作角色权限直接引用 - * - * @return cache - */ - List getMenuCache(); - - /** - * 获取 角色菜单关联 - * - * @return cache - */ - Map> getRoleMenuCache(); - /** * 初始化权限缓存 */ @@ -91,17 +68,54 @@ public interface UserPermissionService { boolean hasAnyPermission(String... permissions); /** - * 获取用户菜单 + * 获取 角色缓存 * - * @return 菜单 + * @return cache */ - List getUserMenuList(); + Map getRoleCache(); /** - * 获取用户权限 + * 获取 菜单缓存 以作角色权限直接引用 * - * @return 权限信息 + * @return cache */ - UserPermissionVO getUserPermission(); + List getMenuCache(); + + /** + * 获取 角色菜单关联 + * + * @return cache + */ + Map> getRoleMenuCache(); + + /** + * 获取用户启用的角色 + * + * @return roles + */ + Map getUserEnabledRoles(); + + /** + * 获取用户启用的菜单 + * + * @return menus + */ + List getUserEnabledMenus(); + + /** + * 获取角色启用的菜单 + * + * @param roles roles + * @return menus + */ + List getRolesEnabledMenus(Map roles); + + /** + * 获取菜单权限 + * + * @param menus menus + * @return permissions + */ + List getMenuPermissions(List menus); } diff --git a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/impl/SystemUserServiceImpl.java b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/impl/SystemUserServiceImpl.java index f0be2469..0708c55d 100644 --- a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/impl/SystemUserServiceImpl.java +++ b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/impl/SystemUserServiceImpl.java @@ -120,8 +120,8 @@ public class SystemUserServiceImpl implements SystemUserService { this.checkNicknamePresent(record); // 加密密码 record.setPassword(Signatures.md5(request.getPassword())); - record.setPasswordUpdateStatus(UpdatePasswordStatusEnum.REQUIRED.getStatus()); - record.setPasswordUpdateReason(UpdatePasswordReasonEnum.NEW.name()); + record.setUpdatePasswordStatus(UpdatePasswordStatusEnum.REQUIRED.getStatus()); + record.setUpdatePasswordReason(UpdatePasswordReasonEnum.NEW.name()); // 插入 int effect = systemUserDAO.insert(record); log.info("SystemUserService-createSystemUser effect: {}, record: {}", effect, JSON.toJSONString(record)); @@ -313,8 +313,8 @@ public class SystemUserServiceImpl implements SystemUserService { SystemUserDO update = new SystemUserDO(); update.setId(id); update.setPassword(Signatures.md5(request.getPassword())); - update.setPasswordUpdateStatus(UpdatePasswordStatusEnum.NO_REQUIRE.getStatus()); - update.setPasswordUpdateReason(Const.EMPTY); + update.setUpdatePasswordStatus(UpdatePasswordStatusEnum.NO_REQUIRE.getStatus()); + update.setUpdatePasswordReason(Const.EMPTY); int effect = systemUserDAO.updateById(update); log.info("SystemUserService-resetPassword record: {}, effect: {}", JSON.toJSONString(update), effect); // 删除登录失败次数缓存 diff --git a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/impl/UserAggregateServiceImpl.java b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/impl/UserAggregateServiceImpl.java new file mode 100644 index 00000000..1194a5af --- /dev/null +++ b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/impl/UserAggregateServiceImpl.java @@ -0,0 +1,100 @@ +package org.dromara.visor.module.infra.service.impl; + + +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.dromara.visor.framework.security.core.utils.SecurityUtils; +import org.dromara.visor.module.infra.convert.SystemMenuConvert; +import org.dromara.visor.module.infra.convert.SystemUserConvert; +import org.dromara.visor.module.infra.dao.SystemUserDAO; +import org.dromara.visor.module.infra.entity.domain.SystemUserDO; +import org.dromara.visor.module.infra.entity.dto.SystemMenuCacheDTO; +import org.dromara.visor.module.infra.entity.vo.SystemMenuVO; +import org.dromara.visor.module.infra.entity.vo.UserAggregateVO; +import org.dromara.visor.module.infra.entity.vo.UserUpdatePasswordVO; +import org.dromara.visor.module.infra.enums.MenuTypeEnum; +import org.dromara.visor.module.infra.enums.PreferenceTypeEnum; +import org.dromara.visor.module.infra.enums.UpdatePasswordStatusEnum; +import org.dromara.visor.module.infra.service.*; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Future; +import java.util.stream.Collectors; + +/** + * 用户聚合服务 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/12/16 14:43 + */ +@Slf4j +@Service +public class UserAggregateServiceImpl implements UserAggregateService { + + @Resource + private SystemUserDAO systemUserDAO; + + @Resource + private SystemMenuService systemMenuService; + + @Resource + private PreferenceService preferenceService; + + @Resource + private TipsService tipsService; + + @Resource + private UserPermissionService userPermissionService; + + @Override + public List getUserMenuList() { + // 获取菜单 + List menus = userPermissionService.getUserEnabledMenus() + .stream() + .filter(s -> !MenuTypeEnum.FUNCTION.getType().equals(s.getType())) + .map(SystemMenuConvert.MAPPER::to) + .collect(Collectors.toList()); + // 构建菜单树 + return systemMenuService.buildSystemMenuTree(menus); + } + + @SneakyThrows + @Override + public UserAggregateVO getUserAggregateInfo() { + // 获取用户信息 + Long userId = SecurityUtils.getLoginUserId(); + // 获取用户系统偏好 + Future> systemPreference = preferenceService.getPreferenceAsync(userId, PreferenceTypeEnum.SYSTEM); + // 查询用户信息 + SystemUserDO user = systemUserDAO.selectById(userId); + // 修改密码信息 + UserUpdatePasswordVO updatePassword = null; + if (UpdatePasswordStatusEnum.REQUIRED.getStatus().equals(user.getUpdatePasswordStatus())) { + updatePassword = UserUpdatePasswordVO.builder() + .updatePasswordStatus(user.getUpdatePasswordStatus()) + .updatePasswordReason(user.getUpdatePasswordReason()) + .build(); + } + // 获取用户角色 + Map roles = userPermissionService.getUserEnabledRoles(); + // 获取角色权限 + List menus = userPermissionService.getRolesEnabledMenus(roles); + List permissions = userPermissionService.getMenuPermissions(menus); + // 提示信息 + List tippedKeys = tipsService.getTippedKeys(); + // 组装数据 + return UserAggregateVO.builder() + .user(SystemUserConvert.MAPPER.toBase(user)) + .roles(roles.values()) + .permissions(permissions) + .updatePassword(updatePassword) + .systemPreference(systemPreference.get()) + .tippedKeys(tippedKeys) + .build(); + } + +} diff --git a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/impl/UserPermissionServiceImpl.java b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/impl/UserPermissionServiceImpl.java index 15cc4ecf..a54ad086 100644 --- a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/impl/UserPermissionServiceImpl.java +++ b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/java/org/dromara/visor/module/infra/service/impl/UserPermissionServiceImpl.java @@ -16,43 +16,31 @@ package org.dromara.visor.module.infra.service.impl; import cn.orionsec.kit.lang.utils.Arrays1; +import cn.orionsec.kit.lang.utils.Strings; import cn.orionsec.kit.lang.utils.collect.Lists; import cn.orionsec.kit.lang.utils.collect.Maps; import lombok.Getter; -import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import org.dromara.visor.framework.common.constant.Const; import org.dromara.visor.framework.common.security.LoginUser; import org.dromara.visor.framework.common.security.UserRole; import org.dromara.visor.framework.security.core.utils.SecurityUtils; import org.dromara.visor.module.infra.convert.SystemMenuConvert; -import org.dromara.visor.module.infra.convert.SystemUserConvert; import org.dromara.visor.module.infra.dao.SystemMenuDAO; import org.dromara.visor.module.infra.dao.SystemRoleDAO; import org.dromara.visor.module.infra.dao.SystemRoleMenuDAO; -import org.dromara.visor.module.infra.dao.SystemUserDAO; import org.dromara.visor.module.infra.define.RoleDefine; import org.dromara.visor.module.infra.entity.domain.SystemMenuDO; import org.dromara.visor.module.infra.entity.domain.SystemRoleDO; import org.dromara.visor.module.infra.entity.domain.SystemRoleMenuDO; -import org.dromara.visor.module.infra.entity.domain.SystemUserDO; import org.dromara.visor.module.infra.entity.dto.SystemMenuCacheDTO; -import org.dromara.visor.module.infra.entity.vo.SystemMenuVO; -import org.dromara.visor.module.infra.entity.vo.UserPermissionVO; import org.dromara.visor.module.infra.enums.MenuStatusEnum; -import org.dromara.visor.module.infra.enums.MenuTypeEnum; -import org.dromara.visor.module.infra.enums.PreferenceTypeEnum; import org.dromara.visor.module.infra.enums.RoleStatusEnum; -import org.dromara.visor.module.infra.service.PreferenceService; -import org.dromara.visor.module.infra.service.SystemMenuService; -import org.dromara.visor.module.infra.service.TipsService; import org.dromara.visor.module.infra.service.UserPermissionService; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.util.*; -import java.util.concurrent.Future; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -77,9 +65,6 @@ public class UserPermissionServiceImpl implements UserPermissionService { @Getter private final Map> roleMenuCache = new HashMap<>(); - @Resource - private SystemUserDAO systemUserDAO; - @Resource private SystemRoleDAO systemRoleDAO; @@ -89,15 +74,6 @@ public class UserPermissionServiceImpl implements UserPermissionService { @Resource private SystemRoleMenuDAO systemRoleMenuDAO; - @Resource - private SystemMenuService systemMenuService; - - @Resource - private PreferenceService preferenceService; - - @Resource - private TipsService tipsService; - @PostConstruct @Override public void initPermissionCache() { @@ -141,7 +117,7 @@ public class UserPermissionServiceImpl implements UserPermissionService { if (roles.isEmpty()) { return false; } - // 检查是否为超级管理员或包含此角色 + // 检查是否为超级管理员 || 包含此角色 return RoleDefine.containsAdmin(roles.values()) || roles.containsValue(role); } @@ -162,19 +138,10 @@ public class UserPermissionServiceImpl implements UserPermissionService { @Override public boolean hasPermission(String permission) { - // 获取用户角色 - Map roles = this.getUserEnabledRoles(); - if (roles.isEmpty()) { - return false; - } - // 检查是否为超级管理员 - if (RoleDefine.containsAdmin(roles.values())) { - return true; - } - // 检查普通角色是否有此权限 - return roles.keySet() - .stream() - .anyMatch(s -> this.checkRoleHasPermission(s, permission)); + // 获取用户权限 + List userPermissions = this.getMenuPermissions(this.getUserEnabledMenus()); + // 检查权限 + return userPermissions.contains(permission); } @Override @@ -182,105 +149,14 @@ public class UserPermissionServiceImpl implements UserPermissionService { if (Arrays1.isEmpty(permissions)) { return true; } - // 获取用户角色 - Map roles = this.getUserEnabledRoles(); - if (roles.isEmpty()) { - return false; - } - // 检查是否为超级管理员 - if (RoleDefine.containsAdmin(roles.values())) { - return true; - } - // 检查用户角色是否包含权限 - return Arrays.stream(permissions) - .anyMatch(perm -> roles.keySet() - .stream() - .anyMatch(s -> this.checkRoleHasPermission(s, perm))); + // 获取用户权限 + List userPermissions = this.getMenuPermissions(this.getUserEnabledMenus()); + // 检查权限 + return Arrays.stream(permissions).anyMatch(userPermissions::contains); } @Override - public List getUserMenuList() { - // 获取用户角色 - Map roles = this.getUserEnabledRoles(); - if (roles.isEmpty()) { - return Lists.empty(); - } - // 查询角色菜单 - Stream mergeStream; - if (RoleDefine.containsAdmin(roles.values())) { - // 管理员拥有全部菜单 - mergeStream = menuCache.stream(); - } else { - // 当前用户所适配的角色菜单 - mergeStream = roles.keySet() - .stream() - .map(roleMenuCache::get) - .filter(Objects::nonNull) - .flatMap(Collection::stream) - .distinct(); - } - // 状态过滤 - List menus = mergeStream - .filter(s -> MenuStatusEnum.ENABLED.getStatus().equals(s.getStatus())) - .filter(s -> !MenuTypeEnum.FUNCTION.getType().equals(s.getType())) - .map(SystemMenuConvert.MAPPER::to) - .collect(Collectors.toList()); - // 构建菜单树 - return systemMenuService.buildSystemMenuTree(menus); - } - - @SneakyThrows - @Override - public UserPermissionVO getUserPermission() { - // 获取用户信息 - Long userId = SecurityUtils.getLoginUserId(); - // 获取用户系统偏好 - Future> systemPreference = preferenceService.getPreferenceAsync(userId, PreferenceTypeEnum.SYSTEM); - // 查询用户信息 - SystemUserDO user = systemUserDAO.selectById(userId); - // 获取用户角色 - Map roles = this.getUserEnabledRoles(); - // 获取角色权限 - List permissions = this.getRolePermissions(roles); - // 提示信息 - List tippedKeys = tipsService.getTippedKeys(); - // 组装数据 - return UserPermissionVO.builder() - .user(SystemUserConvert.MAPPER.toBase(user)) - .roles(roles.values()) - .permissions(permissions) - .systemPreference(systemPreference.get()) - .tippedKeys(tippedKeys) - .build(); - } - - /** - * 检查角色是否有权限 - * - * @param roleId roleId - * @param permission permission - * @return 是否有权限 - */ - private boolean checkRoleHasPermission(Long roleId, String permission) { - // 获取角色权限列表 - List menus = roleMenuCache.get(roleId); - if (Lists.isEmpty(menus)) { - return false; - } - // 检查是否有此权限 - return menus.stream() - .filter(s -> MenuStatusEnum.ENABLED.getStatus().equals(s.getStatus())) - .map(SystemMenuCacheDTO::getPermission) - .filter(Objects::nonNull) - .anyMatch(permission::equals); - } - - /** - * 获取用户启用的角色 - * - * @return roles - */ - private Map getUserEnabledRoles() { + public Map getUserEnabledRoles() { // 获取当前用户角色 List userRoles = Optional.ofNullable(SecurityUtils.getLoginUser()) .map(LoginUser::getRoles) @@ -302,29 +178,47 @@ public class UserPermissionServiceImpl implements UserPermissionService { return roles; } - /** - * 获取角色对应的权限 - * - * @param roles roles - * @return 权限 - */ - private List getRolePermissions(Map roles) { - if (Maps.isEmpty(roles)) { + @Override + public List getUserEnabledMenus() { + // 获取用户角色 + Map roles = this.getUserEnabledRoles(); + if (roles.isEmpty()) { return Lists.empty(); } - // 管理员拥有全部权限 + // 获取角色菜单 + return this.getRolesEnabledMenus(roles); + } + + @Override + public List getRolesEnabledMenus(Map roles) { + // 查询角色菜单 + Stream mergeStream; if (RoleDefine.containsAdmin(roles.values())) { - return Lists.singleton(Const.ASTERISK); + // 管理员拥有全部菜单 + mergeStream = menuCache.stream(); + } else { + // 当前用户所适配的角色菜单 + mergeStream = roles.keySet() + .stream() + .map(roleMenuCache::get) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .distinct(); } - // 角色权限 - return roles.keySet() - .stream() - .map(roleMenuCache::get) - .filter(Objects::nonNull) - .flatMap(Collection::stream) + // 过滤未启用的权限 + return mergeStream .filter(s -> MenuStatusEnum.ENABLED.getStatus().equals(s.getStatus())) + .collect(Collectors.toList()); + } + + @Override + public List getMenuPermissions(List menus) { + if (menus.isEmpty()) { + return Lists.empty(); + } + return menus.stream() .map(SystemMenuCacheDTO::getPermission) - .filter(Objects::nonNull) + .filter(Strings::isNotBlank) .distinct() .collect(Collectors.toList()); } diff --git a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/resources/mapper/SystemUserMapper.xml b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/resources/mapper/SystemUserMapper.xml index 8320530a..1e07e3da 100644 --- a/orion-visor-module-infra/orion-visor-module-infra-service/src/main/resources/mapper/SystemUserMapper.xml +++ b/orion-visor-module-infra/orion-visor-module-infra-service/src/main/resources/mapper/SystemUserMapper.xml @@ -17,8 +17,8 @@ - - + + diff --git a/orion-visor-ui/src/api/system/menu.ts b/orion-visor-ui/src/api/system/menu.ts index cbd32818..2a68e551 100644 --- a/orion-visor-ui/src/api/system/menu.ts +++ b/orion-visor-ui/src/api/system/menu.ts @@ -93,5 +93,5 @@ export function deleteMenu(id: number) { * 刷新缓存 */ export function refreshCache() { - return axios.put('/infra/user-permission/refresh-cache'); + return axios.put('/infra/system-menu/refresh-cache'); } diff --git a/orion-visor-ui/src/api/user/permission.ts b/orion-visor-ui/src/api/user/permission.ts deleted file mode 100644 index 344bf7f4..00000000 --- a/orion-visor-ui/src/api/user/permission.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { MenuQueryResponse } from '@/api/system/menu'; -import axios from 'axios'; - -/** - * 用户权限响应 - */ -export interface UserPermissionResponse { - user: UserBaseResponse; - roles: Array; - permissions: Array; - systemPreference: Record; - tippedKeys: Array; -} - -/** - * 用户基础信息 - */ -export interface UserBaseResponse { - id: number; - username: string; - nickname: string; - avatar: string; - passwordUpdateStatus: number; - passwordUpdateReason: string; -} - -/** - * 获取用户信息 - */ -export function getUserPermission() { - return axios.get('/infra/user-permission/user'); -} - -/** - * 获取菜单列表 - */ -export function getUserMenuList() { - return axios.get>('/infra/user-permission/menu'); -} diff --git a/orion-visor-ui/src/api/user/user-aggregate.ts b/orion-visor-ui/src/api/user/user-aggregate.ts new file mode 100644 index 00000000..3e274670 --- /dev/null +++ b/orion-visor-ui/src/api/user/user-aggregate.ts @@ -0,0 +1,46 @@ +import type { MenuQueryResponse } from '@/api/system/menu'; +import axios from 'axios'; + +/** + * 用户聚合信息 + */ +export interface UserAggregateResponse { + user: UserBaseResponse; + roles: Array; + updatePassword?: UserUpdatePasswordResponse; + permissions: Array; + systemPreference: Record; + tippedKeys: Array; +} + +/** + * 用户基础信息 + */ +export interface UserBaseResponse { + id: number; + username: string; + nickname: string; + avatar: string; +} + +/** + * 用户更新密码响应 + */ +export interface UserUpdatePasswordResponse { + updatePasswordStatus: number; + updatePasswordReason: string; +} + +/** + * 获取用户聚合信息 + */ +export function getUserAggregateInfo() { + return axios.get('/infra/user-aggregate/user'); +} + +/** + * 获取用户菜单列表 + */ +export function getUserMenuList() { + return axios.get>('/infra/user-aggregate/menu'); +} diff --git a/orion-visor-ui/src/assets/style/host-terminal-layout.less b/orion-visor-ui/src/assets/style/host-terminal-layout.less index bd6f2dbf..4a5bd36e 100644 --- a/orion-visor-ui/src/assets/style/host-terminal-layout.less +++ b/orion-visor-ui/src/assets/style/host-terminal-layout.less @@ -22,8 +22,8 @@ body { --color-panel-gradient-end: rgba(218, 218, 218, 0); --color-button-bg: #E3E3E3; --color-button-bg-active: var(--color-sidebar-icon-checked); - --search-bg-focus: rgba(234, 234, 234, .75); - --search-bg: rgba(234, 234, 234, .95); + --search-bg-focus: rgba(234, 234, 234, .95); + --search-bg: rgba(234, 234, 234, .75); --search-color-text: #0E0E0E; --search-color-text-focus: #0F0F0F; --search-bg-icon-hover: rgba(12, 12, 12, .04); diff --git a/orion-visor-ui/src/components/view/editor/index.vue b/orion-visor-ui/src/components/view/editor/index.vue index 579fd84a..c8fd11c4 100644 --- a/orion-visor-ui/src/components/view/editor/index.vue +++ b/orion-visor-ui/src/components/view/editor/index.vue @@ -90,7 +90,12 @@ editor?.setValue(value); }; - defineExpose({ getValue, setValue }); + // 聚焦 + const focus = () => { + editor?.focus(); + }; + + defineExpose({ getValue, setValue, focus }); // 监听主题变更 watch(() => appStore.theme, (v) => { diff --git a/orion-visor-ui/src/directive/permission/index.ts b/orion-visor-ui/src/directive/permission/index.ts index 01731875..d728475f 100644 --- a/orion-visor-ui/src/directive/permission/index.ts +++ b/orion-visor-ui/src/directive/permission/index.ts @@ -6,8 +6,15 @@ function checkPermission(el: HTMLElement, binding: DirectiveBinding) { const permission = usePermission(); if (Array.isArray(value)) { if (value.length > 0) { - if (!permission.hasAnyPermission(value) && el.parentNode) { - el.parentNode.removeChild(el); + const parentNode = el.parentNode as Element; + if (!permission.hasAnyPermission(value) && parentNode) { + if (parentNode.classList.contains('arco-space-item')) { + // 如果是 arco-space-item 则移除父节点 + parentNode.parentNode?.removeChild(parentNode); + } else { + // 只移除当前元素 + parentNode.removeChild(el); + } } } } else { diff --git a/orion-visor-ui/src/hooks/permission.ts b/orion-visor-ui/src/hooks/permission.ts index c1da1eeb..dbae9ed9 100644 --- a/orion-visor-ui/src/hooks/permission.ts +++ b/orion-visor-ui/src/hooks/permission.ts @@ -32,17 +32,15 @@ export default function usePermission() { * 是否有权限 */ hasPermission(permission: string) { - return userStore.permission?.includes('*') || - userStore.permission?.includes(permission); + return userStore.permission?.includes(permission); }, /** * 是否有权限 */ hasAnyPermission(permission: string[]) { - return userStore.permission?.includes('*') || - permission.map(s => userStore.permission?.includes(s)) - .filter(Boolean).length > 0; + return permission.map(s => userStore.permission?.includes(s)) + .filter(Boolean).length > 0; }, /** diff --git a/orion-visor-ui/src/router/guard/user-login-info.ts b/orion-visor-ui/src/router/guard/user-login-info.ts index dfe05a30..9b189a21 100644 --- a/orion-visor-ui/src/router/guard/user-login-info.ts +++ b/orion-visor-ui/src/router/guard/user-login-info.ts @@ -19,11 +19,11 @@ export default function setupUserLoginInfoGuard(router: Router) { try { // 获取用户信息 const info = await userStore.getUserInfo(); - if (info.user.passwordUpdateStatus === 1) { + if (info.updatePassword?.updatePasswordStatus === 1) { // 跳转到修改密码页面 next({ name: UPDATE_PASSWORD_ROUTE_NAME, - query: { reason: info.user.passwordUpdateReason }, + query: { reason: info.updatePassword?.updatePasswordReason }, } as RouteLocationRaw); } else { // 跳转 diff --git a/orion-visor-ui/src/store/modules/menu/index.ts b/orion-visor-ui/src/store/modules/menu/index.ts index 5210d91c..b2698fbc 100644 --- a/orion-visor-ui/src/store/modules/menu/index.ts +++ b/orion-visor-ui/src/store/modules/menu/index.ts @@ -5,7 +5,7 @@ import router from '@/router'; import { defineStore } from 'pinia'; import { Notification } from '@arco-design/web-vue'; import { EnabledStatus } from '@/types/const'; -import { getUserMenuList } from '@/api/user/permission'; +import { getUserMenuList } from '@/api/user/user-aggregate'; export default defineStore('menu', { state: (): MenuState => ({ diff --git a/orion-visor-ui/src/store/modules/user/index.ts b/orion-visor-ui/src/store/modules/user/index.ts index 62de6900..cc75bcff 100644 --- a/orion-visor-ui/src/store/modules/user/index.ts +++ b/orion-visor-ui/src/store/modules/user/index.ts @@ -5,7 +5,7 @@ import { md5 } from '@/utils'; import { defineStore } from 'pinia'; import { clearToken, setToken } from '@/utils/auth'; import { removeRouteListener } from '@/utils/route-listener'; -import { getUserPermission } from '@/api/user/permission'; +import { getUserAggregateInfo } from '@/api/user/user-aggregate'; import { useAppStore, useCacheStore, useMenuStore, useTabBarStore, useTipsStore } from '@/store'; export default defineStore('user', { @@ -32,7 +32,7 @@ export default defineStore('user', { // 获取用户信息 async getUserInfo() { - const { data } = await getUserPermission(); + const { data } = await getUserAggregateInfo(); // 设置用户信息 this.setUserInfo({ id: data.user.id,