#840 万象城增加告警查询,外滩27号增加数据转发

已關閉
hanzhengyi 請求將 59 次代碼提交從 uskycloud/han 合併至 uskycloud/server-165
共有 100 個文件被更改,包括 4988 次插入1857 次删除
  1. 3 0
      pom.xml
  2. 1 0
      service-agbox/service-agbox-biz/pom.xml
  3. 7 1
      service-agbox/service-agbox-biz/src/main/java/com/usky/agbox/service/mqtt/event/event.java
  4. 1 1
      service-agbox/service-agbox-biz/src/main/resources/logback.xml
  5. 1 0
      service-alarm/service-alarm-biz/pom.xml
  6. 3 3
      service-cdi/pom.xml
  7. 31 0
      service-cdi/service-cdi-api/pom.xml
  8. 13 0
      service-cdi/service-cdi-api/src/main/java/com/usky/cdi/RemotecdiTaskService.java
  9. 25 0
      service-cdi/service-cdi-api/src/main/java/com/usky/cdi/factory/RemotecdiTaskFactory.java
  10. 15 42
      service-cdi/service-cdi-biz/pom.xml
  11. 4 22
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/RuoYiSystemApplication.java
  12. 56 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/AlarmDataController.java
  13. 84 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/BaseDataController.java
  14. 67 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/IotDataController.java
  15. 7 7
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/MybatisGeneratorUtils.java
  16. 25 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/api/RemotecdiTaskApi.java
  17. 21 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/web/BaseBuildFacilityController.java
  18. 33 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/web/DmpDeviceInfoController.java
  19. 9 7
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/web/DmpProductController.java
  20. 162 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/domain/BaseBuildFacility.java
  21. 132 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/domain/DmpDevice.java
  22. 141 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/domain/DmpProduct.java
  23. 16 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/mapper/BaseBuildFacilityMapper.java
  24. 16 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/mapper/DmpDeviceMapper.java
  25. 16 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/mapper/DmpProductMapper.java
  26. 18 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/BaseBuildFacilityService.java
  27. 25 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/DmpDeviceInfoService.java
  28. 16 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/DmpProductService.java
  29. 52 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/config/mqtt/MqttBaseConfig.java
  30. 52 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/config/mqtt/MqttInConfig.java
  31. 97 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/config/mqtt/MqttOutConfig.java
  32. 45 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/enums/EnvMonitorMqttTopic.java
  33. 163 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/impl/AlarmDataTransferService.java
  34. 32 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/impl/BaseBuildFacilityServiceImpl.java
  35. 325 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/impl/BaseDataTransferService.java
  36. 35 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/impl/DmpDeviceInfoServiceImpl.java
  37. 20 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/impl/DmpProductServiceImpl.java
  38. 642 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/impl/IotDataTransferService.java
  39. 61 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/listener/MqttListener.java
  40. 13 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/mqtt/MqttStrategy.java
  41. 35 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/mqtt/SimpleContext.java
  42. 29 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/mqtt/event/event.java
  43. 31 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/mqtt/info/Info.java
  44. 333 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/util/DeviceDataQuery.java
  45. 41 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/util/DeviceDataSyncService.java
  46. 138 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/util/HttpClientUtils.java
  47. 34 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/util/SignUtil.java
  48. 145 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/util/SnowflakeIdGenerator.java
  49. 28 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/IotDataTransferVO.java
  50. 21 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/MqttBaseVO.java
  51. 69 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/alarm/AlarmMessage1VO.java
  52. 69 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/alarm/AlarmMessage2VO.java
  53. 74 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/alarm/AlarmMessageVO.java
  54. 93 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/BaseEnvMonitorPushVO.java
  55. 57 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/Co2VO.java
  56. 51 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/CoVO.java
  57. 159 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/ElectricityLoadVO.java
  58. 67 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/EngineeringBaseVO.java
  59. 42 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/ErrorMsgVO.java
  60. 161 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/FacilityDeviceVO.java
  61. 67 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/FloorPlaneVO.java
  62. 51 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/HumidityVO.java
  63. 51 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/OxygenVO.java
  64. 60 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/PersonPresenceVO.java
  65. 68 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/ProtectiveUnitVO.java
  66. 87 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/SensorInfoVO.java
  67. 54 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/TempVO.java
  68. 68 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/WaterLeakVO.java
  69. 3 3
      service-cdi/service-cdi-biz/src/main/resources/bootstrap.yml
  70. 108 0
      service-cdi/service-cdi-biz/src/main/resources/doc/index.adoc
  71. 94 0
      service-cdi/service-cdi-biz/src/main/resources/logback.xml
  72. 38 0
      service-cdi/service-cdi-biz/src/main/resources/mapper/cdi/BaseBuildFacilityMapper.xml
  73. 30 0
      service-cdi/service-cdi-biz/src/main/resources/mapper/cdi/DmpDeviceMapper.xml
  74. 32 0
      service-cdi/service-cdi-biz/src/main/resources/mapper/cdi/DmpProductMapper.xml
  75. 15 0
      service-cdi/service-cdi-biz/src/main/resources/smart-doc.json
  76. 0 13
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/ServletInitializer.java
  77. 0 118
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/base/BaseController.java
  78. 0 24
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/config/CorsConfig.java
  79. 0 2
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/config/DateStringConvert.java
  80. 0 20
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/config/MybatisPlusConfig.java
  81. 0 2
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/config/StringDateConverter.java
  82. 0 72
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/config/V2Config.java
  83. 0 104
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/domain/AjaxResult.java
  84. 0 84
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/domain/ResultTable.java
  85. 0 50
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/domain/Tablepar.java
  86. 0 21
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/interceptor/Interceptor.java
  87. 0 91
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/interceptor/WebMvcConfig.java
  88. 0 87
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/controller/web/ApiController.java
  89. 0 376
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/controller/web/FileController.java
  90. 0 257
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/controller/web/GoviewProjectController.java
  91. 0 21
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/controller/web/Indexcontroller.java
  92. 0 16
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/mapper/GoviewProjectDataMapper.java
  93. 0 16
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/mapper/GoviewProjectMapper.java
  94. 0 17
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/mapper/SysFileMapper.java
  95. 0 16
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/mapper/SysUserMapper.java
  96. 0 48
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/model/GoviewProject.java
  97. 0 39
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/model/GoviewProjectData.java
  98. 0 119
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/model/SysFile.java
  99. 0 39
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/model/SysUser.java
  100. 0 119
      service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/model/vo/GoviewProjectVo.java

+ 3 - 0
pom.xml

@@ -97,6 +97,9 @@
 
     <module>service-ids</module>
 
+
+    <module>service-cdi</module>
+
   </modules>
           
   

+ 1 - 0
service-agbox/service-agbox-biz/pom.xml

@@ -74,6 +74,7 @@
             <plugin>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.2.6.RELEASE</version>
                 <executions>
                     <execution>
                         <goals>

+ 7 - 1
service-agbox/service-agbox-biz/src/main/java/com/usky/agbox/service/mqtt/event/event.java

@@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.Map;
 
 @Service("event")
@@ -40,9 +41,14 @@ public class event implements MqttStrategy {
                 }else {
                     eventVO.put("eventCode",16);
                 }
+                // 定义原始格式的解析器(包含'T'和毫秒)
+                DateTimeFormatter originalFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
+                DateTimeFormatter targetFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                 String timeWithT = eventVO1.get("createTime").toString();
+                LocalDateTime dateTime = LocalDateTime.parse(timeWithT, originalFormatter);
+                String targetTime = dateTime.format(targetFormatter);
                 eventVO.put("deviceId",eventVO1.get("deviceId"));
-                eventVO.put("triggerTime",timeWithT.replace("T", " "));
+                eventVO.put("triggerTime",targetTime);
                 eventVO.put("name",eventVO1.get("createBy"));
                 eventVO.put("certifiedNo","");
                 PatrolAgbox.addEvent(eventVO.toJSONString());

+ 1 - 1
service-agbox/service-agbox-biz/src/main/resources/logback.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration scan="true" scanPeriod="60 seconds" debug="false">
     <!-- 日志存放路径 -->
-    <property name="log.path" value="/var/log/uskycloud/service-alarm" />
+    <property name="log.path" value="/var/log/uskycloud/service-agbox" />
     <!-- 日志输出格式 -->
     <property name="log.pattern" value="%d{MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{26}:%line: %msg%n" />
     <!--    	<property name="log.pattern" value="%gray(%d{MM-dd HH:mm:ss.SSS}) %highlight(%-5level) &#45;&#45; [%gray(%thread)] %cyan(%logger{26}:%line): %msg%n" />-->

+ 1 - 0
service-alarm/service-alarm-biz/pom.xml

@@ -74,6 +74,7 @@
             <plugin>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.2.6.RELEASE</version>
                 <executions>
                     <execution>
                         <goals>

+ 3 - 3
service-cockpit/pom.xml → service-cdi/pom.xml

@@ -8,13 +8,13 @@
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <artifactId>service-iot</artifactId>
+    <artifactId>service-cdi</artifactId>
 
     <packaging>pom</packaging>
     <version>0.0.1</version>
 
     <modules>
-        <module>service-iot-biz</module>
-        <module>service-iot-api</module>
+        <module>service-cdi-biz</module>
+        <module>service-cdi-api</module>
     </modules>
 </project>

+ 31 - 0
service-cdi/service-cdi-api/pom.xml

@@ -0,0 +1,31 @@
+<?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>service-cdi</artifactId>
+        <groupId>com.usky</groupId>
+        <version>0.0.1</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>service-cdi-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>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-openfeign-core</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+    </build>
+
+</project>

+ 13 - 0
service-cdi/service-cdi-api/src/main/java/com/usky/cdi/RemotecdiTaskService.java

@@ -0,0 +1,13 @@
+package com.usky.cdi;
+
+import com.usky.cdi.factory.RemotecdiTaskFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+@FeignClient(contextId = "RemotecdiTaskService", value = "service-cdi", fallbackFactory = RemotecdiTaskFactory.class)
+public interface RemotecdiTaskService {
+    @GetMapping("/synchronizeDeviceData")
+    void synchronizeDeviceData(@RequestParam("tenantId") Integer tenantId,
+                               @RequestParam("engineeringId") Long engineeringId);
+}

+ 25 - 0
service-cdi/service-cdi-api/src/main/java/com/usky/cdi/factory/RemotecdiTaskFactory.java

@@ -0,0 +1,25 @@
+package com.usky.cdi.factory;
+
+import com.usky.cdi.RemotecdiTaskService;
+import com.usky.common.core.exception.FeignBadRequestException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RemotecdiTaskFactory implements FallbackFactory<RemotecdiTaskService> {
+    private static final Logger log = LoggerFactory.getLogger(RemotecdiTaskFactory.class);
+
+    @Override
+    public RemotecdiTaskService create(Throwable throwable) {
+        log.error("用户服务调用失败:{}", throwable.getMessage());
+        return new RemotecdiTaskService() {
+            @Override
+            public void synchronizeDeviceData(Integer tenantId, Long engineeringId) {
+                throw new FeignBadRequestException(500, "人防设备数据定时推送异常" + throwable.getMessage());
+            }
+
+        };
+    }
+}

+ 15 - 42
service-cockpit/service-cockpit-biz/pom.xml → service-cdi/service-cdi-biz/pom.xml

@@ -1,13 +1,14 @@
 <?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>service-iot</artifactId>
+        <artifactId>service-cdi</artifactId>
         <groupId>com.usky</groupId>
         <version>0.0.1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <artifactId>service-iot-biz</artifactId>
+    <artifactId>service-cdi-biz</artifactId>
+
     <dependencies>
         <dependency>
             <groupId>com.usky</groupId>
@@ -22,7 +23,7 @@
 
         <dependency>
             <groupId>com.usky</groupId>
-            <artifactId>service-iot-api</artifactId>
+            <artifactId>service-cdi-api</artifactId>
             <version>0.0.1</version>
         </dependency>
 
@@ -60,54 +61,26 @@
             <artifactId>spring-websocket</artifactId>
             <version>5.2.8.RELEASE</version>
         </dependency>
-        <dependency>
-            <groupId>com.usky</groupId>
-            <artifactId>service-agbox-api</artifactId>
-            <version>0.0.1</version>
-            <scope>compile</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>com.usky</groupId>
-            <artifactId>service-system-api</artifactId>
-            <version>0.0.1</version>
-        </dependency>
-
-        <dependency>
-            <groupId>com.github.binarywang</groupId>
-            <artifactId>weixin-java-mp</artifactId>
-            <version>4.3.0</version>
-        </dependency>
+        
+        <!--Redis依赖-->
         <dependency>
             <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-amqp</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.usky</groupId>
-            <artifactId>service-alarm-api</artifactId>
-            <version>0.0.1</version>
-            <scope>compile</scope>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
         </dependency>
 
+        <!--MySQL依赖-->
         <dependency>
-            <groupId>com.usky</groupId>
-            <artifactId>ruoyi-common-core</artifactId>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>runtime</scope>
         </dependency>
 
-        <!--钉钉-->
-        <!--获取企业accessToken(企业内部应用) 新版SDK-->
         <dependency>
-            <groupId>com.aliyun</groupId>
-            <artifactId>dingtalk</artifactId>
-            <version>2.1.34</version>
-        </dependency>
-        <!--旧版SDK-->
-        <dependency>
-            <groupId>com.aliyun</groupId>
-            <artifactId>alibaba-dingtalk-service-sdk</artifactId>
-            <version>2.0.0</version>
+            <groupId>com.mchange</groupId>
+            <artifactId>mchange-commons-java</artifactId>
+            <version>0.2.15</version>
+            <scope>compile</scope>
         </dependency>
-
     </dependencies>
 
     <build>

+ 4 - 22
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/RuoYiSystemApplication.java → service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/RuoYiSystemApplication.java

@@ -1,24 +1,17 @@
-package com.usky.iot;
+package com.usky.cdi;
 
 
 
-import com.usky.iot.constant.constant;
-import io.swagger.annotations.SwaggerDefinition;
-import lombok.val;
-import me.chanjar.weixin.mp.api.WxMpService;
-import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
-import me.chanjar.weixin.mp.config.impl.WxMpMapConfigImpl;
 import org.mybatis.spring.annotation.MapperScan;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.amqp.rabbit.annotation.EnableRabbit;
 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.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.core.env.Environment;
+import org.springframework.scheduling.annotation.EnableScheduling;
 
 import java.net.InetAddress;
 import java.net.UnknownHostException;
@@ -30,26 +23,15 @@ import java.net.UnknownHostException;
  */
 
 //@EnableSwagger2
+@EnableScheduling
 @EnableFeignClients(basePackages = "com.usky")
-@MapperScan(value = "com.usky.iot.mapper")
+@MapperScan(value = "com.usky.cdi.mapper")
 @ComponentScan("com.usky")
 @SpringBootApplication
-@EnableRabbit
 public class RuoYiSystemApplication
 {
     private static final Logger LOGGER = LoggerFactory.getLogger(RuoYiSystemApplication.class);
 
-    @Bean
-    public WxMpService wxMpService(){
-        WxMpMapConfigImpl wxMpMapConfig = new WxMpMapConfigImpl();
-        wxMpMapConfig.setAppId(constant.WE_CHAT_APP_ID);
-        wxMpMapConfig.setSecret(constant.WE_CHAT_SECRET);
-        val wxMpService = new WxMpServiceImpl();
-        wxMpService.setWxMpConfigStorage(wxMpMapConfig);
-
-        return wxMpService;
-    }
-
     public static void main(String[] args) throws UnknownHostException {
         ConfigurableApplicationContext application = SpringApplication.run(RuoYiSystemApplication.class, args);
         Environment env = application.getEnvironment();

+ 56 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/AlarmDataController.java

@@ -0,0 +1,56 @@
+package com.usky.cdi.controller;
+
+import com.usky.cdi.service.impl.AlarmDataTransferService;
+import com.usky.cdi.service.vo.alarm.AlarmMessage1VO;
+import com.usky.cdi.service.vo.alarm.AlarmMessage2VO;
+import com.usky.cdi.service.vo.alarm.AlarmMessageVO;
+import com.usky.cdi.service.vo.base.EngineeringBaseVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 基础类数据传输控制器
+ * 提供基础类数据上报的接口
+ *
+ * @author han
+ * @date 2025/12/08
+ */
+@Slf4j
+@RestController
+@RequestMapping("/api/alarm")
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+public class AlarmDataController {
+    @Autowired
+    private AlarmDataTransferService alarmDataTransferService;
+    /**
+     * 上报人防工程基础信息
+     */
+    @PostMapping("/alarmMessage")
+    public String sendAlarmMessage(@RequestBody AlarmMessageVO vo) {
+        boolean success = alarmDataTransferService.sendAlarmMessage(vo);
+        return success ? "上报成功" : "上报失败";
+    }
+
+    /**
+     * 上报人防工程基础信息
+     */
+    @PostMapping("/alarmMessage1")
+    public String sendAlarmMessage1(@RequestBody AlarmMessage1VO vo) {
+        boolean success = alarmDataTransferService.sendAlarmMessage1(vo);
+        return success ? "上报成功" : "上报失败";
+    }
+
+    /**
+     * 上报倾斜、位移、裂缝监测事件
+     */
+    @PostMapping("/alarmMessage2")
+    public String sendAlarmMessage2(@RequestBody AlarmMessage2VO vo) {
+        boolean success = alarmDataTransferService.sendAlarmMessage2(vo);
+        return success ? "上报成功" : "上报失败";
+    }
+}

+ 84 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/BaseDataController.java

@@ -0,0 +1,84 @@
+package com.usky.cdi.controller;
+
+import com.usky.cdi.domain.BaseBuildFacility;
+import com.usky.cdi.service.impl.BaseDataTransferService;
+import com.usky.cdi.service.vo.base.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.web.bind.annotation.*;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 基础类数据传输控制器
+ * 提供基础类数据上报的接口
+ *
+ * @author han
+ * @date 2025/03/20
+ */
+@Slf4j
+@RestController
+@RequestMapping("/api/base")
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+public class BaseDataController {
+
+    @Autowired
+    private BaseDataTransferService baseDataTransferService;
+
+    /**
+     * 上报人防工程基础信息
+     */
+    @PostMapping("/engineering")
+    public String sendEngineeringBase(@RequestBody EngineeringBaseVO vo) {
+        boolean success = baseDataTransferService.sendEngineeringBase(vo);
+        return success ? "上报成功" : "上报失败";
+    }
+
+    /**
+     * 上报防护单元基础信息
+     */
+    @PostMapping("/protectiveUnit")
+    public String sendProtectiveUnit(@RequestBody ProtectiveUnitVO vo) {
+        boolean success = baseDataTransferService.sendProtectiveUnit(vo);
+        return success ? "上报成功" : "上报失败";
+    }
+
+    /**
+     * 批量上报防护单元基础信息
+     */
+    @PostMapping("/protectiveUnits")
+    public String batchSendProtectiveUnits(@RequestBody List<ProtectiveUnitVO> units) {
+        int successCount = baseDataTransferService.batchSendProtectiveUnits(units);
+        return String.format("上报成功 %d/%d", successCount, units.size());
+    }
+
+    /**
+     * 上报楼层平面图信息
+     */
+    @PostMapping("/floorPlane")
+    public String sendFloorPlane(@RequestBody FloorPlaneVO vo) {
+        boolean success = baseDataTransferService.sendFloorPlane(vo);
+        return success ? "上报成功" : "上报失败";
+    }
+
+    /**
+     * 上报智能监管物联设施信息
+     */
+    @PostMapping("/sensorInfo")
+    public String sendSensorInfo(@RequestBody FacilityDeviceVO vo) {
+        boolean success = baseDataTransferService.sendSensorInfo(vo);
+        return success ? "上报成功" : "上报失败";
+    }
+
+    /**
+     * 批量上报智能监管物联设施信息
+     */
+    @GetMapping("/sensorInfos")
+    public String batchSendSensorInfos(@RequestParam(value = "tenantId",required = false) Integer tenantId) {
+        int successCount = baseDataTransferService.batchSendSensorInfos(tenantId);
+        return String.format("上报成功 %d", successCount);
+    }
+}
+

+ 67 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/IotDataController.java

@@ -0,0 +1,67 @@
+package com.usky.cdi.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.usky.cdi.service.impl.IotDataTransferService;
+import com.usky.cdi.service.vo.IotDataTransferVO;
+import com.usky.cdi.service.vo.base.*;
+import com.usky.common.core.bean.ApiResult;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ *
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/11/20
+ */
+@Slf4j
+@RestController
+@RequestMapping("/api/iotInfo")
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+public class IotDataController {
+
+    @Autowired
+    private IotDataTransferService iotDataTransferService;
+
+    /**
+     * 上报水浸状态
+     */
+    @PostMapping("/flooded")
+    public ApiResult<Void> sendWaterLeak(@RequestBody IotDataTransferVO jsonObject) {
+        iotDataTransferService.sendWaterLeak(jsonObject);
+        return ApiResult.success();
+    }
+
+    /**
+     * 上报温度、湿度、氧气、一氧化碳、二氧化碳
+     */
+    @PostMapping("/envData")
+    public ApiResult<Void> sendEnvData(@RequestBody IotDataTransferVO jsonObject) {
+        iotDataTransferService.sendEnvData(jsonObject);
+        return ApiResult.success();
+    }
+
+    /**
+     * 上报人员闯入
+     */
+    @PostMapping("/personPresence")
+    public ApiResult<Void> sendPerson(@RequestBody IotDataTransferVO jsonObject) {
+        iotDataTransferService.sendPersonPresence(jsonObject);
+        return ApiResult.success();
+    }
+
+    /**
+     * 上报用电负荷
+     */
+    @PostMapping("/electricityLoad")
+    public ApiResult<Void> sendElectricityLoad(@RequestBody IotDataTransferVO jsonObject) {
+        iotDataTransferService.sendElectricityLoad(jsonObject);
+        return ApiResult.success();
+    }
+
+}

+ 7 - 7
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/controller/MybatisGeneratorUtils.java → service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/MybatisGeneratorUtils.java

@@ -1,4 +1,4 @@
-package com.usky.iot.controller;//package com.usky.iot.controller;//package com.usky.dm.controller.web.business;//package com.usky.dm.controller.web;
+package com.usky.cdi.controller;//package com.usky.iot.controller;//package com.usky.dm.controller.web.business;//package com.usky.dm.controller.web;
 
 
 import com.baomidou.mybatisplus.core.toolkit.StringPool;
@@ -18,7 +18,7 @@ import java.util.List;
 public class MybatisGeneratorUtils {
     public static void main(String[] args) {
 
-            shell("service-iot","service-iot-biz");
+            shell("service-cdi","service-cdi-biz");
     }
 
     private static void shell(String parentName,String model) {
@@ -33,7 +33,7 @@ public class MybatisGeneratorUtils {
         projectPath+="/"+model;
         gc.setOutputDir(projectPath+ "/src/main/java");  //生成路径(一般都是生成在此项目的src/main/java下面)
         //修改为自己的名字
-        gc.setAuthor("han"); //设置作者
+        gc.setAuthor("fu"); //设置作者
         gc.setOpen(false);
         gc.setFileOverride(true); //第二次生成会把第一次生成的覆盖掉
         gc.setServiceName("%sService"); //生成的service接口名字首字母是否为I,这样设置就没有
@@ -43,7 +43,7 @@ public class MybatisGeneratorUtils {
         //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.setUrl("jdbc:mysql://47.111.81.118:13307/usky-cloud?useUnicode=true&serverTimezone=GMT&useSSL=false&characterEncoding=utf8");
         dsc.setDriverName("com.mysql.jdbc.Driver");
         dsc.setUsername("usky");
         dsc.setPassword("Yt#75Usky");
@@ -51,7 +51,7 @@ public class MybatisGeneratorUtils {
 
         // 3、包配置
         PackageConfig pc = new PackageConfig();
-        pc.setParent("com.usky.iot");
+        pc.setParent("com.usky.cdi");
         pc.setController("controller.web");
         pc.setEntity("domain");
         pc.setMapper("mapper");
@@ -71,7 +71,7 @@ public class MybatisGeneratorUtils {
         // strategy.setTablePrefix("t_"); // 表名前缀
         strategy.setEntityLombokModel(true); //使用lombok
         //修改自己想要生成的表
-        strategy.setInclude("sys_dept");  // 逆向工程使用的表   如果要生成多个,这里可以传入String[]
+        strategy.setInclude("dmp_product");  // 逆向工程使用的表   如果要生成多个,这里可以传入String[]
         mpg.setStrategy(strategy);
 
         // 关闭默认 xml 生成,调整生成 至 根目录
@@ -94,7 +94,7 @@ public class MybatisGeneratorUtils {
             @Override
             public String outputFile(TableInfo tableInfo) {
                 // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
-                return finalProjectPath + "/src/main/resources/mapper/iot" + "/"
+                return finalProjectPath + "/src/main/resources/mapper/cdi" + "/"
                         + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
             }
         });

+ 25 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/api/RemotecdiTaskApi.java

@@ -0,0 +1,25 @@
+package com.usky.cdi.controller.api;
+
+import com.usky.cdi.RemotecdiTaskService;
+import com.usky.cdi.service.impl.IotDataTransferService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  数据统一查询 前端控制器
+ * </p>
+ *
+ * @author f
+ */
+@RestController
+public class RemotecdiTaskApi implements RemotecdiTaskService {
+
+    @Autowired
+    private IotDataTransferService iotDataTransferService;
+
+    @Override
+    public void synchronizeDeviceData(Integer tenantId, Long engineeringId) {
+        iotDataTransferService.synchronizeDeviceData(tenantId, engineeringId);
+    }
+}

+ 21 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/web/BaseBuildFacilityController.java

@@ -0,0 +1,21 @@
+package com.usky.cdi.controller.web;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.stereotype.Controller;
+
+/**
+ * <p>
+ * 建筑设施 前端控制器
+ * </p>
+ *
+ * @author fu
+ * @since 2025-12-02
+ */
+@Controller
+@RequestMapping("/baseBuildFacility")
+public class BaseBuildFacilityController {
+
+}
+

+ 33 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/web/DmpDeviceInfoController.java

@@ -0,0 +1,33 @@
+package com.usky.cdi.controller.web;
+
+import com.usky.backend.domain.*;
+import com.usky.cdi.domain.DmpDevice;
+import com.usky.cdi.service.DmpDeviceInfoService;
+import com.usky.common.core.bean.ApiResult;
+import com.usky.common.core.bean.CommonPage;
+import com.usky.common.core.utils.poi.ExcelUtil;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 设备信息表
+ *
+ * @author ya
+ * @since 2022-10-08
+ */
+@RestController
+@RequestMapping("/dmpDeviceInfo")
+public class DmpDeviceInfoController {
+
+    @Autowired
+    private DmpDeviceInfoService dmpDeviceInfoService;
+
+}
+

+ 9 - 7
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/controller/web/SysUserController.java → service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/web/DmpProductController.java

@@ -1,20 +1,22 @@
-package cn.com.v2.controller;
+package com.usky.cdi.controller.web;
 
 
 import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+
 import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RestController;
 
 /**
  * <p>
- *  前端控制器
+ * 产品信息表 前端控制器
  * </p>
  *
- * @author fc
- * @since 2023-04-30
+ * @author fu
+ * @since 2025-12-05
  */
 @RestController
-@RequestMapping("/v2/sys-user")
-public class SysUserController {
+@RequestMapping("/dmpProduct")
+public class DmpProductController {
 
 }
+

+ 162 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/domain/BaseBuildFacility.java

@@ -0,0 +1,162 @@
+package com.usky.cdi.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 fu
+ * @since 2025-12-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class BaseBuildFacility implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 设施编号
+     */
+    private String facilityNum;
+
+    /**
+     * 设施名称
+     */
+    private String facilityName;
+
+    /**
+     * 设施类型
+     */
+    private String facilityType;
+
+    /**
+     * 所属楼层
+     */
+    private String floor;
+
+    /**
+     * 安装位置
+     */
+    private String address;
+
+    /**
+     * 图⽚地址URL
+     */
+    private String imagesUrl;
+
+    /**
+     * 设备ID
+     */
+    private String deviceId;
+
+    /**
+     * 联系人
+     */
+    private String contact;
+
+    /**
+     * 联系方式
+     */
+    private String contactPhone;
+
+    /**
+     * 平面X轴坐标
+     */
+    private String planeX;
+
+    /**
+     * 平面Y轴坐标
+     */
+    private String planeY;
+
+    private String coordinateX;
+
+    private String coordinateY;
+
+    private String coordinateZ;
+
+    /**
+     * 删除标识
+     */
+    private Integer deleteFlag;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 更新人
+     */
+    private String updateBy;
+
+    /**
+     * 创建人
+     */
+    private String createBy;
+
+    /**
+     * 组织结构ID
+     */
+    private Integer deptId;
+
+    /**
+     * 租户ID
+     */
+    private Integer tenantId;
+
+    /**
+     * 建筑设施备注
+     */
+    private String facilityDesc;
+
+    /**
+     * 三维角度X
+     */
+    private Double anglesX;
+
+    /**
+     * 三维角度y
+     */
+    private Double anglesY;
+
+    /**
+     * 三维角度z
+     */
+    private Double anglesZ;
+
+    /**
+     * 三维图标大小
+     */
+    private Double scaleL;
+
+    /**
+     * 三维图标大小
+     */
+    private Double scaleW;
+
+    /**
+     * 三维图标大小
+     */
+    private Double scaleH;
+
+
+}

+ 132 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/domain/DmpDevice.java

@@ -0,0 +1,132 @@
+package com.usky.cdi.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 设备信息表
+ * </p>
+ *
+ * @author han
+ * @since 2023-09-22
+ */
+@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;
+
+
+}

+ 141 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/domain/DmpProduct.java

@@ -0,0 +1,141 @@
+package com.usky.cdi.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 fu
+ * @since 2025-12-05
+ */
+@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;
+
+    /**
+     * 接入方式
+     */
+    private Integer accessMode;
+
+    /**
+     * 网络类型
+     */
+    private Integer networkType;
+
+    /**
+     * 设备类型
+     */
+    private Integer deviceType;
+
+    /**
+     * 通信协议
+     */
+    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;
+
+
+}

+ 16 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/mapper/BaseBuildFacilityMapper.java

@@ -0,0 +1,16 @@
+package com.usky.cdi.mapper;
+
+import com.usky.cdi.domain.BaseBuildFacility;
+import com.usky.common.mybatis.core.CrudMapper;
+
+/**
+ * <p>
+ * 建筑设施 Mapper 接口
+ * </p>
+ *
+ * @author fu
+ * @since 2025-12-02
+ */
+public interface BaseBuildFacilityMapper extends CrudMapper<BaseBuildFacility> {
+
+}

+ 16 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/mapper/DmpDeviceMapper.java

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

+ 16 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/mapper/DmpProductMapper.java

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

+ 18 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/BaseBuildFacilityService.java

@@ -0,0 +1,18 @@
+package com.usky.cdi.service;
+
+import com.usky.cdi.domain.BaseBuildFacility;
+import com.usky.common.mybatis.core.CrudService;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 建筑设施 服务类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-12-02
+ */
+public interface BaseBuildFacilityService extends CrudService<BaseBuildFacility> {
+    List<BaseBuildFacility> facilityInfo(Integer tenantId);
+}

+ 25 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/DmpDeviceInfoService.java

@@ -0,0 +1,25 @@
+package com.usky.cdi.service;
+
+import com.usky.backend.domain.*;
+import com.usky.cdi.domain.BaseBuildFacility;
+import com.usky.cdi.domain.DmpDevice;
+import com.usky.common.core.bean.CommonPage;
+import com.usky.common.mybatis.core.CrudService;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * <p>
+ * 设备信息表
+ * </p>
+ *
+ * @author ya
+ * @since 2022-10-08
+ */
+public interface DmpDeviceInfoService extends CrudService<DmpDevice> {
+    List<DmpDevice> deviceInfo(Integer tenantId);
+}

+ 16 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/DmpProductService.java

@@ -0,0 +1,16 @@
+package com.usky.cdi.service;
+
+import com.usky.cdi.domain.DmpProduct;
+import com.usky.common.mybatis.core.CrudService;
+
+/**
+ * <p>
+ * 产品信息表 服务类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-12-05
+ */
+public interface DmpProductService extends CrudService<DmpProduct> {
+
+}

+ 52 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/config/mqtt/MqttBaseConfig.java

@@ -0,0 +1,52 @@
+package com.usky.cdi.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());
+        if (this.getPassword() != null) {
+            options.setPassword(this.getPassword().toCharArray());
+        }
+        factory.setConnectionOptions(options);
+        return factory;
+    }
+
+}

+ 52 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/config/mqtt/MqttInConfig.java

@@ -0,0 +1,52 @@
+package com.usky.cdi.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.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;
+
+/**
+ * @author han
+ * @date 2025/03/20 14:30
+ */
+@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 msgTopic = mqttBaseConfig.getMsgTopic();
+        if (msgTopic == null || msgTopic.trim().isEmpty()) {
+            throw new IllegalStateException("MQTT订阅主题配置不能为空");
+        }
+        String[] tops = msgTopic.split(",");
+        String clientId = "h-agbox-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;
+    }
+}

+ 97 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/config/mqtt/MqttOutConfig.java

@@ -0,0 +1,97 @@
+package com.usky.cdi.service.config.mqtt;
+
+import com.alibaba.fastjson.JSONObject;
+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;
+
+import java.util.Map;
+
+/**
+ * @author han
+ * @date 2025/03/20 14:31
+ */
+@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-backend-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);
+
+        /**
+         * 指定top发送消息
+         *
+         * @param topic
+         * @param payload
+         */
+        void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, Map<String, Object> payload);
+
+        /**
+         * 指定队列和qos
+         *
+         * @param topic
+         * @param qos
+         * @param payload
+         */
+        void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload);
+    }
+}

+ 45 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/enums/EnvMonitorMqttTopic.java

@@ -0,0 +1,45 @@
+package com.usky.cdi.service.enums;
+
+import lombok.Data;
+
+/**
+ * 环境监测MQTT Topic枚举(统一管理)
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/11/20
+ */
+public enum EnvMonitorMqttTopic {
+    // 水浸状态
+    WATER_LEAK("iotInfo/flooded"),
+
+    // 温度
+    TEMP("iotInfo/temp"),
+
+    // 湿度
+    HUMIDITY("iotInfo/rh"),
+
+    // 氧气
+    OXYGEN("iotInfo/o2"),
+
+    // 二氧化碳
+    CO2("iotInfo/co2"),
+
+    // 一氧化碳
+    CO("iotInfo/co"),
+
+    // 人员闯入情况
+    PERSON_PRESENCE("iotInfo/personPresence"),
+
+    // 用电负荷(后续用电负荷用)
+    ELECTRICITY_LOAD("iotInfo/electricityLoad");
+
+    private final String topic;
+
+    EnvMonitorMqttTopic(String topic) {
+        this.topic = topic;
+    }
+
+    public String getTopic() {
+        return topic;
+    }
+}

+ 163 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/impl/AlarmDataTransferService.java

@@ -0,0 +1,163 @@
+package com.usky.cdi.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.nacos.shaded.com.google.gson.Gson;
+import com.usky.cdi.service.config.mqtt.MqttOutConfig;
+import com.usky.cdi.service.util.SnowflakeIdGenerator;
+import com.usky.cdi.service.vo.alarm.AlarmMessage1VO;
+import com.usky.cdi.service.vo.alarm.AlarmMessage2VO;
+import com.usky.cdi.service.vo.alarm.AlarmMessageVO;
+import com.usky.cdi.service.vo.base.FloorPlaneVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+
+/**
+ * 告警类数据传输服务
+ * 负责向市适配平台发送告警类数据
+ *
+ * @author han
+ * @date 2025/12/08
+ */
+@Slf4j
+@Service
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+public class AlarmDataTransferService {
+
+    @Resource
+    private MqttOutConfig.MqttGateway mqttGateway;
+
+    private final SnowflakeIdGenerator idGenerator;
+    private final SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+    public AlarmDataTransferService() {
+        // 使用默认的workerId和datacenterId,实际项目中可以从配置读取
+        this.idGenerator = new SnowflakeIdGenerator(1L, 1L);
+    }
+
+    /**
+     * 获取当前时间字符串
+     */
+    private String getCurrentTime() {
+        return timeFormat.format(new Date());
+    }
+
+    /**
+     * 生成数据包ID
+     */
+    private Long generateDataPacketID() {
+        return idGenerator.nextPacketId();
+    }
+
+    /**
+     * 发送告警信息
+     * Topic: base/floorPlane
+     *
+     * @param vo 楼层平面图信息
+     * @return 是否发送成功
+     */
+    public boolean sendAlarmMessage(AlarmMessageVO vo) {
+        try {
+            if (vo.getDataPacketID() == null) {
+                vo.setDataPacketID(generateDataPacketID());
+            }
+            if (vo.getPublishTime() == null) {
+                vo.setPublishTime(getCurrentTime());
+            }
+
+            HashMap<String, Object> map = new HashMap<>();
+//            map.put("dataPacketID", vo.getDataPacketID());
+//            map.put("engineeringID", vo.getEngineeringID());
+//            map.put("floor", vo.getFloor());
+//            map.put("floorFileID", vo.getFloorFileID());
+//            map.put("floorFileName", vo.getFloorFileName());
+//            map.put("floorFileSuffix", vo.getFloorFileSuffix());
+//            map.put("filePixWidth", vo.getFilePixWidth());
+//            map.put("filePixHeight", vo.getFilePixHeight());
+//            map.put("floorFile", imageBytes);
+//            map.put("publishTime", vo.getPublishTime());
+            Gson gson = new Gson();
+            JSONObject jsonObject = (JSONObject) JSON.toJSON(vo);
+            String json = jsonObject.toJSONString();
+            System.out.println(json);
+            String topic = "alarm/message";
+            mqttGateway.sendToMqtt(topic, json);
+
+            return true;
+        } catch (Exception e) {
+            log.error("发送告警信息失败,AlarmID: {}", vo.getAlarmID(), e);
+            return false;
+        }
+    }
+
+    /**
+     * 发送告警信息
+     * Topic: base/floorPlane
+     *
+     * @param vo 楼层平面图信息
+     * @return 是否发送成功
+     */
+    public boolean sendAlarmMessage1(AlarmMessage1VO vo) {
+        try {
+            if (vo.getDataPacketID() == null) {
+                vo.setDataPacketID(generateDataPacketID());
+            }
+            if (vo.getPublishTime() == null) {
+                vo.setPublishTime(getCurrentTime());
+            }
+
+            HashMap<String, Object> map = new HashMap<>();
+//            map.put("dataPacketID", vo.getDataPacketID());
+//            map.put("engineeringID", vo.getEngineeringID());
+//            map.put("floor", vo.getFloor());
+//            map.put("floorFileID", vo.getFloorFileID());
+//            map.put("floorFileName", vo.getFloorFileName());
+//            map.put("floorFileSuffix", vo.getFloorFileSuffix());
+//            map.put("filePixWidth", vo.getFilePixWidth());
+//            map.put("filePixHeight", vo.getFilePixHeight());
+//            map.put("floorFile", imageBytes);
+//            map.put("publishTime", vo.getPublishTime());
+            Gson gson = new Gson();
+            JSONObject jsonObject = (JSONObject) JSON.toJSON(vo);
+            String json = jsonObject.toJSONString();
+            System.out.println(json);
+            String topic = "alarm/message";
+            mqttGateway.sendToMqtt(topic, json);
+
+            return true;
+        } catch (Exception e) {
+            log.error("发送告警信息失败,AlarmID: {}", vo.getAlarmID(), e);
+            return false;
+        }
+    }
+
+    public boolean sendAlarmMessage2(AlarmMessage2VO vo) {
+        try {
+            if (vo.getDataPacketID() == null) {
+                vo.setDataPacketID(generateDataPacketID());
+            }
+            if (vo.getPublishTime() == null) {
+                vo.setPublishTime(getCurrentTime());
+            }
+
+            JSONObject jsonObject = (JSONObject) JSON.toJSON(vo);
+            String json = jsonObject.toJSONString();
+            System.out.println(json);
+            String topic = "alarm/message";
+            mqttGateway.sendToMqtt(topic, json);
+
+            return true;
+        } catch (Exception e) {
+            log.error("发送告警信息失败,AlarmID: {}", vo.getAlarmID(), e);
+            return false;
+        }
+    }
+}

+ 32 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/impl/BaseBuildFacilityServiceImpl.java

@@ -0,0 +1,32 @@
+package com.usky.cdi.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.cdi.domain.BaseBuildFacility;
+import com.usky.cdi.mapper.BaseBuildFacilityMapper;
+import com.usky.cdi.service.BaseBuildFacilityService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.common.security.utils.SecurityUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 建筑设施 服务实现类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-12-02
+ */
+@Service
+public class BaseBuildFacilityServiceImpl extends AbstractCrudService<BaseBuildFacilityMapper, BaseBuildFacility> implements BaseBuildFacilityService {
+    @Override
+    public List<BaseBuildFacility> facilityInfo(Integer tenantId){
+        LambdaQueryWrapper<BaseBuildFacility> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(BaseBuildFacility::getDeleteFlag,0)
+                .eq(BaseBuildFacility::getTenantId, tenantId);
+        List<BaseBuildFacility> list = this.list(queryWrapper);
+        return list;
+    }
+}

+ 325 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/impl/BaseDataTransferService.java

@@ -0,0 +1,325 @@
+package com.usky.cdi.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.nacos.shaded.com.google.gson.Gson;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.usky.cdi.domain.BaseBuildFacility;
+import com.usky.cdi.domain.DmpDevice;
+import com.usky.cdi.service.BaseBuildFacilityService;
+import com.usky.cdi.service.DmpDeviceInfoService;
+import com.usky.cdi.service.config.mqtt.MqttOutConfig;
+import com.usky.cdi.service.util.SnowflakeIdGenerator;
+import com.usky.cdi.service.vo.base.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * 基础类数据传输服务
+ * 负责向市适配平台发送基础类数据
+ * 
+ * @author han
+ * @date 2025/03/20
+ */
+@Slf4j
+@Service
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+public class BaseDataTransferService {
+
+    @Autowired
+    private BaseBuildFacilityService baseBuildFacilityService;
+
+    @Autowired
+    private DmpDeviceInfoService dmpDeviceInfoService;
+
+    @Resource
+    private MqttOutConfig.MqttGateway mqttGateway;
+
+    @Value("${config.engineeringID}")
+    private String engineeringID;
+
+    private final SnowflakeIdGenerator idGenerator;
+    private final SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+    public BaseDataTransferService() {
+        // 使用默认的workerId和datacenterId,实际项目中可以从配置读取
+        this.idGenerator = new SnowflakeIdGenerator(1L, 1L);
+    }
+
+    /**
+     * 获取当前时间字符串
+     */
+    private String getCurrentTime() {
+        return timeFormat.format(new Date());
+    }
+
+    /**
+     * 生成数据包ID
+     */
+    private Long generateDataPacketID() {
+        return idGenerator.nextPacketId();
+    }
+
+    /**
+     * 发送人防工程基础信息
+     * Topic: base/engineering
+     * 
+     * @param vo 人防工程基础信息
+     * @return 是否发送成功
+     */
+    public boolean sendEngineeringBase(EngineeringBaseVO vo) {
+        try {
+            if (vo.getDataPacketID() == null) {
+                vo.setDataPacketID(generateDataPacketID());
+            }
+            if (vo.getPublishTime() == null) {
+                vo.setPublishTime(getCurrentTime());
+            }
+
+            String json = JSON.toJSONString(vo);
+            String topic = "base/engineering";
+            
+            log.info("发送人防工程基础信息,Topic: {}, Data: {}", topic, json);
+            mqttGateway.sendToMqtt(topic, json);
+            
+            return true;
+        } catch (Exception e) {
+            log.error("发送人防工程基础信息失败", e);
+            return false;
+        }
+    }
+
+    /**
+     * 发送防护单元基础信息
+     * Topic: base/protectiveUnit
+     * 
+     * @param vo 防护单元基础信息
+     * @return 是否发送成功
+     */
+    public boolean sendProtectiveUnit(ProtectiveUnitVO vo) {
+        try {
+            if (vo.getDataPacketID() == null) {
+                vo.setDataPacketID(generateDataPacketID());
+            }
+            if (vo.getPublishTime() == null) {
+                vo.setPublishTime(getCurrentTime());
+            }
+
+            String json = JSON.toJSONString(vo);
+            String topic = "base/protectiveUnit";
+            
+            log.info("发送防护单元基础信息,Topic: {}, Data: {}", topic, json);
+            mqttGateway.sendToMqtt(topic, json);
+            
+            return true;
+        } catch (Exception e) {
+            log.error("发送防护单元基础信息失败", e);
+            return false;
+        }
+    }
+
+    /**
+     * 发送楼层平面图信息
+     * Topic: base/floorPlane
+     * 
+     * @param vo 楼层平面图信息
+     * @return 是否发送成功
+     */
+    public boolean sendFloorPlane(FloorPlaneVO vo) {
+        try {
+            if (vo.getDataPacketID() == null) {
+                vo.setDataPacketID(generateDataPacketID());
+            }
+            if (vo.getPublishTime() == null) {
+                vo.setPublishTime(getCurrentTime());
+            }
+
+            String imagePath = "D://games/3492.jpg";
+            // 将图片文件读取为字节数组
+            byte[] imageBytes = Files.readAllBytes(Paths.get(imagePath));
+
+            // 检查文件大小(不超过5MB)
+            if (vo.getFloorFile() != null && imageBytes.length > 5 * 1024 * 1024) {
+                log.error("楼层平面图文件大小超过5MB限制,FileID: {}", vo.getFloorFileID());
+                return false;
+            }
+
+            HashMap<String, Object> map = new HashMap<>();
+            map.put("dataPacketID", vo.getDataPacketID());
+            map.put("engineeringID", vo.getEngineeringID());
+            map.put("floor", vo.getFloor());
+            map.put("floorFileID", vo.getFloorFileID());
+            map.put("floorFileName", vo.getFloorFileName());
+            map.put("floorFileSuffix", vo.getFloorFileSuffix());
+            map.put("filePixWidth", vo.getFilePixWidth());
+            map.put("filePixHeight", vo.getFilePixHeight());
+            map.put("floorFile", imageBytes);
+            map.put("publishTime", vo.getPublishTime());
+            Gson gson = new Gson();
+            // 将字节数组转换为Base64编码
+            JSONObject jsonObject = (JSONObject) JSON.toJSON(vo);
+            vo.setFloorFile(imageBytes);
+//            jsonObject.put("floorFile", imageBytes);
+            if (vo.getFloorFile() != null) {
+                // 使用Base64编码传输二进制数据
+                String base64File = java.util.Base64.getEncoder().encodeToString(vo.getFloorFile());
+                jsonObject.put("floorFile", imageBytes);
+            }
+
+            String json = jsonObject.toJSONString();
+            System.out.println(gson.toJson(map));
+            String topic = "base/floorPlane";
+            
+            log.info("发送楼层平面图信息,Topic: {}, FileID: {}, FileSize: {} bytes", 
+                    topic, vo.getFloorFileID(), 
+                    vo.getFloorFile() != null ? vo.getFloorFile().length : 0);
+            mqttGateway.sendToMqtt(topic, gson.toJson(map));
+            
+            return true;
+        } catch (Exception e) {
+            log.error("发送楼层平面图信息失败,FileID: {}", vo.getFloorFileID(), e);
+            return false;
+        }
+    }
+
+    /**
+     * 根据输入的键(key)从Map中匹配并返回对应的值
+     * @param key 要匹配的键(输入值)
+     * @param dataMap 存储键值对的Map
+     * @return 匹配到的值(若未匹配到返回null)
+     */
+    public static <K, V> V matchByKey(K key, Map<K, V> dataMap) {
+        // 判空处理(避免空指针)
+        if (key == null || dataMap == null) {
+            return null;
+        }
+        // 直接通过Map的get方法匹配
+        return dataMap.get(key);
+    }
+
+    /**
+     * 发送智能监管物联设施信息
+     * Topic: base/sensorInfo
+     * 
+     * @param vo 智能监管物联设施信息
+     * @return 是否发送成功
+     */
+    public boolean sendSensorInfo(FacilityDeviceVO vo) {
+        try {
+            Map<Integer, Integer> userIdToName = new HashMap<>();
+            userIdToName.put(702, 31);
+            userIdToName.put(703, 33);
+            userIdToName.put(704, 11);
+            userIdToName.put(707, 19);
+            userIdToName.put(708, 19);
+            userIdToName.put(709, 15);
+            userIdToName.put(710, 16);
+            userIdToName.put(711, 2);
+            userIdToName.put(712, 34);
+            userIdToName.put(713, 36);
+            userIdToName.put(714, 37);
+
+            HashMap<String, Object> map = new HashMap<>();
+            map.put("dataPacketID", generateDataPacketID());
+            map.put("engineeringID", Long.parseLong(engineeringID));
+            map.put("floor", "B2");
+            map.put("floorFileID", 1);
+            map.put("sensorID", Integer.parseInt(vo.getDeviceId()));
+            map.put("sensorNo", vo.getDeviceUuid());
+            map.put("sensorType", matchByKey(vo.getDeviceType(), userIdToName));
+            map.put("unitName", vo.getFacilityDesc());
+            map.put("monitorObjNo", vo.getFacilityNum());
+            map.put("monitorObj", vo.getFacilityName());
+            map.put("location", vo.getAddress());
+//            map.put("xCoordinate", (int) Math.floor(Double.parseDouble(vo.getPlaneX())*4.34));
+//            map.put("yCoordinate", (int) Math.floor(Double.parseDouble(vo.getPlaneY())*4.34));
+            map.put("xCoordinate", Integer.valueOf(vo.getPlaneX()));
+            map.put("yCoordinate", Integer.valueOf(vo.getPlaneY()));
+            map.put("publishTime", getCurrentTime());
+            Gson gson = new Gson();
+            String topic = "base/sensorInfo";
+            System.out.println(gson.toJson(map));
+//            log.info("发送智能监管物联设施信息,Topic: {}, SensorID: {}", topic, vo.getSensorID());
+            mqttGateway.sendToMqtt(topic, gson.toJson(map));
+            
+            return true;
+        } catch (Exception e) {
+            log.error("发送智能监管物联设施信息失败", e);
+            return false;
+        }
+    }
+
+    /**
+     * 批量发送防护单元基础信息
+     * 
+     * @param units 防护单元列表
+     * @return 成功发送的数量
+     */
+    public int batchSendProtectiveUnits(java.util.List<ProtectiveUnitVO> units) {
+        if (units == null || units.isEmpty()) {
+            return 0;
+        }
+        
+        int successCount = 0;
+        for (ProtectiveUnitVO unit : units) {
+            if (sendProtectiveUnit(unit)) {
+                successCount++;
+            }
+        }
+        
+        log.info("批量发送防护单元基础信息,总数: {}, 成功: {}", units.size(), successCount);
+        return successCount;
+    }
+
+    /**
+     * 批量发送智能监管物联设施信息
+     * 
+     * @param tenantId 租户ID
+     * @return 成功发送的数量
+     */
+    public int batchSendSensorInfos(Integer tenantId) {
+        List<BaseBuildFacility> list = baseBuildFacilityService.facilityInfo(tenantId);
+        List<DmpDevice> list1 = dmpDeviceInfoService.deviceInfo(tenantId);
+        List<FacilityDeviceVO> list2 = new ArrayList<>();
+        if(CollectionUtils.isNotEmpty(list)&&CollectionUtils.isNotEmpty(list1)){
+            for (int j=0;j<list.size();j++) {
+                for (int k=0;k<list1.size();k++) {
+                    if (list.get(j).getDeviceId().equals(list1.get(k).getDeviceId())){
+                        FacilityDeviceVO facilityDeviceVO = new FacilityDeviceVO();
+                        facilityDeviceVO.setFloor(list.get(j).getFloor());
+                        facilityDeviceVO.setFacilityName(list.get(j).getFacilityName());
+                        facilityDeviceVO.setFacilityNum(list.get(j).getFacilityNum());
+                        facilityDeviceVO.setDeviceId(list.get(j).getDeviceId());
+                        facilityDeviceVO.setAddress(list.get(j).getAddress());
+                        facilityDeviceVO.setPlaneX(list.get(j).getPlaneX());
+                        facilityDeviceVO.setPlaneY(list.get(j).getPlaneY());
+                        facilityDeviceVO.setDeviceUuid(list1.get(k).getDeviceUuid());
+                        facilityDeviceVO.setFacilityDesc(list.get(j).getFacilityDesc());
+                        facilityDeviceVO.setDeviceType(list1.get(k).getDeviceType());
+                        list2.add(facilityDeviceVO);
+                    }
+                }
+            }
+        }
+        int successCount = 0;
+        if(CollectionUtils.isNotEmpty(list2)){
+            for (int i=0;i<list2.size();i++) {
+                if (sendSensorInfo(list2.get(i))) {
+                    successCount++;
+                }
+            }
+        }
+        log.info("批量发送智能监管物联设施信息,总数: {}, 成功: {}", list2.size(), successCount);
+        return successCount;
+    }
+}
+

