🔨 修改聚合配置.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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")
|
||||
|
||||
@@ -47,10 +47,4 @@ public class SystemUserBaseVO {
|
||||
@Schema(description = "头像地址")
|
||||
private String avatar;
|
||||
|
||||
@Schema(description = "修改密码状态")
|
||||
private Integer passwordUpdateStatus;
|
||||
|
||||
@Schema(description = "修改密码原因")
|
||||
private String passwordUpdateReason;
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
// 删除登录失败次数缓存
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
46
orion-visor-ui/src/api/user/user-aggregate.ts
Normal file
46
orion-visor-ui/src/api/user/user-aggregate.ts
Normal 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');
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -90,7 +90,12 @@
|
||||
editor?.setValue(value);
|
||||
};
|
||||
|
||||
defineExpose({ getValue, setValue });
|
||||
// 聚焦
|
||||
const focus = () => {
|
||||
editor?.focus();
|
||||
};
|
||||
|
||||
defineExpose({ getValue, setValue, focus });
|
||||
|
||||
// 监听主题变更
|
||||
watch(() => appStore.theme, (v) => {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 {
|
||||
// 跳转
|
||||
|
||||
@@ -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 => ({
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user