Преглед изворни кода

Merge branch 'data-zyj' into server-165

james пре 1 недеља
родитељ
комит
95e2632036
100 измењених фајлова са 5274 додато и 0 уклоњено
  1. 87 0
      data-gateway/data-gateway-eg-kat/pom.xml
  2. 43 0
      data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/ApplicationRun.java
  3. 20 0
      data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/domain/GatewayDeviceConfig.java
  4. 18 0
      data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/mapper/GatewayDeviceConfigMapper.java
  5. 50 0
      data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/config/mqtt/MqttBaseConfig.java
  6. 53 0
      data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/config/mqtt/MqttInConfig.java
  7. 84 0
      data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/config/mqtt/MqttOutConfig.java
  8. 19 0
      data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/config/udp/UdpBaseConfig.java
  9. 53 0
      data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/listener/MqttListener.java
  10. 22 0
      data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/mqtt/MqttStrategy.java
  11. 26 0
      data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/mqtt/SimpleContext.java
  12. 106 0
      data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/mqtt/control/control.java
  13. 54 0
      data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/mqtt/info/Info.java
  14. 22 0
      data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/utils/ByteUtil.java
  15. 54 0
      data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/utils/UdpUtil.java
  16. 21 0
      data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/vo/MqttBaseVO.java
  17. 34 0
      data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/vo/ProductMapVO.java
  18. 58 0
      data-gateway/data-gateway-eg-kat/src/main/resources/application.yml
  19. BIN
      data-gateway/data-gateway-eg-kat/src/main/resources/db/yt_gateway.db
  20. 108 0
      data-gateway/data-gateway-eg-kat/src/main/resources/doc/index.adoc
  21. 74 0
      data-gateway/data-gateway-eg-kat/src/main/resources/logback.xml
  22. 15 0
      data-gateway/data-gateway-eg-kat/src/main/resources/smart-doc.json
  23. 117 0
      data-gateway/data-gateway-vd-hik/pom.xml
  24. 44 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/DataGatewayVdHikApplicationRun.java
  25. 222 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/controller/api/HkVideoApi.java
  26. 103 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/controller/web/DeviceAlarmController.java
  27. 51 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/controller/web/HikThrowController.java
  28. 26 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/domain/HikThrow.java
  29. 21 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/mapper/HikThrowMapper.java
  30. 50 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/config/mqtt/MqttBaseConfig.java
  31. 53 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/config/mqtt/MqttInConfig.java
  32. 84 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/config/mqtt/MqttOutConfig.java
  33. 19 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/config/udp/UdpBaseConfig.java
  34. 62 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/listener/MqttListener.java
  35. 22 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/mqtt/MqttStrategy.java
  36. 28 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/mqtt/SimpleContext.java
  37. 80 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/mqtt/driverRecordControl/driverRecordControl.java
  38. 67 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/mqtt/parkRemainSpaceControl/parkRemainSpaceControl.java
  39. 84 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/mqtt/streamControl/streamControl.java
  40. 22 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/utils/ByteUtil.java
  41. 137 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/utils/HttpClientUtils.java
  42. 54 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/utils/UdpUtil.java
  43. 21 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/vo/MqttBaseVO.java
  44. 34 0
      data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/vo/ProductMapVO.java
  45. 53 0
      data-gateway/data-gateway-vd-hik/src/main/resources/application.yml
  46. BIN
      data-gateway/data-gateway-vd-hik/src/main/resources/db/yt_hik.db
  47. 108 0
      data-gateway/data-gateway-vd-hik/src/main/resources/doc/index.adoc
  48. 74 0
      data-gateway/data-gateway-vd-hik/src/main/resources/logback.xml
  49. 15 0
      data-gateway/data-gateway-vd-hik/src/main/resources/smart-doc.json
  50. 17 0
      data-gateway/pom.xml
  51. 29 0
      data-transfer/data-transfer-api/pom.xml
  52. 28 0
      data-transfer/data-transfer-api/src/main/java/com/usky/transfer/RemoteTransferService.java
  53. 41 0
      data-transfer/data-transfer-api/src/main/java/com/usky/transfer/domain/DeviceDataInfoVO.java
  54. 43 0
      data-transfer/data-transfer-api/src/main/java/com/usky/transfer/domain/DeviceDataWriteVO.java
  55. 30 0
      data-transfer/data-transfer-api/src/main/java/com/usky/transfer/domain/HistoryRequestVO.java
  56. 19 0
      data-transfer/data-transfer-api/src/main/java/com/usky/transfer/domain/HistoryResultVO.java
  57. 20 0
      data-transfer/data-transfer-api/src/main/java/com/usky/transfer/domain/LastRequestVO.java
  58. 20 0
      data-transfer/data-transfer-api/src/main/java/com/usky/transfer/domain/LastResultVO.java
  59. 20 0
      data-transfer/data-transfer-api/src/main/java/com/usky/transfer/domain/MetricVO.java
  60. 44 0
      data-transfer/data-transfer-api/src/main/java/com/usky/transfer/factory/RemoteTransferFallbackFactory.java
  61. 112 0
      data-transfer/data-transfer-biz/pom.xml
  62. 51 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/ApplicationRun.java
  63. 107 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/MybatisGenerator.java
  64. 35 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/controller/api/DataTransferControllerApi.java
  65. 212 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/controller/web/QueryDeviceDataController.java
  66. 31 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/controller/web/SendMessageController.java
  67. 141 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/domain/DmpDevice.java
  68. 96 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/domain/DmpDeviceCommand.java
  69. 61 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/domain/DmpDeviceStatus.java
  70. 141 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/domain/DmpProduct.java
  71. 27 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/domain/QueryInfluxdbData.java
  72. 16 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/mapper/DmpDeviceCommandMapper.java
  73. 16 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/mapper/DmpDeviceMapper.java
  74. 19 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/mapper/DmpDeviceStatusMapper.java
  75. 16 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/mapper/DmpProductMapper.java
  76. 16 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/mapper/QueryInfluxdbDataMapper.java
  77. 19 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/DmpDeviceCommandService.java
  78. 16 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/DmpDeviceService.java
  79. 16 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/DmpDeviceStatusService.java
  80. 24 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/DmpProductService.java
  81. 23 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/QueryInfluxdbDataService.java
  82. 12 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/config/CodeCache.java
  83. 57 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/config/TsdbConfig.java
  84. 50 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/config/mqtt/MqttBaseConfig.java
  85. 56 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/config/mqtt/MqttInConfig.java
  86. 84 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/config/mqtt/MqttOutConfig.java
  87. 60 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/enums/TopListener.java
  88. 42 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/impl/DmpDeviceCommandServiceImpl.java
  89. 20 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/impl/DmpDeviceServiceImpl.java
  90. 22 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/impl/DmpDeviceStatusServiceImpl.java
  91. 97 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/impl/DmpProductServiceImpl.java
  92. 245 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/impl/QueryInfluxdbDataServiceImpl.java
  93. 60 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/listener/MqttListener.java
  94. 21 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/mqtt/MqttStrategy.java
  95. 26 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/mqtt/SimpleContext.java
  96. 53 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/mqtt/control/control.java
  97. 73 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/mqtt/info/Info.java
  98. 21 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/rocketmq/MyConsumer.java
  99. 17 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/rocketmq/MyProducer.java
  100. 80 0
      data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/rocketmq/RocketMQSimpleContext.java

+ 87 - 0
data-gateway/data-gateway-eg-kat/pom.xml

@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>data-gateway</artifactId>
+        <groupId>com.usky</groupId>
+        <version>0.0.1</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>data-gateway-eg-kat</artifactId>
+    <dependencies>
+        <!--MQTT依赖-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-integration</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.integration</groupId>
+            <artifactId>spring-integration-mqtt</artifactId>
+            <optional>true</optional>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>com.usky</groupId>-->
+<!--            <artifactId>common-cloud-starter</artifactId>-->
+<!--        </dependency>-->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-openfeign-core</artifactId>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>com.usky</groupId>-->
+<!--            <artifactId>usky-common-core</artifactId>-->
+<!--        </dependency>-->
+
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+
+        <!--udp-->
+        <dependency>
+            <groupId>org.springframework.integration</groupId>
+            <artifactId>spring-integration-ip</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <!-- sqlite3驱动包 -->
+        <dependency>
+            <groupId>org.xerial</groupId>
+            <artifactId>sqlite-jdbc</artifactId>
+            <version>3.42.0.1</version>
+        </dependency>
+        <!--mybatis-plus插件-->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.5.5</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.2.6.RELEASE</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 43 - 0
data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/ApplicationRun.java

@@ -0,0 +1,43 @@
+package com.usky.gateway;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.core.env.Environment;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * 应用启动模块
+ * 
+ */
+
+
+@EnableFeignClients(basePackages = "com.usky")
+@ComponentScan("com.usky")
+@SpringBootApplication
+public class ApplicationRun
+{
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationRun.class);
+
+    public static void main(String[] args) throws UnknownHostException {
+        ConfigurableApplicationContext application = SpringApplication.run(ApplicationRun.class, args);
+        Environment env = application.getEnvironment();
+        String ip = InetAddress.getLocalHost().getHostAddress();
+        String port = env.getProperty("server.port");
+        String path = env.getProperty("server.servlet.context-path");
+        LOGGER.info("\n----------------------------------------------------------\n\t" +
+                "Application is running! Access URLs:\n\t" +
+                "Local: \t\thttp://localhost:" + port + (null==path?"":path) + "/\n\t" +
+                "External: \thttp://" + ip + ":" + port + (null==path?"":path) + "/\n\t" +
+                "Api: \t\thttp://" + ip + ":" + port + (null==path?"":path) + "/swagger-ui/index.html\n\t" +
+                "----------------------------------------------------------");
+    }
+}

+ 20 - 0
data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/domain/GatewayDeviceConfig.java

@@ -0,0 +1,20 @@
+package com.usky.gateway.domain;
+
+import lombok.Data;
+
+@Data
+public class GatewayDeviceConfig {
+
+    private String productCode;
+
+    private String deviceId;
+
+    private String ip;
+    private String port;
+
+    private String param1;
+    private String param2;
+    private String param3;
+    private String param4;
+    private String param5;
+}

+ 18 - 0
data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/mapper/GatewayDeviceConfigMapper.java

@@ -0,0 +1,18 @@
+package com.usky.gateway.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.usky.gateway.domain.GatewayDeviceConfig;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * <p>
+ * 用户信息表 Mapper 接口
+ * </p>
+ *
+ * @since 2022-04-21
+ */
+@Repository
+@Mapper
+public interface GatewayDeviceConfigMapper extends BaseMapper<GatewayDeviceConfig> {}  // 结合mybatis plus
+

+ 50 - 0
data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/config/mqtt/MqttBaseConfig.java

@@ -0,0 +1,50 @@
+package com.usky.gateway.service.config.mqtt;
+
+import lombok.Data;
+import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
+import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
+import org.springframework.stereotype.Component;
+
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+@Data
+@Component
+@ConfigurationProperties(prefix = "mqtt")
+public class MqttBaseConfig {
+
+	@Value("${mqtt.username}")
+	private String username;
+
+	@Value("${mqtt.password}")
+	private String password;
+
+	@Value("${mqtt.url}")
+	private String hostUrl;
+
+	@Value("${mqtt.sub-topics}")
+	private String msgTopic;
+
+	@Value("${mqtt.keep-alive-interval}")
+	//心跳间隔
+	private int keepAliveInterval;
+	@Value("${mqtt.completionTimeout}")
+	//心跳间隔
+	private int completionTimeout;
+
+
+	@Bean
+	public MqttPahoClientFactory mqttClientFactory() {
+		DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
+		MqttConnectOptions options = new MqttConnectOptions();
+		options.setServerURIs(new String[]{this.getHostUrl()});
+		options.setUserName(this.getUsername());
+		options.setPassword(this.getPassword().toCharArray());
+		factory.setConnectionOptions(options);
+		return factory;
+	}
+
+}

+ 53 - 0
data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/config/mqtt/MqttInConfig.java

@@ -0,0 +1,53 @@
+package com.usky.gateway.service.config.mqtt;
+
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.integration.channel.DirectChannel;
+import org.springframework.integration.core.MessageProducer;
+import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
+import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
+import org.springframework.messaging.MessageChannel;
+
+import java.util.List;
+
+/**
+ * @author yq
+ * @date 2021/11/1 16:37
+ */
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+@Configuration
+public class MqttInConfig {
+
+    @Autowired
+    private MqttBaseConfig mqttBaseConfig;
+
+    public static final String CHANNEL_NAME_INPUT = "mqttInputChannel";
+
+    @Bean(name = CHANNEL_NAME_INPUT)
+    public MessageChannel mqttInputChannel() {
+        return new DirectChannel();
+    }
+
+
+    /**
+     * 消息订阅绑定-消费者
+     *
+     * @return
+     */
+    @Bean
+    public MessageProducer inbound() {
+        String[] tops = mqttBaseConfig.getMsgTopic().split(",");
+        String clientId = "gateway-eg-kat-mqtt-in-" + System.currentTimeMillis();
+        MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(clientId,
+                mqttBaseConfig.mqttClientFactory(), tops);
+        adapter.setCompletionTimeout(mqttBaseConfig.getCompletionTimeout());
+        adapter.setConverter(new DefaultPahoMessageConverter());
+        adapter.setQos(2);
+        adapter.setOutputChannel(mqttInputChannel());
+        return adapter;
+    }
+}

+ 84 - 0
data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/config/mqtt/MqttOutConfig.java

@@ -0,0 +1,84 @@
+package com.usky.gateway.service.config.mqtt;
+
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.integration.annotation.MessagingGateway;
+import org.springframework.integration.annotation.ServiceActivator;
+import org.springframework.integration.channel.DirectChannel;
+import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
+import org.springframework.integration.mqtt.support.MqttHeaders;
+import org.springframework.messaging.MessageChannel;
+import org.springframework.messaging.MessageHandler;
+import org.springframework.messaging.handler.annotation.Header;
+
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+@Configuration
+public class MqttOutConfig {
+
+    @Autowired
+    public MqttBaseConfig mqttBaseConfig;
+
+    public static final String CHANNEL_NAME_OUT = "mqttOutboundChannel";
+
+    public static final String MESSAGE_NAME = "messageOut";
+
+    public static final String DEFAULT_TOPIC = "testTopic";
+
+    /**
+     * 连接通道
+     *
+     * @return
+     */
+    @Bean(name = CHANNEL_NAME_OUT)
+    public MessageChannel mqttOutboundChannel() {
+        return new DirectChannel();
+    }
+
+    /**
+     * 发送消息和消费消息Channel可以使用相同MqttPahoClientFactory
+     *
+     * @return
+     */
+    @Bean(name = MESSAGE_NAME)
+    @ServiceActivator(inputChannel = CHANNEL_NAME_OUT)
+    public MessageHandler outbound() {
+        // 在这里进行mqttOutboundChannel的相关设置
+        String clientId = "gateway-eg-kat-mqtt-out-" + System.currentTimeMillis();
+        MqttPahoMessageHandler messageHandler =
+                new MqttPahoMessageHandler(clientId, mqttBaseConfig.mqttClientFactory());
+        //如果设置成true,发送消息时将不会阻塞。
+        messageHandler.setAsync(true);
+        messageHandler.setDefaultTopic(DEFAULT_TOPIC);
+        return messageHandler;
+    }
+
+    @MessagingGateway(defaultRequestChannel = CHANNEL_NAME_OUT)
+    public interface MqttGateway {
+        /**
+         * 发送消息
+         *
+         * @param payload
+         */
+        void sendToMqtt(String payload);
+
+        /**
+         * 指定top发送消息
+         *
+         * @param topic
+         * @param payload
+         */
+        void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, String payload);
+
+        /**
+         * 指定队列和qos
+         *
+         * @param topic
+         * @param qos
+         * @param payload
+         */
+        void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload);
+    }
+}

+ 19 - 0
data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/config/udp/UdpBaseConfig.java

@@ -0,0 +1,19 @@
+package com.usky.gateway.service.config.udp;
+
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@ConditionalOnProperty(prefix = "udp", value = {"enabled"}, havingValue = "true")
+@Data
+@Component
+@ConfigurationProperties(prefix = "udp")
+public class UdpBaseConfig {
+    @Value("${udp.deviceIp}")
+    private String deviceIp;
+
+    @Value("${udp.sendingPort}")
+    private Integer sendingPort;
+}

+ 53 - 0
data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/listener/MqttListener.java

@@ -0,0 +1,53 @@
+package com.usky.gateway.service.listener;
+
+
+import com.usky.gateway.service.config.mqtt.MqttInConfig;
+import com.usky.gateway.service.mqtt.SimpleContext;
+import com.usky.gateway.service.vo.MqttBaseVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.integration.annotation.ServiceActivator;
+import org.springframework.messaging.MessageHandler;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author yq
+ * @date 2021/11/3 8:13
+ */
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+@Slf4j
+@Component
+public class MqttListener {
+
+    public static final String MESSAGE_NAME = "messageInput";
+
+    @Autowired
+    private SimpleContext simpleContext;
+
+    /**
+     * 处理消息-消费者
+     *
+     * @return
+     */
+    @Bean(MESSAGE_NAME)
+    @ServiceActivator(inputChannel = MqttInConfig.CHANNEL_NAME_INPUT)
+    public MessageHandler handler() {
+        return message -> {
+            String payload = message.getPayload().toString();
+            Object mqttReceivedTopic = message.getHeaders().get("mqtt_receivedTopic");
+            if (null != mqttReceivedTopic) {
+                String topic = mqttReceivedTopic.toString();
+                MqttBaseVO mqttBaseVO = new MqttBaseVO();
+                mqttBaseVO.setTopic(topic);
+                if (topic.indexOf("control") != -1 ) {
+                    mqttBaseVO.setDescribe("control");
+                    mqttBaseVO.setData(payload);
+                }
+                //统一处理数据
+                simpleContext.getResource(mqttBaseVO);
+            }
+        };
+    }
+}

+ 22 - 0
data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/mqtt/MqttStrategy.java

@@ -0,0 +1,22 @@
+package com.usky.gateway.service.mqtt;
+
+
+import com.usky.gateway.service.vo.MqttBaseVO;
+
+
+/**
+ * 策略类
+ *
+ * @author yq
+ * @date 2021/11/3 8:27
+ */
+public interface MqttStrategy {
+    /**
+     * 处理消息(策略模式由子类实现)
+     *
+     * @param mqttBaseVO
+     * @return
+     */
+    String disposeMessage(MqttBaseVO mqttBaseVO) ;
+
+}

+ 26 - 0
data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/mqtt/SimpleContext.java

@@ -0,0 +1,26 @@
+package com.usky.gateway.service.mqtt;
+
+
+import com.usky.gateway.service.vo.MqttBaseVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 中间处理消息转发
+ */
+@Service
+public class SimpleContext {
+    @Autowired
+    private final Map<String, MqttStrategy> strategyMap = new ConcurrentHashMap<>();
+
+    public SimpleContext(Map<String, MqttStrategy> strategyMap) {
+        strategyMap.forEach(this.strategyMap::put);
+    }
+
+    public String getResource(MqttBaseVO mqttBaseVO) {
+        return strategyMap.get(mqttBaseVO.getDescribe()).disposeMessage(mqttBaseVO);
+    }
+}

+ 106 - 0
data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/mqtt/control/control.java

