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/pom.xml                                                           |    7 +
 ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerProperties.java    |   63 ++++++++++++
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java |    1 
 ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerConfig.java        |  181 +++++++++++++++++++++++++++--------
 ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java  |    2 
 5 files changed, 208 insertions(+), 46 deletions(-)

diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index 622c28a..905a605 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -16,7 +16,12 @@
     </description>
 
     <dependencies>
-
+        <!-- ruoyi-springboot2 / swagger knife4j 閰嶇疆 -->
+        <dependency>
+            <groupId>com.github.xiaoymin</groupId>
+            <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
+            <version>4.4.0</version>
+        </dependency>
         <!-- spring-boot-devtools -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
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
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerProperties.java b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerProperties.java
new file mode 100644
index 0000000..3cb9cbc
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/core/config/SwaggerProperties.java
@@ -0,0 +1,63 @@
+package com.ruoyi.web.core.config;
+
+
+import jakarta.validation.constraints.NotEmpty;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+/**
+ * @author :yys
+ * @date : 2025/8/22 9:16
+ */
+
+
+
+/**
+ * Swagger 閰嶇疆灞炴��*/
+@ConfigurationProperties("aixin.swagger")
+@Data
+public class SwaggerProperties {
+
+    /**
+     * 鏍囬
+     */
+    @NotEmpty(message = "鏍囬涓嶈兘涓虹┖")
+    private String title;
+    /**
+     * 鎻忚堪
+     */
+    @NotEmpty(message = "鎻忚堪涓嶈兘涓虹┖")
+    private String description;
+    /**
+     * 浣滆��
+     */
+    @NotEmpty(message = "浣滆�呬笉鑳戒负绌�")
+    private String author;
+    /**
+     * 鐗堟湰
+     */
+    @NotEmpty(message = "鐗堟湰涓嶈兘涓虹┖")
+    private String version;
+    /**
+     * url
+     */
+    @NotEmpty(message = "鎵弿鐨� package 涓嶈兘涓虹┖")
+    private String url;
+    /**
+     * email
+     */
+    @NotEmpty(message = "鎵弿鐨� email 涓嶈兘涓虹┖")
+    private String email;
+
+    /**
+     * license
+     */
+    @NotEmpty(message = "鎵弿鐨� license 涓嶈兘涓虹┖")
+    private String license;
+
+    /**
+     * license-url
+     */
+    @NotEmpty(message = "鎵弿鐨� license-url 涓嶈兘涓虹┖")
+    private String licenseUrl;
+
+}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java
index 0f48b11..3900552 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/ResourcesConfig.java
@@ -55,6 +55,7 @@
     public CorsFilter corsFilter()
     {
         CorsConfiguration config = new CorsConfiguration();
+        config.setAllowCredentials(true);
         // 璁剧疆璁块棶婧愬湴鍧�
         config.addAllowedOriginPattern("*");
         // 璁剧疆璁块棶婧愯姹傚ご
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
index 330039f..2bece06 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
@@ -114,7 +114,7 @@
                 requests.requestMatchers("/login", "/register", "/captchaImage").permitAll()
                     // 闈欐�佽祫婧愶紝鍙尶鍚嶈闂�
                     .requestMatchers(HttpMethod.GET, "/", "/*.html", "/**.html", "/**.css", "/**.js", "/profile/**").permitAll()
-                    .requestMatchers("/swagger-ui.html", "/v3/api-docs/**", "/swagger-ui/**", "/druid/**").permitAll()
+                    .requestMatchers("/swagger-ui.html", "/v3/api-docs/**", "/swagger-ui/**","/swagger-resources", "/druid/**","/swagger-resources","/webjars/**", "/favicon.ico", "/doc.html").permitAll()
                     // 闄や笂闈㈠鐨勬墍鏈夎姹傚叏閮ㄩ渶瑕侀壌鏉冭璇�
                     .anyRequest().authenticated();
             })

--
Gitblit v1.9.3