【7.6.0】【sys】【resource】更新resource接口

pull/55/MERGE
fengshuonan 2023-06-17 08:58:21 +08:00
parent 2e70a16930
commit d76aba852c
12 changed files with 1564 additions and 0 deletions

View File

@ -47,6 +47,25 @@
<version>${roses.version}</version>
</dependency>
<!--资源缓存-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>cache-api</artifactId>
<version>${roses.version}</version>
</dependency>
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>cache-sdk-memory</artifactId>
<version>${roses.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>cache-sdk-redis</artifactId>
<version>${roses.version}</version>
<optional>true</optional>
</dependency>
<!--数据库sdk-->
<!--数据库dao框架-->
<dependency>

View File

@ -0,0 +1,56 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* 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.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.sys.modular.resource.cache;
import cn.hutool.cache.impl.TimedCache;
import cn.stylefeng.roses.kernel.cache.memory.AbstractMemoryCacheOperator;
import cn.stylefeng.roses.kernel.scanner.api.constants.ScannerConstants;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.ResourceDefinition;
/**
*
*
* @author fengshuonan
* @since 2021/5/17 16:05
*/
public class MemoryResourceCache extends AbstractMemoryCacheOperator<ResourceDefinition> {
/**
* TimedCachekeyurlvalueResourceDefinition
*
* @author fengshuonan
* @since 2021/5/17 16:06
*/
public MemoryResourceCache(TimedCache<String, ResourceDefinition> timedCache) {
super(timedCache);
}
@Override
public String getCommonKeyPrefix() {
return ScannerConstants.RESOURCE_CACHE_KEY;
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* 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.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.sys.modular.resource.cache;
import cn.stylefeng.roses.kernel.cache.redis.AbstractRedisHashCacheOperator;
import cn.stylefeng.roses.kernel.scanner.api.constants.ScannerConstants;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.ResourceDefinition;
import org.springframework.data.redis.core.RedisTemplate;
/**
* redis
*
* @author fengshuonan
* @since 2021/5/17 16:05
*/
public class RedisResourceCache extends AbstractRedisHashCacheOperator<ResourceDefinition> {
/**
* RedisTemplatekeyurlvalueResourceDefinition
*
* @author fengshuonan
* @since 2021/5/17 16:06
*/
public RedisResourceCache(RedisTemplate<String, ResourceDefinition> redisTemplate) {
super(redisTemplate);
}
/**
* hashkey
*
* @author fengshuonan
* @since 2021/5/17 17:34
*/
@Override
public String getCommonKeyPrefix() {
return ScannerConstants.RESOURCE_CACHE_KEY;
}
}

View File

@ -0,0 +1,102 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* 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.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.sys.modular.resource.controller;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.rule.enums.ResBizTypeEnum;
import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData;
import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData;
import cn.stylefeng.roses.kernel.scanner.api.annotation.ApiResource;
import cn.stylefeng.roses.kernel.scanner.api.annotation.GetResource;
import cn.stylefeng.roses.kernel.system.api.pojo.resource.ResourceRequest;
import cn.stylefeng.roses.kernel.system.api.pojo.role.request.SysRoleRequest;
import cn.stylefeng.roses.kernel.system.modular.resource.entity.SysResource;
import cn.stylefeng.roses.kernel.system.modular.resource.pojo.ResourceTreeNode;
import cn.stylefeng.roses.kernel.system.modular.resource.service.SysResourceService;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
*
*
* @author fengshuonan
* @since 2020/11/24 19:47
*/
@RestController
@ApiResource(name = "资源管理", resBizType = ResBizTypeEnum.SYSTEM)
public class ResourceController {
@Resource
private SysResourceService sysResourceService;
/**
*
*
* @author fengshuonan
* @since 2020/11/24 19:47
*/
@GetResource(name = "获取资源列表", path = "/resource/pageList")
public ResponseData<PageResult<SysResource>> pageList(ResourceRequest resourceRequest) {
PageResult<SysResource> result = this.sysResourceService.findPage(resourceRequest);
return new SuccessResponseData<>(result);
}
/**
*
*
* @author fengshuonan
* @since 2020/11/24 19:51
*/
@GetResource(name = "获取资源下拉列表", path = "/resource/getMenuResourceList")
public ResponseData<List<SysResource>> getMenuResourceList(ResourceRequest resourceRequest) {
List<SysResource> menuResourceList = this.sysResourceService.findList(resourceRequest);
return new SuccessResponseData<>(menuResourceList);
}
/**
* Layui--
*
* @author majianguo
* @since 2021/1/9 15:07
*/
@GetResource(name = "Layui版本--获取资源树列表,用于角色分配接口权限", path = "/resource/getRoleResourceTree")
public List<ResourceTreeNode> getLateralTree(SysRoleRequest sysRoleRequest) {
return sysResourceService.getRoleResourceTree(sysRoleRequest.getRoleId(), false, null);
}
/**
* AntdVue--
*
* @author majianguo
* @since 2021/1/9 15:07
*/
@GetResource(name = "AntdVue版本--获取资源树列表,用于角色分配接口权限", path = "/resource/getRoleResourceTreeAntdv")
public ResponseData<List<ResourceTreeNode>> getLateralTreeChildren(SysRoleRequest sysRoleRequest) {
List<ResourceTreeNode> resourceLateralTree = sysResourceService.getRoleResourceTree(sysRoleRequest.getRoleId(), true, sysRoleRequest.getResourceBizType());
return new SuccessResponseData<>(resourceLateralTree);
}
}

View File

@ -0,0 +1,74 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* 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.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.sys.modular.resource.controller;
import cn.stylefeng.roses.kernel.rule.enums.ResBizTypeEnum;
import cn.stylefeng.roses.kernel.scanner.api.ResourceReportApi;
import cn.stylefeng.roses.kernel.scanner.api.annotation.ApiResource;
import cn.stylefeng.roses.kernel.scanner.api.annotation.PostResource;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.ReportResourceParam;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.SysResourcePersistencePojo;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
*
*
* @author fengshuonan
* @since 2021/9/25 17:55
*/
@RestController
@ApiResource(name = "微服务汇报资源接口", resBizType = ResBizTypeEnum.SYSTEM)
public class ResourceReportController {
@Resource
private ResourceReportApi resourceReportApi;
/**
*
*
* @author fengshuonan
* @since 2021/9/25 17:55
*/
@PostResource(path = "/resourceService/reportResources", name = "汇报资源")
public void reportResources(@RequestBody ReportResourceParam reportResourceReq) {
resourceReportApi.reportResources(reportResourceReq);
}
/**
*
*
* @author fengshuonan
* @since 2021/9/25 17:55
*/
@PostResource(path = "/resourceService/reportResourcesAndGetResult", name = "汇报资源")
public List<SysResourcePersistencePojo> reportResourcesAndGetResult(@RequestBody ReportResourceParam reportResourceReq) {
return resourceReportApi.reportResourcesAndGetResult(reportResourceReq);
}
}

View File

@ -0,0 +1,193 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* 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.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.sys.modular.resource.entity;
import cn.stylefeng.roses.kernel.db.api.pojo.entity.BaseEntity;
import cn.stylefeng.roses.kernel.rule.annotation.ChineseDescription;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
*
*
* @author fengshuonan
* @since 2020/11/23 22:45
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_resource")
public class SysResource extends BaseEntity {
/**
* id
*/
@TableId("resource_id")
@ChineseDescription("资源id")
private Long resourceId;
/**
*
*/
@TableField("app_code")
@ChineseDescription("应用编码")
private String appCode;
/**
*
*/
@TableField("resource_code")
@ChineseDescription("资源编码")
private String resourceCode;
/**
*
*/
@TableField("resource_name")
@ChineseDescription("资源名称")
private String resourceName;
/**
*
*/
@TableField("project_code")
@ChineseDescription("项目编码")
private String projectCode;
/**
*
*/
@TableField("class_name")
@ChineseDescription("类名称")
private String className;
/**
*
*/
@TableField("method_name")
@ChineseDescription("方法名称")
private String methodName;
/**
*
*/
@TableField("modular_code")
@ChineseDescription("资源模块编码")
private String modularCode;
/**
*
*/
@TableField("modular_name")
@ChineseDescription("资源模块名称")
private String modularName;
/**
* ip
*/
@TableField("ip_address")
@ChineseDescription("资源初始化的服务器ip地址")
private String ipAddress;
/**
* Y-N-
* url '/view'
* htmljson
*
*/
@TableField("view_flag")
@ChineseDescription("是否是视图类型")
private String viewFlag;
/**
* url
*/
@TableField("url")
@ChineseDescription("资源url")
private String url;
/**
* http
*/
@TableField("http_method")
@ChineseDescription("http请求方法")
private String httpMethod;
/**
* 1-2-
*/
@TableField("resource_biz_type")
@ChineseDescription("资源的业务类型1-业务类型2-系统类型")
private Integer resourceBizType;
/**
* Y-N-
*/
@TableField("required_login_flag")
@ChineseDescription("是否需要登录Y-是N-否")
private String requiredLoginFlag;
/**
* Y-N-
*/
@TableField("required_permission_flag")
@ChineseDescription("是否需要鉴权Y-是N-否")
private String requiredPermissionFlag;
/**
*
* <p>
* json
*/
@TableField("validate_groups")
@ChineseDescription("需要进行参数校验的分组")
private String validateGroups;
/**
*
* <p>
* json
*/
@TableField("param_field_descriptions")
@ChineseDescription("接口参数的字段描述")
private String paramFieldDescriptions;
/**
*
* <p>
* json
*/
@TableField("response_field_descriptions")
@ChineseDescription("接口返回结果的字段描述")
private String responseFieldDescriptions;
/**
*
*/
private transient String appName;
}

View File

@ -0,0 +1,221 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* 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.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.sys.modular.resource.factory;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.roses.kernel.rule.enums.YesOrNotEnum;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.FieldMetadata;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.ResourceDefinition;
import cn.stylefeng.roses.kernel.sys.modular.resource.entity.SysResource;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* ResourceDefinitionSysResource
*
* @author fengshuonan
* @since 2019-05-29-14:37
*/
public class ResourceFactory {
/**
* ResourceDefinitionSysResource
*
* @author fengshuonan
* @since 2020/12/9 14:14
*/
public static SysResource createResource(ResourceDefinition resourceDefinition) {
SysResource resource = new SysResource();
BeanUtil.copyProperties(resourceDefinition, resource, CopyOptions.create().ignoreError());
resource.setResourceCode(resourceDefinition.getResourceCode());
if (resourceDefinition.getRequiredLoginFlag()) {
resource.setRequiredLoginFlag(YesOrNotEnum.Y.name());
} else {
resource.setRequiredLoginFlag(YesOrNotEnum.N.name());
}
if (resourceDefinition.getRequiredPermissionFlag()) {
resource.setRequiredPermissionFlag(YesOrNotEnum.Y.name());
} else {
resource.setRequiredPermissionFlag(YesOrNotEnum.N.name());
}
if (resourceDefinition.getViewFlag()) {
resource.setViewFlag(YesOrNotEnum.Y.name());
} else {
resource.setViewFlag(YesOrNotEnum.N.name());
}
// 转化校验组
if (ObjectUtil.isNotEmpty(resourceDefinition.getValidateGroups())) {
resource.setValidateGroups(JSON.toJSONString(resourceDefinition.getValidateGroups(), SerializerFeature.WriteClassName));
}
// 转化接口参数的字段描述
if (ObjectUtil.isNotEmpty(resourceDefinition.getParamFieldDescriptions())) {
resource.setParamFieldDescriptions(JSON.toJSONString(resourceDefinition.getParamFieldDescriptions(), SerializerFeature.WriteClassName));
}
// 转化接口返回结果的字段描述
if (ObjectUtil.isNotEmpty(resourceDefinition.getResponseFieldDescriptions())) {
resource.setResponseFieldDescriptions(JSON.toJSONString(resourceDefinition.getResponseFieldDescriptions(), SerializerFeature.WriteClassName));
}
return resource;
}
/**
* SysResourceResourceDefinition
*
* @author fengshuonan
* @since 2020/12/9 14:15
*/
public static ResourceDefinition createResourceDefinition(SysResource sysResource) {
ResourceDefinition resourceDefinition = new ResourceDefinition();
// 拷贝公共属性
BeanUtil.copyProperties(sysResource, resourceDefinition, CopyOptions.create().ignoreError());
// 设置是否需要登录标识Y为需要登录
resourceDefinition.setRequiredLoginFlag(YesOrNotEnum.Y.name().equals(sysResource.getRequiredLoginFlag()));
// 设置是否需要权限认证标识Y为需要权限认证
resourceDefinition.setRequiredPermissionFlag(YesOrNotEnum.Y.name().equals(sysResource.getRequiredPermissionFlag()));
// 设置是否是视图类型
resourceDefinition.setViewFlag(YesOrNotEnum.Y.name().equals(sysResource.getViewFlag()));
// 转化校验组
if (ObjectUtil.isNotEmpty(sysResource.getValidateGroups())) {
resourceDefinition.setValidateGroups(JSON.parseObject(sysResource.getValidateGroups(), Set.class, Feature.SupportAutoType));
}
// 转化接口参数的字段描述
if (ObjectUtil.isNotEmpty(sysResource.getParamFieldDescriptions())) {
resourceDefinition.setParamFieldDescriptions(JSON.parseObject(sysResource.getParamFieldDescriptions(), Set.class, Feature.SupportAutoType));
}
// 转化接口返回结果的字段描述
if (ObjectUtil.isNotEmpty(sysResource.getResponseFieldDescriptions())) {
resourceDefinition.setResponseFieldDescriptions(JSON.parseObject(sysResource.getResponseFieldDescriptions(), FieldMetadata.class, Feature.SupportAutoType));
}
return resourceDefinition;
}
/**
* ResourceDefinitionapi
*
* @author fengshuonan
* @since 2021/1/16 16:09
*/
public static ResourceDefinition fillResourceDetail(ResourceDefinition resourceDefinition) {
// 这个接口的校验组信息
Set<String> validateGroups = resourceDefinition.getValidateGroups();
// 接口的请求参数信息
Set<FieldMetadata> paramFieldDescriptions = resourceDefinition.getParamFieldDescriptions();
if(paramFieldDescriptions != null && paramFieldDescriptions.size() > 0){
for (FieldMetadata fieldMetadata : paramFieldDescriptions) {
fillDetailMessage(validateGroups, fieldMetadata);
}
}
// 接口的响应参数信息
FieldMetadata responseFieldDescriptions = resourceDefinition.getResponseFieldDescriptions();
fillDetailMessage(validateGroups, responseFieldDescriptions);
return resourceDefinition;
}
/**
*
*
* @author fengshuonan
* @since 2021/1/16 18:00
*/
public static void fillDetailMessage(Set<String> validateGroups, FieldMetadata fieldMetadata) {
if (validateGroups == null || validateGroups.isEmpty()) {
return;
}
if (fieldMetadata == null) {
return;
}
StringBuilder finalValidateMessages = new StringBuilder();
Map<String, Set<String>> groupAnnotations = fieldMetadata.getGroupValidationMessage();
if (groupAnnotations != null) {
for (String validateGroup : validateGroups) {
Set<String> validateMessage = groupAnnotations.get(validateGroup);
if (validateMessage != null && !validateMessage.isEmpty()) {
finalValidateMessages.append(StrUtil.join("", validateMessage));
}
}
}
fieldMetadata.setValidationMessages(finalValidateMessages.toString());
// 递归填充子类型的详细提示信息
if (fieldMetadata.getGenericFieldMetadata() != null && !fieldMetadata.getGenericFieldMetadata().isEmpty()) {
for (FieldMetadata metadata : fieldMetadata.getGenericFieldMetadata()) {
fillDetailMessage(validateGroups, metadata);
}
}
}
/**
* mapkeyurlvalueResourceDefinition
*
* @author fengshuonan
* @since 2021/5/17 16:21
*/
public static Map<String, ResourceDefinition> orderedResourceDefinition(List<ResourceDefinition> sysResourceList) {
HashMap<String, ResourceDefinition> result = new HashMap<>();
if (ObjectUtil.isEmpty(sysResourceList)) {
return result;
}
for (ResourceDefinition sysResource : sysResourceList) {
String url = sysResource.getUrl();
result.put(url, sysResource);
}
return result;
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* 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.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.sys.modular.resource.mapper;
import cn.stylefeng.roses.kernel.db.mp.injector.CustomBaseMapper;
import cn.stylefeng.roses.kernel.sys.modular.resource.entity.SysResource;
/**
* Mapper
*
* @author fengshuonan
* @since 2020/11/23 22:45
*/
public interface SysResourceMapper extends CustomBaseMapper<SysResource> {
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.stylefeng.roses.kernel.system.modular.resource.mapper.SysResourceMapper">
</mapper>

View File

@ -0,0 +1,101 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* 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.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.sys.modular.resource.pojo;
import cn.stylefeng.roses.kernel.rule.annotation.ChineseDescription;
import cn.stylefeng.roses.kernel.rule.tree.factory.base.AbstractTreeNode;
import lombok.Data;
import java.util.List;
/**
*
*
* @author fengshuonan
* @since 2020/3/26 14:29
*/
@Data
public class ResourceTreeNode implements AbstractTreeNode<ResourceTreeNode> {
/**
* id
*/
@ChineseDescription("资源id")
private String code;
/**
* id
*/
@ChineseDescription("父级资源id")
private String parentCode;
/**
*
*/
@ChineseDescription("资源名称")
private String nodeName;
/**
*
* <p>
* true-
* false-
*/
@ChineseDescription("是否是资源标识")
private Boolean resourceFlag;
/**
*
*/
@ChineseDescription("能否选择")
private Boolean checked;
/**
*
*/
@ChineseDescription("是否是半开状态(一部分选中)")
private Boolean indeterminate;
/**
*
*/
@ChineseDescription("子节点集合")
private List<ResourceTreeNode> children;
@Override
public String getNodeId() {
return this.code;
}
@Override
public String getNodeParentId() {
return this.parentCode;
}
@Override
public void setChildrenNodes(List<ResourceTreeNode> childrenNodes) {
this.children = childrenNodes;
}
}

View File

@ -0,0 +1,115 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* 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.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.sys.modular.resource.service;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.ResourceDefinition;
import cn.stylefeng.roses.kernel.sys.modular.resource.entity.SysResource;
import cn.stylefeng.roses.kernel.sys.modular.resource.pojo.ResourceTreeNode;
import com.baomidou.mybatisplus.extension.service.IService;
import jdk.management.resource.ResourceRequest;
import java.util.List;
/**
*
*
* @author fengshuonan
* @since 2020/11/24 19:56
*/
public interface SysResourceService extends IService<SysResource> {
/**
*
*
* @param resourceRequest
* @return
* @author fengshuonan
* @since 2020/11/24 20:45
*/
PageResult<SysResource> findPage(ResourceRequest resourceRequest);
/**
* code
* <p>
*
*
* @param resourceRequest
* @return
* @author fengshuonan
* @since 2020/11/24 20:45
*/
List<SysResource> findList(ResourceRequest resourceRequest);
/**
*
*
* @param roleId id
* @param treeBuildFlag true-false-
* @param resourceBizType 1-2-
* @author fengshuonan
* @since 2022/9/28 23:46
*/
List<ResourceTreeNode> getRoleResourceTree(Long roleId, Boolean treeBuildFlag, Integer resourceBizType);
/**
*
*
* @param resourceCodes
* @param treeBuildFlag
* @param resourceBizType 1-2-
* @author fengshuonan
* @since 2021/8/8 22:24
*/
List<ResourceTreeNode> getResourceList(List<String> resourceCodes, Boolean treeBuildFlag, Integer resourceBizType);
/**
*
*
* @param resourceRequest
* @return
* @author fengshuonan
* @since 2020/12/18 16:04
*/
ResourceDefinition getApiResourceDetail(ResourceRequest resourceRequest);
/**
*
*
* @param projectCode spring application name
* @author fengshuonan
* @since 2020/11/24 20:46
*/
void deleteResourceByProjectCode(String projectCode);
/**
* guns$
*
* @author fengshuonan
* @since 2022/11/17 0:17
*/
void updateResourceAppCode(String newAppCode);
}

View File

@ -0,0 +1,577 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* 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.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.sys.modular.resource.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.roses.kernel.auth.api.LoginUserApi;
import cn.stylefeng.roses.kernel.auth.api.context.LoginContext;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.basic.SimpleRoleInfo;
import cn.stylefeng.roses.kernel.cache.api.CacheOperatorApi;
import cn.stylefeng.roses.kernel.db.api.context.DbOperatorContext;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.rule.constants.RuleConstants;
import cn.stylefeng.roses.kernel.rule.constants.TreeConstants;
import cn.stylefeng.roses.kernel.rule.enums.DbTypeEnum;
import cn.stylefeng.roses.kernel.rule.enums.ResBizTypeEnum;
import cn.stylefeng.roses.kernel.rule.enums.YesOrNotEnum;
import cn.stylefeng.roses.kernel.rule.tree.factory.DefaultTreeBuildFactory;
import cn.stylefeng.roses.kernel.rule.util.GunsResourceCodeUtil;
import cn.stylefeng.roses.kernel.scanner.api.ResourceReportApi;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.ReportResourceParam;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.ResourceDefinition;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.ResourceUrlParam;
import cn.stylefeng.roses.kernel.scanner.api.pojo.resource.SysResourcePersistencePojo;
import cn.stylefeng.roses.kernel.sys.modular.resource.entity.SysResource;
import cn.stylefeng.roses.kernel.sys.modular.resource.factory.ResourceFactory;
import cn.stylefeng.roses.kernel.sys.modular.resource.mapper.SysResourceMapper;
import cn.stylefeng.roses.kernel.sys.modular.resource.pojo.ResourceTreeNode;
import cn.stylefeng.roses.kernel.sys.modular.resource.service.SysResourceService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jdk.management.resource.ResourceRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
*
*
* @author fengshuonan
* @since 2020/11/23 22:45
*/
@Service
@Slf4j
public class SysResourceServiceImpl extends ServiceImpl<SysResourceMapper, SysResource> implements SysResourceService, ResourceReportApi, ResourceServiceApi {
@Resource
private SysResourceMapper resourceMapper;
@Resource
private RoleServiceApi roleServiceApi;
@Resource(name = "resourceCache")
private CacheOperatorApi<ResourceDefinition> resourceCache;
@Override
public PageResult<SysResource> findPage(ResourceRequest resourceRequest) {
LambdaQueryWrapper<SysResource> wrapper = createWrapper(resourceRequest);
Page<SysResource> page = this.page(PageFactory.defaultPage(), wrapper);
return PageResultFactory.createPageResult(page);
}
@Override
public List<SysResource> findList(ResourceRequest resourceRequest) {
LambdaQueryWrapper<SysResource> wrapper = createWrapper(resourceRequest);
// 只查询code和name
wrapper.select(SysResource::getResourceCode, SysResource::getResourceName);
List<SysResource> menuResourceList = this.list(wrapper);
// 增加返回虚拟菜单的情况
SysResource sysResource = new SysResource();
sysResource.setResourceCode("");
sysResource.setResourceName("虚拟目录(空)");
menuResourceList.add(0, sysResource);
return menuResourceList;
}
@Override
public List<ResourceTreeNode> getRoleResourceTree(Long roleId, Boolean treeBuildFlag, Integer resourceBizType) {
// 查询当前角色已有的接口
List<SysRoleResourceDTO> resourceList = roleServiceApi.getRoleResourceList(Collections.singletonList(roleId));
// 该角色已拥有权限
List<String> alreadyList = new ArrayList<>();
for (SysRoleResourceDTO sysRoleResponse : resourceList) {
alreadyList.add(sysRoleResponse.getResourceCode());
}
return this.getResourceList(alreadyList, treeBuildFlag, resourceBizType);
}
@Override
public List<ResourceTreeNode> getResourceList(List<String> resourceCodes, Boolean treeBuildFlag, Integer resourceBizType) {
List<ResourceTreeNode> res = new ArrayList<>();
// 获取所有的资源
LambdaQueryWrapper<SysResource> sysResourceLambdaQueryWrapper = new LambdaQueryWrapper<>();
sysResourceLambdaQueryWrapper.select(SysResource::getAppCode, SysResource::getModularCode, SysResource::getModularName, SysResource::getResourceCode, SysResource::getUrl,
SysResource::getResourceName);
// 只查询需要授权的接口
sysResourceLambdaQueryWrapper.eq(SysResource::getRequiredPermissionFlag, YesOrNotEnum.Y.getCode());
// 查询指定范围的资源
sysResourceLambdaQueryWrapper.eq(ObjectUtil.isNotEmpty(resourceBizType), SysResource::getResourceBizType, resourceBizType);
LoginUserApi loginUserApi = LoginContext.me();
if (!loginUserApi.getSuperAdminFlag()) {
// 获取权限列表
List<Long> roleIds = loginUserApi.getLoginUser().getSimpleRoleInfoList().parallelStream().map(SimpleRoleInfo::getRoleId).collect(Collectors.toList());
Set<String> resourceCodeList = roleServiceApi.getRoleResourceCodeList(roleIds);
if (!resourceCodeList.isEmpty()) {
sysResourceLambdaQueryWrapper.in(SysResource::getResourceCode, resourceCodeList);
}
}
List<SysResource> allResource = this.list(sysResourceLambdaQueryWrapper);
// 根据模块名称把资源分类
Map<String, List<SysResource>> modularMap = new HashMap<>();
for (SysResource sysResource : allResource) {
List<SysResource> sysResources = modularMap.get(sysResource.getModularName());
// 没有就新建一个
if (ObjectUtil.isEmpty(sysResources)) {
sysResources = new ArrayList<>();
modularMap.put(sysResource.getModularName(), sysResources);
}
// 把自己加入进去
sysResources.add(sysResource);
}
// 创建一级节点
for (Map.Entry<String, List<SysResource>> entry : modularMap.entrySet()) {
ResourceTreeNode item = new ResourceTreeNode();
item.setResourceFlag(false);
String id = IdWorker.get32UUID();
item.setCode(id);
item.setParentCode(RuleConstants.TREE_ROOT_ID.toString());
item.setNodeName(entry.getKey());
// 设置临时变量,统计半开状态
int checkedNumber = 0;
//创建二级节点
for (SysResource resource : entry.getValue()) {
ResourceTreeNode subItem = new ResourceTreeNode();
// 判断是否已经拥有
if (!resourceCodes.contains(resource.getResourceCode())) {
subItem.setChecked(false);
} else {
checkedNumber++;
// 让父类也选择
item.setChecked(true);
subItem.setChecked(true);
}
subItem.setResourceFlag(true);
subItem.setNodeName(resource.getResourceName());
subItem.setCode(resource.getResourceCode());
subItem.setParentCode(id);
res.add(subItem);
}
// 统计选中的数量
if (checkedNumber == 0) {
item.setChecked(false);
item.setIndeterminate(false);
} else if (checkedNumber == entry.getValue().size()) {
item.setChecked(true);
item.setIndeterminate(false);
} else {
item.setChecked(false);
item.setIndeterminate(true);
}
res.add(item);
}
// 根据map组装资源树
if (treeBuildFlag) {
return new DefaultTreeBuildFactory<ResourceTreeNode>().doTreeBuild(res);
} else {
return res;
}
}
@Override
public List<LayuiApiResourceTreeNode> getApiResourceTree(ResourceRequest resourceRequest) {
// 1. 获取所有的资源
LambdaQueryWrapper<SysResource> sysResourceLambdaQueryWrapper = new LambdaQueryWrapper<>();
sysResourceLambdaQueryWrapper.eq(SysResource::getViewFlag, YesOrNotEnum.N.getCode());
sysResourceLambdaQueryWrapper.select(SysResource::getAppCode, SysResource::getModularCode, SysResource::getModularName, SysResource::getResourceCode, SysResource::getUrl,
SysResource::getResourceName);
// 查询条件
if (ObjectUtil.isNotEmpty(resourceRequest.getResourceName())) {
sysResourceLambdaQueryWrapper.like(SysResource::getUrl, resourceRequest.getResourceName()).or().like(SysResource::getResourceName, resourceRequest.getResourceName());
}
List<SysResource> allResource = this.list(sysResourceLambdaQueryWrapper);
// 2. 按应用和模块编码设置map
Map<String, Map<String, List<LayuiApiResourceTreeNode>>> appModularResources = divideResources(allResource);
// 3. 创建模块code和模块name的映射
Map<String, String> modularCodeName = createModularCodeName(allResource);
// 4. 根据map组装资源树
return createResourceTree(appModularResources, modularCodeName);
}
@Override
public ResourceDefinition getApiResourceDetail(ResourceRequest resourceRequest) {
LambdaQueryWrapper<SysResource> sysResourceLambdaQueryWrapper = new LambdaQueryWrapper<>();
sysResourceLambdaQueryWrapper.eq(SysResource::getResourceCode, resourceRequest.getResourceCode());
SysResource sysResource = this.getOne(sysResourceLambdaQueryWrapper);
if (sysResource != null) {
// 实体转化为ResourceDefinition
ResourceDefinition resourceDefinition = ResourceFactory.createResourceDefinition(sysResource);
// 填充具体的提示信息
return ResourceFactory.fillResourceDetail(resourceDefinition);
} else {
return null;
}
}
@Override
public void deleteResourceByProjectCode(String projectCode) {
LambdaQueryWrapper<SysResource> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SysResource::getProjectCode, projectCode);
this.remove(wrapper);
}
@Override
public void updateResourceAppCode(String newAppCode) {
// 获取所有资源表信息
List<SysResource> list = this.list();
// 批量更新资源编码
for (SysResource sysResource : list) {
String newResourceCode = GunsResourceCodeUtil.replace(sysResource.getResourceCode(), newAppCode);
sysResource.setResourceCode(newResourceCode);
}
this.updateBatchById(list);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void reportResources(@RequestBody ReportResourceParam reportResourceReq) {
this.reportResourcesAndGetResult(reportResourceReq);
}
@Override
public List<SysResourcePersistencePojo> reportResourcesAndGetResult(ReportResourceParam reportResourceReq) {
String projectCode = reportResourceReq.getProjectCode();
Map<String, Map<String, ResourceDefinition>> resourceDefinitions = reportResourceReq.getResourceDefinitions();
if (ObjectUtil.isEmpty(projectCode) || resourceDefinitions == null) {
return new ArrayList<>();
}
// 根据project删除该项目下的所有资源
this.deleteResourceByProjectCode(projectCode);
// 获取当前应用的所有资源
ArrayList<SysResource> allResources = new ArrayList<>();
ArrayList<ResourceDefinition> resourceDefinitionArrayList = new ArrayList<>();
for (Map.Entry<String, Map<String, ResourceDefinition>> appModularResources : resourceDefinitions.entrySet()) {
Map<String, ResourceDefinition> value = appModularResources.getValue();
for (Map.Entry<String, ResourceDefinition> modularResources : value.entrySet()) {
resourceDefinitionArrayList.add(modularResources.getValue());
SysResource resource = ResourceFactory.createResource(modularResources.getValue());
allResources.add(resource);
}
}
// 将资源存入库中
DbTypeEnum currentDbType = DbOperatorContext.me().getCurrentDbType();
if (DbTypeEnum.MYSQL.equals(currentDbType)) {
// 分批插入记录
List<List<SysResource>> split = ListUtil.split(allResources, RuleConstants.DEFAULT_BATCH_INSERT_SIZE);
for (List<SysResource> sysResources : split) {
this.getBaseMapper().insertBatchSomeColumn(sysResources);
}
} else {
this.saveBatch(allResources, allResources.size());
}
// 将资源存入缓存一份
Map<String, ResourceDefinition> resourceDefinitionMap = ResourceFactory.orderedResourceDefinition(resourceDefinitionArrayList);
for (Map.Entry<String, ResourceDefinition> entry : resourceDefinitionMap.entrySet()) {
resourceCache.put(entry.getKey(), entry.getValue());
}
// 组装返回结果
ArrayList<SysResourcePersistencePojo> finalResult = new ArrayList<>();
for (SysResource item : allResources) {
SysResourcePersistencePojo sysResourcePersistencePojo = new SysResourcePersistencePojo();
BeanUtil.copyProperties(item, sysResourcePersistencePojo);
finalResult.add(sysResourcePersistencePojo);
}
return finalResult;
}
@Override
public ResourceDefinition getResourceByUrl(@RequestBody ResourceUrlParam resourceUrlReq) {
if (ObjectUtil.isEmpty(resourceUrlReq.getUrl())) {
return null;
} else {
// 先从缓存中查询
ResourceDefinition tempCachedResourceDefinition = resourceCache.get(resourceUrlReq.getUrl());
if (tempCachedResourceDefinition != null) {
return tempCachedResourceDefinition;
}
// 缓存中没有去数据库查询
List<SysResource> resources = resourceMapper.selectList(new QueryWrapper<SysResource>().eq("url", resourceUrlReq.getUrl()));
if (resources == null || resources.isEmpty()) {
return null;
} else {
// 获取接口资源信息
SysResource resource = resources.get(0);
ResourceDefinition resourceDefinition = new ResourceDefinition();
BeanUtils.copyProperties(resource, resourceDefinition);
// 获取是否需要登录的标记, 判断是否需要登录如果是则设置为true,否则为false
String requiredLoginFlag = resource.getRequiredLoginFlag();
resourceDefinition.setRequiredLoginFlag(YesOrNotEnum.Y.name().equals(requiredLoginFlag));
// 获取请求权限的标记判断是否有权限如果有则设置为true,否则为false
String requiredPermissionFlag = resource.getRequiredPermissionFlag();
resourceDefinition.setRequiredPermissionFlag(YesOrNotEnum.Y.name().equals(requiredPermissionFlag));
// 查询结果添加到缓存
resourceCache.put(resourceDefinition.getUrl(), resourceDefinition);
return resourceDefinition;
}
}
}
@Override
public Set<String> getResourceUrlsListByCodes(Set<String> resourceCodes) {
if (resourceCodes == null || resourceCodes.isEmpty()) {
return new HashSet<>();
}
// 拼接in条件
LambdaQueryWrapper<SysResource> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(SysResource::getResourceCode, resourceCodes);
queryWrapper.select(SysResource::getUrl);
// 获取资源详情
List<SysResource> list = this.list(queryWrapper);
return list.stream().map(SysResource::getUrl).collect(Collectors.toSet());
}
@Override
public Integer getResourceCount() {
long count = this.count();
return Convert.toInt(count);
}
@Override
public List<SysRoleResourceDTO> getTotalResourceCode(ResBizTypeEnum resBizTypeEnum) {
LambdaQueryWrapper<SysResource> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.select(SysResource::getResourceCode, SysResource::getResourceBizType);
// 根据资源类型查询
queryWrapper.eq(ObjectUtil.isNotEmpty(resBizTypeEnum), SysResource::getResourceBizType, resBizTypeEnum.getCode());
List<SysResource> list = this.list(queryWrapper);
ArrayList<SysRoleResourceDTO> results = new ArrayList<>();
for (SysResource sysResource : list) {
SysRoleResourceDTO sysRoleResourceDTO = new SysRoleResourceDTO();
sysRoleResourceDTO.setResourceCode(sysResource.getResourceCode());
sysRoleResourceDTO.setResourceBizType(sysResource.getResourceBizType());
results.add(sysRoleResourceDTO);
}
return results;
}
@Override
public Integer getResourceBizTypeByCode(String resCode) {
LambdaQueryWrapper<SysResource> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.select(SysResource::getResourceBizType);
queryWrapper.eq(SysResource::getResourceCode, resCode);
SysResource one = this.getOne(queryWrapper, false);
if (one == null) {
return ResBizTypeEnum.DEFAULT.getCode();
} else {
return one.getResourceBizType();
}
}
/**
* wrapper
*
* @author fengshuonan
* @since 2020/11/6 10:16
*/
private LambdaQueryWrapper<SysResource> createWrapper(ResourceRequest resourceRequest) {
LambdaQueryWrapper<SysResource> queryWrapper = new LambdaQueryWrapper<>();
if (ObjectUtil.isEmpty(resourceRequest)) {
return queryWrapper;
}
// 根据应用编码查询
queryWrapper.eq(ObjectUtil.isNotEmpty(resourceRequest.getAppCode()), SysResource::getAppCode, resourceRequest.getAppCode());
// 根据资源名称
queryWrapper.like(ObjectUtil.isNotEmpty(resourceRequest.getResourceName()), SysResource::getResourceName, resourceRequest.getResourceName());
// 根据资源url
queryWrapper.like(ObjectUtil.isNotEmpty(resourceRequest.getUrl()), SysResource::getUrl, resourceRequest.getUrl());
return queryWrapper;
}
/**
*
*
* @return keykey
* @author fengshuonan
* @since 2020/12/18 15:34
*/
private Map<String, Map<String, List<LayuiApiResourceTreeNode>>> divideResources(List<SysResource> sysResources) {
HashMap<String, Map<String, List<LayuiApiResourceTreeNode>>> appModularResources = new HashMap<>();
for (SysResource sysResource : sysResources) {
// 查询应用下有无资源
String appCode = sysResource.getAppCode();
Map<String, List<LayuiApiResourceTreeNode>> modularResource = appModularResources.get(appCode);
// 该应用下没资源就创建一个map
if (modularResource == null) {
modularResource = new HashMap<>();
}
// 查询当前资源的模块有没有在appModularResources存在
List<LayuiApiResourceTreeNode> resourceTreeNodes = modularResource.get(sysResource.getModularCode());
if (resourceTreeNodes == null) {
resourceTreeNodes = new ArrayList<>();
}
// 将当前资源放入资源集合
LayuiApiResourceTreeNode resourceTreeNode = new LayuiApiResourceTreeNode();
resourceTreeNode.setResourceFlag(true);
resourceTreeNode.setTitle(sysResource.getResourceName());
resourceTreeNode.setId(sysResource.getResourceCode());
resourceTreeNode.setParentId(sysResource.getModularCode());
resourceTreeNode.setUrl(sysResource.getUrl());
resourceTreeNode.setSpread(false);
resourceTreeNodes.add(resourceTreeNode);
modularResource.put(sysResource.getModularCode(), resourceTreeNodes);
appModularResources.put(appCode, modularResource);
}
return appModularResources;
}
/**
* codename
*
* @author fengshuonan
* @since 2020/12/21 11:23
*/
private Map<String, String> createModularCodeName(List<SysResource> resources) {
HashMap<String, String> modularCodeName = new HashMap<>();
for (SysResource resource : resources) {
modularCodeName.put(resource.getModularCode(), resource.getModularName());
}
return modularCodeName;
}
/**
*
*
* @author fengshuonan
* @since 2020/12/18 15:45
*/
private List<LayuiApiResourceTreeNode> createResourceTree(Map<String, Map<String, List<LayuiApiResourceTreeNode>>> appModularResources, Map<String, String> modularCodeName) {
List<LayuiApiResourceTreeNode> finalTree = new ArrayList<>();
// 按应用遍历应用模块资源集合
for (String appName : appModularResources.keySet()) {
// 创建当前应用节点
LayuiApiResourceTreeNode appNode = new LayuiApiResourceTreeNode();
appNode.setId(appName);
appNode.setTitle(appName);
appNode.setSpread(true);
appNode.setResourceFlag(false);
appNode.setParentId(TreeConstants.DEFAULT_PARENT_ID.toString());
// 遍历当前应用下的模块资源
Map<String, List<LayuiApiResourceTreeNode>> modularResources = appModularResources.get(appName);
// 创建模块节点
ArrayList<LayuiApiResourceTreeNode> modularNodes = new ArrayList<>();
for (String modularCode : modularResources.keySet()) {
LayuiApiResourceTreeNode modularNode = new LayuiApiResourceTreeNode();
modularNode.setId(modularCode);
modularNode.setTitle(modularCodeName.get(modularCode));
modularNode.setParentId(appName);
modularNode.setSpread(false);
modularNode.setResourceFlag(false);
modularNode.setChildren(modularResources.get(modularCode));
modularNodes.add(modularNode);
}
// 当前应用下添加模块的资源
appNode.setChildren(modularNodes);
// 添加到最终结果
finalTree.add(appNode);
}
return finalTree;
}
}