bihuisong 2 maanden geleden
commit
3e152fba1a
52 gewijzigde bestanden met toevoegingen van 3184 en 0 verwijderingen
  1. 144 0
      pom.xml
  2. 51 0
      src/main/java/com/sooka/sponest/data/attach/domain/CenterdataTAttach.java
  3. 25 0
      src/main/java/com/sooka/sponest/data/attach/mapper/CenterdataTAttachMapper.java
  4. 20 0
      src/main/java/com/sooka/sponest/data/attach/service/ICenterdataTAttachService.java
  5. 48 0
      src/main/java/com/sooka/sponest/data/attach/service/impl/CenterdataTAttachServiceImpl.java
  6. 166 0
      src/main/java/com/sooka/sponest/event/download/domain/CentereventTDownloads.java
  7. 20 0
      src/main/java/com/sooka/sponest/event/download/mapper/CentereventTDownloadsMapper.java
  8. 14 0
      src/main/java/com/sooka/sponest/event/download/service/ICentereventTDownloadsService.java
  9. 30 0
      src/main/java/com/sooka/sponest/event/download/service/impl/CentereventTDownloadsServiceImpl.java
  10. 39 0
      src/main/java/com/sooka/sponest/monitor/SookaMonitorPlaybackByTimeApplication.java
  11. 11 0
      src/main/java/com/sooka/sponest/monitor/base/controller/BaseController.java
  12. 52 0
      src/main/java/com/sooka/sponest/monitor/base/domain/BaseBusinessEntity.java
  13. 13 0
      src/main/java/com/sooka/sponest/monitor/base/domain/DataTestVO.java
  14. 73 0
      src/main/java/com/sooka/sponest/monitor/base/service/impl/BaseService.java
  15. 19 0
      src/main/java/com/sooka/sponest/monitor/base/util/database/DynamicDataSource.java
  16. 41 0
      src/main/java/com/sooka/sponest/monitor/base/util/database/DynamicDataSourceAspect.java
  17. 41 0
      src/main/java/com/sooka/sponest/monitor/base/util/database/DynamicDataSourceSwitcher.java
  18. 4 0
      src/main/java/com/sooka/sponest/monitor/base/util/database/GlobalTransactionalRabbitMQ.java
  19. 136 0
      src/main/java/com/sooka/sponest/monitor/base/util/database/MultipleDataSourceConfig.java
  20. 15 0
      src/main/java/com/sooka/sponest/monitor/base/util/database/MyDataSource.java
  21. 258 0
      src/main/java/com/sooka/sponest/monitor/camera/domain/CentermonitorTCamera.java
  22. 32 0
      src/main/java/com/sooka/sponest/monitor/camera/domain/CentermonitorTCameraImg.java
  23. 36 0
      src/main/java/com/sooka/sponest/monitor/camera/mapper/CentermonitorTCameraMapper.java
  24. 29 0
      src/main/java/com/sooka/sponest/monitor/camera/service/ICentermonitorTCameraService.java
  25. 58 0
      src/main/java/com/sooka/sponest/monitor/camera/service/impl/CentermonitorTCameraServiceImpl.java
  26. 64 0
      src/main/java/com/sooka/sponest/monitor/dahua/controller/DahuaController.java
  27. 27 0
      src/main/java/com/sooka/sponest/monitor/dahua/domain/PlayBackProperties.java
  28. 67 0
      src/main/java/com/sooka/sponest/monitor/dahua/login/Login.java
  29. 36 0
      src/main/java/com/sooka/sponest/monitor/dahua/login/bean/LoginFirst.java
  30. 102 0
      src/main/java/com/sooka/sponest/monitor/dahua/login/bean/LoginSecond.java
  31. 33 0
      src/main/java/com/sooka/sponest/monitor/dahua/service/DahuaService.java
  32. 287 0
      src/main/java/com/sooka/sponest/monitor/dahua/service/impl/DahuaServiceImpl.java
  33. 96 0
      src/main/java/com/sooka/sponest/monitor/dahua/utils/DSSUtils.java
  34. 26 0
      src/main/java/com/sooka/sponest/monitor/dahua/utils/HttpEnum.java
  35. 195 0
      src/main/java/com/sooka/sponest/monitor/dahua/utils/HttpTestUtils.java
  36. 25 0
      src/main/java/com/sooka/sponest/monitor/dahua/utils/ImgUtils.java
  37. 70 0
      src/main/java/com/sooka/sponest/monitor/dahua/utils/RestRedirectStrategy.java
  38. 35 0
      src/main/java/com/sooka/sponest/monitor/feign/CenterMonitorFeignController.java
  39. 22 0
      src/main/java/com/sooka/sponest/monitor/remoteapi/EnableSookaFeignClients.java
  40. 4 0
      src/main/java/com/sooka/sponest/monitor/remoteapi/RemoveApiBaseService.java
  41. 16 0
      src/main/java/com/sooka/sponest/monitor/remoteapi/fallback/file/RemoteFileServiceFallbackFactory.java
  42. 47 0
      src/main/java/com/sooka/sponest/monitor/remoteapi/fallback/system/RemoteSystemBaseServiceFallbackFactory.java
  43. 51 0
      src/main/java/com/sooka/sponest/monitor/remoteapi/service/ModulesServiceNameContants.java
  44. 22 0
      src/main/java/com/sooka/sponest/monitor/remoteapi/service/file/RemoteFileBaseService.java
  45. 26 0
      src/main/java/com/sooka/sponest/monitor/remoteapi/service/system/RemoteService.java
  46. 78 0
      src/main/java/com/sooka/sponest/monitor/util/BeanUtil.java
  47. 244 0
      src/main/java/com/sooka/sponest/monitor/util/Mp4ParserUtils.java
  48. 9 0
      src/main/resources/banner.txt
  49. 23 0
      src/main/resources/bootstrap.yml
  50. 28 0
      src/main/resources/mapper/data/attach/CenterdataTAttachMapper.xml
  51. 77 0
      src/main/resources/mapper/event/download/CentereventTDownloadsMapper.xml
  52. 99 0
      src/main/resources/mapper/monitor/camera/CentermonitorTCameraMapper.xml

+ 144 - 0
pom.xml

@@ -0,0 +1,144 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://maven.apache.org/POM/4.0.0"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>ruoyi-modules</artifactId>
+        <groupId>com.ruoyi</groupId>
+        <version>3.4.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.sooka.onest</groupId>
+    <artifactId>center-monitor-playbackByTime</artifactId>
+
+
+    <dependencies>
+        <!-- SpringCloud Alibaba Nacos -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+
+        <!-- SpringCloud Alibaba Nacos Config -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+
+        <!-- SpringCloud Alibaba Sentinel -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
+        </dependency>
+
+        <!-- Sentinel Datasource Nacos -->
+        <dependency>
+            <groupId>com.alibaba.csp</groupId>
+            <artifactId>sentinel-datasource-nacos</artifactId>
+        </dependency>
+
+        <!-- Swagger UI -->
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+            <version>${swagger.fox.version}</version>
+        </dependency>
+
+        <!-- Mysql Connector -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+
+        <!-- RuoYi Common DataSource -->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>sooka-sponest-common-datasource</artifactId>
+        </dependency>
+
+        <!-- RuoYi Common DataScope -->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>sooka-sponest-common-datascope</artifactId>
+        </dependency>
+
+        <!-- RuoYi Common Log -->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>sooka-sponest-common-log</artifactId>
+        </dependency>
+
+        <!-- RuoYi Common Swagger -->
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>sooka-sponest-common-swagger</artifactId>
+        </dependency>
+
+        <!--海康-->
+        <dependency>
+            <groupId>com.hikvision.ga</groupId>
+            <artifactId>artemis-http-client</artifactId>
+            <version>1.1.3</version>
+        </dependency>
+
+        <!-- ICC鉴权 -->
+        <dependency>
+            <groupId>com.dahuatech.icc</groupId>
+            <artifactId>java-sdk-oauth</artifactId>
+            <version>1.0.9</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>java-sdk-core</artifactId>
+                    <groupId>com.dahuatech.icc</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>com.dahuatech.icc</groupId>
+            <artifactId>java-sdk-core</artifactId>
+            <version>1.0.9</version>
+        </dependency>
+
+        <!-- mp4文件操作jar -->
+        <!-- https://mvnrepository.com/artifact/com.googlecode.mp4parser/isoparser -->
+        <dependency>
+            <groupId>com.googlecode.mp4parser</groupId>
+            <artifactId>isoparser</artifactId>
+            <version>1.1.22</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.1.5.RELEASE</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+                <configuration>
+                    <nonFilteredFileExtensions>
+                        <nonFilteredFileExtension>xdb</nonFilteredFileExtension>
+                    </nonFilteredFileExtensions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
+

+ 51 - 0
src/main/java/com/sooka/sponest/data/attach/domain/CenterdataTAttach.java

@@ -0,0 +1,51 @@
+package com.sooka.sponest.data.attach.domain;
+
+import com.ruoyi.common.core.web.domain.BaseEntity;
+import lombok.Data;
+
+/**
+ * 附件对象 centerdata_t_attach
+ *
+ * @author ruoyi
+ * @date 2022-06-11
+ */
+@Data
+public class CenterdataTAttach extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 业务ID
+     */
+    private String busId;
+
+    /**
+     * 路径
+     */
+    private String attachPath;
+
+    /**
+     * 业务类型(索引)
+     */
+    private String busIndx;
+
+    /**
+     * 附件来源
+     */
+    private String busSource;
+
+    /**
+     * 附件名称
+     */
+    private String fileName;
+
+    /**
+     * 附件类型
+     */
+    private String fileType;
+
+    /**
+     * 排序
+     */
+    private int attachSorts;
+}

+ 25 - 0
src/main/java/com/sooka/sponest/data/attach/mapper/CenterdataTAttachMapper.java

@@ -0,0 +1,25 @@
+package com.sooka.sponest.data.attach.mapper;
+
+import com.ruoyi.common.datascope.base.util.database.DynamicDataSourceSwitcher;
+import com.sooka.sponest.data.attach.domain.CenterdataTAttach;
+import com.sooka.sponest.monitor.base.util.database.MyDataSource;
+import org.springframework.stereotype.Repository;
+
+/**
+ * 附件Mapper接口
+ *
+ * @author ruoyi
+ * @date 2022-06-11
+ */
+@Repository
+public interface CenterdataTAttachMapper {
+
+    /**
+     * 新增附件
+     *
+     * @param centerdataTAttach 附件
+     * @return 结果
+     */
+    @MyDataSource(value = DynamicDataSourceSwitcher.dbCenterData)
+    int insertCenterdataTAttach(CenterdataTAttach centerdataTAttach);
+}

+ 20 - 0
src/main/java/com/sooka/sponest/data/attach/service/ICenterdataTAttachService.java

@@ -0,0 +1,20 @@
+package com.sooka.sponest.data.attach.service;
+
+import com.sooka.sponest.data.attach.domain.CenterdataTAttach;
+
+/**
+ * 附件Service接口
+ *
+ * @author ruoyi
+ * @date 2022-06-11
+ */
+public interface ICenterdataTAttachService {
+
+    /**
+     * 新增附件
+     *
+     * @param centerdataTAttach 附件
+     * @return 结果
+     */
+    int insertCenterdataTAttach(CenterdataTAttach centerdataTAttach);
+}

+ 48 - 0
src/main/java/com/sooka/sponest/data/attach/service/impl/CenterdataTAttachServiceImpl.java

@@ -0,0 +1,48 @@
+package com.sooka.sponest.data.attach.service.impl;
+
+import com.sooka.sponest.data.attach.domain.CenterdataTAttach;
+import com.sooka.sponest.data.attach.mapper.CenterdataTAttachMapper;
+import com.sooka.sponest.data.attach.service.ICenterdataTAttachService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * 附件Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2022-06-11
+ */
+@Service
+public class CenterdataTAttachServiceImpl implements ICenterdataTAttachService {
+
+    @Autowired
+    private CenterdataTAttachMapper centerdataTAttachMapper;
+
+    /**
+     * 新增附件
+     *
+     * @param centerdataTAttach 附件
+     * @return 结果
+     */
+    @Override
+    public int insertCenterdataTAttach(CenterdataTAttach centerdataTAttach) {
+        /*
+         *ImageUpload返回是全路径,数据库保存不要ip和端口号
+         */
+        if (centerdataTAttach.getAttachPath().startsWith("http")) {
+            String attachPath = centerdataTAttach.getAttachPath();
+            if (centerdataTAttach.getAttachPath().contains("Download")) {
+                int i1 = attachPath.indexOf("group=");
+                attachPath = attachPath.replace("&&path=", "/");
+                attachPath = attachPath.substring(i1 + 6);
+                centerdataTAttach.setAttachPath(attachPath);
+            } else {
+                int i1 = attachPath.indexOf('/');
+                int i2 = attachPath.indexOf('/', i1 + 1);
+                int i3 = attachPath.indexOf('/', i2 + 1);
+                centerdataTAttach.setAttachPath(centerdataTAttach.getAttachPath().substring(i3 + 1, attachPath.length()));
+            }
+        }
+        return centerdataTAttachMapper.insertCenterdataTAttach(centerdataTAttach);
+    }
+}

+ 166 - 0
src/main/java/com/sooka/sponest/event/download/domain/CentereventTDownloads.java