@@ -0,0 +1,106 @@
+package com.usky.gateway.service.mqtt.control;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.gateway.domain.GatewayDeviceConfig;
+import com.usky.gateway.mapper.GatewayDeviceConfigMapper;
+import com.usky.gateway.service.config.mqtt.MqttOutConfig;
+import com.usky.gateway.service.config.udp.UdpBaseConfig;
+import com.usky.gateway.service.mqtt.MqttStrategy;
+import com.usky.gateway.service.utils.ByteUtil;
+import com.usky.gateway.service.utils.UdpUtil;
+import com.usky.gateway.service.vo.MqttBaseVO;
+import feign.form.util.CharsetUtil;
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+@Service("control")
+@Configuration
+@Data
+public class control implements MqttStrategy {
+//    @Value("${udp.deviceIp}")
+//    private String deviceIp;
+//
+//    @Value("${udp.sendingPort}")
+//    private Integer sendingPort;
+
+    @Autowired
+    private UdpUtil udpUtil;
+    @Autowired
+    private ByteUtil byteUtil;
+    @Resource
+    private MqttOutConfig.MqttGateway mqttGateway;
+
+    @Autowired
+    private GatewayDeviceConfigMapper gatewayDeviceConfigMapper;
+
+    //处理下发命令消息,下发命令控制设备
+    public String disposeMessage(MqttBaseVO mqttBaseVO) {
+        String[] topics = mqttBaseVO.getTopic().split("/");
+        String productCode = topics[1];
+        JSONObject obj_data = JSONObject.parseObject(mqttBaseVO.getData().toString());
+        Integer commandId = Integer.parseInt(obj_data.get("id").toString());
+        Object params = JSONObject.toJSONString(obj_data.get("params"));
+        JSONObject params_data = JSON.parseObject(params.toString());
+        String deviceId = params_data.getString("deviceId");
+        String commandCode = params_data.getString("commandCode");
+        String commandValue = params_data.getString("commandValue");
+
+        //开门   17 40 00 00 E0 F4 4D 0D 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+        if(commandCode.equals("door_onoff")){
+            //通过查询db文件获取对应udpIp udpPort 目标设备id 门号
+            LambdaQueryWrapper<GatewayDeviceConfig> queryWrapper = Wrappers.lambdaQuery();
+            queryWrapper.select(GatewayDeviceConfig::getIp,GatewayDeviceConfig::getPort,GatewayDeviceConfig::getParam1,GatewayDeviceConfig::getParam2)
+                    .eq(GatewayDeviceConfig::getProductCode,productCode)
+                    .eq(GatewayDeviceConfig::getDeviceId,deviceId);
+            GatewayDeviceConfig one = gatewayDeviceConfigMapper.selectOne(queryWrapper);
+            if(one != null){
+                String devId = one.getParam1();
+                byte[] deviceByte = byteUtil.toLH(Integer.parseInt(devId));
+                int doorNum = Integer.parseInt(one.getParam2());
+                byte bDoorNum = (byte)doorNum;
+                byte[] requestBytes = new byte[] { 0x17, 0x40, 0x00, 0x00, deviceByte[0], deviceByte[1], deviceByte[2], deviceByte[3], bDoorNum, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+                byteUtil.printBytes(requestBytes);
+                String responseData = udpUtil.sendUDPRequest(one.getIp(), Integer.parseInt(one.getPort()), requestBytes);
+
+                //推送下发命令响应mqtt
+                JSONObject jsonObject = new JSONObject();
+                byte[] responseByte = responseData.getBytes(Charset.forName("ISO-8859-1"));  //"US-ASCII"
+                byteUtil.printBytes(responseByte);
+
+                if(responseByte[8] == 0x01){
+                    jsonObject.put("result","success");
+
+                }else{
+                    JSONObject obj1 = new JSONObject();
+                    obj1.put("code",-1);
+                    obj1.put("message","open failed");
+                    jsonObject.put("error",obj1);
+
+                }
+
+                jsonObject.put("timeStamp",System.currentTimeMillis());
+                jsonObject.put("id",commandId);
+
+                String res_topic = mqttBaseVO.getTopic().replace("control","controlResponse");
+                mqttGateway.sendToMqtt(res_topic,jsonObject.toJSONString());
+            }
+        }
+
+
+        return null;
+    }
+
+
+}

+ 54 - 0
data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/mqtt/info/Info.java

@@ -0,0 +1,54 @@
+package com.usky.gateway.service.mqtt.info;
+
+import com.usky.gateway.service.mqtt.MqttStrategy;
+import com.usky.gateway.service.vo.MqttBaseVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author zyj
+ * @date 2022/12/6 15:07
+ */
+@Service("info")
+public class Info implements MqttStrategy {
+//    @Resource
+//    private MyProducer myProducer;
+//    @Autowired
+//    private QueryInfluxdbDataService queryInfluxdbDataService;
+//
+    public String disposeMessage(MqttBaseVO mqttBaseVO) {
+//        Map<String, Object> tags = new HashMap<>();
+//        Map<String, Object> fields = new HashMap<>();
+//        Map map_data = JsonUtils.fromJson(mqttBaseVO.getData().toString(), Map.class);
+//        String deviceId = map_data.get("device_id").toString();
+//        String productCode = map_data.get("product_code").toString().toLowerCase();
+//        Long timestamp = Long.valueOf(map_data.get("timestamp").toString());
+//
+//        String tableName = deviceId;
+//
+//        Object tg = JSONObject.toJSONString(map_data.get("tags"));
+//        JSONObject tag = JSON.parseObject(tg.toString());
+//        for (String entry : tag.keySet()){
+//            tags.put(entry.toLowerCase(),tag.get(entry).toString());
+//        }
+//
+//        Object met = JSONObject.toJSONString(map_data.get("metrics"));
+//        JSONObject metrics = JSON.parseObject(met.toString());
+//        for(String entry : metrics.keySet()){
+//            fields.put(entry.toLowerCase(),metrics.get(entry));
+//        }
+//
+//        DeviceDataWriteVO deviceDataWriteVO = new DeviceDataWriteVO();
+//        deviceDataWriteVO.setDeviceId(deviceId);
+//        deviceDataWriteVO.setProductCode(productCode);
+//        deviceDataWriteVO.setTimestamp(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
+//        deviceDataWriteVO.setTags(tags);
+//        deviceDataWriteVO.setMetrics(metrics);
+//
+//        queryInfluxdbDataService.sendDeviceDataToMQ(deviceDataWriteVO);
+//
+        return null;
+    }
+
+
+}

+ 22 - 0
data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/utils/ByteUtil.java

@@ -0,0 +1,22 @@
+package com.usky.gateway.service.utils;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class ByteUtil {
+    public byte[] toLH(int n) {
+        byte[] b = new byte[4];
+        b[0] = (byte) (n & 0xff);
+        b[1] = (byte) (n >> 8 & 0xff);
+        b[2] = (byte) (n >> 16 & 0xff);
+        b[3] = (byte) (n >> 24 & 0xff);
+        return b;
+    }
+
+    // 打印字节数组的十六进制表示
+    public void printBytes(byte[] bytes) {
+        for (byte b : bytes) {
+            System.out.print(Integer.toHexString(b & 0xFF).toUpperCase() + " ");
+        }
+    }
+}

+ 54 - 0
data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/utils/UdpUtil.java

@@ -0,0 +1,54 @@
+package com.usky.gateway.service.utils;
+
+import feign.form.util.CharsetUtil;
+import org.springframework.stereotype.Component;
+
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.nio.charset.Charset;
+
+
+@Component
+public class UdpUtil {
+
+    /**
+     * 发送UDP请求并打印返回结果
+     *
+     * @param requestBytes 要发送的自定义命令
+     */
+    public static String sendUDPRequest(String host, int port, byte[] requestBytes) {
+        try {
+            // 创建DatagramSocket随机端口
+            DatagramSocket socket = new DatagramSocket();
+
+            // 创建InetAddress对象
+            InetAddress address = InetAddress.getByName(host);
+
+            // 创建DatagramPacket,包含发送的数据和目的地
+            DatagramPacket OutPacket = new DatagramPacket(requestBytes, requestBytes.length, address, port);
+
+            // 发送DatagramPacket
+            socket.send(OutPacket);
+
+            // 创建一个DatagramPacket来接收响应,大小与发送的数据包相同
+            DatagramPacket inPacket = new DatagramPacket(requestBytes, requestBytes.length);
+
+            // 接收响应
+            socket.receive(inPacket);
+
+            // 打印接收到的数据
+            String receivedData = new String(inPacket.getData(), 0, inPacket.getLength(), Charset.forName("ISO-8859-1"));
+            System.out.println("接收到的响应: " + receivedData+ ": ");
+
+            // 关闭socket
+            socket.close();
+
+            return receivedData;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+}

+ 21 - 0
data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/vo/MqttBaseVO.java

@@ -0,0 +1,21 @@
+package com.usky.gateway.service.vo;
+
+import lombok.Data;
+
+/**
+ * @author yq
+ * @date 2021/11/3 8:32
+ */
+@Data
+public class MqttBaseVO {
+    /**
+     * 接口描述
+     */
+    private String describe;
+
+    private String topic;
+    /**
+     * 数据内容
+      */
+    private Object data;
+}

+ 34 - 0
data-gateway/data-gateway-eg-kat/src/main/java/com/usky/gateway/service/vo/ProductMapVO.java

@@ -0,0 +1,34 @@
+package com.usky.gateway.service.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class ProductMapVO implements Serializable {
+    /**
+     * 产品ID
+     */
+    private Integer productId;
+
+    /**
+     * 产品编码
+     */
+    private String productCode;
+
+    /**
+     * 创建人
+     */
+    private String createdBy;
+
+    /**
+     * 租户号
+     */
+    private Integer tenantId;
+
+    /**
+     * 设备类型
+     */
+    private Integer deviceType;
+
+}

+ 58 - 0
data-gateway/data-gateway-eg-kat/src/main/resources/application.yml

@@ -0,0 +1,58 @@
+# Tomcat
+server:
+#  port: 21000
+  port: 21001
+  servlet:
+    context-path: /data-gateway
+spring:
+  application:
+    # 应用名称
+    name: agbox-energy
+  cache:
+    ehcache:
+      config: classpath:ehcache.xml
+      enabled: false
+    redis:
+      enabled: true
+  jackson:
+    date-format: yyyy-MM-dd HH:mm:ss
+    default-property-inclusion: always
+    deserialization:
+      fail-on-unknown-properties: false
+    parser:
+      allow-single-quotes: true
+      allow-unquoted-control-chars: true
+    serialization:
+      fail-on-empty-beans: false
+    time-zone: GMT+8
+  tenant:
+    enable: false
+  servlet:
+    multipart:
+      max-file-size: 10MB
+      max-request-size: 15MB
+  datasource:
+    name: sqlite3
+    url: jdbc:sqlite::resource:db/yt_gateway.db
+    driver-class-name: org.sqlite.JDBC
+    username:
+    password:
+
+temp:
+  basedir: C:/Users/pc/Desktop/
+mqtt:
+  completionTimeout: 5000
+  enabled: true
+  keep-alive-interval: 60
+#  password: public
+#  sub-topics: /502_KAT/+/control
+#  url: tcp://192.168.123.165:1883
+#  username: admin
+  password: usky
+  sub-topics: /502_KAT/+/control
+  url: tcp://47.98.201.73:1883
+  username: usky
+# 和嵌入式udp通信的发送端口和监听端口地址
+#udp:
+#  deviceIp: 192.168.123.44
+#  sendingPort: 60000

BIN
data-gateway/data-gateway-eg-kat/src/main/resources/db/yt_gateway.db


+ 108 - 0
data-gateway/data-gateway-eg-kat/src/main/resources/doc/index.adoc

@@ -0,0 +1,108 @@
+= 安防项目
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Version |  Update Time  | Status | Author |  Description
+|v2022-04-21 16:57:08|2022-04-21 16:57:08|auto|@yq|Created by smart-doc
+|====================
+
+
+== &lt;p&gt;参数配置表 前端控制器&lt;/p&gt;
+== &lt;p&gt;部门信息&lt;/p&gt;
+=== 查看部门信息
+*URL:* http:10.23.39.1:8082/sysDept/list
+
+*Type:* POST
+
+*Author:* ya
+
+*Content-Type:* application/json; charset=utf-8
+
+
+
+
+*Body-parameters:*
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Parameter | Type|Description|Required|Since
+|deptId|int64|部门id|false|-
+|parentId|int64|父部门id|false|-
+|ancestors|string|祖级列表|false|-
+|deptName|string|部门名称|false|-
+|orderNum|int32|显示顺序|false|-
+|leader|string|负责人|false|-
+|phone|string|联系电话|false|-
+|email|string|邮箱|false|-
+|status|string|部门状态(0正常 1停用)|false|-
+|delFlag|string|删除标志(0代表存在 2代表删除)|false|-
+|createBy|string|创建者|false|-
+|createTime|string|创建时间|false|-
+|updateBy|string|更新者|false|-
+|updateTime|string|更新时间|false|-
+|bId|int64|建筑id|false|-
+|====================
+
+*Response-fields:*
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Field | Type|Description|Since
+|status|object|No comments found.|-
+|code|string|No comments found.|-
+|msg|string|No comments found.|-
+|data|object|No comments found.|-
+|└─deptId|int64|部门id|-
+|└─parentId|int64|父部门id|-
+|└─ancestors|string|祖级列表|-
+|└─deptName|string|部门名称|-
+|└─orderNum|int32|显示顺序|-
+|└─leader|string|负责人|-
+|└─phone|string|联系电话|-
+|└─email|string|邮箱|-
+|└─status|string|部门状态(0正常 1停用)|-
+|└─delFlag|string|删除标志(0代表存在 2代表删除)|-
+|└─createBy|string|创建者|-
+|└─createTime|string|创建时间|-
+|└─updateBy|string|更新者|-
+|└─updateTime|string|更新时间|-
+|└─bId|int64|建筑id|-
+|exception|string|No comments found.|-
+|====================
+
+*Response-example:*
+----
+{
+	"status": {
+		
+	},
+	"code": "97564",
+	"msg": "wnr5qt",
+	"data": [
+		{
+			"deptId": 540,
+			"parentId": 858,
+			"ancestors": "o5lg60",
+			"deptName": "文.沈",
+			"orderNum": 260,
+			"leader": "ufz93p",
+			"phone": "17852835049",
+			"email": "智渊.徐@yahoo.com",
+			"status": "nu6cnp",
+			"delFlag": "72oiji",
+			"createBy": "5fxr6j",
+			"createTime": "2022-04-21 16:57:10",
+			"updateBy": "4kcs4e",
+			"updateTime": "2022-04-21 16:57:10",
+			"bId": 977
+		}
+	],
+	"exception": "53u6bg"
+}
+----
+
+== &lt;p&gt;用户信息表 前端控制器&lt;/p&gt;
+

+ 74 - 0
data-gateway/data-gateway-eg-kat/src/main/resources/logback.xml

@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="60 seconds" debug="false">
+    <!-- 日志存放路径 -->
+	<property name="log.path" value="/var/log/uskycloud/usky-demo" />
+   <!-- 日志输出格式 -->
+	<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
+
+    <!-- 控制台输出 -->
+	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+	</appender>
+
+    <!-- 系统日志输出 -->
+	<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+	    <file>${log.path}/info.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+			<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>60</maxHistory>
+		</rollingPolicy>
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>INFO</level>
+            <!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+	</appender>
+
+    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+	    <file>${log.path}/error.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+            <fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>ERROR</level>
+			<!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+			<!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 系统模块日志级别控制  -->
+	<logger name="com.usky" level="info" />
+	<!-- Spring日志级别控制  -->
+	<logger name="org.springframework" level="warn" />
+
+	<root level="info">
+		<appender-ref ref="console" />
+	</root>
+	
+	<!--系统操作日志-->
+    <root level="info">
+        <appender-ref ref="file_info" />
+        <appender-ref ref="file_error" />
+    </root>
+</configuration>

+ 15 - 0
data-gateway/data-gateway-eg-kat/src/main/resources/smart-doc.json

@@ -0,0 +1,15 @@
+{
+  "outPath":"./src/main/resources/doc",
+  "serverUrl": "http:10.23.39.1:8082/",
+  "isStrict": false,
+  "coverOld": true,
+  "allInOne": true,
+  "packageFilters": "com.usky.demo.controller.web",
+  "requestExample":"false",
+  "responseExample":"true",
+  "projectName": "安防项目",
+  "appKey": "20211216921084883495813120",
+  "appToken":"36bde2426ad546a5a50311bb747e7e61",
+  "secret": "N@Pd,KXAHki*BW3=zK.XPNykf!=CM79J",
+  "openUrl": "http://101.133.214.75:7700/api"
+}

+ 117 - 0
data-gateway/data-gateway-vd-hik/pom.xml

@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>data-gateway</artifactId>
+        <groupId>com.usky</groupId>
+        <version>0.0.1</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>data-gateway-vd-hik</artifactId>
+    <dependencies>
+        <!--MQTT依赖-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-integration</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.integration</groupId>
+            <artifactId>spring-integration-mqtt</artifactId>
+            <optional>true</optional>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>com.usky</groupId>-->
+<!--            <artifactId>common-cloud-starter</artifactId>-->
+<!--        </dependency>-->
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-openfeign-core</artifactId>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>com.usky</groupId>-->
+<!--            <artifactId>usky-common-core</artifactId>-->
+<!--        </dependency>-->
+
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.usky</groupId>
+            <artifactId>ruoyi-common-swagger</artifactId>
+        </dependency>
+
+        <!--udp-->
+        <dependency>
+            <groupId>org.springframework.integration</groupId>
+            <artifactId>spring-integration-ip</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.boot</groupId>-->
+<!--            <artifactId>spring-boot-starter-test</artifactId>-->
+<!--            <scope>test</scope>-->
+<!--        </dependency>-->
+        <!-- Pagehelper -->
+<!--        <dependency>-->
+<!--            <groupId>com.github.pagehelper</groupId>-->
+<!--            <artifactId>pagehelper-spring-boot-starter</artifactId>-->
+<!--        </dependency>-->
+        <dependency>
+            <groupId>com.hikvision.ga</groupId>
+            <artifactId>artemis-http-client</artifactId>
+            <version>1.1.3</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>ch.qos.logback</groupId>
+                    <artifactId>logback-core</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>ch.qos.logback</groupId>
+                    <artifactId>logback-classic</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <!-- sqlite3驱动包 -->
+        <dependency>
+            <groupId>org.xerial</groupId>
+            <artifactId>sqlite-jdbc</artifactId>
+            <version>3.42.0.1</version>
+        </dependency>
+        <!--mybatis-plus插件-->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>3.5.5</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.2.6.RELEASE</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 44 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/DataGatewayVdHikApplicationRun.java

@@ -0,0 +1,44 @@
+package com.usky.hik;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.core.env.Environment;
+import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * 应用启动模块
+ * 
+ */
+
+@EnableCustomSwagger2
+@EnableFeignClients(basePackages = "com.usky")
+@ComponentScan("com.usky")
+@SpringBootApplication
+public class DataGatewayVdHikApplicationRun
+{
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(DataGatewayVdHikApplicationRun.class);
+
+    public static void main(String[] args) throws UnknownHostException {
+        ConfigurableApplicationContext application = SpringApplication.run(DataGatewayVdHikApplicationRun.class, args);
+        Environment env = application.getEnvironment();
+        String ip = InetAddress.getLocalHost().getHostAddress();
+        String port = env.getProperty("server.port");
+        String path = env.getProperty("server.servlet.context-path");
+        LOGGER.info("\n----------------------------------------------------------\n\t" +
+                "Application is running! Access URLs:\n\t" +
+                "Local: \t\thttp://localhost:" + port + (null==path?"":path) + "/\n\t" +
+                "External: \thttp://" + ip + ":" + port + (null==path?"":path) + "/\n\t" +
+                "Api: \t\thttp://" + ip + ":" + port + (null==path?"":path) + "/swagger-ui/index.html\n\t" +
+                "----------------------------------------------------------");
+    }
+}

+ 222 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/controller/api/HkVideoApi.java

@@ -0,0 +1,222 @@
+package com.usky.hik.controller.api;
+
+import com.alibaba.fastjson.JSONObject;
+import com.hikvision.artemis.sdk.ArtemisHttpUtil;
+import com.hikvision.artemis.sdk.Client;
+import com.hikvision.artemis.sdk.Request;
+import com.hikvision.artemis.sdk.Response;
+import com.hikvision.artemis.sdk.config.ArtemisConfig;
+import com.hikvision.artemis.sdk.constant.Constants;
+import com.hikvision.artemis.sdk.enums.Method;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 海康视频api
+ * @author han
+ * @date 2023/10/29 13:21
+ */
+
+public class HkVideoApi {
+    private static final Logger logger = LoggerFactory.getLogger(ArtemisHttpUtil.class);
+
+    static {
+        /**
+         * 添加连接配置
+         */
+        ArtemisConfig.host = "192.168.10.101:443";
+        /**
+         * 密钥appkey
+         */
+        ArtemisConfig.appKey = "27427790";
+        /**
+         * 密钥appSecret
+         */
+        ArtemisConfig.appSecret = "lqIzdXZElwxNYS0a1YqZ";
+    }
+
+    /**
+     * 实时视频
+     * @param cameraIndexCode
+     * @param streamType
+     * @param protocol
+     * @param transmode
+     * @param expand
+     * @param streamform
+     * @return
+     */
+    public static String getVideoUrl(String cameraIndexCode, Integer streamType,String protocol,Integer transmode,String expand,
+                                     String streamform){
+        /**
+         * 获取视频资源
+         */
+        /**
+         * STEP2:设置OpenAPI接口的上下文
+         */
+        final String ARTEMIS_PATH = "/artemis";
+        final String url = ARTEMIS_PATH+"/api/video/v1/cameras/previewURLs";
+        Map<String, String> path = new HashMap<String, String>(2) {
+            {
+                put("https://", url);//根据现场环境部署确认是http还是https
+            }
+        };
+        /**
+         * 添加请求参数
+         */
+        JSONObject jsonBody = new JSONObject();
+        if (StringUtils.isNotBlank(cameraIndexCode)){
+            jsonBody.put("cameraIndexCode", cameraIndexCode);
+        }
+        if (null != streamType){
+            jsonBody.put("streamType", streamType);
+        }
+        if (StringUtils.isNotBlank(protocol)){
+            jsonBody.put("protocol", protocol);
+        }
+        if (null != transmode){
+            jsonBody.put("transmode", transmode);
+        }
+        if (StringUtils.isNotBlank(expand)){
+            jsonBody.put("expand", expand);
+        }
+        if (StringUtils.isNotBlank(streamform)){
+            jsonBody.put("streamform", streamform);
+        }
+        String body = jsonBody.toJSONString();
+        /**
+         * STEP4:设置参数提交方式
+         */
+        String contentType = "application/json";
+        return ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType , null);
+    }
+
+    /**
+     * 使用签名请求海康数据服务接口
+     * @param path
+     * @param body
+     * @param signature
+     * @return
+     */
+    public static String doPostSignatureStringArtemis(Map<String, String> path, String body, String signature) {
+        String httpSchema = (String)path.keySet().toArray()[0];
+        if (httpSchema != null && !StringUtils.isEmpty(httpSchema)) {
+            String responseStr = null;
+
+            try {
+                Map<String, String> headers = new HashMap();
+                headers.put("Accept", "*/*");
+                headers.put("Content-Type", "application/text;charset=UTF-8");
+                headers.put("x-ca-key","27427790");
+                headers.put("x-ca-signature-headers","x-ca-key");
+                headers.put("x-ca-signature",signature);
+
+                Request request = new Request(Method.POST_STRING, httpSchema + ArtemisConfig.host, (String)path.get(httpSchema), ArtemisConfig.appKey, ArtemisConfig.appSecret, Constants.DEFAULT_TIMEOUT);
+                request.setHeaders(headers);
+                request.setStringBody(body);
+                Response response = Client.execute(request);
+                responseStr = getResponseResult(response);
+            } catch (Exception var11) {
+                logger.error("the Artemis PostString Request is failed[doPostStringArtemis]", var11);
+            }
+
+            return responseStr;
+        } else {
+            throw new RuntimeException("http和https参数错误httpSchema: " + httpSchema);
+        }
+    }
+
+    private static String getResponseResult(Response response) {
+        String responseStr = null;
+        int statusCode = response.getStatusCode();
+        if (!String.valueOf(statusCode).startsWith("2") && !String.valueOf(statusCode).startsWith("3")) {
+            String msg = response.getErrorMessage();
+            responseStr = response.getBody();
+            logger.error("the Artemis Request is Failed,statusCode:" + statusCode + " errorMsg:" + msg);
+        } else {
+            responseStr = response.getBody();
+            logger.info("the Artemis Request is Success,statusCode:" + statusCode + " SuccessMsg:" + response.getBody());
+        }
+
+        return responseStr;
+    }
+
+    /**
+     * 行车记录
+     * @param startTime
+     * @param endTime
+     * @param pageNo
+     * @param pageSize
+     * @return
+     */
+    public static String driverRecord(String startTime, String endTime,Integer pageNo,Integer pageSize){
+
+        /**
+         * STEP2:设置OpenAPI接口的上下文
+         */
+        final String ARTEMIS_PATH = "/artemis";
+        final String url = ARTEMIS_PATH+"/api/pms/v1/crossRecords/page";
+        Map<String, String> path = new HashMap<String, String>(2) {
+            {
+                put("https://", url);//根据现场环境部署确认是http还是https
+            }
+        };
+        /**
+         * 添加请求参数
+         */
+        JSONObject jsonBody = new JSONObject();
+        if (StringUtils.isNotBlank(startTime)){
+            jsonBody.put("startTime", startTime);
+        }
+        if (StringUtils.isNotBlank(endTime)){
+            jsonBody.put("endTime", endTime);
+        }
+        if (null != pageNo){
+            jsonBody.put("pageNo", pageNo);
+        }
+        if (null != pageSize){
+            jsonBody.put("pageSize", pageSize);
+        }
+        String body = jsonBody.toJSONString();
+        /**
+         * STEP4:设置参数提交方式
+         */
+        String contentType = "application/json";
+
+        return ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType , null);
+    }
+
+    /**
+     * 查询停车库剩余车位数
+     * @param parkSyscode
+     * @return
+     */
+    public static String parkRemainSpace(String parkSyscode){
+
+        /**
+         * STEP2:设置OpenAPI接口的上下文
+         */
+        final String ARTEMIS_PATH = "/artemis";
+        final String url = ARTEMIS_PATH+"/api/pms/v1/park/remainSpaceNum";
+        Map<String, String> path = new HashMap<String, String>(2) {
+            {
+                put("https://", url);//根据现场环境部署确认是http还是https
+            }
+        };
+        /**
+         * 添加请求参数
+         */
+        JSONObject jsonBody = new JSONObject();
+        jsonBody.put("parkSyscode", parkSyscode);
+        String body = jsonBody.toJSONString();
+        /**
+         * STEP4:设置参数提交方式
+         */
+        String contentType = "application/json";
+
+        return ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType , null);
+    }
+}

