‘liusuyi’
2023-06-24 78c03299a3d9bfe22cb9cff9aad951276f1d8d8f
提交
已添加77个文件
13756 ■■■■■ 文件已修改
lib/AudioRender.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/ClientDemoDll/ReadMe.txt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/ClientDemoDll/calib.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/ClientDemoDll/iconv.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/ClientDemoDll/libcrypto-1_1-x64.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/ClientDemoDll/libssl-1_1-x64.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/ClientDemoDll/libxml2.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/ClientDemoDll/zlib1.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/GdiPlus.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCCore.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDK.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/AnalyzeData.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/AudioIntercom.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/AudioRender.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/HCAlarm.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/HCAlarm.lib 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/HCCoreDevCfg.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/HCDisplay.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/HCGeneralCfgMgr.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/HCGeneralCfgMgr.lib 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/HCIndustry.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/HCPlayBack.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/HCPreview.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/HCPreview.lib 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/HCVoiceTalk.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/OpenAL32.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/StreamTransClient.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/SystemTransform.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HCNetSDKCom/libiconv2.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HXVA.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/HmMerge.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/MP_Render.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/NPQos.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/OpenAL32.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/PlayCtrl.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/SuperRender.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/YUVProcess.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/hlog.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/hpr.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/libcrypto-1_1-x64.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/libmmd.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/libssl-1_1-x64.dll 补丁 | 查看 | 原始文档 | blame | 历史
lib/zlib1.dll 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/ArdAlarmApplication.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/camera/domain/ArdCameras.java 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/camera/domain/CameraCmd.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/camera/mapper/ArdCamerasMapper.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/camera/service/IArdCamerasService.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/camera/service/impl/ArdCamerasServiceImpl.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/stealelec/domain/ArdAlarmStealelec.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/stealelec/service/StealElecAlarmService.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/tube/service/TubeAlarmService.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/async/AsyncConfiguration.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/config/MinioClientSingleton.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/config/RestTemplateConfig.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/hiksdk/common/GlobalVariable.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/hiksdk/domain/alarmEventInfo.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/hiksdk/domain/recordInfo.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/hiksdk/service/impl/FMSGCallBack.java 213 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/hiksdk/service/impl/HikClientUtil.java 347 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/hiksdk/service/impl/LoginResultCallBack.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/hiksdk/util/DateUtils.java 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/hiksdk/util/hikSdkUtil/HCNetSDK.java 10662 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/hiksdk/util/hikSdkUtil/HIKSDKStructure.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/hiksdk/util/imageUtil/waterMarkUtil.java 166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/hiksdk/util/minio/MinioUtils.java 474 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/DateUtils.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/SpringTool.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/mqtt/MqttConsumer.java 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/mqtt/MqttConsumerCallback.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/mqtt/PropertiesUtil.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/udp/NettyUdpHandler.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/udp/NettyUdpServer.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/logback-spring.xml 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ArdCamerasMapper.xml 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/AudioRender.dll
Binary files differ
lib/ClientDemoDll/ReadMe.txt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
The dll in this directory(iconv.dll,libxml2.dll,zlib1.dll,calib.dll)only used in ClientDemo.
lib/ClientDemoDll/calib.dll
Binary files differ
lib/ClientDemoDll/iconv.dll
Binary files differ
lib/ClientDemoDll/libcrypto-1_1-x64.dll
Binary files differ
lib/ClientDemoDll/libssl-1_1-x64.dll
Binary files differ
lib/ClientDemoDll/libxml2.dll
Binary files differ
lib/ClientDemoDll/zlib1.dll
Binary files differ
lib/GdiPlus.dll
Binary files differ
lib/HCCore.dll
Binary files differ
lib/HCNetSDK.dll
Binary files differ
lib/HCNetSDKCom/AnalyzeData.dll
Binary files differ
lib/HCNetSDKCom/AudioIntercom.dll
Binary files differ
lib/HCNetSDKCom/AudioRender.dll
Binary files differ
lib/HCNetSDKCom/HCAlarm.dll
Binary files differ
lib/HCNetSDKCom/HCAlarm.lib
Binary files differ
lib/HCNetSDKCom/HCCoreDevCfg.dll
Binary files differ
lib/HCNetSDKCom/HCDisplay.dll
Binary files differ
lib/HCNetSDKCom/HCGeneralCfgMgr.dll
Binary files differ
lib/HCNetSDKCom/HCGeneralCfgMgr.lib
Binary files differ
lib/HCNetSDKCom/HCIndustry.dll
Binary files differ
lib/HCNetSDKCom/HCPlayBack.dll
Binary files differ
lib/HCNetSDKCom/HCPreview.dll
Binary files differ
lib/HCNetSDKCom/HCPreview.lib
Binary files differ
lib/HCNetSDKCom/HCVoiceTalk.dll
Binary files differ
lib/HCNetSDKCom/OpenAL32.dll
Binary files differ
lib/HCNetSDKCom/StreamTransClient.dll
Binary files differ
lib/HCNetSDKCom/SystemTransform.dll
Binary files differ
lib/HCNetSDKCom/libiconv2.dll
Binary files differ
lib/HXVA.dll
Binary files differ
lib/HmMerge.dll
Binary files differ
lib/MP_Render.dll
Binary files differ
lib/NPQos.dll
Binary files differ
lib/OpenAL32.dll
Binary files differ
lib/PlayCtrl.dll
Binary files differ
lib/SuperRender.dll
Binary files differ
lib/YUVProcess.dll
Binary files differ
lib/hlog.dll
Binary files differ
lib/hpr.dll
Binary files differ
lib/libcrypto-1_1-x64.dll
Binary files differ
lib/libmmd.dll
Binary files differ
lib/libssl-1_1-x64.dll
Binary files differ
lib/zlib1.dll
Binary files differ
pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.12</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.ard</groupId>
    <artifactId>ard-alarm</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>ard-alarm</name>
    <description>ard-alarm</description>
    <properties>
        <java.version>1.8</java.version>
        <docker.image.prefix>ard</docker.image.prefix>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!-- netty依赖 springboot2.x自动导入版本 -->
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
        </dependency>
        <!--mqtt-->
        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-mqtt</artifactId>
            <version>6.0.3</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.23</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
        </dependency>
        <!--海康录像机二次开发依赖jar包-->
        <dependency>
            <groupId>net.java.jna</groupId>
            <artifactId>jna</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>net.java.examples</groupId>
            <artifactId>examples</artifactId>
            <version>1.0.0</version>
        </dependency>
        <!--mybatis依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>
        <!--minio依赖-->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.3.5</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>
    </dependencies>
    <build>
        <!-- é¡¹ç›®æ‰“包名称 -->
        <finalName>ard_alarm</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>dockerfile-maven-plugin</artifactId>
                <version>1.3.6</version>
                <configuration>
                    <repository>${docker.image.prefix}/${project.artifactId}</repository>
                    <buildArgs>
                        <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
                    </buildArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
src/main/java/com/ard/ArdAlarmApplication.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,15 @@
package com.ard;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class ArdAlarmApplication {
    public static void main(String[] args) {
        SpringApplication.run(ArdAlarmApplication.class, args);
    }
}
src/main/java/com/ard/alarm/camera/domain/ArdCameras.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,175 @@
package com.ard.alarm.camera.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
 * ç›¸æœºè®¾å¤‡å¯¹è±¡ ard_cameras
 *
 * @author åˆ˜è‹ä¹‰
 * @date 2023-02-11
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ArdCameras {
    private static final long serialVersionUID = 1L;
    public ArdCameras(String gdtype)
    {
        this.gdtype=gdtype;
    }
    /**
     * id
     */
    private String id;
    /**
     * åç§°
     */
    private String name;
    /**
     * ip
     */
    private String ip;
    /**
     * ç«¯å£
     */
    private Integer port;
    /**
     * rtsp端口
     */
    private Integer rtspPort;
    /**
     * ç”¨æˆ·å
     */
    private String username;
    /**
     * å¯†ç 
     */
    private String password;
    /**
     * å…‰ç”µç±»åž‹
     */
    private String gdtype;
    /**
     * é€šé“号
     */
    private Integer channel;
    /**
     * ç»åº¦
     */
    private Double longitude;
    /**
     * çº¬åº¦
     */
    private Double latitude;
    /**
     * é«˜å±‚
     */
    private Double altitude;
    /**
     * ç”¨æˆ·ID
     */
    private String userId;
    /**
     * éƒ¨é—¨ID
     */
    private Integer deptId;
    /**
     * æ–¹ä½è§’
     */
    private Double camHeading;
    /**
     * ä¿¯ä»°è§’
     */
    private Double camPitch;
    /**
     * æ—‹è½¬è§’
     */
    private Double camRoll;
    /**
     * è®¾å¤‡ç„¦è·
     */
    private Double camNear;
    /**
     * æ‹æ‘„距离
     */
    private Double camFar;
    /**
     * å®½é«˜æ¯”
     */
    private Double camAspectratio;
    /**
     * èžåˆæ·±åº¦
     */
    private Double camDepth;
    /**
     * è§†åœºè§’
     */
    private Double camFov;
    /**
     * æœ€å¤§å¯è§†è·ç¦»
     */
    private Double camMaxVisibleDistance;
    /** ç›¸æœºæŠ¥è­¦å¼•导开关 */
    private Integer camAlarmGuideEnable;
    /**
     * æ‰€å±žå¡”ID
     */
    private String towerId;
    /**
     * ç™»å½•ID
     */
    private Integer loginId;
    private String operatorId;
    private Date operatorExpired;
}
src/main/java/com/ard/alarm/camera/domain/CameraCmd.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
package com.ard.alarm.camera.domain;
import lombok.Data;
import java.util.Map;
@Data
public class CameraCmd {
    /*相机ID*/
    String cameraId;
    /*相机通道号*/
    Integer channelNum;
    /*云台代码*/
    Integer code;
    /*云台速度*/
    Integer speed;
    /*开启关闭标识*/
    boolean enable;
    /*预置位号*/
    Integer presetIndex;
    /*聚焦值*/
    Integer dwFocusPos;
    /*PTZ值*/
    Map<String,Double>ptzMap;
    /*目标经纬度*/
    double[] targetPosition;
    /*当前操作者*/
    String operator;
    /*过期间隔(秒)*/
    Integer expired;
    /*存储池名称*/
    String bucketName;
    /*文件名称*/
    String objectName;
    /*是否上传minio*/
    boolean isUploadMinio;
}
src/main/java/com/ard/alarm/camera/mapper/ArdCamerasMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package com.ard.alarm.camera.mapper;
import java.util.List;
import com.ard.alarm.camera.domain.ArdCameras;
import org.apache.ibatis.annotations.Mapper;
/**
 * ç›¸æœºè®¾å¤‡Mapper接口
 *
 * @author åˆ˜è‹ä¹‰
 * @date 2023-02-11
 */
@Mapper
public interface ArdCamerasMapper
{
    /**
     * æŸ¥è¯¢ç›¸æœºè®¾å¤‡
     *
     * @param id ç›¸æœºè®¾å¤‡ä¸»é”®
     * @return ç›¸æœºè®¾å¤‡
     */
    public ArdCameras selectArdCamerasById(String id);
    /**
     * æŸ¥è¯¢ç›¸æœºè®¾å¤‡åˆ—表
     *
     * @param ardCameras ç›¸æœºè®¾å¤‡
     * @return ç›¸æœºè®¾å¤‡é›†åˆ
     */
    public List<ArdCameras> selectArdCamerasList(ArdCameras ardCameras);
}
src/main/java/com/ard/alarm/camera/service/IArdCamerasService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package com.ard.alarm.camera.service;
import java.util.List;
import com.ard.alarm.camera.domain.ArdCameras;
/**
 * ç›¸æœºè®¾å¤‡Service接口
 *
 * @author åˆ˜è‹ä¹‰
 * @date 2023-02-11
 */
public interface IArdCamerasService
{
    /**
     * æŸ¥è¯¢ç›¸æœºè®¾å¤‡
     *
     * @param id ç›¸æœºè®¾å¤‡ä¸»é”®
     * @return ç›¸æœºè®¾å¤‡
     */
    public ArdCameras selectArdCamerasById(String id);
    /**
     * æŸ¥è¯¢ç›¸æœºè®¾å¤‡åˆ—表
     *
     * @param ardCameras ç›¸æœºè®¾å¤‡
     * @return ç›¸æœºè®¾å¤‡é›†åˆ
     */
    public List<ArdCameras> selectArdCamerasList(ArdCameras ardCameras);
}
src/main/java/com/ard/alarm/camera/service/impl/ArdCamerasServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
package com.ard.alarm.camera.service.impl;
import java.util.*;
import com.ard.alarm.camera.domain.ArdCameras;
import com.ard.alarm.camera.mapper.ArdCamerasMapper;
import com.ard.alarm.camera.service.IArdCamerasService;
import com.ard.hiksdk.service.impl.HikClientUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
/**
 * ç›¸æœºè®¾å¤‡Service业务层处理
 *
 * @author åˆ˜è‹ä¹‰
 * @date 2023-02-11
 */
