| New file |
| | |
| | | The dll in this directory£¨iconv.dll,libxml2.dll,zlib1.dll,calib.dll£©only used in ClientDemo. |
| New file |
| | |
| | | <?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> |
| New file |
| | |
| | | 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); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | 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; |
| | | } |
| New file |
| | |
| | | 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; |
| | | } |
| New file |
| | |
| | | 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); |
| | | |
| | | } |
| New file |
| | |
| | | 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); |
| | | |
| | | } |
| New file |
| | |
| | | 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); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | 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; |
| | | } |
| New file |
| | |
| | | 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()); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | 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()); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | 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; |
| | | } |
| | | } |
| New file |
| | |
| | | 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(); |
| | | } |
| | | |
| | | } |
| | | |
| New file |
| | |
| | | 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(); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | 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<>(); |
| | | } |
| New file |
| | |
| | | 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; |
| | | } |
| New file |
| | |
| | | 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; |
| | | } |
| New file |
| | |
| | | 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)); |
| | | } |
| | | } |
| New file |
| | |
| | | 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 ""; |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | 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; |
| | | } |
| | | } |
| New file |
| | |
| | | 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; |
| | | } |
| | | } |
| New file |
| | |
| | | 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; |
| | | } |
| | | } |
| New file |
| | |
| | | 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("给图片添加水印文字完毕"); |
| | | // } |
| | | |
| | | |
| New file |
| | |
| | | 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; |
| | | } |
| | | } |
| New file |
| | |
| | | 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); |
| | | } |
| | | } |
| New file |
| | |
| | | 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); |
| | | } |
| | | } |
| New file |
| | |
| | | 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(); |
| | | } |
| | | } |
| | | } |
| | | |
| New file |
| | |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | | |
| New file |
| | |
| | | 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(); |
| | | } |
| | | } |
| New file |
| | |
| | | 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()); |
| | | } |
| | | } |
| | | } |
| | | |
| New file |
| | |
| | | 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(); |
| | | } |
| | | } |
| | | } |
| New file |
| | |
| | | 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 |
| New file |
| | |
| | | <?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> |
| | | |
| New file |
| | |
| | | <?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> |