+ 103 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/controller/web/DeviceAlarmController.java

@@ -0,0 +1,103 @@
+package com.usky.hik.controller.web;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.hikvision.artemis.sdk.ArtemisHttpUtil;
+import com.usky.hik.service.utils.HttpClientUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.HashMap;
+
+
+@RestController
+@RequestMapping("/deviceAlarm")
+@Slf4j
+public class DeviceAlarmController {
+    private static final Logger logger = LoggerFactory.getLogger(DeviceAlarmController.class);
+    @Value("${alarm.url}")
+    private String alarmUrl;
+
+    @Autowired
+    private HikThrowController hikThrowController;
+
+    /**
+     * 海康高空抛物事件回调接口
+     * @param body
+     * @return
+     */
+    @PostMapping("/skyThrow")
+    public String skyThrow(@RequestBody String body) throws ParseException {
+        System.out.println("body: "+body);
+
+        JSONObject rec_body = JSON.parseObject(body);
+        Object obj_params = JSON.toJSONString(rec_body.get("params"));
+        JSONObject json_params = JSONObject.parseObject(obj_params.toString());
+
+        JSONArray array_events = JSONArray.parseArray(json_params.get("events").toString());
+        JSONObject json_events = JSONObject.parseObject(array_events.getJSONObject(0).toJSONString());
+
+        //utc时间格式转换
+        SimpleDateFormat fromDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
+        SimpleDateFormat toDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String happenTime = json_events.get("happenTime").toString();
+        Date date = fromDateFormat.parse(happenTime);
+        Long dateTime = date.getTime();
+        String toHappenTime = toDateFormat.format(dateTime);
+
+        Object obj_data = JSON.toJSONString(json_events.get("data"));
+        JSONObject json_data = JSONObject.parseObject(obj_data.toString());
+
+        Object obj_target_attrs = JSON.toJSONString(json_data.get("targetAttrs"));
+        JSONObject json_target_attrs = JSONObject.parseObject(obj_target_attrs.toString());
+        String deviceIndexCode = json_target_attrs.get("cameraIndexCode").toString();
+        JSONArray array_throw = JSONArray.parseArray(json_data.get("ObjectsThrownDetection").toString());
+        JSONObject json_throw = JSONObject.parseObject(array_throw.getJSONObject(0).toJSONString());
+
+        Object obj_image = JSON.toJSONString(json_throw.get("Image"));
+        JSONObject json_image = JSONObject.parseObject(obj_image.toString());
+        String resourcesContent = json_image.get("resourcesContent").toString();
+
+
+
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("deviceId",deviceIndexCode);
+        jsonObject.put("alarmTime",toHappenTime);
+        jsonObject.put("sitePhoto",resourcesContent);
+
+        jsonObject.put("alarmType","105");
+        jsonObject.put("alarmObject","");
+        jsonObject.put("alarmData","");
+        jsonObject.put("alarmAttribute","高空抛物");
+        jsonObject.put("alarmContent","高空抛物");
+        jsonObject.put("alarmGrade",1);
+        jsonObject.put("alarmAddress","");
+        jsonObject.put("productCode","501_HGHK");
+
+        String resultString = HttpClientUtils.doPostJson(alarmUrl,jsonObject.toJSONString());
+
+        System.out.println("resultString: "+resultString);
+        hikThrowController.insert(body,resultString);
+
+        String responseBody = "HTTP/1.1 200 OK";
+        return responseBody;
+    }
+
+}
+
+
+
+
+
+
+
+

+ 51 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/controller/web/HikThrowController.java

@@ -0,0 +1,51 @@
+package com.usky.hik.controller.web;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.hik.domain.HikThrow;
+import com.usky.hik.mapper.HikThrowMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+@RestController
+@RequestMapping("/sqliteDB")
+public class HikThrowController {
+
+    @Autowired
+    private HikThrowMapper throwMapper;
+
+    /** 增添数据 */
+    @PostMapping("/insert")
+    public Object insert(String skyThrowData,String alarmResponse) {
+        HikThrow hikThrow = new HikThrow();
+
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        hikThrow.setDataTime(simpleDateFormat.format(new Date()));
+        hikThrow.setSkyThrowData(skyThrowData);
+        hikThrow.setAlarmResponse(alarmResponse);
+        return throwMapper.insert(hikThrow);
+    }
+    /** 查询数据 */
+    @GetMapping("/show")
+    public Object show() {
+        LambdaQueryWrapper<HikThrow> queryWrapper = Wrappers.lambdaQuery();
+        return throwMapper.selectList(queryWrapper);
+    }
+    /** 删除数据 */
+    @DeleteMapping("/delete")
+    public Object delete(Integer id) {
+        return throwMapper.deleteById(id);
+    }
+    /** 修改数据 */
+    @PutMapping("update")
+    public Object update(Integer id, String skyThrowData) {
+        HikThrow hikThrow = new HikThrow();
+        hikThrow.setId(id);
+        hikThrow.setSkyThrowData(skyThrowData);
+        return throwMapper.updateById(hikThrow);
+    }
+}

+ 26 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/domain/HikThrow.java

@@ -0,0 +1,26 @@
+package com.usky.hik.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+public class HikThrow {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+    /**
+     * 数据时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private String dataTime;
+
+    private String skyThrowData;
+
+    private String alarmResponse;
+}

+ 21 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/mapper/HikThrowMapper.java

@@ -0,0 +1,21 @@
+package com.usky.hik.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.usky.hik.domain.HikThrow;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 用户信息表 Mapper 接口
+ * </p>
+ *
+ * @since 2022-04-21
+ */
+@Repository
+@Mapper
+public interface HikThrowMapper extends BaseMapper<HikThrow> {}  // 结合mybatis plus
+

+ 50 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/config/mqtt/MqttBaseConfig.java

@@ -0,0 +1,50 @@
+package com.usky.hik.service.config.mqtt;
+
+import lombok.Data;
+import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
+import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
+import org.springframework.stereotype.Component;
+
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+@Data
+@Component
+@ConfigurationProperties(prefix = "mqtt")
+public class MqttBaseConfig {
+
+	@Value("${mqtt.username}")
+	private String username;
+
+	@Value("${mqtt.password}")
+	private String password;
+
+	@Value("${mqtt.url}")
+	private String hostUrl;
+
+	@Value("${mqtt.sub-topics}")
+	private String msgTopic;
+
+	@Value("${mqtt.keep-alive-interval}")
+	//心跳间隔
+	private int keepAliveInterval;
+	@Value("${mqtt.completionTimeout}")
+	//心跳间隔
+	private int completionTimeout;
+
+
+	@Bean
+	public MqttPahoClientFactory mqttClientFactory() {
+		DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
+		MqttConnectOptions options = new MqttConnectOptions();
+		options.setServerURIs(new String[]{this.getHostUrl()});
+		options.setUserName(this.getUsername());
+		options.setPassword(this.getPassword().toCharArray());
+		factory.setConnectionOptions(options);
+		return factory;
+	}
+
+}

+ 53 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/config/mqtt/MqttInConfig.java

@@ -0,0 +1,53 @@
+package com.usky.hik.service.config.mqtt;
+
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.integration.channel.DirectChannel;
+import org.springframework.integration.core.MessageProducer;
+import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
+import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
+import org.springframework.messaging.MessageChannel;
+
+import java.util.List;
+
+/**
+ * @author yq
+ * @date 2021/11/1 16:37
+ */
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+@Configuration
+public class MqttInConfig {
+
+    @Autowired
+    private MqttBaseConfig mqttBaseConfig;
+
+    public static final String CHANNEL_NAME_INPUT = "mqttInputChannel";
+
+    @Bean(name = CHANNEL_NAME_INPUT)
+    public MessageChannel mqttInputChannel() {
+        return new DirectChannel();
+    }
+
+
+    /**
+     * 消息订阅绑定-消费者
+     *
+     * @return
+     */
+    @Bean
+    public MessageProducer inbound() {
+        String[] tops = mqttBaseConfig.getMsgTopic().split(",");
+        String clientId = "gateway-vd-hik-mqtt-in-" + System.currentTimeMillis();
+        MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(clientId,
+                mqttBaseConfig.mqttClientFactory(), tops);
+        adapter.setCompletionTimeout(mqttBaseConfig.getCompletionTimeout());
+        adapter.setConverter(new DefaultPahoMessageConverter());
+        adapter.setQos(2);
+        adapter.setOutputChannel(mqttInputChannel());
+        return adapter;
+    }
+}

+ 84 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/config/mqtt/MqttOutConfig.java

@@ -0,0 +1,84 @@
+package com.usky.hik.service.config.mqtt;
+
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.integration.annotation.MessagingGateway;
+import org.springframework.integration.annotation.ServiceActivator;
+import org.springframework.integration.channel.DirectChannel;
+import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
+import org.springframework.integration.mqtt.support.MqttHeaders;
+import org.springframework.messaging.MessageChannel;
+import org.springframework.messaging.MessageHandler;
+import org.springframework.messaging.handler.annotation.Header;
+
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+@Configuration
+public class MqttOutConfig {
+
+    @Autowired
+    public MqttBaseConfig mqttBaseConfig;
+
+    public static final String CHANNEL_NAME_OUT = "mqttOutboundChannel";
+
+    public static final String MESSAGE_NAME = "messageOut";
+
+    public static final String DEFAULT_TOPIC = "testTopic";
+
+    /**
+     * 连接通道
+     *
+     * @return
+     */
+    @Bean(name = CHANNEL_NAME_OUT)
+    public MessageChannel mqttOutboundChannel() {
+        return new DirectChannel();
+    }
+
+    /**
+     * 发送消息和消费消息Channel可以使用相同MqttPahoClientFactory
+     *
+     * @return
+     */
+    @Bean(name = MESSAGE_NAME)
+    @ServiceActivator(inputChannel = CHANNEL_NAME_OUT)
+    public MessageHandler outbound() {
+        // 在这里进行mqttOutboundChannel的相关设置
+        String clientId = "gateway-vd-hik-mqtt-out-" + System.currentTimeMillis();
+        MqttPahoMessageHandler messageHandler =
+                new MqttPahoMessageHandler(clientId, mqttBaseConfig.mqttClientFactory());
+        //如果设置成true,发送消息时将不会阻塞。
+        messageHandler.setAsync(true);
+        messageHandler.setDefaultTopic(DEFAULT_TOPIC);
+        return messageHandler;
+    }
+
+    @MessagingGateway(defaultRequestChannel = CHANNEL_NAME_OUT)
+    public interface MqttGateway {
+        /**
+         * 发送消息
+         *
+         * @param payload
+         */
+        void sendToMqtt(String payload);
+
+        /**
+         * 指定top发送消息
+         *
+         * @param topic
+         * @param payload
+         */
+        void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, String payload);
+
+        /**
+         * 指定队列和qos
+         *
+         * @param topic
+         * @param qos
+         * @param payload
+         */
+        void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload);
+    }
+}

+ 19 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/config/udp/UdpBaseConfig.java

@@ -0,0 +1,19 @@
+package com.usky.hik.service.config.udp;
+
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@ConditionalOnProperty(prefix = "udp", value = {"enabled"}, havingValue = "true")
+@Data
+@Component
+@ConfigurationProperties(prefix = "udp")
+public class UdpBaseConfig {
+    @Value("${udp.deviceIp}")
+    private String deviceIp;
+
+    @Value("${udp.sendingPort}")
+    private Integer sendingPort;
+}

+ 62 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/listener/MqttListener.java