@Service
@Slf4j
public class ArdCamerasServiceImpl implements IArdCamerasService {
    @Resource
    private ArdCamerasMapper ardCamerasMapper;
    @PostConstruct
    public void init()
    {
        List<ArdCameras> ardCameras = ardCamerasMapper.selectArdCamerasList(new ArdCameras());
        HikClientUtil.loadHCNetSDKLib();
        HikClientUtil.loginAll(ardCameras);
    }
    /**
     * æŸ¥è¯¢ç›¸æœºè®¾å¤‡
     *
     * @param id ç›¸æœºè®¾å¤‡ä¸»é”®
     * @return ç›¸æœºè®¾å¤‡
     */
    @Override
    public ArdCameras selectArdCamerasById(String id) {
        return ardCamerasMapper.selectArdCamerasById(id);
    }
    /**
     * æŸ¥è¯¢ç›¸æœºè®¾å¤‡åˆ—表
     *
     * @param ardCameras ç›¸æœºè®¾å¤‡
     * @return ç›¸æœºè®¾å¤‡
     */
    @Override
    public List<ArdCameras> selectArdCamerasList(ArdCameras ardCameras) {
        return ardCamerasMapper.selectArdCamerasList(ardCameras);
    }
}
src/main/java/com/ard/alarm/stealelec/domain/ArdAlarmStealelec.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,79 @@
package com.ard.alarm.stealelec.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
@Data
public class ArdAlarmStealelec {
    private static final long serialVersionUID = 1L;
    /**
     * id
     */
    private String id;
    /**
     * command
     */
    private Integer command;
    /**
     * æ²¹äº•代码
     */
    private String name;
    /**
     * äº•号
     */
    private String describe;
    /**
     * æŠ¥è­¦ç±»åž‹
     */
    private String catalogText;
    /**
     * æŠ¥è­¦å€¼
     */
    private String description;
    /**
     * æŠ¥è­¦å¼€å§‹æ—¶é—´
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date startTime;
    /**
     * æŠ¥è­¦ç»“束时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date endTime;
    /**
     * ç”¨æˆ·ID
     */
    private String userId;
    /**
     * éƒ¨é—¨ID
     */
    private Long deptId;
    /**
     * æŸ¥çœ‹æ—¶é—´
     */
    private Date viewTime;
    /**
     * ç»åº¦
     */
    private double longitude;
    /**
     * çº¬åº¦
     */
    private double latitude;
    /**
     * é«˜å±‚
     */
    private double altitude;
    /**
     * æŠ¥è­¦æ€»æ•°
     */
    private Integer total;
    /**
     * æœªè¯»æŠ¥è­¦æ•°é‡
     */
    private Integer count;
}
src/main/java/com/ard/alarm/stealelec/service/StealElecAlarmService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,75 @@
package com.ard.alarm.stealelec.service;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ard.alarm.stealelec.domain.ArdAlarmStealelec;
import com.ard.utils.mqtt.MqttConsumer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
 * @ClassName StealElecAlarmServiceImpl
 * @Description:盗电警报服务实现类
 * @Author åˆ˜è‹ä¹‰
 * @Date 2022/12/26 16:34
 * @Version 1.0
 */
@Slf4j(topic = "stealAlarm")
@Service
public class StealElecAlarmService{
    @Resource
    RestTemplate restTemplate;
    @Value("${spring.stealelec.url}")
    private String stealElecUrl;
    List<String> tempList=new ArrayList<>();
    /**
     * @描述 èŽ·å–api数据推送mqtt
     * @参数 []
     * @返回值 void
     * @创建人 åˆ˜è‹ä¹‰
     * @创建时间 2023/6/14 9:45
     * @修改人和其它信息
     */
    @Async("alarm")
  //  @Scheduled(cron="0/5 * * * * ?")
    public void alarmHandler() {
        try {
            String allAlarmData = restTemplate.getForObject(stealElecUrl, String.class);
            //剔除所有\符号
            String message = allAlarmData.replaceAll("\\\\", "");
            //剔除整个字符串首尾双引号
            if (message.startsWith("\"")) {
                message = message.substring(1);
            }
            if (message.endsWith("\"")) {
                message = message.substring(0, message.length() - 1);
            }
            Map<String, Object> result = (Map<String, Object>) JSON.parse(message);
            //获取到json对象list集合
            List<JSONObject> list = (List<JSONObject>) result.get("data");
            if (list.size() > 0) {
                for (JSONObject object : list) {
                    String JSONStr = JSON.toJSONString(object);
                    //转成实体对象
                    ArdAlarmStealelec wd = JSON.parseObject(JSONStr, ArdAlarmStealelec.class);
                    if(tempList.contains(wd.getId()))
                    {
                        continue;
                    }
                    MqttConsumer.publish(2,false,"stealelec", JSON.toJSONString(wd));
                    tempList.add(wd.getId());
                }
            }
        } catch (Exception ex) {
            log.error("stealelec报警数据推送异常:" + ex.getMessage());
        }
    }
}
src/main/java/com/ard/alarm/tube/service/TubeAlarmService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,82 @@
package com.ard.alarm.tube.service;
import com.alibaba.fastjson2.JSON;
import com.ard.utils.DateUtils;
import com.ard.utils.mqtt.MqttConsumer;
import com.ard.utils.udp.NettyUdpServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * @Description: ç®¡çº¿æ³„漏报警服务
 * @ClassName: TubeAlarmService
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´06月06日8:56
 * @Version: 1.0
 **/
@Service
@Slf4j(topic = "tube")
public class TubeAlarmService {
    @Resource
    NettyUdpServer nettyUdpServer;
    @Value("${spring.netty.port}")
    private Integer udpPort;
    @Value("${spring.netty.enabled}")
    private String UdpServerEnable;
    @PostConstruct
    public void init() {
        if (UdpServerEnable.equals("false")) {
            return;
        }
        nettyUdpServer.init(udpPort);
        log.info("UDP服务已经启动");
    }
    @Async("alarm")
    public void alarmHandler(String message) {
        try {
            String[] messages = message.split(",");
            if (messages.length == 8) {
                String start = messages[0];
                String host = messages[1];
                String tubeId = messages[2];
                String alarmTime = DateUtils.convertDate(messages[3]);
                String position = messages[4];
                String type = messages[5];
                String watcher = messages[6];
                String stop = messages[7];
                Map<String, Object> map = new HashMap<>();
                map.put("host", host);
                map.put("tubeId", tubeId);
                map.put("alarmTime", alarmTime);
                map.put("type", type);
                map.put("alarmType", start);
                map.put("position", position);
                map.put("watcher", watcher);
                log.info("开始解析" + start);
                log.info("主机:" + host);
                log.info("管线编号:" + tubeId);
                log.info("报警时间:" + alarmTime);
                log.info("报警类型:" + type);
                log.info("位置:" + position);
                log.info("值班人:" + watcher);
                log.info("结束解析" + stop);
                MqttConsumer.publish(2, false, "tube", JSON.toJSONString(map));
            } else {
                log.error("数据异常");
            }
        } catch (Exception ex) {
            log.error("tube报警数据推送异常:" + ex.getMessage());
        }
    }
}
src/main/java/com/ard/async/AsyncConfiguration.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
package com.ard.async;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
/**
 * @ClassName: AsyncConfiguration
 * @Description: å¼‚步线程配置类
 * @Author: Administrator
 * @Date: 2023å¹´02月03日 11:25
 * @Version: 1.0
 **/
@Configuration
@EnableAsync(proxyTargetClass = true)
public class AsyncConfiguration {
    @Bean("alarm")
    public ThreadPoolTaskExecutor executor(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //配置核心线程数
        executor.setCorePoolSize(15);
        //配置最大线程数
        executor.setMaxPoolSize(30);
        //配置队列大小
        executor.setQueueCapacity(1000);
        //线程的名称前缀
        executor.setThreadNamePrefix("Executor-");
        //线程活跃时间(秒)
        //executor.setKeepAliveSeconds(60);
        //等待所有任务结束后再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        //设置拒绝策略
        //executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //执行初始化
        executor.initialize();
        return executor;
    }
}
src/main/java/com/ard/config/MinioClientSingleton.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,75 @@
package com.ard.config;
import io.minio.MinioClient;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Properties;
/**
 * @Description:
 * @ClassName: MinioClientSingleton
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´05月18日9:32
 * @Version: 1.0
 **/
