Ver código fonte

人防物联网国动办数据推送

hanzhengyi 3 dias atrás
pai
commit
cfd39a3bf2
41 arquivos alterados com 2041 adições e 17 exclusões
  1. 3 0
      pom.xml
  2. 7 1
      service-agbox/service-agbox-biz/src/main/java/com/usky/agbox/service/mqtt/event/event.java
  3. 20 0
      service-cdi/pom.xml
  4. 31 0
      service-cdi/service-cdi-api/pom.xml
  5. 4 0
      service-cdi/service-cdi-api/src/main/java/com/usky/cdi/RemotecdiTaskService.java
  6. 4 0
      service-cdi/service-cdi-api/src/main/java/com/usky/cdi/factory/RemotecdiTaskFactory.java
  7. 105 0
      service-cdi/service-cdi-biz/pom.xml
  8. 46 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/RuoYiSystemApplication.java
  9. 83 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/BaseDataController.java
  10. 108 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/MybatisGeneratorUtils.java
  11. 52 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/config/mqtt/MqttBaseConfig.java
  12. 41 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/config/mqtt/MqttGateway.java
  13. 52 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/config/mqtt/MqttInConfig.java
  14. 60 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/config/mqtt/MqttOutConfig.java
  15. 245 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/impl/BaseDataTransferService.java
  16. 61 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/listener/MqttListener.java
  17. 13 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/mqtt/MqttStrategy.java
  18. 35 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/mqtt/SimpleContext.java
  19. 29 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/mqtt/event/event.java
  20. 31 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/mqtt/info/Info.java
  21. 138 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/util/HttpClientUtils.java
  22. 34 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/util/SignUtil.java
  23. 145 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/util/SnowflakeIdGenerator.java
  24. 21 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/MqttBaseVO.java
  25. 67 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/EngineeringBaseVO.java
  26. 42 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/ErrorMsgVO.java
  27. 67 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/FloorPlaneVO.java
  28. 68 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/ProtectiveUnitVO.java
  29. 87 0
      service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/vo/base/SensorInfoVO.java
  30. 25 0
      service-cdi/service-cdi-biz/src/main/resources/bootstrap.yml
  31. 108 0
      service-cdi/service-cdi-biz/src/main/resources/doc/index.adoc
  32. 94 0
      service-cdi/service-cdi-biz/src/main/resources/logback.xml
  33. 15 0
      service-cdi/service-cdi-biz/src/main/resources/smart-doc.json
  34. 4 3
      service-ids/service-ids-biz/src/main/java/com/usky/ids/controller/MybatisGeneratorUtils.java
  35. 19 3
      service-ids/service-ids-biz/src/main/java/com/usky/ids/controller/web/AccessAlarmController.java
  36. 17 3
      service-ids/service-ids-biz/src/main/java/com/usky/ids/controller/web/AccessEntryExitRecordController.java
  37. 4 2
      service-ids/service-ids-biz/src/main/java/com/usky/ids/service/AccessAlarmService.java
  38. 3 1
      service-ids/service-ids-biz/src/main/java/com/usky/ids/service/AccessEntryExitRecordService.java
  39. 16 2
      service-ids/service-ids-biz/src/main/java/com/usky/ids/service/impl/AccessAlarmServiceImpl.java
  40. 36 1
      service-ids/service-ids-biz/src/main/java/com/usky/ids/service/impl/AccessEntryExitRecordServiceImpl.java
  41. 1 1
      service-job/src/main/java/com/ruoyi/job/task/RyTask.java

+ 3 - 0
pom.xml

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

+ 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")
@@ -45,9 +46,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());

+ 20 - 0
service-cdi/pom.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>usky-modules</artifactId>
+        <groupId>com.usky</groupId>
+        <version>0.0.1</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>service-cdi</artifactId>
+
+    <packaging>pom</packaging>
+    <version>0.0.1</version>
+
+    <modules>
+        <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>

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

@@ -0,0 +1,4 @@
+package com.usky.cdi;
+
+public interface RemotecdiTaskService {
+}

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

@@ -0,0 +1,4 @@
+package com.usky.cdi.factory;
+
+public class RemotecdiTaskFactory {
+}

+ 105 - 0
service-cdi/service-cdi-biz/pom.xml