@@ -0,0 +1,62 @@
+package com.usky.hik.service.listener;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.usky.hik.service.config.mqtt.MqttInConfig;
+import com.usky.hik.service.mqtt.SimpleContext;
+import com.usky.hik.service.vo.MqttBaseVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.integration.annotation.ServiceActivator;
+import org.springframework.messaging.MessageHandler;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author yq
+ * @date 2021/11/3 8:13
+ */
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+@Slf4j
+@Component
+public class MqttListener {
+
+    public static final String MESSAGE_NAME = "messageInput";
+
+    @Autowired
+    private SimpleContext simpleContext;
+
+    /**
+     * 处理消息-消费者
+     *
+     * @return
+     */
+    @Bean(MESSAGE_NAME)
+    @ServiceActivator(inputChannel = MqttInConfig.CHANNEL_NAME_INPUT)
+    public MessageHandler handler() {
+        return message -> {
+            String payload = message.getPayload().toString();
+            JSONObject dataObj = JSONObject.parseObject(payload);
+            String method = dataObj.get("method").toString();
+            Object mqttReceivedTopic = message.getHeaders().get("mqtt_receivedTopic");
+            if (null != mqttReceivedTopic) {
+                String topic = mqttReceivedTopic.toString();
+                MqttBaseVO mqttBaseVO = new MqttBaseVO();
+                mqttBaseVO.setTopic(topic);
+                if (method.equals("streamControl")) {
+                    mqttBaseVO.setDescribe("streamControl");
+                    mqttBaseVO.setData(payload);
+                }else if(method.equals("driverRecordControl")){
+                    mqttBaseVO.setDescribe("driverRecordControl");
+                    mqttBaseVO.setData(payload);
+                }else if(method.equals("parkRemainSpaceControl")){
+                    mqttBaseVO.setDescribe("parkRemainSpaceControl");
+                    mqttBaseVO.setData(payload);
+                }
+                //统一处理数据
+                simpleContext.getResource(mqttBaseVO);
+            }
+        };
+    }
+}

+ 22 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/mqtt/MqttStrategy.java

@@ -0,0 +1,22 @@
+package com.usky.hik.service.mqtt;
+
+
+import com.usky.hik.service.vo.MqttBaseVO;
+
+
+/**
+ * 策略类
+ *
+ * @author yq
+ * @date 2021/11/3 8:27
+ */
+public interface MqttStrategy {
+    /**
+     * 处理消息(策略模式由子类实现)
+     *
+     * @param mqttBaseVO
+     * @return
+     */
+    String disposeMessage(MqttBaseVO mqttBaseVO) ;
+
+}

+ 28 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/mqtt/SimpleContext.java

@@ -0,0 +1,28 @@
+package com.usky.hik.service.mqtt;
+
+
+import com.hikvision.artemis.sdk.config.ArtemisConfig;
+import com.usky.hik.service.vo.MqttBaseVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 中间处理消息转发
+ */
+@Service
+public class SimpleContext {
+
+    @Autowired
+    private final Map<String, MqttStrategy> strategyMap = new ConcurrentHashMap<>();
+
+    public SimpleContext(Map<String, MqttStrategy> strategyMap) {
+        strategyMap.forEach(this.strategyMap::put);
+    }
+
+    public String getResource(MqttBaseVO mqttBaseVO) {
+        return strategyMap.get(mqttBaseVO.getDescribe()).disposeMessage(mqttBaseVO);
+    }
+}

+ 80 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/mqtt/driverRecordControl/driverRecordControl.java

@@ -0,0 +1,80 @@
+package com.usky.hik.service.mqtt.driverRecordControl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.hikvision.artemis.sdk.ArtemisHttpUtil;
+import com.usky.hik.controller.api.HkVideoApi;
+import com.usky.hik.service.config.mqtt.MqttOutConfig;
+import com.usky.hik.service.mqtt.MqttStrategy;
+import com.usky.hik.service.vo.MqttBaseVO;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * @author zyj
+ * @date 2022/12/6 15:07
+ */
+@Service("driverRecordControl")
+public class driverRecordControl implements MqttStrategy {
+    @Resource
+    private MqttOutConfig.MqttGateway mqttGateway;
+
+    /**
+     * 获取海康系统行车记录数据
+     * @return
+     */
+    public String disposeMessage(MqttBaseVO mqttBaseVO){
+
+        /**
+         * 添加请求参数
+         */
+        JSONObject obj_data = JSONObject.parseObject(mqttBaseVO.getData().toString());
+        Integer commandId = Integer.parseInt(obj_data.get("id").toString());
+        Object params = JSONObject.toJSONString(obj_data.get("params"));
+        JSONObject params_data = JSON.parseObject(params.toString());
+        String startTime = "";
+        if(Objects.nonNull(params_data.get("startTime"))){
+            startTime = params_data.get("startTime").toString();
+        }
+        String endTime = "";
+        if(Objects.nonNull(params_data.get("endTime"))){
+            endTime = params_data.get("endTime").toString();
+        }
+        Integer pageNo = Integer.parseInt(params_data.get("pageNo").toString());
+        Integer pageSize = Integer.parseInt(params_data.get("pageSize").toString());
+
+        String rec_body = HkVideoApi.driverRecord(startTime+"+08:00", endTime+"+08:00", pageNo, pageSize);
+
+        JSONObject rec_data = JSONObject.parseObject(rec_body);
+        String rec_code = rec_data.get("code").toString();
+
+        //推送下发命令响应mqtt
+        JSONObject jsonObject = new JSONObject();
+
+        if(rec_code.equals("0")){
+            jsonObject.put("result","success");
+            jsonObject.put("message",rec_body);
+
+        }else{
+            JSONObject obj1 = new JSONObject();
+            obj1.put("code",-1);
+            obj1.put("message","open failed");
+            jsonObject.put("error",obj1);
+
+        }
+
+        jsonObject.put("timeStamp",System.currentTimeMillis());
+        jsonObject.put("id",commandId);
+
+        String res_topic = mqttBaseVO.getTopic().replace("control","controlResponse");
+        mqttGateway.sendToMqtt(res_topic,jsonObject.toJSONString());
+
+        return null;
+    }
+
+}

+ 67 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/mqtt/parkRemainSpaceControl/parkRemainSpaceControl.java

@@ -0,0 +1,67 @@
+package com.usky.hik.service.mqtt.parkRemainSpaceControl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.usky.hik.controller.api.HkVideoApi;
+import com.usky.hik.service.config.mqtt.MqttOutConfig;
+import com.usky.hik.service.mqtt.MqttStrategy;
+import com.usky.hik.service.vo.MqttBaseVO;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Objects;
+
+/**
+ * @author zyj
+ * @date 2022/12/6 15:07
+ */
+@Service("parkRemainSpaceControl")
+public class parkRemainSpaceControl implements MqttStrategy {
+    @Resource
+    private MqttOutConfig.MqttGateway mqttGateway;
+
+    /**
+     * 查询停车库剩余车位数
+     * @return
+     */
+    public String disposeMessage(MqttBaseVO mqttBaseVO){
+
+        /**
+         * 添加请求参数
+         */
+        JSONObject obj_data = JSONObject.parseObject(mqttBaseVO.getData().toString());
+        Integer commandId = Integer.parseInt(obj_data.get("id").toString());
+        Object params = JSONObject.toJSONString(obj_data.get("params"));
+        JSONObject params_data = JSON.parseObject(params.toString());
+        String parkSyscode = params_data.get("parkSyscode").toString();
+
+        String rec_body = HkVideoApi.parkRemainSpace(parkSyscode);
+
+        JSONObject rec_data = JSONObject.parseObject(rec_body);
+        String rec_code = rec_data.get("code").toString();
+
+        //推送下发命令响应mqtt
+        JSONObject jsonObject = new JSONObject();
+
+        if(rec_code.equals("0")){
+            jsonObject.put("result","success");
+            jsonObject.put("message",rec_body);
+
+        }else{
+            JSONObject obj1 = new JSONObject();
+            obj1.put("code",-1);
+            obj1.put("message","open failed");
+            jsonObject.put("error",obj1);
+
+        }
+
+        jsonObject.put("timeStamp",System.currentTimeMillis());
+        jsonObject.put("id",commandId);
+
+        String res_topic = mqttBaseVO.getTopic().replace("control","controlResponse");
+        mqttGateway.sendToMqtt(res_topic,jsonObject.toJSONString());
+
+        return null;
+    }
+
+}

+ 84 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/mqtt/streamControl/streamControl.java

@@ -0,0 +1,84 @@
+package com.usky.hik.service.mqtt.streamControl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.hikvision.artemis.sdk.ArtemisHttpUtil;
+import com.hikvision.artemis.sdk.config.ArtemisConfig;
+import com.usky.hik.controller.api.HkVideoApi;
+import com.usky.hik.service.config.mqtt.MqttOutConfig;
+import com.usky.hik.service.mqtt.MqttStrategy;
+import com.usky.hik.service.utils.ByteUtil;
+import com.usky.hik.service.utils.UdpUtil;
+import com.usky.hik.service.vo.MqttBaseVO;
+import lombok.Data;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.Map;
+
+@Service("streamControl")
+@Configuration
+@Data
+public class streamControl implements MqttStrategy {
+
+    @Resource
+    private MqttOutConfig.MqttGateway mqttGateway;
+
+    /**
+     * 海康监控系统实时视频预览取流
+     * @return
+     */
+    public String disposeMessage(MqttBaseVO mqttBaseVO){
+
+        /**
+         * 添加请求参数
+         */
+        JSONObject obj_data = JSONObject.parseObject(mqttBaseVO.getData().toString());
+        Integer commandId = Integer.parseInt(obj_data.get("id").toString());
+        Object params = JSONObject.toJSONString(obj_data.get("params"));
+        JSONObject params_data = JSON.parseObject(params.toString());
+        String cameraIndexCode = params_data.get("device_id").toString();
+        Integer streamType = Integer.parseInt(params_data.get("streamType").toString());
+        String protocol = params_data.get("protocol").toString();
+        Integer transmode = Integer.parseInt(params_data.get("transmode").toString());
+        String expand = "";
+        String streamform = "";
+
+        String rec_body = HkVideoApi.getVideoUrl(cameraIndexCode,streamType,protocol,transmode,expand,streamform);
+        System.out.println("rec_body: "+rec_body);
+
+        JSONObject rec_data = JSONObject.parseObject(rec_body);
+        String rec_code = rec_data.get("code").toString();
+
+        //推送下发命令响应mqtt
+        JSONObject jsonObject = new JSONObject();
+
+        if(rec_code.equals("0")){
+            jsonObject.put("result","success");
+            jsonObject.put("message",rec_body);
+
+        }else{
+            JSONObject obj1 = new JSONObject();
+            obj1.put("code",-1);
+            obj1.put("message","open failed");
+            jsonObject.put("error",obj1);
+
+        }
+
+        jsonObject.put("timeStamp",System.currentTimeMillis());
+        jsonObject.put("id",commandId);
+
+        String res_topic = mqttBaseVO.getTopic().replace("control","controlResponse");
+        mqttGateway.sendToMqtt(res_topic,jsonObject.toJSONString());
+
+        return null;
+    }
+
+
+}

+ 22 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/utils/ByteUtil.java

@@ -0,0 +1,22 @@
+package com.usky.hik.service.utils;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class ByteUtil {
+    public byte[] toLH(int n) {
+        byte[] b = new byte[4];
+        b[0] = (byte) (n & 0xff);
+        b[1] = (byte) (n >> 8 & 0xff);
+        b[2] = (byte) (n >> 16 & 0xff);
+        b[3] = (byte) (n >> 24 & 0xff);
+        return b;
+    }
+
+    // 打印字节数组的十六进制表示
+    public void printBytes(byte[] bytes) {
+        for (byte b : bytes) {
+            System.out.print(Integer.toHexString(b & 0xFF).toUpperCase() + " ");
+        }
+    }
+}

+ 137 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/utils/HttpClientUtils.java

