mirror of https://gitee.com/xiaonuobase/snowy
Pre Merge pull request !285 from 这么难演/dev
commit
e781252faa
|
@ -25,6 +25,11 @@ public class CacheConstant {
|
|||
*/
|
||||
public static final String PERMISSION_RESOURCE_CACHE_KEY = "permission-resource";
|
||||
|
||||
/**
|
||||
* 权限资源Method
|
||||
*/
|
||||
public static final String PERMISSION_RESOURCE_METHOD_CACHE_KEY = "permission-resource-method";
|
||||
|
||||
/**
|
||||
* B端权限列表
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.common.detector;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import jakarta.annotation.Nullable;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
import vip.xiaonuo.common.prop.CommonProperties;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 环境检测器
|
||||
*
|
||||
* @author jiangcs
|
||||
* @since 2025/9/13 23:20
|
||||
*/
|
||||
@Configuration
|
||||
public class EnvironmentDetector implements ApplicationListener<ApplicationReadyEvent> {
|
||||
|
||||
// 是否是SnowyCloud
|
||||
private static boolean snowyCloud = false;
|
||||
|
||||
@Resource
|
||||
private Environment environment;
|
||||
@Resource
|
||||
private CommonProperties commonProperties;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(@Nullable ApplicationReadyEvent event) {
|
||||
// 检查是否存在 Nacos 相关配置
|
||||
boolean hasNacosConfig = environment.containsProperty("spring.cloud.nacos.config.server-addr");
|
||||
boolean hasNacosDiscovery = environment.containsProperty("spring.cloud.nacos.discovery.server-addr");
|
||||
snowyCloud = hasNacosConfig || hasNacosDiscovery;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换后端路径
|
||||
*
|
||||
* @param path 路径
|
||||
* @return 路径
|
||||
*/
|
||||
public String convertBackendPath(String path) {
|
||||
if (snowyCloud) {
|
||||
List<Map<String, String>> list = commonProperties.getBackendPaths();
|
||||
Set<Map<String, String>> urlSet = list.stream().filter(m -> path.startsWith(m.get("name")))
|
||||
.collect(Collectors.toSet());
|
||||
if (ObjectUtil.isNotEmpty(urlSet)) {
|
||||
return urlSet.iterator().next().get("value") + path;
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
}
|
|
@ -17,6 +17,9 @@ import lombok.Setter;
|
|||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 通用基础配置
|
||||
*
|
||||
|
@ -32,6 +35,14 @@ public class CommonProperties {
|
|||
/** 前端地址 */
|
||||
private String frontUrl;
|
||||
|
||||
/** 后端地址 */
|
||||
/**
|
||||
* 后端地址
|
||||
*/
|
||||
private String backendUrl;
|
||||
|
||||
/**
|
||||
* 后端路由
|
||||
*/
|
||||
private List<Map<String, String>> backendPaths;
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.common.prop;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 数据建模相关配置
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/1/2 17:03
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "snowy.config.dom")
|
||||
public class DomProperties {
|
||||
|
||||
/**
|
||||
* 数据建模,授权数据库表前缀,逗号分割
|
||||
*/
|
||||
private String authTableNamePrefixes;
|
||||
|
||||
}
|
|
@ -12,16 +12,15 @@
|
|||
*/
|
||||
package vip.xiaonuo.sys.modular.role.service.impl;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollStreamUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.core.lang.tree.TreeNode;
|
||||
import cn.hutool.core.lang.tree.TreeUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
|
@ -29,12 +28,11 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.servlet.mvc.condition.PathPatternsRequestCondition;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
import vip.xiaonuo.common.cache.CommonCacheOperator;
|
||||
import vip.xiaonuo.common.consts.CacheConstant;
|
||||
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
|
||||
import vip.xiaonuo.common.exception.CommonException;
|
||||
import vip.xiaonuo.common.listener.CommonDataChangeEventCenter;
|
||||
|
@ -63,10 +61,7 @@ import vip.xiaonuo.sys.modular.user.entity.SysUser;
|
|||
import vip.xiaonuo.sys.modular.user.enums.SysUserStatusEnum;
|
||||
import vip.xiaonuo.sys.modular.user.service.SysUserService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
@ -96,22 +91,25 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
@Resource
|
||||
private MobileMenuApi mobileMenuApi;
|
||||
|
||||
@Resource
|
||||
private CommonCacheOperator commonCacheOperator;
|
||||
|
||||
@Override
|
||||
public Page<SysRole> page(SysRolePageParam sysRolePageParam) {
|
||||
QueryWrapper<SysRole> queryWrapper = new QueryWrapper<SysRole>().checkSqlInjection();
|
||||
// 查询部分字段
|
||||
queryWrapper.lambda().select(SysRole::getId, SysRole::getOrgId, SysRole::getName, SysRole::getCode,
|
||||
SysRole::getCategory, SysRole::getSortCode);
|
||||
if(ObjectUtil.isNotEmpty(sysRolePageParam.getOrgId())) {
|
||||
if (ObjectUtil.isNotEmpty(sysRolePageParam.getOrgId())) {
|
||||
queryWrapper.lambda().eq(SysRole::getOrgId, sysRolePageParam.getOrgId());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(sysRolePageParam.getCategory())) {
|
||||
if (ObjectUtil.isNotEmpty(sysRolePageParam.getCategory())) {
|
||||
queryWrapper.lambda().eq(SysRole::getCategory, sysRolePageParam.getCategory());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(sysRolePageParam.getSearchKey())) {
|
||||
if (ObjectUtil.isNotEmpty(sysRolePageParam.getSearchKey())) {
|
||||
queryWrapper.lambda().like(SysRole::getName, sysRolePageParam.getSearchKey());
|
||||
}
|
||||
if(ObjectUtil.isAllNotEmpty(sysRolePageParam.getSortField(), sysRolePageParam.getSortOrder())) {
|
||||
if (ObjectUtil.isAllNotEmpty(sysRolePageParam.getSortField(), sysRolePageParam.getSortOrder())) {
|
||||
CommonSortOrderEnum.validate(sysRolePageParam.getSortOrder());
|
||||
queryWrapper.orderBy(true, sysRolePageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
|
||||
StrUtil.toUnderlineCase(sysRolePageParam.getSortField()));
|
||||
|
@ -134,8 +132,8 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
|
||||
private void checkParam(SysRoleAddParam sysRoleAddParam) {
|
||||
SysRoleCategoryEnum.validate(sysRoleAddParam.getCategory());
|
||||
if(SysRoleCategoryEnum.ORG.getValue().equals(sysRoleAddParam.getCategory())) {
|
||||
if(ObjectUtil.isEmpty(sysRoleAddParam.getOrgId())) {
|
||||
if (SysRoleCategoryEnum.ORG.getValue().equals(sysRoleAddParam.getCategory())) {
|
||||
if (ObjectUtil.isEmpty(sysRoleAddParam.getOrgId())) {
|
||||
throw new CommonException("orgId不能为空");
|
||||
}
|
||||
} else {
|
||||
|
@ -143,8 +141,8 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
}
|
||||
boolean repeatName = this.count(new LambdaQueryWrapper<SysRole>().eq(SysRole::getOrgId, sysRoleAddParam.getOrgId())
|
||||
.eq(SysRole::getName, sysRoleAddParam.getName())) > 0;
|
||||
if(repeatName) {
|
||||
if(ObjectUtil.isEmpty(sysRoleAddParam.getOrgId())) {
|
||||
if (repeatName) {
|
||||
if (ObjectUtil.isEmpty(sysRoleAddParam.getOrgId())) {
|
||||
throw new CommonException("存在重复的全局角色,名称为:{}", sysRoleAddParam.getName());
|
||||
} else {
|
||||
throw new CommonException("同组织下存在重复的角色,名称为:{}", sysRoleAddParam.getName());
|
||||
|
@ -152,8 +150,8 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
}
|
||||
boolean repeatCode = this.count(new LambdaQueryWrapper<SysRole>().eq(SysRole::getOrgId, sysRoleAddParam.getOrgId())
|
||||
.eq(SysRole::getCode, sysRoleAddParam.getCode())) > 0;
|
||||
if(repeatCode) {
|
||||
if(ObjectUtil.isEmpty(sysRoleAddParam.getOrgId())) {
|
||||
if (repeatCode) {
|
||||
if (ObjectUtil.isEmpty(sysRoleAddParam.getOrgId())) {
|
||||
throw new CommonException("存在重复的全局角色,编码为:{}", sysRoleAddParam.getCode());
|
||||
} else {
|
||||
throw new CommonException("同组织下存在重复的角色,编码为:{}", sysRoleAddParam.getCode());
|
||||
|
@ -167,7 +165,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
SysRole sysRole = this.queryEntity(sysRoleEditParam.getId());
|
||||
checkParam(sysRoleEditParam);
|
||||
boolean superRole = sysRole.getCode().equals(SysBuildInEnum.BUILD_IN_ROLE_CODE.getValue());
|
||||
if(superRole) {
|
||||
if (superRole) {
|
||||
throw new CommonException("不可编辑超管角色");
|
||||
}
|
||||
BeanUtil.copyProperties(sysRoleEditParam, sysRole);
|
||||
|
@ -179,8 +177,8 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
|
||||
private void checkParam(SysRoleEditParam sysRoleEditParam) {
|
||||
SysRoleCategoryEnum.validate(sysRoleEditParam.getCategory());
|
||||
if(SysRoleCategoryEnum.ORG.getValue().equals(sysRoleEditParam.getCategory())) {
|
||||
if(ObjectUtil.isEmpty(sysRoleEditParam.getOrgId())) {
|
||||
if (SysRoleCategoryEnum.ORG.getValue().equals(sysRoleEditParam.getCategory())) {
|
||||
if (ObjectUtil.isEmpty(sysRoleEditParam.getOrgId())) {
|
||||
throw new CommonException("orgId不能为空");
|
||||
}
|
||||
} else {
|
||||
|
@ -188,8 +186,8 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
}
|
||||
boolean repeatName = this.count(new LambdaQueryWrapper<SysRole>().eq(SysRole::getOrgId, sysRoleEditParam.getOrgId())
|
||||
.eq(SysRole::getName, sysRoleEditParam.getName()).ne(SysRole::getId, sysRoleEditParam.getId())) > 0;
|
||||
if(repeatName) {
|
||||
if(ObjectUtil.isEmpty(sysRoleEditParam.getOrgId())) {
|
||||
if (repeatName) {
|
||||
if (ObjectUtil.isEmpty(sysRoleEditParam.getOrgId())) {
|
||||
throw new CommonException("存在重复的全局角色,名称为:{}", sysRoleEditParam.getName());
|
||||
} else {
|
||||
throw new CommonException("同组织下存在重复的角色,名称为:{}", sysRoleEditParam.getName());
|
||||
|
@ -197,8 +195,8 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
}
|
||||
boolean repeatCode = this.count(new LambdaQueryWrapper<SysRole>().eq(SysRole::getOrgId, sysRoleEditParam.getOrgId())
|
||||
.eq(SysRole::getCode, sysRoleEditParam.getCode()).ne(SysRole::getId, sysRoleEditParam.getId())) > 0;
|
||||
if(repeatCode) {
|
||||
if(ObjectUtil.isEmpty(sysRoleEditParam.getOrgId())) {
|
||||
if (repeatCode) {
|
||||
if (ObjectUtil.isEmpty(sysRoleEditParam.getOrgId())) {
|
||||
throw new CommonException("存在重复的全局角色,编码为:{}", sysRoleEditParam.getCode());
|
||||
} else {
|
||||
throw new CommonException("同组织下存在重复的角色,编码为:{}", sysRoleEditParam.getCode());
|
||||
|
@ -211,10 +209,10 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
@Override
|
||||
public void delete(List<SysRoleIdParam> sysRoleIdParamList) {
|
||||
List<String> sysRoleIdList = CollStreamUtil.toList(sysRoleIdParamList, SysRoleIdParam::getId);
|
||||
if(ObjectUtil.isNotEmpty(sysRoleIdList)) {
|
||||
if (ObjectUtil.isNotEmpty(sysRoleIdList)) {
|
||||
boolean containsSuperAdminRole = this.listByIds(sysRoleIdList).stream().map(SysRole::getCode)
|
||||
.collect(Collectors.toSet()).contains(SysBuildInEnum.BUILD_IN_ROLE_CODE.getValue());
|
||||
if(containsSuperAdminRole) {
|
||||
if (containsSuperAdminRole) {
|
||||
throw new CommonException("不可删除系统内置超管角色");
|
||||
}
|
||||
// 级联删除角色与用户关系
|
||||
|
@ -258,12 +256,12 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
SysRole sysRole = this.queryEntity(id);
|
||||
List<String> menuIdList = sysRoleGrantResourceParam.getGrantInfoList().stream()
|
||||
.map(SysRoleGrantResourceParam.SysRoleGrantResource::getMenuId).collect(Collectors.toList());
|
||||
if(!SysBuildInEnum.BUILD_IN_ROLE_CODE.getValue().equals(sysRole.getCode())) {
|
||||
if(ObjectUtil.isNotEmpty(menuIdList)) {
|
||||
if (!SysBuildInEnum.BUILD_IN_ROLE_CODE.getValue().equals(sysRole.getCode())) {
|
||||
if (ObjectUtil.isNotEmpty(menuIdList)) {
|
||||
Set<String> sysModuleIdList = sysMenuService.listByIds(menuIdList).stream().map(SysMenu::getModule).collect(Collectors.toSet());
|
||||
boolean containsSystemModule = sysModuleService.listByIds(sysModuleIdList).stream().map(SysModule::getCode)
|
||||
.collect(Collectors.toSet()).contains(SysBuildInEnum.BUILD_IN_MODULE_CODE.getValue());
|
||||
if(containsSystemModule) {
|
||||
if (containsSystemModule) {
|
||||
throw new CommonException("非超管角色不可被授权系统模块菜单资源");
|
||||
}
|
||||
}
|
||||
|
@ -326,7 +324,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
public void grantUser(SysRoleGrantUserParam sysRoleGrantUserParam) {
|
||||
String id = sysRoleGrantUserParam.getId();
|
||||
List<String> grantInfoList = sysRoleGrantUserParam.getGrantInfoList();
|
||||
if(sysRoleGrantUserParam.getRemoveFirst()) {
|
||||
if (sysRoleGrantUserParam.getRemoveFirst()) {
|
||||
sysRelationService.remove(new LambdaQueryWrapper<SysRelation>().eq(SysRelation::getTargetId, id)
|
||||
.eq(SysRelation::getCategory, SysRelationCategoryEnum.SYS_USER_HAS_ROLE.getValue()));
|
||||
}
|
||||
|
@ -342,7 +340,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
@Override
|
||||
public SysRole queryEntity(String id) {
|
||||
SysRole sysRole = this.getById(id);
|
||||
if(ObjectUtil.isEmpty(sysRole)) {
|
||||
if (ObjectUtil.isEmpty(sysRole)) {
|
||||
throw new CommonException("角色不存在,id值为:{}", id);
|
||||
}
|
||||
return sysRole;
|
||||
|
@ -354,7 +352,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
public List<Tree<String>> orgTreeSelector() {
|
||||
List<SysOrg> sysOrgList = sysOrgService.getAllOrgList();
|
||||
List<TreeNode<String>> treeNodeList = sysOrgList.stream().map(sysOrg ->
|
||||
new TreeNode<>(sysOrg.getId(), sysOrg.getParentId(), sysOrg.getName(), sysOrg.getSortCode()))
|
||||
new TreeNode<>(sysOrg.getId(), sysOrg.getParentId(), sysOrg.getName(), sysOrg.getSortCode()))
|
||||
.collect(Collectors.toList());
|
||||
return TreeUtil.build(treeNodeList, "0");
|
||||
}
|
||||
|
@ -364,7 +362,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
LambdaQueryWrapper<SysMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
lambdaQueryWrapper.in(SysMenu::getCategory, SysResourceCategoryEnum.MODULE.getValue(), SysResourceCategoryEnum.MENU.getValue(),
|
||||
SysResourceCategoryEnum.BUTTON.getValue());
|
||||
if(!containsTen) {
|
||||
if (!containsTen) {
|
||||
lambdaQueryWrapper.ne(SysMenu::getCode, SysBuildInEnum.BUILD_IN_NO_TEN_MENU_CODE.getValue());
|
||||
}
|
||||
return this.resourceTreeSelector(sysMenuService.list(lambdaQueryWrapper));
|
||||
|
@ -401,18 +399,18 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
// 排除菜单中的目录
|
||||
boolean isLeafMenu = !"0".equals(sysMenu.getId())
|
||||
&& !sysMenu.getMenuType().equals(SysResourceMenuTypeEnum.CATALOG.getValue());
|
||||
if(isLeafMenu) {
|
||||
if (isLeafMenu) {
|
||||
SysRoleGrantResourceTreeResult.SysRoleGrantResourceMenuResult sysRoleGrantResourceMenuResult =
|
||||
new SysRoleGrantResourceTreeResult.SysRoleGrantResourceMenuResult();
|
||||
BeanUtil.copyProperties(sysMenu, sysRoleGrantResourceMenuResult);
|
||||
JSONObject parentJsonObject = getParentNode(treeList, sysMenu);
|
||||
List<String> parentIdSplitList = StrUtil.split(parentJsonObject.getStr("parentId"), StrUtil.DASHED);
|
||||
List<String> parentNameSplitList = StrUtil.split(parentJsonObject.getStr("parentName"), StrUtil.DASHED);
|
||||
if(parentNameSplitList.size() > 1) {
|
||||
if (parentNameSplitList.size() > 1) {
|
||||
sysRoleGrantResourceMenuResult.setParentId(parentIdSplitList.get(3));
|
||||
sysRoleGrantResourceMenuResult.setParentName(parentNameSplitList.get(0));
|
||||
StringBuilder selfNamePrefix = new StringBuilder();
|
||||
for(int i = 1; i< parentNameSplitList.size(); i++) {
|
||||
for (int i = 1; i < parentNameSplitList.size(); i++) {
|
||||
selfNamePrefix.append(parentNameSplitList.get(i)).append(StrUtil.DASHED);
|
||||
}
|
||||
sysRoleGrantResourceMenuResult.setTitle(selfNamePrefix + sysRoleGrantResourceMenuResult.getTitle());
|
||||
|
@ -455,26 +453,12 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
@Override
|
||||
public List<String> permissionTreeSelector() {
|
||||
List<String> permissionResult = CollectionUtil.newArrayList();
|
||||
SpringUtil.getApplicationContext().getBeansOfType(RequestMappingHandlerMapping.class).values()
|
||||
.forEach(requestMappingHandlerMapping -> requestMappingHandlerMapping.getHandlerMethods()
|
||||
.forEach((key, value) -> {
|
||||
SaCheckPermission saCheckPermission = value.getMethod().getAnnotation(SaCheckPermission.class);
|
||||
if(ObjectUtil.isNotEmpty(saCheckPermission)) {
|
||||
PathPatternsRequestCondition pathPatternsCondition = key.getPathPatternsCondition();
|
||||
if (pathPatternsCondition != null) {
|
||||
String apiName = "未定义接口名称";
|
||||
Operation apiOperation = value.getMethod().getAnnotation(Operation.class);
|
||||
if(ObjectUtil.isNotEmpty(apiOperation)) {
|
||||
String annotationValue = apiOperation.summary();
|
||||
if(ObjectUtil.isNotEmpty(annotationValue)) {
|
||||
apiName = annotationValue;
|
||||
}
|
||||
}
|
||||
String nm = StrUtil.BRACKET_START + apiName + StrUtil.BRACKET_END;
|
||||
pathPatternsCondition.getPatterns().forEach(pt -> permissionResult.add(pt + nm));
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
Object permissionResourceObject = commonCacheOperator.get(CacheConstant.PERMISSION_RESOURCE_CACHE_KEY);
|
||||
if (Objects.nonNull(permissionResourceObject)) {
|
||||
permissionResult = Convert.toList(String.class, permissionResourceObject);
|
||||
}
|
||||
|
||||
return CollectionUtil.sortByPinyin(permissionResult.stream().filter(api ->
|
||||
!api.startsWith("/" + StrUtil.BRACKET_START)
|
||||
&& !api.startsWith("/error")
|
||||
|
@ -488,20 +472,20 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
// 查询部分字段
|
||||
queryWrapper.lambda().select(SysRole::getId, SysRole::getOrgId, SysRole::getName, SysRole::getCode,
|
||||
SysRole::getCategory, SysRole::getSortCode);
|
||||
if(ObjectUtil.isNotEmpty(sysRoleSelectorRoleParam.getOrgId())) {
|
||||
if (ObjectUtil.isNotEmpty(sysRoleSelectorRoleParam.getOrgId())) {
|
||||
queryWrapper.lambda().eq(SysRole::getOrgId, sysRoleSelectorRoleParam.getOrgId());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(sysRoleSelectorRoleParam.getCategory())) {
|
||||
if (ObjectUtil.isNotEmpty(sysRoleSelectorRoleParam.getCategory())) {
|
||||
queryWrapper.lambda().eq(SysRole::getCategory, sysRoleSelectorRoleParam.getCategory());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(sysRoleSelectorRoleParam.getSearchKey())) {
|
||||
if (ObjectUtil.isNotEmpty(sysRoleSelectorRoleParam.getSearchKey())) {
|
||||
queryWrapper.lambda().like(SysRole::getName, sysRoleSelectorRoleParam.getSearchKey());
|
||||
}
|
||||
if(ObjectUtil.isNotEmpty(sysRoleSelectorRoleParam.getDataScopeList())) {
|
||||
if (ObjectUtil.isNotEmpty(sysRoleSelectorRoleParam.getDataScopeList())) {
|
||||
queryWrapper.lambda().in(SysRole::getOrgId, sysRoleSelectorRoleParam.getDataScopeList());
|
||||
}
|
||||
// 排除超管角色
|
||||
if(sysRoleSelectorRoleParam.isExcludeSuperAdmin()) {
|
||||
if (sysRoleSelectorRoleParam.isExcludeSuperAdmin()) {
|
||||
queryWrapper.lambda().ne(SysRole::getCode, SysBuildInEnum.BUILD_IN_ROLE_CODE.getValue());
|
||||
}
|
||||
queryWrapper.lambda().orderByAsc(SysRole::getSortCode);
|
||||
|
@ -517,7 +501,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
queryWrapper.lambda().select(SysUser::getId, SysUser::getAvatar, SysUser::getOrgId, SysUser::getPositionId, SysUser::getAccount,
|
||||
SysUser::getName, SysUser::getSortCode, SysUser::getGender, SysUser::getEntryDate);
|
||||
// 如果查询条件为空,则直接查询
|
||||
if(ObjectUtil.isAllEmpty(sysRoleSelectorUserParam.getOrgId(), sysRoleSelectorUserParam.getSearchKey())) {
|
||||
if (ObjectUtil.isAllEmpty(sysRoleSelectorUserParam.getOrgId(), sysRoleSelectorUserParam.getSearchKey())) {
|
||||
return sysUserService.getAllUserSelectorList();
|
||||
} else {
|
||||
if (ObjectUtil.isNotEmpty(sysRoleSelectorUserParam.getOrgId())) {
|
||||
|
@ -544,9 +528,9 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
List<Tree<String>> resultList = CollectionUtil.newArrayList();
|
||||
getNode(treeList, sysMenu.getId(), resultList);
|
||||
JSONObject jsonObject = JSONUtil.createObj();
|
||||
if(ObjectUtil.isNotEmpty(resultList)) {
|
||||
if (ObjectUtil.isNotEmpty(resultList)) {
|
||||
Tree<String> currentNode = resultList.get(0);
|
||||
if("0".equals(currentNode.getId()) || "0".equals(currentNode.getParentId())) {
|
||||
if ("0".equals(currentNode.getId()) || "0".equals(currentNode.getParentId())) {
|
||||
jsonObject.set("parentId", sysMenu.getId());
|
||||
jsonObject.set("parentName", sysMenu.getTitle());
|
||||
} else {
|
||||
|
@ -581,13 +565,13 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
}
|
||||
|
||||
public void getNode(List<Tree<String>> treeList, String id, List<Tree<String>> resultList) {
|
||||
for (Tree<String> tree: treeList) {
|
||||
if(tree.getId().equals(id)) {
|
||||
for (Tree<String> tree : treeList) {
|
||||
if (tree.getId().equals(id)) {
|
||||
resultList.add(tree);
|
||||
break;
|
||||
} else {
|
||||
List<Tree<String>> children = tree.getChildren();
|
||||
if(ObjectUtil.isNotEmpty(children)) {
|
||||
if (ObjectUtil.isNotEmpty(children)) {
|
||||
getNode(children, id, resultList);
|
||||
}
|
||||
}
|
||||
|
@ -597,9 +581,9 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
public List<SysMenu> getChildListById(List<SysMenu> originDataList, String id, boolean includeSelf) {
|
||||
List<SysMenu> sysResourceList = CollectionUtil.newArrayList();
|
||||
execRecursionFindChild(originDataList, id, sysResourceList);
|
||||
if(includeSelf) {
|
||||
if (includeSelf) {
|
||||
SysMenu self = this.getById(originDataList, id);
|
||||
if(ObjectUtil.isNotEmpty(self)) {
|
||||
if (ObjectUtil.isNotEmpty(self)) {
|
||||
sysResourceList.add(self);
|
||||
}
|
||||
}
|
||||
|
@ -609,9 +593,9 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
public List<SysMenu> getParentListById(List<SysMenu> originDataList, String id, boolean includeSelf) {
|
||||
List<SysMenu> sysResourceList = CollectionUtil.newArrayList();
|
||||
execRecursionFindParent(originDataList, id, sysResourceList);
|
||||
if(includeSelf) {
|
||||
if (includeSelf) {
|
||||
SysMenu self = this.getById(originDataList, id);
|
||||
if(ObjectUtil.isNotEmpty(self)) {
|
||||
if (ObjectUtil.isNotEmpty(self)) {
|
||||
sysResourceList.add(self);
|
||||
}
|
||||
}
|
||||
|
@ -620,7 +604,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
|
||||
public void execRecursionFindChild(List<SysMenu> originDataList, String id, List<SysMenu> resultList) {
|
||||
originDataList.forEach(item -> {
|
||||
if(item.getParentId().equals(id)) {
|
||||
if (item.getParentId().equals(id)) {
|
||||
resultList.add(item);
|
||||
execRecursionFindChild(originDataList, item.getId(), resultList);
|
||||
}
|
||||
|
@ -629,9 +613,9 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
|
||||
public void execRecursionFindParent(List<SysMenu> originDataList, String id, List<SysMenu> resultList) {
|
||||
originDataList.forEach(item -> {
|
||||
if(item.getId().equals(id)) {
|
||||
if (item.getId().equals(id)) {
|
||||
SysMenu parent = this.getById(originDataList, item.getParentId());
|
||||
if(ObjectUtil.isNotEmpty(parent)) {
|
||||
if (ObjectUtil.isNotEmpty(parent)) {
|
||||
resultList.add(parent);
|
||||
}
|
||||
execRecursionFindParent(originDataList, item.getParentId(), resultList);
|
||||
|
@ -641,16 +625,16 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
|
||||
public SysMenu getById(List<SysMenu> originDataList, String id) {
|
||||
int index = CollStreamUtil.toList(originDataList, SysMenu::getId).indexOf(id);
|
||||
return index == -1?null:originDataList.get(index);
|
||||
return index == -1 ? null : originDataList.get(index);
|
||||
}
|
||||
|
||||
public SysMenu getParentById(List<SysMenu> originDataList, String id) {
|
||||
SysMenu self = this.getById(originDataList, id);
|
||||
return ObjectUtil.isNotEmpty(self)?self:this.getById(originDataList, self.getParentId());
|
||||
return ObjectUtil.isNotEmpty(self) ? self : this.getById(originDataList, self.getParentId());
|
||||
}
|
||||
|
||||
public SysMenu getChildById(List<SysMenu> originDataList, String id) {
|
||||
int index = CollStreamUtil.toList(originDataList, SysMenu::getParentId).indexOf(id);
|
||||
return index == -1?null:originDataList.get(index);
|
||||
return index == -1 ? null : originDataList.get(index);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -177,8 +177,8 @@ public class GlobalConfigure implements WebMvcConfigurer {
|
|||
/* 可视化大屏插件放行 */
|
||||
"/screen/project/releaseDetail",
|
||||
"/screen/project/verifyAccessPassword",
|
||||
"/dbs/application/getAuth",
|
||||
"/dbs/dataSet/invoke",
|
||||
"/dataset/application/getAuth",
|
||||
"/dataset/dataSet/invoke",
|
||||
|
||||
/* 知识库插件放行 */
|
||||
"/wiki/wikidocumentshare/getInfoByCode",
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.core.listener;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.hutool.log.Log;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.mvc.condition.PathPatternsRequestCondition;
|
||||
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
import vip.xiaonuo.common.cache.CommonCacheOperator;
|
||||
import vip.xiaonuo.common.consts.CacheConstant;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 资源搜集器,将项目中所有接口(带@RequestMapping的)都搜集起来
|
||||
* <p>
|
||||
* 搜集到的接口会被缓存
|
||||
*
|
||||
* @author dongxiayu
|
||||
* @date 2023/1/29 23:24
|
||||
**/
|
||||
@Component
|
||||
@Order(1)
|
||||
public class ResourceCollectListener implements CommandLineRunner {
|
||||
|
||||
private static final Log log = Log.get();
|
||||
|
||||
@Resource
|
||||
private CommonCacheOperator commonCacheOperator;
|
||||
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
//1.获取所有后端接口
|
||||
List<String> permissionResult = CollectionUtil.newArrayList();
|
||||
Map<String, String> permissionMethodMap = MapUtil.newHashMap();
|
||||
SpringUtil.getApplicationContext().getBeansOfType(RequestMappingHandlerMapping.class).values()
|
||||
.forEach(requestMappingHandlerMapping -> requestMappingHandlerMapping.getHandlerMethods()
|
||||
.forEach((key, value) -> {
|
||||
SaCheckPermission saCheckPermission = value.getMethod().getAnnotation(SaCheckPermission.class);
|
||||
if (ObjectUtil.isNotEmpty(saCheckPermission)) {
|
||||
String path = null;
|
||||
// Spring Boot 3.x
|
||||
PathPatternsRequestCondition pathPatternsCondition = key.getPathPatternsCondition();
|
||||
if (pathPatternsCondition != null) {
|
||||
path = pathPatternsCondition.getPatterns().iterator().next().getPatternString();
|
||||
}
|
||||
// Spring Boot 2.x
|
||||
PatternsRequestCondition patternsCondition = key.getPatternsCondition();
|
||||
if (patternsCondition != null) {
|
||||
path = patternsCondition.getPatterns().iterator().next();
|
||||
}
|
||||
if (path != null) {
|
||||
String apiName = "未定义接口名称";
|
||||
Operation apiOperation = value.getMethod().getAnnotation(Operation.class);
|
||||
if (ObjectUtil.isNotEmpty(apiOperation)) {
|
||||
String annotationValue = apiOperation.summary();
|
||||
if (ObjectUtil.isNotEmpty(annotationValue)) {
|
||||
apiName = annotationValue;
|
||||
}
|
||||
}
|
||||
|
||||
String permissionKey = path + StrUtil.BRACKET_START + apiName + StrUtil.BRACKET_END;
|
||||
permissionResult.add(permissionKey);
|
||||
|
||||
// build permission method map data
|
||||
buildPermissionMethodMapData(value, permissionMethodMap, permissionKey);
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
//2.汇总添加到缓存
|
||||
Object permissionResourceObject = commonCacheOperator.get(CacheConstant.PERMISSION_RESOURCE_CACHE_KEY);
|
||||
List<String> permissionResource;
|
||||
if (Objects.isNull(permissionResourceObject)) {
|
||||
permissionResource = CollUtil.newArrayList();
|
||||
} else {
|
||||
permissionResource = Convert.toList(String.class, permissionResourceObject);
|
||||
}
|
||||
if (CollUtil.isNotEmpty(permissionResult)) {
|
||||
for (String permission : permissionResult) {
|
||||
if (!permissionResource.contains(permission)) {
|
||||
permissionResource.add(permission);
|
||||
}
|
||||
}
|
||||
|
||||
// 刷新缓存
|
||||
commonCacheOperator.put(CacheConstant.PERMISSION_RESOURCE_CACHE_KEY, permissionResource);
|
||||
}
|
||||
|
||||
// 3.汇总添加Permission Method Map数据到缓存
|
||||
refreshPermissionMethodMapDataToCache(permissionMethodMap);
|
||||
|
||||
log.info(">>> 缓存资源URL集合完成!资源数量:{}", permissionResult.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* refreshPermissionMethodMapDataToCache
|
||||
*
|
||||
* @param permissionMethodMap map of key {@link String},value {@link String}
|
||||
*/
|
||||
private void refreshPermissionMethodMapDataToCache(Map<String, String> permissionMethodMap) {
|
||||
Object permissionMethodMapObject = commonCacheOperator.get(CacheConstant.PERMISSION_RESOURCE_METHOD_CACHE_KEY);
|
||||
Map<String, String> permissionMethodMapFromCache = null;
|
||||
if (Objects.isNull(permissionMethodMapObject)) {
|
||||
permissionMethodMapFromCache = MapUtil.newHashMap();
|
||||
} else {
|
||||
permissionMethodMapFromCache = Convert.toMap(String.class, String.class, permissionMethodMapObject);
|
||||
}
|
||||
if (CollUtil.isNotEmpty(permissionMethodMap)) {
|
||||
for (Map.Entry<String, String> permissionMethodEntry : permissionMethodMap.entrySet()) {
|
||||
String permissionKey = permissionMethodEntry.getKey();
|
||||
String permissionMethod = permissionMethodEntry.getValue();
|
||||
permissionMethodMapFromCache.put(permissionKey, permissionMethod);
|
||||
}
|
||||
|
||||
// 刷新缓存
|
||||
commonCacheOperator.put(CacheConstant.PERMISSION_RESOURCE_METHOD_CACHE_KEY, permissionMethodMapFromCache);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* buildPermissionMethodMapData
|
||||
*
|
||||
* @param value {@link HandlerMethod}
|
||||
* @param permissionMethodMap map of key {@link String},value {@link String}
|
||||
* @param permissionKey {@link String}
|
||||
*/
|
||||
private static void buildPermissionMethodMapData(HandlerMethod value, Map<String, String> permissionMethodMap, String permissionKey) {
|
||||
GetMapping getMappingAnno = value.getMethod().getAnnotation(GetMapping.class);
|
||||
PostMapping postMappingAnno = value.getMethod().getAnnotation(PostMapping.class);
|
||||
|
||||
String permissionMethod = null;
|
||||
if (Objects.nonNull(getMappingAnno)) {
|
||||
permissionMethod = HttpMethod.GET.name();
|
||||
}
|
||||
if (Objects.nonNull(postMappingAnno)) {
|
||||
permissionMethod = HttpMethod.POST.name();
|
||||
}
|
||||
permissionMethodMap.put(permissionKey, permissionMethod);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue