Browse Source

feat:更新接口文档依赖

yangliu 3 months ago
parent
commit
69e630a3a8

+ 14 - 0
hfln-framework-design-starter/knife4j-doc-spring-boot-starter/src/main/java/cn/hfln/framework/knife4j/doc/configure/PropertiesAutoConfigure.java

@@ -0,0 +1,14 @@
+package cn.hfln.framework.knife4j.doc.configure;
+
+import cn.hfln.framework.knife4j.doc.properties.DocProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 配置属性自动配置类
+ * 确保 DocProperties 总是被创建
+ */
+@Configuration
+@EnableConfigurationProperties(DocProperties.class)
+public class PropertiesAutoConfigure {
+} 

+ 15 - 0
hfln-framework-design-starter/knife4j-doc-spring-boot-starter/src/main/java/cn/hfln/framework/knife4j/doc/gateway/GatewayAutoConfigure.java

@@ -0,0 +1,15 @@
+package cn.hfln.framework.knife4j.doc.gateway;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+/**
+ * 网关自动配置类
+ * 专门用于网关环境的配置
+ */
+@Configuration
+@ConditionalOnProperty(value = "lnxx.knife4j.doc.gateway.enable", havingValue = "true", matchIfMissing = false)
+@Import({GatewaySwaggerConfig.class, GatewaySwaggerController.class})
+public class GatewayAutoConfigure {
+} 

+ 39 - 0
hfln-framework-design-starter/knife4j-doc-spring-boot-starter/src/main/java/cn/hfln/framework/knife4j/doc/gateway/GatewaySwaggerConfig.java

@@ -0,0 +1,39 @@
+package cn.hfln.framework.knife4j.doc.gateway;
+
+import cn.hfln.framework.knife4j.doc.properties.DocProperties;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * 网关 Swagger 配置
+ * 用于在网关中提供 Swagger UI 和 API 文档聚合
+ */
+@Configuration
+@ConditionalOnProperty(value = "lnxx.knife4j.doc.gateway.enable", havingValue = "true", matchIfMissing = false)
+public class GatewaySwaggerConfig implements WebMvcConfigurer {
+
+    private final DocProperties docProperties;
+
+    public GatewaySwaggerConfig(DocProperties docProperties) {
+        this.docProperties = docProperties;
+    }
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+        // 配置 Swagger UI 静态资源
+        registry.addResourceHandler("/swagger-ui/**")
+                .addResourceLocations("classpath:/META-INF/resources/webjars/springdoc-openapi-ui/");
+        
+        // 配置 Knife4j 静态资源
+        registry.addResourceHandler("/webjars/**")
+                .addResourceLocations("classpath:/META-INF/resources/webjars/");
+    }
+
+    @Bean
+    public SwaggerAggregator swaggerAggregator() {
+        return new SwaggerAggregator(docProperties);
+    }
+} 

+ 40 - 0
hfln-framework-design-starter/knife4j-doc-spring-boot-starter/src/main/java/cn/hfln/framework/knife4j/doc/gateway/GatewaySwaggerController.java

@@ -0,0 +1,40 @@
+package cn.hfln.framework.knife4j.doc.gateway;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+/**
+ * 网关 Swagger 控制器
+ * 用于在网关中提供 Swagger 相关的 API 接口
+ */
+@RestController
+@RequestMapping("/v3/api-docs")
+@ConditionalOnProperty(value = "lnxx.knife4j.doc.gateway.enable", havingValue = "true", matchIfMissing = false)
+public class GatewaySwaggerController {
+
+    private static final Logger log = LoggerFactory.getLogger(GatewaySwaggerController.class);
+
+    private final SwaggerAggregator swaggerAggregator;
+
+    public GatewaySwaggerController(SwaggerAggregator swaggerAggregator) {
+        this.swaggerAggregator = swaggerAggregator;
+        log.info("=== GatewaySwaggerController 初始化 ===");
+    }
+
+    /**
+     * 获取 Swagger 配置
+     */
+    @GetMapping("/swagger-config")
+    public Map<String, Object> getSwaggerConfig() {
+        log.info("=== 处理 /v3/api-docs/swagger-config 请求 ===");
+        Map<String, Object> config = swaggerAggregator.getSwaggerConfig();
+        log.info("返回 swagger-config: {}", config);
+        return config;
+    }
+} 