+ 35 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/impl/DmpDeviceInfoServiceImpl.java

@@ -0,0 +1,35 @@
+package com.usky.cdi.service.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.cdi.domain.BaseBuildFacility;
+import com.usky.cdi.domain.DmpDevice;
+import com.usky.cdi.mapper.DmpDeviceMapper;
+import com.usky.cdi.service.DmpDeviceInfoService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 设备信息表 服务实现类
+ * </p>
+ *
+ * @author ya
+ * @since 2022-10-08
+ */
+@Slf4j
+@Service
+public class DmpDeviceInfoServiceImpl extends AbstractCrudService<DmpDeviceMapper, DmpDevice> implements DmpDeviceInfoService {
+    @Override
+    public List<DmpDevice> deviceInfo(Integer tenantId){
+        LambdaQueryWrapper<DmpDevice> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(DmpDevice::getDeleteFlag,0)
+                .eq(DmpDevice::getTenantId, tenantId);
+        List<DmpDevice> list = this.list(queryWrapper);
+        return list;
+    }
+}

+ 20 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/impl/DmpProductServiceImpl.java

@@ -0,0 +1,20 @@
+package com.usky.cdi.service.impl;
+
+import com.usky.cdi.domain.DmpProduct;
+import com.usky.cdi.mapper.DmpProductMapper;
+import com.usky.cdi.service.DmpProductService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 产品信息表 服务实现类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-12-05
+ */
+@Service
+public class DmpProductServiceImpl extends AbstractCrudService<DmpProductMapper, DmpProduct> implements DmpProductService {
+
+}

+ 642 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/impl/IotDataTransferService.java