@@ -0,0 +1,105 @@
+<?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-biz</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.usky</groupId>
+            <artifactId>common-cloud-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.usky</groupId>
+            <artifactId>service-backend-api</artifactId>
+            <version>0.0.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.usky</groupId>
+            <artifactId>service-cdi-api</artifactId>
+            <version>0.0.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.afterturn</groupId>
+            <artifactId>easypoi-spring-boot-starter</artifactId>
+            <version>4.1.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-core</artifactId>
+            <version>4.5.16</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
+            <version>1.1.0</version>
+        </dependency>
+
+        <!--MQTT依赖-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-integration</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.integration</groupId>
+            <artifactId>spring-integration-mqtt</artifactId>
+        </dependency>
+        <!--websocket依赖-->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-websocket</artifactId>
+            <version>5.2.8.RELEASE</version>
+        </dependency>
+        
+        <!--Redis依赖-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.2.6.RELEASE</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>com.github.shalousun</groupId>
+                <artifactId>smart-doc-maven-plugin</artifactId>
+                <version>2.1.1</version>
+                <configuration>
+                    <!--指定生成文档的使用的配置文件,配置文件放在自己的项目中-->
+                    <configFile>./src/main/resources/smart-doc.json</configFile>
+                    <!--指定项目名称-->
+                    <projectName>test</projectName>
+                    <!--                    <excludes>-->
+                    <!--                        <exclude>com.bizmatics:product-service-provider</exclude>-->
+                    <!--                        <exclude>cn.afterturn:easypoi-web</exclude>-->
+                    <!--                    </excludes>-->
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 46 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/RuoYiSystemApplication.java

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

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

@@ -0,0 +1,83 @@
+package com.usky.cdi.controller;
+
+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 SensorInfoVO vo) {
+        boolean success = baseDataTransferService.sendSensorInfo(vo);
+        return success ? "上报成功" : "上报失败";
+    }
+
+    /**
+     * 批量上报智能监管物联设施信息
+     */
+    @PostMapping("/sensorInfos")
+    public String batchSendSensorInfos(@RequestBody List<SensorInfoVO> sensors) {
+        int successCount = baseDataTransferService.batchSendSensorInfos(sensors);
+        return String.format("上报成功 %d/%d", successCount, sensors.size());
+    }
+}
+

+ 108 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/controller/MybatisGeneratorUtils.java

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

+ 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;
+    }
+
+}

+ 41 - 0
service-cdi/service-cdi-biz/src/main/java/com/usky/cdi/service/config/mqtt/MqttGateway.java

@@ -0,0 +1,41 @@
+package com.usky.cdi.service.config.mqtt;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.integration.annotation.MessagingGateway;
+import org.springframework.integration.mqtt.support.MqttHeaders;
+import org.springframework.messaging.handler.annotation.Header;
+
+/**
+ * MQTT消息发送网关
+ * 
+ * @author han
+ * @date 2025/03/20
+ */
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+@MessagingGateway(defaultRequestChannel = MqttOutConfig.CHANNEL_NAME_OUT)
+public interface MqttGateway {
+    /**
+     * 发送消息
+     *
+     * @param payload 消息内容
+     */
+    void sendToMqtt(String payload);
+
+    /**
+     * 指定topic发送消息
+     *
+     * @param topic 消息主题
+     * @param payload 消息内容
+     */
+    void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, String payload);
+
+    /**
+     * 指定topic和qos发送消息
+     *
+     * @param topic 消息主题
+     * @param qos 消息质量等级
+     * @param payload 消息内容
+     */
+    void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload);
+}
+

+ 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;
+    }
+}

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