@@ -0,0 +1,166 @@
+package com.sooka.sponest.event.download.domain;
+
+import com.ruoyi.common.core.annotation.Excel;
+import com.ruoyi.common.core.web.domain.BaseEntity;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * 【请填写功能名称】对象 centerevent_t_downloads
+ *
+ * @author ruoyi
+ * @date 2023-09-12
+ */
+public class CentereventTDownloads extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * $column.columnComment
+     */
+    private String id;
+
+    /**
+     * 事件编码
+     */
+    @Excel(name = "事件编码")
+    private String eventCode;
+
+    /**
+     * 事件名称
+     */
+    @Excel(name = "事件名称")
+    private String eventName;
+
+    /**
+     * 视频路径
+     */
+    @Excel(name = "视频路径")
+    private String path;
+
+    /**
+     * 视频下载是否成功
+     */
+    @Excel(name = "视频下载是否成功")
+    private String flag;
+
+    /**
+     * 失败原因
+     */
+    @Excel(name = "失败原因")
+    private String reason;
+
+    /**
+     * 创建人名称
+     */
+    @Excel(name = "创建人名称")
+    private String createName;
+
+    /**
+     * 更新人名称
+     */
+    @Excel(name = "更新人名称")
+    private String updateName;
+
+    private String logId;
+
+    public String getAttachPath() {
+        return attachPath;
+    }
+
+    public void setAttachPath(String attachPath) {
+        this.attachPath = attachPath;
+    }
+
+    private String attachPath;
+
+    public String getLogId() {
+        return logId;
+    }
+
+    public void setLogId(String logId) {
+        this.logId = logId;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setEventCode(String eventCode) {
+        this.eventCode = eventCode;
+    }
+
+    public String getEventCode() {
+        return eventCode;
+    }
+
+    public void setEventName(String eventName) {
+        this.eventName = eventName;
+    }
+
+    public String getEventName() {
+        return eventName;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setFlag(String flag) {
+        this.flag = flag;
+    }
+
+    public String getFlag() {
+        return flag;
+    }
+
+    public void setReason(String reason) {
+        this.reason = reason;
+    }
+
+    public String getReason() {
+        return reason;
+    }
+
+    public void setCreateName(String createName) {
+        this.createName = createName;
+    }
+
+    public String getCreateName() {
+        return createName;
+    }
+
+    public void setUpdateName(String updateName) {
+        this.updateName = updateName;
+    }
+
+    public String getUpdateName() {
+        return updateName;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
+                .append("id", getId())
+                .append("eventCode", getEventCode())
+                .append("eventName", getEventName())
+                .append("path", getPath())
+                .append("flag", getFlag())
+                .append("reason", getReason())
+                .append("createBy", getCreateBy())
+                .append("createName", getCreateName())
+                .append("createTime", getCreateTime())
+                .append("updateBy", getUpdateBy())
+                .append("updateName", getUpdateName())
+                .append("updateTime", getUpdateTime())
+                .toString();
+    }
+}

+ 20 - 0
src/main/java/com/sooka/sponest/event/download/mapper/CentereventTDownloadsMapper.java

@@ -0,0 +1,20 @@
+package com.sooka.sponest.event.download.mapper;
+
+import com.ruoyi.common.datascope.base.util.database.DynamicDataSourceSwitcher;
+import com.sooka.sponest.event.download.domain.CentereventTDownloads;
+import com.sooka.sponest.monitor.base.util.database.MyDataSource;
+import com.sooka.sponest.monitor.dahua.domain.PlayBackProperties;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Map;
+
+@Repository
+public interface CentereventTDownloadsMapper {
+
+    @MyDataSource(value = DynamicDataSourceSwitcher.dbCenterEvent)
+    List<PlayBackProperties> getbeforedateDownload(Map<String, Object> params);
+
+    @MyDataSource(value = DynamicDataSourceSwitcher.dbCenterEvent)
+    int insertCentereventTDownloads(CentereventTDownloads centereventTDownloads);
+}

+ 14 - 0
src/main/java/com/sooka/sponest/event/download/service/ICentereventTDownloadsService.java

@@ -0,0 +1,14 @@
+package com.sooka.sponest.event.download.service;
+
+import com.sooka.sponest.event.download.domain.CentereventTDownloads;
+import com.sooka.sponest.monitor.dahua.domain.PlayBackProperties;
+
+import java.util.List;
+import java.util.Map;
+
+public interface ICentereventTDownloadsService {
+
+    List<PlayBackProperties> downloadsCommon(Map<String, Object> params);
+
+    int insertCentereventTDownloads(CentereventTDownloads centereventTDownloads);
+}

+ 30 - 0
src/main/java/com/sooka/sponest/event/download/service/impl/CentereventTDownloadsServiceImpl.java

@@ -0,0 +1,30 @@
+package com.sooka.sponest.event.download.service.impl;
+
+import com.ruoyi.common.core.utils.DateUtils;
+import com.sooka.sponest.event.download.domain.CentereventTDownloads;
+import com.sooka.sponest.event.download.mapper.CentereventTDownloadsMapper;
+import com.sooka.sponest.event.download.service.ICentereventTDownloadsService;
+import com.sooka.sponest.monitor.dahua.domain.PlayBackProperties;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class CentereventTDownloadsServiceImpl implements ICentereventTDownloadsService {
+
+    @Autowired
+    private CentereventTDownloadsMapper centereventTDownloadsMapper;
+
+    @Override
+    public List<PlayBackProperties> downloadsCommon(Map<String, Object> params) {
+        return centereventTDownloadsMapper.getbeforedateDownload(params);
+    }
+
+    @Override
+    public int insertCentereventTDownloads(CentereventTDownloads centereventTDownloads) {
+        centereventTDownloads.setCreateTime(DateUtils.getNowDate());
+        return centereventTDownloadsMapper.insertCentereventTDownloads(centereventTDownloads);
+    }
+}

+ 39 - 0
src/main/java/com/sooka/sponest/monitor/SookaMonitorPlaybackByTimeApplication.java

@@ -0,0 +1,39 @@
+package com.sooka.sponest.monitor;
+
+import com.ruoyi.common.security.annotation.EnableCustomConfig;
+import com.ruoyi.common.security.annotation.EnableRyFeignClients;
+import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.MultipartConfigFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.util.unit.DataSize;
+
+import javax.servlet.MultipartConfigElement;
+
+@EnableAsync
+@EnableCustomConfig
+@EnableCustomSwagger2
+@EnableRyFeignClients
+@SpringBootApplication(scanBasePackages = "com.sooka.sponest")
+public class SookaMonitorPlaybackByTimeApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(SookaMonitorPlaybackByTimeApplication.class, args);
+        System.out.println("(♥◠‿◠)ノ゙  首佳科技 一体化 事件前后1分钟视频拉取服务 启动成功   ლ(´ڡ`ლ)゙  \n" +
+                "  __________   ____ |  | _______          ____________   ____   ____   ____   _______/  |_\n" +
+                " /  ___/  _ \\ /  _ \\|  |/ /\\__  \\        /  ___/\\____ \\ /  _ \\ /    \\_/ __ \\ /  ___/\\   __\\\n" +
+                " \\___ (  <_> |  <_> )    <  / __ \\_      \\___ \\ |  |_> >  <_> )   |  \\  ___/ \\___ \\  |  |\n" +
+                "/____  >____/ \\____/|__|_ \\(____  /     /____  >|   __/ \\____/|___|  /\\___  >____  > |__|\n" +
+                "     \\/                  \\/     \\/           \\/ |__|               \\/     \\/     \\/\n"
+        );
+    }
+
+    @Bean
+    public MultipartConfigElement multipartConfigElement() {
+        MultipartConfigFactory factory = new MultipartConfigFactory();
+        factory.setMaxFileSize(DataSize.parse("10240000KB"));
+        factory.setMaxRequestSize(DataSize.parse("10240000KB"));
+        return factory.createMultipartConfig();
+    }
+}

+ 11 - 0
src/main/java/com/sooka/sponest/monitor/base/controller/BaseController.java

@@ -0,0 +1,11 @@
+package com.sooka.sponest.monitor.base.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/BaseController")
+public class BaseController {
+
+
+}

+ 52 - 0
src/main/java/com/sooka/sponest/monitor/base/domain/BaseBusinessEntity.java

@@ -0,0 +1,52 @@
+package com.sooka.sponest.monitor.base.domain;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@Getter
+@Setter
+public class BaseBusinessEntity {
+
+    /**
+     * 搜索值
+     */
+    String searchValue;
+
+    Long dataDeptId;
+
+    /**
+     * 创建者
+     */
+    Long createBy;
+    /**
+     * 创建者
+     */
+    String remark;
+    /**
+     * 请求参数
+     */
+    Map<String, Object> params = new HashMap();
+    String database_system;
+    String database_event;
+    String database_data;
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime = new Date();
+    /**
+     * 更新者
+     */
+    private Long updateBy;
+    /**
+     * 更新时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+}

+ 13 - 0
src/main/java/com/sooka/sponest/monitor/base/domain/DataTestVO.java

@@ -0,0 +1,13 @@
+package com.sooka.sponest.monitor.base.domain;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class DataTestVO extends BaseBusinessEntity {
+
+    String name;
+
+
+}

+ 73 - 0
src/main/java/com/sooka/sponest/monitor/base/service/impl/BaseService.java

@@ -0,0 +1,73 @@
+package com.sooka.sponest.monitor.base.service.impl;
+
+import com.ruoyi.common.datascope.base.domain.BaseBusinessEntity;
+import com.ruoyi.common.redis.service.RedisService;
+import com.ruoyi.common.security.service.TokenService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+@Service
+public class BaseService {
+
+    @Value("${sooka.database.database_system:}")
+    public String database_system;
+    @Value("${sooka.database.database_event:}")
+    public String database_event;
+    @Value("${sooka.database.database_data:}")
+    public String database_data;
+    @Value("${sooka.dahua_video_server.loginIp:}")
+    public String loginIp;
+    @Value("${sooka.dahua_video_server.userName:}")
+    public String userName;
+    @Value("${sooka.dahua_video_server.userPwd:}")
+    public String userPwd;
+    @Value("${sooka.dahua_video_server.loginPort:}")
+    public Integer loginPort;
+    //app
+    @Value("${sooka.dahua_video_server_app.loginIpApp:}")
+    public String loginIpApp;
+    @Value("${sooka.dahua_video_server_app.userNameApp:}")
+    public String userNameApp;
+    @Value("${sooka.dahua_video_server_app.userPwdApp:}")
+    public String userPwdApp;
+    @Value("${sooka.dahua_video_server_app.loginPortApp:}")
+    public Integer loginPortApp;
+    //
+    @Value("${sooka.dahua_dss_server.host:}")
+    public String host;
+    @Value("${sooka.dahua_dss_server.user_name:}")
+    public String user_name;
+    @Value("${sooka.dahua_dss_server.password:}")
+    public String password;
+    @Value("${sooka.dahua_dss_server.client_id:}")
+    public String client_id;
+    @Value("${sooka.dahua_dss_server.client_secret:}")
+    public String client_secret;
+    @Value("${sooka.dahua_dss_server.version:}")
+    public String version;
+    @Value("${sooka.dahua_dss_server.video_download_url_linux:}")
+    public String videoDownloadUrlLinux;
+    @Value("${sooka.dahua_dss_server.video_download_url_win:}")
+    public String videoDownloadUrlWin;
+    @Value("${sooka.haikang_video_server.loginIp:}")
+    public String HkloginIp;
+    @Value("${sooka.haikang_video_server.appkey:}")
+    public String Hkappkey;
+    @Value("${sooka.haikang_video_server.secret:}")
+    public String Hksecret;
+    @Value("${sooka.haikang_video_server.loginPort:}")
+    public String HkloginPort;
+    @Autowired
+    TokenService tokenService;
+    @Autowired
+    private RedisService redisService;
+
+    public void setSookaDataBase(BaseBusinessEntity entity) {
+        entity.setDatabase_system(this.database_system);
+        entity.setDatabase_event(this.database_event);
+        entity.setDatabase_data(this.database_data);
+    }
+
+}
+

+ 19 - 0
src/main/java/com/sooka/sponest/monitor/base/util/database/DynamicDataSource.java

@@ -0,0 +1,19 @@
+package com.sooka.sponest.monitor.base.util.database;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
+
+
+public class DynamicDataSource extends AbstractRoutingDataSource {
+
+    Logger logger = LoggerFactory.getLogger(DynamicDataSource.class);
+
+    @Override
+    protected Object determineCurrentLookupKey() {
+        String datasource = DynamicDataSourceSwitcher.getDataSource();
+        logger.info("------------------当前数据源 {}", DynamicDataSourceSwitcher.getDataSource());
+        return DynamicDataSourceSwitcher.getDataSource();
+    }
+}

+ 41 - 0
src/main/java/com/sooka/sponest/monitor/base/util/database/DynamicDataSourceAspect.java

@@ -0,0 +1,41 @@
+package com.sooka.sponest.monitor.base.util.database;
+
+import org.aspectj.lang.annotation.After;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+@Aspect
+@Component
+@Order(1)
+public class DynamicDataSourceAspect {
+    private Logger logger = LoggerFactory.getLogger(DynamicDataSourceAspect.class);
+
+    /**
+     * 切入点只对@Service注解的类上的@DataSource方法生效
+     *
+     * @param myDataSource
+     */
+    @Pointcut(value = "(@within(org.springframework.stereotype.Service) ||@within(org.springframework.stereotype.Repository)) && @annotation(myDataSource)")
+    public void dynamicDataSourcePointCut(MyDataSource myDataSource) {
+    }
+
+    @Before(value = "dynamicDataSourcePointCut(myDataSource)")
+    public void switchDataSource(MyDataSource myDataSource) {
+        DynamicDataSourceSwitcher.setDataSource(myDataSource.value());
+    }
+
+    /**
+     * 切点执行完后 切换成主数据库
+     *
+     * @param myDataSource
+     */
+    @After(value = "dynamicDataSourcePointCut(myDataSource)")
+    public void after(MyDataSource myDataSource) {
+        DynamicDataSourceSwitcher.cleanDataSource();
+    }
+}