@@ -0,0 +1,137 @@
+package com.usky.hik.service.utils;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ 1. 跨域请求工具类
+ */
+public class HttpClientUtils {
+
+    public static String doGet(String url, Map<String, String> param) {
+
+        // 创建Httpclient对象
+        CloseableHttpClient httpclient = HttpClients.createDefault();
+
+        String resultString = "";
+        CloseableHttpResponse response = null;
+        try {
+            // 创建uri
+            URIBuilder builder = new URIBuilder(url);
+            if (param != null) {
+                for (String key : param.keySet()) {
+                    builder.addParameter(key, param.get(key));
+                }
+            }
+            URI uri = builder.build();
+
+            // 创建http GET请求
+            HttpGet httpGet = new HttpGet(uri);
+
+            // 执行请求
+            response = httpclient.execute(httpGet);
+            // 判断返回状态是否为200
+            if (response.getStatusLine().getStatusCode() == 200) {
+                resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (response != null) {
+                    response.close();
+                }
+                httpclient.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return resultString;
+    }
+
+    public static String doGet(String url) {
+        return doGet(url, null);
+    }
+
+    public static String doPost(String url, Map<String, Object> param) {
+        // 创建Httpclient对象
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        CloseableHttpResponse response = null;
+        String resultString = "";
+        try {
+            // 创建Http Post请求
+            HttpPost httpPost = new HttpPost(url);
+            httpPost.setHeader("Content-Type", "charset=utf-8");
+            // 创建参数列表
+            if (param != null) {
+                List<NameValuePair> paramList = new ArrayList<>();
+                for (String key : param.keySet()) {
+                    paramList.add(new BasicNameValuePair(key, param.get(key).toString()));
+                }
+                // 模拟表单
+                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
+                httpPost.setEntity(entity);
+            }
+            // 执行http请求
+            response = httpClient.execute(httpPost);
+            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                response.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+
+        return resultString;
+    }
+
+    public static String doPost(String url) {
+        return doPost(url, null);
+    }
+
+    public static String doPostJson(String url, String json) {
+        // 创建Httpclient对象
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        CloseableHttpResponse response = null;
+        String resultString = "";
+        try {
+            // 创建Http Post请求
+            HttpPost httpPost = new HttpPost(url);
+            // 创建请求内容
+            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
+            httpPost.setEntity(entity);
+            // 执行http请求
+            response = httpClient.execute(httpPost);
+            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                response.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+
+        return resultString;
+    }
+}

+ 54 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/utils/UdpUtil.java

@@ -0,0 +1,54 @@
+package com.usky.hik.service.utils;
+
+import feign.form.util.CharsetUtil;
+import org.springframework.stereotype.Component;
+
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.nio.charset.Charset;
+
+
+@Component
+public class UdpUtil {
+
+    /**
+     * 发送UDP请求并打印返回结果
+     *
+     * @param requestBytes 要发送的自定义命令
+     */
+    public static String sendUDPRequest(String host, int port, byte[] requestBytes) {
+        try {
+            // 创建DatagramSocket随机端口
+            DatagramSocket socket = new DatagramSocket();
+
+            // 创建InetAddress对象
+            InetAddress address = InetAddress.getByName(host);
+
+            // 创建DatagramPacket,包含发送的数据和目的地
+            DatagramPacket OutPacket = new DatagramPacket(requestBytes, requestBytes.length, address, port);
+
+            // 发送DatagramPacket
+            socket.send(OutPacket);
+
+            // 创建一个DatagramPacket来接收响应,大小与发送的数据包相同
+            DatagramPacket inPacket = new DatagramPacket(requestBytes, requestBytes.length);
+
+            // 接收响应
+            socket.receive(inPacket);
+
+            // 打印接收到的数据
+            String receivedData = new String(inPacket.getData(), 0, inPacket.getLength(), Charset.forName("ISO-8859-1"));
+            System.out.println("接收到的响应: " + receivedData+ ": ");
+
+            // 关闭socket
+            socket.close();
+
+            return receivedData;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+}

+ 21 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/vo/MqttBaseVO.java

@@ -0,0 +1,21 @@
+package com.usky.hik.service.vo;
+
+import lombok.Data;
+
+/**
+ * @author yq
+ * @date 2021/11/3 8:32
+ */
+@Data
+public class MqttBaseVO {
+    /**
+     * 接口描述
+     */
+    private String describe;
+
+    private String topic;
+    /**
+     * 数据内容
+      */
+    private Object data;
+}

+ 34 - 0
data-gateway/data-gateway-vd-hik/src/main/java/com/usky/hik/service/vo/ProductMapVO.java

@@ -0,0 +1,34 @@
+package com.usky.hik.service.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class ProductMapVO implements Serializable {
+    /**
+     * 产品ID
+     */
+    private Integer productId;
+
+    /**
+     * 产品编码
+     */
+    private String productCode;
+
+    /**
+     * 创建人
+     */
+    private String createdBy;
+
+    /**
+     * 租户号
+     */
+    private Integer tenantId;
+
+    /**
+     * 设备类型
+     */
+    private Integer deviceType;
+
+}

+ 53 - 0
data-gateway/data-gateway-vd-hik/src/main/resources/application.yml

@@ -0,0 +1,53 @@
+# Tomcat
+server:
+  port: 21002
+spring:
+  application:
+    # 应用名称
+    name: data-gateway-vd-hik
+  cache:
+    ehcache:
+      config: classpath:ehcache.xml
+      enabled: false
+    redis:
+      enabled: true
+  jackson:
+    date-format: yyyy-MM-dd HH:mm:ss
+    default-property-inclusion: always
+    deserialization:
+      fail-on-unknown-properties: false
+    parser:
+      allow-single-quotes: true
+      allow-unquoted-control-chars: true
+    serialization:
+      fail-on-empty-beans: false
+    time-zone: GMT+8
+  tenant:
+    enable: false
+  servlet:
+    multipart:
+      max-file-size: 10MB
+      max-request-size: 15MB
+  datasource:
+    name: sqlite3
+    url: jdbc:sqlite:data-gateway/data-gateway-vd-hik/src/main/resources/db/yt_hik.db
+    driver-class-name: org.sqlite.JDBC
+    username:
+    password:
+
+temp:
+  basedir: C:/Users/pc/Desktop/
+mqtt:
+  completionTimeout: 5000
+  enabled: true
+  keep-alive-interval: 60
+  password: public
+  sub-topics: /501_HGHK/+/control
+  url: tcp://192.169.15.51:1883
+  username: admin
+#  password: usky
+#  sub-topics: /501_HGHK/+/control
+#  url: tcp://47.98.201.73:1883
+#  username: usky
+alarm:
+  url: http://192.169.15.51:13200/dev-api/service-iot/baseAlarm/alarmInfo

BIN
data-gateway/data-gateway-vd-hik/src/main/resources/db/yt_hik.db


+ 108 - 0
data-gateway/data-gateway-vd-hik/src/main/resources/doc/index.adoc

@@ -0,0 +1,108 @@
+= 安防项目
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Version |  Update Time  | Status | Author |  Description
+|v2022-04-21 16:57:08|2022-04-21 16:57:08|auto|@yq|Created by smart-doc
+|====================
+
+
+== &lt;p&gt;参数配置表 前端控制器&lt;/p&gt;
+== &lt;p&gt;部门信息&lt;/p&gt;
+=== 查看部门信息
+*URL:* http:10.23.39.1:8082/sysDept/list
+
+*Type:* POST
+
+*Author:* ya
+
+*Content-Type:* application/json; charset=utf-8
+
+
+
+
+*Body-parameters:*
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Parameter | Type|Description|Required|Since
+|deptId|int64|部门id|false|-
+|parentId|int64|父部门id|false|-
+|ancestors|string|祖级列表|false|-
+|deptName|string|部门名称|false|-
+|orderNum|int32|显示顺序|false|-
+|leader|string|负责人|false|-
+|phone|string|联系电话|false|-
+|email|string|邮箱|false|-
+|status|string|部门状态(0正常 1停用)|false|-
+|delFlag|string|删除标志(0代表存在 2代表删除)|false|-
+|createBy|string|创建者|false|-
+|createTime|string|创建时间|false|-
+|updateBy|string|更新者|false|-
+|updateTime|string|更新时间|false|-
+|bId|int64|建筑id|false|-
+|====================
+
+*Response-fields:*
+
+[width="100%",options="header"]
+[stripes=even]
+|====================
+|Field | Type|Description|Since
+|status|object|No comments found.|-
+|code|string|No comments found.|-
+|msg|string|No comments found.|-
+|data|object|No comments found.|-
+|└─deptId|int64|部门id|-
+|└─parentId|int64|父部门id|-
+|└─ancestors|string|祖级列表|-
+|└─deptName|string|部门名称|-
+|└─orderNum|int32|显示顺序|-
+|└─leader|string|负责人|-
+|└─phone|string|联系电话|-
+|└─email|string|邮箱|-
+|└─status|string|部门状态(0正常 1停用)|-
+|└─delFlag|string|删除标志(0代表存在 2代表删除)|-
+|└─createBy|string|创建者|-
+|└─createTime|string|创建时间|-
+|└─updateBy|string|更新者|-
+|└─updateTime|string|更新时间|-
+|└─bId|int64|建筑id|-
+|exception|string|No comments found.|-
+|====================
+
+*Response-example:*
+----
+{
+	"status": {
+		
+	},
+	"code": "97564",
+	"msg": "wnr5qt",
+	"data": [
+		{
+			"deptId": 540,
+			"parentId": 858,
+			"ancestors": "o5lg60",
+			"deptName": "文.沈",
+			"orderNum": 260,
+			"leader": "ufz93p",
+			"phone": "17852835049",
+			"email": "智渊.徐@yahoo.com",
+			"status": "nu6cnp",
+			"delFlag": "72oiji",
+			"createBy": "5fxr6j",
+			"createTime": "2022-04-21 16:57:10",
+			"updateBy": "4kcs4e",
+			"updateTime": "2022-04-21 16:57:10",
+			"bId": 977
+		}
+	],
+	"exception": "53u6bg"
+}
+----
+
+== &lt;p&gt;用户信息表 前端控制器&lt;/p&gt;
+

+ 74 - 0
data-gateway/data-gateway-vd-hik/src/main/resources/logback.xml

@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="60 seconds" debug="false">
+    <!-- 日志存放路径 -->
+	<property name="log.path" value="/var/log/uskycloud/usky-demo" />
+   <!-- 日志输出格式 -->
+	<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
+
+    <!-- 控制台输出 -->
+	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+	</appender>
+
+    <!-- 系统日志输出 -->
+	<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+	    <file>${log.path}/info.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+			<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>60</maxHistory>
+		</rollingPolicy>
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>INFO</level>
+            <!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+	</appender>
+
+    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+	    <file>${log.path}/error.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+            <fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>ERROR</level>
+			<!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+			<!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 系统模块日志级别控制  -->
+	<logger name="com.usky" level="info" />
+	<!-- Spring日志级别控制  -->
+	<logger name="org.springframework" level="warn" />
+
+	<root level="info">
+		<appender-ref ref="console" />
+	</root>
+	
+	<!--系统操作日志-->
+    <root level="info">
+        <appender-ref ref="file_info" />
+        <appender-ref ref="file_error" />
+    </root>
+</configuration>

+ 15 - 0
data-gateway/data-gateway-vd-hik/src/main/resources/smart-doc.json

@@ -0,0 +1,15 @@
+{
+  "outPath":"./src/main/resources/doc",
+  "serverUrl": "http:10.23.39.1:8082/",
+  "isStrict": false,
+  "coverOld": true,
+  "allInOne": true,
+  "packageFilters": "com.usky.demo.controller.web",
+  "requestExample":"false",
+  "responseExample":"true",
+  "projectName": "安防项目",
+  "appKey": "20211216921084883495813120",
+  "appToken":"36bde2426ad546a5a50311bb747e7e61",
+  "secret": "N@Pd,KXAHki*BW3=zK.XPNykf!=CM79J",
+  "openUrl": "http://101.133.214.75:7700/api"
+}

+ 17 - 0
data-gateway/pom.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>usky-data</artifactId>
+        <groupId>com.usky</groupId>
+        <version>0.0.1</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>data-gateway</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>data-gateway-eg-kat</module><!--科奥特门禁-->
+        <module>data-gateway-vd-hik</module><!--海康监控-->
+  </modules>
+
+</project>

+ 29 - 0
data-transfer/data-transfer-api/pom.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>data-transfer</artifactId>
+        <groupId>com.usky</groupId>
+        <version>0.0.1</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>data-transfer-api</artifactId>
+    <!-- SpringCloud Openfeign -->
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.usky</groupId>
+            <artifactId>usky-common-core</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+    </build>
+
+</project>

+ 28 - 0
data-transfer/data-transfer-api/src/main/java/com/usky/transfer/RemoteTransferService.java

@@ -0,0 +1,28 @@
+package com.usky.transfer;
+
+
+import com.usky.common.core.bean.ApiResult;
+import com.usky.transfer.domain.*;
+import com.usky.transfer.factory.RemoteTransferFallbackFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+@FeignClient(contextId = "remoteTransferService", value = "data-transfer", fallbackFactory = RemoteTransferFallbackFactory.class)
+public interface RemoteTransferService {
+
+    /**
+     * 单个设备数据写入
+     * @return
+     */
+    @PostMapping("/sendDeviceData")
+    ApiResult<Void> sendDeviceData(@RequestBody DeviceDataWriteVO writeVO);
+
+    /**
+     * 下发单个设备控制命令
+     */
+    @PostMapping("/deviceControl")
+    Map<String,Object> deviceControl(@RequestParam("productCode") String productCode, @RequestParam(value = "deviceId",required = false) String deviceId, @RequestParam("commandStr") String commandStr,@RequestParam(value = "tenantId") Integer tenantId, @RequestParam(value = "userId") Long userId, @RequestParam(value = "userName") String userName);
+}

+ 41 - 0
data-transfer/data-transfer-api/src/main/java/com/usky/transfer/domain/DeviceDataInfoVO.java

@@ -0,0 +1,41 @@
+package com.usky.transfer.domain;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class DeviceDataInfoVO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 属性值集合
+     */
+    private Map<String,Object> metrics;
+
+    /**
+     * 标签集合
+     */
+    private Map<String,Object> tags;
+
+    /**
+     * 设备编号
+     */
+    private String deviceUUId;
+
+    /**
+     * 产品编码
+     */
+    private String productCode;
+
+    /**
+     * 数据上报时间
+     */
+    private long timestamp;
+}

+ 43 - 0
data-transfer/data-transfer-api/src/main/java/com/usky/transfer/domain/DeviceDataWriteVO.java

@@ -0,0 +1,43 @@
+package com.usky.transfer.domain;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class DeviceDataWriteVO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 产品编码
+     */
+    private String productCode;
+
+    /**
+     * 设备UUId
+     */
+    private String deviceUUId;
+
+    /**
+     * 数据上报时间
+     */
+    private long timestamp;
+
+    /**
+     * 标签集合
+     */
+    private Map<String,String> tags;
+
+    /**
+     * 属性值集合
+     */
+    private Map<String,Object> metrics;
+
+}
+

+ 30 - 0
data-transfer/data-transfer-api/src/main/java/com/usky/transfer/domain/HistoryRequestVO.java

@@ -0,0 +1,30 @@
+package com.usky.transfer.domain;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class HistoryRequestVO implements Serializable {
+
+    /**
+     * 产品编码
+     */
+    private String  productCode;
+
+    /**
+     * 设备Id
+     */
+    private List<String> deviceId;
+
+    /**
+     * 开始时间
+     */
+    private String startTime;
+
+    /**
+     * 结束时间
+     */
+    private String endTime;
+}

+ 19 - 0
data-transfer/data-transfer-api/src/main/java/com/usky/transfer/domain/HistoryResultVO.java

@@ -0,0 +1,19 @@
+package com.usky.transfer.domain;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class HistoryResultVO implements Serializable {
+    private String deviceId;
+    private List<MetricVO> metrics;
+
+    public HistoryResultVO(String devId,List<MetricVO> metrics){
+        this.deviceId = devId;
+        this.metrics = metrics;
+    }
+
+}

+ 20 - 0
data-transfer/data-transfer-api/src/main/java/com/usky/transfer/domain/LastRequestVO.java

@@ -0,0 +1,20 @@
+package com.usky.transfer.domain;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class LastRequestVO implements Serializable {
+
+    /**
+     * 产品编码
+     */
+    private String  productCode;
+
+    /**
+     * 设备Id
+     */
+    private List<String> deviceId;
+}

+ 20 - 0
data-transfer/data-transfer-api/src/main/java/com/usky/transfer/domain/LastResultVO.java

@@ -0,0 +1,20 @@
+package com.usky.transfer.domain;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class LastResultVO implements Serializable {
+
+    private String deviceId;
+    private List<Map<String,Object>> metrics;
+
+    public LastResultVO(String devId,List<Map<String,Object>> metrics){
+        this.deviceId = devId;
+        this.metrics = metrics;
+    }
+
+}

+ 20 - 0
data-transfer/data-transfer-api/src/main/java/com/usky/transfer/domain/MetricVO.java

@@ -0,0 +1,20 @@
+package com.usky.transfer.domain;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class MetricVO implements Serializable {
+
+    private String metric;
+    private List<Map<String,Object>> metricItems;
+
+    public MetricVO(String metric,List<Map<String,Object>> metricItems){
+        this.metric = metric;
+        this.metricItems = metricItems;
+    }
+
+}

+ 44 - 0
data-transfer/data-transfer-api/src/main/java/com/usky/transfer/factory/RemoteTransferFallbackFactory.java

@@ -0,0 +1,44 @@
+package com.usky.transfer.factory;
+
+import com.usky.common.core.bean.ApiResult;
+import com.usky.common.core.exception.BusinessException;
+import com.usky.transfer.RemoteTransferService;
+import com.usky.transfer.domain.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * 用户服务降级处理
+ *
+ * @author ruoyi
+ */
+@Component
+public class RemoteTransferFallbackFactory implements FallbackFactory<RemoteTransferService>
+{
+    private static final Logger log = LoggerFactory.getLogger(RemoteTransferFallbackFactory.class);
+
+    @Override
+    public RemoteTransferService create(Throwable throwable)
+    {
+        log.error("用户服务调用失败:{}", throwable.getMessage());
+        return new RemoteTransferService() {
+            @Override
+            public ApiResult<Void> sendDeviceData(DeviceDataWriteVO writeVO) {
+                throw new BusinessException(throwable.getMessage());
+            }
+            @Override
+            public Map<String,Object> deviceControl(String productCode, String deviceId, String commandStr,Integer tenantId, Long userId, String userName) {
+                throw new BusinessException(throwable.getMessage());
+            }
+        };
+    }
+}

+ 112 - 0
data-transfer/data-transfer-biz/pom.xml

@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>data-transfer</artifactId>
+        <groupId>com.usky</groupId>
+        <version>0.0.1</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>data-transfer-biz</artifactId>
+    <dependencies>
+        <!--MQTT依赖-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-integration</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.integration</groupId>
+            <artifactId>spring-integration-mqtt</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>com.usky</groupId>
+            <artifactId>common-cloud-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <!-- Pagehelper -->
+        <dependency>
+            <groupId>com.github.pagehelper</groupId>
+            <artifactId>pagehelper-spring-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.usky</groupId>
+            <artifactId>ruoyi-common-swagger</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.28</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.rocketmq</groupId>
+            <artifactId>rocketmq-spring-boot-starter</artifactId>
+            <version>2.1.1</version>
+        </dependency>
+        <!-- InfluxDB Java 客户端,用于连接和操作 InfluxDB 数据库 -->
+        <dependency>
+            <groupId>org.influxdb</groupId>
+            <artifactId>influxdb-java</artifactId>
+            <version>2.23</version>
+        </dependency>
+        <dependency>
+            <groupId>com.usky</groupId>
+            <artifactId>data-transfer-api</artifactId>
+            <version>0.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.usky</groupId>
+            <artifactId>data-tsdb-proxy-api</artifactId>
+            <version>0.0.1</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.2.6.RELEASE</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>com.github.shalousun</groupId>
+                <artifactId>smart-doc-maven-plugin</artifactId>
+                <version>2.1.1</version>
+                <configuration>
+                    <!--指定生成文档的使用的配置文件,配置文件放在自己的项目中-->
+                    <configFile>./src/main/resources/smart-doc.json</configFile>
+                    <!--指定项目名称-->
+                    <projectName>test</projectName>
+                    <!--                    <excludes>-->
+                    <!--                        <exclude>com.bizmatics:product-service-provider</exclude>-->
+                    <!--                        <exclude>cn.afterturn:easypoi-web</exclude>-->
+                    <!--                    </excludes>-->
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 51 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/ApplicationRun.java

@@ -0,0 +1,51 @@
+package com.usky.transfer;
+
+
+import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2;
+import org.mybatis.spring.annotation.MapperScan;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.core.env.Environment;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * 应用启动模块
+ * 
+ */
+
+
+@EnableCaching
+@EnableCustomSwagger2
+//@EnableSwagger2
+@EnableFeignClients(basePackages = "com.usky")
+@MapperScan(value = "com.usky.transfer.mapper")
+@ComponentScan("com.usky")
+@SpringBootApplication
+public class ApplicationRun
+{
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationRun.class);
+
+    public static void main(String[] args) throws UnknownHostException {
+        ConfigurableApplicationContext application = SpringApplication.run(ApplicationRun.class, args);
+        Environment env = application.getEnvironment();
+        String ip = InetAddress.getLocalHost().getHostAddress();
+        String port = env.getProperty("server.port");
+        String path = env.getProperty("server.servlet.context-path");
+        LOGGER.info("\n----------------------------------------------------------\n\t" +
+                "Application is running! Access URLs:\n\t" +
+                "Local: \t\thttp://localhost:" + port + (null==path?"":path) + "/\n\t" +
+                "External: \thttp://" + ip + ":" + port + (null==path?"":path) + "/\n\t" +
+                "Api: \t\thttp://" + ip + ":" + port + (null==path?"":path) + "/swagger-ui/index.html\n\t" +
+                "----------------------------------------------------------");
+    }
+}

+ 107 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/MybatisGenerator.java

@@ -0,0 +1,107 @@
+package com.usky.transfer;//package com.usky.demo.controller;//package com.usky.dm.controller.web.business;//package com.usky.dm.controller.web;
+
+
+
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.generator.AutoGenerator;
+import com.baomidou.mybatisplus.generator.InjectionConfig;
+import com.baomidou.mybatisplus.generator.config.*;
+import com.baomidou.mybatisplus.generator.config.po.TableInfo;
+import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ */
+public class MybatisGenerator {
+    public static void main(String[] args) {
+
+            shell("data-transfer","data-transfer-biz");
+    }
+
+    private static void shell(String parentName,String model) {
+
+        AutoGenerator mpg = new AutoGenerator();
+        //1、全局配置
+        GlobalConfig gc = new GlobalConfig();
+//        File file = new File(model);
+//        String path = file.getAbsolutePath();
+        String projectPath = System.getProperty("user.dir");
+        projectPath+="/"+parentName;
+        projectPath+="/"+model;
+        gc.setOutputDir(projectPath+ "/src/main/java");  //生成路径(一般都是生成在此项目的src/main/java下面)
+        //修改为自己的名字
+        gc.setAuthor("ya"); //设置作者
+        gc.setOpen(false);
+        gc.setFileOverride(true); //第二次生成会把第一次生成的覆盖掉
+        gc.setServiceName("%sService"); //生成的service接口名字首字母是否为I,这样设置就没有
+        gc.setBaseResultMap(true); //生成resultMap
+        mpg.setGlobalConfig(gc);
+
+        //2、数据源配置
+        //修改数据源
+        DataSourceConfig dsc = new DataSourceConfig();
+        dsc.setUrl("jdbc:mysql://172.16.120.165:3306/usky-cloud?useUnicode=true&serverTimezone=GMT&useSSL=false&characterEncoding=utf8");
+        dsc.setDriverName("com.mysql.jdbc.Driver");
+        dsc.setUsername("root");
+        dsc.setPassword("yt123456");
+        mpg.setDataSource(dsc);
+
+        // 3、包配置
+        PackageConfig pc = new PackageConfig();
+        pc.setParent("com.usky.transfer");
+        pc.setController("controller.web");
+        pc.setEntity("domain");
+        pc.setMapper("mapper");
+        pc.setService("service");
+        pc.setServiceImpl("service.impl");
+//        pc.setXml("mapper.demo");
+        //pc.setModuleName("test");
+        mpg.setPackageInfo(pc);
+
+        // 4、策略配置
+        StrategyConfig strategy = new StrategyConfig();
+        strategy.setNaming(NamingStrategy.underline_to_camel);
+        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
+        strategy.setSuperMapperClass("com.usky.common.mybatis.core.CrudMapper");
+        strategy.setSuperServiceClass("com.usky.common.mybatis.core.CrudService");
+        strategy.setSuperServiceImplClass("com.usky.common.mybatis.core.AbstractCrudService");
+        // strategy.setTablePrefix("t_"); // 表名前缀
+        strategy.setEntityLombokModel(true); //使用lombok
+        //修改自己想要生成的表
+        strategy.setInclude("dmp_device_command");  // 逆向工程使用的表   如果要生成多个,这里可以传入String[]
+        mpg.setStrategy(strategy);
+
+        // 关闭默认 xml 生成,调整生成 至 根目录
+        //修改对应的模块名称
+        TemplateConfig tc = new TemplateConfig();
+        // 自定义配置
+        InjectionConfig cfg = new InjectionConfig() {
+            @Override
+            public void initMap() {
+                // to do nothing
+            }
+        };
+        //如果模板引擎是 velocity
+        String templatePath = "/templates/mapper.xml.vm";
+        // 自定义输出配置
+        List<FileOutConfig> focList = new ArrayList<>();
+        // 自定义配置会被优先输出
+        String finalProjectPath = projectPath;
+        focList.add(new FileOutConfig(templatePath) {
+            @Override
+            public String outputFile(TableInfo tableInfo) {
+                // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
+                return finalProjectPath + "/src/main/resources/mapper/transfer" + "/"
+                        + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
+            }
+        });
+        cfg.setFileOutConfigList(focList);
+        mpg.setCfg(cfg);
+        tc.setXml(null);
+        mpg.setTemplate(tc);
+        //5、执行
+        mpg.execute();
+    }
+}

+ 35 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/controller/api/DataTransferControllerApi.java

@@ -0,0 +1,35 @@
+package com.usky.transfer.controller.api;
+
+import com.usky.common.core.bean.ApiResult;
+import com.usky.transfer.RemoteTransferService;
+import com.usky.transfer.domain.*;
+import com.usky.transfer.service.QueryInfluxdbDataService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+
+@RestController
+public class DataTransferControllerApi implements RemoteTransferService {
+
+    @Autowired
+    private QueryInfluxdbDataService queryInfluxdbDataService;
+
+    /**
+     * 单个设备数据写入
+     * @return
+     */
+    @Override
+    public ApiResult<Void> sendDeviceData(DeviceDataWriteVO writeVO){
+        queryInfluxdbDataService.sendDeviceDataToMQ(writeVO);
+        return ApiResult.success();
+    }
+
+    /**
+     * 下发单个设备控制命令
+     */
+    @Override
+    public Map<String,Object> deviceControl(String productCode, String deviceId, String commandStr,Integer tenantId, Long userId, String userName){
+        return queryInfluxdbDataService.deviceControl(productCode, deviceId, commandStr, tenantId, userId, userName);
+    }
+}

+ 212 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/controller/web/QueryDeviceDataController.java

@@ -0,0 +1,212 @@
+package com.usky.transfer.controller.web;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.common.core.bean.ApiResult;
+import com.usky.common.core.bean.CommonPage;
+import com.usky.common.core.exception.BusinessException;
+import com.usky.demo.RemoteTsdbProxyService;
+import com.usky.demo.domain.HistoryRequestVO;
+import com.usky.demo.domain.HistoryResultVO;
+import com.usky.demo.domain.LastRequestVO;
+import com.usky.demo.domain.LastResultVO;
+import com.usky.transfer.domain.DmpDevice;
+import com.usky.transfer.domain.DmpDeviceCommand;
+import com.usky.transfer.service.DmpDeviceCommandService;
+import com.usky.transfer.service.DmpDeviceService;
+import com.usky.transfer.service.vo.DeviceMapVO;
+import com.usky.transfer.service.vo.ExternalHistoryRequestVO;
+import com.usky.transfer.service.vo.ExternalLastRequestVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("dataQuery")
+public class QueryDeviceDataController {
+    @Autowired
+    private RemoteTsdbProxyService remoteTsdbProxyService;
+    @Autowired
+    private DmpDeviceService dmpDeviceService;
+    @Autowired
+    private DmpDeviceCommandService dmpDeviceCommandService;
+
+    @Cacheable(cacheNames = "externalDeviceList",sync = true)
+    public Map<String, DeviceMapVO> getExternalDeviceMap(){
+        Map<String,DeviceMapVO> deviceMap = new HashMap<>();
+        LambdaQueryWrapper<DmpDevice> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(DmpDevice::getDeleteFlag,0)
+                .orderByDesc(DmpDevice::getId);
+        List<DmpDevice> list = dmpDeviceService.list(queryWrapper);
+        if(CollectionUtils.isNotEmpty(list)){
+            for (int i = 0; i < list.size(); i++) {
+                String deviceId = list.get(i).getDeviceId();
+                DeviceMapVO mapVO = new DeviceMapVO();
+                mapVO.setProductCode(list.get(i).getProductCode());
+                mapVO.setDeviceId(list.get(i).getDeviceId());
+                mapVO.setDeviceUuid(list.get(i).getDeviceUuid());
+                mapVO.setDeviceStatus(list.get(i).getServiceStatus());
+
+                deviceMap.put(deviceId,mapVO);
+            }
+        }
+
+        return deviceMap;
+    }
+
+    /**
+     * 单个设备实时数据查询(对外)
+     * @param productCode
+     * @param deviceId
+     * @return
+     */
+    @GetMapping("/externalLast")
+    public ApiResult<LastResultVO> queryLastDeviceData(@RequestParam(value = "productCode") String productCode,
+                                                       @RequestParam(value = "deviceId") String deviceId){
+        Map<String, DeviceMapVO> deviceMapList = this.getExternalDeviceMap();
+        if(!deviceMapList.containsKey(deviceId)){
+            throw new BusinessException(deviceId+"无设备信息");
+        }
+
+        String deviceUUId = "";
+
+        for (Map.Entry<String,DeviceMapVO> map:deviceMapList.entrySet()) {
+            String productCode1 = map.getValue().getProductCode();
+            String deviceId1 = map.getKey();
+            if((productCode.equals(productCode1)) && (deviceId.equals(deviceId1))){
+                deviceUUId = map.getValue().getDeviceUuid();
+            }
+        }
+
+        return ApiResult.success(remoteTsdbProxyService.queryLastDeviceData(deviceUUId));
+    }
+
+    /**
+     * 批量设备实时数据查询(对外)
+     * @param requestVO
+     * @return
+     */
+    @PostMapping("/externalLast")
+    public ApiResult<List<LastResultVO>> queryLastDeviceData(@RequestBody ExternalLastRequestVO requestVO){
+        Map<String, DeviceMapVO> deviceMapList = this.getExternalDeviceMap();
+        LastRequestVO reqVO = new LastRequestVO();
+
+        String productCode = requestVO.getProductCode();
+        List<String> deviceIds = requestVO.getDeviceId();
+        List<String> deviceUUIds = new ArrayList<>();
+        for (int i = 0; i < deviceIds.size(); i++) {
+            String deviceId = deviceIds.get(i);
+            if(!deviceMapList.containsKey(deviceId)){
+                throw new BusinessException(deviceId+"无设备信息");
+            }
+
+            for (Map.Entry<String,DeviceMapVO> map:deviceMapList.entrySet()) {
+                String productCode1 = map.getValue().getProductCode();
+                String deviceId1 = map.getKey();
+                if((productCode.equals(productCode1)) && (deviceId.equals(deviceId1))){
+                    deviceUUIds.add(map.getValue().getDeviceUuid());
+
+                }
+            }
+        }
+        reqVO.setDeviceUUId(deviceUUIds);
+
+        return ApiResult.success(remoteTsdbProxyService.queryLastDeviceData(reqVO));
+    }
+
+    /**
+     * 单个设备历史数据查询(对外)
+     * @param productCode
+     * @param deviceId
+     * @param startTime
+     * @param endTime
+     * @return
+     */
+    @GetMapping("/externalHistory")
+    public ApiResult<HistoryResultVO> queryHistoryDeviceData(@RequestParam(value = "productCode") String productCode,
+                                                             @RequestParam(value = "deviceId") String deviceId,
+                                                             @RequestParam(value = "startTime") String startTime,
+                                                             @RequestParam(value = "endTime") String endTime){
+        Map<String, DeviceMapVO> deviceMapList = this.getExternalDeviceMap();
+        if(!deviceMapList.containsKey(deviceId)){
+            throw new BusinessException(deviceId+"无设备信息");
+        }
+
+        String deviceUUId = "";
+
+        for (Map.Entry<String,DeviceMapVO> map:deviceMapList.entrySet()) {
+            String productCode1 = map.getValue().getProductCode();
+            String deviceId1 = map.getKey();
+            if((productCode.equals(productCode1)) && (deviceId.equals(deviceId1))){
+                deviceUUId = map.getValue().getDeviceUuid();
+            }
+        }
+
+        return ApiResult.success(remoteTsdbProxyService.queryHistoryDeviceData(deviceUUId,startTime,endTime));
+    }
+
+    /**
+     * 批量设备历史数据查询(对外)
+     * @param requestVO
+     * @return
+     */
+    @PostMapping("/externalHistory")
+    public ApiResult<List<HistoryResultVO>> queryHistoryDeviceData(@RequestBody ExternalHistoryRequestVO requestVO){
+        Map<String, DeviceMapVO> deviceMapList = this.getExternalDeviceMap();
+        HistoryRequestVO reqVO = new HistoryRequestVO();
+
+        String productCode = requestVO.getProductCode();
+        List<String> deviceIds = requestVO.getDeviceId();
+        List<String> deviceUUIds = new ArrayList<>();
+        for (int i = 0; i < deviceIds.size(); i++) {
+            String deviceId = deviceIds.get(i);
+            if(!deviceMapList.containsKey(deviceId)){
+                throw new BusinessException(deviceId+"无设备信息");
+            }
+
+            for (Map.Entry<String,DeviceMapVO> map:deviceMapList.entrySet()) {
+                String productCode1 = map.getValue().getProductCode();
+                String deviceId1 = map.getKey();
+                if((productCode.equals(productCode1)) && (deviceId.equals(deviceId1))){
+                    deviceUUIds.add(map.getValue().getDeviceUuid());
+
+                }
+            }
+        }
+        reqVO.setDeviceUUId(deviceUUIds);
+        reqVO.setStartTime(requestVO.getStartTime());
+        reqVO.setEndTime(requestVO.getEndTime());
+
+        return ApiResult.success(remoteTsdbProxyService.queryHistoryDeviceData(reqVO));
+    }
+
+    /**
+     * 指令记录
+     * @param commandStatus
+     * @param productCode
+     * @param deviceId
+     * @param userName
+     * @param startTime
+     * @param endTime
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @GetMapping("deviceCommandRecord")
+    public ApiResult<CommonPage<DmpDeviceCommand>> deviceCommandRecord(@RequestParam(value = "commandStatus",required = false) Integer commandStatus,
+                                                                       @RequestParam(value = "productCode",required = false) String productCode,
+                                                                       @RequestParam(value = "deviceId",required = false) String deviceId,
+                                                                       @RequestParam(value = "userName",required = false) String userName,
+                                                                       @RequestParam(value = "startTime",required = false) String startTime,
+                                                                       @RequestParam(value = "endTime",required = false) String endTime,
+                                                                       @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
+                                                                       @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize){
+        return ApiResult.success(dmpDeviceCommandService.deviceCommandRecord(commandStatus,productCode,deviceId,userName,startTime,endTime,pageNum,pageSize));
+    }
+}

+ 31 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/controller/web/SendMessageController.java

@@ -0,0 +1,31 @@
+package com.usky.transfer.controller.web;
+
+import com.usky.common.core.bean.ApiResult;
+import com.usky.transfer.domain.DeviceDataWriteVO;
+import com.usky.transfer.service.QueryInfluxdbDataService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+
+/**
+ * @Author :
+ * @CreateTime : 2024/2/29
+ * @Description :
+ **/
+@RestController
+@RequestMapping("/dataWrite")
+public class SendMessageController {
+    @Autowired
+    private QueryInfluxdbDataService queryInfluxdbDataService;
+
+    /**
+     * 单个设备数据写入
+     * @return
+     */
+    @PostMapping("/sendDeviceData")
+    public ApiResult<Map<String,Object>> sendDeviceData(@RequestBody DeviceDataWriteVO writeVO){
+        return ApiResult.success(queryInfluxdbDataService.sendDeviceDataToMQ(writeVO));
+    }
+
+}

+ 141 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/domain/DmpDevice.java

@@ -0,0 +1,141 @@
+package com.usky.transfer.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 设备信息表
+ * </p>
+ *
+ * @author ya
+ * @since 2024-09-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class DmpDevice implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键id
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 设备ID;设备注册时系统自动生成一个唯一编号
+     */
+    private String deviceId;
+
+    /**
+     * 设备名称
+     */
+    private String deviceName;
+
+    /**
+     * 设备类型(501、监控系统  502、门禁系统  503、梯控系统  504、机房系统  509、环境系统  510、照明系统)
+     */
+    private Integer deviceType;
+
+    /**
+     * 产品ID
+     */
+    private Integer productId;
+
+    /**
+     * 物联网卡号
+     */
+    private String simCode;
+
+    /**
+     * 国际移动用户识别码
+     */
+    private String imsiCode;
+
+    /**
+     * 自动订阅标识(0:否,1:是)
+     */
+    private Integer subscribeFlag;
+
+    /**
+     * 节点类型
+     */
+    private Integer nodeType;
+
+    /**
+     * 分组id
+     */
+    private Integer groupId;
+
+    /**
+     * 删除标识
+     */
+    private Integer deleteFlag;
+
+    /**
+     * 创建人
+     */
+    private String createdBy;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createdTime;
+
+    /**
+     * 更新人
+     */
+    private String updatedBy;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updatedTime;
+
+    /**
+     * 租户号
+     */
+    private Integer tenantId;
+
+    /**
+     * 单位编号
+     */
+    private String companyCode;
+
+    /**
+     * 安装位置
+     */
+    private String installAddress;
+
+    /**
+     * 业务状态;1:未激活,2:已激活,3:禁用
+     */
+    private Integer serviceStatus;
+
+    /**
+     * 产品编码
+     */
+    private String productCode;
+
+    /**
+     * 设备uuid
+     */
+    private String deviceUuid;
+
+    /**
+     * 经度
+     */
+    private String longitude;
+
+    /**
+     * 纬度
+     */
+    private String latitude;
+
+
+}

+ 96 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/domain/DmpDeviceCommand.java

@@ -0,0 +1,96 @@
+package com.usky.transfer.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 创建下发命令历史记录表
+ * </p>
+ *
+ * @author ya
+ * @since 2024-09-24
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class DmpDeviceCommand implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键id
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 产品编码
+     */
+    private String productCode;
+
+    /**
+     * 设备编码
+     */
+    private String deviceId;
+
+    /**
+     * 下发命令内容
+     */
+    private String commandContent;
+
+    /**
+     * 下发命令响应内容
+     */
+    private String commandResponse;
+
+    /**
+     * 命令状态;0 命令执行中,1 命令成功,2 命令失败
+     */
+    private Integer commandStatus;
+
+    /**
+     * 创建人
+     */
+    private String createdBy;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createdTime;
+
+    /**
+     * 更新人
+     */
+    private String updatedBy;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updatedTime;
+
+    /**
+     * 组织结构ID
+     */
+    private Integer deptId;
+
+    /**
+     * 租户ID
+     */
+    private Integer tenantId;
+
+    /**
+     * 操作人
+     */
+    private String userName;
+
+    /**
+     * 操作人Id
+     */
+    private Long userId;
+
+
+}

+ 61 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/domain/DmpDeviceStatus.java

@@ -0,0 +1,61 @@
+package com.usky.transfer.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 设备状态表
+ * </p>
+ *
+ * @author ya
+ * @since 2024-09-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class DmpDeviceStatus implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键id
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 设备ID;设备注册时系统自动生成一个唯一编号
+     */
+    private String deviceId;
+
+    /**
+     * 产品ID
+     */
+    private Integer productId;
+
+    /**
+     * 设备状态;1:在线,2:离线
+     */
+    private Integer deviceStatus;
+
+    /**
+     * 最后上线时间
+     */
+    private LocalDateTime lastOnlineTime;
+
+    /**
+     * 最后离线时间
+     */
+    private LocalDateTime lastOfflineTime;
+
+    /**
+     * 产品编码
+     */
+    private String productCode;
+
+
+}

+ 141 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/domain/DmpProduct.java

@@ -0,0 +1,141 @@
+package com.usky.transfer.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 产品信息表
+ * </p>
+ *
+ * @author ya
+ * @since 2024-09-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class DmpProduct implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键id
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 产品名称
+     */
+    private String productName;
+
+    /**
+     * 接入方式(1、设备直连  2、网关接入)
+     */
+    private Integer accessMode;
+
+    /**
+     * 网络类型(1、WIFI  2、移动蜂窝数据 3、NB-IoT 4、以太网)
+     */
+    private Integer networkType;
+
+    /**
+     * 设备类型(501、监控系统  502、门禁系统  503、梯控系统  504、机房系统  509、环境系统  510、照明系统)
+     */
+    private Integer deviceType;
+
+    /**
+     * 通信协议(1、MQTT  2、TCP设备直连 3、HTTP)
+     */
+    private Integer comProtocol;
+
+    /**
+     * 认证方式
+     */
+    private String authMode;
+
+    /**
+     * 设备型号
+     */
+    private String deviceModel;
+
+    /**
+     * 产品描述
+     */
+    private String productDescribe;
+
+    /**
+     * 厂家名称
+     */
+    private String factoryName;
+
+    /**
+     * 厂家联系人
+     */
+    private String factoryPerson;
+
+    /**
+     * 厂家联系电话
+     */
+    private String factoryPhone;
+
+    /**
+     * 资质证书1
+     */
+    private String certificateUrl1;
+
+    /**
+     * 资质证书2
+     */
+    private String certificateUrl2;
+
+    /**
+     * 资质证书3
+     */
+    private String certificateUrl3;
+
+    /**
+     * 协议文档
+     */
+    private String agreementUrl;
+
+    /**
+     * 删除标识
+     */
+    private Integer deleteFlag;
+
+    /**
+     * 创建人
+     */
+    private String createdBy;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createdTime;
+
+    /**
+     * 更新人
+     */
+    private String updatedBy;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updatedTime;
+
+    /**
+     * 租户号
+     */
+    private Integer tenantId;
+
+    /**
+     * 产品编码
+     */
+    private String productCode;
+
+
+}

