🔨 修改聚合配置.

This commit is contained in:
lijiahangmax
2024-12-16 20:37:17 +08:00
parent 985091f42b
commit 6d74b4379e
24 changed files with 403 additions and 349 deletions

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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<SystemMenuVO> getUserMenuList() {
return userAggregateService.getUserMenuList();
}
@IgnoreLog(IgnoreLogMode.RET)
@GetMapping("/user")
@Operation(summary = "获取用户权限聚合信息")
public UserAggregateVO getUserAggregateInfo() {
return userAggregateService.getUserAggregateInfo();
}
}

View File

@@ -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<SystemMenuVO> getUserMenuList() {
return userPermissionService.getUserMenuList();
}
@IgnoreLog(IgnoreLogMode.RET)
@GetMapping("/user")
@Operation(summary = "获取用户权限聚合信息")
public UserPermissionVO getUserPermission() {
return userPermissionService.getUserPermission();
}
}

View File

@@ -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")

View File

@@ -47,10 +47,4 @@ public class SystemUserBaseVO {
@Schema(description = "头像地址")
private String avatar;
@Schema(description = "修改密码状态")
private Integer passwordUpdateStatus;
@Schema(description = "修改密码原因")
private String passwordUpdateReason;
}

View File

@@ -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<String> permissions;
@Schema(description = "更新密码")
private UserUpdatePasswordVO updatePassword;
@Schema(description = "系统偏好")
private Map<String, Object> systemPreference;

View File

@@ -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;
}

View File

@@ -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<SystemMenuVO> getUserMenuList();
/**
* 获取用户权限聚合信息
*
* @return UserAggregate
*/
UserAggregateVO getUserAggregateInfo();
}

View File

@@ -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<Long, SystemRoleDO> getRoleCache();
/**
* 获取 菜单缓存 以作角色权限直接引用
*
* @return cache
*/
List<SystemMenuCacheDTO> getMenuCache();
/**
* 获取 角色菜单关联
*
* @return cache
*/
Map<Long, List<SystemMenuCacheDTO>> getRoleMenuCache();
/**
* 初始化权限缓存
*/
@@ -91,17 +68,54 @@ public interface UserPermissionService {
boolean hasAnyPermission(String... permissions);
/**
* 获取用户菜单
* 获取 角色缓存
*
* @return 菜单
* @return cache
*/
List<SystemMenuVO> getUserMenuList();
Map<Long, SystemRoleDO> getRoleCache();
/**
* 获取用户权限
* 获取 菜单缓存 以作角色权限直接引
*
* @return 权限信息
* @return cache
*/
UserPermissionVO getUserPermission();
List<SystemMenuCacheDTO> getMenuCache();
/**
* 获取 角色菜单关联
*
* @return cache
*/
Map<Long, List<SystemMenuCacheDTO>> getRoleMenuCache();
/**
* 获取用户启用的角色
*
* @return roles
*/
Map<Long, String> getUserEnabledRoles();
/**
* 获取用户启用的菜单
*
* @return menus
*/
List<SystemMenuCacheDTO> getUserEnabledMenus();
/**
* 获取角色启用的菜单
*
* @param roles roles
* @return menus
*/
List<SystemMenuCacheDTO> getRolesEnabledMenus(Map<Long, String> roles);
/**
* 获取菜单权限
*
* @param menus menus
* @return permissions
*/
List<String> getMenuPermissions(List<SystemMenuCacheDTO> menus);
}

View File

@@ -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);
// 删除登录失败次数缓存

View File

@@ -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<SystemMenuVO> getUserMenuList() {
// 获取菜单
List<SystemMenuVO> 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<Map<String, Object>> 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<Long, String> roles = userPermissionService.getUserEnabledRoles();
// 获取角色权限
List<SystemMenuCacheDTO> menus = userPermissionService.getRolesEnabledMenus(roles);
List<String> permissions = userPermissionService.getMenuPermissions(menus);
// 提示信息
List<String> tippedKeys = tipsService.getTippedKeys();
// 组装数据
return UserAggregateVO.builder()
.user(SystemUserConvert.MAPPER.toBase(user))
.roles(roles.values())
.permissions(permissions)
.updatePassword(updatePassword)
.systemPreference(systemPreference.get())
.tippedKeys(tippedKeys)
.build();
}
}

View File