+ 41 - 0
src/main/java/com/sooka/sponest/monitor/base/util/database/DynamicDataSourceSwitcher.java

@@ -0,0 +1,41 @@
+package com.sooka.sponest.monitor.base.util.database;
+
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class DynamicDataSourceSwitcher {
+
+    public static final String Master = "master";
+    public static final String dbCenterTtranmanager = "db-center-tranmanager";
+    public static final String dbCenterData = "db-center-data";
+    public static final String dbCenterEvent = "db-center-event";
+    public static final String dbCenterMonitor = "db-center-monitor";
+    public static final String dbCenterTask = "db-center-task";
+    public static final String dbCenterEvaluation = "db-center-evaluation";
+    public static final String dbCenterFire = "db-center-fire";
+    public static final String dbCenterStraw = "db-center-straw";
+    public static final String dbCenterPests = "db-center-pests";
+    public static final String dbCenterComprehensive = "db-center-comprehensive";
+    public static final String dbCenterOnest = "db-center-onest";
+    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
+    static Logger logger = LoggerFactory.getLogger(DynamicDataSourceSwitcher.class);
+
+    public static String getDataSource() {
+        if (StringUtils.isEmpty(contextHolder.get())) {
+            setDataSource(Master);
+        }
+        return contextHolder.get();
+    }
+
+    public static void setDataSource(String name) {
+        logger.info("-------- 设置数据源数据源为 :{} ", name);
+        contextHolder.set(name);
+    }
+
+    public static void cleanDataSource() {
+        contextHolder.remove();
+    }
+
+}

+ 4 - 0
src/main/java/com/sooka/sponest/monitor/base/util/database/GlobalTransactionalRabbitMQ.java

@@ -0,0 +1,4 @@
+package com.sooka.sponest.monitor.base.util.database;
+
+public @interface GlobalTransactionalRabbitMQ {
+}

+ 136 - 0
src/main/java/com/sooka/sponest/monitor/base/util/database/MultipleDataSourceConfig.java

@@ -0,0 +1,136 @@
+package com.sooka.sponest.monitor.base.util.database;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+
+import javax.sql.DataSource;
+import java.util.HashMap;
+import java.util.Map;
+
+@Configuration
+public class MultipleDataSourceConfig {
+
+    @Bean("master")
+    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.master")
+    public DataSource createMasterDataSource() {
+        return new DruidDataSource();
+    }
+
+    @Bean("dbSystemData")
+    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.db-system")
+    public DataSource createSystemDataSource() {
+        return new DruidDataSource();
+    }
+
+    @Bean("dbCenterTranmanager")
+    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.db-center-tranmanager")
+    public DataSource createTranmanagerDataSource() {
+        return new DruidDataSource();
+    }
+
+    @Bean("dbCenterData")
+    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.db-center-data")
+    public DataSource createDataDataSource() {
+        return new DruidDataSource();
+    }
+
+    @Bean("dbCenterEvent")
+    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.db-center-event")
+    public DataSource createEventDataSource() {
+        return new DruidDataSource();
+    }
+
+    @Bean("dbCenterMonitor")
+    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.db-center-monitor")
+    public DataSource createMonitorDataSource() {
+        return new DruidDataSource();
+    }
+
+    @Bean("dbCenterTask")
+    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.db-center-task")
+    public DataSource createTaskDataSource() {
+        return new DruidDataSource();
+    }
+
+    @Bean("dbCenterEvaluation")
+    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.db-center-evaluation")
+    public DataSource createEvaluationDataSource() {
+        return new DruidDataSource();
+    }
+
+    @Bean("dbCenterFire")
+    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.db-center-fire")
+    public DataSource createFireDataSource() {
+        return new DruidDataSource();
+    }
+
+    @Bean("dbCenterStraw")
+    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.db-center-straw")
+    public DataSource createStrawDataSource() {
+        return new DruidDataSource();
+    }
+
+    @Bean("dbCenterPests")
+    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.db-center-pests")
+    public DataSource createPestsDataSource() {
+        return new DruidDataSource();
+    }
+
+    @Bean("dbCenterComprehensive")
+    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.db-center-comprehensive")
+    public DataSource createComprehensiveDataSource() {
+        return new DruidDataSource();
+    }
+
+    @Bean("dbCenterOnest")
+    @ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.db-center-onest")
+    public DataSource createOnestDataSource() {
+        return new DruidDataSource();
+    }
+
+    /**
+     * 设置动态数据源,通过@Primary 来确定主DataSource
+     *
+     * @return
+     */
+    @Bean
+    @Primary
+    public DataSource createDynamicDataSource(@Qualifier("master") DataSource master,
+                                              @Qualifier("dbSystemData") DataSource dbSystemData,
+                                              @Qualifier("dbCenterData") DataSource dbCenterData,
+                                              @Qualifier("dbCenterEvent") DataSource dbCenterEvent,
+                                              @Qualifier("dbCenterMonitor") DataSource dbCenterMonitor,
+                                              @Qualifier("dbCenterTask") DataSource dbCenterTask,
+                                              @Qualifier("dbCenterEvaluation") DataSource dbCenterEvaluation,
+                                              @Qualifier("dbCenterFire") DataSource dbCenterFire,
+                                              @Qualifier("dbCenterStraw") DataSource dbCenterStraw,
+                                              @Qualifier("dbCenterPests") DataSource dbCenterPests,
+                                              @Qualifier("dbCenterComprehensive") DataSource dbCenterComprehensive,
+                                              @Qualifier("dbCenterOnest") DataSource dbCenterOnest,
+                                              @Qualifier("dbCenterTranmanager") DataSource dbCenterTranmanager) {
+        DynamicDataSource dynamicDataSource = new DynamicDataSource();
+        //设置默认数据源
+        dynamicDataSource.setDefaultTargetDataSource(master);
+        //配置多数据源
+        Map<Object, Object> map = new HashMap<>();
+        map.put("master", master);
+        map.put("db-system", dbSystemData);
+        map.put("db-center-tranmanager", dbCenterTranmanager);
+        map.put("db-center-data", dbCenterData);
+        map.put("db-center-event", dbCenterEvent);
+        map.put("db-center-monitor", dbCenterMonitor);
+        map.put("db-center-task", dbCenterTask);
+        map.put("db-center-evaluation", dbCenterEvaluation);
+        map.put("db-center-fire", dbCenterFire);
+        map.put("db-center-straw", dbCenterStraw);
+        map.put("db-center-pests", dbCenterPests);
+        map.put("db-center-comprehensive", dbCenterComprehensive);
+        map.put("db-center-onest", dbCenterOnest);
+        dynamicDataSource.setTargetDataSources(map);
+        return dynamicDataSource;
+    }
+}

+ 15 - 0
src/main/java/com/sooka/sponest/monitor/base/util/database/MyDataSource.java

@@ -0,0 +1,15 @@
+package com.sooka.sponest.monitor.base.util.database;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({
+        ElementType.METHOD
+})
+public @interface MyDataSource {
+    String value() default "";
+}

+ 258 - 0
src/main/java/com/sooka/sponest/monitor/camera/domain/CentermonitorTCamera.java

@@ -0,0 +1,258 @@
+package com.sooka.sponest.monitor.camera.domain;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.ruoyi.common.core.annotation.Excel;
+import com.ruoyi.common.datascope.base.domain.BaseBusinessEntity;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 摄像头对象 centermonitor_t_camera
+ *
+ * @author ruoyi
+ * @date 2022-06-08
+ */
+@Data
+public class CentermonitorTCamera extends BaseBusinessEntity {
+    private static final long serialVersionUID = 1L;
+
+    public Integer pageNum;
+
+    public Integer pageSize;
+
+    private List<CentermonitorTCamera> list = new ArrayList<>();
+
+    /**
+     * 主键id
+     */
+    private String id;
+    private String type;
+    private String typeName;
+    /**
+     * 数据状态(1-可用 2-不可用 )
+     */
+//    @Excel(name = "数据状态(1-可用 2-不可用 )")
+    private String dataStatus;
+
+    /**
+     * 数据所属部门(政或党的id)
+     */
+//    @Excel(name = "数据所属部门(政或党的id)")
+
+    private Long dataDeptId;
+
+    /**
+     * 摄像头id
+     */
+//    @Excel(name = "摄像头名称")
+    private String cameraId;
+
+    /**
+     * 摄像头名称
+     */
+    @Excel(name = "摄像头名称")
+    private String cameraName;
+
+    /**
+     * ip
+     */
+    @Excel(name = "ip")
+    private String cameraIp;
+
+    /**
+     * 端口
+     */
+    @Excel(name = "端口")
+    private String cameraPort;
+
+    /**
+     * 账号
+     */
+    @Excel(name = "账号")
+    private String cameraAccount;
+
+    /**
+     * 密码
+     */
+    @Excel(name = "密码")
+    private String cameraPasword;
+
+    /**
+     * 摄像头编码
+     */
+    @Excel(name = "摄像头编码")
+    private String cameraCode;
+
+    /**
+     * 摄像头厂家(海康、大华)
+     */
+    @Excel(name = "摄像头厂家(海康、大华)", readConverterExp = "0=海康,1=大华")
+    private String cameraFactory;
+
+    /**
+     * 融合平台(海康、大华)
+     */
+    @Excel(name = "融合平台(海康、大华)", readConverterExp = "0=海康平台,1=大华平台")
+    private String convergencePlatform;
+
+    /**
+     * 所属区域
+     */
+    @Excel(name = "所属区域")
+    private String cameraRegion;
+
+    /**
+     * 半径
+     */
+    @Excel(name = "半径")
+    private String cameraRadius;
+
+    /**
+     * 高度
+     */
+    @Excel(name = "高度")
+    private String height;
+
+    /**
+     * 经度
+     */
+    @Excel(name = "经度")
+    private String longitude;
+
+    /**
+     * 维度
+     */
+    @Excel(name = "纬度")
+    private String latitude;
+
+    /**
+     * 通道编号
+     */
+    private String channelNum;
+
+    /**
+     * 摄像头类型
+     */
+    @Excel(name = "摄像头类型", readConverterExp = "0=枪机,1=球机,2=半球")
+    private String cameraType;
+
+    /**
+     * 运营商类型
+     */
+    @Excel(name = "运营商类型", readConverterExp = "1=联通,2=移动,3=电信")
+    private String operatorType;
+
+    /**
+     * 摄像头用途
+     */
+    @Excel(name = "摄像头用途", readConverterExp = "1=河道,2=高空云台,3=交通,4=矿坑,5=水库")
+    private String cameraUse;
+
+    private String deptId;
+
+    /**
+     * 摄像头距离
+     */
+//    @Excel(name = "摄像头距离")
+    private String distance;
+    /**
+     * 摄像头图片
+     */
+    private String cameraImg;
+
+    @JsonProperty("cameraImages")
+    private List<String> cameraImages;
+
+    private List<String> cameraImagesList;
+
+    private String channelCode;
+    private String deptLongitude;
+    private String deptLatitude;
+
+    private String workingStatus;
+    private String offlineReason;
+    //在线设备
+    private int online;
+    //离线设备
+    private int offline;
+    //摄像头
+    private String camera;
+    //传感器
+    private String device;
+    //县区名称
+    private String qx;
+    //摄像头在线
+    private int camera_online;
+    //摄像头离线
+    private int camera_offline;
+    //传感器在线
+    private int device_online;
+    //传感器离线
+    private int device_offline;
+    //离线设备统计
+    private int device_offline_count;
+    //离线原因
+    private String offline_reason;
+    //离线设备统计
+    private String count;
+    //设备编码(暂用于执法仪)
+    private String deviceCode;
+    //唯一编码,默认为国标编码(暂用于执法仪)
+    private String deviceSn;
+    //接入协议(暂用于执法仪)
+    private String deviceProtocolType;
+    //设备登录类型(暂用于执法仪)
+    private String deviceLoginType;
+
+    @Override
+    public String toString() {
+        return "CentermonitorTCamera{" +
+                "pageNum=" + pageNum +
+                ", pageSize=" + pageSize +
+                ", list=" + list +
+                ", id='" + id + '\'' +
+                ", type='" + type + '\'' +
+                ", typeName='" + typeName + '\'' +
+                ", dataStatus='" + dataStatus + '\'' +
+
+                ", cameraId='" + cameraId + '\'' +
+                ", cameraName='" + cameraName + '\'' +
+                ", cameraIp='" + cameraIp + '\'' +
+                ", cameraPort=" + cameraPort +
+                ", cameraAccount='" + cameraAccount + '\'' +
+                ", cameraPasword='" + cameraPasword + '\'' +
+                ", cameraCode='" + cameraCode + '\'' +
+                ", cameraFactory='" + cameraFactory + '\'' +
+                ", cameraRegion='" + cameraRegion + '\'' +
+                ", cameraRadius='" + cameraRadius + '\'' +
+                ", height='" + height + '\'' +
+                ", longitude='" + longitude + '\'' +
+                ", latitude='" + latitude + '\'' +
+                ", channelNum='" + channelNum + '\'' +
+                ", cameraType='" + cameraType + '\'' +
+                ", operatorType='" + operatorType + '\'' +
+                ", cameraUse='" + cameraUse + '\'' +
+                ", deptId='" + deptId + '\'' +
+                ", distance='" + distance + '\'' +
+                ", channelCode='" + channelCode + '\'' +
+                ", deptLongitude='" + deptLongitude + '\'' +
+                ", deptLatitude='" + deptLatitude + '\'' +
+                ", workingStatus='" + workingStatus + '\'' +
+                ", offlineReason='" + offlineReason + '\'' +
+                ", online=" + online +
+                ", offline=" + offline +
+                ", camera='" + camera + '\'' +
+                ", device='" + device + '\'' +
+                ", qx='" + qx + '\'' +
+                ", camera_online=" + camera_online +
+                ", camera_offline=" + camera_offline +
+                ", device_online=" + device_online +
+                ", device_offline=" + device_offline +
+                ", device_offline_count=" + device_offline_count +
+                ", offline_reason='" + offline_reason + '\'' +
+                ", count='" + count + '\'' +
+                '}';
+    }
+}

