diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java index c04a3c51b..76e1e52ea 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/swagger/config/YudaoSwaggerAutoConfiguration.java @@ -6,6 +6,7 @@ import io.swagger.v3.oas.models.info.Contact; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.info.License; import io.swagger.v3.oas.models.media.IntegerSchema; +import io.swagger.v3.oas.models.media.StringSchema; import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.security.SecurityRequirement; import io.swagger.v3.oas.models.security.SecurityScheme; @@ -27,8 +28,11 @@ import java.util.Optional; import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_TENANT_ID; /** - * springdoc 自动配置类 - * 使用 knife4j.enable=false 禁用 Swagger + * Swagger 自动配置类,基于 OpenAPI + Springdoc 实现。 + * + * 友情提示: + * 1. Springdoc 文档地址:仓库 + * 2. Swagger 规范,于 2015 更名为 OpenAPI 规范,本质是一个东西 * * @author 芋道源码 */ @@ -37,53 +41,21 @@ import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.HEADER_ @EnableConfigurationProperties(SwaggerProperties.class) public class YudaoSwaggerAutoConfiguration { + // ========== 全局 OpenAPI 配置 ========== + @Bean public OpenAPI createApi(SwaggerProperties properties) { - Map maps = securityScheme(); + Map securitySchemas = buildSecuritySchemes(); OpenAPI openAPI = new OpenAPI() + // 接口信息 .info(buildInfo(properties)) - .components(new Components().securitySchemes(maps)) + // 接口安全配置 + .components(new Components().securitySchemes(securitySchemas)) .addSecurityItem(new SecurityRequirement().addList(HttpHeaders.AUTHORIZATION)); - maps.keySet().forEach(key -> openAPI.addSecurityItem(new SecurityRequirement().addList(key))); + securitySchemas.keySet().forEach(key -> openAPI.addSecurityItem(new SecurityRequirement().addList(key))); return openAPI; } - /** - * 自定义 openapi 处理器 - */ - @Bean - public OpenAPIService openApiBuilder(Optional openAPI, - SecurityService securityParser, - SpringDocConfigProperties springDocConfigProperties, - PropertyResolverUtils propertyResolverUtils, - Optional> openApiBuilderCustomisers, - Optional> serverBaseUrlCustomisers, - Optional javadocProvider) { - return new OpenAPIService(openAPI, securityParser, springDocConfigProperties, propertyResolverUtils, openApiBuilderCustomisers, serverBaseUrlCustomisers, javadocProvider); - } - - @Bean - public GroupedOpenApi appApi() { - return GroupedOpenApi.builder() - .group("app") - .addOperationCustomizer((operation, handlerMethod) -> - operation.addParametersItem(globalHeaderParameter()) - ) - .pathsToMatch("/app-api/**") - .build(); - } - - @Bean - public GroupedOpenApi adminApi() { - return GroupedOpenApi.builder() - .group("admin") - .addOperationCustomizer((operation, handlerMethod) -> - operation.addParametersItem(globalHeaderParameter()) - ) - .pathsToMatch("/admin-api/**") - .build(); - } - /** * API 摘要信息 */ @@ -99,33 +71,82 @@ public class YudaoSwaggerAutoConfiguration { /** * 安全模式,这里配置通过请求头 Authorization 传递 token 参数 */ - private Map securityScheme() { - Map map = new HashMap<>(); + private Map buildSecuritySchemes() { + Map securitySchemes = new HashMap<>(); SecurityScheme securityScheme = new SecurityScheme() - //类型 - .type(SecurityScheme.Type.APIKEY) - //请求头的name - .name(HttpHeaders.AUTHORIZATION) - //token所在未知 - .in(SecurityScheme.In.HEADER); - map.put(HttpHeaders.AUTHORIZATION, securityScheme); - return map; + .type(SecurityScheme.Type.APIKEY) // 类型 + .name(HttpHeaders.AUTHORIZATION) // 请求头的 name + .in(SecurityScheme.In.HEADER); // token 所在位置 + securitySchemes.put(HttpHeaders.AUTHORIZATION, securityScheme); + return securitySchemes; } /** - * globalHeaderParameter + * 自定义 OpenAPI 处理器 + */ + @Bean + public OpenAPIService openApiBuilder(Optional openAPI, + SecurityService securityParser, + SpringDocConfigProperties springDocConfigProperties, + PropertyResolverUtils propertyResolverUtils, + Optional> openApiBuilderCustomizers, + Optional> serverBaseUrlCustomizers, + Optional javadocProvider) { + + return new OpenAPIService(openAPI, securityParser, springDocConfigProperties, + propertyResolverUtils, openApiBuilderCustomizers, serverBaseUrlCustomizers, javadocProvider); + } + + // ========== 分组 OpenAPI 配置 ========== + + /** + * 所有模块的 API 分组 + */ + @Bean + public GroupedOpenApi allGroupedOpenApi() { + return buildGroupedOpenApi("all", ""); + } + + public static GroupedOpenApi buildGroupedOpenApi(String group) { + return buildGroupedOpenApi(group, group); + } + + public static GroupedOpenApi buildGroupedOpenApi(String group, String path) { + return GroupedOpenApi.builder() + .group(group) + .pathsToMatch("/admin-api/" + path + "/**", "/app-api/" + path + "/**") + .addOperationCustomizer((operation, handlerMethod) -> operation + .addParametersItem(buildTenantHeaderParameter()) + .addParametersItem(buildSecurityHeaderParameter())) + .build(); + } + + /** + * 构建 Tenant 租户编号请求头参数 + * * @return 多租户参数 */ - private static Parameter globalHeaderParameter() { + private static Parameter buildTenantHeaderParameter() { return new Parameter() - .name(HEADER_TENANT_ID) - .description("租户编号") - .in(String.valueOf(SecurityScheme.In.HEADER)) - .schema(new IntegerSchema() - ._default(1L) - .name(HEADER_TENANT_ID) - .description("租户编号") - ); + .name(HEADER_TENANT_ID) // header 名 + .description("租户编号") // 描述 + .in(String.valueOf(SecurityScheme.In.HEADER)) // 请求 header + .schema(new IntegerSchema()._default(1L).name(HEADER_TENANT_ID).description("租户编号")); // 默认:使用租户编号为 1 + } + + /** + * 构建 Authorization 认证请求头参数 + * + * 解决 Knife4j Authorize 未生效,请求header里未包含参数 + * + * @return 认证参数 + */ + private static Parameter buildSecurityHeaderParameter() { + return new Parameter() + .name(HttpHeaders.AUTHORIZATION) // header 名 + .description("认证 Token") // 描述 + .in(String.valueOf(SecurityScheme.In.HEADER)) // 请求 header + .schema(new StringSchema()._default("Bearer test1").name(HEADER_TENANT_ID).description("认证 Token")); // 默认:使用用户编号为 1 } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/config/BpmWebConfiguration.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/config/BpmWebConfiguration.java new file mode 100644 index 000000000..036e8a12f --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/config/BpmWebConfiguration.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.bpm.framework.web.config; + +import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * bpm 模块的 web 组件的 Configuration + * + * @author 芋道源码 + */ +@Configuration(proxyBeanMethods = false) +public class BpmWebConfiguration { + + /** + * bpm 模块的 API 分组 + */ + @Bean + public GroupedOpenApi bpmGroupedOpenApi() { + return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("bpm"); + } + +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/package-info.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/package-info.java new file mode 100644 index 000000000..c01417081 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/web/package-info.java @@ -0,0 +1,4 @@ +/** + * bpm 模块的 web 配置 + */ +package cn.iocoder.yudao.module.bpm.framework.web; diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/web/config/InfraWebConfiguration.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/web/config/InfraWebConfiguration.java new file mode 100644 index 000000000..09f2c2b3f --- /dev/null +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/web/config/InfraWebConfiguration.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.infra.framework.web.config; + +import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * infra 模块的 web 组件的 Configuration + * + * @author 芋道源码 + */ +@Configuration(proxyBeanMethods = false) +public class InfraWebConfiguration { + + /** + * infra 模块的 API 分组 + */ + @Bean + public GroupedOpenApi infraGroupedOpenApi() { + return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("infra"); + } + +} diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/web/package-info.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/web/package-info.java new file mode 100644 index 000000000..6fb49bfde --- /dev/null +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/web/package-info.java @@ -0,0 +1,4 @@ +/** + * infra 模块的 web 配置 + */ +package cn.iocoder.yudao.module.infra.framework.web; diff --git a/yudao-module-mall/README.md b/yudao-module-mall/README.md new file mode 100644 index 000000000..6664ebef7 --- /dev/null +++ b/yudao-module-mall/README.md @@ -0,0 +1,4 @@ +mall 后端的代码,暂时归档成一个 yudao-module-mall 的压缩包。 + +精力有限,近期还是以管理后台的工作流、大屏报表等功能为主! + diff --git a/yudao-module-mall/yudao-module-mall.zip b/yudao-module-mall/yudao-module-mall.zip new file mode 100755 index 000000000..9f361e3f7 Binary files /dev/null and b/yudao-module-mall/yudao-module-mall.zip differ diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/config/MemberWebConfiguration.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/config/MemberWebConfiguration.java new file mode 100644 index 000000000..82c70034e --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/config/MemberWebConfiguration.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.member.framework.web.config; + +import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * member 模块的 web 组件的 Configuration + * + * @author 芋道源码 + */ +@Configuration(proxyBeanMethods = false) +public class MemberWebConfiguration { + + /** + * member 模块的 API 分组 + */ + @Bean + public GroupedOpenApi memberGroupedOpenApi() { + return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("member"); + } + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/package-info.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/package-info.java new file mode 100644 index 000000000..3a964cfc2 --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/framework/web/package-info.java @@ -0,0 +1,4 @@ +/** + * member 模块的 web 配置 + */ +package cn.iocoder.yudao.module.member.framework.web; diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/web/config/MpWebConfiguration.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/web/config/MpWebConfiguration.java new file mode 100644 index 000000000..3e6e1acfc --- /dev/null +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/web/config/MpWebConfiguration.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.mp.framework.web.config; + +import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * mp 模块的 web 组件的 Configuration + * + * @author 芋道源码 + */ +@Configuration(proxyBeanMethods = false) +public class MpWebConfiguration { + + /** + * mp 模块的 API 分组 + */ + @Bean + public GroupedOpenApi mpGroupedOpenApi() { + return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("mp"); + } + +} diff --git a/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/web/package-info.java b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/web/package-info.java new file mode 100644 index 000000000..a103f1c38 --- /dev/null +++ b/yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/web/package-info.java @@ -0,0 +1,4 @@ +/** + * mp 模块的 web 配置 + */ +package cn.iocoder.yudao.module.mp.framework.web; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/web/config/PayWebConfiguration.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/web/config/PayWebConfiguration.java new file mode 100644 index 000000000..febc2bc8a --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/web/config/PayWebConfiguration.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.pay.framework.web.config; + +import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * pay 模块的 web 组件的 Configuration + * + * @author 芋道源码 + */ +@Configuration(proxyBeanMethods = false) +public class PayWebConfiguration { + + /** + * pay 模块的 API 分组 + */ + @Bean + public GroupedOpenApi payGroupedOpenApi() { + return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("pay"); + } + +} diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/web/package-info.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/web/package-info.java new file mode 100644 index 000000000..03bfad978 --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/web/package-info.java @@ -0,0 +1,4 @@ +/** + * pay 模块的 web 配置 + */ +package cn.iocoder.yudao.module.pay.framework.web; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/web/config/SystemWebConfiguration.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/web/config/SystemWebConfiguration.java new file mode 100644 index 000000000..5b1b2355b --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/web/config/SystemWebConfiguration.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.system.framework.web.config; + +import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration; +import org.springdoc.core.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * system 模块的 web 组件的 Configuration + * + * @author 芋道源码 + */ +@Configuration(proxyBeanMethods = false) +public class SystemWebConfiguration { + + /** + * system 模块的 API 分组 + */ + @Bean + public GroupedOpenApi systemGroupedOpenApi() { + return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("system"); + } + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/web/package-info.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/web/package-info.java new file mode 100644 index 000000000..1a17a3d7c --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/framework/web/package-info.java @@ -0,0 +1,4 @@ +/** + * system 模块的 web 配置 + */ +package cn.iocoder.yudao.module.system.framework.web; diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index 03cd5c9f6..0d4eceb29 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -41,19 +41,19 @@ yudao-spring-boot-starter-biz-error-code - - - - - - - + + + cn.iocoder.boot + yudao-module-visualization-biz + ${revision} + + - + cn.iocoder.boot yudao-module-pay-biz diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index ecac514f3..6348c7fd4 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -34,8 +34,9 @@ spring: redis: time-to-live: 1h # 设置过期时间为 1 小时 +--- #################### 接口文档配置 #################### + springdoc: - show-actuator: true swagger-ui: enabled: true path: /swagger-ui