+ 27 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/domain/QueryInfluxdbData.java

@@ -0,0 +1,27 @@
+package com.usky.transfer.domain;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author ya
+ * @since 2024-07-29
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class QueryInfluxdbData implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    private String influxdbName;
+
+
+}

+ 16 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/mapper/DmpDeviceCommandMapper.java

@@ -0,0 +1,16 @@
+package com.usky.transfer.mapper;
+
+import com.usky.transfer.domain.DmpDeviceCommand;
+import com.usky.common.mybatis.core.CrudMapper;
+
+/**
+ * <p>
+ * 创建下发命令历史记录表 Mapper 接口
+ * </p>
+ *
+ * @author ya
+ * @since 2024-09-24
+ */
+public interface DmpDeviceCommandMapper extends CrudMapper<DmpDeviceCommand> {
+
+}

+ 16 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/mapper/DmpDeviceMapper.java

@@ -0,0 +1,16 @@
+package com.usky.transfer.mapper;
+
+import com.usky.common.mybatis.core.CrudMapper;
+import com.usky.transfer.domain.DmpDevice;
+
+/**
+ * <p>
+ * 设备信息表 Mapper 接口
+ * </p>
+ *
+ * @author ya
+ * @since 2024-09-19
+ */
+public interface DmpDeviceMapper extends CrudMapper<DmpDevice> {
+
+}

+ 19 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/mapper/DmpDeviceStatusMapper.java

@@ -0,0 +1,19 @@
+package com.usky.transfer.mapper;
+
+import com.usky.common.mybatis.core.CrudMapper;
+import com.usky.transfer.domain.DmpDeviceStatus;
+
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * <p>
+ * 设备状态表 Mapper 接口
+ * </p>
+ *
+ * @author ya
+ * @since 2022-10-08
+ */
+public interface DmpDeviceStatusMapper extends CrudMapper<DmpDeviceStatus> {
+}

+ 16 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/mapper/DmpProductMapper.java

@@ -0,0 +1,16 @@
+package com.usky.transfer.mapper;
+
+import com.usky.common.mybatis.core.CrudMapper;
+import com.usky.transfer.domain.DmpProduct;
+
+/**
+ * <p>
+ * 产品信息表 Mapper 接口
+ * </p>
+ *
+ * @author ya
+ * @since 2024-09-19
+ */
+public interface DmpProductMapper extends CrudMapper<DmpProduct> {
+
+}

+ 16 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/mapper/QueryInfluxdbDataMapper.java

@@ -0,0 +1,16 @@
+package com.usky.transfer.mapper;
+
+import com.usky.common.mybatis.core.CrudMapper;
+import com.usky.transfer.domain.QueryInfluxdbData;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author ya
+ * @since 2024-07-29
+ */
+public interface QueryInfluxdbDataMapper extends CrudMapper<QueryInfluxdbData> {
+
+}

+ 19 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/DmpDeviceCommandService.java

@@ -0,0 +1,19 @@
+package com.usky.transfer.service;
+
+import com.usky.common.core.bean.CommonPage;
+import com.usky.transfer.domain.DmpDeviceCommand;
+import com.usky.common.mybatis.core.CrudService;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * <p>
+ * 创建下发命令历史记录表 服务类
+ * </p>
+ *
+ * @author ya
+ * @since 2024-09-24
+ */
+public interface DmpDeviceCommandService extends CrudService<DmpDeviceCommand> {
+
+    CommonPage<DmpDeviceCommand> deviceCommandRecord(Integer commandStatus,String productCode,String deviceId,String userName,String startTime,String endTime,Integer pageNum,Integer pageSize);
+}

+ 16 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/DmpDeviceService.java

@@ -0,0 +1,16 @@
+package com.usky.transfer.service;
+
+import com.usky.transfer.domain.DmpDevice;
+import com.usky.common.mybatis.core.CrudService;
+
+/**
+ * <p>
+ * 设备信息表 服务类
+ * </p>
+ *
+ * @author ya
+ * @since 2024-09-19
+ */
+public interface DmpDeviceService extends CrudService<DmpDevice> {
+
+}

+ 16 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/DmpDeviceStatusService.java