@@ -0,0 +1,60 @@
+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.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;
+
+/**
+ * @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;
+    }
+
+}

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

@@ -0,0 +1,245 @@
+package com.usky.cdi.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.usky.cdi.service.config.mqtt.MqttGateway;
+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.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.stereotype.Service;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * 基础类数据传输服务
+ * 负责向市适配平台发送基础类数据
+ * 
+ * @author han
+ * @date 2025/03/20
+ */
+@Slf4j
+@Service
+@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
+public class BaseDataTransferService {
+
+    @Autowired(required = false)
+    private MqttGateway mqttGateway;
+
+    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) {
+        if (mqttGateway == null) {
+            log.warn("MQTT Gateway未初始化,无法发送消息");
+            return false;
+        }
+        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) {
+        if (mqttGateway == null) {
+            log.warn("MQTT Gateway未初始化,无法发送消息");
+            return false;
+        }
+        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) {
+        if (mqttGateway == null) {
+            log.warn("MQTT Gateway未初始化,无法发送消息");
+            return false;
+        }
+        try {
+            if (vo.getDataPacketID() == null) {
+                vo.setDataPacketID(generateDataPacketID());
+            }
+            if (vo.getPublishTime() == null) {
+                vo.setPublishTime(getCurrentTime());
+            }
+
+            // 检查文件大小(不超过5MB)
+            if (vo.getFloorFile() != null && vo.getFloorFile().length > 5 * 1024 * 1024) {
+                log.error("楼层平面图文件大小超过5MB限制,FileID: {}", vo.getFloorFileID());
+                return false;
+            }
+
+            // 将字节数组转换为Base64编码
+            JSONObject jsonObject = (JSONObject) JSON.toJSON(vo);
+            if (vo.getFloorFile() != null) {
+                // 使用Base64编码传输二进制数据
+                String base64File = java.util.Base64.getEncoder().encodeToString(vo.getFloorFile());
+                jsonObject.put("floorFile", base64File);
+            }
+
+            String json = jsonObject.toJSONString();
+            String topic = "base/floorPlane";
+            
+            log.info("发送楼层平面图信息,Topic: {}, FileID: {}, FileSize: {} bytes", 
+                    topic, vo.getFloorFileID(), 
+                    vo.getFloorFile() != null ? vo.getFloorFile().length : 0);
+            mqttGateway.sendToMqtt(topic, json);
+            
+            return true;
+        } catch (Exception e) {
+            log.error("发送楼层平面图信息失败,FileID: {}", vo.getFloorFileID(), e);
+            return false;
+        }
+    }
+
+    /**
+     * 发送智能监管物联设施信息
+     * Topic: base/sensorInfo
+     * 
+     * @param vo 智能监管物联设施信息
+     * @return 是否发送成功
+     */
+    public boolean sendSensorInfo(SensorInfoVO vo) {
+        if (mqttGateway == null) {
+            log.warn("MQTT Gateway未初始化,无法发送消息");
+            return false;
+        }
+        try {
+            if (vo.getDataPacketID() == null) {
+                vo.setDataPacketID(generateDataPacketID());
+            }
+            if (vo.getPublishTime() == null) {
+                vo.setPublishTime(getCurrentTime());
+            }
+
+            String json = JSON.toJSONString(vo);
+            String topic = "base/sensorInfo";
+            
+            log.info("发送智能监管物联设施信息,Topic: {}, SensorID: {}", topic, vo.getSensorID());
+            mqttGateway.sendToMqtt(topic, json);
+            
+            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 sensors 物联设施列表
+     * @return 成功发送的数量
+     */
+    public int batchSendSensorInfos(java.util.List<SensorInfoVO> sensors) {
+        if (sensors == null || sensors.isEmpty()) {
+            return 0;
+        }
+        
+        int successCount = 0;
+        for (SensorInfoVO sensor : sensors) {
+            if (sendSensorInfo(sensor)) {
+                successCount++;
+            }
+        }
+        
+        log.info("批量发送智能监管物联设施信息,总数: {}, 成功: {}", sensors.size(), successCount);
+        return successCount;
+    }
+}
+

+ 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;
+    }
+}

+ 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;
+    }
+}
+

+ 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;
+}

+ 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;
+}
+

+ 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;
+}
+

+ 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;
+
+    /**
+     * 设施在平面图的X轴坐标
+     */
+    private Integer xCoordinate;
+
+    /**
+     * 设施在平面图的Y轴坐标
+     */
+    private Integer yCoordinate;
+
+    /**
+     * 上报时间
+     */
+    private String publishTime;
+}
+

+ 25 - 0
service-cdi/service-cdi-biz/src/main/resources/bootstrap.yml

@@ -0,0 +1,25 @@
+# Tomcat
+server:
+  port: 9893
+
+# Spring
+spring: 
+  application:
+    # 应用名称
+    name: service-cdi
+  profiles:
+    # 环境配置
+    active: dev
+  cloud:
+    nacos:
+      discovery:
+        # 服务注册地址
+        server-addr: usky-cloud-nacos:8848
+      config:
+        # 配置中心地址
+        server-addr: usky-cloud-nacos:8848
+        # 配置文件格式
+        file-extension: yml
+        # 共享配置
+        shared-configs:
+          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

+ 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-offline" />
+    <!-- 日志输出格式 -->
+    <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.iot.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>

+ 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:9887/",
+  "isStrict": false,
+  "coverOld": true,
+  "allInOne": true,
+  "packageFilters": "com.usky.iot.controller.web",
+  "requestExample":"false",
+  "responseExample":"true",
+  "projectName": "iot项目",
+  "appKey": "20211216921084883495813120",
+  "appToken":"967031b0cc6f474aaf73616cbf2b25c2",
+  "secret": "N@Pd,KXAHki*BW3=zK.XPNykf!=CM79J",
+  "openUrl": "http://101.133.214.75:7700/api"
+}