@@ -0,0 +1,642 @@
+package com.usky.cdi.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.usky.cdi.domain.DmpDevice;
+import com.usky.cdi.domain.DmpProduct;
+import com.usky.cdi.mapper.DmpDeviceMapper;
+import com.usky.cdi.mapper.DmpProductMapper;
+//import com.usky.cdi.service.config.mqtt.MqttGateway;
+import com.usky.cdi.service.config.mqtt.MqttOutConfig;
+import com.usky.cdi.service.enums.EnvMonitorMqttTopic;
+import com.usky.cdi.service.util.DeviceDataQuery;
+import com.usky.cdi.service.util.SnowflakeIdGenerator;
+import com.usky.cdi.service.vo.IotDataTransferVO;
+import com.usky.cdi.service.vo.base.*;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+
+import javax.annotation.Resource;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/11/20
+ */
+@Slf4j
+@Service
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+public class IotDataTransferService {
+
+    @Resource
+    private MqttOutConfig.MqttGateway mqttGateway;
+
+    private SnowflakeIdGenerator idGenerator;
+
+    @Autowired
+    private DeviceDataQuery deviceDataQuery;
+
+    @Autowired
+    private DmpDeviceMapper dmpDeviceMapper;
+
+    @Value("${device.data.simulation}")
+    private boolean simulation;
+
+    @Autowired
+    private DmpProductMapper dmpProductMapper;
+
+    // 从配置文件读取Snowflake参数,默认值为2
+    @Value("${snowflake.worker-id:2}")
+    private long workerId;
+
+    @Value("${snowflake.data-center-id:2}")
+    private long dataCenterId;
+
+    @PostConstruct
+    public void init() {
+        this.idGenerator = new SnowflakeIdGenerator(workerId, dataCenterId);
+    }
+
+    /**
+     * 获取当前时间
+     */
+    private LocalDateTime getCurrentTime() {
+        return LocalDateTime.now();
+    }
+
+    /**
+     * 生成数据包ID
+     */
+    private Long generateDataPacketID() {
+        return idGenerator.nextPacketId();
+    }
+
+    /**
+     * 发送水浸状态(deviceType:702)
+     * Topic: iotInfo/flooded
+     *
+     * @return 推送结果,包含成功数和失败数
+     */
+    public Map<String, Integer> sendWaterLeak(IotDataTransferVO transferVO) {
+        Map<String, Integer> result = new HashMap<>();
+        result.put("successCount", 0);
+        result.put("failureCount", 0);
+
+        if (!validateMqttGateway()) {
+            return result;
+        }
+
+        try {
+            List<JSONObject> deviceData = deviceDataQuery.getDeviceData(transferVO);
+            Integer deviceType = transferVO.getDeviceType();
+            Integer totalDevices = transferVO.getDevices().size();
+
+            log.info("开始推送水浸状态数据,设备类型:{},设备数量:{},获取到的数据条数:{}",
+                    deviceType, totalDevices, deviceData.size());
+
+            if (deviceData.isEmpty()) {
+                log.warn("没有获取到水浸数据!设备类型:{}", deviceType);
+                result.put("failureCount", totalDevices);
+                return result;
+            }
+
+            Long engineeringId = transferVO.getEngineeringId();
+            for (JSONObject deviceDataItem : deviceData) {
+                LocalDateTime dataEndTime = parseDataTime(deviceDataItem);
+                if (dataEndTime == null) {
+                    result.put("failureCount", result.get("failureCount") + 1);
+                    continue;
+                }
+
+                Integer deviceId = deviceDataItem.getIntValue("device_id");
+                Integer value = deviceDataItem.getInteger("leach_status");
+                if (value == null) {
+                    log.warn("设备{}的水浸状态数据为空", deviceId);
+                    result.put("failureCount", result.get("failureCount") + 1);
+                    continue;
+                }
+
+                WaterLeakVO vo = new WaterLeakVO();
+                vo.setDataPacketID(generateDataPacketID());
+                vo.setSensorID(deviceId);
+                vo.setEngineeringID(engineeringId);
+                vo.setPublishTime(getCurrentTime());
+                vo.setSensorValue(value);
+                vo.setDataEndTime(dataEndTime);
+
+                try {
+                    sendMqttMessage(EnvMonitorMqttTopic.WATER_LEAK, vo, "水浸状态信息");
+                    result.put("successCount", result.get("successCount") + 1);
+                } catch (Exception e) {
+                    log.warn("设备{}的水浸状态数据推送失败:{}", deviceId, e.getMessage());
+                    result.put("failureCount", result.get("failureCount") + 1);
+                }
+            }
+
+            log.info("水浸状态数据推送完成,设备类型:{},成功:{},失败:{}",
+                    deviceType, result.get("successCount"), result.get("failureCount"));
+
+            return result;
+        } catch (Exception e) {
+            log.error("水浸状态数据推送发生异常", e);
+            result.put("failureCount", transferVO.getDevices().size());
+            return result;
+        }
+    }
+
+    /**
+     * 发送温湿度及气体浓度数据(设备类型:701,707-711)
+     * 包含: wd(温度), sd(湿度), o2(氧气), co(一氧化碳), co2(二氧化碳)
+     *
+     * @return 推送结果,包含成功数和失败数
+     */
+    public Map<String, Integer> sendEnvData(IotDataTransferVO transferVO) {
+        Map<String, Integer> result = new HashMap<>();
+        result.put("successCount", 0);
+        result.put("failureCount", 0);
+
+        if (!validateMqttGateway()) {
+            return result;
+        }
+
+        try {
+            Integer deviceType = transferVO.getDeviceType();
+            List<JSONObject> deviceData = deviceDataQuery.getDeviceData(transferVO);
+            Integer totalDevices = transferVO.getDevices().size();
+
+            log.info("开始推送温湿度及气体浓度数据,设备类型:{},设备数量:{},获取到的数据条数:{}",
+                    deviceType, totalDevices, deviceData.size());
+
+            if (deviceData.isEmpty()) {
+                log.warn("没有获取到空气质量数据!设备类型:{}", deviceType);
+                result.put("failureCount", totalDevices);
+                return result;
+            }
+
+            Long engineeringId = transferVO.getEngineeringId();
+            for (JSONObject deviceDataItem : deviceData) {
+                LocalDateTime dataEndTime = parseDataTime(deviceDataItem);
+                if (dataEndTime == null) {
+                    result.put("failureCount", result.get("failureCount") + 1);
+                    continue;
+                }
+
+                Integer deviceId = deviceDataItem.getIntValue("device_id");
+                boolean deviceSuccess = true;
+
+                // 根据设备类型发送对应的数据
+                try {
+                    switch (deviceType) {
+                        case 707:
+                            sendTempData(deviceId, dataEndTime, deviceDataItem, engineeringId);
+                            break;
+                        case 708:
+                            sendHumidityData(deviceId, dataEndTime, deviceDataItem, engineeringId);
+                            break;
+                        case 709:
+                            sendOxygenData(deviceId, dataEndTime, deviceDataItem, engineeringId);
+                            break;
+                        case 710:
+                            sendCo2Data(deviceId, dataEndTime, deviceDataItem, engineeringId);
+                            break;
+                        case 711:
+                            sendCoData(deviceId, dataEndTime, deviceDataItem, engineeringId);
+                            break;
+                    }
+                } catch (Exception e) {
+                    log.warn("设备{}的环境数据推送失败:{}", deviceId, e.getMessage());
+                    deviceSuccess = false;
+                }
+
+                // 统计设备推送结果
+                if (deviceSuccess) {
+                    result.put("successCount", result.get("successCount") + 1);
+                } else {
+                    result.put("failureCount", result.get("failureCount") + 1);
+                }
+            }
+
+            log.info("温湿度及气体浓度数据推送完成,设备类型:{},成功:{},失败:{}",
+                    deviceType, result.get("successCount"), result.get("failureCount"));
+
+            return result;
+        } catch (Exception e) {
+            log.error("温湿度及气体浓度数据推送发生异常", e);
+            result.put("failureCount", transferVO.getDevices().size());
+            return result;
+        }
+    }
+
+    /**
+     * 发送人员闯入情况(703)
+     *
+     * @return 推送结果,包含成功数和失败数
+     **/
+    public Map<String, Integer> sendPersonPresence(IotDataTransferVO transferVO) {
+        Map<String, Integer> result = new HashMap<>();
+        result.put("successCount", 0);
+        result.put("failureCount", 0);
+
+        if (!validateMqttGateway()) {
+            return result;
+        }
+
+        try {
+            List<JSONObject> deviceData = deviceDataQuery.getDeviceData(transferVO);
+            Integer deviceType = transferVO.getDeviceType();
+            Integer totalDevices = transferVO.getDevices().size();
+
+            log.info("开始推送人员闯入情况数据,设备类型:{},设备数量:{},获取到的数据条数:{}",
+                    deviceType, totalDevices, deviceData.size());
+
+            if (deviceData.isEmpty()) {
+                log.warn("没有获取到人员闯入情况数据!设备类型:{}", deviceType);
+                result.put("failureCount", totalDevices);
+                return result;
+            }
+
+            Long engineeringId = transferVO.getEngineeringId();
+            for (JSONObject deviceDataItem : deviceData) {
+                LocalDateTime dataEndTime = parseDataTime(deviceDataItem);
+                if (dataEndTime == null) {
+                    result.put("failureCount", result.get("failureCount") + 1);
+                    continue;
+                }
+
+                Integer deviceId = deviceDataItem.getIntValue("device_id");
+
+                PersonPresenceVO vo = new PersonPresenceVO();
+                vo.setDataPacketID(generateDataPacketID());
+                vo.setSensorID(deviceId);
+                vo.setDataEndTime(dataEndTime);
+                vo.setPublishTime(getCurrentTime());
+                vo.setEngineeringID(engineeringId);
+                // 传感器值固定为0(可能是默认值或占位符)
+                vo.setSensorValue(0);
+
+                try {
+                    sendMqttMessage(EnvMonitorMqttTopic.PERSON_PRESENCE, vo, "人员闯入情况");
+                    result.put("successCount", result.get("successCount") + 1);
+                } catch (Exception e) {
+                    log.warn("设备{}的人员闯入情况数据推送失败:{}", deviceId, e.getMessage());
+                    result.put("failureCount", result.get("failureCount") + 1);
+                }
+            }
+
+            log.info("人员闯入情况数据推送完成,设备类型:{},成功:{},失败:{}",
+                    deviceType, result.get("successCount"), result.get("failureCount"));
+
+            return result;
+        } catch (Exception e) {
+            log.error("人员闯入情况数据推送发生异常", e);
+            result.put("failureCount", transferVO.getDevices().size());
+            return result;
+        }
+    }
+
+    /**
+     * 发送人防用电负荷情况(704)
+     *
+     * @return 推送结果,包含成功数和失败数
+     **/
+    public Map<String, Integer> sendElectricityLoad(IotDataTransferVO transferVO) {
+        Map<String, Integer> result = new HashMap<>();
+        result.put("successCount", 0);
+        result.put("failureCount", 0);
+
+        if (!validateMqttGateway()) {
+            return result;
+        }
+
+        try {
+            List<JSONObject> deviceData = deviceDataQuery.getDeviceData(transferVO);
+            Integer deviceType = transferVO.getDeviceType();
+            Integer totalDevices = transferVO.getDevices().size();
+
+            log.info("开始推送人防用电负荷情况数据,设备类型:{},设备数量:{},获取到的数据条数:{}",
+                    deviceType, totalDevices, deviceData.size());
+
+            if (deviceData.isEmpty()) {
+                log.warn("没有获取到人防用电负荷情况数据!设备类型:{}", deviceType);
+                result.put("failureCount", totalDevices);
+                return result;
+            }
+
+            Long engineeringId = transferVO.getEngineeringId();
+            for (JSONObject deviceDataItem : deviceData) {
+                LocalDateTime dataEndTime = parseDataTime(deviceDataItem);
+                if (dataEndTime == null) {
+                    result.put("failureCount", result.get("failureCount") + 1);
+                    continue;
+                }
+
+                Integer deviceId = deviceDataItem.getIntValue("device_id");
+                ElectricityLoadVO vo = new ElectricityLoadVO();
+                vo.setDataPacketID(generateDataPacketID());
+                vo.setSensorID(deviceId);
+                vo.setEngineeringID(engineeringId);
+                vo.setPublishTime(getCurrentTime());
+                vo.setDataEndTime(dataEndTime);
+                vo.setAVoltage(deviceDataItem.getFloat("aVoltage"));
+                vo.setBVoltage(deviceDataItem.getFloat("bVoltage"));
+                vo.setCVoltage(deviceDataItem.getFloat("cVoltage"));
+                vo.setAElectricity(deviceDataItem.getFloat("aElectricity"));
+                vo.setBElectricity(deviceDataItem.getFloat("bElectricity"));
+                vo.setCElectricity(deviceDataItem.getFloat("cElectricity"));
+                vo.setLine1TEMP(deviceDataItem.getFloat("line1TEMP"));
+                vo.setLine2TEMP(deviceDataItem.getFloat("Line2TEMP"));
+                vo.setLine3TEMP(deviceDataItem.getFloat("Line3TEMP"));
+                vo.setLeakageCurrent(deviceDataItem.getFloat("leakageCurrent"));
+
+                // 根据模拟模式选择不同的功率字段
+                vo.setTotalPower(simulation ?
+                        deviceDataItem.getFloat("totalPower") :
+                        deviceDataItem.getFloat("active_power"));
+
+                try {
+                    sendMqttMessage(EnvMonitorMqttTopic.ELECTRICITY_LOAD, vo, "人防用电负荷情况");
+                    result.put("successCount", result.get("successCount") + 1);
+                } catch (Exception e) {
+                    log.warn("设备{}的人防用电负荷情况数据推送失败:{}", deviceId, e.getMessage());
+                    result.put("failureCount", result.get("failureCount") + 1);
+                }
+            }
+
+            log.info("人防用电负荷情况数据推送完成,设备类型:{},成功:{},失败:{}",
+                    deviceType, result.get("successCount"), result.get("failureCount"));
+
+            return result;
+        } catch (Exception e) {
+            log.error("人防用电负荷情况数据推送发生异常", e);
+            result.put("failureCount", transferVO.getDevices().size());
+            return result;
+        }
+    }
+
+    // 提取公共发送方法,减少代码冗余
+    private void sendTempData(Integer deviceId, LocalDateTime dataEndTime, JSONObject deviceDataItem, Long engineeringID) {
+        Float value = deviceDataItem.getFloat("wd");
+        if (value == null) {
+            log.warn("设备{}的温度数据为空", deviceId);
+            return;
+        }
+        TempVO tempVO = new TempVO();
+        tempVO.setDataPacketID(generateDataPacketID());
+        tempVO.setSensorID(deviceId);
+        tempVO.setEngineeringID(engineeringID);
+        tempVO.setPublishTime(getCurrentTime());
+        tempVO.setSensorValue(value);
+        tempVO.setDataEndTime(dataEndTime);
+        sendMqttMessage(EnvMonitorMqttTopic.TEMP, tempVO, "温度信息");
+    }
+
+    private void sendHumidityData(Integer deviceId, LocalDateTime dataEndTime, JSONObject deviceDataItem, Long engineeringID) {
+        Float value = deviceDataItem.getFloat("sd");
+        if (value == null) {
+            log.warn("设备{}的湿度数据为空", deviceId);
+            return;
+        }
+        HumidityVO humidityVO = new HumidityVO();
+        humidityVO.setDataPacketID(generateDataPacketID());
+        humidityVO.setSensorID(deviceId);
+        humidityVO.setEngineeringID(engineeringID);
+        humidityVO.setPublishTime(getCurrentTime());
+        humidityVO.setSensorValue(value);
+        humidityVO.setDataEndTime(dataEndTime);
+        sendMqttMessage(EnvMonitorMqttTopic.HUMIDITY, humidityVO, "湿度信息");
+    }
+
+    private void sendOxygenData(Integer deviceId, LocalDateTime dataEndTime, JSONObject deviceDataItem, Long engineeringID) {
+        Float value = deviceDataItem.getFloat("o2");
+        if (value == null) {
+            log.warn("设备{}的氧气浓度数据为空", deviceId);
+            return;
+        }
+        OxygenVO oxygenVO = new OxygenVO();
+        oxygenVO.setDataPacketID(generateDataPacketID());
+        oxygenVO.setSensorID(deviceId);
+        oxygenVO.setEngineeringID(engineeringID);
+        oxygenVO.setPublishTime(getCurrentTime());
+        oxygenVO.setSensorValue(value);
+        oxygenVO.setDataEndTime(dataEndTime);
+        sendMqttMessage(EnvMonitorMqttTopic.OXYGEN, oxygenVO, "氧气浓度信息");
+    }
+
+    private void sendCoData(Integer deviceId, LocalDateTime dataEndTime, JSONObject deviceDataItem, Long engineeringID) {
+        Float value = deviceDataItem.getFloat("co");
+        if (value == null) {
+            log.warn("设备{}的一氧化碳浓度数据为空", deviceId);
+            return;
+        }
+        CoVO coVO = new CoVO();
+        coVO.setDataPacketID(generateDataPacketID());
+        coVO.setSensorID(deviceId);
+        coVO.setEngineeringID(engineeringID);
+        coVO.setPublishTime(getCurrentTime());
+        coVO.setSensorValue(value);
+        coVO.setDataEndTime(dataEndTime);
+        sendMqttMessage(EnvMonitorMqttTopic.CO, coVO, "一氧化碳浓度信息");
+    }
+
+    private void sendCo2Data(Integer deviceId, LocalDateTime dataEndTime, JSONObject deviceDataItem, Long engineeringID) {
+        Float value = deviceDataItem.getFloat("co2");
+        if (value == null) {
+            log.warn("设备{}的二氧化碳浓度数据为空", deviceId);
+            return;
+        }
+        Co2VO co2VO = new Co2VO();
+        co2VO.setDataPacketID(generateDataPacketID());
+        co2VO.setSensorID(deviceId);
+        co2VO.setEngineeringID(engineeringID);
+        co2VO.setPublishTime(getCurrentTime());
+        co2VO.setSensorValue(value);
+        co2VO.setDataEndTime(dataEndTime);
+        sendMqttMessage(EnvMonitorMqttTopic.CO2, co2VO, "二氧化碳浓度信息");
+    }
+
+    /**
+     * 同步设备数据
+     * @param tenantId 租户ID
+     * @param engineeringId 工程ID
+     */
+    public void synchronizeDeviceData(Integer tenantId, Long engineeringId) {
+        // 参数校验
+        if (tenantId == null || engineeringId == null) {
+            log.error("租户ID或工程ID不能为空");
+            return;
+        }
+
+        // 查询租户下的所有产品类型
+        List<String> deviceTypeList = getDeviceTypeListByTenant(tenantId);
+        if (deviceTypeList.isEmpty()) {
+            log.warn("租户{}不存在任何产品", tenantId);
+            return;
+        }
+
+        // 查询设备列表
+        List<DmpDevice> deviceList = getDeviceListByType(deviceTypeList, tenantId);
+        if (deviceList.isEmpty()) {
+            log.warn("租户{}不存在任何设备", tenantId);
+            return;
+        }
+
+        // 按设备类型分组
+        Map<Integer, List<DmpDevice>> deviceTypeMap = deviceList.stream()
+                .collect(Collectors.groupingBy(DmpDevice::getDeviceType));
+
+        // 构建数据传输对象列表
+        List<IotDataTransferVO> transferList = new ArrayList<>();
+        deviceTypeMap.forEach((deviceType, devices) -> {
+            IotDataTransferVO transferVO = new IotDataTransferVO();
+            transferVO.setDeviceType(deviceType);
+            transferVO.setDevices(devices);
+            transferVO.setEngineeringId(engineeringId);
+            transferList.add(transferVO);
+        });
+
+        // 按产品代码分组,构建ProductCode到uuid列表的映射,过滤掉产品代码为null的设备
+        Map<String, List<String>> codeDeviceUuidsMap = deviceList.stream()
+                .filter(device -> device.getProductCode() != null)
+                .collect(Collectors.groupingBy(DmpDevice::getProductCode,
+                        Collectors.mapping(DmpDevice::getDeviceUuid, Collectors.toList())));
+
+        // 任务开始日志
+        Integer totalDevices = deviceList.size();
+        Integer totalProductTypes = codeDeviceUuidsMap.size();
+        log.info("设备数据同步任务开始,租户ID:{},工程ID:{}", tenantId, engineeringId);
+        log.info("总共涉及产品类型数:{}个,产品代码为:{}", totalProductTypes, codeDeviceUuidsMap.keySet());
+        log.info("总共需要推送设备数量:{}个,涉及设备类型数:{}个,设备类型为:{}",
+                totalDevices, deviceTypeMap.size(), deviceTypeMap.keySet());
+
+        // 记录每种设备类型的设备数量
+        deviceTypeMap.forEach((deviceType, devices) -> {
+            log.info("设备类型:{},设备数量:{}", deviceType, devices.size());
+        });
+
+        // 按设备类型处理数据同步
+        int totalSuccessCount = 0;
+        int totalFailureCount = 0;
+
+        for (IotDataTransferVO transferVO : transferList) {
+            Integer deviceType = transferVO.getDeviceType();
+            Map<String, Integer> result = new HashMap<>();
+
+            switch (deviceType) {
+                case 707:
+                case 708:
+                case 709:
+                case 710:
+                case 711:
+                    result = sendEnvData(transferVO);
+                    break;
+                case 702:
+                    result = sendWaterLeak(transferVO);
+                    break;
+                case 703:
+                    result = sendPersonPresence(transferVO);
+                    break;
+                case 704:
+                    result = sendElectricityLoad(transferVO);
+                    break;
+                default:
+                    log.debug("不支持的设备类型:{}", deviceType);
+                    continue;
+            }
+
+            // 累加成功数和失败数
+            totalSuccessCount += result.get("successCount");
+            totalFailureCount += result.get("failureCount");
+        }
+
+        // 任务完成总结
+        log.info("设备数据同步任务完成,租户ID:{},工程ID:{}", tenantId, engineeringId);
+        log.info("总共涉及产品类型数:{}个,产品代码为:{}", totalProductTypes, codeDeviceUuidsMap.keySet());
+        log.info("总共推送设备数量:{}个,成功:{}个,失败:{}个",
+                totalDevices, totalSuccessCount, totalFailureCount);
+    }
+
+    /**
+     * 查询租户下的设备类型列表
+     * @param tenantId 租户ID
+     * @return 设备类型列表
+     */
+    private List<String> getDeviceTypeListByTenant(Integer tenantId) {
+        LambdaQueryWrapper<DmpProduct> productQueryWrapper = new LambdaQueryWrapper<>();
+        productQueryWrapper.select(DmpProduct::getProductCode)
+                .eq(DmpProduct::getTenantId, tenantId)
+                .eq(DmpProduct::getDeleteFlag, 0);
+        List<DmpProduct> productList = dmpProductMapper.selectList(productQueryWrapper);
+        return productList.stream()
+                .map(DmpProduct::getProductCode)
+                .distinct() // 去重
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * 根据设备类型列表查询设备
+     * @param productCodeList 设备类型列表
+     * @return 设备列表
+     */
+    private List<DmpDevice> getDeviceListByType(List<String> productCodeList, Integer tenantId) {
+        LambdaQueryWrapper<DmpDevice> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.select(DmpDevice::getDeviceUuid, DmpDevice::getDeviceType, DmpDevice::getDeviceId, DmpDevice::getProductCode)
+                .in(DmpDevice::getProductCode, productCodeList)
+                .eq(DmpDevice::getDeleteFlag, 0)
+                .notIn(DmpDevice::getServiceStatus, 3)
+                .orderByAsc(DmpDevice::getProductCode);
+        return dmpDeviceMapper.selectList(queryWrapper);
+    }
+
+    /**
+     * 验证MQTT网关是否初始化
+     * @return 是否初始化
+     */
+    private boolean validateMqttGateway() {
+        if (mqttGateway == null) {
+            log.warn("MQTT Gateway未初始化,无法发送消息");
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 解析数据时间
+     * @param deviceDataItem 设备数据
+     * @return 解析后的时间,如果解析失败返回null
+     */
+    private LocalDateTime parseDataTime(JSONObject deviceDataItem) {
+        Long dataTime = deviceDataItem.getLong("time");
+        if (dataTime == null) {
+            log.warn("设备{}的time为空", deviceDataItem.getString("device_id"));
+            return null;
+        }
+        return LocalDateTime.ofInstant(Instant.ofEpochMilli(dataTime), ZoneId.systemDefault());
+    }
+
+    /**
+     * 发送MQTT消息
+     * @param topicEnum 主题枚举
+     * @param vo 消息对象
+     * @param messageType 消息类型描述
+     */
+    private void sendMqttMessage(EnvMonitorMqttTopic topicEnum, Object vo, String messageType) {
+        String json = JSON.toJSONString(vo);
+        String topic = topicEnum.getTopic();
+        // 不再记录每条数据的详情,只记录发送操作
+        mqttGateway.sendToMqtt(topic, json);
+    }
+}

+ 61 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/listener/MqttListener.java

@@ -0,0 +1,61 @@
+package com.usky.cdi.service.listener;
+
+import com.usky.cdi.service.config.mqtt.MqttInConfig;
+import com.usky.cdi.service.mqtt.SimpleContext;
+import com.usky.cdi.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 han
+ * @date 2025/03/20 14:41
+ */
+@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 -> {
+            try {
+                String payload = message.getPayload().toString();
+                //进行接口推送
+                Object mqttReceivedTopic = message.getHeaders().get("mqtt_receivedTopic");
+                if (null != mqttReceivedTopic) {
+                    String topic = mqttReceivedTopic.toString();
+                    if (topic != null) {
+                        MqttBaseVO mqttBaseVO = new MqttBaseVO();
+                        mqttBaseVO.setTopic(topic);
+                        if (topic.indexOf("info") != -1) {
+                            mqttBaseVO.setDescribe("info");
+                            mqttBaseVO.setData(payload);
+                        } else if (topic.indexOf("event") != -1) {
+                            mqttBaseVO.setDescribe("event");
+                            mqttBaseVO.setData(payload);
+                        }
+                        //统一处理数据
+                        simpleContext.getResource(mqttBaseVO);
+                    }
+                }
+            } catch (Exception e) {
+                log.error("处理MQTT消息时发生错误", e);
+            }
+        };
+    }
+}

+ 13 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/mqtt/MqttStrategy.java

@@ -0,0 +1,13 @@
+package com.usky.cdi.service.mqtt;
+
+import com.usky.cdi.service.vo.MqttBaseVO;
+
+public interface MqttStrategy {
+    /**
+     * 处理消息(策略模式由子类实现)
+     *
+     * @param mqttBaseVO
+     * @return
+     */
+    String disposeMessage(MqttBaseVO mqttBaseVO);
+}

+ 35 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/mqtt/SimpleContext.java

@@ -0,0 +1,35 @@
+package com.usky.cdi.service.mqtt;
+
+import com.usky.cdi.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 {
+    private final Map<String, MqttStrategy> strategyMap;
+
+    @Autowired
+    public SimpleContext(Map<String, MqttStrategy> strategyMap) {
+        this.strategyMap = new ConcurrentHashMap<>();
+        if (strategyMap != null) {
+            strategyMap.forEach(this.strategyMap::put);
+        }
+    }
+
+    public String getResource(MqttBaseVO mqttBaseVO) {
+        if (mqttBaseVO == null || mqttBaseVO.getDescribe() == null) {
+            return null;
+        }
+        MqttStrategy strategy = strategyMap.get(mqttBaseVO.getDescribe());
+        if (strategy == null) {
+            return null;
+        }
+        return strategy.disposeMessage(mqttBaseVO);
+    }
+}

+ 29 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/mqtt/event/event.java

@@ -0,0 +1,29 @@
+package com.usky.cdi.service.mqtt.event;
+
+import com.alibaba.fastjson.JSONObject;
+import com.usky.cdi.service.mqtt.MqttStrategy;
+import com.usky.cdi.service.vo.MqttBaseVO;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author han
+ * @date 2025/03/20
+ */
+@Service("event")
+public class event implements MqttStrategy {
+
+    //处理下发命令响应消息
+    public String disposeMessage(MqttBaseVO mqttBaseVO) {
+
+        try {
+            JSONObject eventVO1 = JSONObject.parseObject(mqttBaseVO.getData().toString());
+            JSONObject eventVO = new JSONObject();
+            JSONObject eventVO2 = new JSONObject();
+            System.out.println("FEventReceiver消费者收到消息: " + mqttBaseVO.getData().toString());
+        } catch (Exception e){
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+}

+ 31 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/mqtt/info/Info.java

@@ -0,0 +1,31 @@
+package com.usky.cdi.service.mqtt.info;
+
+import com.alibaba.fastjson.JSONObject;
+import com.usky.cdi.service.mqtt.MqttStrategy;
+import com.usky.cdi.service.vo.MqttBaseVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author han
+ * @date 2025/03/20 17:56
+ */
+@Slf4j
+@Service("info")
+public class Info implements MqttStrategy {
+
+    public String disposeMessage(MqttBaseVO mqttBaseVO) {
+        if (mqttBaseVO == null || mqttBaseVO.getData() == null) {
+            log.warn("MqttBaseVO或数据为空");
+            return null;
+        }
+        try {
+            JSONObject mapData = JSONObject.parseObject(mqttBaseVO.getData().toString());
+            log.info("FInfoReceiver消费者收到消息: {}", mqttBaseVO.getData().toString());
+        } catch (Exception e) {
+            log.error("处理Info消息时发生错误", e);
+        }
+
+        return null;
+    }
+}

+ 333 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/util/DeviceDataQuery.java

@@ -0,0 +1,333 @@
+package com.usky.cdi.service.util;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.usky.cdi.domain.DmpDevice;
+import com.usky.cdi.mapper.DmpDeviceMapper;
+import com.usky.cdi.service.vo.IotDataTransferVO;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.text.DecimalFormat;
+import java.util.*;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.stream.Collectors;
+
+/**
+ *
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/11/27
+ */
+@Data
+@Slf4j
+@Component
+@ConfigurationProperties(prefix = "device")
+public class DeviceDataQuery {
+    @Autowired
+    private DmpDeviceMapper dmpDeviceMapper;
+    @Value("${device.data.base-url}")
+    private String baseUrl;
+    @Value("${device.data.simulation}")
+    private boolean simulation;
+    private Map<String, String> deviceFieldMapping;
+
+    // 定义各参数的格式化器(整数位,小数位)
+    private static final DecimalFormat FORMAT_2_2 = new DecimalFormat("00.00"); // 2位整数+2位小数
+    private static final DecimalFormat FORMAT_0_3 = new DecimalFormat("0.000"); // 0位整数+3位小数
+    private static final DecimalFormat FORMAT_3_2 = new DecimalFormat("000.00"); // 3位整数+2位小数
+    private static final DecimalFormat FORMAT_4_2 = new DecimalFormat("0000.00"); // 4位整数+2位小数
+
+    /**
+     * 获取指定设备类型的设备数据
+     * @param transferVO 设备数据传输请求参数
+     * @return 设备数据列表
+     */
+    public List<JSONObject> getDeviceData(IotDataTransferVO transferVO) {
+        // 参数验证
+        if (transferVO == null || transferVO.getDevices() == null || transferVO.getDevices().isEmpty()) {
+            log.warn("获取设备数据失败:参数无效");
+            return Collections.emptyList();
+        }
+
+        try {
+            // 构建请求参数
+            JSONObject requestBody = new JSONObject();
+            List<String> deviceUuids = transferVO.getDevices().stream()
+                    .map(DmpDevice::getDeviceUuid)
+                    .collect(Collectors.toList());
+            requestBody.put("deviceUuids", deviceUuids);
+
+            log.debug("请求设备数据接口,设备数量:{}", deviceUuids.size());
+            String response = HttpClientUtils.doPostJson(baseUrl, requestBody.toJSONString());
+
+            List<JSONObject> resultList = parseResponseData(response, transferVO.getDeviceType(), transferVO.getDevices());
+
+            // 若返回数据为空且开启模拟模式,则生成模拟数据
+            if (resultList.isEmpty() && simulation) {
+                log.info("接口返回数据为空,生成模拟数据,设备类型:{}", transferVO.getDeviceType());
+                resultList = generateSimulationData(transferVO.getDeviceType(), transferVO.getDevices());
+            }
+
+            return resultList;
+        } catch (Exception e) {
+            log.error("获取设备数据失败:{}", e.getMessage(), e);
+            // 异常情况下若开启模拟模式,则生成模拟数据
+            if (simulation) {
+                log.info("接口调用异常,生成模拟数据,设备类型:{}", transferVO.getDeviceType());
+                return generateSimulationData(transferVO.getDeviceType(), transferVO.getDevices());
+            }
+            return Collections.emptyList();
+        }
+    }
+
+    /**
+     * 解析接口响应数据,提取指定字段
+     * @param responseJson 接口响应JSON字符串
+     * @param deviceType 设备类型
+     * @param devices 设备列表
+     * @return 解析后的设备数据列表
+     */
+    private List<JSONObject> parseResponseData(String responseJson, Integer deviceType, List<DmpDevice> devices) {
+        List<JSONObject> resultList = new ArrayList<>();
+        if (responseJson == null || responseJson.trim().isEmpty()) {
+            log.warn("接口响应数据为空");
+            return resultList;
+        }
+
+        try {
+            // 构建设备UUID到ID的映射,过滤掉deviceUuid为null的设备
+            Map<String, String> deviceUuidToIdMap = devices.stream()
+                    .filter(device -> device.getDeviceUuid() != null)
+                    .collect(Collectors.toMap(DmpDevice::getDeviceUuid, DmpDevice::getDeviceId));
+
+            JSONObject responseObj = JSON.parseObject(responseJson);
+
+            // 检查响应状态
+            String status = responseObj.getString("status");
+            String code = responseObj.getString("code");
+
+            if (!"SUCCESS".equals(status) || !"0".equals(code)) {
+                log.warn("接口返回失败:状态={}, 错误码={}, 错误信息={}", status, code, responseObj.getString("msg"));
+                return resultList;
+            }
+
+            JSONArray dataArray = responseObj.getJSONArray("data");
+            if (dataArray == null || dataArray.isEmpty()) {
+                log.debug("接口响应数据为空数组");
+                return resultList;
+            }
+
+            List<String> targetFields = getTargetFieldsByDeviceType(deviceType);
+
+            for (int i = 0; i < dataArray.size(); i++) {
+                JSONObject deviceData = dataArray.getJSONObject(i);
+                if (deviceData == null) {
+                    continue;
+                }
+
+                JSONObject metrics = deviceData.getJSONObject("metrics");
+                String deviceUuid = deviceData.getString("deviceuuid");
+
+                if (metrics == null || deviceUuid == null) {
+                    continue;
+                }
+
+                JSONObject targetData = new JSONObject();
+                boolean hasValidData = false;
+
+                // 提取目标字段数据
+                for (String field : targetFields) {
+                    Object value = metrics.get(field);
+                    if (value != null) {
+                        targetData.put(field, value);
+                        hasValidData = true;
+                    }
+                }
+
+                // 添加设备标识信息
+                targetData.put("deviceuuid", deviceUuid);
+                String deviceId = deviceUuidToIdMap.get(deviceUuid);
+                if (deviceId != null) {
+                    targetData.put("device_id", deviceId);
+                }
+
+                if (hasValidData) {
+                    resultList.add(targetData);
+                }
+            }
+
+            log.debug("解析接口响应数据完成,有效设备数据数量:{}", resultList.size());
+            return resultList;
+        } catch (Exception e) {
+            log.error("解析接口响应数据失败:{}", e.getMessage(), e);
+            return Collections.emptyList();
+        }
+    }
+
+    /**
+     * 根据设备类型获取目标字段(自动包含time)
+     * @param deviceType 设备类型
+     * @return 目标字段列表
+     */
+    private List<String> getTargetFieldsByDeviceType(Integer deviceType) {
+        if (deviceType == null) {
+            log.warn("获取目标字段失败:设备类型为空");
+            return Collections.singletonList("time");
+        }
+
+        String fieldsStr = deviceFieldMapping.get(deviceType.toString());
+        if (fieldsStr == null || fieldsStr.trim().isEmpty()) {
+            log.warn("获取目标字段失败:设备类型{}对应的字段映射不存在", deviceType);
+            return Collections.singletonList("time");
+        }
+
+        List<String> fields = Arrays.stream(fieldsStr.split(","))
+                .map(String::trim)
+                .filter(field -> !field.isEmpty())
+                .collect(Collectors.toList());
+
+        // 确保包含时间字段
+        if (!fields.contains("time")) {
+            fields.add("time");
+        }
+
+        return fields;
+    }
+
+    /**
+     * 生成模拟数据(按指定精度格式化)
+     * @param deviceType 设备类型
+     * @param devices 设备列表
+     * @return 模拟数据列表
+     */
+    private List<JSONObject> generateSimulationData(Integer deviceType, List<DmpDevice> devices) {
+        List<JSONObject> simulationList = new ArrayList<>();
+        long currentTime = System.currentTimeMillis();
+
+        // 定义模拟数据范围常量
+        final double TEMP_RANGE_MIN = 10.0;
+        final double TEMP_RANGE_MAX = 20.0;
+        final double HUMIDITY_RANGE_MIN = 40.0;
+        final double HUMIDITY_RANGE_MAX = 85.0;
+        final double OXYGEN_RANGE_MIN = 20.0;
+        final double OXYGEN_RANGE_MAX = 21.0;
+        final double CO2_RANGE_MIN = 750.0;
+        final double CO2_RANGE_MAX = 760.0;
+        final double VOLTAGE_RANGE_MIN = 220.0;
+        final double VOLTAGE_RANGE_MAX = 230.0;
+        final double CURRENT_RANGE_MIN = 0.0;
+        final double CURRENT_RANGE_MAX = 50.0;
+        final double POWER_RANGE_MIN = 1.0;
+        final double POWER_RANGE_MAX = 20.0;
+        final double TEMP_LINE_RANGE_MIN = 20.0;
+        final double TEMP_LINE_RANGE_MAX = 50.0;
+        final double LEAKAGE_CURRENT_RANGE_MIN = 0.0;
+        final double LEAKAGE_CURRENT_RANGE_MAX = 100.0;
+
+        for (DmpDevice device : devices) {
+            JSONObject simulationData = new JSONObject();
+            simulationData.put("time", currentTime);
+            simulationData.put("device_id", device.getDeviceId());
+
+            if (deviceType == null) {
+                log.warn("生成模拟数据失败:设备类型为空,设备ID:{}", device.getId());
+                continue;
+            }
+
+            switch (deviceType) {
+                // 单一温度传感器(707)
+                case 707:
+                    double temp707 = ThreadLocalRandom.current().nextDouble(TEMP_RANGE_MIN, TEMP_RANGE_MAX);
+                    simulationData.put("wd", formatNumber(temp707, FORMAT_2_2));
+                    break;
+
+                // 单一湿度传感器(708)
+                case 708:
+                    double hum708 = ThreadLocalRandom.current().nextDouble(HUMIDITY_RANGE_MIN, HUMIDITY_RANGE_MAX);
+                    simulationData.put("sd", formatNumber(hum708, FORMAT_2_2));
+                    break;
+
+                // 单一氧气传感器(709)
+                case 709:
+                    double o2709 = ThreadLocalRandom.current().nextDouble(OXYGEN_RANGE_MIN, OXYGEN_RANGE_MAX);
+                    simulationData.put("o2", formatNumber(o2709, FORMAT_2_2));
+                    break;
+
+                // 单一二氧化碳传感器(710)
+                case 710:
+                    double co2710 = ThreadLocalRandom.current().nextDouble(CO2_RANGE_MIN, CO2_RANGE_MAX);
+                    simulationData.put("co2", formatNumber(co2710, FORMAT_0_3));
+                    break;
+
+                // 单一一氧化碳传感器(711)
+                case 711:
+                    simulationData.put("co", 0);
+                    break;
+
+                // 水浸(702)
+                case 702:
+                    simulationData.put("leach_status", 0);
+                    break;
+
+                // 人员统计(703)
+                case 703:
+                    simulationData.put("sensorValue", 0);
+                    break;
+
+                // 电气火灾(704)
+                case 704:
+                    // A/B/C相电压:3位整数+2位小数(220.00~230.00V)
+                    simulationData.put("aVoltage", formatNumber(ThreadLocalRandom.current().nextDouble(VOLTAGE_RANGE_MIN, VOLTAGE_RANGE_MAX), FORMAT_3_2));
+                    simulationData.put("bVoltage", formatNumber(ThreadLocalRandom.current().nextDouble(VOLTAGE_RANGE_MIN, VOLTAGE_RANGE_MAX), FORMAT_3_2));
+                    simulationData.put("cVoltage", formatNumber(ThreadLocalRandom.current().nextDouble(VOLTAGE_RANGE_MIN, VOLTAGE_RANGE_MAX), FORMAT_3_2));
+
+                    // A/B/C相电流:3位整数+2位小数(0.00~50.00A)
+                    simulationData.put("aElectricity", formatNumber(ThreadLocalRandom.current().nextDouble(CURRENT_RANGE_MIN, CURRENT_RANGE_MAX), FORMAT_3_2));
+                    simulationData.put("bElectricity", formatNumber(ThreadLocalRandom.current().nextDouble(CURRENT_RANGE_MIN, CURRENT_RANGE_MAX), FORMAT_3_2));
+                    simulationData.put("cElectricity", formatNumber(ThreadLocalRandom.current().nextDouble(CURRENT_RANGE_MIN, CURRENT_RANGE_MAX), FORMAT_3_2));
+
+                    // 总功率:4位整数+2位小数(1.00~20.00)
+                    simulationData.put("totalPower", formatNumber(ThreadLocalRandom.current().nextDouble(POWER_RANGE_MIN, POWER_RANGE_MAX), FORMAT_4_2));
+
+                    // 线温1-4:2位整数+2位小数(20.00~50.00℃)
+                    simulationData.put("line1TEMP", formatNumber(ThreadLocalRandom.current().nextDouble(TEMP_LINE_RANGE_MIN, TEMP_LINE_RANGE_MAX), FORMAT_2_2));
+                    simulationData.put("Line2TEMP", formatNumber(ThreadLocalRandom.current().nextDouble(TEMP_LINE_RANGE_MIN, TEMP_LINE_RANGE_MAX), FORMAT_2_2));
+                    simulationData.put("Line3TEMP", formatNumber(ThreadLocalRandom.current().nextDouble(TEMP_LINE_RANGE_MIN, TEMP_LINE_RANGE_MAX), FORMAT_2_2));
+                    simulationData.put("Line4TEMP", formatNumber(ThreadLocalRandom.current().nextDouble(TEMP_LINE_RANGE_MIN, TEMP_LINE_RANGE_MAX), FORMAT_2_2));
+
+                    // 剩余电流:4位整数+2位小数(0.00~100.00mA)
+                    simulationData.put("leakageCurrent", formatNumber(ThreadLocalRandom.current().nextDouble(LEAKAGE_CURRENT_RANGE_MIN, LEAKAGE_CURRENT_RANGE_MAX), FORMAT_4_2));
+                    break;
+
+                default:
+                    log.warn("未知设备类型:{},无法生成模拟数据", deviceType);
+                    break;
+            }
+
+            simulationList.add(simulationData);
+        }
+
+        log.info("生成模拟数据完成,设备类型:{},数量:{}", deviceType, simulationList.size());
+        return simulationList;
+    }
+
+    /**
+     * 通用数值格式化方法
+     * @param value 原始数值
+     * @param format 格式化器
+     * @return 格式化后的字符串
+     */
+    private String formatNumber(double value, DecimalFormat format) {
+        if (format == null) {
+            return String.valueOf(value);
+        }
+        return format.format(value);
+    }
+
+}

+ 41 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/util/DeviceDataSyncService.java

@@ -0,0 +1,41 @@
+package com.usky.cdi.service.util;
+
+import com.usky.cdi.service.impl.IotDataTransferService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+/**
+ * 设备数据同步组件(包含定时任务)
+ */
+@Slf4j
+@Component
+public class DeviceDataSyncService {
+
+    private final IotDataTransferService iotDataTransferService;
+
+    @Autowired
+    public DeviceDataSyncService(IotDataTransferService iotDataTransferService) {
+        this.iotDataTransferService = iotDataTransferService;
+    }
+
+    /**
+     * 定时任务:定期执行设备数据同步上报
+     * fixedDelay:任务执行完成后固定延迟29分钟执行下一次
+     * initialDelay:初始化后立即执行第一次任务
+     */
+    @Scheduled(fixedDelay = 15 * 60 * 1000, initialDelay = 0)
+    public void scheduledDeviceDataSync() {
+        Integer tenantId = 1205;
+        Long engineeringId = 3101070011L;
+        log.info("开始执行设备数据同步定时任务,租户ID:{},工程ID:{}", tenantId, engineeringId);
+
+        try {
+            iotDataTransferService.synchronizeDeviceData(tenantId, engineeringId);
+        } catch (Exception e) {
+            log.error("定时任务执行设备数据同步失败:{}", e.getMessage(), e);
+        }
+    }
+}

+ 138 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/util/HttpClientUtils.java

@@ -0,0 +1,138 @@
+package com.usky.cdi.service.util;
+
+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;
+
+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, String> param) {
+        // 创建Httpclient对象
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        CloseableHttpResponse response = null;
+        String resultString = "";
+        try {
+            // 创建Http Post请求
+            HttpPost httpPost = new HttpPost(url);
+            // 创建参数列表
+            if (param != null) {
+                List<NameValuePair> paramList = new ArrayList<>();
+                for (String key : param.keySet()) {
+                    paramList.add(new BasicNameValuePair(key, param.get(key)));
+                }
+                // 模拟表单
+                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 {
+                if (response != null) {
+                    response.close();
+                }
+                httpClient.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 {
+                if (response != null) {
+                    response.close();
+                }
+                httpClient.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+
+        return resultString;
+    }
+}

+ 34 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/util/SignUtil.java

@@ -0,0 +1,34 @@
+package com.usky.cdi.service.util;
+
+import cn.hutool.crypto.SecureUtil;
+import com.usky.common.core.utils.StringUtils;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class SignUtil {
+
+    /**
+     * 使用 Map按key进行排序
+     *
+     * @param map
+     * @return
+     */
+    public static Map<String, String> sortMapByKey(Map<String, String> map) {
+        if (map == null || map.isEmpty()) {
+            return null;
+        }
+        //升序排序
+        Map<String, String> sortMap = new TreeMap<>(String::compareTo);
+        sortMap.putAll(map);
+        return sortMap;
+    }
+
+    public static String sign(String body, Map<String, String[]> params, Map<String, String> requestPathMap,
+                              String secretKey, String timestamp, String appKey) {
+        String a = String.join("#", secretKey, timestamp, appKey);
+        return SecureUtil.md5(a);
+    }
+}

+ 145 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/util/SnowflakeIdGenerator.java

@@ -0,0 +1,145 @@
+package com.usky.cdi.service.util;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 雪花算法ID生成器
+ * 用于生成15位不重复的数据包ID
+ * 
+ * @author han
+ * @date 2025/03/20
+ */
+@Slf4j
+public class SnowflakeIdGenerator {
+    
+    // 起始时间戳 (2025-01-01 00:00:00)
+    private static final long START_TIMESTAMP = 1735689600000L;
+    
+    // 机器ID所占的位数
+    private static final long WORKER_ID_BITS = 5L;
+    
+    // 数据标识ID所占的位数
+    private static final long DATACENTER_ID_BITS = 5L;
+    
+    // 支持的最大机器ID,结果是31
+    private static final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS);
+    
+    // 支持的最大数据标识ID,结果是31
+    private static final long MAX_DATACENTER_ID = ~(-1L << DATACENTER_ID_BITS);
+    
+    // 序列在ID中占的位数
+    private static final long SEQUENCE_BITS = 12L;
+    
+    // 机器ID向左移12位
+    private static final long WORKER_ID_SHIFT = SEQUENCE_BITS;
+    
+    // 数据标识ID向左移17位(12+5)
+    private static final long DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;
+    
+    // 时间戳向左移22位(5+5+12)
+    private static final long TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS;
+    
+    // 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095)
+    private static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS);
+    
+    // 工作机器ID(0~31)
+    private long workerId;
+    
+    // 数据中心ID(0~31)
+    private long datacenterId;
+    
+    // 毫秒内序列(0~4095)
+    private long sequence = 0L;
+    
+    // 上次生成ID的时间戳
+    private long lastTimestamp = -1L;
+    
+    /**
+     * 构造函数
+     * 
+     * @param workerId 工作ID (0~31)
+     * @param datacenterId 数据中心ID (0~31)
+     */
+    public SnowflakeIdGenerator(long workerId, long datacenterId) {
+        if (workerId > MAX_WORKER_ID || workerId < 0) {
+            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", MAX_WORKER_ID));
+        }
+        if (datacenterId > MAX_DATACENTER_ID || datacenterId < 0) {
+            throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", MAX_DATACENTER_ID));
+        }
+        this.workerId = workerId;
+        this.datacenterId = datacenterId;
+    }
+    
+    /**
+     * 获得下一个ID (该方法是线程安全的)
+     * 
+     * @return SnowflakeId
+     */
+    public synchronized long nextId() {
+        long timestamp = timeGen();
+        
+        // 如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
+        if (timestamp < lastTimestamp) {
+            log.error("时钟回退,拒绝生成ID。当前时间戳: {}, 上次时间戳: {}", timestamp, lastTimestamp);
+            throw new RuntimeException(String.format("时钟回退,拒绝生成ID。当前时间戳: %d, 上次时间戳: %d", timestamp, lastTimestamp));
+        }
+        
+        // 如果是同一时间生成的,则进行毫秒内序列
+        if (lastTimestamp == timestamp) {
+            sequence = (sequence + 1) & SEQUENCE_MASK;
+            // 毫秒内序列溢出
+            if (sequence == 0) {
+                // 阻塞到下一个毫秒,获得新的时间戳
+                timestamp = tilNextMillis(lastTimestamp);
+            }
+        } else {
+            // 时间戳改变,毫秒内序列重置
+            sequence = 0L;
+        }
+        
+        // 上次生成ID的时间戳
+        lastTimestamp = timestamp;
+        
+        // 移位并通过或运算拼到一起组成64位的ID
+        return ((timestamp - START_TIMESTAMP) << TIMESTAMP_LEFT_SHIFT)
+                | (datacenterId << DATACENTER_ID_SHIFT)
+                | (workerId << WORKER_ID_SHIFT)
+                | sequence;
+    }
+    
+    /**
+     * 阻塞到下一个毫秒,直到获得新的时间戳
+     * 
+     * @param lastTimestamp 上次生成ID的时间戳
+     * @return 当前时间戳
+     */
+    protected long tilNextMillis(long lastTimestamp) {
+        long timestamp = timeGen();
+        while (timestamp <= lastTimestamp) {
+            timestamp = timeGen();
+        }
+        return timestamp;
+    }
+    
+    /**
+     * 返回以毫秒为单位的当前时间
+     * 
+     * @return 当前时间(毫秒)
+     */
+    protected long timeGen() {
+        return System.currentTimeMillis();
+    }
+    
+    /**
+     * 生成15位数据包ID(取后15位)
+     * 
+     * @return 15位数据包ID
+     */
+    public long nextPacketId() {
+        long id = nextId();
+        // 取后15位,确保不超过15位
+        return id % 1000000000000000L;
+    }
+}
+

+ 28 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/IotDataTransferVO.java

@@ -0,0 +1,28 @@
+package com.usky.cdi.service.vo;
+
+import com.usky.cdi.domain.DmpDevice;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author fu
+ * @date 2025/12/08 10:02
+ */
+@Data
+public class IotDataTransferVO {
+    /**
+     * 设备UUID列表
+     */
+    private List<DmpDevice> devices;
+
+    /**
+     * 人防工程ID
+     */
+    private Long engineeringId;
+
+    /**
+     * 产品ID
+     */
+    private Integer deviceType;
+}

+ 21 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/MqttBaseVO.java

@@ -0,0 +1,21 @@
+package com.usky.cdi.service.vo;
+
+import lombok.Data;
+
+/**
+ * @author han
+ * @date 2025/03/20 14:41
+ */
+@Data
+public class MqttBaseVO {
+    /**
+     * 接口描述
+     */
+    private String describe;
+
+    private String topic;
+    /**
+     * 数据内容
+     */
+    private Object data;
+}

+ 69 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/alarm/AlarmMessage1VO.java

@@ -0,0 +1,69 @@
+package com.usky.cdi.service.vo.alarm;
+
+import lombok.Data;
+
+@Data
+public class AlarmMessage1VO {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 数据包ID
+     */
+    private Long dataPacketID;
+
+    /**
+     * 人防工程ID
+     */
+    private Long engineeringID;
+
+    /**
+     * 事件ID
+     */
+    private Integer alarmID;
+
+    /**
+     * 事件来源
+     */
+    private Integer alarmSource;
+
+    /**
+     * 物联设施ID
+     */
+    private Integer sensorID;
+
+    /**
+     * 事件类型
+     */
+    private String alarmType;
+
+    /**
+     * 事件状态
+     */
+    private Integer alarmStatus;
+
+    /**
+     * 最新水浸状态
+     */
+    private Integer sensorValue;
+
+    /**
+     * 事件发生/更新时间
+     */
+    private String alarmUpdateTime;
+
+    /**
+     * 监测对象编号
+     */
+    private String monitorObjNo;
+
+    /**
+     * 事件描述
+     */
+    private String alarmDesc;
+
+    /**
+     * 上报时间
+     */
+    private String publishTime;
+
+}

+ 69 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/alarm/AlarmMessage2VO.java

@@ -0,0 +1,69 @@
+package com.usky.cdi.service.vo.alarm;
+
+import lombok.Data;
+
+@Data
+public class AlarmMessage2VO {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 数据包ID
+     */
+    private Long dataPacketID;
+
+    /**
+     * 人防工程ID
+     */
+    private Long engineeringID;
+
+    /**
+     * 事件ID
+     */
+    private Integer alarmID;
+
+    /**
+     * 事件来源
+     */
+    private Integer alarmSource;
+
+    /**
+     * 防护单元
+     */
+    private String unitName;
+
+    /**
+     * 事件类型
+     */
+    private String alarmType;
+
+    /**
+     * 事件状态
+     */
+    private Integer alarmStatus;
+
+    /**
+     * 倾斜、位移、裂缝监测结果
+     */
+    private Double sensorValue;
+
+    /**
+     * 事件发生/更新时间
+     */
+    private String alarmUpdateTime;
+
+    /**
+     * 监测对象编号
+     */
+    private String monitorObjNo;
+
+    /**
+     * 事件描述
+     */
+    private String alarmDesc;
+
+    /**
+     * 上报时间
+     */
+    private String publishTime;
+
+}

+ 74 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/alarm/AlarmMessageVO.java

@@ -0,0 +1,74 @@
+package com.usky.cdi.service.vo.alarm;
+
+import lombok.Data;
+
+@Data
+public class AlarmMessageVO {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 数据包ID
+     */
+    private Long dataPacketID;
+
+    /**
+     * 人防工程ID
+     */
+    private Long engineeringID;
+
+    /**
+     * 事件ID
+     */
+    private Integer alarmID;
+
+    /**
+     * 事件来源
+     */
+    private Integer alarmSource;
+
+    /**
+     * 物联设施ID
+     */
+    private Integer sensorID;
+
+    /**
+     * 事件类型
+     */
+    private String alarmType;
+
+    /**
+     * 事件状态
+     */
+    private Integer alarmStatus;
+
+    /**
+     * 最新水浸状态
+     */
+    private Double sensorValue;
+
+    /**
+     * 告警阈值
+     */
+    private Double thresholding;
+
+    /**
+     * 事件发生/更新时间
+     */
+    private String alarmUpdateTime;
+
+    /**
+     * 监测对象编号
+     */
+    private String monitorObjNo;
+
+    /**
+     * 事件描述
+     */
+    private String alarmDesc;
+
+    /**
+     * 上报时间
+     */
+    private String publishTime;
+
+}

+ 93 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/BaseEnvMonitorPushVO.java

@@ -0,0 +1,93 @@
+package com.usky.cdi.service.vo.base;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 环境监测数据推送基类(兼容2021版)
+ * 子类:温度、湿度、氧气、二氧化碳、一氧化碳
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/11/20
+ */
+@Data
+public abstract class BaseEnvMonitorPushVO implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 数据包ID(必填)
+     * 类型:Int,长度15(0 ~ 999999999999999)
+     */
+    private Long dataPacketID;
+
+    /**
+     * 人防工程ID(必填)
+     * 类型:Int,长度10(0 ~ 9999999999)
+     */
+    private Long engineeringID;
+
+    /**
+     * 物联设施ID(必填)
+     * 类型:Int,长度8(0 ~ 99999999)
+     */
+    private Integer sensorID;
+
+    /**
+     * 监测时间(必填)
+     * 类型:Time(yyyy-MM-dd HH:mm:ss.SSS)
+     * 说明:1小时平均周期的末点时间(如10:00表示9:00-10:00的平均数据)
+     */
+    @JSONField(format = "yyyy-MM-dd HH:mm:ss.SSS")
+    private LocalDateTime dataEndTime;
+
+    /**
+     * 上报时间(必填)
+     * 类型:Time(yyyy-MM-dd HH:mm:ss.SSS)
+     */
+    @JSONField(format = "yyyy-MM-dd HH:mm:ss.SSS")
+    private LocalDateTime publishTime;
+
+    /**
+     * 获取监测值(子类实现,返回具体数值)
+     */
+    public abstract Number getSensorValue();
+
+    /**
+     * 校验公共字段(子类需重写校验监测值)
+     */
+    public void validateCommon() {
+        // 1. 必填字段非空校验
+        if (dataPacketID == null) throw new IllegalArgumentException("数据包ID(dataPacketID)为必填项");
+        if (engineeringID == null) throw new IllegalArgumentException("人防工程ID(engineeringID)为必填项");
+        if (sensorID == null) throw new IllegalArgumentException("物联设施ID(sensorID)为必填项");
+        if (dataEndTime == null) throw new IllegalArgumentException("监测时间(dataEndTime)为必填项");
+        if (publishTime == null) throw new IllegalArgumentException("上报时间(publishTime)为必填项");
+
+        // 2. 字段长度校验
+        if (String.valueOf(dataPacketID).length() > 15) throw new IllegalArgumentException("数据包ID长度不能超过15位");
+        if (String.valueOf(engineeringID).length() > 10)
+            throw new IllegalArgumentException("人防工程ID长度不能超过10位");
+        if (String.valueOf(sensorID).length() > 8) throw new IllegalArgumentException("物联设施ID长度不能超过8位");
+
+        // 3. 时间逻辑校验(监测时间不能晚于上报时间)
+        if (dataEndTime.isAfter(publishTime)) throw new IllegalArgumentException("监测时间不能晚于上报时间");
+    }
+
+    /**
+     * 完整校验(公共字段+监测值)
+     */
+    public final void validate() {
+        validateCommon();
+        validateSensorValue();
+    }
+
+    /**
+     * 校验监测值(子类重写,实现具体规则)
+     */
+    protected abstract void validateSensorValue();
+}

+ 57 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/Co2VO.java

@@ -0,0 +1,57 @@
+package com.usky.cdi.service.vo.base;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 二氧化碳浓度推送VO(兼容2021版)
+ * MQTT Topic:iotInfo/co2
+ * 说明:Float(0,3) → 无整数位,3位小数(如 0.123mg/m³,范围:0.000 ~ 0.999)
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/11/20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class Co2VO extends BaseEnvMonitorPushVO {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 1小时平均浓度(必填)
+     * 类型:Float(0,3),单位:mg/m³
+     */
+    private Float sensorValue;
+
+    @Override
+    public Number getSensorValue() {
+        return sensorValue;
+    }
+
+    @Override
+    protected void validateSensorValue() {
+        if (sensorValue == null) throw new IllegalArgumentException("二氧化碳浓度(sensorValue)为必填项");
+
+        // 校验范围:0.000 ~ 0.999mg/m³(符合Float(0,3)约束)
+        if (sensorValue < 0.000f || sensorValue > 0.999f) {
+            throw new IllegalArgumentException("二氧化碳浓度超出范围(0.000 ~ 0.999mg/m³),当前值:" + sensorValue);
+        }
+
+        // 校验小数位:最多3位
+        if (getDecimalDigits(sensorValue) > 3) {
+            throw new IllegalArgumentException("二氧化碳浓度小数位不能超过3位,当前值:" + sensorValue);
+        }
+    }
+
+    private int getDecimalDigits(float value) {
+        String str = String.valueOf(value);
+        if (!str.contains(".")) return 0;
+        String decimalPart = str.split("\\.")[1];
+        // 处理科学计数法(如 1.234E-4 → 0.0001234)
+        if (decimalPart.contains("E")) {
+            return 6;
+            // 科学计数法默认按超3位处理
+        }
+        return decimalPart.length();
+    }
+}

+ 51 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/CoVO.java

@@ -0,0 +1,51 @@
+package com.usky.cdi.service.vo.base;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 一氧化碳浓度推送VO(兼容2021版)
+ * MQTT Topic:iotInfo/co
+ * 说明:Float(2,2) → 0.00 ~ 99.99mg/m³
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/11/20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class CoVO extends BaseEnvMonitorPushVO {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 1小时平均浓度(必填)
+     * 类型:Float(2,2),单位:mg/m³
+     */
+    private Float sensorValue;
+
+    @Override
+    public Number getSensorValue() {
+        return sensorValue;
+    }
+
+    @Override
+    protected void validateSensorValue() {
+        if (sensorValue == null) throw new IllegalArgumentException("一氧化碳浓度(sensorValue)为必填项");
+
+        // 校验范围:0.00 ~ 99.99mg/m³(符合Float(2,2)约束)
+        if (sensorValue < 0.00f || sensorValue > 99.99f) {
+            throw new IllegalArgumentException("一氧化碳浓度超出范围(0.00 ~ 99.99mg/m³),当前值:" + sensorValue);
+        }
+
+        // 校验小数位:最多2位
+        if (getDecimalDigits(sensorValue) > 2) {
+            throw new IllegalArgumentException("一氧化碳浓度小数位不能超过2位,当前值:" + sensorValue);
+        }
+    }
+
+    private int getDecimalDigits(float value) {
+        String str = String.valueOf(value);
+        if (!str.contains(".")) return 0;
+        return str.split("\\.")[1].length();
+    }
+}

+ 159 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/ElectricityLoadVO.java

@@ -0,0 +1,159 @@
+package com.usky.cdi.service.vo.base;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+/**
+ * 人防用电负荷推送VO(兼容2021版)
+ * 用途:每半小时上报配电箱监测数据(电压、电流、功率等)
+ * MQTT Topic:iotInfo/electricityLoad
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/11/20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class ElectricityLoadVO extends BaseEnvMonitorPushVO {
+
+    private static final long serialVersionUID = 1L;
+
+    // ====================== 专属字段(严格映射数据包定义)======================
+
+    /**
+     * A相电压(必填)
+     * 类型:Float(3,2),单位:伏(V)(范围:0.00 ~ 999.99V)
+     */
+    private Float aVoltage;
+
+    /**
+     * B相电压(必填)
+     * 类型:Float(3,2),单位:伏(V)
+     */
+    private Float bVoltage;
+
+    /**
+     * C相电压(必填)
+     * 类型:Float(3,2),单位:伏(V)
+     */
+    private Float cVoltage;
+
+    /**
+     * A相电流(必填)
+     * 类型:Float(3,2),单位:安(A)
+     */
+    private Float aElectricity;
+
+    /**
+     * B相电流(必填)
+     * 类型:Float(3,2),单位:安(A)
+     */
+    private Float bElectricity;
+
+    /**
+     * C相电流(必填)
+     * 类型:Float(3,2),单位:安(A)
+     */
+    private Float cElectricity;
+
+    /**
+     * 总功率(必填)
+     * 类型:Float(4,2),单位:千瓦(kW)(范围:0.00 ~ 9999.99kW)
+     */
+    private Float totalPower;
+
+    /**
+     * 线温1(非必填)
+     * 类型:Float(2,2),单位:℃(范围:-99.99 ~ 99.99℃)
+     */
+    private Float line1TEMP;
+
+    /**
+     * 线温2(非必填)
+     * 类型:Float(2,2),单位:℃
+     */
+    private Float line2TEMP;
+
+    /**
+     * 线温3(非必填)
+     * 类型:Float(2,2),单位:℃
+     */
+    private Float line3TEMP;
+
+    /**
+     * 线温4(非必填)
+     * 类型:Float(2,2),单位:℃
+     */
+    private Float line4TEMP;
+
+    /**
+     * 剩余电流(非必填)
+     * 类型:Float(4,2),单位:mA(范围:0.00 ~ 9999.99mA)
+     */
+    private Float leakageCurrent;
+
+    // ====================== 重写父类方法(适配多字段校验)======================
+
+    /**
+     * 父类抽象方法:返回核心监测值(取总功率作为代表)
+     */
+    @Override
+    public Number getSensorValue() {
+        return totalPower;
+    }
+
+    /**
+     * 个性化校验:校验所有用电负荷字段的合法性
+     */
+    @Override
+    protected void validateSensorValue() {
+        // 1. 必填字段非空校验(父类已校验公共字段,此处校验专属必填字段)
+        if (aVoltage == null) throw new IllegalArgumentException("A相电压(aVoltage)为必填项");
+        if (bVoltage == null) throw new IllegalArgumentException("B相电压(bVoltage)为必填项");
+        if (cVoltage == null) throw new IllegalArgumentException("C相电压(cVoltage)为必填项");
+        if (aElectricity == null) throw new IllegalArgumentException("A相电流(aElectricity)为必填项");
+        if (bElectricity == null) throw new IllegalArgumentException("B相电流(bElectricity)为必填项");
+        if (cElectricity == null) throw new IllegalArgumentException("C相电流(cElectricity)为必填项");
+        if (totalPower == null) throw new IllegalArgumentException("总功率(totalPower)为必填项");
+
+        // 2. 字段长度/范围校验(Float(3,2):总3位+2位小数;Float(4,2):总4位+2位小数)
+        validateFloatRange(aVoltage, 0.00f, 999.99f, "A相电压", 2);
+        validateFloatRange(bVoltage, 0.00f, 999.99f, "B相电压", 2);
+        validateFloatRange(cVoltage, 0.00f, 999.99f, "C相电压", 2);
+        validateFloatRange(aElectricity, 0.00f, 999.99f, "A相电流", 2);
+        validateFloatRange(bElectricity, 0.00f, 999.99f, "B相电流", 2);
+        validateFloatRange(cElectricity, 0.00f, 999.99f, "C相电流", 2);
+        validateFloatRange(totalPower, 0.00f, 9999.99f, "总功率", 2);
+
+        // 3. 非必填字段校验(存在时才校验)
+        if (line1TEMP != null) validateFloatRange(line1TEMP, -99.99f, 99.99f, "线温1", 2);
+        if (line2TEMP != null) validateFloatRange(line2TEMP, -99.99f, 99.99f, "线温2", 2);
+        if (line3TEMP != null) validateFloatRange(line3TEMP, -99.99f, 99.99f, "线温3", 2);
+        if (line4TEMP != null) validateFloatRange(line4TEMP, -99.99f, 99.99f, "线温4", 2);
+        if (leakageCurrent != null) validateFloatRange(leakageCurrent, 0.00f, 9999.99f, "剩余电流", 2);
+    }
+
+    /**
+     * 辅助方法:校验Float类型的范围和小数位
+     * @param value 字段值
+     * @param min 最小值
+     * @param max 最大值
+     * @param fieldName 字段名称
+     * @param maxDecimal 最大小数位数
+     */
+    private void validateFloatRange(Float value, float min, float max, String fieldName, int maxDecimal) {
+        // 范围校验
+        if (value < min || value > max) {
+            throw new IllegalArgumentException(fieldName + "(" + fieldName.toLowerCase() + ")超出范围[" + min + "~" + max + "],当前值:" + value);
+        }
+        // 小数位校验
+        String str = String.valueOf(value);
+        if (str.contains(".")) {
+            int decimalLen = str.split("\\.")[1].length();
+            if (decimalLen > maxDecimal) {
+                throw new IllegalArgumentException(fieldName + "(" + fieldName.toLowerCase() + ")小数位不能超过" + maxDecimal + "位,当前值:" + value);
+            }
+        }
+    }
+}

+ 67 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/EngineeringBaseVO.java

@@ -0,0 +1,67 @@
+package com.usky.cdi.service.vo.base;
+
+import lombok.Data;
+import java.io.Serializable;
+
+/**
+ * 人防工程基础信息VO
+ * Topic: base/engineering
+ * 
+ * @author han
+ * @date 2025/03/20
+ */
+@Data
+public class EngineeringBaseVO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 数据包ID
+     */
+    private Long dataPacketID;
+
+    /**
+     * 人防工程名称
+     */
+    private String engineeringName;
+
+    /**
+     * 人防工程ID
+     */
+    private Long engineeringID;
+
+    /**
+     * 人防工程其他系统编号1
+     */
+    private String otherCode1;
+
+    /**
+     * 人防工程其他系统编号2
+     */
+    private String otherCode2;
+
+    /**
+     * 人防工程其他系统编号3
+     */
+    private String otherCode3;
+
+    /**
+     * 人防工程地址
+     */
+    private String engineeringAddr;
+
+    /**
+     * 人防工程建设单位
+     */
+    private String constructionCompany;
+
+    /**
+     * 人防工程管理单位
+     */
+    private String managerCompany;
+
+    /**
+     * 上报时间
+     */
+    private String publishTime;
+}
+