@Slf4j(topic = "minio")
@Component
public class MinioClientSingleton {
    public static String domainUrl;
    private static String accessKey;
    private static String secretKey;
    private volatile static MinioClient minioClient;
    static {
        domainUrl = getYmlNew("minio.endpoint");
        accessKey = getYmlNew("minio.accessKey");
        secretKey = getYmlNew("minio.secretKey");
        log.info("minio信息:" + domainUrl + "(" + accessKey + "/" + secretKey + ")");
    }
    /**
     * èŽ·å–minio客户端实例
     *
     * @return {@link MinioClient}
     */
    public static MinioClient getMinioClient() {
        if (minioClient == null) {
            synchronized (MinioClientSingleton.class) {
                if (minioClient == null) {
                    minioClient = MinioClient.builder()
                            .endpoint(domainUrl)
                            .credentials(accessKey, secretKey)
                            .build();
                }
            }
        }
        return minioClient;
    }
    /*yml配置信息获取*/
    public static String getYmlNew(String key) {
        Resource resource = new ClassPathResource("application.yml");
        Properties properties = null;
        try {
            YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
            yamlFactory.setResources(resource);
            properties = yamlFactory.getObject();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return properties.get(key).toString();
    }
}
src/main/java/com/ard/config/RestTemplateConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package com.ard.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
 * @Description:
 * @ClassName: RestTemplateConfig
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´06月14日9:32
 * @Version: 1.0
 **/
@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
src/main/java/com/ard/hiksdk/common/GlobalVariable.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package com.ard.hiksdk.common;
import com.ard.alarm.camera.domain.ArdCameras;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
/**
 * @ClassName: globalVariable
 * @Description: å…¨å±€å˜é‡
 * @Author: Administrator
 * @Date: 2023å¹´01月31日 17:05
 * @Version: 1.0
 **/
@Data
public class GlobalVariable {
    //保存相机信息key:ip value:camera对象
    public static Map<String, ArdCameras> cameraMap = new HashMap<>();
    //保存相机登录信息key:cameraId value:loginId
    public static Map<String, Integer> loginMap = new HashMap<>();
}
src/main/java/com/ard/hiksdk/domain/alarmEventInfo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
package com.ard.hiksdk.domain;
import lombok.Data;
/**
 * @ClassName alarmInfo
 * @Description:
 * @Author åˆ˜è‹ä¹‰
 * @Date 2023/2/16 20:31
 * @Version 1.0
 */
@Data
public class alarmEventInfo {
    /**
     * æŠ¥è­¦åç§°
     */
    String alarmName;
    /**
     *  æŠ¥è­¦ç±»åˆ«
     */
    String alarmType;
    /**
     * æŠ¥è­¦æ—¶é—´
     */
    String alarmTime;
    /**
     * ç›®æ ‡è¯†åˆ«
     */
    String targetIdentification;
    /**
     * å…³è”相机id
     */
    String cameraId;
    /**
     * å…³è”相机名称
     */
    String cameraName;
    /**
     * å…³è”相机ip
     */
    String cameraIp;
    /**
     * å…³è”相机通道
     */
    Integer cameraChannel;
    /**
     * å…³è”相机经度
     */
    Double longitude;
    /**
     * å…³è”相机纬度
     */
    Double latitude;
    /**
     * å…³è”相机类型
     */
    String cameraType;
    /**
     * å›¾ç‰‡é“¾æŽ¥
     */
    String picUrl;
    /**
     * è§„则ID
     */
    Integer ruleId;
}
src/main/java/com/ard/hiksdk/domain/recordInfo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ard.hiksdk.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * @ClassName: recordInfo
 * @Description:录像实体-保存预览id和录像路径
 * @Author: Administrator
 * @Date: 2023å¹´01月28日 9:24
 * @Version: 1.0
 **/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class recordInfo {
    Integer lRealHandle;
    String recordPath;
}
src/main/java/com/ard/hiksdk/service/impl/FMSGCallBack.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,213 @@
package com.ard.hiksdk.service.impl;
import com.alibaba.fastjson2.JSON;
import com.ard.alarm.camera.domain.ArdCameras;
import com.ard.alarm.camera.domain.CameraCmd;
import com.ard.alarm.camera.service.impl.ArdCamerasServiceImpl;
import com.ard.config.MinioClientSingleton;
import com.ard.hiksdk.common.GlobalVariable;
import com.ard.hiksdk.domain.alarmEventInfo;
import com.ard.hiksdk.util.DateUtils;
import com.ard.hiksdk.util.hikSdkUtil.HCNetSDK;
import com.ard.hiksdk.util.minio.MinioUtils;
import com.ard.utils.SpringTool;
import com.ard.utils.mqtt.MqttConsumer;
import com.sun.jna.Pointer;
import lombok.extern.slf4j.Slf4j;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
 * @ClassName: FMSGCallBack
 * @Description:
 * @Author: Administrator
 * @Date: 2023å¹´02月15日 12:16
 * @Version: 1.0
 **/
@Slf4j(topic = "hiksdk")
public class FMSGCallBack implements HCNetSDK.FMSGCallBack_V31 {
    /**
     * æŠ¥è­¦ä¿¡æ¯å›žè°ƒå‡½æ•°
     *
     * @param lCommand   ä¸Šä¼ æ¶ˆæ¯ç±»åž‹
     * @param pAlarmer   æŠ¥è­¦è®¾å¤‡ä¿¡æ¯
     * @param pAlarmInfo æŠ¥è­¦ä¿¡æ¯
     * @param dwBufLen   æŠ¥è­¦ä¿¡æ¯ç¼“存大小
     * @param pUser      ç”¨æˆ·æ•°æ®
     */
    @Override
    public boolean invoke(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
        ArdCamerasServiceImpl ardCamerasService = SpringTool.getApplicationContext().getBean(ArdCamerasServiceImpl.class);
        String sTime;//事件时间
        String url;//事件图片
        alarmEventInfo info;//事件信息
        //lCommand是传的报警类型
        switch (lCommand) {
            case HCNetSDK.COMM_ALARM_RULE:
                //region è¡Œä¸ºåˆ†æžä¿¡æ¯
                log.info("报警事件类型:lCommand:" + Integer.toHexString(lCommand));
                HCNetSDK.NET_VCA_RULE_ALARM strVcaAlarm = new HCNetSDK.NET_VCA_RULE_ALARM();
                strVcaAlarm.write();
                Pointer pVCAInfo = strVcaAlarm.getPointer();
                pVCAInfo.write(0, pAlarmInfo.getByteArray(0, strVcaAlarm.size()), 0, strVcaAlarm.size());
                strVcaAlarm.read();
                Integer ruleID =  Integer.valueOf(strVcaAlarm.struRuleInfo.byRuleID);
                sTime = DateUtils.parseTime(strVcaAlarm.dwAbsTime);//事件时间
                String ipaddr = new String(strVcaAlarm.struDevInfo.struDevIP.sIpV4).trim();//设备ip
                Integer channel = Integer.valueOf(strVcaAlarm.struDevInfo.byChannel);//通道
                ArdCameras ardCameras = new ArdCameras();
                ardCameras.setIp(ipaddr);
                ArdCameras ardcamere = ardCamerasService.selectArdCamerasList(ardCameras).get(0);
                info = new alarmEventInfo();
                info.setAlarmName("人员行为分析");
                info.setAlarmTime(sTime);
                info.setCameraName(ardcamere.getName());
                info.setCameraId(ardcamere.getId());
                info.setCameraIp(ipaddr);
                info.setCameraType(ardcamere.getGdtype());
                info.setCameraChannel(channel);
                info.setLongitude(ardcamere.getLongitude());
                info.setLatitude(ardcamere.getLatitude());
                info.setAlarmType(ardcamere.getGdtype());
                info.setRuleId(ruleID);
                switch (strVcaAlarm.struRuleInfo.wEventTypeEx) {
                    case 1: //region穿越警戒面 (越界侦测)
                        info.setAlarmType("越界侦测报警");
                        strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_TRAVERSE_PLANE.class);
                        //endregion
                        break;
                    case 2: //region ç›®æ ‡è¿›å…¥åŒºåŸŸ
                        info.setAlarmType("目标进入区域报警");
                        strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_AREA.class);
                        //endregion
                        break;
                    case 3: //region ç›®æ ‡ç¦»å¼€åŒºåŸŸ
                        info.setAlarmType("目标离开区域报警");
                        strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_AREA.class);
                        //endregion
                        break;
                    case 4: //region å‘¨ç•Œå…¥ä¾µ
                        info.setAlarmType("周界入侵报警");
                        strVcaAlarm.struRuleInfo.uEventParam.setType(HCNetSDK.NET_VCA_INTRUSION.class);
                        //endregion
                        break;
                    case 5: //region å¾˜å¾Š
                        info.setAlarmType("徘徊事件报警");
                        //endregion
                        break;
                    case 8: //region å¿«é€Ÿç§»åЍ(奔跑)
                        info.setAlarmType("快速移动(奔跑)事件报警");
                        //endregion
                        break;
                    case 13: //region ç‰©å“é—留事件
                        info.setAlarmType("物品遗留事件报警");
                        //endregion
                        break;
                    case 14: //region ç‰©å“æ‹¿å–事件
                        info.setAlarmType("物品拿取事件事件报警");
                        //endregion
                        break;
                    case 20: //region å€’地检测
                        info.setAlarmType("倒地事件触发");
                        //endregion
                        break;
                    case 44: //region çŽ©æ‰‹æœº
                        info.setAlarmType("玩手机报警事件");
                        //endregion
                        break;
                    default:
                        log.info("未知行为事件类型:" + strVcaAlarm.struRuleInfo.wEventTypeEx);
                        printLog(info);
                        break;
                }
                //endregion
                //图片存入minio
                url = savePicture(info);
                info.setPicUrl(url);
                publishMqtt(info);
                break;
            case HCNetSDK.COMM_UPLOAD_FACESNAP_RESULT:
                log.info("人脸检测事件");
                break;
            default:
                log.info("未知报警事件类型:lCommand:" + Integer.toHexString(lCommand));
                break;
        }
        return true;
    }
    /**
     * @描述 ä¿å­˜å›¾ç‰‡å°è£…方法
     * @参数 [strVcaAlarm, eventName, eventNameEng]
     * @返回值 java.lang.String
     * @创建人 åˆ˜è‹ä¹‰
     * @创建时间 2023/2/17 15:05
     * @修改人和其它信息
     */
    private String savePicture(HCNetSDK.NET_VCA_RULE_ALARM strVcaAlarm, String eventName, String eventNameEng) {
        String url = "";
        if ((strVcaAlarm.dwPicDataLen > 0) && (strVcaAlarm.byPicTransType == 0)) {
            String currentTime = new SimpleDateFormat("yyyyMMdd").format(new Date());
            try {
                //存入minio
                long offset = 0;
                ByteBuffer buffers = strVcaAlarm.pImage.getByteBuffer(offset, strVcaAlarm.dwPicDataLen);
                byte[] bytes = new byte[strVcaAlarm.dwPicDataLen];
                buffers.rewind();
                buffers.get(bytes);
                InputStream inputStream = new ByteArrayInputStream(bytes);
                String ipaddr = new String(strVcaAlarm.struDevInfo.struDevIP.sIpV4).trim();//设备ip
                String UUID = java.util.UUID.randomUUID().toString().replace("-", "");
                String filename = ipaddr + "/" + currentTime + "/" + eventNameEng + "/" + UUID + ".jpg";
                boolean uploadRes = MinioUtils.uploadObject("pic", filename, inputStream, inputStream.available(), "image/jpeg");
                if (uploadRes) {
                    url = MinioClientSingleton.domainUrl + filename;
                    log.info("写入minio图片地址:" + url);
                }
            } catch (Exception ex) {
                log.error(eventName + "处理图片异常:" + ex.getMessage());
            }
        }
        return url;
    }
    /**
     * æ‰“保存图片
     */
    private String savePicture(alarmEventInfo info) {
        CameraCmd cmd = new CameraCmd();
        ArdCameras Cameras = GlobalVariable.cameraMap.get(info.getCameraIp());
        cmd.setCameraId(Cameras.getId());
        cmd.setChannelNum(info.getCameraChannel());
        cmd.setBucketName("pic");
        String UUID = java.util.UUID.randomUUID().toString().replace("-", "");
        String filename = info.getCameraName() + "/" + info.getAlarmType() + "/" + UUID + ".jpg";
        cmd.setObjectName(filename);
        String url = HikClientUtil.picCutCate(cmd);
        return url;
    }
    /**
     * æ‰“印日志
     */
    private void printLog(alarmEventInfo info) {
        log.info("【规则】" + info.getAlarmName() +"【规则id】" + info.getRuleId() + "【类型】" + info.getAlarmType() +
                "【时间】" + info.getAlarmTime() + "【相机id】" + info.getCameraId() + "【相机】" + info.getCameraName() +
                "【IP】" + info.getCameraIp() + "【通道】" + info.getCameraChannel() +"【型号】" + info.getCameraType() +
                "【图片】" + info.getPicUrl() + "【坐标】" + info.getLongitude() + "," + info.getLatitude());
    }
    /**
     * æŽ¨é€mqtt
     */
    private void publishMqtt(alarmEventInfo info) {
       // printLog(info);
        MqttConsumer.publish(2, false, "camera", JSON.toJSONString(info));
    }
}
src/main/java/com/ard/hiksdk/service/impl/HikClientUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,347 @@
package com.ard.hiksdk.service.impl;
import com.ard.alarm.camera.domain.ArdCameras;
import com.ard.alarm.camera.domain.CameraCmd;
import com.ard.hiksdk.common.GlobalVariable;
import com.ard.hiksdk.util.hikSdkUtil.HCNetSDK;
import com.ard.hiksdk.util.minio.MinioUtils;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.ptr.IntByReference;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.nio.ByteBuffer;
import java.util.*;
import static com.ard.hiksdk.common.GlobalVariable.cameraMap;
/**
 * @ClassName: hikClientServiceImpl
 * @Description: æµ·åº·æ“ä½œå®¢æˆ·ç«¯å®žçŽ°ç±»
 * @Author: Administrator
 * @Date: 2023å¹´01月17日 11:25
 * @Version: 1.2
 **/