+ 71 - 0
hfln-framework-design-starter/knife4j-doc-spring-boot-starter/src/main/java/cn/hfln/framework/knife4j/doc/gateway/Knife4jGatewayConfig.java

@@ -0,0 +1,71 @@
+package cn.hfln.framework.knife4j.doc.gateway;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.function.RouterFunction;
+import org.springframework.web.servlet.function.RouterFunctions;
+import org.springframework.web.servlet.function.ServerResponse;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Gateway 网关 Knife4j 聚合配置示例
+ * 支持 Servlet 和 WebFlux 环境
+ */
+@Configuration
+@ConditionalOnWebApplication
+@ConditionalOnProperty(value = "lnxx.knife4j.doc.gateway.enable", havingValue = "true", matchIfMissing = false)
+public class Knife4jGatewayConfig {
+
+    @Bean
+    public RouterFunction<ServerResponse> apiRouter() {
+        return RouterFunctions.route()
+                .GET("/v3/api-docs/swagger-config", request ->
+                        ServerResponse.ok().body(swaggerConfig()))
+                .build();
+    }
+
+    private Map<String, Object> swaggerConfig() {
+        Map<String, Object> config = new HashMap<>(8);
+        config.put("urls", buildServiceUrls());
+        return config;
+    }
+
+    private List<ServiceUrl> buildServiceUrls() {
+        List<ServiceUrl> serviceUrls = new ArrayList<>();
+        // 这里添加需要聚合的服务,实际项目中可以从注册中心动态获取
+        serviceUrls.add(new ServiceUrl("订单服务", "/portal-service-server/v3/api-docs"));
+        return serviceUrls;
+    }
+
+    public static class ServiceUrl {
+        private String name;
+        private String url;
+
+        public ServiceUrl(String name, String url) {
+            this.name = name;
+            this.url = url;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        public String getUrl() {
+            return url;
+        }
+
+        public void setUrl(String url) {
+            this.url = url;
+        }
+    }
+} 

+ 126 - 0
hfln-framework-design-starter/knife4j-doc-spring-boot-starter/src/main/java/cn/hfln/framework/knife4j/doc/gateway/SwaggerAggregator.java

@@ -0,0 +1,126 @@
+package cn.hfln.framework.knife4j.doc.gateway;
+
+import cn.hfln.framework.knife4j.doc.properties.DocProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Swagger 文档聚合器
+ * 用于在网关中聚合多个微服务的 API 文档
+ */
+@Component
+public class SwaggerAggregator {
+
+    private static final Logger log = LoggerFactory.getLogger(SwaggerAggregator.class);
+
+    private final DocProperties docProperties;
+
+    public SwaggerAggregator(DocProperties docProperties) {
+        this.docProperties = docProperties;
+        log.info("=== SwaggerAggregator 初始化 ===");
+        log.info("DocProperties.gateway: {}", docProperties.getGateway());
+        if (docProperties.getGateway() != null && docProperties.getGateway().getServices() != null) {
+            log.info("网关聚合服务数量: {}", docProperties.getGateway().getServices().size());
+            for (int i = 0; i < docProperties.getGateway().getServices().size(); i++) {
+                DocProperties.ServiceConfig service = docProperties.getGateway().getServices().get(i);
+                log.info("  [{}] 服务: name={}, url={}, description={}", 
+                    i, service.getName(), service.getUrl(), service.getDescription());
+            }
+        } else {
+            log.warn("未配置网关聚合服务");
+        }
+    }
+
+    /**
+     * 获取聚合的 Swagger 配置
+     */
+    public Map<String, Object> getSwaggerConfig() {
+        log.info("=== 构建 Swagger 聚合配置 ===");
+        Map<String, Object> config = new HashMap<>(8);
+        List<ServiceUrl> serviceUrls = buildServiceUrls();
+        config.put("urls", serviceUrls);
+        
+        log.info("聚合配置构建完成,分组数量: {}", serviceUrls.size());
+        for (int i = 0; i < serviceUrls.size(); i++) {
+            ServiceUrl serviceUrl = serviceUrls.get(i);
+            log.info("  [{}] 分组: name={}, url={}, description={}", 
+                i, serviceUrl.getName(), serviceUrl.getUrl(), serviceUrl.getDescription());
+        }
+        
+        return config;
+    }
+
+    /**
+     * 构建服务 URL 列表
+     * 直接使用配置文件中的 url,不做任何自动转换
+     */
+    private List<ServiceUrl> buildServiceUrls() {
+        log.info("=== 构建服务 URL 列表 ===");
+        List<ServiceUrl> serviceUrls = new ArrayList<>();
+        if (docProperties.getGateway() != null && docProperties.getGateway().getServices() != null) {
+            for (DocProperties.ServiceConfig serviceConfig : docProperties.getGateway().getServices()) {
+                ServiceUrl serviceUrl = new ServiceUrl(
+                    serviceConfig.getName(),
+                    serviceConfig.getUrl(),
+                    serviceConfig.getDescription()
+                );
+                serviceUrls.add(serviceUrl);
+                log.info("  添加服务分组: name={}, url={}", serviceConfig.getName(), serviceConfig.getUrl());
+            }
+        } else {
+            log.warn("docProperties.getGateway().getServices() 为空,无法构建服务列表");
+        }
+        log.info("服务 URL 列表构建完成,共 {} 个服务", serviceUrls.size());
+        return serviceUrls;
+    }
+
+    /**
+     * 服务 URL 信息
+     */
+    public static class ServiceUrl {
+        private String name;
+        private String url;
+        private String description;
+
+        public ServiceUrl(String name, String url) {
+            this.name = name;
+            this.url = url;
+        }
+
+        public ServiceUrl(String name, String url, String description) {
+            this.name = name;
+            this.url = url;
+            this.description = description;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        public String getUrl() {
+            return url;
+        }
+
+        public void setUrl(String url) {
+            this.url = url;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        public void setDescription(String description) {
+            this.description = description;
+        }
+    }
+} 

+ 64 - 0
hfln-framework-design-starter/mqtt-spring-boot-starter/src/main/java/cn/hfln/framework/mqtt/config/MqttSimpleAutoConfiguration.java

@@ -0,0 +1,64 @@
+package cn.hfln.framework.mqtt.config;
+
+import cn.hfln.framework.mqtt.converter.JsonMessageConverter;
+import cn.hfln.framework.mqtt.converter.MessageConverter;
+import cn.hfln.framework.mqtt.template.MqttTemplate;
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.paho.client.mqttv3.MqttClient;
+import org.eclipse.paho.client.mqttv3.MqttException;
+import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+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 java.util.Collections;
+import java.util.UUID;
+
+/**
+ * 简化的MQTT自动配置,用于调试
+ */
+@Slf4j
+@Configuration
+@EnableConfigurationProperties(MqttProperties.class)
+@ConditionalOnProperty(prefix = "mqtt", name = "enabled", havingValue = "true", matchIfMissing = true)
+@ConditionalOnClass(org.eclipse.paho.client.mqttv3.MqttClient.class)
+public class MqttSimpleAutoConfiguration {
+
+    private final MqttProperties mqttProperties;
+
+    public MqttSimpleAutoConfiguration(MqttProperties mqttProperties) {
+        this.mqttProperties = mqttProperties;
+        log.info("MqttSimpleAutoConfiguration initialized with broker: {}", mqttProperties.getBroker());
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    public MessageConverter messageConverter() {
+        log.info("Creating MessageConverter bean");
+        return new JsonMessageConverter();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    public MqttTemplate mqttTemplate() {
+        log.info("Creating simplified MqttTemplate bean");
+        try {
+            // 创建一个简单的MQTT客户端(不连接)
+            String clientId = mqttProperties.getClientId();
+            if (clientId == null || clientId.isEmpty()) {
+                clientId = "simple-mqtt-client-" + UUID.randomUUID();
+            }
+            
+            MqttClient mqttClient = new MqttClient(mqttProperties.getBroker(), clientId, new MemoryPersistence());
+            
+            // 创建MqttTemplate,但不强制连接
+            return new MqttTemplate(mqttClient, Collections.emptyList(), messageConverter());
+        } catch (MqttException e) {
+            log.error("Failed to create MqttTemplate", e);
+            throw new RuntimeException("Failed to create MqttTemplate", e);
+        }
+    }
+}