@@ -0,0 +1,16 @@
+package com.usky.transfer.service;
+
+import com.usky.transfer.domain.DmpDeviceStatus;
+import com.usky.common.mybatis.core.CrudService;
+
+/**
+ * <p>
+ * 设备状态表 服务类
+ * </p>
+ *
+ * @author ya
+ * @since 2024-09-19
+ */
+public interface DmpDeviceStatusService extends CrudService<DmpDeviceStatus> {
+
+}

+ 24 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/DmpProductService.java

@@ -0,0 +1,24 @@
+package com.usky.transfer.service;
+
+import com.usky.transfer.domain.DmpProduct;
+import com.usky.common.mybatis.core.CrudService;
+import com.usky.transfer.service.vo.DeviceMapVO;
+import com.usky.transfer.service.vo.ProductMapVO;
+
+import java.util.Map;
+
+/**
+ * <p>
+ * 产品信息表 服务类
+ * </p>
+ *
+ * @author ya
+ * @since 2024-09-19
+ */
+public interface DmpProductService extends CrudService<DmpProduct> {
+    void deleteProductCache();
+    void deleteDeviceCache();
+
+    Map<String, ProductMapVO> getProductMap();
+    Map<String, DeviceMapVO> getDeviceMap();
+}

+ 23 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/QueryInfluxdbDataService.java

@@ -0,0 +1,23 @@
+package com.usky.transfer.service;
+
+import com.usky.transfer.domain.*;
+import com.usky.common.mybatis.core.CrudService;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author ya
+ * @since 2024-07-29
+ */
+public interface QueryInfluxdbDataService extends CrudService<QueryInfluxdbData> {
+
+    Map<String,Object> sendDeviceDataToMQ(DeviceDataWriteVO writeVO);
+
+    Map<String,Object> deviceControl(String productCode, String deviceId, String commandStr,Integer tenantId, Long userId, String userName);
+
+}

+ 12 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/config/CodeCache.java

@@ -0,0 +1,12 @@
+package com.usky.transfer.service.config;
+
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Component
+public class CodeCache {
+    public static List<String> tablesList = new ArrayList<>();
+
+}

+ 57 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/config/TsdbConfig.java

@@ -0,0 +1,57 @@
+package com.usky.transfer.service.config;
+
+import com.usky.common.core.util.StringUtils;
+import org.influxdb.InfluxDB;
+import org.influxdb.InfluxDBFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class TsdbConfig {
+
+    @Value("${spring.influx.url}")
+    private String influxDBUrl;
+
+    @Value("${spring.influx.username}")
+    private String userName;
+
+    @Value("${spring.influx.password}")
+    private String password;
+    @Value("${spring.influx.retention_policy}")
+    private String retention_policy;
+
+    @Value("${spring.influx.database}")
+    private String database;
+
+    @Bean
+    public InfluxDB influxdb() {
+        InfluxDB influxDB = null;
+        if (StringUtils.isEmpty(userName)) {
+            influxDB = InfluxDBFactory.connect(influxDBUrl);
+        } else {
+            influxDB = InfluxDBFactory.connect(influxDBUrl, userName, password);
+        }
+        try {
+
+            /**
+             * 异步插入:
+             * enableBatch这里第一个是point的个数,第二个是时间,单位毫秒
+             * point的个数和时间是联合使用的,如果满100条或者60 * 1000毫秒
+             * 满足任何一个条件就会发送一次写的请求。
+             */
+//            influxDB.setDatabase(database).enableBatch(100, 1000 * 60, TimeUnit.MILLISECONDS);
+            influxDB.setDatabase(database);
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            //设置默认策略
+            this.retention_policy = retention_policy == null || "".equals(retention_policy) ? "autogen" : retention_policy;
+            influxDB.setRetentionPolicy(retention_policy);
+        }
+        //设置日志输出级别
+        influxDB.setLogLevel(InfluxDB.LogLevel.BASIC);
+        return influxDB;
+    }
+
+}

+ 50 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/config/mqtt/MqttBaseConfig.java

@@ -0,0 +1,50 @@
+package com.usky.transfer.service.config.mqtt;
+
+import lombok.Data;
+import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
+import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
+import org.springframework.stereotype.Component;
+
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+@Data
+@Component
+@ConfigurationProperties(prefix = "mqtt")
+public class MqttBaseConfig {
+
+	@Value("${mqtt.username}")
+	private String username;
+
+	@Value("${mqtt.password}")
+	private String password;
+
+	@Value("${mqtt.url}")
+	private String hostUrl;
+
+	@Value("${mqtt.sub-topics}")
+	private String msgTopic;
+
+	@Value("${mqtt.keep-alive-interval}")
+	//心跳间隔
+	private int keepAliveInterval;
+	@Value("${mqtt.completionTimeout}")
+	//心跳间隔
+	private int completionTimeout;
+
+
+	@Bean
+	public MqttPahoClientFactory mqttClientFactory() {
+		DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
+		MqttConnectOptions options = new MqttConnectOptions();
+		options.setServerURIs(new String[]{this.getHostUrl()});
+		options.setUserName(this.getUsername());
+		options.setPassword(this.getPassword().toCharArray());
+		factory.setConnectionOptions(options);
+		return factory;
+	}
+
+}

+ 56 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/config/mqtt/MqttInConfig.java

@@ -0,0 +1,56 @@
+package com.usky.transfer.service.config.mqtt;
+
+import com.usky.transfer.service.enums.TopListener;
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.integration.channel.DirectChannel;
+import org.springframework.integration.core.MessageProducer;
+import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
+import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
+import org.springframework.messaging.MessageChannel;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * @author yq
+ * @date 2021/11/1 16:37
+ */
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+@Configuration
+public class MqttInConfig {
+
+    @Autowired
+    private MqttBaseConfig mqttBaseConfig;
+
+    public static final String CHANNEL_NAME_INPUT = "mqttInputChannel";
+
+    @Bean(name = CHANNEL_NAME_INPUT)
+    public MessageChannel mqttInputChannel() {
+        return new DirectChannel();
+    }
+
+
+    /**
+     * 消息订阅绑定-消费者
+     *
+     * @return
+     */
+    @Bean
+    public MessageProducer inbound() {
+        String[] tops = mqttBaseConfig.getMsgTopic().split(",");
+        String clientId = "h-transfer-mqtt-in-" + System.currentTimeMillis();
+        MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(clientId,
+                mqttBaseConfig.mqttClientFactory(), tops);
+        adapter.setCompletionTimeout(mqttBaseConfig.getCompletionTimeout());
+        adapter.setConverter(new DefaultPahoMessageConverter());
+        adapter.setQos(2);
+        adapter.setOutputChannel(mqttInputChannel());
+        return adapter;
+    }
+}

+ 84 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/config/mqtt/MqttOutConfig.java

@@ -0,0 +1,84 @@
+package com.usky.transfer.service.config.mqtt;
+
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.integration.annotation.MessagingGateway;
+import org.springframework.integration.annotation.ServiceActivator;
+import org.springframework.integration.channel.DirectChannel;
+import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
+import org.springframework.integration.mqtt.support.MqttHeaders;
+import org.springframework.messaging.MessageChannel;
+import org.springframework.messaging.MessageHandler;
+import org.springframework.messaging.handler.annotation.Header;
+
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+@Configuration
+public class MqttOutConfig {
+
+    @Autowired
+    public MqttBaseConfig mqttBaseConfig;
+
+    public static final String CHANNEL_NAME_OUT = "mqttOutboundChannel";
+
+    public static final String MESSAGE_NAME = "messageOut";
+
+    public static final String DEFAULT_TOPIC = "testTopic";
+
+    /**
+     * 连接通道
+     *
+     * @return
+     */
+    @Bean(name = CHANNEL_NAME_OUT)
+    public MessageChannel mqttOutboundChannel() {
+        return new DirectChannel();
+    }
+
+    /**
+     * 发送消息和消费消息Channel可以使用相同MqttPahoClientFactory
+     *
+     * @return
+     */
+    @Bean(name = MESSAGE_NAME)
+    @ServiceActivator(inputChannel = CHANNEL_NAME_OUT)
+    public MessageHandler outbound() {
+        // 在这里进行mqttOutboundChannel的相关设置
+        String clientId = "h-transfer-mqtt-in-" + System.currentTimeMillis();
+        MqttPahoMessageHandler messageHandler =
+                new MqttPahoMessageHandler(clientId, mqttBaseConfig.mqttClientFactory());
+        //如果设置成true,发送消息时将不会阻塞。
+        messageHandler.setAsync(true);
+        messageHandler.setDefaultTopic(DEFAULT_TOPIC);
+        return messageHandler;
+    }
+
+    @MessagingGateway(defaultRequestChannel = CHANNEL_NAME_OUT)
+    public interface MqttGateway {
+        /**
+         * 发送消息
+         *
+         * @param payload
+         */
+        void sendToMqtt(String payload);
+
+        /**
+         * 指定top发送消息
+         *
+         * @param topic
+         * @param payload
+         */
+        void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, String payload);
+
+        /**
+         * 指定队列和qos
+         *
+         * @param topic
+         * @param qos
+         * @param payload
+         */
+        void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload);
+    }
+}

+ 60 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/enums/TopListener.java

@@ -0,0 +1,60 @@
+package com.usky.transfer.service.enums;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author ZYJ
+ * @date 2024/9/23 15:11
+ */
+public enum TopListener {
+
+    /**
+     * 对接设备info信息和下发命令响应信息
+     */
+    DEVICE_INFO("deviceInfo","/+/+/info",1),
+    DEVICE_CONTROLRESPONSE("deviceControlResponse","/+/+/controlResponse",1);
+
+
+
+
+    private String name;
+    private String code;
+    //0发送队列,1监听队列2都是
+    private Integer type;
+
+    TopListener(String name, String code, Integer type){
+        this.name = name;
+        this.code = code;
+        this.type = type;
+    }
+
+    public static TopListener parse(String code){
+        TopListener topListener = null;
+        for (TopListener t:TopListener.values()) {
+            if (t.getCode().equals(code)){
+                topListener = t;
+                break;
+            }
+        }
+        return topListener;
+    }
+    public static List<TopListener> parse(Integer type){
+        List<TopListener> listeners = new ArrayList<>();
+        for (TopListener t:TopListener.values()) {
+            if (t.getType().equals(type)){
+                listeners.add(t);
+            }
+        }
+        return listeners;
+    }
+    public String getCode(){
+        return code;
+    }
+    public String getName(){
+        return name;
+    }
+    public Integer getType(){
+        return type;
+    }
+}

+ 42 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/impl/DmpDeviceCommandServiceImpl.java

@@ -0,0 +1,42 @@
+package com.usky.transfer.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.usky.common.core.bean.CommonPage;
+import com.usky.common.security.utils.SecurityUtils;
+import com.usky.transfer.domain.DmpDeviceCommand;
+import com.usky.transfer.mapper.DmpDeviceCommandMapper;
+import com.usky.transfer.service.DmpDeviceCommandService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 创建下发命令历史记录表 服务实现类
+ * </p>
+ *
+ * @author ya
+ * @since 2024-09-24
+ */
+@Service
+public class DmpDeviceCommandServiceImpl extends AbstractCrudService<DmpDeviceCommandMapper, DmpDeviceCommand> implements DmpDeviceCommandService {
+
+    @Override
+    public CommonPage<DmpDeviceCommand> deviceCommandRecord(Integer commandStatus,String productCode,String deviceId, String userName, String startTime, String endTime, Integer pageNum, Integer pageSize){
+        IPage<DmpDeviceCommand> page = new Page<>(pageNum,pageSize);
+        LambdaQueryWrapper<DmpDeviceCommand> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(commandStatus != null,DmpDeviceCommand::getCommandStatus,commandStatus)
+                .like(StringUtils.isNotBlank(productCode),DmpDeviceCommand::getProductCode,productCode)
+                .like(StringUtils.isNotBlank(deviceId),DmpDeviceCommand::getDeviceId,deviceId)
+                .like(StringUtils.isNotBlank(userName),DmpDeviceCommand::getUserName,userName)
+                .between(StringUtils.isNotBlank(startTime)&&StringUtils.isNotBlank(endTime),DmpDeviceCommand::getCreatedTime,startTime,endTime)
+                .eq(DmpDeviceCommand::getTenantId, SecurityUtils.getTenantId())
+                .orderByDesc(DmpDeviceCommand::getId);
+        page = this.page(page,queryWrapper);
+
+        return new CommonPage<>(page.getRecords(),page.getTotal(),pageSize,pageNum);
+    }
+}

+ 20 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/impl/DmpDeviceServiceImpl.java

@@ -0,0 +1,20 @@
+package com.usky.transfer.service.impl;
+
+import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.transfer.domain.DmpDevice;
+import com.usky.transfer.mapper.DmpDeviceMapper;
+import com.usky.transfer.service.DmpDeviceService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 设备信息表 服务实现类
+ * </p>
+ *
+ * @author ya
+ * @since 2024-09-19
+ */
+@Service
+public class DmpDeviceServiceImpl extends AbstractCrudService<DmpDeviceMapper, DmpDevice> implements DmpDeviceService {
+
+}

+ 22 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/impl/DmpDeviceStatusServiceImpl.java

@@ -0,0 +1,22 @@
+package com.usky.transfer.service.impl;
+
+import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.transfer.domain.DmpDeviceStatus;
+import com.usky.transfer.mapper.DmpDeviceStatusMapper;
+import com.usky.transfer.service.DmpDeviceStatusService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 设备状态表 服务实现类
+ * </p>
+ *
+ * @author ya
+ * @since 2022-10-08
+ */
+@Service
+public class DmpDeviceStatusServiceImpl extends AbstractCrudService<DmpDeviceStatusMapper, DmpDeviceStatus> implements DmpDeviceStatusService {
+}

+ 97 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/impl/DmpProductServiceImpl.java

@@ -0,0 +1,97 @@
+package com.usky.transfer.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.transfer.domain.DmpDevice;
+import com.usky.transfer.domain.DmpProduct;
+import com.usky.transfer.mapper.DmpProductMapper;
+import com.usky.transfer.service.DmpDeviceService;
+import com.usky.transfer.service.DmpProductService;
+import com.usky.transfer.service.vo.DeviceMapVO;
+import com.usky.transfer.service.vo.ProductMapVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 产品信息表 服务实现类
+ * </p>
+ *
+ * @author ya
+ * @since 2024-09-19
+ */
+@Service
+public class DmpProductServiceImpl extends AbstractCrudService<DmpProductMapper, DmpProduct> implements DmpProductService {
+
+    @Autowired
+    private DmpDeviceService dmpDeviceService;
+
+    //清除产品缓存
+    @CacheEvict(cacheNames = "productList")
+    public void deleteProductCache(){
+        System.out.println("deleteProductCache");
+    }
+
+    //清除设备缓存
+    @CacheEvict(cacheNames = "deviceList")
+    public void deleteDeviceCache(){
+        System.out.println("deleteDeviceCache");
+    }
+
+    @Cacheable(cacheNames = "productList",sync = true)
+    public Map<String, ProductMapVO> getProductMap(){
+        Map<String,ProductMapVO> productMap = new HashMap<>();
+        LambdaQueryWrapper<DmpProduct> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(DmpProduct::getDeleteFlag,0)
+                .orderByDesc(DmpProduct::getId);
+        List<DmpProduct> list = this.list(queryWrapper);
+        if(CollectionUtils.isNotEmpty(list)){
+            for (int i = 0; i < list.size(); i++) {
+                String productCode = list.get(i).getProductCode();
+                ProductMapVO mapVO = new ProductMapVO();
+                mapVO.setProductId(list.get(i).getId());
+                mapVO.setProductCode(list.get(i).getProductCode());
+                mapVO.setCreatedBy(list.get(i).getCreatedBy());
+                mapVO.setTenantId(list.get(i).getTenantId());
+                mapVO.setDeviceType(list.get(i).getDeviceType());
+
+                productMap.put(productCode,mapVO);
+            }
+        }
+
+
+        return productMap;
+    }
+
+    @Cacheable(cacheNames = "deviceList",sync = true)
+    public Map<String, DeviceMapVO> getDeviceMap(){
+        Map<String,DeviceMapVO> deviceMap = new HashMap<>();
+        LambdaQueryWrapper<DmpDevice> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(DmpDevice::getDeleteFlag,0)
+                .orderByDesc(DmpDevice::getId);
+        List<DmpDevice> list = dmpDeviceService.list(queryWrapper);
+        if(CollectionUtils.isNotEmpty(list)){
+            for (int i = 0; i < list.size(); i++) {
+                String deviceId = list.get(i).getDeviceId();
+                DeviceMapVO mapVO = new DeviceMapVO();
+                mapVO.setProductCode(list.get(i).getProductCode());
+                mapVO.setDeviceId(list.get(i).getDeviceId());
+                mapVO.setDeviceUuid(list.get(i).getDeviceUuid());
+                mapVO.setDeviceStatus(list.get(i).getServiceStatus());
+
+                deviceMap.put(deviceId,mapVO);
+            }
+        }
+
+        return deviceMap;
+    }
+}

+ 245 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/impl/QueryInfluxdbDataServiceImpl.java