+ 32 - 0
src/main/java/com/sooka/sponest/monitor/camera/domain/CentermonitorTCameraImg.java

@@ -0,0 +1,32 @@
+package com.sooka.sponest.monitor.camera.domain;
+
+import lombok.Data;
+
+/**
+ * 摄像头图片 centermonitor_t_camera
+ *
+ * @author ruoyi
+ * @date 2022-06-08
+ */
+@Data
+public class CentermonitorTCameraImg {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键id
+     */
+    public Long id;
+
+    /**
+     * 摄像头图片
+     */
+    public String cameraImg;
+
+    /**
+     * 摄像头id
+     */
+    private String cameraId;
+    private String cameraCode;
+
+    private CentermonitorTCamera camera;
+}

+ 36 - 0
src/main/java/com/sooka/sponest/monitor/camera/mapper/CentermonitorTCameraMapper.java

@@ -0,0 +1,36 @@
+package com.sooka.sponest.monitor.camera.mapper;
+
+import com.sooka.sponest.monitor.camera.domain.CentermonitorTCamera;
+import com.sooka.sponest.monitor.camera.domain.CentermonitorTCameraImg;
+import org.springframework.stereotype.Repository;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * 摄像头Mapper接口
+ *
+ * @author ruoyi
+ * @date 2022-06-08
+ */
+@Repository
+public interface CentermonitorTCameraMapper {
+
+    /**
+     * 查询摄像头
+     *
+     * @param id 摄像头主键
+     * @return 摄像头
+     */
+    CentermonitorTCamera selectCentermonitorTCameraById(String id);
+
+
+    /**
+     * 根据摄像头id查询其id下的摄像头图片
+     */
+    List<CentermonitorTCamera> SelectByIdcreameType(String cameraId);
+
+    ArrayList<CentermonitorTCameraImg> selectCentermonitorTCameraImgByCameraId(String id);
+}
+

+ 29 - 0
src/main/java/com/sooka/sponest/monitor/camera/service/ICentermonitorTCameraService.java

@@ -0,0 +1,29 @@
+package com.sooka.sponest.monitor.camera.service;
+
+import com.sooka.sponest.monitor.camera.domain.CentermonitorTCamera;
+
+
+/**
+ * 摄像头Service接口
+ *
+ * @author ruoyi
+ * @date 2022-06-08
+ */
+public interface ICentermonitorTCameraService {
+
+    /**
+     * 查询摄像头
+     *
+     * @param id 摄像头主键
+     * @return 摄像头
+     */
+    CentermonitorTCamera selectCentermonitorTCameraById(String id);
+
+
+}
+
+
+
+
+
+

+ 58 - 0
src/main/java/com/sooka/sponest/monitor/camera/service/impl/CentermonitorTCameraServiceImpl.java

@@ -0,0 +1,58 @@
+package com.sooka.sponest.monitor.camera.service.impl;
+
+import com.ruoyi.common.core.domain.R;
+import com.sooka.sponest.monitor.base.service.impl.BaseService;
+import com.sooka.sponest.monitor.camera.domain.CentermonitorTCamera;
+import com.sooka.sponest.monitor.camera.domain.CentermonitorTCameraImg;
+import com.sooka.sponest.monitor.camera.mapper.CentermonitorTCameraMapper;
+import com.sooka.sponest.monitor.camera.service.ICentermonitorTCameraService;
+import com.sooka.sponest.monitor.remoteapi.service.system.RemoteService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 摄像头Service业务层处理
+ *
+ * @author ruoyi
+ * @date 2022-06-08
+ */
+@Service
+public class CentermonitorTCameraServiceImpl extends BaseService implements ICentermonitorTCameraService {
+
+    @Resource
+    private CentermonitorTCameraMapper centermonitorTCameraMapper;
+
+    @Resource
+    private RemoteService remoteService;
+
+    /**
+     * 查询摄像头
+     *
+     * @param id 摄像头主键
+     * @return 摄像头
+     */
+    @Override
+    public CentermonitorTCamera selectCentermonitorTCameraById(String id) {
+        /*图片前缀**/
+        List<String> imgList = new ArrayList<>();
+        R<String> url = remoteService.selectConfigKey_fileUrl();
+        CentermonitorTCamera camera = centermonitorTCameraMapper.selectCentermonitorTCameraById(id);
+        camera.setList(centermonitorTCameraMapper.SelectByIdcreameType(id));
+        ArrayList<CentermonitorTCameraImg> cameraImg = centermonitorTCameraMapper.selectCentermonitorTCameraImgByCameraId(id);
+        for (CentermonitorTCameraImg img : cameraImg) {
+            String imgPath = img.getCameraImg();
+            if (imgPath != null && !imgPath.isEmpty()) {
+                img.setCameraImg(url.getData() + imgPath);
+                imgList.add(url.getData() + imgPath);
+            }
+        }
+        camera.setCameraImagesList(imgList);
+        return camera;
+    }
+
+}
+
+

+ 64 - 0
src/main/java/com/sooka/sponest/monitor/dahua/controller/DahuaController.java

@@ -0,0 +1,64 @@
+package com.sooka.sponest.monitor.dahua.controller;
+
+import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.common.core.web.domain.AjaxResult;
+import com.ruoyi.common.log.annotation.Log;
+import com.ruoyi.common.log.enums.BusinessType;
+import com.sooka.sponest.event.download.service.ICentereventTDownloadsService;
+import com.sooka.sponest.monitor.dahua.domain.PlayBackProperties;
+import com.sooka.sponest.monitor.dahua.service.DahuaService;
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.springframework.web.bind.annotation.RequestMethod.POST;
+
+@Api(tags = "大华控制器")
+@RestController
+@RequestMapping("DahuaController")
+@Slf4j
+public class DahuaController {
+
+    @Autowired
+    private DahuaService dahuaService;
+
+    @Autowired
+    private ICentereventTDownloadsService downloadsService;
+
+    /**
+     * 摄像头获取回放
+     *
+     * @return
+     */
+    @Log(title = "大华", businessType = BusinessType.OTHER)
+    @RequestMapping(value = "/getPlaybackByTime", method = POST)
+    public AjaxResult getPlaybackByTime(@RequestBody Map<String, Object> params) {
+        List<PlayBackProperties> list = downloadsService.downloadsCommon(params);
+        return dahuaService.getPlaybackByTime(list);
+    }
+
+    /**
+     * 事件视频下载
+     *
+     * @param id
+     * @return
+     */
+    @Log(title = "事件视频下载", businessType = BusinessType.OTHER)
+    @GetMapping("/eventhandleDownload/{id}")
+    public AjaxResult eventhandleDownload(@PathVariable("id") String id) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("id", id);
+        List<PlayBackProperties> list = downloadsService.downloadsCommon(params);
+        // 校验 已下载不让重复下载
+        if (StringUtils.isEmpty(list)) {
+            return AjaxResult.error("已下载的视频,不能重复下载!");
+        } else {
+            return dahuaService.getPlaybackByTime(list);
+        }
+    }
+}

+ 27 - 0
src/main/java/com/sooka/sponest/monitor/dahua/domain/PlayBackProperties.java

@@ -0,0 +1,27 @@
+package com.sooka.sponest.monitor.dahua.domain;
+
+import lombok.Data;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+public class PlayBackProperties {
+
+    private String eventCode;
+
+    private String eventName;
+
+    private String logId;
+
+    private String cameraId;
+
+    private String startTime;
+
+    private String endTime;
+
+    private String host;
+
+    private String videoDownloadUrlWin;
+
+    private String videoDownloaUrlLinux;
+}

+ 67 - 0
src/main/java/com/sooka/sponest/monitor/dahua/login/Login.java