+ 42 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/ErrorMsgVO.java

@@ -0,0 +1,42 @@
+package com.usky.cdi.service.vo.base;
+
+import lombok.Data;
+import java.io.Serializable;
+
+/**
+ * 数据错误信息VO
+ * Topic: errorMsg/{engineeringId}
+ * 
+ * @author han
+ * @date 2025/03/20
+ */
+@Data
+public class ErrorMsgVO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 错误数据包ID
+     */
+    private Long dataPacketID;
+
+    /**
+     * 人防工程ID
+     */
+    private Long engineeringID;
+
+    /**
+     * 数据错误代码
+     */
+    private String errorCode;
+
+    /**
+     * 数据错误描述
+     */
+    private String errorDesc;
+
+    /**
+     * 市适配平台处理时间
+     */
+    private String processTime;
+}
+

+ 161 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/FacilityDeviceVO.java

@@ -0,0 +1,161 @@
+package com.usky.cdi.service.vo.base;
+
+import lombok.Data;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 楼层平面图信息VO
+ * Topic: base/floorPlane
+ * 
+ * @author han
+ * @date 2025/03/20
+ */
+@Data
+public class FacilityDeviceVO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private Integer id;
+
+    /**
+     * 设施编号
+     */
+    private String facilityNum;
+
+    /**
+     * 设施名称
+     */
+    private String facilityName;
+
+    /**
+     * 设施类型
+     */
+    private String facilityType;
+
+    /**
+     * 所属楼层
+     */
+    private String floor;
+
+    /**
+     * 安装位置
+     */
+    private String address;
+
+    /**
+     * 图⽚地址URL
+     */
+    private String imagesUrl;
+
+    /**
+     * 设备ID
+     */
+    private String deviceId;
+
+    /**
+     * 联系人
+     */
+    private String contact;
+
+    /**
+     * 联系方式
+     */
+    private String contactPhone;
+
+    /**
+     * 平面X轴坐标
+     */
+    private String planeX;
+
+    /**
+     * 平面Y轴坐标
+     */
+    private String planeY;
+
+    private String coordinateX;
+
+    private String coordinateY;
+
+    private String coordinateZ;
+
+    /**
+     * 删除标识
+     */
+    private Integer deleteFlag;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 更新人
+     */
+    private String updateBy;
+
+    /**
+     * 创建人
+     */
+    private String createBy;
+
+    /**
+     * 组织结构ID
+     */
+    private Integer deptId;
+
+    /**
+     * 租户ID
+     */
+    private Integer tenantId;
+
+    /**
+     * 建筑设施备注
+     */
+    private String facilityDesc;
+
+    /**
+     * 三维角度X
+     */
+    private Double anglesX;
+
+    /**
+     * 三维角度y
+     */
+    private Double anglesY;
+
+    /**
+     * 三维角度z
+     */
+    private Double anglesZ;
+
+    /**
+     * 三维图标大小
+     */
+    private Double scaleL;
+
+    /**
+     * 三维图标大小
+     */
+    private Double scaleW;
+
+    /**
+     * 三维图标大小
+     */
+    private Double scaleH;
+
+    /**
+     * 设备类型
+     */
+    private Integer deviceType;
+
+    /**
+     * 设备UUID
+     */
+    private String deviceUuid;
+}
+