@Slf4j(topic = "hikSdk")
public class HikClientUtil {
    private static HCNetSDK hCNetSDK;
    // æŠ¥è­¦å›žè°ƒå‡½æ•°å®žçް
    public static HCNetSDK.FMSGCallBack_V31 fMSFCallBack_V31;
    public static void loadHCNetSDKLib() {
        try {
            log.debug("开始加载sdk库文件路径");
            if (Platform.isWindows()) {
                String WIN_PATH = System.getProperty("user.dir") + File.separator + "lib" + File.separator + "HCNetSDK.dll";
                log.debug("当前Windows平台的sdk库路径:" + WIN_PATH);
                hCNetSDK = (HCNetSDK) Native.loadLibrary(WIN_PATH, HCNetSDK.class);
            } else {
                log.debug("Linux平台");
                String LINUX_PATH = System.getProperty("user.dir") + File.separator + "hiklib" + File.separator + "libhcnetsdk.so";
                log.debug("当前Linux平台的sdk库路径:" + LINUX_PATH);
                hCNetSDK = (HCNetSDK) Native.loadLibrary(LINUX_PATH, HCNetSDK.class);
                //设置HCNetSDKCom组件库所在路径
                //libhcnetsdk.so
                String strPathCom = "/home/hiklib";
                HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
                System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
                struComPath.write();
                hCNetSDK.NET_DVR_SetSDKInitCfg(2, struComPath.getPointer());
                //设置libcrypto.so所在路径
                HCNetSDK.BYTE_ARRAY ptrByteArrayCrypto = new HCNetSDK.BYTE_ARRAY(256);
                String strPathCrypto = "/home/hiklib/libcrypto.so.1.1";
                System.arraycopy(strPathCrypto.getBytes(), 0, ptrByteArrayCrypto.byValue, 0, strPathCrypto.length());
                ptrByteArrayCrypto.write();
                hCNetSDK.NET_DVR_SetSDKInitCfg(3, ptrByteArrayCrypto.getPointer());
                //设置libssl.so所在路径
                HCNetSDK.BYTE_ARRAY ptrByteArraySsl = new HCNetSDK.BYTE_ARRAY(256);
                String strPathSsl = "/home/hiklib/libssl.so.1.1";
                System.arraycopy(strPathSsl.getBytes(), 0, ptrByteArraySsl.byValue, 0, strPathSsl.length());
                ptrByteArraySsl.write();
                hCNetSDK.NET_DVR_SetSDKInitCfg(4, ptrByteArraySsl.getPointer());
            }
        } catch (Exception ex) {
            log.error("加载库文件异常:" + ex.getMessage());
        }
    }
    /**
     * @描述 æ³¨å†Œç™»å½• åªæ”¯æŒåŒæ­¥ç™»é™†ï¼Œä¸”官方不建议直接在此接口下写耗时操作
     * @参数 [dvrLogin]
     * @返回值 java.lang.Integer
     * @创建人 åˆ˜è‹ä¹‰
     * @创建时间 2023/1/17 16:12
     * @修改人和其它信息
     */
    public ArdCameras login1(ArdCameras camera) {
        // åˆå§‹åŒ–
        if (!hCNetSDK.NET_DVR_Init()) {
            log.error("SDK初始化失败");
        }
        //打印海康sdk日志
        if (Platform.isWindows()) {
            String WIN_PATH = System.getProperty("user.dir") + File.separator + "ardLog" + File.separator + "logs" + File.separator;
            hCNetSDK.NET_DVR_SetLogToFile(3, WIN_PATH, true);
        } else {
            hCNetSDK.NET_DVR_SetLogToFile(3, "/home/ardLog/hiklog", true);
        }
        String m_sDeviceIP = camera.getIp();
        String m_sUsername = camera.getUsername();
        String m_sPassword = camera.getPassword();
        short m_sPort = camera.getPort().shortValue();
        //设置连接时间与重连时间
        hCNetSDK.NET_DVR_SetConnectTime(2000, 1);
        hCNetSDK.NET_DVR_SetReconnect(100000, true);
        //设备信息, è¾“出参数
        HCNetSDK.NET_DVR_DEVICEINFO_V30 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V30();
        int lUserID = hCNetSDK.NET_DVR_Login_V30(m_sDeviceIP, m_sPort, m_sUsername, m_sPassword, m_strDeviceInfo);
        if (lUserID < 0) {
            //释放SDK资源
            hCNetSDK.NET_DVR_Cleanup();
            camera.setLoginId(-1);
        }
        if (GlobalVariable.loginMap.containsKey(camera.getId())) {
            GlobalVariable.loginMap.remove(camera.getId());
        }
        GlobalVariable.loginMap.put(camera.getId(), lUserID);
        camera.setLoginId(lUserID);
        camera.setChannel((int) m_strDeviceInfo.byStartChan);
        return camera;
    }
    /**
     * @描述 æ³¨å†Œç™»å½• é›†æˆäºŽNET_DVR_Login_V30,支持同步和异步登录
     * @参数 [dvrLogin]
     * @返回值 java.lang.Integer
     * @创建人 åˆ˜è‹ä¹‰
     * @创建时间 2023/1/17 16:12
     * @修改人和其它信息
     */
    public static void login(ArdCameras camera) {
        // åˆå§‹åŒ–
        if (!hCNetSDK.NET_DVR_Init()) {
            log.error("SDK初始化失败");
        }
        //打印海康sdk日志
        if (Platform.isWindows()) {
            String WIN_PATH = System.getProperty("user.dir") + File.separator + "ardLog" + File.separator + "logs" + File.separator;
            hCNetSDK.NET_DVR_SetLogToFile(3, WIN_PATH, true);
        } else {
            hCNetSDK.NET_DVR_SetLogToFile(3, "/home/ardLog/hiklog", true);
        }
        String m_sDeviceIP = camera.getIp();
        String m_sUsername = camera.getUsername();
        String m_sPassword = camera.getPassword();
        short m_sPort = camera.getPort().shortValue();
        //设置连接时间与重连时间
        hCNetSDK.NET_DVR_SetConnectTime(2000, 1);
        hCNetSDK.NET_DVR_SetReconnect(100000, true);
        //设备信息, è¾“出参数
        HCNetSDK.NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
        HCNetSDK.NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
        // æ³¨å†Œè®¾å¤‡-登录参数,包括设备地址、登录用户、密码等
        m_strLoginInfo.sDeviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
        System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
        m_strLoginInfo.sUserName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
        System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
        m_strLoginInfo.sPassword = new byte[HCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
        System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
        m_strLoginInfo.wPort = m_sPort;
        m_strLoginInfo.byVerifyMode = 0;
        m_strLoginInfo.byLoginMode = 0;
        //是否异步登录:0- å¦ï¼Œ1- æ˜¯  windowsSDK里是true和false
        m_strLoginInfo.bUseAsynLogin = true;
        //异步登录回调
        m_strLoginInfo.cbLoginResult = new LoginResultCallBack(camera);
        m_strLoginInfo.write();
        int i = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo, m_strDeviceInfo);
        if (i < 0) {
            int errorCode = hCNetSDK.NET_DVR_GetLastError();
            log.info("登录异常:" + errorCode);
        }
    }
    /**
     * @描述 ç™»å½•所有相机
     * @参数 []
     * @返回值 void
     * @创建人 åˆ˜è‹ä¹‰
     * @创建时间 2023/2/3 10:10
     * @修改人和其它信息
     */
    public static void loginAll(List<ArdCameras> ardCameras) {
        try {
            log.debug("加载lib完成!");
            for (ArdCameras camera : ardCameras) {
                Thread.sleep(100);
                login(camera);
                String ip = camera.getIp();
                cameraMap.put(ip,camera);
            }
        } catch (Exception ex) {
            log.error("初始化登录相机异常:" + ex.getMessage());
        }
    }
    /**
     * @描述 æ³¨é”€ç™»å½•
     * @参数 [dvrLogin]
     * @返回值 java.lang.Integer
     * @创建人 åˆ˜è‹ä¹‰
     * @创建时间 2023/1/17 16:12
     * @修改人和其它信息
     */
    public static boolean loginOut(String cameraId) {
        if (!GlobalVariable.loginMap.containsKey(cameraId)) {
            return false;
        }
        Integer userId = GlobalVariable.loginMap.get(cameraId);
        boolean b = hCNetSDK.NET_DVR_Logout(userId);
        if (b) {
            GlobalVariable.loginMap.remove(cameraId);
        }
        return b;
    }
    /**
     * æ˜¯å¦åœ¨çº¿
     *
     * @param cmd
     */
    public static boolean isOnLine(CameraCmd cmd) {
        String cameraId = cmd.getCameraId();
        if (!GlobalVariable.loginMap.containsKey(cameraId)) {
            return false;
        }
        Integer userId = GlobalVariable.loginMap.get(cameraId);
        boolean isOnLine = hCNetSDK.NET_DVR_RemoteControl(userId, HCNetSDK.NET_DVR_CHECK_USER_STATUS, null, 0);
        return isOnLine;
    }
    /**
     * å»ºç«‹å¸ƒé˜²ä¸Šä¼ é€šé“,用于传输数据
     *
     * @param lUserID      å”¯ä¸€æ ‡è¯†ç¬¦
     * @param lAlarmHandle æŠ¥è­¦å¤„理器
     */
    public static int setupAlarmChan(int lUserID, int lAlarmHandle) {
        // æ ¹æ®è®¾å¤‡æ³¨å†Œç”Ÿæˆçš„lUserID建立布防的上传通道,即数据的上传通道
        if (lUserID == -1) {
            log.info("请先注册");
            return lUserID;
        }
        if (lAlarmHandle < 0) {
            // è®¾å¤‡å°šæœªå¸ƒé˜²,需要先进行布防
            if (fMSFCallBack_V31 == null) {
                fMSFCallBack_V31 = new FMSGCallBack();
                if (!hCNetSDK.NET_DVR_SetDVRMessageCallBack_V50(0, fMSFCallBack_V31, null)) {
                    log.info("设置回调函数失败!错误码==========》" + hCNetSDK.NET_DVR_GetLastError());
                }
            }
            // è¿™é‡Œéœ€è¦å¯¹è®¾å¤‡è¿›è¡Œç›¸åº”的参数设置,不设置或设置错误都会导致设备注册失败
            HCNetSDK.NET_DVR_SETUPALARM_PARAM m_strAlarmInfo = new HCNetSDK.NET_DVR_SETUPALARM_PARAM();
            m_strAlarmInfo.dwSize = m_strAlarmInfo.size();
            // æ™ºèƒ½äº¤é€šå¸ƒé˜²ä¼˜å…ˆçº§ï¼š0 - ä¸€ç­‰çº§ï¼ˆé«˜ï¼‰ï¼Œ1 - äºŒç­‰çº§ï¼ˆä¸­ï¼‰ï¼Œ2 - ä¸‰ç­‰çº§ï¼ˆä½Žï¼‰
            m_strAlarmInfo.byLevel = 1;
            // æ™ºèƒ½äº¤é€šæŠ¥è­¦ä¿¡æ¯ä¸Šä¼ ç±»åž‹ï¼š0 - è€æŠ¥è­¦ä¿¡æ¯ï¼ˆNET_DVR_PLATE_RESULT), 1 - æ–°æŠ¥è­¦ä¿¡æ¯(NET_ITS_PLATE_RESULT)
            m_strAlarmInfo.byAlarmInfoType = 1;
            // å¸ƒé˜²ç±»åž‹(仅针对门禁主机、人证设备):0 - å®¢æˆ·ç«¯å¸ƒé˜²(会断网续传),1 - å®žæ—¶å¸ƒé˜²(只上传实时数据)
            m_strAlarmInfo.byDeployType = 1;
            m_strAlarmInfo.write();
            // å¸ƒé˜²æˆåŠŸï¼Œè¿”å›žå¸ƒé˜²æˆåŠŸçš„æ•°æ®ä¼ è¾“é€šé“å·
            lAlarmHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V41(lUserID, m_strAlarmInfo);
            if (lAlarmHandle == -1) {
                log.error("设备布防失败,错误码==========》" + hCNetSDK.NET_DVR_GetLastError());
                log.error("设备布防失败,错误码==========》" + hCNetSDK.NET_DVR_GetLastError());
                // æ³¨é”€ é‡Šæ”¾sdk资源
                logout(lUserID);
                return lAlarmHandle;
            } else {
                log.info("相机布防成功");
                return lAlarmHandle;
            }
        }
        return lAlarmHandle;
    }
    /**
     * æ³¨é”€
     *
     * @param lUserID è®¾å¤‡æ³¨å†ŒæˆåŠŸå”¯ä¸€æ ‡è¯†ç¬¦
     */
    public static void logout(int lUserID) {
        // æ³¨é”€
        hCNetSDK.NET_DVR_Logout(lUserID);
        // é‡Šæ”¾sdk资源
        hCNetSDK.NET_DVR_Cleanup();
    }
    /**
     * æŠ“图
     *
     * @param cmd æŠ“图命令
     */
    public static String picCutCate(CameraCmd cmd) {
        String cameraId = cmd.getCameraId();
        Integer channelNum = cmd.getChannelNum();
        if (!GlobalVariable.loginMap.containsKey(cameraId)) {
            return "";
        }
        Integer userId = GlobalVariable.loginMap.get(cameraId);
        //图片信息
        HCNetSDK.NET_DVR_JPEGPARA jpeg = new HCNetSDK.NET_DVR_JPEGPARA();
        //设置图片分辨率
        //图片尺寸:0-CIF(352*288/352*240),1-QCIF(176*144/176*120),2-4CIF(704*576/704*480)或D1(720*576/720*486),3-UXGA(1600*1200),
        // 4-SVGA(800*600),5-HD720P(1280*720),6-VGA(640*480),7-XVGA(1280*960),8-HD900P(1600*900),9-HD1080P(1920*1080),10-2560*1920,
        // 11-1600*304,12-2048*1536,13-2448*2048,14-2448*1200,15-2448*800,16-XGA(1024*768),17-SXGA(1280*1024),18-WD1(960*576/960*480),
        // 19-1080I(1920*1080),20-576*576,21-1536*1536,22-1920*1920,23-320*240,24-720*720,25-1024*768,26-1280*1280,27-1600*600,
        // 28-2048*768,29-160*120,75-336*256,78-384*256,79-384*216,80-320*256,82-320*192,83-512*384,127-480*272,128-512*272, 161-288*320,
        // 162-144*176,163-480*640,164-240*320,165-120*160,166-576*720,167-720*1280,168-576*960,180-180*240, 181-360*480, 182-540*720,
        // 183-720*960, 184-960*1280, 185-1080*1440, 500-384*288, 0xff-Auto(使用当前码流分辨率)
        jpeg.wPicSize = 0;
        //设置图片质量:0-最好,1-较好,2-一般
        jpeg.wPicQuality = 0;
        IntByReference a = new IntByReference();
        //设置图片大小
        ByteBuffer jpegBuffer = ByteBuffer.allocate(1024 * 1024);
        // æŠ“图到内存,单帧数据捕获并保存成JPEG存放在指定的内存空间中
        log.debug("-----------这里开始封装 NET_DVR_CaptureJPEGPicture_NEW---------");
        boolean is = hCNetSDK.NET_DVR_CaptureJPEGPicture_NEW(userId, channelNum, jpeg, jpegBuffer, 1024 * 1024, a);
        log.debug("-----------这里开始图片存入内存----------" + is);
        if (is) {
            log.debug("hksdk(抓图)-结果状态值(0表示成功):" + hCNetSDK.NET_DVR_GetLastError());
            byte[] array = jpegBuffer.array();
            //存储到minio
            String ContentType = "image/JPEG";
            InputStream input = new ByteArrayInputStream(array);
            String url = "";
            try {
                boolean b = MinioUtils.uploadObject(cmd.getBucketName(), cmd.getObjectName(), input, input.available(), ContentType);
                if (b) {
                    url = MinioUtils.getBucketObjectUrl(cmd.getBucketName(), cmd.getObjectName());
                    url = url.indexOf('?') != -1 ? url.substring(0, url.indexOf('?')) : url;
                    log.debug("上传文件成功!" + url);
                }
            } catch (IOException ex) {
                log.error("上传文件异常:" + ex.getMessage());
            }
            return url;
        } else {
            int code = hCNetSDK.NET_DVR_GetLastError();
            log.debug("抓图失败,请稍后重试" + code);
            return "";
        }
    }
}
src/main/java/com/ard/hiksdk/service/impl/LoginResultCallBack.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
package com.ard.hiksdk.service.impl;
import com.ard.alarm.camera.domain.ArdCameras;
import com.ard.hiksdk.common.GlobalVariable;
import com.ard.hiksdk.util.hikSdkUtil.HCNetSDK;
import com.sun.jna.Pointer;
import lombok.extern.slf4j.Slf4j;
/**
 * @Description: å¼‚步登录回调
 * @ClassName: FLoginResultCallBack
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´06月12日13:34
 * @Version: 1.0
 **/