@@ -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<Long, List<SystemMenuCacheDTO>> 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<Long, String> 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<String> 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<Long, String> 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<String> userPermissions = this.getMenuPermissions(this.getUserEnabledMenus());
// 检查权限
return Arrays.stream(permissions).anyMatch(userPermissions::contains);
}
@Override
public List<SystemMenuVO> getUserMenuList() {
// 获取用户角色
Map<Long, String> roles = this.getUserEnabledRoles();
if (roles.isEmpty()) {
return Lists.empty();
}
// 查询角色菜单
Stream<SystemMenuCacheDTO> 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<SystemMenuVO> 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<Map<String, Object>> systemPreference = preferenceService.getPreferenceAsync(userId, PreferenceTypeEnum.SYSTEM);
// 查询用户信息
SystemUserDO user = systemUserDAO.selectById(userId);
// 获取用户角色
Map<Long, String> roles = this.getUserEnabledRoles();
// 获取角色权限
List<String> permissions = this.getRolePermissions(roles);
// 提示信息
List<String> 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<SystemMenuCacheDTO> 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<Long, String> getUserEnabledRoles() {
public Map<Long, String> getUserEnabledRoles() {
// 获取当前用户角色
List<UserRole> 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<String> getRolePermissions(Map<Long, String> roles) {
if (Maps.isEmpty(roles)) {
@Override
public List<SystemMenuCacheDTO> getUserEnabledMenus() {
// 获取用户角色
Map<Long, String> roles = this.getUserEnabledRoles();
if (roles.isEmpty()) {
return Lists.empty();
}
// 管理员拥有全部权限
// 获取角色菜单
return this.getRolesEnabledMenus(roles);
}
@Override
public List<SystemMenuCacheDTO> getRolesEnabledMenus(Map<Long, String> roles) {
// 查询角色菜单
Stream<SystemMenuCacheDTO> 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<String> getMenuPermissions(List<SystemMenuCacheDTO> menus) {
if (menus.isEmpty()) {
return Lists.empty();
}
return menus.stream()
.map(SystemMenuCacheDTO::getPermission)
.filter(Objects::nonNull)
.filter(Strings::isNotBlank)
.distinct()
.collect(Collectors.toList());
}

View File

@@ -17,8 +17,8 @@
<result column="mobile" property="mobile"/>
<result column="email" property="email"/>
<result column="status" property="status"/>
<result column="update_password_status" property="passwordUpdateStatus"/>
<result column="update_password_reason" property="passwordUpdateReason"/>
<result column="update_password_status" property="updatePasswordStatus"/>
<result column="update_password_reason" property="updatePasswordReason"/>
<result column="last_login_time" property="lastLoginTime"/>
</resultMap>

View File

@@ -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');
}

View File

@@ -1,39 +0,0 @@
import type { MenuQueryResponse } from '@/api/system/menu';
import axios from 'axios';
/**
* 用户权限响应
*/
export interface UserPermissionResponse {
user: UserBaseResponse;
roles: Array<string>;
permissions: Array<string>;
systemPreference: Record<string, any>;
tippedKeys: Array<string>;
}
/**
* 用户基础信息
*/
export interface UserBaseResponse {
id: number;
username: string;
nickname: string;
avatar: string;
passwordUpdateStatus: number;
passwordUpdateReason: string;
}
/**
* 获取用户信息
*/
export function getUserPermission() {
return axios.get<UserPermissionResponse>('/infra/user-permission/user');
}
/**
* 获取菜单列表
*/
export function getUserMenuList() {
return axios.get<Array<MenuQueryResponse>>('/infra/user-permission/menu');
}

View File

@@ -0,0 +1,46 @@
import type { MenuQueryResponse } from '@/api/system/menu';
import axios from 'axios';
/**
* 用户聚合信息
*/
export interface UserAggregateResponse {
user: UserBaseResponse;
roles: Array<string>;
updatePassword?: UserUpdatePasswordResponse;
permissions: Array<string>;
systemPreference: Record<string, any>;
tippedKeys: Array<string>;
}
/**
* 用户基础信息
*/
export interface UserBaseResponse {
id: number;
username: string;
nickname: string;
avatar: string;
}
/**
* 用户更新密码响应
*/
export interface UserUpdatePasswordResponse {
updatePasswordStatus: number;
updatePasswordReason: string;
}
/**
* 获取用户聚合信息
*/
export function getUserAggregateInfo() {
return axios.get<UserAggregateResponse>('/infra/user-aggregate/user');
}
/**
* 获取用户菜单列表
*/
export function getUserMenuList() {
return axios.get<Array<MenuQueryResponse>>('/infra/user-aggregate/menu');
}

View File

@@ -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);

View File

@@ -90,7 +90,12 @@
editor?.setValue(value);
};
defineExpose({ getValue, setValue });
// 聚焦
const focus = () => {
editor?.focus();
};
defineExpose({ getValue, setValue, focus });
// 监听主题变更
watch(() => appStore.theme, (v) => {

View File

@@ -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 {

View File

@@ -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;
},
/**

View File

@@ -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 {
// 跳转

View File

@@ -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 => ({

View File

@@ -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,