@@ -0,0 +1,67 @@
+package com.sooka.sponest.monitor.dahua.login;//package com.dahuatch.Login;
+
+
+import com.alibaba.nacos.shaded.com.google.gson.Gson;
+import com.ruoyi.common.core.domain.R;
+import com.sooka.sponest.monitor.dahua.login.bean.LoginFirst;
+import com.sooka.sponest.monitor.dahua.login.bean.LoginSecond;
+import com.sooka.sponest.monitor.dahua.utils.HttpEnum;
+import com.sooka.sponest.monitor.dahua.utils.HttpTestUtils;
+
+import java.util.Map;
+
+/**
+ * 创建会话接口
+ */
+public class Login {
+
+    public static final String ACTION = "/videoService/accounts/authorize";
+
+    //第一次登陆,客户端只传用户名,服务端返回realm、readomKey和encryptType信息。
+    private static String firstLogin(String ip, int port, String userName) {
+        LoginFirst loginFirst = new LoginFirst();
+        loginFirst.setClientType("winpc");
+        loginFirst.setUserName(userName);
+        String rsp = HttpTestUtils.httpRequest(HttpEnum.POST, ip, port, ACTION, "", new Gson().toJson(loginFirst));
+        return rsp;
+    }
+
+    //第二次登录,客户端根据返回的信息,按照指定的加密算法计算签名,再带着用户名和签名登陆一次。
+    private static String secondLogin(String ip, int port, String userName, String password, String realm, String randomKey) throws Exception {
+        LoginSecond snd = new LoginSecond();
+        snd.setUserName(userName);
+        snd.setClientType("winpc");
+        snd.setRandomKey(randomKey);
+        snd.setEncryptType("MD5");
+        String signature = snd.calcSignature(password, realm);
+        snd.setSignature(signature);
+        Gson gson = new Gson();
+        String ctx = gson.toJson(snd);
+        String rsp = HttpTestUtils.httpRequest(HttpEnum.POST, ip, port, ACTION, "", ctx);
+        return rsp;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static String login(String ip, int port, String userName, String password) throws Exception {
+        String response = firstLogin(ip, port, userName);
+        Map<String, String> responseMap = new Gson().fromJson(response, Map.class);
+        String random = responseMap.get("randomKey");
+        String realm = responseMap.get("realm");
+        response = secondLogin(ip, port, userName, password, realm, random);
+        return response;
+    }
+
+
+    /**
+     * 调用该登陆方法之前需要修改 baseinfo.properties中ip,port,name,password为当前对接环境
+     * 登录的方法,运行之后即可获取到token,进行登录,登陆完成后,必须调用KeepLogin保活接口,否则,2分钟后会登陆过期
+     */
+    public static void main(String[] args) throws Exception {
+        R<?> result = HttpTestUtils.getToken("10.254.1.20", Integer.valueOf(8320), "system", "Admin123");
+        String token = result.getData().toString();
+        System.out.println("登录成功,token=" + token);
+    }
+}
+
+
+

+ 36 - 0
src/main/java/com/sooka/sponest/monitor/dahua/login/bean/LoginFirst.java

@@ -0,0 +1,36 @@
+package com.sooka.sponest.monitor.dahua.login.bean;//package com.dahuatch.Login;
+
+/**
+ * 第一次登录参数bean
+ */
+public class LoginFirst {
+
+    private String userName;
+    private String clientType;
+    private String ipAddress;
+
+
+    public String getUserName() {
+        return userName;
+    }
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+    public String getClientType() {
+        return clientType;
+    }
+    public void setClientType(String clientType) {
+        this.clientType = clientType;
+    }
+    public String getIpAddress() {
+        return ipAddress;
+    }
+    public void setIpAddress(String ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+    @Override
+    public String toString() {
+
+        return "[userName=" + userName + ",clientType=" + clientType + ",ipAddress=" + ipAddress + "]";
+    }
+}

+ 102 - 0
src/main/java/com/sooka/sponest/monitor/dahua/login/bean/LoginSecond.java

@@ -0,0 +1,102 @@
+package com.sooka.sponest.monitor.dahua.login.bean;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * 第二次登录参数bean和方法
+ */
+public class LoginSecond {
+    private String userName;
+    private String clientType;
+    private String ipAddress;
+	private String signature;
+	private String randomKey;
+	private String encryptType;
+
+    public String getUserName() {
+        return userName;
+    }
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+    public String getClientType() {
+        return clientType;
+    }
+    public void setClientType(String clientType) {
+        this.clientType = clientType;
+    }
+    public String getIpAddress() {
+        return ipAddress;
+    }
+    public void setIpAddress(String ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+    public String getSignature() {
+        return signature;
+    }
+    public void setSignature(String signature) {
+        this.signature = signature;
+    }
+    public String getRandomKey() {
+        return randomKey;
+    }
+    public void setRandomKey(String randomKey) {
+        this.randomKey = randomKey;
+    }
+    public String getEncryptType() {
+        return encryptType;
+    }
+    public String setEncryptType(String encryptType) {
+        return this.encryptType = encryptType;
+    }
+
+	public static boolean isBlankString(String str) {
+		if (str == null || str == "" || str.length() == 0) {
+			return true;
+		}
+		return false;
+	}
+
+	public static String encrypt(String inputText, String algorithmName) throws Exception {
+		if (isBlankString(inputText)) {
+			throw new IllegalArgumentException("Please enter inputText!");
+		}
+		if (isBlankString(algorithmName)
+				|| algorithmName.toLowerCase().equals("md5")) {
+			algorithmName = "MD5";
+		}
+		try {
+			MessageDigest digest = MessageDigest.getInstance(algorithmName);
+			digest.update(inputText.getBytes("UTF8"));
+			byte encryptted[] = digest.digest();
+			int i;
+			StringBuffer rsp = new StringBuffer();
+			for (int offset = 0; offset < encryptted.length; offset++) {
+				i = encryptted[offset];
+				if (i < 0)
+					i += 256;
+				if (i < 16)
+					rsp.append("0");
+				rsp.append(Integer.toHexString(i));
+			}
+			return rsp.toString();
+		} catch (NoSuchAlgorithmException e) {
+			throw e;
+		} catch (UnsupportedEncodingException e) {
+			throw e;
+		}
+	}
+	//根据第一次登录接口调用返回的参数,计算签名,第二次登录接口调用要使用到,本例采用的是MD5的加密方式,可以根据需要采用别的加密方式
+	public String calcSignature(String password, String realm) throws Exception{
+		String signature = encrypt(password, "MD5");
+		signature = encrypt(this.userName+signature, "MD5");
+		signature = encrypt(signature, "MD5");
+		signature = encrypt(this.userName+":"+realm+":"+signature, "MD5");
+		signature = encrypt(signature+":"+this.randomKey, "MD5");
+		return signature;
+	}
+
+}
+

+ 33 - 0
src/main/java/com/sooka/sponest/monitor/dahua/service/DahuaService.java

@@ -0,0 +1,33 @@
+package com.sooka.sponest.monitor.dahua.service;
+
+
+import com.dahuatech.hutool.http.Method;
+import com.dahuatech.hutool.json.JSONObject;
+import com.ruoyi.common.core.web.domain.AjaxResult;
+import com.sooka.sponest.monitor.dahua.domain.PlayBackProperties;
+
+import java.util.List;
+
+
+public interface DahuaService {
+
+    /**
+     * 摄像头获取回放
+     * @return
+     */
+    AjaxResult getPlaybackByTime(List<PlayBackProperties> propertiesList);
+
+    Long getTimeSeconds(String time);
+
+    /**
+     * 获取token方法
+     * 调用此方法以获取token
+     * */
+    String getToken();
+
+    JSONObject IccHttpHttpRequest(String url, Method method, String param, String token, String action);
+
+    boolean isWindows();
+
+    String secondsToFormat(Long seconds);
+}

+ 287 - 0
src/main/java/com/sooka/sponest/monitor/dahua/service/impl/DahuaServiceImpl.java

@@ -0,0 +1,287 @@
+package com.sooka.sponest.monitor.dahua.service.impl;
+
+import com.dahuatech.hutool.core.io.FileUtil;
+import com.dahuatech.hutool.core.io.StreamProgress;
+import com.dahuatech.hutool.http.HttpUtil;
+import com.dahuatech.hutool.http.Method;
+import com.dahuatech.hutool.json.JSONArray;
+import com.dahuatech.hutool.json.JSONObject;
+import com.dahuatech.hutool.json.JSONUtil;
+import com.dahuatech.icc.exception.ClientException;
+import com.dahuatech.icc.oauth.http.IccHttpHttpRequest;
+import com.dahuatech.icc.oauth.http.IccTokenResponse;
+import com.dahuatech.icc.util.BeanUtil;
+import com.ruoyi.common.core.constant.HttpStatus;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.utils.uuid.IdUtils;
+import com.ruoyi.common.core.web.domain.AjaxResult;
+import com.ruoyi.common.redis.service.RedisService;
+import com.ruoyi.system.api.domain.SysFile;
+import com.sooka.sponest.data.attach.domain.CenterdataTAttach;
+import com.sooka.sponest.data.attach.service.ICenterdataTAttachService;
+import com.sooka.sponest.event.download.domain.CentereventTDownloads;
+import com.sooka.sponest.event.download.service.ICentereventTDownloadsService;
+import com.sooka.sponest.monitor.base.service.impl.BaseService;
+import com.sooka.sponest.monitor.camera.domain.CentermonitorTCamera;
+import com.sooka.sponest.monitor.camera.service.ICentermonitorTCameraService;
+import com.sooka.sponest.monitor.dahua.domain.PlayBackProperties;
+import com.sooka.sponest.monitor.dahua.service.DahuaService;
+import com.sooka.sponest.monitor.remoteapi.service.file.RemoteFileBaseService;
+import com.sooka.sponest.monitor.util.Mp4ParserUtils;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+@Service
+public class DahuaServiceImpl extends BaseService implements DahuaService {
+
+    private static org.slf4j.Logger log = LoggerFactory.getLogger(DahuaServiceImpl.class);
+
+
+    @Resource
+    private RedisService redisService;
+
+    @Resource
+    private ICentermonitorTCameraService iCentermonitorTCameraService;
+
+    @Resource
+    private DahuaService dahuaService;
+
+    @Resource
+    private RemoteFileBaseService fileBaseService;
+
+    @Resource
+    private ICenterdataTAttachService attachService;
+
+    @Resource
+    private ICentereventTDownloadsService downloadsService;
+
+
+
+    public AjaxResult getPlaybackByTime(List<PlayBackProperties> propertiesList) {
+        log.info("**GetPlaybackByTime->"+new Date()+"->start**");
+        for (PlayBackProperties property: propertiesList) {
+            //下载并上传视频
+            AjaxResult ajaxResult = getPlaybackByTime(property);
+            //将视频下载结果保存至事件中心
+            CentereventTDownloads downloads = new CentereventTDownloads();
+            downloads.setId(IdUtils.simpleUUID());
+            downloads.setEventCode(property.getEventCode());
+            downloads.setEventName(property.getEventName());
+            downloads.setLogId(property.getLogId());
+            if (Integer.parseInt(ajaxResult.get("code").toString()) == HttpStatus.SUCCESS) {
+                downloads.setPath(ajaxResult.get("data").toString());
+            }
+            downloads.setFlag(ajaxResult.get("code").toString());
+            downloads.setReason(ajaxResult.get("msg").toString());
+            downloadsService.insertCentereventTDownloads(downloads);
+        }
+        log.info("**GetPlaybackByTime->"+new Date()+"->end**");
+        return AjaxResult.success();
+    }
+
+    public AjaxResult getPlaybackByTime(PlayBackProperties playBackProperties) {
+        AjaxResult ajaxResult = new AjaxResult();
+        CentermonitorTCamera camera = iCentermonitorTCameraService.selectCentermonitorTCameraById(playBackProperties.getCameraId());
+        if (camera == null) {
+            return new AjaxResult(HttpStatus.ACCEPTED, "未查询到该摄像头");
+        } else if (camera.getChannelNum().isEmpty()) {
+            return new AjaxResult(HttpStatus.ACCEPTED, "未查询到该摄像头通道编号");
+        }
+        //开始时间
+        Long startTimeStamp = dahuaService.getTimeSeconds(playBackProperties.getStartTime());
+        //结束时间
+        Long endTimeStamp = dahuaService.getTimeSeconds(playBackProperties.getEndTime());
+        //录像请求地址
+        String QUERY_RECORDS_URL = host + "/evo-apigw/admin/API/SS/Record/QueryRecords";
+        //获取大华token
+        String token = dahuaService.getToken();
+        //构造请求参数
+        Map<String, Object> param = new HashMap<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put("channelId", camera.getChannelNum());
+        data.put("recordSource", "3");
+        data.put("startTime", startTimeStamp);
+        data.put("endTime", endTimeStamp);
+        data.put("recordType", "0");
+        data.put("streamType", "1");
+        param.put("data", data);
+        //请求大华服务器查询录像
+        log.info("getPlaybackByTime-查询大华录像、");
+        JSONObject QueryRecordsResult = dahuaService.IccHttpHttpRequest(QUERY_RECORDS_URL, Method.POST, JSONUtil.toJsonStr(param), token, "QueryRecords");
+        //处理返回值
+        if (QueryRecordsResult.get("code") != null && QueryRecordsResult.get("code").toString().equals("1000")) {
+            //未查询到录像
+            if (QueryRecordsResult.getJSONObject("data") != null && QueryRecordsResult.getJSONObject("data").getJSONArray("records").isEmpty()) {
+                log.info("getPlaybackByTime-查询大华录像-result => {}", "该时段未查询到录像信息");
+                return new AjaxResult(HttpStatus.ACCEPTED, "该时段未查询到录像信息");
+                //查询到路线
+            } else {
+                List<String> fileNames = new ArrayList<>();
+                String dssFileDownloadUrl = dahuaService.isWindows() ? videoDownloadUrlWin : videoDownloadUrlLinux;
+                JSONArray records = QueryRecordsResult.getJSONObject("data").getJSONArray("records");
+                for (Object record : records) {
+                    JSONObject jsonObject = JSONUtil.parseObj(record);
+                    String url = host + "/download/vod/cam/download.mp4";
+                    url += "?vcuid=" + camera.getChannelNum().split("\\$")[0] + "%240";
+                    url += "&subtype=1";
+                    url += "&starttime=" + dahuaService.secondsToFormat(Long.parseLong(jsonObject.getStr("startTime")));
+                    url += "&endtime=" + dahuaService.secondsToFormat(Long.parseLong(jsonObject.getStr("endTime")));
+                    url += "&videoType=3";//videoType 2:设备录像 3:平台录像
+                    url += "&substream=1";//substream 码流类型:1:主码流;2:辅码流
+                    url += "&token=1:" + token;
+                    url += "&recordType=1";
+                    String fileName = dssFileDownloadUrl + System.currentTimeMillis() + ".mp4";
+                    //下载 录像
+                    HttpUtil.downloadFile(url, FileUtil.file(fileName), new StreamProgress() {
+                        @Override
+                        public void start() {
+                            log.info("getPlaybackByTime logId={} => 开始下载", playBackProperties.getLogId());
+                        }
+
+                        @Override
+                        public void progress(long progressSize) {
+//                        log.info("getPlaybackByTime => 已下载:{}", FileUtil.readableFileSize(progressSize));
+                        }
+
+                        @Override
+                        public void finish() {
+                            log.info("getPlaybackByTime logId={} => 下载完成!", playBackProperties.getLogId());
+                            fileNames.add(fileName);
+
+                        }
+                    });
+                }
+                File file;
+                //如果有多个视频 则合并视频并上传合并后的视频
+                if (fileNames.size() > 1) {
+                    //合并本地下载的视频
+                    String fileName = dssFileDownloadUrl + System.currentTimeMillis() + ".mp4";
+                    file = new File(fileName);
+                    Mp4ParserUtils.mergeVideo(fileNames, file);
+                } else {
+                    file = new File(fileNames.get(0));
+                }
+                //文件上传到文件服务器
+                R<SysFile> sysFileR = fileBaseService.upload(Mp4ParserUtils.getMultipartFile(file));
+                if (sysFileR.getCode() == 200) {
+                    log.info("getPlaybackByTime => 文件上传成功!{}", sysFileR.getData().getUrl());
+                    //保存到数据中心
+                    CenterdataTAttach attach = new CenterdataTAttach();
+                    attach.setBusId(playBackProperties.getLogId());
+                    attach.setAttachPath(sysFileR.getData().getUrl());
+                    attach.setFileName(sysFileR.getData().getName());
+                    attach.setBusSource("PC");
+                    attach.setFileType("video");
+                    attachService.insertCenterdataTAttach(attach);
+                    //清空文件夹
+                    File folder = new File(dssFileDownloadUrl);
+                    File[] files = folder.listFiles();
+                    if (files != null){
+                        for (File f : files) {
+                            boolean b = f.delete();
+                            if(!b) log.error("getPlaybackByTime => 文件删除失败!");
+                        }
+                    }
+                } else {
+                    log.info("getPlaybackByTime => 文件上传失败!{}", sysFileR.getMsg());
+                }
+                return AjaxResult.success("文件下载成功", sysFileR.getData().getUrl());
+            }
+        }else {
+            log.error("getPlaybackByTime-查询大华录像-{}, result => {}", "录像回放接口报错", JSONUtil.toJsonStr(QueryRecordsResult));
+            return AjaxResult.error("录像回放接口报错", QueryRecordsResult.getStr("desc"));
+        }
+    }
+
+
+    public Long getTimeSeconds(String time) {
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        long timeStamp = 0;
+        try {
+            Date date = simpleDateFormat.parse(time);
+            timeStamp = date.getTime() / 1000L;
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return timeStamp;
+    }
+
+    /**
+     * 获取token
+     */
+    public String getToken() {
+        //如果缓存里有 用缓存的,没有就重新获取
+        String token = redisService.getCacheObject("DH_TOKEN");
+        if (token != null) {
+            return token;
+        }
+        String TOKEN_URL = host + "/evo-apigw/evo-oauth/" + version + "/oauth/extend/token";
+        try {
+            log.info("----开始执行----{}------请求地址:{}", "客户端模式_认证申请", TOKEN_URL);
+            Map<String, Object> map = new HashMap();
+            map.put("grant_type", "client_credentials");
+            map.put("client_id", client_id);
+            map.put("client_secret", client_secret);
+            IccHttpHttpRequest pr = new IccHttpHttpRequest(TOKEN_URL, Method.POST, JSONUtil.toJsonStr(map));
+            String prBody = pr.execute();
+            IccTokenResponse keyResp = BeanUtil.toBean(prBody, IccTokenResponse.class);
+            log.info("----结束执行----{}------返回报文:{}", "客户端模式_认证申请", keyResp);
+            token = keyResp.getData().getAccess_token();
+            redisService.setCacheObject("DH_TOKEN", token);
+            //token 有效期1小时59分
+            redisService.expire("DH_TOKEN", 60 * 60 * 2 - 60);
+            return token;
+        } catch (Exception e) {
+            return token;
+        }
+    }
+
+    public JSONObject IccHttpHttpRequest(String url, Method method, String param, String token, String action) {
+        log.info("----开始执行----{}------请求参数:{}", action, JSONUtil.toJsonStr(param));
+        String prBody;
+        IccHttpHttpRequest pr;
+        try {
+            pr = new IccHttpHttpRequest(url, method, param);
+        } catch (ClientException e) {
+            throw new RuntimeException(e);
+        }
+        pr.getHttpRequest().header("Authorization", "bearer " + token).header("User-Id", "1");
+        prBody = pr.execute();
+        log.info("----结束执行----{}------返回报文:{}", action, prBody);
+        JSONObject result = JSONUtil.parseObj(prBody);
+        return result;
+    }
+
+    /**
+     * 判断操作系统是否是 Windows
+     *
+     * @return true:操作系统是 Windows
+     * false:其它操作系统
+     */
+    public boolean isWindows() {
+        String osName = getOsName();
+        return osName != null && osName.startsWith("Windows");
+    }
+
+    /**
+     * 获取操作系统名称
+     *
+     * @return os.name 属性值
+     */
+    public static String getOsName() {
+        return System.getProperty("os.name");
+    }
+
+    public String secondsToFormat(Long seconds) {
+        Date d = new Date();
+        d.setTime(seconds * 1000);
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy_M_d_HH_mm_ss");
+        return simpleDateFormat.format(d);
+    }
+}

File diff suppressed because it is too large
+ 96 - 0
src/main/java/com/sooka/sponest/monitor/dahua/utils/DSSUtils.java


+ 26 - 0
src/main/java/com/sooka/sponest/monitor/dahua/utils/HttpEnum.java

@@ -0,0 +1,26 @@
+package com.sooka.sponest.monitor.dahua.utils;
+/**
+ * 请求类型枚举
+ */
+public enum HttpEnum {
+    GET(1,"get"),
+    POST(2,"post"),
+    PUT(3,"put"),
+    DELETE(4,"delete");
+    private int num;
+    private String desc;
+
+
+    HttpEnum(int num, String desc) {
+        this.num = num;
+        this.desc = desc;
+    }
+    public int getNum() {
+        return num;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+}

+ 195 - 0
src/main/java/com/sooka/sponest/monitor/dahua/utils/HttpTestUtils.java

@@ -0,0 +1,195 @@
+package com.sooka.sponest.monitor.dahua.utils;
+
+
+import com.alibaba.nacos.shaded.com.google.gson.Gson;
+import com.ruoyi.common.core.domain.R;
+import com.sooka.sponest.monitor.dahua.login.Login;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.client.methods.*;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.X509HostnameVerifier;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.ssl.SSLContexts;
+import org.apache.http.ssl.TrustStrategy;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import java.io.*;
+import java.security.KeyStore;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Map;
+/**
+ * 远程调用请求工具
+ */
+@Slf4j
+public class HttpTestUtils {
+    public static String httpRequest(HttpEnum method, String ip, int port, String action, String token, String content) {
+        String responJson = null;
+        CloseableHttpClient httpClient = null;
+        CloseableHttpResponse httpResponse = null;
+        InputStream inputStream = null;
+        KeyStore trustStore = null;
+        SSLContext sslcontext = null;
+        try {
+            trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
+            // 设置信任签名
+            sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustStrategy() {
+                @Override
+                public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
+                    return true;
+                }
+            }).build();
+            X509HostnameVerifier hostnameVerifier = new X509HostnameVerifier() {
+                @Override
+                public void verify(String s, SSLSocket sslSocket) throws IOException {
+
+                }
+
+                @Override
+                public void verify(String s, X509Certificate x509Certificate) throws SSLException {
+
+                }
+
+                @Override
+                public void verify(String s, String[] strings, String[] strings1) throws SSLException {
+
+                }
+
+                @Override
+                public boolean verify(String s, SSLSession sslSession) {
+                    return true;
+                }
+            };
+            // 设置协议http和https对应的处理socket链接工厂的对象
+            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
+                    .register("http", PlainConnectionSocketFactory.INSTANCE)
+                    .register("https", new SSLConnectionSocketFactory(sslcontext, hostnameVerifier))
+                    .build();
+
+            PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
+
+            httpClient = HttpClientBuilder.create()
+                    .setConnectionManager(connectionManager)
+                    .setRedirectStrategy(new RestRedirectStrategy()).build();
+            String proto = port == 8320 ? "https://" : "http://";
+            String uri = proto + ip + ":" + port + action;
+            HttpRequestBase httpReq = getRequestEntity(method, token, uri, content);
+            httpResponse = httpClient.execute(httpReq);
+            inputStream = httpResponse.getEntity().getContent();
+            responJson = convertToString(inputStream);
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (null != httpResponse) {
+                try {
+                    httpResponse.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (null != httpClient) {
+                try {
+                    httpClient.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return responJson;
+    }
+
+    private static HttpRequestBase getRequestEntity(HttpEnum method, String token, String uri, String content) throws UnsupportedEncodingException {
+        switch (method.getNum()) {
+            case 1:
+                HttpGet httpGet = new HttpGet(uri + content);
+                httpGet.addHeader("Content-type", "application/json");
+                httpGet.addHeader("X-Subject-Token", token);
+                return httpGet;
+            case 2:
+                HttpPost httpPost = new HttpPost(uri);
+                httpPost.addHeader("Content-type", "application/json");
+                httpPost.addHeader("X-Subject-Token", token);
+                httpPost.setEntity(new StringEntity(content, "UTF-8"));
+                return httpPost;
+            case 3:
+                HttpPut httpPut = new HttpPut(uri);
+                httpPut.addHeader("Content-type", "application/json");
+                httpPut.addHeader("X-Subject-Token", token);
+                httpPut.setEntity(new StringEntity(content, "UTF-8"));
+                return httpPut;
+            case 4:
+                HttpDelete httpDelete = new HttpDelete(uri + content);
+                httpDelete.addHeader("Content-type", "application/json");
+                httpDelete.addHeader("X-Subject-Token", token);
+                return httpDelete;
+            default:
+                System.out.println("请求方法不对");
+        }
+        return null;
+    }
+
+    private static String convertToString(InputStream is) {
+        if (is == null) {
+            return null;
+        }
+        BufferedReader bf = null;
+        try {
+            StringBuilder sb = new StringBuilder();
+            String temp = "";
+            bf = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+            while ((temp = bf.readLine()) != null) {
+                sb.append(temp);
+            }
+            return sb.toString();
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        } finally {
+            closeStream(bf);
+            closeStream(is);
+        }
+    }
+
+    private static void closeStream(Closeable closeable) {
+        if (null != closeable) {
+            try {
+                closeable.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public static R<?> getToken(String ip, int port, String userName, String password) throws Exception {
+        String response = "";
+        String token = "";
+        response = Login.login(ip, port, userName, password);
+        Map<String, Object> rsp = new Gson().fromJson(response, Map.class);
+        String message = (String) rsp.get("message");
+        if (message != null && !"".equals(message)) {
+            System.out.println(message);
+            log.info("获取token信息:{}",message);
+            return R.fail("用户名或密码错误,未获取到token");
+        }
+        token = (String) rsp.get("token");
+        if (token == null || "".equals(token)) {
+            System.out.println("获取到的token为空");
+            log.info("获取token:{}",message);
+            return R.fail("获取到的token为空");
+        }
+        return R.ok(token);
+    }
+
+}

+ 25 - 0
src/main/java/com/sooka/sponest/monitor/dahua/utils/ImgUtils.java

@@ -0,0 +1,25 @@
+package com.sooka.sponest.monitor.dahua.utils;
+
+/******************************
+ *
+ * @author yanhongliang
+ * @date 2022-06-20 10:22 AM
+ ******************************/
+
+public class ImgUtils {
+
+
+    public static String[] getImgUrl(String... path) {
+
+        String[] url = {};
+
+        for (int i = 0; i < path.length; i++) {
+            url[i] =  "https//192.168.100.2:8443/evo-pic/" + path + "?token=" + DSSUtils.getToken();
+        }
+
+        return url;
+
+    }
+
+
+}

+ 70 - 0
src/main/java/com/sooka/sponest/monitor/dahua/utils/RestRedirectStrategy.java

@@ -0,0 +1,70 @@
+package com.sooka.sponest.monitor.dahua.utils;
+
+import org.apache.http.*;
+import org.apache.http.annotation.Contract;
+import org.apache.http.annotation.ThreadingBehavior;
+import org.apache.http.client.methods.*;
+import org.apache.http.impl.client.DefaultRedirectStrategy;
+import org.apache.http.protocol.HttpContext;
+
+import java.net.URI;
+
+/**
+ * 功能简介:重定向策略,GET/POST/PUT/DELTE 都支持重定向
+ * 功能详解:
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE)
+public class RestRedirectStrategy extends DefaultRedirectStrategy {
+
+    /**
+     * Redirect methods
+     */
+    private static final String[] REDIRECT_METHODS = new String[]{
+            HttpGet.METHOD_NAME,
+            HttpPut.METHOD_NAME,
+            HttpDelete.METHOD_NAME,
+            HttpPost.METHOD_NAME
+    };
+
+    @Override
+    protected boolean isRedirectable(final String method) {
+        for (final String m : REDIRECT_METHODS) {
+            if (m.equalsIgnoreCase(method)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public HttpUriRequest getRedirect(final HttpRequest request, final HttpResponse response, final HttpContext context) throws ProtocolException {
+        final URI uri = getLocationURI(request, response, context);
+        final String method = request.getRequestLine().getMethod();
+        if (method.equalsIgnoreCase(HttpGet.METHOD_NAME)) {
+            return new HttpGet(uri);
+        } else if (method.equalsIgnoreCase(HttpPost.METHOD_NAME)) {
+            HttpPost post = new HttpPost(uri);
+            if (request instanceof HttpEntityEnclosingRequest) {
+                HttpEntity oldEntity = ((HttpEntityEnclosingRequest) request).getEntity();
+                post.setEntity(oldEntity);
+            }
+            return post;
+        } else if (method.equalsIgnoreCase(HttpPut.METHOD_NAME)) {
+            HttpPut put = new HttpPut(uri);
+            if (request instanceof HttpEntityEnclosingRequest) {
+                HttpEntity oldEntity = ((HttpEntityEnclosingRequest) request).getEntity();
+                put.setEntity(oldEntity);
+            }
+            return put;
+        } else if (method.equalsIgnoreCase(HttpDelete.METHOD_NAME)) {
+            return new HttpDelete(uri);
+        } else {
+            final int status = response.getStatusLine().getStatusCode();
+            if (status == HttpStatus.SC_TEMPORARY_REDIRECT) {
+                return RequestBuilder.copy(request).setUri(uri).build();
+            } else {
+                return new HttpGet(uri);
+            }
+        }
+    }
+}

+ 35 - 0
src/main/java/com/sooka/sponest/monitor/feign/CenterMonitorFeignController.java

@@ -0,0 +1,35 @@
+package com.sooka.sponest.monitor.feign;
+
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.log.annotation.Log;
+import com.ruoyi.common.log.enums.BusinessType;
+import com.ruoyi.system.api.domain.SysFile;
+import com.sooka.sponest.monitor.remoteapi.service.file.RemoteFileBaseService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 监控中心远程接口控制器
+ */
+@Api(tags = "监控中心远程接口控制器")
+@RestController
+@RequestMapping("/centerMonitorFeign")
+public class CenterMonitorFeignController {
+
+    @Autowired
+    private RemoteFileBaseService remoteFileBaseService;
+
+    /**
+     * 病虫害文件上传
+     */
+    @Log(title = "监控中心", businessType = BusinessType.OTHER)
+    @PostMapping ("/upload")
+    public R<SysFile> upload(MultipartFile file) {
+        return remoteFileBaseService.upload(file);
+
+    }
+}

+ 22 - 0
src/main/java/com/sooka/sponest/monitor/remoteapi/EnableSookaFeignClients.java

@@ -0,0 +1,22 @@
+package com.sooka.sponest.monitor.remoteapi;
+
+import org.springframework.cloud.openfeign.EnableFeignClients;
+
+import java.lang.annotation.*;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@EnableFeignClients
+public @interface EnableSookaFeignClients {
+
+    String[] value() default {};
+
+    String[] basePackages() default {"com.ruoyi", "com.sooka" };
+
+    Class<?>[] basePackageClasses() default {};
+
+    Class<?>[] defaultConfiguration() default {};
+
+    Class<?>[] clients() default {};
+}

+ 4 - 0
src/main/java/com/sooka/sponest/monitor/remoteapi/RemoveApiBaseService.java

@@ -0,0 +1,4 @@
+package com.sooka.sponest.monitor.remoteapi;
+
+public interface RemoveApiBaseService {
+}

+ 16 - 0
src/main/java/com/sooka/sponest/monitor/remoteapi/fallback/file/RemoteFileServiceFallbackFactory.java

@@ -0,0 +1,16 @@
+package com.sooka.sponest.monitor.remoteapi.fallback.file;
+
+
+import com.sooka.sponest.monitor.remoteapi.service.file.RemoteFileBaseService;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class RemoteFileServiceFallbackFactory implements FallbackFactory<RemoteFileBaseService> {
+
+    @Override
+    public RemoteFileBaseService create(Throwable cause) {
+        System.out.println("文件服务中心 remote service error!!!");
+        return null;
+    }
+}

+ 47 - 0
src/main/java/com/sooka/sponest/monitor/remoteapi/fallback/system/RemoteSystemBaseServiceFallbackFactory.java

@@ -0,0 +1,47 @@
+package com.sooka.sponest.monitor.remoteapi.fallback.system;
+
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.system.api.domain.SysDept;
+import com.ruoyi.system.api.factory.RemoteUserFallbackFactory;
+import com.sooka.sponest.monitor.remoteapi.service.system.RemoteService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * @program: ruoyi
+ * @description: yy
+ * @author: yy
+ * @create: 2022-06-16 11:05
+ **/
+@Component
+public class RemoteSystemBaseServiceFallbackFactory implements FallbackFactory<RemoteService> {
+
+    private static final Logger log = LoggerFactory.getLogger(RemoteUserFallbackFactory.class);
+
+    @Override
+    public RemoteService create(Throwable cause) {
+        log.error("消息中心-服务调用失败:{}", cause.getMessage());
+
+        return new RemoteService() {
+
+            /**
+             * 根据用户名查询dept_id, parent_id, ancestors, dept_name
+             */
+            @Override
+            public R<SysDept> findDeptIdByUserName(String userName) {
+                return null;
+            }
+
+            /**
+             * 获取参数配置_文件地址
+             */
+            @Override
+            public R<String> selectConfigKey_fileUrl() {
+                return null;
+            }
+
+        };
+    }
+}

+ 51 - 0
src/main/java/com/sooka/sponest/monitor/remoteapi/service/ModulesServiceNameContants.java

@@ -0,0 +1,51 @@
+package com.sooka.sponest.monitor.remoteapi.service;
+
+import com.ruoyi.common.core.constant.ServiceNameConstants;
+
+public class ModulesServiceNameContants extends ServiceNameConstants {
+
+    //综合治理中心中心
+   public static final String CENTER_COMPREHENSIVE = "sooka-sponest-center-comprehensive";
+
+   //数据中心
+   public static final String CENTER_DATA = "sooka-sponest-center-data";
+
+   //测评中心
+   public static final String CENTER_EVALUATION = "sooka-sponest-center-evaluation";
+
+    //事件中心
+    public static final String CENTER_EVENT = "sooka-sponest-center-event";
+
+    //森林防火中心
+    public static final String CENTER_FIRE = "sooka-sponest-center-fire";
+
+    //监控中心
+    public static final String CENTER_MONITOR = "sooka-sponest-center-monitor";
+
+    //一体化平台
+    public static final String CENTER_ONEST = "sooka-sponest-center-onest";
+
+    //病虫灾害中心
+    public static final String CENTER_PESTS = "sooka-sponest-center-pests";
+
+    //秸秆禁烧中心
+    public static final String CENTER_STRAW = "sooka-sponest-center-straw";
+
+    //任务中心
+    public static final String CENTER_TASK = "sooka-sponest-center-task";
+
+    //运管中心
+    public static final String CENTER_TRANMANAGER = "sooka-sponest-center-tranmanager";
+    //文件中心
+    public static final String CENTER_FILE = "sooka-sponest-file";
+    /**
+     * 系统模块的serviceid
+     */
+    public static final String SYSTEM_SERVICE = "sooka-sponest-system";
+
+    public static final String MIDDLE_GROUND_SERVICE = "sooka-middleGround";
+
+    //执法
+    public static final String CENTER_LAWENFORCEMENT = "sooka-sponest-lawenforcement";
+
+}

+ 22 - 0
src/main/java/com/sooka/sponest/monitor/remoteapi/service/file/RemoteFileBaseService.java

@@ -0,0 +1,22 @@
+package com.sooka.sponest.monitor.remoteapi.service.file;
+
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.system.api.domain.SysFile;
+import com.sooka.sponest.monitor.remoteapi.fallback.file.RemoteFileServiceFallbackFactory;
+import com.sooka.sponest.monitor.remoteapi.service.ModulesServiceNameContants;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.multipart.MultipartFile;
+
+@FeignClient(contextId = "remoteFileBaseService", value = ModulesServiceNameContants.CENTER_FILE,
+        fallbackFactory = RemoteFileServiceFallbackFactory.class)
+public interface RemoteFileBaseService {
+
+    /**
+     * 文件上传请求
+     */
+    @PostMapping(value = "/upload", headers = "content-type=" + MediaType.MULTIPART_FORM_DATA_VALUE)
+    R<SysFile> upload(@RequestPart("file") MultipartFile file);
+}

+ 26 - 0
src/main/java/com/sooka/sponest/monitor/remoteapi/service/system/RemoteService.java

@@ -0,0 +1,26 @@
+package com.sooka.sponest.monitor.remoteapi.service.system;
+
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.system.api.domain.SysDept;
+import com.sooka.sponest.monitor.remoteapi.fallback.system.RemoteSystemBaseServiceFallbackFactory;
+import com.sooka.sponest.monitor.remoteapi.service.ModulesServiceNameContants;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+
+@FeignClient(contextId = "remoteService", fallbackFactory = RemoteSystemBaseServiceFallbackFactory.class,value = ModulesServiceNameContants.SYSTEM_SERVICE)
+public interface RemoteService {
+
+    /**
+     * 根据用户名查询dept_id, parent_id, ancestors, dept_name
+     */
+    @GetMapping(value = "/dept/findDeptIdByUserName/{userName}")
+    R<SysDept> findDeptIdByUserName(@PathVariable("userName") String userName);
+
+    /**
+     * 获取参数配置_文件地址
+     */
+    @GetMapping("/config/selectConfigKey/fileUrl")
+    public R<String> selectConfigKey_fileUrl();
+
+}

+ 78 - 0
src/main/java/com/sooka/sponest/monitor/util/BeanUtil.java

@@ -0,0 +1,78 @@
+package com.sooka.sponest.monitor.util;
+
+import com.dahuatech.hutool.json.JSONNull;
+import com.ruoyi.common.core.utils.StringUtils;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+
+public class BeanUtil {
+
+    /**
+     * map转对象
+     *
+     * @param map
+     * @param beanClass
+     * @param <T>
+     * @return
+     * @throws Exception
+     */
+    public static <T> T mapToBean(Map map, Class<T> beanClass) throws Exception {
+        T object = beanClass.newInstance();
+        Field[] fields = object.getClass().getDeclaredFields();
+        for (Field field : fields) {
+            int mod = field.getModifiers();
+            if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
+                continue;
+            }
+            field.setAccessible(true);
+            if (map.containsKey(field.getName())) {
+                field.set(object, map.get(field.getName()) instanceof JSONNull ? StringUtils.EMPTY : map.get(field.getName()));
+            }
+        }
+        return object;
+    }
+
+    /**
+     * 实体类转Map
+     *
+     * @param object
+     * @return
+     */
+    public static Map<String, Object> beanToMap(Object object) {
+        Map<String, Object> map = new HashMap();
+        for (Field field : object.getClass().getDeclaredFields()) {
+            try {
+                boolean flag = field.isAccessible();
+                field.setAccessible(true);
+                Object o = field.get(object);
+                map.put(field.getName(), o);
+                field.setAccessible(flag);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return map;
+    }
+
+    public static <T> T arrayToBean(String[] values, Class<T> beanClass) throws Exception {
+        T object = beanClass.newInstance();
+        Field[] fields = object.getClass().getDeclaredFields();
+        for (int i = 0; i < fields.length; i++) {
+            int mod = fields[i].getModifiers();
+            if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
+                continue;
+            }
+            // 检查 values 数组的长度
+            if (i < values.length) {
+                fields[i].setAccessible(true);
+                fields[i].set(object, values[i].split(" ")[0]); // 只取第一个值
+            }
+//            fields[i].setAccessible(true);
+//            fields[i].set(object, values[i].split(" ")[0]);
+        }
+        return object;
+    }
+}

+ 244 - 0
src/main/java/com/sooka/sponest/monitor/util/Mp4ParserUtils.java

@@ -0,0 +1,244 @@
+package com.sooka.sponest.monitor.util;
+
+import com.alibaba.cloud.commons.io.IOUtils;
+import com.coremedia.iso.boxes.Container;
+import com.googlecode.mp4parser.authoring.Movie;
+import com.googlecode.mp4parser.authoring.Track;
+import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;
+import com.googlecode.mp4parser.authoring.container.mp4.MovieCreator;
+import com.googlecode.mp4parser.authoring.tracks.AppendTrack;
+import com.googlecode.mp4parser.authoring.tracks.CroppedTrack;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.springframework.http.MediaType;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
+
+import java.io.*;
+import java.nio.channels.FileChannel;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+public class Mp4ParserUtils {
+    /**
+     * 合并视频
+     *
+     * @param videoList: 所有视频地址集合
+     * @param mergeVideoFile: 目标文件
+     * @return
+     */
+    public static String mergeVideo(List<String> videoList, File mergeVideoFile) {
+        FileOutputStream fos = null;
+        FileChannel fc = null;
+        try {
+            List<Movie> sourceMovies = new ArrayList<>();
+            for (String video : videoList) {
+                sourceMovies.add(MovieCreator.build(video));
+            }
+
+            List<Track> videoTracks = new LinkedList<>();
+            List<Track> audioTracks = new LinkedList<>();
+
+            for (Movie movie : sourceMovies) {
+                for (Track track : movie.getTracks()) {
+                    if ("soun".equals(track.getHandler())) {
+                        audioTracks.add(track);
+                    }
+
+                    if ("vide".equals(track.getHandler())) {
+                        videoTracks.add(track);
+                    }
+                }
+            }
+
+            Movie mergeMovie = new Movie();
+            if (audioTracks.size() > 0) {
+                mergeMovie.addTrack(new AppendTrack(audioTracks.toArray(new Track[audioTracks.size()])));
+            }
+
+            if (videoTracks.size() > 0) {
+                mergeMovie.addTrack(new AppendTrack(videoTracks.toArray(new Track[videoTracks.size()])));
+            }
+
+            Container out = new DefaultMp4Builder().build(mergeMovie);
+            fos = new FileOutputStream(mergeVideoFile);
+            fc = fos.getChannel();
+            out.writeContainer(fc);
+            fc.close();
+            fos.close();
+            return mergeVideoFile.getAbsolutePath();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (fc != null) {
+                try {
+                    fc.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+
+            if (fos != null) {
+                try {
+                    fos.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public static MultipartFile getMultipartFile(File file) {
+        FileItem item = new DiskFileItemFactory().createItem("file"
+                , MediaType.MULTIPART_FORM_DATA_VALUE
+                , true
+                , file.getName());
+        InputStream input = null;
+        OutputStream output = null;
+        try {
+            input = Files.newInputStream(file.toPath());
+            output = item.getOutputStream();
+            // 流转移
+            IOUtils.copy(input, output, 1024);
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Invalid file: " + e, e);
+        } finally {
+            if (input != null && output != null){
+                try {
+                    input.close();
+                    output.close();
+                } catch (IOException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+        return new CommonsMultipartFile(item);
+    }
+
+
+    /**
+     * 剪切视频
+     * @param srcVideoPath
+     * @param dstVideoPath
+     * @param times
+     * @throws IOException
+     */
+    public static void cutVideo(String srcVideoPath, String dstVideoPath, double[] times) throws IOException {
+        int dstVideoNumber = times.length / 2;
+        String[] dstVideoPathes = new String[dstVideoNumber];
+        for (int i = 0; i < dstVideoNumber; i++) {
+            dstVideoPathes[i] = dstVideoPath + "cutOutput-" + i + ".mp4";
+        }
+        int timesCount = 0;
+
+        for (int idst = 0; idst < dstVideoPathes.length; idst++) {
+            //Movie movie = new MovieCreator().build(new RandomAccessFile("/home/sannies/suckerpunch-distantplanet_h1080p/suckerpunch-distantplanet_h1080p.mov", "r").getChannel());
+            Movie movie = MovieCreator.build(srcVideoPath);
+
+            List<Track> tracks = movie.getTracks();
+            movie.setTracks(new LinkedList<Track>());
+            // remove all tracks we will create new tracks from the old
+
+
+            double startTime1 = times[timesCount];
+            double endTime1 = times[timesCount + 1];
+            timesCount = timesCount + 2;
+
+            boolean timeCorrected = false;
+
+            // Here we try to find a track that has sync samples. Since we can only start decoding
+            // at such a sample we SHOULD make sure that the start of the new fragment is exactly
+            // such a frame
+            for (Track track : tracks) {
+                if (track.getSyncSamples() != null && track.getSyncSamples().length > 0) {
+                    if (timeCorrected) {
+                        // This exception here could be a false positive in case we have multiple tracks
+                        // with sync samples at exactly the same positions. E.g. a single movie containing
+                        // multiple qualities of the same video (Microsoft Smooth Streaming file)
+
+                        throw new RuntimeException("The startTime has already been corrected by another track with SyncSample. Not Supported.");
+                    }
+                    startTime1 = correctTimeToSyncSample(track, startTime1, false);
+                    endTime1 = correctTimeToSyncSample(track, endTime1, true);
+
+                    timeCorrected = true;
+                }
+            }
+
+            for (Track track : tracks) {
+                long currentSample = 0;
+                double currentTime = 0;
+                double lastTime = -1;
+                long startSample1 = -1;
+                long endSample1 = -1;
+
+
+                for (int i = 0; i < track.getSampleDurations().length; i++) {
+                    long delta = track.getSampleDurations()[i];
+
+
+                    if (currentTime > lastTime && currentTime <= startTime1) {
+                        // current sample is still before the new starttime
+                        startSample1 = currentSample;
+                    }
+                    if (currentTime > lastTime && currentTime <= endTime1) {
+                        // current sample is after the new start time and still before the new endtime
+                        endSample1 = currentSample;
+                    }
+
+                    lastTime = currentTime;
+                    currentTime += (double) delta / (double) track.getTrackMetaData().getTimescale();
+                    currentSample++;
+                }
+                //movie.addTrack(new AppendTrack(new ClippedTrack(track, startSample1, endSample1), new ClippedTrack(track, startSample2, endSample2)));
+                movie.addTrack(new CroppedTrack(track, startSample1, endSample1));
+            }
+            long start1 = System.currentTimeMillis();
+            Container out = new DefaultMp4Builder().build(movie);
+            long start2 = System.currentTimeMillis();
+            FileOutputStream fos = new FileOutputStream(String.format(dstVideoPathes[idst]));
+            FileChannel fc = fos.getChannel();
+            out.writeContainer(fc);
+
+            fc.close();
+            fos.close();
+            long start3 = System.currentTimeMillis();
+
+        }
+    }
+
+    private static double correctTimeToSyncSample(Track track, double cutHere, boolean next) {
+        double[] timeOfSyncSamples = new double[track.getSyncSamples().length];
+        long currentSample = 0;
+        double currentTime = 0;
+        for (int i = 0; i < track.getSampleDurations().length; i++) {
+            long delta = track.getSampleDurations()[i];
+
+            if (Arrays.binarySearch(track.getSyncSamples(), currentSample + 1) >= 0) {
+                // samples always start with 1 but we start with zero therefore +1
+                timeOfSyncSamples[Arrays.binarySearch(track.getSyncSamples(), currentSample + 1)] = currentTime;
+            }
+            currentTime += (double) delta / (double) track.getTrackMetaData().getTimescale();
+            currentSample++;
+
+        }
+        double previous = 0;
+        for (double timeOfSyncSample : timeOfSyncSamples) {
+            if (timeOfSyncSample > cutHere) {
+                if (next) {
+                    return timeOfSyncSample;
+                } else {
+                    return previous;
+                }
+            }
+            previous = timeOfSyncSample;
+        }
+        return timeOfSyncSamples[timeOfSyncSamples.length - 1];
+    }
+
+}

+ 9 - 0
src/main/resources/banner.txt

@@ -0,0 +1,9 @@
+Spring Boot Version: ${spring-boot.version}
+Spring Application Name: ${spring.application.name}
+
+  __________   ____ |  | _______          ____________   ____   ____   ____   _______/  |_
+
+ /  ___/  _ \ /  _ \|  |/ /\__  \        /  ___/\____ \ /  _ \ /    \_/ __ \ /  ___/\   __\
+ \___ (  <_> |  <_> )    <  / __ \_      \___ \ |  |_> >  <_> )   |  \  ___/ \___ \  |  |
+/____  >____/ \____/|__|_ \(____  /     /____  >|   __/ \____/|___|  /\___  >____  > |__|
+     \/                  \/     \/           \/ |__|               \/     \/     \/

+ 23 - 0
src/main/resources/bootstrap.yml

@@ -0,0 +1,23 @@
+# Spring
+spring:
+  application:
+    # 应用名称
+    name: sooka-sponest-center-monitor-playbackByTime
+  profiles:
+    # 环境配置
+    active: dev
+  cloud:
+    nacos:
+      discovery:
+        # 服务注册地址
+        server-addr: www.sooka.onest.com:8848
+#         server-addr: 127.0.0.1:8848
+      config:
+        # 配置中心地址
+        server-addr: www.sooka.onest.com:8848
+#        server-addr: 127.0.0.1:8848
+        # 配置文件格式
+        file-extension: yml
+        # 共享配置
+        shared-configs:
+          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

+ 28 - 0
src/main/resources/mapper/data/attach/CenterdataTAttachMapper.xml

@@ -0,0 +1,28 @@
+<?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.sooka.sponest.data.attach.mapper.CenterdataTAttachMapper">
+
+    <insert id="insertCenterdataTAttach" parameterType="CenterdataTAttach">
+        insert into centerdata_t_attach
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="busId != null">bus_id,</if>
+            <if test="attachPath != null">attach_path,</if>
+            <if test="busIndx != null">bus_indx,</if>
+            <if test="busSource != null">bus_source,</if>
+            <if test="fileName != null">file_name,</if>
+            <if test="fileType != null">file_type,</if>
+            <if test="attachSorts != null">attach_sorts,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="busId != null">#{busId},</if>
+            <if test="attachPath != null">#{attachPath},</if>
+            <if test="busIndx != null">#{busIndx},</if>
+            <if test="busSource != null">#{busSource},</if>
+            <if test="fileName != null">#{fileName},</if>
+            <if test="fileType != null">#{fileType},</if>
+            <if test="attachSorts != null">#{attachSorts},</if>
+        </trim>
+    </insert>
+</mapper>

+ 77 - 0
src/main/resources/mapper/event/download/CentereventTDownloadsMapper.xml

@@ -0,0 +1,77 @@
+<?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.sooka.sponest.event.download.mapper.CentereventTDownloadsMapper">
+
+    <select id="getbeforedateDownload" parameterType="map" resultType="PlayBackProperties">
+        SELECT l.event_code eventCode, a.event_name eventName, l.id logId, a.create_by cameraId, DATE_SUB(a.report_time,
+        INTERVAL 2 MINUTE) startTime, DATE_ADD(a.report_time, INTERVAL 1 MINUTE) endTime
+        FROM centerevent_t_fire_log l
+        LEFT JOIN centerevent_t_eventcatalogue a ON a.event_code = l.event_code
+        <where>
+            <if test="id != null and id != ''">
+                AND a.id = #{id}
+            </if>
+            <if test="taskValue != null and taskValue != ''">
+                AND DATEDIFF( l.create_time, now( ) ) = -1
+            </if>
+            <if test="monthValueStart != null and monthValueStart != ''">
+                AND DATE_FORMAT(l.create_time,'%Y-%m-%d') = #{monthValueStart}
+            </if>
+            AND l.log_content LIKE '%确认该事件%' AND l.event_code NOT IN (
+            SELECT event_code FROM centerevent_t_downloads
+            <where>
+                flag IN ( 200, 202 )
+                <if test="id != null and id != ''">
+                    AND event_code = #{id}
+                </if>
+                <if test="taskValue != null and taskValue != ''">
+                    AND DATEDIFF( create_time, now( ) ) = 0
+                </if>
+                <if test="monthValueStart != null and monthValueStart != ''">
+                    AND DATE_FORMAT(create_time,'%Y-%m-%d') >= #{monthValueStart}
+                </if>
+                <if test="monthValueEnd != null and monthValueEnd != ''">
+                    AND DATE_FORMAT(create_time,'%Y-%m-%d') &lt;= #{monthValueEnd}
+                </if>
+            </where>
+            ) AND report_source = 'reporting_source_1'
+            AND a.event_status_value NOT IN ( 'forest_event_status_3', 'forest_event_status_4' )
+        </where>
+    </select>
+
+    <insert id="insertCentereventTDownloads" parameterType="CentereventTDownloads">
+        insert into centerevent_t_downloads
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="id != null">id,</if>
+            <if test="eventCode != null">event_code,</if>
+            <if test="eventName != null">event_name,</if>
+            <if test="path != null">path,</if>
+            <if test="flag != null">flag,</if>
+            <if test="reason != null">reason,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createName != null">create_name,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateName != null">update_name,</if>
+            <if test="updateTime != null">update_time,</if>
+            <if test="logId != null">log_id,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="id != null">#{id},</if>
+            <if test="eventCode != null">#{eventCode},</if>
+            <if test="eventName != null">#{eventName},</if>
+            <if test="path != null">#{path},</if>
+            <if test="flag != null">#{flag},</if>
+            <if test="reason != null">#{reason},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createName != null">#{createName},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateName != null">#{updateName},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+            <if test="logId != null">#{logId},</if>
+        </trim>
+    </insert>
+</mapper>

+ 99 - 0
src/main/resources/mapper/monitor/camera/CentermonitorTCameraMapper.xml

@@ -0,0 +1,99 @@
+<?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.sooka.sponest.monitor.camera.mapper.CentermonitorTCameraMapper">
+
+    <resultMap type="CentermonitorTCamera" id="CentermonitorTCameraResult">
+        <result property="id" column="id"/>
+        <result property="createBy" column="create_by"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateBy" column="update_by"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="dataStatus" column="data_status"/>
+        <result property="dataDeptId" column="data_dept_id"/>
+        <result property="cameraId" column="camera_id"/>
+        <result property="cameraName" column="camera_name"/>
+        <result property="cameraIp" column="camera_ip"/>
+        <result property="cameraPort" column="camera_port"/>
+        <result property="cameraAccount" column="camera_account"/>
+        <result property="cameraPasword" column="camera_pasword"/>
+        <result property="cameraCode" column="camera_code"/>
+        <result property="cameraFactory" column="camera_factory"/>
+        <result property="cameraRegion" column="camera_region"/>
+        <result property="cameraRadius" column="camera_radius"/>
+        <result property="height" column="height"/>
+        <result property="longitude" column="longitude"/>
+        <result property="latitude" column="latitude"/>
+        <result property="cameraType" column="camera_type"/>
+        <result property="channelCode" column="channel_code"/>
+        <result property="distance" column="distance"/>
+        <result property="deptLongitude" column="dept_longitude"/>
+        <result property="deptLatitude" column="dept_latitude"/>
+        <result property="operatorType" column="operator_type"/>
+        <result property="cameraUse" column="camera_use"/>
+        <result property="channelNum" column="channel_num"/>
+        <result property="workingStatus" column="working_status"/>
+        <result property="offlineReason" column="offline_reason"/>
+        <result property="convergencePlatform" column="convergence_platform"/>
+        <result property="cameraImg" column="camera_img"/>
+        <result property="deviceCode" column="device_code"/>
+        <result property="deviceSn" column="device_sn"/>
+        <result property="deviceProtocolType" column="device_protocol_type"/>
+        <result property="deviceLoginType" column="device_login_type"/>
+    </resultMap>
+
+    <resultMap type="CentermonitorTCameraImg" id="CentermonitorTCameraImgResult">
+        <result property="id" column="id"/>
+        <result property="cameraId" column="camera_id"/>
+        <result property="cameraImg" column="camera_img"/>
+    </resultMap>
+
+    <sql id="selectCentermonitorTCameraVo">
+        select id,
+               create_by,
+               create_time,
+               update_by,
+               update_time,
+               data_status,
+               data_dept_id,
+               camera_name,
+               camera_ip,
+               camera_port,
+               camera_type,
+               camera_account,
+               camera_pasword,
+               camera_code,
+               camera_factory,
+               camera_region,
+               camera_radius,
+               height,
+               longitude,
+               latitude,
+               operator_type,
+               camera_use,
+               channel_num,
+               working_status,
+               offline_reason,
+               convergence_platform
+        from centermonitor_t_camera
+    </sql>
+
+    <select id="selectCentermonitorTCameraById" parameterType="String" resultMap="CentermonitorTCameraResult">
+        <include refid="selectCentermonitorTCameraVo"/>
+        where id = #{id}
+    </select>
+
+    <select id="SelectByIdcreameType" parameterType="java.lang.String" resultType="CentermonitorTCamera">
+        select type, type_name as typeName
+        from centermonitor_t_type
+        where camera_id = #{cameraId}
+    </select>
+
+    <select id="selectCentermonitorTCameraImgByCameraId" parameterType="java.util.ArrayList"
+            resultMap="CentermonitorTCameraImgResult">
+        select *
+        from centermonitor_t_camera_img
+        where camera_id = #{cameraId}
+    </select>
+</mapper>