+ 67 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/FloorPlaneVO.java

@@ -0,0 +1,67 @@
+package com.usky.cdi.service.vo.base;
+
+import lombok.Data;
+import java.io.Serializable;
+
+/**
+ * 楼层平面图信息VO
+ * Topic: base/floorPlane
+ * 
+ * @author han
+ * @date 2025/03/20
+ */
+@Data
+public class FloorPlaneVO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 数据包ID
+     */
+    private Long dataPacketID;
+
+    /**
+     * 人防工程ID
+     */
+    private Long engineeringID;
+
+    /**
+     * 楼层
+     */
+    private String floor;
+
+    /**
+     * 楼层平面图文件ID
+     */
+    private Long floorFileID;
+
+    /**
+     * 楼层平面图文件中文名称
+     */
+    private String floorFileName;
+
+    /**
+     * 楼层平面图文件后缀
+     */
+    private String floorFileSuffix;
+
+    /**
+     * 楼层平面图图片像素宽度
+     */
+    private Integer filePixWidth;
+
+    /**
+     * 楼层平面图图片像素高度
+     */
+    private Integer filePixHeight;
+
+    /**
+     * 平面图文件(二进制字节数组)
+     */
+    private byte[] floorFile;
+
+    /**
+     * 上报时间
+     */
+    private String publishTime;
+}
+

+ 51 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/HumidityVO.java

@@ -0,0 +1,51 @@
+package com.usky.cdi.service.vo.base;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 空气湿度推送VO(兼容2021版)
+ * MQTT Topic:iotInfo/rh
+ * 说明:Float(2,2) → 0.00 ~ 100.00%
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/11/20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class HumidityVO extends BaseEnvMonitorPushVO {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 湿度(必填)
+     * 类型:Float(2,2),单位:%
+     */
+    private Float sensorValue;
+
+    @Override
+    public Number getSensorValue() {
+        return sensorValue;
+    }
+
+    @Override
+    protected void validateSensorValue() {
+        if (sensorValue == null) throw new IllegalArgumentException("湿度(sensorValue)为必填项");
+
+        // 校验范围:0.00 ~ 100.00%(湿度不可能为负或超过100%)
+        if (sensorValue < 0.00f || sensorValue > 100.00f) {
+            throw new IllegalArgumentException("湿度值超出范围(0.00 ~ 100.00%),当前值:" + sensorValue);
+        }
+
+        // 校验小数位:最多2位
+        if (getDecimalDigits(sensorValue) > 2) {
+            throw new IllegalArgumentException("湿度值小数位不能超过2位,当前值:" + sensorValue);
+        }
+    }
+
+    private int getDecimalDigits(float value) {
+        String str = String.valueOf(value);
+        if (!str.contains(".")) return 0;
+        return str.split("\\.")[1].length();
+    }
+}

+ 51 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/OxygenVO.java

@@ -0,0 +1,51 @@
+package com.usky.cdi.service.vo.base;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 氧气浓度推送VO(兼容2021版)
+ * MQTT Topic:iotInfo/o2
+ * 说明:Float(2,2) → 0.00 ~ 100.00%
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/11/20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class OxygenVO extends BaseEnvMonitorPushVO {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 1小时平均浓度(必填)
+     * 类型:Float(2,2),单位:%
+     */
+    private Float sensorValue;
+
+    @Override
+    public Number getSensorValue() {
+        return sensorValue;
+    }
+
+    @Override
+    protected void validateSensorValue() {
+        if (sensorValue == null) throw new IllegalArgumentException("氧气浓度(sensorValue)为必填项");
+
+        // 校验范围:0.00 ~ 100.00%(浓度不可能为负或超过100%)
+        if (sensorValue < 0.00f || sensorValue > 100.00f) {
+            throw new IllegalArgumentException("氧气浓度超出范围(0.00 ~ 100.00%),当前值:" + sensorValue);
+        }
+
+        // 校验小数位:最多2位
+        if (getDecimalDigits(sensorValue) > 2) {
+            throw new IllegalArgumentException("氧气浓度小数位不能超过2位,当前值:" + sensorValue);
+        }
+    }
+
+    private int getDecimalDigits(float value) {
+        String str = String.valueOf(value);
+        if (!str.contains(".")) return 0;
+        return str.split("\\.")[1].length();
+    }
+}

+ 60 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/PersonPresenceVO.java

@@ -0,0 +1,60 @@
+package com.usky.cdi.service.vo.base;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+/**
+ * 人员闯入情况推送VO(兼容2021版)
+ * 用途:每半小时上报最新人员闯入状态,设防时段闯入需同步作为告警事件上传
+ * MQTT Topic:iotInfo/personPresence
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/11/20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class PersonPresenceVO extends BaseEnvMonitorPushVO {
+
+    private static final long serialVersionUID = 1L;
+
+    // ====================== 人员闯入状态专属枚举(对应附录表19)======================
+    public static final class SensorValueEnum {
+        public static final int NO_INTRUSION = 0; // 无人员闯入
+        public static final int INTRUSION = 1;    // 有人员闯入
+
+        /**
+         * 校验状态编码合法性
+         */
+        public static boolean isValid(int value) {
+            return value == NO_INTRUSION || value == INTRUSION;
+        }
+    }
+
+    // ====================== 专属字段(父类已包含公共字段)======================
+    /**
+     * 人员闯入状态(必填)
+     * 类型:Int,长度1(取值参考 SensorValueEnum)
+     */
+    private Integer sensorValue;
+
+    // ====================== 实现父类抽象方法 ======================
+    @Override
+    public Number getSensorValue() {
+        return sensorValue;
+    }
+
+    @Override
+    protected void validateSensorValue() {
+        // 1. 非空校验
+        if (sensorValue == null) {
+            throw new IllegalArgumentException("人员闯入状态(sensorValue)为必填项");
+        }
+
+        // 2. 状态合法性校验
+        if (!SensorValueEnum.isValid(sensorValue)) {
+            throw new IllegalArgumentException("人员闯入状态(sensorValue)无效,允许值:0(无闯入)、1(有闯入)");
+        }
+    }
+}

+ 68 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/ProtectiveUnitVO.java

@@ -0,0 +1,68 @@
+package com.usky.cdi.service.vo.base;
+
+import lombok.Data;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 防护单元基础信息VO
+ * Topic: base/protectiveUnit
+ * 
+ * @author han
+ * @date 2025/03/20
+ */
+@Data
+public class ProtectiveUnitVO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 数据包ID
+     */
+    private Long dataPacketID;
+
+    /**
+     * 人防工程ID
+     */
+    private Long engineeringID;
+
+    /**
+     * 楼层
+     */
+    private String floor;
+
+    /**
+     * 防护单元
+     */
+    private String unitName;
+
+    /**
+     * 面积
+     */
+    private BigDecimal unitArea;
+
+    /**
+     * 防护单元用途
+     */
+    private String unitUsage;
+
+    /**
+     * 掩蔽人数上限
+     */
+    private Integer peopleNumber;
+
+    /**
+     * 主要出入口名称
+     */
+    private String unitmainexit;
+
+    /**
+     * 次要出入口名称
+     */
+    private String unitotherexit;
+
+    /**
+     * 上报时间
+     */
+    private String publishTime;
+}
+

+ 87 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/SensorInfoVO.java

@@ -0,0 +1,87 @@
+package com.usky.cdi.service.vo.base;
+
+import lombok.Data;
+import java.io.Serializable;
+
+/**
+ * 智能监管物联设施信息VO
+ * Topic: base/sensorInfo
+ * 
+ * @author han
+ * @date 2025/03/20
+ */
+@Data
+public class SensorInfoVO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 数据包ID
+     */
+    private Long dataPacketID;
+
+    /**
+     * 人防工程ID
+     */
+    private Long engineeringID;
+
+    /**
+     * 物联设施ID
+     */
+    private Integer sensorID;
+
+    /**
+     * 物联设施编号
+     */
+    private String sensorNo;
+
+    /**
+     * 设施类型
+     */
+    private Integer sensorType;
+
+    /**
+     * 所在楼层
+     */
+    private String floor;
+
+    /**
+     * 所在防护单元
+     */
+    private String unitName;
+
+    /**
+     * 监测对象编号
+     */
+    private String monitorObjNo;
+
+    /**
+     * 监测对象描述
+     */
+    private String monitorObj;
+
+    /**
+     * 设施位置描述
+     */
+    private String location;
+
+    /**
+     * 楼层平面图文件ID
+     */
+    private Long floorFileID;
+
+    /**
+     * 上报时间
+     */
+    private String publishTime;
+
+    /**
+     * 设施在平面图的X轴坐标
+     */
+    private Long x;
+
+    /**
+     * 设施在平面图的Y轴坐标
+     */
+    private Long y;
+}
+

+ 54 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/TempVO.java

@@ -0,0 +1,54 @@
+package com.usky.cdi.service.vo.base;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 空气温度推送VO(兼容2021版)
+ * MQTT Topic:iotInfo/temp
+ * 说明:Float(2,2) → 总长度2位,小数位2位(如 18.50℃,范围:-99.99 ~ 99.99)
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/11/20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class TempVO extends BaseEnvMonitorPushVO {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 温度(必填)
+     * 类型:Float(2,2),单位:℃
+     */
+    private Float sensorValue;
+
+    @Override
+    public Number getSensorValue() {
+        return sensorValue;
+    }
+
+    @Override
+    protected void validateSensorValue() {
+        if (sensorValue == null) throw new IllegalArgumentException("温度(sensorValue)为必填项");
+
+        // 校验范围:-99.99 ~ 99.99(符合Float(2,2)长度约束)
+        if (sensorValue < -99.99f || sensorValue > 99.99f) {
+            throw new IllegalArgumentException("温度值超出范围(-99.99 ~ 99.99℃),当前值:" + sensorValue);
+        }
+
+        // 校验小数位:最多2位
+        if (getDecimalDigits(sensorValue) > 2) {
+            throw new IllegalArgumentException("温度值小数位不能超过2位,当前值:" + sensorValue);
+        }
+    }
+
+    /**
+     * 辅助方法:获取小数位数
+     */
+    private int getDecimalDigits(float value) {
+        String str = String.valueOf(value);
+        if (!str.contains(".")) return 0;
+        return str.split("\\.")[1].length();
+    }
+}

+ 68 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/WaterLeakVO.java

@@ -0,0 +1,68 @@
+package com.usky.cdi.service.vo.base;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+/**
+ * 水浸状态定时上报 VO(兼容2021版)
+ * 用途:每半小时上报传感器最新水浸状态
+ * MQTT Topic:iotInfo/flooded
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/11/20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class WaterLeakVO extends BaseEnvMonitorPushVO {
+
+    private static final long serialVersionUID = 1L;
+
+    // ====================== 水浸状态专属枚举(保留个性化定义)======================
+
+    /**
+     * 水浸状态定义(对应附录表12)
+     */
+    public static final class SensorValueEnum {
+        public static final int NO_WATER = 0; // 无水
+        public static final int HAS_WATER = 1; // 有水
+
+        /**
+         * 校验状态编码合法性
+         */
+        public static boolean isValid(int value) {
+            return value == NO_WATER || value == HAS_WATER;
+        }
+    }
+
+    // ====================== 水浸状态专属字段(仅保留个性化字段)======================
+    /**
+     * 最新水浸状态(必填)
+     * 类型:Int,长度1(取值参考 SensorValueEnum)
+     * 说明:0=无水,1=有水
+     */
+    private Integer sensorValue;
+
+    // ====================== 实现父类抽象方法(个性化逻辑)======================
+    @Override
+    public Number getSensorValue() {
+        return sensorValue;
+    }
+
+    /**
+     * 个性化校验:仅校验水浸状态的合法性(公共字段校验由父类完成)
+     */
+    @Override
+    protected void validateSensorValue() {
+        // 1. 校验水浸状态非空
+        if (sensorValue == null) {
+            throw new IllegalArgumentException("最新水浸状态(sensorValue)为必填项");
+        }
+
+        // 2. 校验水浸状态编码合法性(对应附录表12)
+        if (!SensorValueEnum.isValid(sensorValue)) {
+            throw new IllegalArgumentException("最新水浸状态(sensorValue)无效,允许值:0(无水)、1(有水)");
+        }
+    }
+}

+ 3 - 3
service-cockpit/service-cockpit-biz/src/main/resources/bootstrap.yml → service-cdi/service-cdi-biz/src/main/resources/bootstrap.yml

@@ -1,12 +1,12 @@
 # Tomcat
 server:
-  port: 8083
+  port: 9901
 
 # Spring
-spring:
+spring: 
   application:
     # 应用名称
-    name: service-cockpit
+    name: service-cdi
   profiles:
     # 环境配置
     active: dev

+ 108 - 0
service-cdi/service-cdi-biz/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;
+

+ 94 - 0
service-cdi/service-cdi-biz/src/main/resources/logback.xml

@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="60 seconds" debug="false">
+    <!-- 日志存放路径 -->
+    <property name="log.path" value="/var/log/uskycloud/service-cdi" />
+    <!-- 日志输出格式 -->
+    <property name="log.pattern" value="%d{MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{26}:%line: %msg%n" />
+    <!--    	<property name="log.pattern" value="%gray(%d{MM-dd HH:mm:ss.SSS}) %highlight(%-5level) &#45;&#45; [%gray(%thread)] %cyan(%logger{26}:%line): %msg%n" />-->
+
+
+    <property name="SQL_PACKAGE" value="com.usky.cdi.mapper"/>
+
+    <!-- 控制台输出 -->
+    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="file_sql" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${log.path}/sql.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+            <fileNamePattern>${log.path}/sql.%d{yyyy-MM-dd}.log</fileNamePattern>
+            <!-- 日志最大的历史 60天 -->
+            <maxHistory>3</maxHistory>
+        </rollingPolicy>
+        <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>3</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" />-->
+
+    <logger name="${SQL_PACKAGE}" additivity="false" level="debug">
+        <appender-ref ref="console"/>
+        <appender-ref ref="file_sql"/>
+    </logger>
+
+    <!--系统操作日志-->
+    <root level="info">
+        <appender-ref ref="file_info" />
+        <appender-ref ref="file_error" />
+        <appender-ref ref="console" />
+    </root>
+</configuration>

+ 38 - 0
service-cdi/service-cdi-biz/src/main/resources/mapper/cdi/BaseBuildFacilityMapper.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.usky.cdi.mapper.BaseBuildFacilityMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.cdi.domain.BaseBuildFacility">
+        <id column="id" property="id" />
+        <result column="facility_num" property="facilityNum" />
+        <result column="facility_name" property="facilityName" />
+        <result column="facility_type" property="facilityType" />
+        <result column="floor" property="floor" />
+        <result column="address" property="address" />
+        <result column="images_url" property="imagesUrl" />
+        <result column="device_id" property="deviceId" />
+        <result column="contact" property="contact" />
+        <result column="contact_phone" property="contactPhone" />
+        <result column="plane_x" property="planeX" />
+        <result column="plane_y" property="planeY" />
+        <result column="coordinate_x" property="coordinateX" />
+        <result column="coordinate_y" property="coordinateY" />
+        <result column="coordinate_z" property="coordinateZ" />
+        <result column="delete_flag" property="deleteFlag" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+        <result column="update_by" property="updateBy" />
+        <result column="create_by" property="createBy" />
+        <result column="dept_id" property="deptId" />
+        <result column="tenant_id" property="tenantId" />
+        <result column="facility_desc" property="facilityDesc" />
+        <result column="angles_x" property="anglesX" />
+        <result column="angles_y" property="anglesY" />
+        <result column="angles_z" property="anglesZ" />
+        <result column="scale_l" property="scaleL" />
+        <result column="scale_w" property="scaleW" />
+        <result column="scale_h" property="scaleH" />
+    </resultMap>
+
+</mapper>

+ 30 - 0
service-cdi/service-cdi-biz/src/main/resources/mapper/cdi/DmpDeviceMapper.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.usky.cdi.mapper.DmpDeviceMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.cdi.domain.DmpDevice">
+        <id column="id" property="id" />
+        <result column="device_id" property="deviceId" />
+        <result column="device_name" property="deviceName" />
+        <result column="device_type" property="deviceType" />
+        <result column="product_id" property="productId" />
+        <result column="sim_code" property="simCode" />
+        <result column="imsi_code" property="imsiCode" />
+        <result column="subscribe_flag" property="subscribeFlag" />
+        <result column="node_type" property="nodeType" />
+        <result column="group_id" property="groupId" />
+        <result column="delete_flag" property="deleteFlag" />
+        <result column="created_by" property="createdBy" />
+        <result column="created_time" property="createdTime" />
+        <result column="updated_by" property="updatedBy" />
+        <result column="updated_time" property="updatedTime" />
+        <result column="tenant_id" property="tenantId" />
+        <result column="company_code" property="companyCode" />
+        <result column="install_address" property="installAddress" />
+        <result column="service_status" property="serviceStatus" />
+        <result column="product_code" property="productCode" />
+        <result column="device_uuid" property="deviceUuid" />
+    </resultMap>
+
+</mapper>

+ 32 - 0
service-cdi/service-cdi-biz/src/main/resources/mapper/cdi/DmpProductMapper.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.usky.cdi.mapper.DmpProductMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.cdi.domain.DmpProduct">
+        <id column="id" property="id" />
+        <result column="product_name" property="productName" />
+        <result column="access_mode" property="accessMode" />
+        <result column="network_type" property="networkType" />
+        <result column="device_type" property="deviceType" />
+        <result column="com_protocol" property="comProtocol" />
+        <result column="auth_mode" property="authMode" />
+        <result column="device_model" property="deviceModel" />
+        <result column="product_describe" property="productDescribe" />
+        <result column="factory_name" property="factoryName" />
+        <result column="factory_person" property="factoryPerson" />
+        <result column="factory_phone" property="factoryPhone" />
+        <result column="certificate_url1" property="certificateUrl1" />
+        <result column="certificate_url2" property="certificateUrl2" />
+        <result column="certificate_url3" property="certificateUrl3" />
+        <result column="agreement_url" property="agreementUrl" />
+        <result column="delete_flag" property="deleteFlag" />
+        <result column="created_by" property="createdBy" />
+        <result column="created_time" property="createdTime" />
+        <result column="updated_by" property="updatedBy" />
+        <result column="updated_time" property="updatedTime" />
+        <result column="tenant_id" property="tenantId" />
+        <result column="product_code" property="productCode" />
+    </resultMap>
+
+</mapper>

+ 15 - 0
service-cdi/service-cdi-biz/src/main/resources/smart-doc.json

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

+ 0 - 13
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/ServletInitializer.java

@@ -1,13 +0,0 @@
-package cn.com;
-
-import org.springframework.boot.builder.SpringApplicationBuilder;
-import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
-
-public class ServletInitializer extends SpringBootServletInitializer {
-
-	@Override
-	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
-		return application.sources(GogoApplication.class);
-	}
-
-}

+ 0 - 118
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/base/BaseController.java