@Slf4j(topic = "hikSdk")
public class LoginResultCallBack implements HCNetSDK.FLoginResultCallBack {
    private ArdCameras camera;
    public LoginResultCallBack(ArdCameras camera) {
        this.camera = camera;
    }
    @Override
    public int invoke(int lUserID, int dwResult, HCNetSDK.NET_DVR_DEVICEINFO_V30 lpDeviceinfo, Pointer pUser) {
        if (GlobalVariable.loginMap.containsKey(camera.getId())) {
            GlobalVariable.loginMap.remove(camera.getId());
        }
        if (dwResult == 1) {
            GlobalVariable.loginMap.put(camera.getId(), lUserID);
            log.info(camera.getIp() + ":" + camera.getPort() + "登录成功");
            camera.setLoginId(lUserID);
            camera.setChannel((int) lpDeviceinfo.byChanNum);
            // è®¾ç½®æŠ¥è­¦å›žè°ƒå‡½æ•°ï¼Œå»ºç«‹æŠ¥è­¦ä¸Šä¼ é€šé“(启用布防)
            HikClientUtil.setupAlarmChan(lUserID, -1);
        } else {
            log.info(camera.getIp() + ":" + camera.getPort() + "登录失败");
            camera.setChannel(0);
            camera.setLoginId(-1);
        }
        return 1;
    }
}
src/main/java/com/ard/hiksdk/util/DateUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,197 @@
package com.ard.hiksdk.util;
import org.apache.commons.lang3.time.DateFormatUtils;
import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.Date;
/**
 * @ClassName DateUtils
 * @Description: è¿™æ˜¯ä¸€ä¸ªæ—¶é—´å·¥å…·ç±»
 * @Author åˆ˜è‹ä¹‰
 * @Date 2023/2/16 21:58
 * @Version 1.0
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils
{
    public static String YYYY = "yyyy";
    public static String YYYY_MM = "yyyy-MM";
    public static String YYYY_MM_DD = "yyyy-MM-dd";
    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
    /**
     * èŽ·å–å½“å‰Date型日期
     *
     * @return Date() å½“前日期
     */
    public static Date getNowDate()
    {
        return new Date();
    }
    /**
     * èŽ·å–å½“å‰æ—¥æœŸ, é»˜è®¤æ ¼å¼ä¸ºyyyy-MM-dd
     *
     * @return String
     */
    public static String getDate()
    {
        return dateTimeNow(YYYY_MM_DD);
    }
    public static final String getTime()
    {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }
    public static final String dateTimeNow()
    {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }
    public static final String dateTimeNow(final String format)
    {
        return parseDateToStr(format, new Date());
    }
    public static final String dateTime(final Date date)
    {
        return parseDateToStr(YYYY_MM_DD, date);
    }
    public static final String parseDateToStr(final String format, final Date date)
    {
        return new SimpleDateFormat(format).format(date);
    }
    public static final Date dateTime(final String format, final String ts)
    {
        try
        {
            return new SimpleDateFormat(format).parse(ts);
        }
        catch (ParseException e)
        {
            throw new RuntimeException(e);
        }
    }
    /**
     * æ—¥æœŸè·¯å¾„ å³å¹´/月/日 å¦‚2018/08/08
     */
    public static final String datePath()
    {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }
    /**
     * æ—¥æœŸè·¯å¾„ å³å¹´/月/日 å¦‚20180808
     */
    public static final String dateTime()
    {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyyMMdd");
    }
    /**
     * æ—¥æœŸåž‹å­—符串转化为日期 æ ¼å¼
     */
    public static Date parseDate(Object str)
    {
        if (str == null)
        {
            return null;
        }
        try
        {
            return parseDate(str.toString(), parsePatterns);
        }
        catch (ParseException e)
        {
            return null;
        }
    }
    /**
     * èŽ·å–æœåŠ¡å™¨å¯åŠ¨æ—¶é—´
     */
    public static Date getServerStartDate()
    {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }
    /**
     * è®¡ç®—相差天数
     */
    public static int differentDaysByMillisecond(Date date1, Date date2)
    {
        return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
    }
    /**
     * è®¡ç®—两个时间差
     */
    public static String getDatePoor(Date endDate, Date nowDate)
    {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // èŽ·å¾—ä¸¤ä¸ªæ—¶é—´çš„æ¯«ç§’æ—¶é—´å·®å¼‚
        long diff = endDate.getTime() - nowDate.getTime();
        // è®¡ç®—差多少天
        long day = diff / nd;
        // è®¡ç®—差多少小时
        long hour = diff % nd / nh;
        // è®¡ç®—差多少分钟
        long min = diff % nd % nh / nm;
        // è®¡ç®—差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "天" + hour + "小时" + min + "分钟";
    }
    /**
     * å¢žåŠ  LocalDateTime ==> Date
     */
    public static Date toDate(LocalDateTime temporalAccessor)
    {
        ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }
    /**
     * å¢žåŠ  LocalDate ==> Date
     */
    public static Date toDate(LocalDate temporalAccessor)
    {
        LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
        ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }
    //SDK时间解析
    public static String parseTime(int time)
    {
        int year=(time>>26)+2000;
        int month=(time>>22)&15;
        int day=(time>>17)&31;
        int hour=(time>>12)&31;
        int min=(time>>6)&63;
        int second=(time>>0)&63;
        String sTime=String.format("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, min, second);
        return sTime;
    }
}
src/main/java/com/ard/hiksdk/util/hikSdkUtil/HCNetSDK.java
¶Ô±ÈÐÂÎļþ
ÎļþÌ«´ó
src/main/java/com/ard/hiksdk/util/hikSdkUtil/HIKSDKStructure.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
package com.ard.hiksdk.util.hikSdkUtil;
import com.sun.jna.Structure;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
/**
 * @ClassName: HIKSDKStructure
 * @Description:
 * å› ä¸ºæµ·åº·jna.jar比较老,结构体定义没有getFiledOrder,创建一个类继承 Structure
 * ç„¶åŽ HCNetSDK ç±»é‡Œæ‰€æœ‰ç»§æ‰¿ Structure æ›¿æ¢ä¸º HIKSDKStructure å³å¯
 * @Author: Administrator
 * @Date: 2023å¹´02月01日 11:44
 * @Version: 1.0
 **/
public class HIKSDKStructure extends Structure {
    protected List<String> getFieldOrder(){
        List<String> fieldOrderList = new ArrayList<String>();
        for (Class<?> cls = getClass();
             !cls.equals(HIKSDKStructure.class);
             cls = cls.getSuperclass()) {
            Field[] fields = cls.getDeclaredFields();
            int modifiers;
            for (Field field : fields) {
                modifiers = field.getModifiers();
                if (Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) {
                    continue;
                }
                fieldOrderList.add(field.getName());
            }
        }
        return fieldOrderList;
    }
}
src/main/java/com/ard/hiksdk/util/imageUtil/waterMarkUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,166 @@
package com.ard.hiksdk.util.imageUtil;
/**
 * @ClassName WaterMarkUtil
 * @Description:
 * @Author åˆ˜è‹ä¹‰
 * @Date 2023/1/17 20:20
 * @Version 1.0
 */
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
/**
 *   å›¾ç‰‡æ°´å°å·¥å…·ç±»
 *
 */
