From 3b9d4ccc8283d44b9eea0a44479b4c928f644e1e Mon Sep 17 00:00:00 2001 From: maven <2163098428@qq.com> Date: 星期五, 22 八月 2025 09:22:38 +0800 Subject: [PATCH] yys 增加接口文档 --- ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java | 181 ++++++++++++++++++++++++++++++++++----------- 1 files changed, 137 insertions(+), 44 deletions(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java index 9ab7c24..89f250a 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java @@ -1,64 +1,157 @@ package com.ruoyi.web.core.config; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import com.ruoyi.common.config.RuoYiConfig; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; 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.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; +import io.swagger.v3.oas.models.security.SecurityScheme.In; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.springdoc.core.customizers.OpenApiBuilderCustomizer; +import org.springdoc.core.customizers.ServerBaseUrlCustomizer; +import org.springdoc.core.models.GroupedOpenApi; +import org.springdoc.core.properties.SpringDocConfigProperties; +import org.springdoc.core.providers.JavadocProvider; +import org.springdoc.core.service.OpenAPIService; +import org.springdoc.core.service.SecurityService; +import org.springdoc.core.utils.PropertyResolverUtils; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; /** - * Swagger2鐨勬帴鍙i厤缃� - * - * @author ruoyi + * Swagger 鑷姩閰嶇疆绫伙紝鍩轰簬 OpenAPI + Springdoc 瀹炵幇銆� + * + * 鍙嬫儏鎻愮ず锛� + * 1. Springdoc 鏂囨。鍦板潃锛�<a href="https://github.com/springdoc/springdoc-openapi">浠撳簱</a> + * 2. Swagger 瑙勮寖锛屼簬 2015 鏇村悕涓� OpenAPI 瑙勮寖锛屾湰璐ㄦ槸涓�涓笢瑗� + * */ +// @AutoConfiguration @Configuration +@ConditionalOnClass({OpenAPI.class}) +@EnableConfigurationProperties(SwaggerProperties.class) +@ConditionalOnProperty(prefix = "springdoc.api-docs", name = "enabled", havingValue = "true", matchIfMissing = true) // 璁剧疆涓� false 鏃讹紝绂佺敤 public class SwaggerConfig { - /** 绯荤粺鍩虹閰嶇疆 */ - @Autowired - private RuoYiConfig ruoyiConfig; - - /** - * 鑷畾涔夌殑 OpenAPI 瀵硅薄 - */ + + public static final String HEADER_TENANT_ID = "tenant-id"; + + + // ========== 鍏ㄥ眬 OpenAPI 閰嶇疆 ========== + @Bean - public OpenAPI customOpenApi() - { - return new OpenAPI().components(new Components() - // 璁剧疆璁よ瘉鐨勮姹傚ご - .addSecuritySchemes("apikey", securityScheme())) - .addSecurityItem(new SecurityRequirement().addList("apikey")) - .info(getApiInfo()); + public OpenAPI createApi(SwaggerProperties properties) { + Map<String, SecurityScheme> securitySchemas = buildSecuritySchemes(); + OpenAPI openAPI = new OpenAPI() + // 鎺ュ彛淇℃伅 + .info(buildInfo(properties)) + // 鎺ュ彛瀹夊叏閰嶇疆 + .components(new Components().securitySchemes(securitySchemas)) + .addSecurityItem(new SecurityRequirement().addList(HttpHeaders.AUTHORIZATION)); + securitySchemas.keySet().forEach(key -> openAPI.addSecurityItem(new SecurityRequirement().addList(key))); + return openAPI; } - - @Bean - public SecurityScheme securityScheme() - { - return new SecurityScheme() - .type(SecurityScheme.Type.APIKEY) - .name("Authorization") - .in(SecurityScheme.In.HEADER) - .scheme("Bearer"); - } - + /** - * 娣诲姞鎽樿淇℃伅 + * API 鎽樿淇℃伅 */ - public Info getApiInfo() - { + private Info buildInfo(SwaggerProperties properties) { return new Info() - // 璁剧疆鏍囬 - .title("鏍囬锛氳嫢渚濈鐞嗙郴缁焈鎺ュ彛鏂囨。") - // 鎻忚堪 - .description("鎻忚堪锛氱敤浜庣鐞嗛泦鍥㈡棗涓嬪叕鍙哥殑浜哄憳淇℃伅,鍏蜂綋鍖呮嫭XXX,XXX妯″潡...") - // 浣滆�呬俊鎭� - .contact(new Contact().name(ruoyiConfig.getName())) - // 鐗堟湰 - .version("鐗堟湰鍙�:" + ruoyiConfig.getVersion()); + .title(properties.getTitle()) + .description(properties.getDescription()) + .version(properties.getVersion()) + .contact(new Contact().name(properties.getAuthor()).url(properties.getUrl()).email(properties.getEmail())) + .license(new License().name(properties.getLicense()).url(properties.getLicenseUrl())); } -} + + /** + * 瀹夊叏妯″紡锛岃繖閲岄厤缃�氳繃璇锋眰澶� Authorization 浼犻�� token 鍙傛暟 + */ + private Map<String, SecurityScheme> buildSecuritySchemes() { + Map<String, SecurityScheme> securitySchemes = new HashMap<>(); + SecurityScheme securityScheme = new SecurityScheme() + .type(SecurityScheme.Type.APIKEY) // 绫诲瀷 + .name(HttpHeaders.AUTHORIZATION) // 璇锋眰澶寸殑 name + .in(SecurityScheme.In.HEADER); // token 鎵�鍦ㄤ綅缃� + securitySchemes.put(HttpHeaders.AUTHORIZATION, securityScheme); + return securitySchemes; + } + + /** + * 鑷畾涔� OpenAPI 澶勭悊鍣� + */ + @Bean + public OpenAPIService openApiBuilder(Optional<OpenAPI> openAPI, + SecurityService securityParser, + SpringDocConfigProperties springDocConfigProperties, + PropertyResolverUtils propertyResolverUtils, + Optional<List<OpenApiBuilderCustomizer>> openApiBuilderCustomizers, + Optional<List<ServerBaseUrlCustomizer>> serverBaseUrlCustomizers, + Optional<JavadocProvider> 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(); + } + + /** + * 鏋勫缓 Authorization 璁よ瘉璇锋眰澶村弬鏁� + * + * 瑙e喅 Knife4j <a href="https://gitee.com/xiaoym/knife4j/issues/I69QBU">Authorize 鏈敓鏁堬紝璇锋眰header閲屾湭鍖呭惈鍙傛暟</a> + * + * @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 + } + + /** + * 鏋勫缓 Tenant 绉熸埛缂栧彿璇锋眰澶村弬鏁� + * @return 澶氱鎴峰弬鏁� + */ +/* private static Parameter buildTenantHeaderParameter() { + return new Parameter() + .name(HEADER_TENANT_ID) // header 鍚� + .description("绉熸埛缂栧彿") // 鎻忚堪 + .in(String.valueOf(SecurityScheme.In.HEADER)) // 璇锋眰 header + .schema(new IntegerSchema()._default(1L).name(HEADER_TENANT_ID).description("绉熸埛缂栧彿")); // 榛樿锛氫娇鐢ㄧ鎴风紪鍙蜂负 1 + } */ +} \ No newline at end of file -- Gitblit v1.9.3