@@ -0,0 +1,245 @@
+package com.usky.transfer.service.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.nacos.shaded.com.google.protobuf.Internal;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.common.core.util.UUIDUtils;
+import com.usky.common.security.utils.SecurityUtils;
+import com.usky.transfer.domain.*;
+import com.usky.transfer.mapper.QueryInfluxdbDataMapper;
+import com.usky.transfer.service.*;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.transfer.service.config.mqtt.MqttOutConfig;
+import com.usky.transfer.service.rocketmq.MyProducer;
+import com.usky.transfer.service.utils.TsdbUtils;
+import com.usky.transfer.service.vo.DeviceMapVO;
+import com.usky.transfer.service.vo.ProductMapVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.*;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author ya
+ * @since 2024-07-29
+ */
+@Slf4j
+@Service
+public class QueryInfluxdbDataServiceImpl extends AbstractCrudService<QueryInfluxdbDataMapper, QueryInfluxdbData> implements QueryInfluxdbDataService {
+    @Autowired
+    private TsdbUtils tsdbUtils;
+    @Autowired
+    private DmpProductService dmpProductService;
+    @Autowired
+    private DmpDeviceService dmpDeviceService;
+    @Autowired
+    private DmpDeviceStatusService dmpDeviceStatusService;
+    @Autowired
+    private DmpDeviceCommandService dmpDeviceCommandService;
+
+    @Resource
+    private MyProducer myProducer;
+    @Resource
+    private MqttOutConfig.MqttGateway mqttGateway;
+
+    @Override
+    public Map<String,Object> deviceControl(String productCode, String deviceId, String commandStr,Integer tenantId, Long userId, String userName){
+        Map<String,Object> rec_map = new HashMap<>();
+
+
+        //存储下发设备控制命令到数据库表中
+        DmpDeviceCommand command = new DmpDeviceCommand();
+        command.setProductCode(productCode);
+        if(StringUtils.isNotBlank(deviceId)){
+            command.setDeviceId(deviceId);
+        }
+
+        command.setCommandContent(commandStr);
+        command.setCreatedTime(LocalDateTime.now());
+//        if (Objects.nonNull(SecurityUtils.getLoginUser().getSysUser().getDeptId())){
+//            command.setDeptId(SecurityUtils.getLoginUser().getSysUser().getDeptId().intValue());
+//        }
+
+        command.setTenantId(tenantId);
+        command.setUserId(userId);
+        command.setUserName(userName);
+        dmpDeviceCommandService.save(command);
+        int commandId = command.getId();
+
+        JSONObject dataJson = JSONObject.parseObject(commandStr);
+        dataJson.put("id",commandId);
+
+        command.setCommandContent(dataJson.toJSONString());
+        dmpDeviceCommandService.updateById(command);
+        //推送下发设备控制mqtt
+        if(StringUtils.isNotBlank(commandStr)){
+            String topic = "/"+productCode+"/"+deviceId+"/control";
+            mqttGateway.sendToMqtt(topic,dataJson.toJSONString());
+        }
+
+        long startTimeStamp = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
+        while (true){
+            LambdaQueryWrapper<DmpDeviceCommand> queryWrapper = Wrappers.lambdaQuery();
+            queryWrapper.eq(DmpDeviceCommand::getId,commandId);
+            DmpDeviceCommand one = dmpDeviceCommandService.getOne(queryWrapper);
+            if(Objects.nonNull(one.getCommandResponse())){
+                rec_map.put("code",200);
+                rec_map.put("message","下发命令成功");
+                rec_map.put("data",one.getCommandResponse());
+                break;
+            }
+
+            long endTimeStamp = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
+            if((endTimeStamp - startTimeStamp) >= 3){ //请求超时3秒,返回失败
+                rec_map.put("code",-1);
+                rec_map.put("message","下发命令失败");
+                break;
+            }
+        }
+
+        return rec_map;
+    }
+
+    @Override
+    public Map<String,Object> sendDeviceDataToMQ(DeviceDataWriteVO writeVO){
+        Map<String,Object> rec_map = new HashMap<>();
+        DeviceDataInfoVO dataInfo = new DeviceDataInfoVO();
+        Map<String,Object> metrics = writeVO.getMetrics();
+        Map<String,String> tags = writeVO.getTags();
+        if(metrics.size() > 0){
+            Map<String,Object> mp = new HashMap<>();
+            Map<String,Object> mp_tag = new HashMap<>();
+            for(Map.Entry<String,Object> map:metrics.entrySet()){
+                mp.put(map.getKey(),map.getValue());
+            }
+            dataInfo.setMetrics(mp);
+            if(tags != null && tags.size() > 0){
+                for(Map.Entry<String,String> map:tags.entrySet()){
+                    mp_tag.put(map.getKey(),map.getValue());
+                }
+                dataInfo.setTags(mp_tag);
+            }else{
+                dataInfo.setTags(new HashMap<>());
+            }
+
+            String productCode = writeVO.getProductCode();
+            String deviceUUId = writeVO.getDeviceUUId();
+            String deviceId = tags.get("deviceId");
+
+            //判断上报数据对应产品是否注册,如未注册则为非法
+            Map<String,ProductMapVO> productMapList = dmpProductService.getProductMap();
+            if(!productMapList.containsKey(productCode)){
+                //通过查询数据库再确认下产品是否注册
+                LambdaQueryWrapper<DmpProduct> queryWrapper = Wrappers.lambdaQuery();
+                queryWrapper.eq(DmpProduct::getDeleteFlag,0)
+                        .eq(DmpProduct::getProductCode,productCode);
+                DmpProduct one = dmpProductService.getOne(queryWrapper);
+                if(one == null){
+                    rec_map.put("code",201) ;
+                    rec_map.put("message","产品未注册!");
+                    log.info("产品未注册");
+                    return rec_map;
+                }else{
+                    dmpProductService.deleteProductCache();
+                }
+            }
+
+            //判断上报数据设备是否已注册(要判断注册过的设备是不是属于本产品的),未注册自动注册
+            Map<String,DeviceMapVO> deviceMapList = dmpProductService.getDeviceMap();
+            if(!deviceMapList.containsKey(deviceId)){
+                DmpDevice dmpDeviceInfo = new DmpDevice();
+                ProductMapVO productMapVO = productMapList.get(productCode);
+                dmpDeviceInfo.setDeviceId(deviceId);
+                dmpDeviceInfo.setDeviceName("");
+                dmpDeviceInfo.setDeviceType(productMapVO.getDeviceType());
+                dmpDeviceInfo.setProductId(productMapVO.getProductId());
+                dmpDeviceInfo.setProductCode(productCode);
+                dmpDeviceInfo.setCreatedBy(productMapVO.getCreatedBy());
+                dmpDeviceInfo.setCreatedTime(LocalDateTime.now());
+                dmpDeviceInfo.setTenantId(productMapVO.getTenantId());
+                dmpDeviceInfo.setServiceStatus(1);
+                dmpDeviceInfo.setDeviceUuid(UUIDUtils.uuid());
+                dmpDeviceService.save(dmpDeviceInfo);
+
+                deviceUUId = dmpDeviceInfo.getDeviceUuid();
+
+                DmpDeviceStatus dmpDeviceStatus = new DmpDeviceStatus();
+                dmpDeviceStatus.setDeviceId(dmpDeviceInfo.getDeviceId());
+                dmpDeviceStatus.setProductId(dmpDeviceInfo.getProductId());
+                dmpDeviceStatus.setDeviceStatus(2);
+                dmpDeviceStatus.setLastOfflineTime(LocalDateTime.now());
+                dmpDeviceStatus.setProductCode(dmpDeviceInfo.getProductCode());
+                dmpDeviceStatusService.save(dmpDeviceStatus);
+
+                dmpProductService.deleteDeviceCache();
+            }else if(deviceMapList.containsKey(deviceId)){
+                LambdaQueryWrapper<DmpDevice> queryWrapper = Wrappers.lambdaQuery();
+                queryWrapper.eq(DmpDevice::getDeleteFlag,0)
+                        .eq(DmpDevice::getProductCode,productCode)
+                        .eq(DmpDevice::getDeviceId,deviceId);
+                DmpDevice one = dmpDeviceService.getOne(queryWrapper);
+                if(one == null){
+                    DmpDevice dmpDeviceInfo = new DmpDevice();
+                    ProductMapVO productMapVO = productMapList.get(productCode);
+                    dmpDeviceInfo.setDeviceId(deviceId);
+                    dmpDeviceInfo.setDeviceName("");
+                    dmpDeviceInfo.setDeviceType(productMapVO.getDeviceType());
+                    dmpDeviceInfo.setProductId(productMapVO.getProductId());
+                    dmpDeviceInfo.setProductCode(productCode);
+                    dmpDeviceInfo.setCreatedBy(productMapVO.getCreatedBy());
+                    dmpDeviceInfo.setCreatedTime(LocalDateTime.now());
+                    dmpDeviceInfo.setTenantId(productMapVO.getTenantId());
+                    dmpDeviceInfo.setServiceStatus(1);
+                    dmpDeviceInfo.setDeviceUuid(UUIDUtils.uuid());
+                    dmpDeviceService.save(dmpDeviceInfo);
+
+                    deviceUUId = dmpDeviceInfo.getDeviceUuid();
+
+                    DmpDeviceStatus dmpDeviceStatus = new DmpDeviceStatus();
+                    dmpDeviceStatus.setDeviceId(dmpDeviceInfo.getDeviceId());
+                    dmpDeviceStatus.setProductId(dmpDeviceInfo.getProductId());
+                    dmpDeviceStatus.setDeviceStatus(2);
+                    dmpDeviceStatus.setLastOfflineTime(LocalDateTime.now());
+                    dmpDeviceStatus.setProductCode(dmpDeviceInfo.getProductCode());
+                    dmpDeviceStatusService.save(dmpDeviceStatus);
+
+                    dmpProductService.deleteDeviceCache();
+                }
+            }
+
+            if(StringUtils.isBlank(deviceUUId)){
+                for (Map.Entry<String,DeviceMapVO> map:deviceMapList.entrySet()) {
+                    String productCode1 = map.getValue().getProductCode();
+                    String deviceId1 = map.getKey();
+                    if((productCode.equals(productCode1)) && (deviceId.equals(deviceId1))){
+                        deviceUUId = map.getValue().getDeviceUuid();
+                    }
+                }
+            }
+
+            dataInfo.setProductCode(productCode);
+            dataInfo.setDeviceUUId(deviceUUId);
+            dataInfo.setTimestamp(writeVO.getTimestamp());
+
+            myProducer.sendMessage("data-tsdb", JSONArray.toJSON(dataInfo).toString());
+        }
+
+        rec_map.put("code",200);
+        rec_map.put("message","操作成功!");
+        return rec_map;
+    }
+
+}

+ 60 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/listener/MqttListener.java

@@ -0,0 +1,60 @@
+package com.usky.transfer.service.listener;
+
+
+import com.usky.transfer.service.config.mqtt.MqttInConfig;
+import com.usky.transfer.service.enums.TopListener;
+import com.usky.transfer.service.mqtt.SimpleContext;
+import com.usky.transfer.service.vo.MqttBaseVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Bean;
+import org.springframework.integration.annotation.ServiceActivator;
+import org.springframework.messaging.MessageHandler;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author yq
+ * @date 2021/11/3 8:13
+ */
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+@Slf4j
+@Component
+public class MqttListener {
+
+    public static final String MESSAGE_NAME = "messageInput";
+
+    @Autowired
+    private SimpleContext simpleContext;
+
+    /**
+     * 处理消息-消费者
+     *
+     * @return
+     */
+    @Bean(MESSAGE_NAME)
+    @ServiceActivator(inputChannel = MqttInConfig.CHANNEL_NAME_INPUT)
+    public MessageHandler handler() {
+        return message -> {
+            String payload = message.getPayload().toString();
+            //进行接口推送
+//            String[] infoCode = TopListener.DEVICE_INFO.getCode().split("/");
+//            String[] controlCode = TopListener.DEVICE_CONTROLRESPONSE.getCode().split("/");
+            Object mqttReceivedTopic = message.getHeaders().get("mqtt_receivedTopic");
+            if (null != mqttReceivedTopic) {
+                String topic = mqttReceivedTopic.toString();
+                MqttBaseVO mqttBaseVO = new MqttBaseVO();
+                mqttBaseVO.setTopic(topic);
+                if (topic.indexOf("info") != -1 ) {
+                    mqttBaseVO.setDescribe("info");
+                    mqttBaseVO.setData(payload);
+                }else if(topic.indexOf("controlResponse") != -1 ) {
+                    mqttBaseVO.setDescribe("controlResponse");
+                    mqttBaseVO.setData(payload);
+                }
+                //统一处理数据
+                simpleContext.getResource(mqttBaseVO);
+            }
+        };
+    }
+}

+ 21 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/mqtt/MqttStrategy.java

@@ -0,0 +1,21 @@
+package com.usky.transfer.service.mqtt;
+
+
+import com.usky.transfer.service.vo.MqttBaseVO;
+
+/**
+ * 策略类
+ *
+ * @author yq
+ * @date 2021/11/3 8:27
+ */
+public interface MqttStrategy {
+    /**
+     * 处理消息(策略模式由子类实现)
+     *
+     * @param mqttBaseVO
+     * @return
+     */
+    String disposeMessage(MqttBaseVO mqttBaseVO);
+
+}

+ 26 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/mqtt/SimpleContext.java

@@ -0,0 +1,26 @@
+package com.usky.transfer.service.mqtt;
+
+
+import com.usky.transfer.service.vo.MqttBaseVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 中间处理消息转发
+ */
+@Service
+public class SimpleContext {
+    @Autowired
+    private final Map<String, MqttStrategy> strategyMap = new ConcurrentHashMap<>();
+
+    public SimpleContext(Map<String, MqttStrategy> strategyMap) {
+        strategyMap.forEach(this.strategyMap::put);
+    }
+
+    public String getResource(MqttBaseVO mqttBaseVO) {
+        return strategyMap.get(mqttBaseVO.getDescribe()).disposeMessage(mqttBaseVO);
+    }
+}

+ 53 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/mqtt/control/control.java

@@ -0,0 +1,53 @@
+package com.usky.transfer.service.mqtt.control;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.usky.common.core.util.JsonUtils;
+import com.usky.common.security.utils.SecurityUtils;
+import com.usky.transfer.domain.DeviceDataWriteVO;
+import com.usky.transfer.domain.DmpDeviceCommand;
+import com.usky.transfer.service.DmpDeviceCommandService;
+import com.usky.transfer.service.QueryInfluxdbDataService;
+import com.usky.transfer.service.mqtt.MqttStrategy;
+import com.usky.transfer.service.rocketmq.MyProducer;
+import com.usky.transfer.service.vo.MqttBaseVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.HashMap;
+import java.util.Map;
+
+@Service("controlResponse")
+public class control implements MqttStrategy {
+    @Autowired
+    private DmpDeviceCommandService dmpDeviceCommandService;
+
+    //处理下发命令响应消息
+    public String disposeMessage(MqttBaseVO mqttBaseVO) {
+
+        //存储下发设备控制命令到数据库表中
+        DmpDeviceCommand command = new DmpDeviceCommand();
+
+        String recData = mqttBaseVO.getData().toString();
+        JSONObject dataJson = JSONObject.parseObject(recData);
+        Integer commandId = Integer.valueOf(dataJson.get("id").toString());
+        command.setId(commandId);
+        command.setCommandResponse(recData);
+        if(recData.contains("error")){
+            command.setCommandStatus(2);
+        }else{
+            command.setCommandStatus(1);
+        }
+
+        command.setUpdatedTime(LocalDateTime.now());
+
+        dmpDeviceCommandService.updateById(command);
+
+        return null;
+    }
+
+
+}

+ 73 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/mqtt/info/Info.java

@@ -0,0 +1,73 @@
+package com.usky.transfer.service.mqtt.info;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.common.core.exception.BusinessException;
+import com.usky.common.core.util.JsonUtils;
+import com.usky.transfer.domain.*;
+import com.usky.transfer.service.*;
+import com.usky.transfer.service.mqtt.MqttStrategy;
+import com.usky.transfer.service.rocketmq.MyProducer;
+import com.usky.transfer.service.vo.MqttBaseVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author zyj
+ * @date 2022/12/6 15:07
+ */
+@Service("info")
+public class Info implements MqttStrategy {
+    @Resource
+    private MyProducer myProducer;
+    @Autowired
+    private QueryInfluxdbDataService queryInfluxdbDataService;
+
+    public String disposeMessage(MqttBaseVO mqttBaseVO) {
+        Map<String, String> tags = new HashMap<>();
+        Map<String, Object> fields = new HashMap<>();
+        Map map_data = JsonUtils.fromJson(mqttBaseVO.getData().toString(), Map.class);
+        String deviceId = map_data.get("device_id").toString();
+        String productCode = map_data.get("product_code").toString().toLowerCase();
+        Long timestamp = Long.valueOf(map_data.get("timestamp").toString());
+
+        String tableName = deviceId;
+
+        Object tg = JSONObject.toJSONString(map_data.get("tags"));
+        JSONObject tag = JSON.parseObject(tg.toString());
+        for (String entry : tag.keySet()){
+            tags.put(entry.toLowerCase(),tag.get(entry).toString());
+        }
+
+        Object met = JSONObject.toJSONString(map_data.get("metrics"));
+        JSONObject metrics = JSON.parseObject(met.toString());
+        for(String entry : metrics.keySet()){
+            fields.put(entry.toLowerCase(),metrics.get(entry));
+        }
+
+        DeviceDataWriteVO deviceDataWriteVO = new DeviceDataWriteVO();
+        deviceDataWriteVO.setDeviceUUId(deviceId);
+        deviceDataWriteVO.setProductCode(productCode);
+        deviceDataWriteVO.setTimestamp(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
+        deviceDataWriteVO.setTags(tags);
+        deviceDataWriteVO.setMetrics(metrics);
+
+        queryInfluxdbDataService.sendDeviceDataToMQ(deviceDataWriteVO);
+
+        return null;
+    }
+
+
+}

+ 21 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/rocketmq/MyConsumer.java

@@ -0,0 +1,21 @@
+package com.usky.transfer.service.rocketmq;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
+import org.apache.rocketmq.spring.core.RocketMQListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+//@Slf4j
+//@Component
+//@RocketMQMessageListener(consumerGroup = "${rocketmq.consumer.group}", topic = "${rocketmq.consumer.topic}")
+//public class MyConsumer implements RocketMQListener<String> {
+//    @Autowired
+//    private RocketMQSimpleContext simpleContext;
+//
+//    @Override
+//    public void onMessage(String message){
+//        System.out.println("DirectReceiver消费者收到消息: " + message);
+//        simpleContext.disposeMessageToDB(message);
+//    }
+//}

+ 17 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/rocketmq/MyProducer.java

@@ -0,0 +1,17 @@
+package com.usky.transfer.service.rocketmq;
+
+import org.apache.rocketmq.spring.core.RocketMQTemplate;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+@Component
+public class MyProducer {
+    @Resource
+    private RocketMQTemplate rocketMQTemplate;
+    //发送普通消息的示例
+    public void sendMessage(String topic, String msg) {
+        rocketMQTemplate.convertAndSend(topic, msg);
+
+    }
+}

+ 80 - 0
data-transfer/data-transfer-biz/src/main/java/com/usky/transfer/service/rocketmq/RocketMQSimpleContext.java

@@ -0,0 +1,80 @@
+//package com.usky.transfer.service.rocketmq;
+//
+//import com.alibaba.fastjson.JSON;
+//import com.alibaba.fastjson.JSONObject;
+//import com.alibaba.nacos.shaded.com.google.gson.JsonArray;
+//import com.usky.common.core.util.JsonUtils;
+//import com.usky.transfer.domain.DeviceDataInfoVO;
+//import com.usky.transfer.domain.DeviceDataWriteVO;
+//import com.usky.transfer.service.QueryInfluxdbDataService;
+//import com.usky.transfer.service.utils.TsdbUtils;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.stereotype.Repository;
+//import org.springframework.stereotype.Service;
+//
+//import javax.annotation.Resource;
+//import java.time.LocalDateTime;
+//import java.time.ZoneOffset;
+//import java.util.*;
+//
+///**
+// * 中间处理消息转发
+// */
+//@Service
+//@Repository
+//public class RocketMQSimpleContext {
+//    @Resource
+//    private MyProducer myProducer;
+//    @Autowired
+//    private QueryInfluxdbDataService queryInfluxdbDataService;
+//
+//    /**
+//     * 设备数据推送到MQ队列
+//     * @param
+//     */
+//    public void disposeMessageToDB(String message){
+//        Map<String, String> tags = new HashMap<>();
+//        Map<String, Object> fields = new HashMap<>();
+//        Map map_data = JsonUtils.fromJson(message,Map.class);
+//        String deviceId = map_data.get("deviceUUId").toString();
+//        String productCode = map_data.get("productCode").toString().toLowerCase();
+//        Long timestamp = Long.valueOf(map_data.get("timestamp").toString());
+//
+//        String tableName = deviceId;
+//
+//        Object tg = JSONObject.toJSONString(map_data.get("tags"));
+//        JSONObject tag = JSON.parseObject(tg.toString());
+//        for (String entry : tag.keySet()){
+//            tags.put(entry.toLowerCase(),tag.get(entry).toString());
+//        }
+//
+//        Object met = JSONObject.toJSONString(map_data.get("metrics"));
+//        JSONObject metrics = JSON.parseObject(met.toString());
+//        for(String entry : metrics.keySet()){
+//            fields.put(entry.toLowerCase(),metrics.get(entry));
+//        }
+//
+//        DeviceDataWriteVO deviceDataWriteVO = new DeviceDataWriteVO();
+//        deviceDataWriteVO.setDeviceUUId(deviceId);
+//        deviceDataWriteVO.setProductCode(productCode);
+//        deviceDataWriteVO.setTimestamp(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
+//        deviceDataWriteVO.setTags(tags);
+//        deviceDataWriteVO.setMetrics(metrics);
+//
+//        queryInfluxdbDataService.sendDeviceDataToMQ(deviceDataWriteVO);
+//    }
+//}
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//
+//

Неке датотеке нису приказане због велике количине промена