public class waterMarkUtil {
    // æ°´å°é€æ˜Žåº¦
    private static final float alpha = 0.8f;
    // æ°´å°æ¨ªå‘位置
    private static int positionWidth = 100;
    // æ°´å°çºµå‘位置
    private static int positionHeight = 300;
    // æ°´å°æ–‡å­—字体
    private static final Font font = new Font("宋体", Font.BOLD, 30);
    // æ°´å°æ–‡å­—颜色
    private static final Color color = Color.white;
    /**
     * ç»™å›¾ç‰‡æ·»åŠ æ°´å°æ–‡å­—
     *
     * @param text       æ°´å°æ–‡å­—
     * @param srcImgPath æºå›¾ç‰‡è·¯å¾„
     * @param targetPath ç›®æ ‡å›¾ç‰‡è·¯å¾„
     */
    public static void markImage(String text, String srcImgPath, String targetPath) {
        markImage(text, srcImgPath, targetPath, null);
    }
    /**
     * ç»™å›¾ç‰‡æ·»åŠ æ°´å°æ–‡å­—ã€å¯è®¾ç½®æ°´å°æ–‡å­—çš„æ—‹è½¬è§’åº¦
     *
     * @param text
     * @param srcImgPath
     * @param targetPath
     * @param degree
     */
    public static void markImage(String text, String srcImgPath, String targetPath, Integer degree) {
        OutputStream os = null;
        try {
            // 0、图片类型
            String type = srcImgPath.substring(srcImgPath.indexOf(".") + 1, srcImgPath.length());
            // 1、源图片
            Image srcImg = ImageIO.read(new File(srcImgPath));
            int imgWidth = srcImg.getWidth(null);
            int imgHeight = srcImg.getHeight(null);
            BufferedImage buffImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
            // 2、得到画笔对象
            Graphics2D g = buffImg.createGraphics();
            // 3、设置对线段的锯齿状边缘处理
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.drawImage(srcImg.getScaledInstance(imgWidth, imgHeight, Image.SCALE_SMOOTH), 0, 0, null);
            // 4、设置水印旋转
            if (null != degree) {
                g.rotate(Math.toRadians(degree), (double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);
            }
            // 5、设置水印文字颜色
            g.setColor(color);
            // 6、设置水印文字Font
            g.setFont(font);
            // 7、设置水印文字透明度
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            // 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
            positionWidth = 50;
            positionHeight = imgHeight - 30;
            g.drawString(text, positionWidth, positionHeight);
            // 9、释放资源
            g.dispose();
            // 10、生成图片
            os = new FileOutputStream(targetPath);
            // ImageIO.write(buffImg, "JPG", os);
            ImageIO.write(buffImg, type.toUpperCase(), os);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != os) {
                    os.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * ç»™å›¾ç‰‡æ·»åŠ æ°´å°æ–‡å­—ã€å¯è®¾ç½®æ°´å°æ–‡å­—çš„æ—‹è½¬è§’åº¦
     *
     * @param text
     * @param inputStream
     * @param outputStream
     * @param degree
     * @param typeName
     */
    public static void markImageByIO(String text, InputStream inputStream, OutputStream outputStream,
                                     Integer degree, String typeName) {
        try {
            // 1、源图片
            Image srcImg = ImageIO.read(inputStream);
            int imgWidth = srcImg.getWidth(null);
            int imgHeight = srcImg.getHeight(null);
            BufferedImage buffImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
            // 2、得到画笔对象
            Graphics2D g = buffImg.createGraphics();
            // 3、设置对线段的锯齿状边缘处理
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.drawImage(srcImg.getScaledInstance(imgWidth, imgHeight, Image.SCALE_SMOOTH), 0, 0, null);
            // 4、设置水印旋转
            if (null != degree) {
                g.rotate(Math.toRadians(degree), (double) buffImg.getWidth() / 2, (double) buffImg.getHeight() / 2);
            }
            // 5、设置水印文字颜色
            g.setColor(color);
            // 6、设置水印文字Font
            g.setFont(font);
            // 7、设置水印文字透明度
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
            // 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
            g.drawString(text, positionWidth, positionHeight);
            // 9、释放资源
            g.dispose();
            // 10、生成图片
            ImageIO.write(buffImg, typeName.toUpperCase(), outputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
//    public static void main(String[] args) {
//        String srcImgPath = "D:\\testSmile.jpg";
//        String text = "JCccc";
//        // ç»™å›¾ç‰‡æ·»åŠ æ°´å°æ–‡å­—
//        markImage(text, srcImgPath, "D:\\testSmileWithMark.jpg");
//        // ç»™å›¾ç‰‡æ·»åŠ æ°´å°æ–‡å­—,水印文字旋转-45
//        markImage(text, srcImgPath, "D:\\testSmileWithMarkRotate.jpg", -45);
//        System.out.println("给图片添加水印文字完毕");
//    }
src/main/java/com/ard/hiksdk/util/minio/MinioUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,474 @@
package com.ard.hiksdk.util.minio;
import com.ard.config.MinioClientSingleton;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
 * @Description: Minio客户端工具类
 * @ClassName: MinioUtils
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´05月18日9:34
 * @Version: 1.0
 **/
@SuppressWarnings("ALL")
@Slf4j(topic = "minio")
public class MinioUtils {
    /**
     * åˆ¤æ–­æ¡¶æ˜¯å¦å­˜åœ¨
     */
    public static boolean exitsBucket(String bucketName) {
        boolean found = false;
        try {
            BucketExistsArgs bucketExistsArgs = BucketExistsArgs.builder().bucket(bucketName).build();
            found = MinioClientSingleton.getMinioClient().bucketExists(bucketExistsArgs);
        } catch (Exception ex) {
            log.error("minio判断桶存在异常:", ex.getMessage());
        }
        return found;
    }
    /**
     * åˆ›å»ºæ¡¶,并设置桶策略为公共
     */
    public static boolean createBucket(String bucketName) {
        try {
            /*创建桶*/
            MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(bucketName).build();
            MinioClientSingleton.getMinioClient().makeBucket(makeBucketArgs);
            /*设置策略*/
            String sb = "{\"Version\":\"2012-10-17\"," +
                    "\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":" +
                    "{\"AWS\":[\"*\"]},\"Action\":[\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"," +
                    "\"s3:GetBucketLocation\"],\"Resource\":[\"arn:aws:s3:::" + bucketName +
                    "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:PutObject\",\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:GetObject\",\"s3:ListMultipartUploadParts\"],\"Resource\":[\"arn:aws:s3:::" +
                    bucketName + "/*\"]}]}";
            SetBucketPolicyArgs setBucketPolicyArgs = SetBucketPolicyArgs.builder()
                    .bucket(bucketName)
                    .config(sb)
                    .build();
            MinioClientSingleton.getMinioClient().setBucketPolicy(setBucketPolicyArgs);
            return true;
        } catch (Exception ex) {
            log.error("minio创建桶异常:", ex.getMessage());
            return false;
        }
    }
    /**
     * åˆ é™¤ä¸€ä¸ªæ¡¶
     *
     * @param bucket æ¡¶åç§°
     */
    public static boolean removeBucket(String bucket) {
        try {
            boolean found = exitsBucket(bucket);
            if (found) {
                Iterable<Result<Item>> myObjects = MinioClientSingleton.getMinioClient().listObjects(ListObjectsArgs.builder().bucket(bucket).build());
                for (Result<Item> result : myObjects) {
                    Item item = result.get();
                    //有对象文件,则删除失败
                    if (item.size() > 0) {
                        return false;
                    }
                }
                // åˆ é™¤`bucketName`存储桶,注意,只有存储桶为空时才能删除成功。
                MinioClientSingleton.getMinioClient().removeBucket(RemoveBucketArgs.builder().bucket(bucket).build());
                found = exitsBucket(bucket);
                return !found;
            }
        } catch (Exception ex) {
            log.error("删除桶异常:" + ex.getMessage());
        }
        return false;
    }
    /**
     * æŸ¥è¯¢æ‰€æœ‰æ¡¶æ–‡ä»¶
     *
     * @return
     */
    public static List<Bucket> getListBuckets() {
        try {
            return MinioClientSingleton.getMinioClient().listBuckets();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Collections.emptyList();
    }
    /**
     * ç”Ÿæˆä¸€ä¸ªGET请求的带有失效时间的分享链接。
     * å¤±æ•ˆæ—¶é—´é»˜è®¤æ˜¯7天。
     *
     * @param bucketName å­˜å‚¨æ¡¶åç§°
     * @param objectName å­˜å‚¨æ¡¶é‡Œçš„对象名称
     * @param expires    å¤±æ•ˆæ—¶é—´ï¼ˆä»¥ç§’为单位),默认是7天,不得大于七天
     * @return
     */
    public static String getObjectWithExpired(String bucketName, String objectName, Integer expires, TimeUnit timeUnit) {
        String url = "";
        if (exitsBucket(bucketName)) {
            try {
                GetPresignedObjectUrlArgs getPresignedObjectUrlArgs = GetPresignedObjectUrlArgs.builder()
                        .method(Method.GET)
                        .bucket(bucketName)
                        .object(objectName)
                        .expiry(expires, timeUnit)
                        .build();
                url = MinioClientSingleton.getMinioClient().getPresignedObjectUrl(getPresignedObjectUrlArgs);
            } catch (Exception ex) {
                log.error("minio生成失效url异常", ex.getMessage());
            }
        }
        return url;
    }
    /**
     * @描述 ä¸Šä¼ MultipartFile文件返回url
     * @参数 [bucketName, file]
     * @返回值 java.lang.String
     * @创建人 åˆ˜è‹ä¹‰
     * @创建时间 2023/5/18 12:16
     * @修改人和其它信息
     */
    public static String putObjectAndGetUrl(String bucketName, MultipartFile file) {
        //判断文件是否为空
        if (null == file || 0 == file.getSize()) {
            log.error("上传minio文件服务器错误,上传文件为空");
        }
        boolean exsit = exitsBucket(bucketName);
        if (!exsit) {
            log.error(bucketName + "-桶不存在");
        }
        //文件名
        String originalFilename = file.getOriginalFilename();
        //新的文件名
        String fileName = UUID.randomUUID().toString().replace("-", "") + originalFilename;
        try {
            InputStream inputStream = file.getInputStream();
            /*上传对象*/
            PutObjectArgs putObjectArgs = PutObjectArgs
                    .builder()
                    .bucket(bucketName)
                    .object(fileName)
                    .stream(inputStream, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build();
            MinioClientSingleton.getMinioClient().putObject(putObjectArgs);
            inputStream.close();
            /*获取url*/
            GetPresignedObjectUrlArgs getPresignedObjectUrlArgs = GetPresignedObjectUrlArgs
                    .builder()
                    .bucket(bucketName)
                    .object(fileName)
                    .build();
            return MinioClientSingleton.getMinioClient().getPresignedObjectUrl(getPresignedObjectUrlArgs);
        } catch (Exception ex) {
            log.error("上传对象返回url异常:" + ex.getMessage());
        }
        return "";
    }
    /**
     * åˆ é™¤æ–‡ä»¶
     *
     * @param bucket     æ¡¶åç§°
     * @param objectName å¯¹è±¡åç§°
     * @return boolean
     */
    public static boolean removeObject(String bucket, String objectName) {
        try {
            boolean exsit = exitsBucket(bucket);
            if (exsit) {
                RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucket).object(objectName).build();
                MinioClientSingleton.getMinioClient().removeObject(removeObjectArgs);
                return true;
            }
        } catch (Exception e) {
            log.error("removeObject", e);
        }
        return false;
    }
    /**
     * æ‰¹é‡åˆ é™¤æ–‡ä»¶
     *
     * @param objectNames å¯¹è±¡åç§°
     * @return boolean
     */
    public static boolean removeObjects(String bucket, List<String> objectNames) {
        if (exitsBucket(bucket)) {
            try {
                List<DeleteObject> objects = new LinkedList<>();
                for (String str : objectNames) {
                    objects.add(new DeleteObject(str));
                }
                RemoveObjectsArgs removeObjectsArgs = RemoveObjectsArgs.builder().bucket(bucket).objects(objects).build();
                Iterable<Result<DeleteError>> results = MinioClientSingleton.getMinioClient().removeObjects(removeObjectsArgs);
                /*删除完遍历结果,否则删不掉*/
                for (Result<DeleteError> result : results) {
                    DeleteError error = result.get();
                    log.error("Error in deleting object " + error.objectName() + "; " + error.message());
                }
                return true;
            } catch (Exception ex) {
                log.error("minio批量删除文件异常", ex.getMessage());
            }
        }
        return false;
    }
    /**
     * èŽ·å–å•ä¸ªæ¡¶ä¸­çš„æ‰€æœ‰æ–‡ä»¶å¯¹è±¡åç§°
     *
     * @param bucket æ¡¶åç§°
     * @return {@link List}<{@link String}>
     */
    public static List<String> getBucketObjectName(String bucket) {
        boolean exsit = exitsBucket(bucket);
        if (exsit) {
            List<String> listObjetcName = new ArrayList<>();
            try {
                ListObjectsArgs listObjectsArgs = ListObjectsArgs.builder().bucket(bucket).build();
                Iterable<Result<Item>> myObjects = MinioClientSingleton.getMinioClient().listObjects(listObjectsArgs);
                for (Result<Item> result : myObjects) {
                    Item item = result.get();
                    listObjetcName.add(item.objectName());
                }
                return listObjetcName;
            } catch (Exception ex) {
                log.error("minio获取桶下对象异常:" + ex.getMessage());
            }
        }
        return null;
    }
    /**
     * èŽ·å–æŸä¸ªæ¡¶ä¸‹æŸä¸ªå¯¹è±¡çš„URL
     *
     * @param bucket     æ¡¶åç§°
     * @param objectName å¯¹è±¡å (文件夹名 + æ–‡ä»¶å)
     * @return
     */
    public static String getBucketObjectUrl(String bucketName, String objectName) {
        try {
            if (!exitsBucket(bucketName)) {
                return "";
            }
            GetPresignedObjectUrlArgs getPresignedObjectUrlArgs = GetPresignedObjectUrlArgs
                    .builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .method(Method.GET)
                    .build();
            return MinioClientSingleton.getMinioClient().getPresignedObjectUrl(getPresignedObjectUrlArgs);
        } catch (Exception ex) {
            log.error("minio获取对象URL异常" + ex.getMessage());
        }
        return "";
    }
    /**
     * ä¸Šä¼ å¯¹è±¡-stream
     *
     * @param bucketName  bucket名称
     * @param objectName  â½‚件名称
     * @param stream      â½‚件流
     * @param size        â¼¤â¼©
     * @param contextType ç±»åž‹ Image/jpeg æµè§ˆå™¨å¯ä»¥ç›´æŽ¥æ‰“开,否则下载
     */
    public static boolean uploadObject(String bucketName, String objectName, InputStream stream, long size, String contextType) {
        try {
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .stream(stream, size, -1)
                    .contentType(contextType)
                    .build();
            ObjectWriteResponse objectWriteResponse = MinioClientSingleton.getMinioClient().putObject(putObjectArgs);
            return true;
        } catch (Exception ex) {
            log.error("minio上传文件(通过stream)异常" + ex.getMessage());
            return false;
        }
    }
    /**
     * ä¸Šä¼ å¯¹è±¡-File
     *
     * @param bucketName  bucket名称
     * @param objectName  â½‚件名称
     * @param file        â½‚ä»¶
     * @param contextType ç±»åž‹ Image/jpeg æµè§ˆå™¨å¯ä»¥ç›´æŽ¥æ‰“开,否则下载
     */
    public static boolean uploadObject(String bucketName, String objectName, File file, String contextType) {
        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .stream(fileInputStream, file.length(), -1)
                    .contentType(contextType)
                    .build();
            ObjectWriteResponse objectWriteResponse = MinioClientSingleton.getMinioClient().putObject(putObjectArgs);
            return true;
        } catch (Exception ex) {
            log.error("minio上传文件(通过File)异常" + ex.getMessage());
            return false;
        }
    }
    /**
     * ä¸Šä¼ å¯¹è±¡-MultipartFile
     *
     * @param bucketName    bucket名称
     * @param objectName    â½‚件名称
     * @param MultipartFile â½‚ä»¶
     * @param contextType   ç±»åž‹ Image/jpeg æµè§ˆå™¨å¯ä»¥ç›´æŽ¥æ‰“开,否则下载
     */
    public static boolean uploadObject(String bucketName, String objectName, MultipartFile multipartFile, String contextType) {
        try {
            if (bucketName.isEmpty()) {
                log.error("bucket名称为空");
                return false;
            }
            if (objectName.isEmpty()) {
                log.error("对象名称为空");
                return false;
            }
            InputStream inputStream = multipartFile.getInputStream();
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .stream(inputStream, multipartFile.getSize(), -1)
                    .contentType(contextType)
                    .build();
            ObjectWriteResponse objectWriteResponse = MinioClientSingleton.getMinioClient().putObject(putObjectArgs);
            return true;
        } catch (Exception ex) {
            log.error("minio上传文件(通过File)异常" + ex.getMessage());
            return false;
        }
    }
    /**
     * ä¸Šä¼ å¯¹è±¡,用multipartFile名称作为对象名
     *
     * @param bucketName    bucket名称
     * @param objectName    â½‚件名称
     * @param MultipartFile â½‚ä»¶
     * @param contextType   ç±»åž‹ Image/jpeg æµè§ˆå™¨å¯ä»¥ç›´æŽ¥æ‰“开,否则下载
     */
    public static boolean uploadObject(String bucketName, MultipartFile multipartFile, String contextType) {
        try {
            if (multipartFile == null) {
                log.error("上传文件为空");
                return false;
            }
            String objectName = multipartFile.getOriginalFilename();
            InputStream inputStream = multipartFile.getInputStream();
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .stream(inputStream, multipartFile.getSize(), -1)
                    .contentType(contextType)
                    .build();
            MinioClientSingleton.getMinioClient().putObject(putObjectArgs);
            return true;
        } catch (Exception ex) {
            log.error("minio上传文件(通过File)异常" + ex.getMessage());
            return false;
        }
    }
    /**
     * ä¸Šä¼ å¯¹è±¡-通过本地路径
     *
     * @param bulkName
     * @param objectName
     * @param localFilePathName
     * @return
     */
    public static boolean uploadObject(String bulkName, String objectName, String localFilePathName, String contextType) {
        try {
            if (!exitsBucket(bulkName)) {
                log.debug(bulkName + "不存在");
                return false;
            }
            File file = new File(localFilePathName);
            if (!file.exists()) {
                log.debug("文件不存在");
                return false;
            }
            UploadObjectArgs uploadObjectArgs = UploadObjectArgs.builder()
                    .bucket(bulkName)
                    .object(objectName)
                    .filename(localFilePathName)
                    .contentType(contextType)
                    .build();
            ObjectWriteResponse objectWriteResponse = MinioClientSingleton.getMinioClient().uploadObject(uploadObjectArgs);
            return true;
        } catch (Exception e) {
            log.error("minio upload object file error " + e.getMessage());
            return false;
        }
    }
    /**
     *@描述 èŽ·å–æ¡¶ä¸­æ‰€æœ‰å¯¹è±¡
     *@参数 [bucketName]
     *@返回值 java.lang.Iterable<io.minio.Result<io.minio.messages.Item>>
     *@创建人 åˆ˜è‹ä¹‰
     *@创建时间 2023/2/6 10:32
     *@修改人和其它信息
     */
    public static Iterable<Result<Item>> getObjectsByBucket(String bucketName)  {
        Iterable<Result<Item>> listObjects = MinioClientSingleton.getMinioClient().listObjects(ListObjectsArgs.builder()
                .bucket(bucketName)
                .recursive(true)
                .build());
        return listObjects;
    }
    public static void main(String[] args) {
        //        /*删除桶*/
        //        boolean b = removeBucket("lsy");
        //        log.info(String.valueOf(b));
        //        /*创建桶*/
        //        boolean lsy = createBucket("lsy");
        //        log.info(String.valueOf(lsy));
        //        /*判断桶是否存在*/
        //        boolean pic = exitsBucket("lsy");
        //        log.info(String.valueOf(pic));
        /*查询所有桶*/
        //        List<Bucket> listBuckets = getListBuckets();
        //        for (Bucket bucket : listBuckets) {
        //            log.info(bucket.name());
        //        }
        String bucket = "lsy";
        String filename = UUID.randomUUID().toString().replace("-", "") + "pic.jpeg";
        String fileFullPath = "C:\\Users\\Administrator\\Desktop\\微信截图_20230518102605.png";
        //        uploadObject(bucket, filename, fileFullPath, "Image/jpeg");
        //        String url = getObjectWithExpired(bucket, filename, 10, SECONDS);
        //        System.out.println(url);
        boolean b = removeBucket(bucket);
        System.out.println(b);
        //        boolean b = uploadObjectBylocalPath(bucket, filename, fileFullPath);
        //        System.out.println(b);
        //String url = getObjectWithExpired(bucket, filename, 10000);
        //
        //String url = getBucketObject(bucket, filename);
        //      System.out.println(url); package com.example.minio;
    }
}
src/main/java/com/ard/utils/DateUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.ard.utils;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
 * @Description: æ—¶é—´å¤„理工具
 * @ClassName: DateUtils
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´06月06日10:04
 * @Version: 1.0
 **/
public class DateUtils {
    /**
     * æ—¥æœŸå­—符串的月日时分秒自动补零,并将/替换成-
     * */
    public static String convertDate(String startDate) {
        DateTimeFormatter inputFormat = DateTimeFormatter.ofPattern("yyyy/M/d H:m:s");
        DateTimeFormatter outputFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return LocalDateTime.parse(startDate, inputFormat).format(outputFormat);
    }
}
src/main/java/com/ard/utils/SpringTool.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,35 @@
package com.ard.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
 * @Description:
 * @ClassName: SpringTool
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´06月06日9:14
 * @Version: 1.0
 **/
@Component
public class SpringTool implements ApplicationContextAware {
    private static ApplicationContext applicationContext = null;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (SpringTool.applicationContext == null) {
            SpringTool.applicationContext = applicationContext;
        }
    }
    //该方法用于外界获取ApplicationContext对象
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
    //该方法用于外界通过bean的名字获取Bean对象
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }
}
src/main/java/com/ard/utils/mqtt/MqttConsumer.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,174 @@
package com.ard.utils.mqtt;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.io.UnsupportedEncodingException;
/**
 * @Description: mqtt消费客户端
 * @ClassName: MqttConsumer
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´05月29日9:55
 * @Version: 1.0
 **/
@Component
@Slf4j(topic = "mqtt")
public class MqttConsumer implements ApplicationRunner {
    private static MqttClient client;
    @Override
    public void run(ApplicationArguments args) {
        log.info("初始化并启动mqtt......");
        if(PropertiesUtil.MQTT_ENABLED)
        {
            this.connect();
        }
    }
    /**
     * è¿žæŽ¥mqtt服务器
     */
    private void connect() {
        try {
            // 1 åˆ›å»ºå®¢æˆ·ç«¯
            getClient();
            // 2 è®¾ç½®é…ç½®
            MqttConnectOptions options = getOptions();
            String[] topic = PropertiesUtil.MQTT_TOPIC.split(",");
            // 3 æ¶ˆæ¯å‘布质量
            int[] qos = getQos(topic.length);
            // 4 æœ€åŽè®¾ç½®
            create(options, topic, qos);
        } catch (Exception e) {
            log.error("mqtt连接异常:" + e);
        }
    }
    /**
     *  åˆ›å»ºå®¢æˆ·ç«¯  --- 1 ---
     */
    public void getClient() {
        try {
            if (null == client) {
                client = new MqttClient(PropertiesUtil.MQTT_HOST, PropertiesUtil.MQTT_CLIENT_ID, new MemoryPersistence());
            }
            log.info("--创建mqtt客户端");
        } catch (Exception e) {
            log.error("创建mqtt客户端异常:" + e);
        }
    }
    /**
     *  ç”Ÿæˆé…ç½®å¯¹è±¡ï¼Œç”¨æˆ·åï¼Œå¯†ç ç­‰  --- 2 ---
     */
    public MqttConnectOptions getOptions() {
        MqttConnectOptions options = new MqttConnectOptions();
        //设置用户名密码
        options.setUserName(PropertiesUtil.MQTT_USER_NAME);
        options.setPassword(PropertiesUtil.MQTT_PASSWORD.toCharArray());
        // è®¾ç½®è¶…æ—¶æ—¶é—´
        options.setConnectionTimeout(PropertiesUtil.MQTT_TIMEOUT);
        // è®¾ç½®ä¼šè¯å¿ƒè·³æ—¶é—´
        options.setKeepAliveInterval(PropertiesUtil.MQTT_KEEP_ALIVE);
        // æ˜¯å¦æ¸…除session
        options.setCleanSession(false);
        log.info("--生成mqtt配置对象");
        return options;
    }
    /**
     *  qos   --- 3 ---
     */
    public int[] getQos(int length) {
        int[] qos = new int[length];
        for (int i = 0; i < length; i++) {
            /**
             *  MQTT协议中有三种消息发布服务质量:
             *
             * QOS0: â€œè‡³å¤šä¸€æ¬¡â€ï¼Œæ¶ˆæ¯å‘布完全依赖底层 TCP/IP ç½‘络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
             * QOS1: â€œè‡³å°‘一次”,确保消息到达,但消息重复可能会发生。
             * QOS2: â€œåªæœ‰ä¸€æ¬¡â€ï¼Œç¡®ä¿æ¶ˆæ¯åˆ°è¾¾ä¸€æ¬¡ã€‚这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果,资源开销大
             */
            qos[i] = 1;
        }
        log.info("--设置消息发布质量");
        return qos;
    }
    /**
     *  è£…载各种实例和订阅主题  --- 4 ---
     */
    public void create(MqttConnectOptions options, String[] topic, int[] qos) {
        try {
            client.setCallback(new MqttConsumerCallback(client, options, topic, qos));
            log.info("--添加回调处理类");
            client.connect(options);
        } catch (Exception e) {
            log.info("装载实例或订阅主题异常:" + e);
        }
    }
    /**
     * è®¢é˜…某个主题
     *
     * @param topic
     * @param qos
     */
    public void subscribe(String topic, int qos) {
        try {
            log.info("topic:" + topic);
            client.subscribe(topic, qos);
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
    /**
     * å‘布,非持久化
     *
     *  qos根据文档设置为1
     *
     * @param topic
     * @param msg
     */
    public static void publish(String topic, String msg) {
        publish(1, false, topic, msg);
    }
    /**
     * å‘布
     */
    public static void publish(int qos, boolean retained, String topic, String pushMessage) {
        log.info("【主题】:" + topic + "【qos】:" + qos + "【pushMessage】:" + pushMessage);
        MqttMessage message = new MqttMessage();
        message.setQos(qos);
        message.setRetained(retained);
        try {
            message.setPayload(pushMessage.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            log.error("mqtt编码异常:" + e.getMessage());
        }
        MqttTopic mTopic = client.getTopic(topic);
        if (null == mTopic) {
            log.error("topic:" + topic + " ä¸å­˜åœ¨");
        }
        MqttDeliveryToken token;
        try {
            token = mTopic.publish(message);
            token.waitForCompletion();
            if (token.isComplete()) {
                log.info("消息发送成功");
            }
        } catch (MqttPersistenceException e) {
            e.printStackTrace();
        } catch (MqttException e) {
            e.printStackTrace();
        }
    }
}
src/main/java/com/ard/utils/mqtt/MqttConsumerCallback.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,95 @@
package com.ard.utils.mqtt;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import java.util.Arrays;
/**
 * @Description: mqtt回调处理类
 * @ClassName: MqttConsumerCallback
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´05月29日9:55
 * @Version: 1.0
 **/
@Slf4j(topic = "mqtt")
public class MqttConsumerCallback implements MqttCallbackExtended {
    private MqttClient client;
    private MqttConnectOptions options;
    private String[] topic;
    private int[] qos;
    public MqttConsumerCallback(MqttClient client, MqttConnectOptions options, String[] topic, int[] qos) {
        this.client = client;
        this.options = options;
        this.topic = topic;
        this.qos = qos;
    }
    /**
     * æ–­å¼€é‡è¿ž
     */
    @Override
    public void connectionLost(Throwable cause) {
        log.info("MQTT连接断开,发起重连......");
        try {
            while (!client.isConnected()) {
                Thread.sleep(5000);
                if (null != client && !client.isConnected()) {
                    client.reconnect();
                    log.error("尝试重新连接");
                } else {
                    client.connect(options);
                    log.error("尝试建立新连接");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * æŽ¥æ”¶åˆ°æ¶ˆæ¯è°ƒç”¨ä»¤ç‰Œä¸­è°ƒç”¨
     */
    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
        //log.info("deliveryComplete---------" + Arrays.toString(topic));
    }
    /**
     * æ¶ˆæ¯å¤„理
     */
    @Override
    public void messageArrived(String topic, MqttMessage message) {
        try {
            // subscribe后得到的消息会执行到这里面
            log.info("接收消息 ã€ä¸»é¢˜ã€‘:" + topic + " ã€å†…容】:" + new String(message.getPayload()));
            //进行业务处理
        } catch (Exception e) {
            log.info("处理mqtt消息异常:" + e);
        }
    }
    /**
     * mqtt连接后订阅主题
     */
    @Override
    public void connectComplete(boolean b, String s) {
        try {
            if (null != topic && null != qos) {
                if (client.isConnected()) {
                    client.subscribe(topic, qos);
                    log.info("mqtt连接成功,客户端ID:" + PropertiesUtil.MQTT_CLIENT_ID);
                    log.info("--订阅主题::" + Arrays.toString(topic));
                } else {
                    log.info("mqtt连接失败,客户端ID:" + PropertiesUtil.MQTT_CLIENT_ID);
                }
            }
        } catch (Exception e) {
            log.info("mqtt订阅主题异常:" + e);
        }
    }
}
src/main/java/com/ard/utils/mqtt/PropertiesUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,54 @@
package com.ard.utils.mqtt;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import java.util.Objects;
import java.util.Properties;
/**
 * @Description: èŽ·å–é…ç½®ä¿¡æ¯
 * @ClassName: PropertiesUtil
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´06月06日9:40
 * @Version: 1.0
 **/
@Component
public class PropertiesUtil {
    public static String MQTT_HOST;
    public static String MQTT_CLIENT_ID;
    public static String MQTT_USER_NAME;
    public static String MQTT_PASSWORD;
    public static String MQTT_TOPIC;
    public static Integer MQTT_TIMEOUT;
    public static Integer MQTT_KEEP_ALIVE;
    public static Boolean MQTT_ENABLED;
    static {
        MQTT_HOST = getYmlNew("spring.mqtt.host");
        MQTT_CLIENT_ID = getYmlNew("spring.mqtt.clientId");
        MQTT_USER_NAME = getYmlNew("spring.mqtt.username");
        MQTT_PASSWORD = getYmlNew("spring.mqtt.password");
        MQTT_TOPIC = getYmlNew("spring.mqtt.topic");
        MQTT_TIMEOUT = Integer.valueOf(Objects.requireNonNull(getYmlNew("spring.mqtt.timeout")));
        MQTT_KEEP_ALIVE = Integer.valueOf(Objects.requireNonNull(getYmlNew("spring.mqtt.keepalive")));
        MQTT_ENABLED = Boolean.valueOf(getYmlNew("spring.mqtt.enabled"));
    }
    public static String getYmlNew(String key) {
        Resource resource = new ClassPathResource("application.yml");
        Properties properties;
        try {
            YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
            yamlFactory.setResources(resource);
            properties = yamlFactory.getObject();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        assert properties != null;
        return properties.get(key).toString();
    }
}
src/main/java/com/ard/utils/udp/NettyUdpHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
package com.ard.utils.udp;
import com.ard.alarm.tube.service.TubeAlarmService;
import com.ard.utils.SpringTool;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import lombok.extern.slf4j.Slf4j;
import java.nio.charset.Charset;
@Slf4j(topic = "tube")
public class NettyUdpHandler extends SimpleChannelInboundHandler<DatagramPacket> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) {
        try {
            ByteBuf byteBuf = packet.content();
            String str = byteBuf.toString(Charset.forName("GBK"));
            log.info("udp收到数据: " + str);
            TubeAlarmService tubeAlarmService = (TubeAlarmService) SpringTool.getApplicationContext().getBean("tubeAlarmService");
            tubeAlarmService.alarmHandler(str);
            String resStr = "ok";
            byte[] resBytes = resStr.getBytes(Charset.forName("GBK"));
            DatagramPacket resData = new DatagramPacket(Unpooled.copiedBuffer(resBytes), packet.sender());
            ctx.writeAndFlush(resData);
        } catch (Exception e) {
            log.error("udp接收数据异常:" + e.getMessage());
        }
    }
}
src/main/java/com/ard/utils/udp/NettyUdpServer.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,50 @@
package com.ard.utils.udp;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
@EnableAsync
@Component
@Slf4j(topic = "tube")
public class NettyUdpServer {
    /**
     * å¯åŠ¨æœåŠ¡
     */
    @Async
    public void init(int port) {
        //表示服务器连接监听线程组,专门接受 accept æ–°çš„客户端client è¿žæŽ¥
        EventLoopGroup bossLoopGroup = new NioEventLoopGroup();
        try {
            //1、创建netty bootstrap å¯åŠ¨ç±»
            Bootstrap serverBootstrap = new Bootstrap();
            //2、设置boostrap çš„eventLoopGroup线程组
            serverBootstrap = serverBootstrap.group(bossLoopGroup);
            //3、设置NIO UDP连接通道
            serverBootstrap = serverBootstrap.channel(NioDatagramChannel.class);
            //4、设置通道参数 SO_BROADCAST广播形式
            serverBootstrap = serverBootstrap.option(ChannelOption.SO_BROADCAST, true);
            //5、设置处理类 è£…配流水线
            serverBootstrap = serverBootstrap.handler(new NettyUdpHandler());
            //6、绑定server,通过调用sync()方法异步阻塞,直到绑定成功
            ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
            log.info("started and listened on " + channelFuture.channel().localAddress());
            //7、监听通道关闭事件,应用程序会一直等待,直到channel关闭
            channelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            log.error("error:"+e.getMessage());
        } finally {
            log.info("netty udp close!");
            //8 å…³é—­EventLoopGroup,
            bossLoopGroup.shutdownGracefully();
        }
    }
}
src/main/resources/application.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,34 @@
spring:
  netty:
    port: 40000
    enabled: true
  mqtt:
    host: tcp://192.168.1.15:1883
    clientId: c3
    username: admin
    password: xzx12345
    topic: tube
    timeout: 100
    keepalive: 60
    enabled: true
  stealelec:
    url: http://iot.zhdk.net:8090/Warning/GetWarning?userName=cy4oil
  datasource:
    driver-class-name: org.postgresql.Driver
#    url: jdbc:postgresql://111.40.46.199:15432/ry-vue?stringtype=unspecified
#    username: postgres
#    password: Yykj.2021
    url: jdbc:postgresql://192.168.1.15:5432/ry-vue?stringtype=unspecified
    username: postgres
    password: postgres
mybatis:
  type-aliases-package: com.ard.alarm.camera.domain.ArdCameras
  mapper-locations: classpath:/mapper/*.xml
# minio配置
minio:
  endpoint: http://192.168.1.15:9001
  accessKey: admin
  secretKey: xzx12345
logging:
  level:
    com.ard: info
src/main/resources/logback-spring.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--日志存放路径-->
    <property name="log.path" value="./logs"/>
    <!--日志输出格式-->
    <property name="log.pattern" value="%d{HH:mm:ss.SSS}[%thread]%-5level%logger{20}-[%method,%line]-%msg%n"/>
    <!--控制台输出-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--系统日志输出-->
    <appender name="sys-info" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-info.log</file>
        <!--循环政策:基于时间创建日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件名格式-->
            <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--过滤的级别-->
            <level>INFO</level>
            <!--匹配时的操作:接收(记录)-->
            <onMatch>ACCEPT</onMatch>
            <!--不匹配时的操作:拒绝(不记录)-->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!--管线泄露报警日志输出-->
    <appender name="tube" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/tube.log</file>
        <!--循环政策:基于时间创建日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件名格式-->
            <fileNamePattern>${log.path}/tube.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--过滤的级别-->
            <level>INFO</level>
            <!--匹配时的操作:接收(记录)-->
            <onMatch>ACCEPT</onMatch>
            <!--不匹配时的操作:拒绝(不记录)-->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <root level="DEBUG">
        <appender-ref ref="console"/>
    </root>
    <!--系统操作日志-->
    <root level="INFO">
        <appender-ref ref="sys-info"/>
    </root>
    <!--管线泄露报警操作日志-->
    <root level="INFO">
        <appender-ref ref="tube"/>
    </root>
</configuration>
src/main/resources/mapper/ArdCamerasMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,105 @@
<?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.ard.alarm.camera.mapper.ArdCamerasMapper">
    <resultMap type="com.ard.alarm.camera.domain.ArdCameras" id="ArdCamerasResult">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="ip" column="ip"/>
        <result property="port" column="port"/>
        <result property="rtspPort" column="rtsp_port"/>
        <result property="username" column="username"/>
        <result property="password" column="password"/>
        <result property="gdtype" column="gdtype"/>
        <result property="channel" column="channel"/>
        <result property="longitude" column="longitude"/>
        <result property="latitude" column="latitude"/>
        <result property="altitude" column="altitude"/>
        <result property="userId" column="user_id"/>
        <result property="deptId" column="dept_id"/>
        <result property="camHeading" column="cam_heading"/>
        <result property="camPitch" column="cam_pitch"/>
        <result property="camRoll" column="cam_roll"/>
        <result property="camNear" column="cam_near"/>
        <result property="camFar" column="cam_far"/>
        <result property="camAspectratio" column="cam_aspectratio"/>
        <result property="camDepth" column="cam_depth"/>
        <result property="camFov" column="cam_fov"/>
        <result property="loginId" column="login_id"/>
        <result property="operatorId" column="operator_id"/>
        <result property="operatorExpired" column="operator_expired"/>
        <result property="camMaxVisibleDistance" column="cam_max_visible_distance"/>
        <result property="camAlarmGuideEnable" column="cam_alarm_guide_enable"/>
    </resultMap>
    <sql id="selectArdCamerasVo">
        select c.id,
               c.name,
               c.ip,
               c.port,
               c.rtsp_port,
               c.username,
               c.password,
               c.gdtype,
               c.channel,
               c.longitude,
               c.latitude,
               c.altitude,
               c.user_id,
               c.dept_id,
               c.cam_heading,
               c.cam_pitch,
               c.cam_roll,
               c.cam_near,
               c.cam_far,
               c.cam_aspectratio,
               c.cam_depth,
               c.cam_fov,
               c.operator_id,
               c.operator_expired,
               c.cam_max_visible_distance,
               c.cam_alarm_guide_enable
        from ard_cameras c
    </sql>
    <select id="selectArdCamerasList" parameterType="com.ard.alarm.camera.domain.ArdCameras" resultMap="ArdCamerasResult">
        <include refid="selectArdCamerasVo"/>
        <where>
            <if test="id != null  and id != ''">and c.id = #{id}</if>
            <if test="name != null  and name != ''">and c.name like '%'||#{name}||'%'</if>
            <if test="ip != null  and ip != ''">and c.ip = #{ip}</if>
            <if test="port != null ">and c.port = #{port}</if>
            <if test="rtspPort != null ">and c.rtsp_port = #{rtspPort}</if>
            <if test="username != null  and username != ''">and c.username like '%'||#{username}||'%'</if>
            <if test="password != null  and password != ''">and c.password = #{password}</if>
            <if test="gdtype != null  and gdtype != ''">and c.gdtype = #{gdtype}</if>
            <if test="channel != null ">and c.channel = #{channel}</if>
            <if test="longitude != null ">and c.longitude = #{longitude}</if>
            <if test="latitude != null ">and c.latitude = #{latitude}</if>
            <if test="altitude != null ">and c.altitude = #{altitude}</if>
            <if test="userId != null  and userId != ''">and c.user_id = #{userId}</if>
            <if test="deptId != null ">and (c.dept_id = #{deptId} OR c.dept_id IN ( SELECT t.dept_id FROM sys_dept t
                WHERE cast(#{deptId} as varchar) = any(string_to_array(ancestors,',')) ))
            </if>
            <if test="camHeading != null ">and c.cam_heading = #{camHeading}</if>
            <if test="camPitch != null ">and c.cam_pitch = #{camPitch}</if>
            <if test="camRoll != null ">and c.cam_roll = #{camRoll}</if>
            <if test="camNear != null ">and c.cam_near = #{camNear}</if>
            <if test="camFar != null ">and c.cam_far = #{camFar}</if>
            <if test="camAspectratio != null ">and c.cam_aspectratio = #{camAspectratio}</if>
            <if test="camDepth != null ">and c.cam_depth = #{camDepth}</if>
            <if test="camFov != null ">and c.cam_fov = #{camFov}</if>
            <if test="camMaxVisibleDistance != null ">and c.cam_max_visible_distance = #{camMaxVisibleDistance}</if>
            <if test="camAlarmGuideEnable != null ">and c.cam_alarm_guide_enable = #{camAlarmGuideEnable}</if>
            <if test="loginId != null ">and c.login_id = #{loginId}</if>
        </where>
    </select>
    <select id="selectArdCamerasById" parameterType="String" resultMap="ArdCamerasResult">
        <include refid="selectArdCamerasVo"/>
        where id = #{id}
    </select>
</mapper>