+ 4 - 3
service-ids/service-ids-biz/src/main/java/com/usky/ids/controller/MybatisGeneratorUtils.java

@@ -44,10 +44,11 @@ public class MybatisGeneratorUtils {
         //2、数据源配置
         //修改数据源
         DataSourceConfig dsc = new DataSourceConfig();
-        dsc.setUrl("jdbc:mysql://192.168.10.165:3306/usky-cloud?useUnicode=true&serverTimezone=GMT&useSSL=false&characterEncoding=utf8");
+        dsc.setUrl("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&serverTimezone=GMT&useSSL=false" +
+                "&characterEncoding=utf8");
         dsc.setDriverName("com.mysql.jdbc.Driver");
         dsc.setUsername("root");
-        dsc.setPassword("yt123456");
+        dsc.setPassword("hs@94950212");
         mpg.setDataSource(dsc);
 
         // 3、包配置
@@ -72,7 +73,7 @@ public class MybatisGeneratorUtils {
         // strategy.setTablePrefix("t_"); // 表名前缀
         strategy.setEntityLombokModel(true); //使用lombok
         //修改自己想要生成的表
-        strategy.setInclude("ids_park_map");  // 逆向工程使用的表   如果要生成多个,这里可以传入String[]
+        strategy.setInclude("access_entry_exit_record");  // 逆向工程使用的表   如果要生成多个,这里可以传入String[]
         mpg.setStrategy(strategy);
 
         // 关闭默认 xml 生成,调整生成 至 根目录

+ 19 - 3
service-ids/service-ids-biz/src/main/java/com/usky/ids/controller/web/AccessAlarmController.java

@@ -1,21 +1,37 @@
 package com.usky.ids.controller.web;
 
 
-import org.springframework.web.bind.annotation.RequestMapping;
+import com.usky.common.core.bean.ApiResult;
+import com.usky.ids.domain.AccessAlarm;
+import com.usky.ids.service.AccessAlarmService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
 
 import org.springframework.stereotype.Controller;
 
+import java.util.List;
+
 /**
  * <p>
  * 报警信息表 前端控制器
  * </p>
  *
  * @author han
- * @since 2025-03-10
+ * @since 2025-03-01
  */
-@Controller
+@RestController
 @RequestMapping("/accessAlarm")
 public class AccessAlarmController {
+    @Autowired
+    private AccessAlarmService accessAlarmService;
 
+    /**
+     * 告警查询接口
+     * @return
+     */
+    @GetMapping("/getAlarmList")
+    public ApiResult<List<AccessAlarm>> getAlarmList(@RequestParam(value = "deviceId", required = false) String deviceId){
+        return ApiResult.success(accessAlarmService.getAlarmList(deviceId));
+    }
 }
 

+ 17 - 3
service-ids/service-ids-biz/src/main/java/com/usky/ids/controller/web/AccessEntryExitRecordController.java

@@ -1,9 +1,14 @@
 package com.usky.ids.controller.web;
 
 
+import com.usky.common.core.bean.ApiResult;
+import com.usky.ids.service.AccessAlarmService;
+import com.usky.ids.service.AccessEntryExitRecordService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 
-import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RestController;
 
 /**
  * <p>
@@ -13,9 +18,18 @@ import org.springframework.stereotype.Controller;
  * @author han
  * @since 2025-03-26
  */
-@Controller
+@RestController
 @RequestMapping("/accessEntryExitRecord")
 public class AccessEntryExitRecordController {
-
+    @Autowired
+    private AccessEntryExitRecordService accessEntryExitRecordService;
+    /**
+     * 获取车位信息
+     * @return
+     */
+    @GetMapping("entryExitCount")
+    ApiResult<Object> entryExitCount(){
+        return ApiResult.success(accessEntryExitRecordService.entryExitCount());
+    }
 }
 

+ 4 - 2
service-ids/service-ids-biz/src/main/java/com/usky/ids/service/AccessAlarmService.java

@@ -3,14 +3,16 @@ package com.usky.ids.service;
 import com.usky.ids.domain.AccessAlarm;
 import com.usky.common.mybatis.core.CrudService;
 
+import java.util.List;
+
 /**
  * <p>
  * 报警信息表 服务类
  * </p>
  *
  * @author han
- * @since 2025-03-10
+ * @since 2025-03-01
  */
 public interface AccessAlarmService extends CrudService<AccessAlarm> {
-
+    List<AccessAlarm> getAlarmList(String deviceId);
 }

+ 3 - 1
service-ids/service-ids-biz/src/main/java/com/usky/ids/service/AccessEntryExitRecordService.java

@@ -3,6 +3,8 @@ package com.usky.ids.service;
 import com.usky.ids.domain.AccessEntryExitRecord;
 import com.usky.common.mybatis.core.CrudService;
 
+import java.util.List;
+
 /**
  * <p>
  * 车辆进出记录 服务类
@@ -12,5 +14,5 @@ import com.usky.common.mybatis.core.CrudService;
  * @since 2025-03-26
  */
 public interface AccessEntryExitRecordService extends CrudService<AccessEntryExitRecord> {
-
+    List<Object> entryExitCount();
 }

+ 16 - 2
service-ids/service-ids-biz/src/main/java/com/usky/ids/service/impl/AccessAlarmServiceImpl.java

@@ -1,20 +1,34 @@
 package com.usky.ids.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.common.security.utils.SecurityUtils;
 import com.usky.ids.domain.AccessAlarm;
 import com.usky.ids.mapper.AccessAlarmMapper;
 import com.usky.ids.service.AccessAlarmService;
 import com.usky.common.mybatis.core.AbstractCrudService;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 /**
  * <p>
  * 报警信息表 服务实现类
  * </p>
  *
  * @author han
- * @since 2025-03-10
+ * @since 2025-03-01
  */
 @Service
 public class AccessAlarmServiceImpl extends AbstractCrudService<AccessAlarmMapper, AccessAlarm> implements AccessAlarmService {
-
+    public List<AccessAlarm> getAlarmList(String deviceId){
+        LambdaQueryWrapper<AccessAlarm> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.select(AccessAlarm::getAlarmId)
+                .eq(AccessAlarm::getCameraIndexCode, deviceId)
+                .eq(AccessAlarm::getAlarmType,'2')
+                .eq(AccessAlarm::getAlarmStatus,'0')
+                .last("limit 1");
+        List<AccessAlarm> list = this.list(queryWrapper);
+        return list;
+    }
 }

+ 36 - 1
service-ids/service-ids-biz/src/main/java/com/usky/ids/service/impl/AccessEntryExitRecordServiceImpl.java

@@ -1,11 +1,23 @@
 package com.usky.ids.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.common.security.utils.SecurityUtils;
 import com.usky.ids.domain.AccessEntryExitRecord;
 import com.usky.ids.mapper.AccessEntryExitRecordMapper;
 import com.usky.ids.service.AccessEntryExitRecordService;
 import com.usky.common.mybatis.core.AbstractCrudService;
 import org.springframework.stereotype.Service;
 
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 /**
  * <p>
  * 车辆进出记录 服务实现类
@@ -16,5 +28,28 @@ import org.springframework.stereotype.Service;
  */
 @Service
 public class AccessEntryExitRecordServiceImpl extends AbstractCrudService<AccessEntryExitRecordMapper, AccessEntryExitRecord> implements AccessEntryExitRecordService {
-
+    @Override
+    public List<Object> entryExitCount(){
+        List<Object> list = new ArrayList<>();
+        Map<String, Object> map = new HashMap<>();
+        LocalDateTime now = LocalDateTime.now();
+        LocalDate today = LocalDate.now();
+        LocalDateTime startOfDay = LocalDateTime.of(today, LocalTime.MIN);
+        // 定义日期时间字符串
+        String dateTimeString = "2025-04-25 02:31:00";
+        // 定义日期时间格式
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        // 将字符串转换为 LocalDateTime 对象
+        LocalDateTime localDateTime = LocalDateTime.parse(dateTimeString, formatter);
+        QueryWrapper<AccessEntryExitRecord> queryWrapper = Wrappers.query();
+        queryWrapper.select("COUNT(action_direction=1 or null) as entryCount","COUNT(action_direction=2 or" +
+                " null) as exitCount")
+                .between("record_time",localDateTime,now);
+        List<Map<String,Object>> entryExitList = this.listMaps(queryWrapper);
+        map.put("entryCount", Integer.valueOf(entryExitList.get(0).get("entryCount").toString()));
+        map.put("exitCount", Integer.valueOf(entryExitList.get(0).get("exitCount").toString()));
+        map.put("iotCount", 102);
+        list.add(map);
+        return list;
+    }
 }

+ 1 - 1
service-job/src/main/java/com/ruoyi/job/task/RyTask.java

@@ -56,7 +56,7 @@ public class RyTask {
 
     public void baseAlarmStatus(){
         System.out.println("baseAlarmStatus start......");
-        remoteIotTaskService.baseAlarmStatus();
+//        remoteIotTaskService.baseAlarmStatus();
     }
 
     public void customInfoStatus(){