@@ -1,118 +0,0 @@
-package cn.com.v2.common.base;
-
-import org.springframework.web.bind.WebDataBinder;
-import org.springframework.web.bind.annotation.InitBinder;
-
-import cn.com.v2.common.domain.AjaxResult;
-
-import java.beans.PropertyEditorSupport;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-/**
- * web层通用数据处理
- * 
- * @ClassName: BaseController
- * @author fuce
- * @date 2018年8月18日
- *
- */
-
-public class BaseController {
-
-	/**
-	 * 将前台传递过来的日期格式的字符串,自动转化为Date类型
-	 */
-	@InitBinder
-	public void initBinder(WebDataBinder binder) {
-		// SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-		// dateFormat.setLenient(false);
-		binder.registerCustomEditor(Date.class, new MyDateEditor());
-	}
-
-	private class MyDateEditor extends PropertyEditorSupport {
-		@Override
-		public void setAsText(String text) throws IllegalArgumentException {
-			// 通过两次异常的处理可以,绑定两次日期的格式
-			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-			Date date = null;
-			try {
-				date = format.parse(text);
-			} catch (ParseException e) {
-				format = new SimpleDateFormat("yyyy-MM-dd");
-				try {
-					date = format.parse(text);
-				} catch (ParseException e1) {
-					format = new SimpleDateFormat("yyyy/MM/dd H:mm");
-					try {
-						date = format.parse(text);
-					} catch (ParseException e2) {
-						e2.printStackTrace();
-					}
-				}
-			}
-			setValue(date);
-		}
-	}
-
-	/**
-	 * 响应返回结果
-	 * 
-	 * @param rows 影响行数
-	 * @return 操作结果
-	 */
-	protected AjaxResult toAjax(int rows) {
-		return rows > 0 ? success() : error();
-	}
-
-	/**
-	 * 返回成功
-	 */
-	public AjaxResult success() {
-		return AjaxResult.success();
-	}
-
-	/**
-	 * 返回失败消息
-	 */
-	public AjaxResult error() {
-		return AjaxResult.error();
-	}
-
-	public AjaxResult successData(int code, Object value) {
-		AjaxResult json = new AjaxResult();
-		json.put("code", code);
-		json.put("data", value);
-		return json;
-	}
-
-	/**
-	 * 返回成功消息
-	 */
-	public AjaxResult success(String message) {
-		return AjaxResult.success(message);
-	}
-
-	/**
-	 * 返回失败消息
-	 */
-	public AjaxResult error(String message) {
-		return AjaxResult.error(message);
-	}
-
-	/**
-	 * 返回错误码消息
-	 */
-	public AjaxResult error(int code, String message) {
-		return AjaxResult.error(code, message);
-	}
-
-	/**
-	 * 返回object数据
-	 */
-	public AjaxResult retobject(int code, Object data) {
-		return AjaxResult.successData(code, data);
-	}
-
-}

+ 0 - 24
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/config/CorsConfig.java

@@ -1,24 +0,0 @@
-package cn.com.v2.common.config;
-
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.servlet.config.annotation.CorsRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-//重写WebMvcConfigurer实现全局跨域配置
-@Configuration
-public class CorsConfig implements WebMvcConfigurer{
-	@Override
-    public void addCorsMappings(CorsRegistry registry) {
-        	registry.addMapping("/**")
-            // 是否发送Cookie
-            .allowCredentials(true)
-            // 放行哪些原始域
-            .allowedOrigins("*")
-            // 放行哪些请求方式
-            .allowedMethods("GET", "POST", "PUT", "DELETE")
-            // 放行哪些原始请求头部信息
-            .allowedHeaders("*")
-            // 暴露哪些头部信息
-            .exposedHeaders("*");
-    }
-}

+ 0 - 2
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/config/DateStringConvert.java

@@ -1,2 +0,0 @@
-package com.usky.cockpit.common.config;public class DateStringConvert {
-}

+ 0 - 20
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/config/MybatisPlusConfig.java

@@ -1,20 +0,0 @@
-package cn.com.v2.common.config;
-
-import com.baomidou.mybatisplus.annotation.DbType;
-import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
-import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-public class MybatisPlusConfig {
-	 /**
-     * 新的分页插件,一缓和二缓遵循mybatis的规则,
-     */
-    @Bean
-    public MybatisPlusInterceptor mybatisPlusInterceptor() {
-        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
-        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.SQLITE));
-        return interceptor;
-    }
-}

+ 0 - 2
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/config/StringDateConverter.java

@@ -1,2 +0,0 @@
-package com.usky.cockpit.common.config;public class StringDateConverter {
-}

+ 0 - 72
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/config/V2Config.java

@@ -1,72 +0,0 @@
-package cn.com.v2.common.config;
-
-import java.util.Map;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
-
-/**
- * 读取项目相关配置
- * 
- * @author fuce
- */
-@Component
-@ConfigurationProperties(prefix = "v2")
-public class V2Config {
-
-	/**
-	 * 存储路径
-	 */
-	private String fileurl;
-	/**
-	 * 请求url
-	 */
-	private String httpurl;
-	/**
-	 * 虚拟路径map
-	 */
-	private Map<String, String> xnljmap;
-	
-	/**
-	 * 默认文件格式
-	 */
-	private String defaultFormat;
-	
-
-	public String getFileurl() {
-		return fileurl;
-	}
-
-	public void setFileurl(String fileurl) {
-		this.fileurl = fileurl;
-	}
-
-	
-
-	
-
-	public String getHttpurl() {
-		return httpurl;
-	}
-
-	public void setHttpurl(String httpurl) {
-		this.httpurl = httpurl;
-	}
-
-	public Map<String, String> getXnljmap() {
-		return xnljmap;
-	}
-
-	public void setXnljmap(Map<String, String> xnljmap) {
-		this.xnljmap = xnljmap;
-	}
-
-	public String getDefaultFormat() {
-		return defaultFormat;
-	}
-
-	public void setDefaultFormat(String defaultFormat) {
-		this.defaultFormat = defaultFormat;
-	}
-	
-	
-}

+ 0 - 104
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/domain/AjaxResult.java

@@ -1,104 +0,0 @@
-package cn.com.v2.common.domain;
-
-import java.util.HashMap;
-
-/**
-* @ClassName: AjaxResult
-* @Description: ajax操作消息提醒
-* @author fuce
-* @date 2018年8月18日
-*
- */
-public class AjaxResult extends HashMap<String, Object>
-{
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 初始化一个新创建的 Message 对象
-     */
-    public AjaxResult()
-    {
-    }
-
-    /**
-     * 返回错误消息
-     * 
-     * @return 错误消息
-     */
-    public static AjaxResult error()
-    {
-        return error(500, "操作失败");
-    }
-
-    /**
-     * 返回错误消息
-     * 
-     * @param msg 内容
-     * @return 错误消息
-     */
-    public static AjaxResult error(String msg)
-    {
-        return error(500, msg);
-    }
-
-    /**
-     * 返回错误消息
-     * 
-     * @param code 错误码
-     * @param msg 内容
-     * @return 错误消息
-     */
-    public static AjaxResult error(int code, String msg)
-    {
-        AjaxResult json = new AjaxResult();
-        json.put("code", code);
-        json.put("msg", msg);
-        return json;
-    }
-
-    /**
-     * 返回成功消息
-     * 
-     * @param msg 内容
-     * @return 成功消息
-     */
-    public static AjaxResult success(String msg)
-    {
-        AjaxResult json = new AjaxResult();
-        json.put("msg", msg);
-        json.put("code", 200);
-        return json;
-    }
-    
-    /**
-     * 返回成功消息
-     * 
-     * @return 成功消息
-     */
-    public static AjaxResult success()
-    {
-        return AjaxResult.success("操作成功");
-    }
-    
-    public static AjaxResult successData(int code, Object value){
-    	 AjaxResult json = new AjaxResult();
-    	 json.put("code", code);
-         json.put("data", value);
-         return json;
-    }
-   
-    
-    /**
-     * 返回成功消息
-     * 
-     * @param key 键值
-     * @param value 内容
-     * @return 成功消息
-     */
-    @Override
-    public AjaxResult put(String key, Object value)
-    {
-        super.put(key, value);
-        return this;
-    }
-}

+ 0 - 84
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/domain/ResultTable.java

@@ -1,84 +0,0 @@
-package cn.com.v2.common.domain;
-
-public class ResultTable {
-     /**
-     * 状态码
-     * */
-    private Integer code;
-
-    /**
-     * 提示消息
-     * */
-    private String msg;
-
-    /**
-     * 消息总量
-     * */
-    private Long count;
-
-    /**
-     * 数据对象
-     * */
-    private Object data;
-
-    public Integer getCode() {
-        return code;
-    }
-
-    public void setCode(Integer code) {
-        this.code = code;
-    }
-
-    public String getMsg() {
-        return msg;
-    }
-
-    public void setMsg(String msg) {
-        this.msg = msg;
-    }
-
-    public Long getCount() {
-        return count;
-    }
-
-    public void setCount(Long count) {
-        this.count = count;
-    }
-
-    public Object getData() {
-        return data;
-    }
-
-    public void setData(Object data) {
-        this.data = data;
-    }
-
-    /**
-     * 构 建
-     * */
-    public static ResultTable pageTable(long count,Object data){
-        ResultTable resultTable = new ResultTable();
-        resultTable.setData(data);
-        resultTable.setCode(0);
-        resultTable.setCount(count);
-        if(data!=null) {
-       	 resultTable.setMsg("获取成功");
-       }else {
-       	 resultTable.setMsg("获取失败");
-       }
-        return resultTable;
-    }
-
-    public static ResultTable dataTable(Object data){
-        ResultTable resultTable = new ResultTable();
-        resultTable.setData(data);
-        resultTable.setCode(0);
-        if(data!=null) {
-        	 resultTable.setMsg("获取成功");
-        }else {
-        	 resultTable.setMsg("获取失败");
-        }
-       
-        return resultTable;
-    }
-}

+ 0 - 50
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/domain/Tablepar.java

@@ -1,50 +0,0 @@
-package cn.com.v2.common.domain;
-
-/**
- * boostrap table post 参数
- * @author fc
- *
- */
-public class Tablepar {
-	private int page;//页码
-	private int limit;//数量
-	private String orderByColumn;//排序字段
-	private String isAsc;//排序字符 asc desc 
-	private String searchText;//列表table里面的搜索
-
-	public int getPage() {
-		return page;
-	}
-
-	public void setPage(int page) {
-		this.page = page;
-	}
-
-	public int getLimit() {
-		return limit;
-	}
-
-	public void setLimit(int limit) {
-		this.limit = limit;
-	}
-
-	public String getOrderByColumn() {
-		return orderByColumn;
-	}
-	public void setOrderByColumn(String orderByColumn) {
-		this.orderByColumn = orderByColumn;
-	}
-	public String getIsAsc() {
-		return isAsc;
-	}
-	public void setIsAsc(String isAsc) {
-		this.isAsc = isAsc;
-	}
-	public String getSearchText() {
-		return searchText;
-	}
-	public void setSearchText(String searchText) {
-		this.searchText = searchText;
-	}
-
-}

+ 0 - 21
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/interceptor/Interceptor.java

@@ -1,21 +0,0 @@
-package cn.com.v2.common.interceptor;
-
-import org.springframework.web.servlet.HandlerInterceptor;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * 拦截器
- */
-public class Interceptor implements HandlerInterceptor {
-    /**
-     * 在请求处理之前进行调用(Controller方法调用之前)
-     */
-	@Override
-    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
-       
-        return true;//如果设置为false时,被请求时,拦截器执行到此处将不会继续操作
-        //如果设置为true时,请求将会继续执行后面的操作
-    }
-
-}

+ 0 - 91
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/common/interceptor/WebMvcConfig.java

@@ -1,91 +0,0 @@
-package cn.com.v2.common.interceptor;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.servlet.config.annotation.CorsRegistry;
-import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
-import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
-import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
-
-import cn.com.v2.common.config.V2Config;
-import cn.hutool.core.util.ArrayUtil;
-
-@Configuration
-public class WebMvcConfig extends WebMvcConfigurationSupport {
- 
-	@Autowired
-	private V2Config v2Config;
-    @Override
-    public void addResourceHandlers(ResourceHandlerRegistry registry) {
-        registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
-        registry.addResourceHandler("error.html").addResourceLocations("classpath:/META-INF/resources/static/error.html");
-        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
-        
-        List<String> list1=new ArrayList<String>();
-        List<String> list2=new ArrayList<String>();
-        
-        Map<String, String> map= v2Config.getXnljmap();
-        
-        Set<String> set = map.keySet();
-        for (String o : set) {
-            list1.add("/"+o+"/**");
-            list2.add(map.get(o));
-        }
-    	registry.addResourceHandler(ArrayUtil.toArray(list1, String.class)).addResourceLocations(ArrayUtil.toArray(list2, String.class));
-    }
-    
-
-    /**
-     * 重写addCorsMappings()解决跨域问题
-     * 配置:允许http请求进行跨域访问
-     *
-     * @param registry
-     */
-    @Override
-    public void addCorsMappings(CorsRegistry registry) {
-    	
-    	// 设置允许多个域名请求
-        //String[] allowDomains = {"http://www.toheart.xin","http://192.168.11.213:8080","http://localhost:8080"};
-    	
-        //指哪些接口URL需要增加跨域设置
-        registry.addMapping("/**")
-                //.allowedOrigins("*")//指的是前端哪些域名被允许跨域
-                .allowedOriginPatterns("*")
-                //需要带cookie等凭证时,设置为true,就会把cookie的相关信息带上
-                .allowCredentials(true)
-                //指的是允许哪些方法
-                .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
-                //cookie的失效时间,单位为秒(s),若设置为-1,则关闭浏览器就失效
-                .maxAge(3600);
-    }
-    
-    /**
-     * 重写addInterceptors()实现拦截器
-     * 配置:要拦截的路径以及不拦截的路径
-     *
-     * @param registry
-     */
-    @Override
-    public void addInterceptors(InterceptorRegistry registry) {
-        //注册Interceptor拦截器(Interceptor这个类是我们自己写的拦截器类)
-        InterceptorRegistration registration = registry.addInterceptor(new Interceptor());
-        //addPathPatterns()方法添加需要拦截的路径
-        //所有路径都被拦截
-        registration.addPathPatterns("/**");
-        //excludePathPatterns()方法添加不拦截的路径
-        
-        
-        String[] excludePatterns = new String[]{"/error","/error.html","/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**",
-                "/api", "/api-docs", "/api-docs/**", "/doc.html/**",
-                "/api/file/*"};
-        
-        //添加不拦截路径
-        registration.excludePathPatterns(excludePatterns);
-    }
- 
-}

+ 0 - 87
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/controller/web/ApiController.java

@@ -1,87 +0,0 @@
-package cn.com.v2.controller;
-
-import java.util.HashMap;
-import java.util.Map;
-import javax.servlet.http.HttpServletRequest;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.ResponseBody;
-import org.springframework.web.bind.annotation.RestController;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-
-import cn.com.v2.common.base.BaseController;
-import cn.com.v2.common.domain.AjaxResult;
-import cn.com.v2.model.SysUser;
-import cn.com.v2.service.ISysUserService;
-import cn.com.v2.util.SaTokenUtil;
-import cn.dev33.satoken.stp.StpUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.crypto.SecureUtil;
-import io.swagger.annotations.ApiOperation;
-
-@RestController
-@RequestMapping("/api/goview/sys")
-public class ApiController  extends BaseController {
-	@Autowired
-	private ISysUserService iSysUserService;
-
-	@ApiOperation(value = "登陆", notes = "登陆")
-	@PostMapping("/login")
-	@ResponseBody
-	public AjaxResult APIlogin(@RequestBody SysUser user, HttpServletRequest request) {
-
-		// 判断是否登陆
-		if (StpUtil.isLogin()) {
-
-			Map<String, Object> map = new HashMap<String, Object>();
-			map.put("userinfo", SaTokenUtil.getUser());
-			map.put("token", StpUtil.getTokenInfo());
-			return success().put("data", map);
-		} else {
-			if (StrUtil.isNotBlank(user.getUsername()) && StrUtil.isNotBlank(user.getPassword())) {
-				SysUser sysUser = iSysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, user.getUsername()).eq(SysUser::getPassword, SecureUtil.md5(user.getPassword())).last("LIMIT 1"));
-				if (sysUser != null) {
-					StpUtil.login(sysUser.getId());
-					SaTokenUtil.setUser(sysUser);
-					Map<String, Object> map = new HashMap<String, Object>();
-					map.put("userinfo", sysUser);
-					map.put("token", StpUtil.getTokenInfo());
-
-					return success().put("data", map);
-				} else {
-					return error(500, "账户或者密码错误");
-				}
-			} else {
-				return error(500, "账户密码不能为空");
-			}
-		}
-
-	}
-	
-	
-	@ApiOperation(value = "登陆", notes = "登陆")
-	@GetMapping("/logout")
-	@ResponseBody
-	public AjaxResult logout() {
-
-		// 判断是否登陆
-		StpUtil.logout();
-
-		return success();
-
-	}
-	
-	
-	@ApiOperation(value = "获取oss地址", notes = "获取oss地址")
-	@GetMapping("/getOssInfo")
-	@ResponseBody
-	public AjaxResult getOssInfo() {
-
-		return success();
-
-	}
-
-}

+ 0 - 376
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/controller/web/FileController.java

@@ -1,376 +0,0 @@
-package cn.com.v2.controller;
-
-import java.io.File;
-import java.io.IOException;
-import java.math.BigInteger;
-import java.security.MessageDigest;
-import java.time.LocalDateTime;
-import java.util.Date;
-import java.util.Map;
-import java.util.Map.Entry;
-import javax.servlet.http.HttpServletResponse;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import lombok.extern.slf4j.Slf4j;
-import cn.com.v2.common.base.BaseController;
-import cn.com.v2.common.config.V2Config;
-import cn.com.v2.common.domain.AjaxResult;
-import cn.com.v2.model.SysFile;
-import cn.com.v2.model.vo.SysFileVo;
-import cn.com.v2.service.ISysFileService;
-import cn.com.v2.util.SnowflakeIdWorker;
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.codec.Base64;
-import cn.hutool.core.date.DateUtil;
-import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.io.IORuntimeException;
-import cn.hutool.core.util.StrUtil;
-
-/**
- * 文件上传controller
- * @author fuce 
- * @date: 2018年9月16日 下午4:23:50
- */
-@Api(value = "文件上传")
-@RestController
-@RequestMapping("/api/file")
-@Slf4j
-public class FileController extends BaseController{
-
-
-	@Autowired
-	private V2Config v2Config;
-	@Autowired
-	private ISysFileService iSysFileService;
-
-	/**
-	 * 删除文件
-	 * @param ids
-	 * @return
-	 */
-	@ApiOperation(value = "删除", notes = "删除")
-	@DeleteMapping("/remove")
-	public AjaxResult remove(String ids){
-		Boolean b=iSysFileService.removeByIds(StrUtil.split(ids, ',',-1));
-		if(b){
-			return success();
-		}else{
-			return error();
-		}
-	}
-	
-	
-	@ApiOperation(value = "修改", notes = "修改")
-	@PutMapping("/update")
-	public AjaxResult update(String id,@RequestBody MultipartFile object) throws IllegalStateException, IOException{
-		SysFile sysFile=iSysFileService.getById(id);
-		if(sysFile!=null){
-			String fileurl=sysFile.getAbsolutePath()+sysFile.getRelativePath()+File.separator+sysFile.getFileName();
-			object.transferTo(new File(fileurl));
-			return success("修改成功");
-		}else{
-			return error();
-		}
-	}
-
-	/**
-	 * 上传文件
-	 * @param object 文件流对象
-	 * @param bucketName 桶名
-	 * @return
-	 * @throws Exception
-	 */
-	@PostMapping("/upload")
-	public AjaxResult upload(@RequestBody MultipartFile object) throws IOException{
-		String fileName = object.getOriginalFilename();
-		//默认文件格式
-		String suffixName=v2Config.getDefaultFormat();
-		String mediaKey="";
-		Long filesize= object.getSize();
-		//文件名字
-		String fileSuffixName="";
-		if(fileName.lastIndexOf(".")!=-1) {//有后缀
-			 suffixName = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
-			 //mediaKey=MD5.create().digestHex(fileName);
-			 mediaKey=SnowflakeIdWorker.getUUID();
-			 fileSuffixName=mediaKey+suffixName;
-		}else {//无后缀
-			//取得唯一id
-			 //mediaKey = MD5.create().digestHex(fileName+suffixName);
-			mediaKey=SnowflakeIdWorker.getUUID();
-			//fileSuffixName=mediaKey+suffixName;
-		}
-		String virtualKey=getFirstNotNull(v2Config.getXnljmap());
-		String absolutePath=v2Config.getXnljmap().get(getFirstNotNull(v2Config.getXnljmap()));
-		SysFile sysFile=new SysFile();
-		sysFile.setId(SnowflakeIdWorker.getUUID());
-		sysFile.setFileName(fileSuffixName);
-		sysFile.setFileSize(Integer.parseInt(filesize+""));
-		sysFile.setFileSuffix(suffixName);
-		sysFile.setCreateTime(DateUtil.formatLocalDateTime(LocalDateTime.now()));
-		String filepath=DateUtil.formatDate(new Date());
-		sysFile.setRelativePath(filepath);
-		sysFile.setVirtualKey(virtualKey);
-		sysFile.setAbsolutePath(absolutePath.replace("file:",""));
-		iSysFileService.saveOrUpdate(sysFile);
-		File desc = getAbsoluteFile(v2Config.getFileurl()+File.separator+filepath,fileSuffixName);
-		object.transferTo(desc);
-		SysFileVo sysFileVo=BeanUtil.copyProperties(sysFile, SysFileVo.class);
-		sysFileVo.setFileurl(v2Config.getHttpurl()+sysFile.getVirtualKey()+"/"+sysFile.getRelativePath()+"/"+sysFile.getFileName());
-		return AjaxResult.successData(200, sysFileVo);
-	}
-	
-	
-	/**
-	 * Base64字符串转成图片
-	 * @param str
-	 * @throws IOException 
-	 */
-	@PostMapping("/uploadbase64")
-	public synchronized AjaxResult uploadbase64(String base64str) throws IOException{
-		if(StrUtil.isNotBlank(base64str)){
-			String suffixName=v2Config.getDefaultFormat();
-			String mediaKey=SnowflakeIdWorker.getUUID();
-			String fileSuffixName=mediaKey+suffixName;
-			String virtualKey=getFirstNotNull(v2Config.getXnljmap());
-			String absolutePath=v2Config.getXnljmap().get(getFirstNotNull(v2Config.getXnljmap()));
-			SysFile sysFile=new SysFile();
-			sysFile.setId(SnowflakeIdWorker.getUUID());
-			sysFile.setFileName(fileSuffixName);
-			sysFile.setFileSuffix(suffixName);
-			sysFile.setCreateTime(DateUtil.formatLocalDateTime(LocalDateTime.now()));
-			String filepath=DateUtil.formatDate(new Date());
-			sysFile.setRelativePath(filepath);
-			sysFile.setVirtualKey(virtualKey);
-			sysFile.setAbsolutePath(absolutePath.replace("file:",""));
-			File desc = getAbsoluteFile(v2Config.getFileurl()+File.separator+filepath,fileSuffixName);
-			File file=null;
-			try {
-				 file=Base64.decodeToFile(base64str, desc);
-			} catch (Exception e) {
-				System.out.println("错误base64:"+base64str);
-				e.printStackTrace();
-			}
-			sysFile.setFileSize(Integer.parseInt(file.length()+""));
-			iSysFileService.saveOrUpdate(sysFile);
-			SysFileVo sysFileVo=BeanUtil.copyProperties(sysFile, SysFileVo.class);
-			sysFileVo.setFileurl(v2Config.getHttpurl()+sysFile.getVirtualKey()+"/"+sysFile.getRelativePath()+"/"+sysFile.getFileName());
-			return AjaxResult.successData(200, sysFileVo);
-		}
-		return AjaxResult.error();
-		
-	}
-	
-	
-	/**
-	 * 定制方法
-	 * 根据关键字与相对路径获取文件内容 
-	 * @param key 访问关键字
-	 * @param rpf 相对路径+文件名字
-	 * @return
-	 */
-	@PostMapping("/getFileText")
-	public AjaxResult getFileText(String key,String relativePath){
-		String absolutePath= v2Config.getXnljmap().get(key).replace("file:", "");
-		String fileurl=absolutePath+relativePath;
-		try {
-			String text=FileUtil.readUtf8String(fileurl);
-			return AjaxResult.successData(200, text);
-		}catch (IORuntimeException e) {
-			return AjaxResult.error("没有该文件");
-		}
-		catch (Exception e) {
-			return AjaxResult.error("报错:"+e.getMessage());
-		}
-	}
-	
-	
-	/**
-	 * 定制方法
-	 * 根据关键字与相对路径获取文件内容 
-	 * @param key 访问关键字
-	 * @param rpf 相对路径+文件名字
-	 * @return
-	 * @throws IOException 
-	 */
-	@PostMapping("/getFileText302")
-	public void getFileText302(String key,String relativePath,HttpServletResponse response) throws IOException{
-		String str=v2Config.getHttpurl()+key+"/"+relativePath;
-		response.sendRedirect(str);
-		
-	}
-	
-	
-	
-	
-	/**
-	 * 覆盖上传文件 key与指定路径
-	 * @param object 文件流对象
-	 * @param bucketName 桶名
-	 * @return
-	 * @throws Exception
-	 */
-	@PostMapping("/coverupload")
-	public AjaxResult coverupload(@RequestBody MultipartFile object,String key,String relativePath) throws IOException{
-		
-		String fileName = object.getOriginalFilename();
-		String suffixName=v2Config.getDefaultFormat();
-		Long filesize= object.getSize();
-		//文件名字
-		String fileSuffixName="";
-		if(fileName.lastIndexOf(".")!=-1) {//有后缀
-			 suffixName = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
-			 //mediaKey=MD5.create().digestHex(fileName);
-			 //mediaKey=SnowflakeIdWorker.getUUID();
-			 fileSuffixName=relativePath.substring(relativePath.lastIndexOf("/")+1,relativePath.length());
-		}else {//无后缀
-			//取得唯一id
-			 //mediaKey = MD5.create().digestHex(fileName+suffixName);
-			//mediaKey=SnowflakeIdWorker.getUUID();
-			//fileSuffixName=mediaKey+suffixName;
-		}
-		String virtualKey=key;
-		String absolutePath=v2Config.getXnljmap().get(key).replace("file:", "");
-		SysFile sysFile=new SysFile();
-		sysFile.setId(SnowflakeIdWorker.getUUID());
-		sysFile.setFileName(fileSuffixName);
-		sysFile.setFileSize(Integer.parseInt(filesize+""));
-		sysFile.setFileSuffix(suffixName);
-		sysFile.setCreateTime(DateUtil.formatLocalDateTime(LocalDateTime.now()));
-		String filepath=relativePath.substring(0,relativePath.lastIndexOf("/"));
-		sysFile.setRelativePath(filepath);
-		sysFile.setVirtualKey(virtualKey);
-		sysFile.setAbsolutePath(absolutePath);
-		iSysFileService.saveOrUpdate(sysFile);
-		File desc = getAbsoluteFile(absolutePath+filepath,fileSuffixName);
-		object.transferTo(desc);
-		SysFileVo sysFileVo=BeanUtil.copyProperties(sysFile, SysFileVo.class);
-		sysFileVo.setFileurl(v2Config.getHttpurl()+sysFile.getVirtualKey()+"/"+sysFile.getRelativePath()+"/"+sysFile.getFileName());
-		return AjaxResult.successData(200, sysFileVo);
-	}
-	
-	
-	
-
-	
-	/**
-	 * 根据文件id查询文件信息json
-	 * @param id
-	 * @return
-	 */
-	@GetMapping("/getFileid/{id}")
-	public AjaxResult getFileid(@PathVariable("id") String id){
-		SysFile sysFile=iSysFileService.getById(id);
-		if(sysFile!=null){
-			SysFileVo sysFileVo=BeanUtil.copyProperties(sysFile, SysFileVo.class);
-			sysFileVo.setFileurl(v2Config.getHttpurl()+sysFile.getVirtualKey()+"/"+sysFile.getRelativePath()+"/"+sysFile.getFileName());
-			return AjaxResult.successData(200, sysFileVo);
-		}
-		return AjaxResult.error("没有该文件");
-		
-	}
-	
-	/**
-	 * 根据文件id 302跳转到绝对地址
-	 * @param id
-	 * @param response
-	 * @throws IOException
-	 */
-	@GetMapping("/getFileid/302/{id}")
-	public void getFileid302(@PathVariable("id") String id,HttpServletResponse response) throws IOException{
-		SysFile sysFile=iSysFileService.getById(id);
-		if(sysFile!=null){
-			String str=v2Config.getHttpurl()+sysFile.getVirtualKey()+"/"+sysFile.getRelativePath()+"/"+sysFile.getFileName();
-			response.sendRedirect(str);
-		}
-	}
-	
-	
-	
-	
-	
-	
-	/**
-	 * 分页查询
-	 * @param current
-	 * @param size
-	 * @return
-	 */
-	@GetMapping("/list")
-	public Object list(long current, long size){
-		Page<SysFile> page= new Page<SysFile>(current, size);
-		IPage<SysFile> sysFile=iSysFileService.page(page, new LambdaQueryWrapper<SysFile>());
-		return sysFile;
-	}
-	
-	
-	
-	
-
-    /**
-     * 获取map中第一个非空数据key
-     *
-     * @param <K> Key的类型
-     * @param <V> Value的类型
-     * @param map 数据源
-     * @return 返回的值
-     */
-    public static <K, V> K getFirstNotNull(Map<K, V> map) {
-        K obj = null;
-        for (Entry<K, V> entry : map.entrySet()) {
-            obj =  entry.getKey();
-            if (obj != null) {
-                break;
-            }
-        }
-        return obj;
-    }
-	
-	
-    public  final static File getAbsoluteFile(String uploadDir, String filename) throws IOException
-    {
-        File desc = new File(uploadDir+File.separator + filename);
-
-        if (!desc.getParentFile().exists())
-        {
-            desc.getParentFile().mkdirs();
-        }
-        if (!desc.exists())
-        {
-            desc.createNewFile();
-        }
-        return desc;
-    }
-	
-	
-	/**
-	 * 获取上传文件的md5
-	 * @param file
-	 * @return
-	 * @throws IOException
-	 */
-	public String getMd5(MultipartFile file) {
-	    try {
-	        //获取文件的byte信息
-	        byte[] uploadBytes = file.getBytes();
-	        // 拿到一个MD5转换器
-	        MessageDigest md5 = MessageDigest.getInstance("MD5");
-	        byte[] digest = md5.digest(uploadBytes);
-	        //转换为16进制
-	        return new BigInteger(1, digest).toString(16);
-	    } catch (Exception e) {
-	        log.error(e.getMessage());
-	    }
-	    return null;
-	}
-
-
-    
-    
-}

