diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/resource/ExternalResourceRequest.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/resource/ExternalResourceRequest.java new file mode 100644 index 000000000..10c27af8c --- /dev/null +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/resource/ExternalResourceRequest.java @@ -0,0 +1,38 @@ +package cn.stylefeng.roses.kernel.system.api.pojo.resource; + +import cn.stylefeng.roses.kernel.rule.pojo.request.BaseRequest; +import cn.stylefeng.roses.kernel.scanner.api.annotation.field.ChineseDescription; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.Valid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 外部资源请求类 + * + * @author majianguo + * @date 2021/6/8 下午2:33 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class ExternalResourceRequest extends BaseRequest { + + /** + * 资源所属应用code + */ + @NotNull(message = "资源所属应用CODE不能为空", groups = {add.class}) + @ChineseDescription("资源所属应用CODE") + private String appCode; + + /** + * 资源列表 + */ + @Valid + @NotNull(message = "资源列表不能为空", groups = {add.class}) + @ChineseDescription("资源列表") + private List resourceRequestList; + +} \ No newline at end of file diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/resource/ResourceRequest.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/resource/ResourceRequest.java index b50c573a6..e68ee2072 100644 --- a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/resource/ResourceRequest.java +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/resource/ResourceRequest.java @@ -26,6 +26,8 @@ package cn.stylefeng.roses.kernel.system.api.pojo.resource; import cn.stylefeng.roses.kernel.rule.pojo.request.BaseRequest; import cn.stylefeng.roses.kernel.scanner.api.annotation.field.ChineseDescription; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; import lombok.Data; import lombok.EqualsAndHashCode; @@ -43,18 +45,18 @@ public class ResourceRequest extends BaseRequest { private static final long serialVersionUID = 1L; + /** + * 资源id + */ + @ChineseDescription("资源id") + private Long resourceId; + /** * 应用编码 */ @ChineseDescription("应用编码") private String appCode; - /** - * 资源名称 - */ - @ChineseDescription("资源名称") - private String resourceName; - /** * 资源编码 */ @@ -63,11 +65,104 @@ public class ResourceRequest extends BaseRequest { private String resourceCode; /** - * 资源地址 + * 资源名称 */ - @ChineseDescription("资源地址") + @ChineseDescription("资源名称") + private String resourceName; + + /** + * 项目编码 + */ + @ChineseDescription("项目编码") + private String projectCode; + + /** + * 类名称 + */ + @ChineseDescription("类名称") + private String className; + + /** + * 方法名称 + */ + @ChineseDescription("方法名称") + private String methodName; + + /** + * 资源模块编码 + */ + @ChineseDescription("资源模块编码") + private String modularCode; + + /** + * 资源模块名称 + */ + @ChineseDescription("资源模块名称") + private String modularName; + + /** + * 资源初始化的服务器ip地址 + */ + @ChineseDescription("资源初始化的服务器ip地址") + private String ipAddress; + + /** + * 是否是视图类型:Y-是,N-否 + * 如果是视图类型,url需要以 '/view' 开头, + * 视图类型的接口会渲染出html界面,而不是json数据, + * 视图层一般会在前后端不分离项目出现 + */ + @ChineseDescription("是否是视图类型") + private String viewFlag; + + /** + * 资源url + */ + @ChineseDescription("资源url") private String url; + /** + * http请求方法 + */ + @ChineseDescription("http请求方法") + private String httpMethod; + + /** + * 是否需要登录:Y-是,N-否 + */ + @ChineseDescription("是否需要登录:Y-是,N-否") + private String requiredLoginFlag; + + /** + * 是否需要鉴权:Y-是,N-否 + */ + @ChineseDescription("是否需要鉴权:Y-是,N-否") + private String requiredPermissionFlag; + + /** + * 需要进行参数校验的分组 + *

+ * json形式存储 + */ + @ChineseDescription("需要进行参数校验的分组") + private String validateGroups; + + /** + * 接口参数的字段描述 + *

+ * json形式存储 + */ + @ChineseDescription("接口参数的字段描述") + private String paramFieldDescriptions; + + /** + * 接口返回结果的字段描述 + *

+ * json形式存储 + */ + @ChineseDescription("接口返回结果的字段描述") + private String responseFieldDescriptions; + /** * 是否是菜单(Y-是,N-否) */ diff --git a/kernel-s-system/system-business-resource/src/main/java/cn/stylefeng/roses/kernel/system/modular/resource/controller/ResourceController.java b/kernel-s-system/system-business-resource/src/main/java/cn/stylefeng/roses/kernel/system/modular/resource/controller/ResourceController.java index 0aeb81447..cc934cea1 100644 --- a/kernel-s-system/system-business-resource/src/main/java/cn/stylefeng/roses/kernel/system/modular/resource/controller/ResourceController.java +++ b/kernel-s-system/system-business-resource/src/main/java/cn/stylefeng/roses/kernel/system/modular/resource/controller/ResourceController.java @@ -24,19 +24,27 @@ */ package cn.stylefeng.roses.kernel.system.modular.resource.controller; +import cn.hutool.core.codec.Base64Decoder; import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult; 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.scanner.api.annotation.PostResource; +import cn.stylefeng.roses.kernel.system.api.pojo.resource.ApiGroupRequest; +import cn.stylefeng.roses.kernel.system.api.pojo.resource.ExternalResourceRequest; 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 com.alibaba.fastjson.JSON; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; +import java.nio.charset.StandardCharsets; import java.util.List; /** @@ -58,7 +66,7 @@ public class ResourceController { * @author fengshuonan * @date 2020/11/24 19:47 */ - @GetResource(name = "获取资源列表", path = "/resource/pageList",responseClass = SysResource.class) + @GetResource(name = "获取资源列表", path = "/resource/pageList", responseClass = SysResource.class) public ResponseData pageList(ResourceRequest resourceRequest) { PageResult result = this.sysResourceService.findPage(resourceRequest); return new SuccessResponseData(result); @@ -70,7 +78,7 @@ public class ResourceController { * @author fengshuonan * @date 2020/11/24 19:51 */ - @GetResource(name = "获取资源下拉列表", path = "/resource/getMenuResourceList",responseClass = SysResource.class) + @GetResource(name = "获取资源下拉列表", path = "/resource/getMenuResourceList", responseClass = SysResource.class) public ResponseData getMenuResourceList(ResourceRequest resourceRequest) { List menuResourceList = this.sysResourceService.findList(resourceRequest); return new SuccessResponseData(menuResourceList); @@ -82,7 +90,7 @@ public class ResourceController { * @author majianguo * @date 2021/1/9 15:07 */ - @GetResource(name = "Layui版本--获取资源树列表,用于角色分配接口权限", path = "/resource/getRoleResourceTree",responseClass = ResourceTreeNode.class) + @GetResource(name = "Layui版本--获取资源树列表,用于角色分配接口权限", path = "/resource/getRoleResourceTree", responseClass = ResourceTreeNode.class) public List getLateralTree(SysRoleRequest sysRoleRequest) { return sysResourceService.getResourceTree(sysRoleRequest.getRoleId(), false); } @@ -93,10 +101,24 @@ public class ResourceController { * @author majianguo * @date 2021/1/9 15:07 */ - @GetResource(name = "AntdVue版本--获取资源树列表,用于角色分配接口权限", path = "/resource/getRoleResourceTreeAntdv",responseClass = ResourceTreeNode.class) + @GetResource(name = "AntdVue版本--获取资源树列表,用于角色分配接口权限", path = "/resource/getRoleResourceTreeAntdv", responseClass = ResourceTreeNode.class) public ResponseData getLateralTreeChildren(SysRoleRequest sysRoleRequest) { List resourceLateralTree = sysResourceService.getResourceTree(sysRoleRequest.getRoleId(), true); return new SuccessResponseData(resourceLateralTree); } + /** + * 添加外部资源 + * + * @return {@link cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData} + * @author majianguo + * @date 2021/6/8 下午2:30 + **/ + @PostResource(name = "添加外部资源", path = "/resource/addExternalResource", requiredPermission = false, requiredLogin = false) + public ResponseData addExternalResource(@RequestBody String base64Data) { + String jsonStr = new String(Base64Decoder.decode(base64Data), StandardCharsets.UTF_8); + sysResourceService.addExternalResource(JSON.parseObject(jsonStr, ExternalResourceRequest.class)); + return new SuccessResponseData(); + } + } diff --git a/kernel-s-system/system-business-resource/src/main/java/cn/stylefeng/roses/kernel/system/modular/resource/service/SysResourceService.java b/kernel-s-system/system-business-resource/src/main/java/cn/stylefeng/roses/kernel/system/modular/resource/service/SysResourceService.java index 6ff8acf06..a9ee5effc 100644 --- a/kernel-s-system/system-business-resource/src/main/java/cn/stylefeng/roses/kernel/system/modular/resource/service/SysResourceService.java +++ b/kernel-s-system/system-business-resource/src/main/java/cn/stylefeng/roses/kernel/system/modular/resource/service/SysResourceService.java @@ -26,6 +26,7 @@ package cn.stylefeng.roses.kernel.system.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.system.api.pojo.resource.ExternalResourceRequest; import cn.stylefeng.roses.kernel.system.api.pojo.resource.LayuiApiResourceTreeNode; import cn.stylefeng.roses.kernel.system.api.pojo.resource.ResourceRequest; import cn.stylefeng.roses.kernel.system.modular.resource.entity.SysResource; @@ -102,4 +103,11 @@ public interface SysResourceService extends IService { */ void deleteResourceByProjectCode(String projectCode); + /** + * 添加外部资源 + * + * @author majianguo + * @date 2021/6/8 下午2:40 + **/ + void addExternalResource(ExternalResourceRequest externalResourceRequest); } diff --git a/kernel-s-system/system-business-resource/src/main/java/cn/stylefeng/roses/kernel/system/modular/resource/service/impl/SysResourceServiceImpl.java b/kernel-s-system/system-business-resource/src/main/java/cn/stylefeng/roses/kernel/system/modular/resource/service/impl/SysResourceServiceImpl.java index 20c9b411e..8fa1229eb 100644 --- a/kernel-s-system/system-business-resource/src/main/java/cn/stylefeng/roses/kernel/system/modular/resource/service/impl/SysResourceServiceImpl.java +++ b/kernel-s-system/system-business-resource/src/main/java/cn/stylefeng/roses/kernel/system/modular/resource/service/impl/SysResourceServiceImpl.java @@ -24,6 +24,7 @@ */ package cn.stylefeng.roses.kernel.system.modular.resource.service.impl; +import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.ObjectUtil; import cn.stylefeng.roses.kernel.auth.api.LoginUserApi; import cn.stylefeng.roses.kernel.auth.api.context.LoginContext; @@ -42,6 +43,7 @@ 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.system.api.ResourceServiceApi; import cn.stylefeng.roses.kernel.system.api.RoleServiceApi; +import cn.stylefeng.roses.kernel.system.api.pojo.resource.ExternalResourceRequest; import cn.stylefeng.roses.kernel.system.api.pojo.resource.LayuiApiResourceTreeNode; import cn.stylefeng.roses.kernel.system.api.pojo.resource.ResourceRequest; import cn.stylefeng.roses.kernel.system.api.pojo.role.dto.SysRoleResourceDTO; @@ -236,6 +238,36 @@ public class SysResourceServiceImpl extends ServiceImpl sysResourceLambdaQueryWrapper = new LambdaQueryWrapper<>(); + sysResourceLambdaQueryWrapper.eq(SysResource::getAppCode, appCode); + this.remove(sysResourceLambdaQueryWrapper); + + // 添加新的资源 + List sysResources = externalResourceRequest.getResourceRequestList().stream().map(item -> { + SysResource sysResource = BeanUtil.toBean(item, SysResource.class); + if (ObjectUtil.isEmpty(sysResource.getViewFlag())) { + sysResource.setViewFlag(YesOrNotEnum.N.getCode()); + } + // 处理JSON序列号类型 + if (ObjectUtil.isNotEmpty(sysResource.getParamFieldDescriptions())) { + sysResource.setParamFieldDescriptions(sysResource.getParamFieldDescriptions().replaceAll("com.sedinbj.kernel.resource.api.pojo.resource.FieldMetadata", "cn.stylefeng.roses.kernel.scanner.api.pojo.resource.FieldMetadata")); + } + if (ObjectUtil.isNotEmpty(sysResource.getResponseFieldDescriptions())) { + sysResource.setResponseFieldDescriptions(sysResource.getResponseFieldDescriptions().replaceAll("com.sedinbj.kernel.resource.api.pojo.resource.FieldMetadata", "cn.stylefeng.roses.kernel.scanner.api.pojo.resource.FieldMetadata")); + } + return sysResource; + }).collect(Collectors.toList()); + this.saveBatch(sysResources); + } + } + @Override @Transactional(rollbackFor = Exception.class) public void reportResources(@RequestBody ReportResourceParam reportResourceReq) {