+ 0 - 257
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/controller/web/GoviewProjectController.java

@@ -1,257 +0,0 @@
-package cn.com.v2.controller;
-
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.ResponseBody;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.multipart.MultipartFile;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import cn.com.v2.common.base.BaseController;
-import cn.com.v2.common.config.V2Config;
-import cn.com.v2.common.domain.AjaxResult;
-import cn.com.v2.common.domain.ResultTable;
-import cn.com.v2.common.domain.Tablepar;
-import cn.com.v2.model.GoviewProject;
-import cn.com.v2.model.GoviewProjectData;
-import cn.com.v2.model.SysFile;
-import cn.com.v2.model.vo.GoviewProjectVo;
-import cn.com.v2.model.vo.SysFileVo;
-import cn.com.v2.service.IGoviewProjectDataService;
-import cn.com.v2.service.IGoviewProjectService;
-import cn.com.v2.service.ISysFileService;
-import cn.com.v2.util.ConvertUtil;
-import cn.com.v2.util.SnowflakeIdWorker;
-import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.date.DateUtil;
-import io.swagger.annotations.ApiOperation;
-import java.io.File;
-import java.io.IOException;
-import java.time.LocalDateTime;
-import java.util.Date;
-import java.util.List;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.ui.ModelMap;
-
-/**
- * <p>
- *  前端控制器
- * </p>
- *
- * @author fc
- * @since 2023-04-30
- */
-@RestController
-@RequestMapping("/api/goview/project")
-public class GoviewProjectController  extends BaseController{
-	@Autowired
-	private ISysFileService iSysFileService;
-	@Autowired
-	private V2Config v2Config;
-	@Autowired
-	private IGoviewProjectService iGoviewProjectService;
-	@Autowired
-	private IGoviewProjectDataService iGoviewProjectDataService;
-	
-	
-	@ApiOperation(value = "分页跳转", notes = "分页跳转")
-	@GetMapping("/list")
-	@ResponseBody
-	public ResultTable list(Tablepar tablepar){
-		Page<GoviewProject> page= new Page<GoviewProject>(tablepar.getPage(), tablepar.getLimit());
-		IPage<GoviewProject> iPages=iGoviewProjectService.page(page, new LambdaQueryWrapper<GoviewProject>());
-		ResultTable resultTable=new ResultTable();
-		resultTable.setData(iPages.getRecords());
-		resultTable.setCode(200);
-		resultTable.setCount(iPages.getTotal());
-		resultTable.setMsg("获取成功");
-		return resultTable;
-	}
-	
-	
-	/**
-     * 新增保存
-     * @param 
-     * @return
-     */
-	//@Log(title = "项目表新增", action = "111")
-	@ApiOperation(value = "新增", notes = "新增")
-	@PostMapping("/create")
-	@ResponseBody
-	public AjaxResult add(@RequestBody GoviewProject goviewProject){
-		goviewProject.setCreateTime(DateUtil.now());
-		goviewProject.setState(-1);
-		boolean b=iGoviewProjectService.save(goviewProject);
-		if(b){
-			return successData(200, goviewProject).put("msg", "创建成功");
-		}else{
-			return error();
-		}
-	}
-	
-	
-	/**
-	 * 项目表删除
-	 * @param ids
-	 * @return
-	 */
-	//@Log(title = "项目表删除", action = "111")
-	@ApiOperation(value = "删除", notes = "删除")
-	@DeleteMapping("/delete")
-	@ResponseBody
-	public AjaxResult remove(String ids){
-		List<String> lista=ConvertUtil.toListStrArray(ids);
-		Boolean b=iGoviewProjectService.removeByIds(lista);
-		if(b){
-			return success();
-		}else{
-			return error();
-		}
-	}
-	
-	@ApiOperation(value = "修改保存", notes = "修改保存")
-    @PostMapping("/edit")
-    @ResponseBody
-    public AjaxResult editSave(@RequestBody GoviewProject goviewProject)
-    {
-		Boolean b= iGoviewProjectService.updateById(goviewProject);
-        if(b){
-        	return success();
-        }
-        return error();
-    }
-	
-	
-	@ApiOperation(value = "项目重命名", notes = "项目重命名")
-    @PostMapping("/rename")
-    @ResponseBody
-    public AjaxResult rename(@RequestBody GoviewProject goviewProject)
-    {
-		
-		LambdaUpdateWrapper<GoviewProject> updateWrapper=new LambdaUpdateWrapper<GoviewProject>();
-		updateWrapper.eq(GoviewProject::getId, goviewProject.getId());
-		updateWrapper.set(GoviewProject::getProjectName, goviewProject.getProjectName());
-		Boolean b=iGoviewProjectService.update(updateWrapper);
-		if(b){
-        	return success();
-        }
-		return error();
-    }
-	
-	
-	//发布/取消项目状态
-    @PutMapping("/publish")
-	@ResponseBody
-    public AjaxResult updateVisible(@RequestBody GoviewProject goviewProject){
-    	if(goviewProject.getState()==-1||goviewProject.getState()==1) {
-    	
-    		LambdaUpdateWrapper<GoviewProject> updateWrapper=new LambdaUpdateWrapper<GoviewProject>();
-    		updateWrapper.eq(GoviewProject::getId, goviewProject.getId());
-    		updateWrapper.set(GoviewProject::getState, goviewProject.getState());
-    		Boolean b=iGoviewProjectService.update(updateWrapper);
-    		if(b){
-            	return success();
-            }
-    		return error();
-    	}
-    	return error("警告非法字段");
-	}
-	
-    
-    @ApiOperation(value = "获取项目存储数据", notes = "获取项目存储数据")
-	@GetMapping("/getData")
-	@ResponseBody
-    public AjaxResult getData(String projectId, ModelMap map)
-    {
-		GoviewProject goviewProject= iGoviewProjectService.getById(projectId);
-		
-		GoviewProjectData blogText=iGoviewProjectDataService.getProjectid(projectId);
-		if(blogText!=null) {
-			GoviewProjectVo goviewProjectVo=new GoviewProjectVo();
-			BeanUtils.copyProperties(goviewProject,goviewProjectVo);
-			goviewProjectVo.setContent(blogText.getContent());
-			return AjaxResult.successData(200,goviewProjectVo).put("msg","获取成功");
-		}
-		return AjaxResult.successData(200, null).put("msg","无数据");
-        
-    }
-	
-	
-	
-	@ApiOperation(value = "保存项目数据", notes = "保存项目数据")
-	@PostMapping("/save/data")
-	@ResponseBody
-	public AjaxResult saveData(GoviewProjectData data) {
-		
-		GoviewProject goviewProject= iGoviewProjectService.getById(data.getProjectId());
-		if(goviewProject==null) {
-			return error("没有该项目ID");
-		}
-		GoviewProjectData goviewProjectData= iGoviewProjectDataService.getOne(new LambdaQueryWrapper<GoviewProjectData>().eq(GoviewProjectData::getProjectId, goviewProject.getId()));
-		if(goviewProjectData!=null) {
-			 data.setId(goviewProjectData.getId());
-			 iGoviewProjectDataService.updateById(data);
-			 return success("数据保存成功");
-		}else {
-			iGoviewProjectDataService.save(data);
-			return success("数据保存成功");
-		}
-	}
-	
-	/**
-	 * 上传文件
-	 * @param object 文件流对象
-	 * @param bucketName 桶名
-	 * @return
-	 * @throws Exception
-	 */
-	@PostMapping("/upload")
-	public AjaxResult upload(@RequestBody MultipartFile object) throws IOException{
-		String fileName = object.getOriginalFilename();
-		//默认文件格式
-		String suffixName=v2Config.getDefaultFormat();
-		String mediaKey="";
-		Long filesize= object.getSize();
-		//文件名字
-		String fileSuffixName="";
-		if(fileName.lastIndexOf(".")!=-1) {//有后缀
-			 suffixName = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
-			 //mediaKey=MD5.create().digestHex(fileName);
-			 mediaKey=SnowflakeIdWorker.getUUID();
-			 fileSuffixName=mediaKey+suffixName;
-		}else {//无后缀
-			//取得唯一id
-			 //mediaKey = MD5.create().digestHex(fileName+suffixName);
-			mediaKey=SnowflakeIdWorker.getUUID();
-			//fileSuffixName=mediaKey+suffixName;
-		}
-		String virtualKey=FileController.getFirstNotNull(v2Config.getXnljmap());
-		String absolutePath=v2Config.getXnljmap().get(FileController.getFirstNotNull(v2Config.getXnljmap()));
-		SysFile sysFile=new SysFile();
-		sysFile.setId(SnowflakeIdWorker.getUUID());
-		sysFile.setFileName(fileSuffixName);
-		sysFile.setFileSize(Integer.parseInt(filesize+""));
-		sysFile.setFileSuffix(suffixName);
-		sysFile.setCreateTime(DateUtil.formatLocalDateTime(LocalDateTime.now()));
-		String filepath=DateUtil.formatDate(new Date());
-		sysFile.setRelativePath(filepath);
-		sysFile.setVirtualKey(virtualKey);
-		sysFile.setAbsolutePath(absolutePath.replace("file:",""));
-		iSysFileService.saveOrUpdate(sysFile);
-		File desc = FileController.getAbsoluteFile(v2Config.getFileurl()+File.separator+filepath,fileSuffixName);
-		object.transferTo(desc);
-		SysFileVo sysFileVo=BeanUtil.copyProperties(sysFile, SysFileVo.class);
-		sysFileVo.setFileurl(v2Config.getHttpurl()+sysFile.getVirtualKey()+"/"+sysFile.getRelativePath()+"/"+sysFile.getFileName());
-		return successData(200, sysFileVo);
-	}
-	
-
-}

+ 0 - 21
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/controller/web/Indexcontroller.java

@@ -1,21 +0,0 @@
-package cn.com.v2.controller;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import javax.servlet.http.HttpServletResponse;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-@RestController
-public class Indexcontroller {
-
-	@GetMapping("/")
-	public void index(HttpServletResponse response) throws IOException {
-		response.setContentType("text/html; charset=utf-8");
-		PrintWriter out = response.getWriter();
-		out.println("<p style='color:orange'>goview后台首页</p>");
-		out.flush();
-		out.close();
-
-	}
-}

+ 0 - 16
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/mapper/GoviewProjectDataMapper.java

@@ -1,16 +0,0 @@
-package cn.com.v2.mapper;
-
-import cn.com.v2.model.GoviewProjectData;
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-
-/**
- * <p>
- *  Mapper 接口
- * </p>
- *
- * @author fc
- * @since 2023-04-30
- */
-public interface GoviewProjectDataMapper extends BaseMapper<GoviewProjectData> {
-
-}

+ 0 - 16
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/mapper/GoviewProjectMapper.java

@@ -1,16 +0,0 @@
-package cn.com.v2.mapper;
-
-import cn.com.v2.model.GoviewProject;
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-
-/**
- * <p>
- *  Mapper 接口
- * </p>
- *
- * @author fc
- * @since 2023-04-30
- */
-public interface GoviewProjectMapper extends BaseMapper<GoviewProject> {
-
-}

+ 0 - 17
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/mapper/SysFileMapper.java

@@ -1,17 +0,0 @@
-package cn.com.v2.mapper;
-
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-
-import cn.com.v2.model.SysFile;
-
-/**
- * <p>
- *  Mapper 接口
- * </p>
- *
- * @author fc
- * @since 2022-12-22
- */
-public interface SysFileMapper extends BaseMapper<SysFile> {
-
-}

+ 0 - 16
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/mapper/SysUserMapper.java

@@ -1,16 +0,0 @@
-package cn.com.v2.mapper;
-
-import cn.com.v2.model.SysUser;
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-
-/**
- * <p>
- *  Mapper 接口
- * </p>
- *
- * @author fc
- * @since 2023-04-30
- */
-public interface SysUserMapper extends BaseMapper<SysUser> {
-
-}

+ 0 - 48
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/model/GoviewProject.java

@@ -1,48 +0,0 @@
-package cn.com.v2.model;
-
-import com.baomidou.mybatisplus.annotation.FieldFill;
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * <p>
- * 
- * </p>
- *
- * @author fc
- * @since 2023-04-30
- */
-@TableName("t_goview_project")
-@Data
-public class GoviewProject implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-    
-    @TableId(type = IdType.ASSIGN_ID)
-    private String id;
-
-    private String projectName;
-
-    private Integer state;
-
-    @TableField(fill = FieldFill.INSERT)
-    private String createTime;
-
-    private String createUserId;
-
-    private Integer isDelete;
-
-    private String indexImage;
-
-    private String remarks;
-
-}
-
-
-

+ 0 - 39
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/model/GoviewProjectData.java

@@ -1,39 +0,0 @@
-package cn.com.v2.model;
-
-import com.baomidou.mybatisplus.annotation.FieldFill;
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.Data;
-import java.io.Serializable;
-import java.sql.Blob;
-import java.sql.SQLException;
-
-/**
- * <p>
- * 
- * </p>
- *
- * @author fc
- * @since 2023-04-30
- */
-@TableName("t_goview_project_data")
-@Data
-public class GoviewProjectData implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-    @TableId(type = IdType.ASSIGN_ID)
-    private String id;
-
-    private String projectId;
-
-    @TableField(fill = FieldFill.INSERT)
-    private String createTime;
-
-    private String createUserId;
-
-    private String content;
-
-   
-}

+ 0 - 119
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/model/SysFile.java

@@ -1,119 +0,0 @@
-package cn.com.v2.model;
-
-import com.baomidou.mybatisplus.annotation.FieldFill;
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import java.io.Serializable;
-
-/**
- * <p>
- * 
- * </p>
- *
- * @author fc
- * @since 2022-12-22
- */
-@TableName("t_sys_file")
-public class SysFile implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    @TableId(value = "id", type = IdType.INPUT)
-    private String id;
-
-    private String fileName;
-
-    private Integer fileSize;
-
-    private String fileSuffix;
-    
-    /**
-     * 虚拟路径
-     */
-    private String virtualKey;
-    
-    /**
-     * 相对路径
-     */
-    private String relativePath;
-    
-    /**
-     * 绝对路径
-     */
-    private String absolutePath;
-    
-    
-    
-    
-    @TableField(fill = FieldFill.INSERT)
-    private String createTime;
-
-    public String getId() {
-        return id;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-    public String getFileName() {
-        return fileName;
-    }
-
-    public void setFileName(String fileName) {
-        this.fileName = fileName;
-    }
-   
-    public Integer getFileSize() {
-        return fileSize;
-    }
-
-    public void setFileSize(Integer fileSize) {
-        this.fileSize = fileSize;
-    }
-    public String getFileSuffix() {
-        return fileSuffix;
-    }
-
-    public void setFileSuffix(String fileSuffix) {
-        this.fileSuffix = fileSuffix;
-    }
-    public String getCreateTime() {
-        return createTime;
-    }
-
-    public void setCreateTime(String createTime) {
-        this.createTime = createTime;
-    }
-    
-
-	public String getVirtualKey() {
-		return virtualKey;
-	}
-
-	public void setVirtualKey(String virtualKey) {
-		this.virtualKey = virtualKey;
-	}
-
-	public String getAbsolutePath() {
-		return absolutePath;
-	}
-
-	public void setAbsolutePath(String absolutePath) {
-		this.absolutePath = absolutePath;
-	}
-
-	public String getRelativePath() {
-		return relativePath;
-	}
-
-	public void setRelativePath(String relativePath) {
-		this.relativePath = relativePath;
-	}
-
-
-
-	
-	
-}

+ 0 - 39
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/model/SysUser.java

@@ -1,39 +0,0 @@
-package cn.com.v2.model;
-
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * <p>
- * 
- * </p>
- *
- * @author fc
- * @since 2023-04-30
- */
-@TableName("t_sys_user")
-@Data
-public class SysUser implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    @TableId(type = IdType.ASSIGN_ID)
-    private String id;
-
-    private String username;
-
-    private String password;
-
-    private String nickname;
-
-    private Integer depId;
-
-    private String posId;
-
- 
-}

+ 0 - 119
service-cockpit/service-cockpit-biz/src/main/java/com/usky/cockpit/model/vo/GoviewProjectVo.java

@@ -1,119 +0,0 @@
-package cn.com.v2.model.vo;
-
-import java.io.Serializable;
-import java.util.Date;
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import cn.hutool.core.date.DateUtil;
-import io.swagger.annotations.ApiModelProperty;
-
-public class GoviewProjectVo implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-	
-	@ApiModelProperty(value = "主键")
-	private String id;
-	
-	@ApiModelProperty(value = "项目名称")
-	private String projectName;
-	
-	@ApiModelProperty(value = "项目状态[-1未发布,1发布]")
-	private Integer state;
-	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
-	@ApiModelProperty(value = "创建时间")
-	private Date createTime;
-	
-	@ApiModelProperty(value = "创建人id")
-	private String createUserId;
-	
-	@ApiModelProperty(value = "删除状态[1删除,-1未删除]")
-	private Integer isDelete;
-	
-	@ApiModelProperty(value = "首页图片")
-	private String indexImage;
-	
-	@ApiModelProperty(value = "项目介绍")
-	private String remarks;
-	
-	private String content;
-	
-	
-	@JsonProperty("id")
-	public String getId() {
-		return id;
-	}
-
-	public void setId(String id) {
-		this.id =  id;
-	}
-	@JsonProperty("projectName")
-	public String getProjectName() {
-		return projectName;
-	}
-
-	public void setProjectName(String projectName) {
-		this.projectName =  projectName;
-	}
-	@JsonProperty("state")
-	public Integer getState() {
-		return state;
-	}
-
-	public void setState(Integer state) {
-		this.state =  state;
-	}
-	@JsonProperty("createTime")
-	public Date getCreateTime() {
-		return createTime;
-	}
-
-	public void setCreateTime(Date createTime) {
-		this.createTime =  createTime;
-	}
-	@JsonProperty("createUserId")
-	public String getCreateUserId() {
-		return createUserId;
-	}
-
-	public void setCreateUserId(String createUserId) {
-		this.createUserId =  createUserId;
-	}
-	@JsonProperty("isDelete")
-	public Integer getIsDelete() {
-		return isDelete;
-	}
-
-	public void setIsDelete(Integer isDelete) {
-		this.isDelete =  isDelete;
-	}
-	@JsonProperty("indexImage")
-	public String getIndexImage() {
-		return indexImage;
-	}
-
-	public void setIndexImage(String indexImage) {
-		this.indexImage =  indexImage;
-	}
-	@JsonProperty("remarks")
-	public String getRemarks() {
-		return remarks;
-	}
-
-	public void setRemarks(String remarks) {
-		this.remarks =  remarks;
-	}
-	public String getContent() {
-		return content;
-	}
-
-	public void setContent(String content) {
-		this.content = content;
-	}
-
-	public String dateToStringConvert(Date date) {
-		if(date!=null) {
-			return DateUtil.format(date, "yyyy-MM-dd HH:mm:ss");
-		}
-		return "";
-	}
-}

部分文件因文件數量過多而無法顯示