摄像头回放
This commit is contained in:
@ -309,6 +309,8 @@ springdoc:
|
|||||||
packages-to-scan: org.dromara.mechanical.jxgl
|
packages-to-scan: org.dromara.mechanical.jxgl
|
||||||
- group: 32.设备模块
|
- group: 32.设备模块
|
||||||
packages-to-scan: org.dromara.device
|
packages-to-scan: org.dromara.device
|
||||||
|
- group: 33.摄像头模块
|
||||||
|
packages-to-scan: org.dromara.other
|
||||||
- group: 34.机械安全模块
|
- group: 34.机械安全模块
|
||||||
packages-to-scan: org.dromara.mechanical.jxaqgl
|
packages-to-scan: org.dromara.mechanical.jxaqgl
|
||||||
# knife4j的增强配置,不需要增强可以不配
|
# knife4j的增强配置,不需要增强可以不配
|
||||||
|
|||||||
@ -0,0 +1,146 @@
|
|||||||
|
package org.dromara.common.core.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DatePattern;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间戳转换工具类(包含时分秒提取)
|
||||||
|
*/
|
||||||
|
public class TimestampUtils {
|
||||||
|
|
||||||
|
// 默认时区(东八区)
|
||||||
|
private static final TimeZone DEFAULT_TIME_ZONE = TimeZone.getTimeZone("GMT+8");
|
||||||
|
|
||||||
|
// 完整日期格式
|
||||||
|
private static final String FULL_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
|
||||||
|
// 时分秒格式
|
||||||
|
private static final String TIME_FORMAT = "HH:mm:ss";
|
||||||
|
|
||||||
|
// 日期格式
|
||||||
|
private static final String DATE_FORMAT = "yyyy-MM-dd";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将日期字符串转为秒级时间戳(优化版)
|
||||||
|
* 支持格式:"2025-12-03 23:59:59"、"2025-12-03"等
|
||||||
|
* @param dateStr 日期字符串
|
||||||
|
* @return 秒级时间戳
|
||||||
|
*/
|
||||||
|
public static Long parseDateToTimestamp(String dateStr) {
|
||||||
|
if (StrUtil.isBlank(dateStr)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用Hutool的DateUtil进行智能解析(推荐)
|
||||||
|
try {
|
||||||
|
Date date = DateUtil.parse(dateStr);
|
||||||
|
return date.getTime() / 1000L; // 转为秒级时间戳
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format("日期格式错误:%s,支持格式:yyyy-MM-dd HH:mm:ss、yyyy-MM-dd等", dateStr)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将时间戳转换为完整日期格式(yyyy-MM-dd HH:mm:ss)
|
||||||
|
*/
|
||||||
|
public static String formatTimestamp(Object timestamp) {
|
||||||
|
if (timestamp == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String timestampStr = timestamp.toString().trim();
|
||||||
|
if (StrUtil.isBlank(timestampStr)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Long time = parseToMilliseconds(timestampStr);
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat(FULL_DATE_FORMAT);
|
||||||
|
sdf.setTimeZone(DEFAULT_TIME_ZONE);
|
||||||
|
return sdf.format(new Date(time));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提取时间戳中的时分秒部分(HH:mm:ss)
|
||||||
|
*/
|
||||||
|
public static String extractTime(Object timestamp) {
|
||||||
|
if (timestamp == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String timestampStr = timestamp.toString().trim();
|
||||||
|
if (StrUtil.isBlank(timestampStr)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Long time = parseToMilliseconds(timestampStr);
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT);
|
||||||
|
sdf.setTimeZone(DEFAULT_TIME_ZONE);
|
||||||
|
return sdf.format(new Date(time));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提取时间戳中的日期部分(yyyy-MM-dd)
|
||||||
|
*/
|
||||||
|
public static String extractDate(Object timestamp) {
|
||||||
|
if (timestamp == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String timestampStr = timestamp.toString().trim();
|
||||||
|
if (StrUtil.isBlank(timestampStr)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Long time = parseToMilliseconds(timestampStr);
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
|
||||||
|
sdf.setTimeZone(DEFAULT_TIME_ZONE);
|
||||||
|
return sdf.format(new Date(time));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析时间戳字符串为毫秒级时间戳
|
||||||
|
*/
|
||||||
|
private static Long parseToMilliseconds(String timestampStr) {
|
||||||
|
try {
|
||||||
|
Long time = Long.parseLong(timestampStr);
|
||||||
|
// 10位秒级时间戳转为13位毫秒级
|
||||||
|
if (timestampStr.length() == 10) {
|
||||||
|
time = time * 1000;
|
||||||
|
}
|
||||||
|
return time;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new IllegalArgumentException("时间戳格式错误:" + timestampStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取时间戳对应的小时
|
||||||
|
*/
|
||||||
|
public static int getHour(Object timestamp) {
|
||||||
|
String timeStr = extractTime(timestamp);
|
||||||
|
return Integer.parseInt(timeStr.split(":")[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取时间戳对应的分钟
|
||||||
|
*/
|
||||||
|
public static int getMinute(Object timestamp) {
|
||||||
|
String timeStr = extractTime(timestamp);
|
||||||
|
return Integer.parseInt(timeStr.split(":")[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取时间戳对应的秒
|
||||||
|
*/
|
||||||
|
public static int getSecond(Object timestamp) {
|
||||||
|
String timeStr = extractTime(timestamp);
|
||||||
|
return Integer.parseInt(timeStr.split(":")[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -46,7 +46,7 @@ public class BusComplaintBoxController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* 查询意见箱列表
|
* 查询意见箱列表
|
||||||
*/
|
*/
|
||||||
// @SaCheckPermission("complaintBox:complaintBox:list")
|
@SaCheckPermission("complaintBox:complaintBox:list")
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
public TableDataInfo<BusComplaintBoxVo> list(BusComplaintBoxBo bo, PageQuery pageQuery) {
|
public TableDataInfo<BusComplaintBoxVo> list(BusComplaintBoxBo bo, PageQuery pageQuery) {
|
||||||
return busComplaintBoxService.queryPageList(bo, pageQuery);
|
return busComplaintBoxService.queryPageList(bo, pageQuery);
|
||||||
@ -54,7 +54,7 @@ public class BusComplaintBoxController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* web获取各个处理状态数量
|
* web获取各个处理状态数量
|
||||||
*/
|
*/
|
||||||
// @SaCheckPermission("complaintBox:complaintBox:list")
|
@SaCheckPermission("complaintBox:complaintBox:list")
|
||||||
@GetMapping("/getCount")
|
@GetMapping("/getCount")
|
||||||
public R<List<ComplaintBoxCountVo>> getCount(BusComplaintBoxBo bo) {
|
public R<List<ComplaintBoxCountVo>> getCount(BusComplaintBoxBo bo) {
|
||||||
return R.ok(busComplaintBoxService.getCount(bo));
|
return R.ok(busComplaintBoxService.getCount(bo));
|
||||||
@ -75,7 +75,7 @@ public class BusComplaintBoxController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* 新增意见回复
|
* 新增意见回复
|
||||||
*/
|
*/
|
||||||
// @SaCheckPermission("complaintBox:complaintBox:add")
|
@SaCheckPermission("complaintBox:complaintBox:add")
|
||||||
@Log(title = "意见箱", businessType = BusinessType.INSERT)
|
@Log(title = "意见箱", businessType = BusinessType.INSERT)
|
||||||
@RepeatSubmit()
|
@RepeatSubmit()
|
||||||
@PostMapping("/postAReply")
|
@PostMapping("/postAReply")
|
||||||
@ -87,7 +87,7 @@ public class BusComplaintBoxController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* 修改意见阅读状态
|
* 修改意见阅读状态
|
||||||
*/
|
*/
|
||||||
// @SaCheckPermission("complaintBox:complaintBox:edit")
|
@SaCheckPermission("complaintBox:complaintBox:edit")
|
||||||
@Log(title = "意见箱", businessType = BusinessType.UPDATE)
|
@Log(title = "意见箱", businessType = BusinessType.UPDATE)
|
||||||
@RepeatSubmit()
|
@RepeatSubmit()
|
||||||
@PutMapping("/editCheckStatus")
|
@PutMapping("/editCheckStatus")
|
||||||
@ -98,7 +98,7 @@ public class BusComplaintBoxController extends BaseController {
|
|||||||
/**
|
/**
|
||||||
* 修改意见阅读状态
|
* 修改意见阅读状态
|
||||||
*/
|
*/
|
||||||
// @SaCheckPermission("complaintBox:complaintBox:edit")
|
@SaCheckPermission("complaintBox:complaintBox:edit")
|
||||||
@Log(title = "意见箱", businessType = BusinessType.UPDATE)
|
@Log(title = "意见箱", businessType = BusinessType.UPDATE)
|
||||||
@RepeatSubmit()
|
@RepeatSubmit()
|
||||||
@PutMapping("/editStatus")
|
@PutMapping("/editStatus")
|
||||||
|
|||||||
@ -327,7 +327,13 @@ public class BusComplaintBoxServiceImpl extends ServiceImpl<BusComplaintBoxMappe
|
|||||||
if ("14".equals(busComplaintBoxVo.getStatus())){
|
if ("14".equals(busComplaintBoxVo.getStatus())){
|
||||||
throw new ServiceException("该意见已经关闭,不允许再修改状态");
|
throw new ServiceException("该意见已经关闭,不允许再修改状态");
|
||||||
}
|
}
|
||||||
return baseMapper.update(new LambdaUpdateWrapper<BusComplaintBox>().set(BusComplaintBox::getStatus,bo.getStatus()).eq(BusComplaintBox::getId, bo.getId()));
|
LambdaUpdateWrapper<BusComplaintBox> lqw = new LambdaUpdateWrapper<BusComplaintBox>();
|
||||||
|
lqw.set(BusComplaintBox::getStatus, bo.getStatus());
|
||||||
|
lqw.eq(BusComplaintBox::getId, bo.getId());
|
||||||
|
if ("0".equals(bo.getStatus())){
|
||||||
|
lqw.set(BusComplaintBox::getCurrentDisposeUserId, null);
|
||||||
|
}
|
||||||
|
return baseMapper.update(lqw);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,4 +61,14 @@ public interface Ys7Constant {
|
|||||||
*/
|
*/
|
||||||
String setDeviceVideoUrlByPost = "https://open.ys7.com/api/lapp/device/fullday/record/switch/set";
|
String setDeviceVideoUrlByPost = "https://open.ys7.com/api/lapp/device/fullday/record/switch/set";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 摄像头查询设备本地录像 Get
|
||||||
|
*/
|
||||||
|
String getDeviceLocalVideoUrlByGet = "https://open.ys7.com/api/v3/device/local/video/unify/query";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取播放地址 POST
|
||||||
|
*/
|
||||||
|
String getDeviceLappVideoUrlByPost = "https://open.ys7.com/api/lapp/v2/live/address/get";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,17 +4,20 @@ import cn.hutool.http.HttpRequest;
|
|||||||
import cn.hutool.http.HttpResponse;
|
import cn.hutool.http.HttpResponse;
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.common.core.constant.HttpStatus;
|
import org.dromara.common.core.constant.HttpStatus;
|
||||||
import org.dromara.common.core.exception.ServiceException;
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
import org.dromara.common.core.utils.StringUtils;
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
import org.dromara.manager.ys7manager.vo.Ys7NoDataResponseVo;
|
import org.dromara.common.core.utils.TimestampUtils;
|
||||||
import org.dromara.manager.ys7manager.vo.Ys7PageResponseVo;
|
import org.dromara.manager.ys7manager.dto.DeviceLocalVideoRequstDto;
|
||||||
import org.dromara.manager.ys7manager.vo.Ys7QueryDeviceResponseVo;
|
import org.dromara.manager.ys7manager.dto.DevicePlayBackUrlRequstDto;
|
||||||
import org.dromara.manager.ys7manager.vo.Ys7ResponseVo;
|
import org.dromara.manager.ys7manager.vo.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author lilemy
|
* @author lilemy
|
||||||
@ -290,4 +293,159 @@ public class Ys7RequestUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取播放地址
|
||||||
|
* @param dto
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getDevicePlayBackUrl(DevicePlayBackUrlRequstDto dto) {
|
||||||
|
if (StringUtils.isAnyBlank(dto.getAccessToken(), dto.getDeviceSerial())) {
|
||||||
|
throw new ServiceException("获取回放录像参数为空", HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
HashMap<String, Object> paramMap = new HashMap<>();
|
||||||
|
paramMap.put("accessToken", dto.getAccessToken());
|
||||||
|
paramMap.put("deviceSerial", dto.getDeviceSerial());
|
||||||
|
if (dto.getChannelNo() != null) {
|
||||||
|
paramMap.put("channelNo", dto.getChannelNo());
|
||||||
|
}
|
||||||
|
if (dto.getQuality() != null) {
|
||||||
|
paramMap.put("quality", dto.getQuality());
|
||||||
|
}
|
||||||
|
if (dto.getProtocol() != null) {
|
||||||
|
paramMap.put("protocol", dto.getProtocol());
|
||||||
|
}
|
||||||
|
if (dto.getStartTime() != null) {
|
||||||
|
paramMap.put("startTime", dto.getStartTime());
|
||||||
|
}
|
||||||
|
if (dto.getEndTime() != null) {
|
||||||
|
paramMap.put("stopTime", dto.getEndTime());
|
||||||
|
}
|
||||||
|
if (dto.getType() != null) {
|
||||||
|
paramMap.put("type", dto.getType());
|
||||||
|
}
|
||||||
|
if (dto.getExpireTime() != null) {
|
||||||
|
paramMap.put("expireTime", dto.getExpireTime());
|
||||||
|
}
|
||||||
|
if (dto.getRecType() != null) {
|
||||||
|
paramMap.put("recType", dto.getRecType());
|
||||||
|
}
|
||||||
|
if (dto.getCode() != null) {
|
||||||
|
paramMap.put("code", dto.getCode());
|
||||||
|
}
|
||||||
|
if (dto.getSupportH265() != null) {
|
||||||
|
paramMap.put("supportH265", dto.getSupportH265());
|
||||||
|
}
|
||||||
|
if (dto.getPlaybackSpeed() != null) {
|
||||||
|
paramMap.put("playbackSpeed", dto.getPlaybackSpeed());
|
||||||
|
}
|
||||||
|
if (dto.getGbchannel() != null) {
|
||||||
|
paramMap.put("gbchannel", dto.getGbchannel());
|
||||||
|
}
|
||||||
|
String errorMsg = "获取回放录像请求失败";
|
||||||
|
try (HttpResponse response = HttpRequest.post(Ys7Constant.getDeviceLappVideoUrlByPost)
|
||||||
|
.form(paramMap)
|
||||||
|
.execute()) {
|
||||||
|
if (!response.isOk()) {
|
||||||
|
log.error("{}:{}", errorMsg, response.getStatus());
|
||||||
|
throw new ServiceException(errorMsg + response.getStatus());
|
||||||
|
}
|
||||||
|
String body = response.body();
|
||||||
|
log.info("本地录像body{}",body);
|
||||||
|
Ys7ResponseVo responseVo = JSONUtil.toBean(body, Ys7ResponseVo.class);
|
||||||
|
if (!responseVo.getCode().equals("200")) {
|
||||||
|
log.error("{},状态码:{},{}", errorMsg, responseVo.getCode(), responseVo.getMsg());
|
||||||
|
throw new ServiceException(errorMsg + responseVo.getMsg());
|
||||||
|
}
|
||||||
|
String data = responseVo.getData();
|
||||||
|
String picUrl = JSONUtil.parseObj(data).getStr("url");
|
||||||
|
log.info("获取回放录像请求成功,设备[{}]回放成功,通道:{},url:{}", dto.getDeviceSerial(), dto.getChannelNo(), picUrl);
|
||||||
|
return picUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询设备某天的本地录像
|
||||||
|
* @param dto
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static List<DeviceLocalVideoRecordsVo> getDeviceLocalVideo(DeviceLocalVideoRequstDto dto) {
|
||||||
|
if (StringUtils.isAnyBlank(dto.getAccessToken(), dto.getDeviceSerial(),dto.getStartTime(), dto.getEndTime())) {
|
||||||
|
throw new ServiceException("查询设备本地录像参数为空", HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
dto.setStartTime(Objects.requireNonNull(TimestampUtils.parseDateToTimestamp(dto.getStartTime())).toString());
|
||||||
|
dto.setEndTime(Objects.requireNonNull(TimestampUtils.parseDateToTimestamp(dto.getEndTime())).toString());
|
||||||
|
List<DeviceLocalVideoRecordsVo> vos = new ArrayList<>();
|
||||||
|
getRexords(dto, vos);
|
||||||
|
return vos;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void getRexords(DeviceLocalVideoRequstDto dto, List<DeviceLocalVideoRecordsVo> vos) {
|
||||||
|
String errorMsg = "查询设备本地录像请求失败";
|
||||||
|
String body = getDevicceLocalVideoBody(dto);
|
||||||
|
log.info("本地录像body{}",body);
|
||||||
|
JSONObject jsonObject = JSONUtil.parseObj(body);
|
||||||
|
DeviceLocalVideoMetaVo meta = JSONUtil.toBean(jsonObject.getJSONObject("meta"), DeviceLocalVideoMetaVo.class);
|
||||||
|
if (!meta.getCode().equals("200")) {
|
||||||
|
log.error("{},状态码:{},{}", errorMsg, meta.getCode(), meta.getMessage());
|
||||||
|
throw new ServiceException(errorMsg + meta.getMessage());
|
||||||
|
}
|
||||||
|
DeviceLocalVideoDataVo data = JSONUtil.toBean(jsonObject.getJSONObject("data"), DeviceLocalVideoDataVo.class);
|
||||||
|
if (data != null) {
|
||||||
|
List<DeviceLocalVideoRecordsVo> list = JSONUtil.toList(data.getRecords(), DeviceLocalVideoRecordsVo.class);
|
||||||
|
if (list != null && !list.isEmpty()) {
|
||||||
|
list.forEach(vo -> {
|
||||||
|
vo.setStartTime(TimestampUtils.extractTime(vo.getStartTime()));
|
||||||
|
vo.setEndTime(TimestampUtils.extractTime(vo.getEndTime()));
|
||||||
|
});
|
||||||
|
vos.addAll(list);
|
||||||
|
}
|
||||||
|
if (data.getHasMore()){
|
||||||
|
dto.setStartTime(data.getNextFileTime());
|
||||||
|
if (Long.parseLong(dto.getStartTime()) > Long.parseLong(dto.getEndTime())){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
getRexords(dto, vos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getDevicceLocalVideoBody(DeviceLocalVideoRequstDto dto) {
|
||||||
|
// 2. 构建Header参数(接口文档的Header部分)
|
||||||
|
HttpRequest request = HttpRequest.get(Ys7Constant.getDeviceLocalVideoUrlByGet)
|
||||||
|
.header("accessToken", dto.getAccessToken()) // Header参数:accessToken
|
||||||
|
.header("deviceSerial", dto.getDeviceSerial());// Header参数:deviceSerial
|
||||||
|
// 可选Header:localIndex(对应dto的channelNo)
|
||||||
|
if (dto.getChannelNo() != null) {
|
||||||
|
request.header("channelNo", dto.getChannelNo().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 构建Query参数(接口文档的query部分)
|
||||||
|
request.form("startTime", dto.getStartTime()) // Query必传:startTime
|
||||||
|
.form("endTime", dto.getEndTime()); // Query必传:endTime
|
||||||
|
// 可选Query参数
|
||||||
|
if (dto.getRecordType() != null) {
|
||||||
|
request.form("recordType", dto.getRecordType().toString());
|
||||||
|
}
|
||||||
|
if (dto.getIsQueryByNvr() != null) {
|
||||||
|
request.form("isQueryByNvr", dto.getIsQueryByNvr().toString());
|
||||||
|
}
|
||||||
|
if (dto.getLocation() != null) {
|
||||||
|
request.form("location", dto.getLocation().toString());
|
||||||
|
}
|
||||||
|
if (dto.getPageSize() != null) {
|
||||||
|
request.form("pageSize", dto.getPageSize().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
String errorMsg = "查询设备本地录像请求失败";
|
||||||
|
try (HttpResponse response = request.execute()) {
|
||||||
|
if (!response.isOk()) {
|
||||||
|
log.error("{}:{}", errorMsg, response.getStatus());
|
||||||
|
throw new ServiceException(errorMsg + response.getStatus());
|
||||||
|
}
|
||||||
|
return response.body();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,18 @@
|
|||||||
|
package org.dromara.manager.ys7manager.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DeviceLocalVideoRequstDto implements Serializable {
|
||||||
|
private String accessToken; //toke
|
||||||
|
private String deviceSerial; //设备序列号
|
||||||
|
private Integer channelNo; // 通道号,默认1
|
||||||
|
private Integer recordType; // 1:定时录像 2:事件录像 3:智能-车 4:智能-人形 5:自动浓缩录像,不填默认查询所有类型
|
||||||
|
private String startTime; // 回放开始时间(格式:yyyy-MM-dd HH:mm:ss)
|
||||||
|
private String endTime; // 回放结束时间(格式:yyyy-MM-dd HH:mm:ss)
|
||||||
|
private Integer isQueryByNvr; // 是否反查NVR录像:0-不反查(默认),1-反查NVR
|
||||||
|
private Integer location; // 录像检索位置:1-本地录像检索(默认),2-CVR中心录像检索
|
||||||
|
private Integer pageSize; // 分页的页面大小,默认50,最大200
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
package org.dromara.manager.ys7manager.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DevicePlayBackUrlRequstDto implements Serializable {
|
||||||
|
private String accessToken; //toke
|
||||||
|
private String deviceSerial; //设备序列号
|
||||||
|
private Integer channelNo; // 通道号,默认1
|
||||||
|
private Integer protocol; // 流协议:1-ezopen、2-hls、3-rtmp、4-flv,默认1
|
||||||
|
private String code; // 视频加密密码
|
||||||
|
private Integer expireTime; // 过期时长(秒),30秒-720天
|
||||||
|
private String type; // 地址类型:1-预览,2-本地录像回放,3-云存储录像回放,默认1
|
||||||
|
private Integer quality; // 清晰度:1-高清,2-流畅
|
||||||
|
private String startTime; // 回放开始时间(格式:yyyy-MM-dd HH:mm:ss)
|
||||||
|
private String endTime; // 回放结束时间(格式:yyyy-MM-dd HH:mm:ss)
|
||||||
|
private Integer supportH265; // 是否需要H265编码:1-是,0-否
|
||||||
|
private Integer recType; // 回放源,0-系统自动选择,1-云存储,2-本地录像。非必选,默认为0
|
||||||
|
private String playbackSpeed; // 回放倍速:-1、0.5、1、2、4、8、16(仅支持flv协议+回放类型)
|
||||||
|
private String gbchannel; // 国标设备通道编号
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
package org.dromara.manager.ys7manager.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lilemy
|
||||||
|
* @date 2025/6/12 17:14
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class DeviceLocalVideoDataVo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应内容
|
||||||
|
*/
|
||||||
|
private String records;
|
||||||
|
|
||||||
|
//该录像文件是否来自关联的nvr
|
||||||
|
private String fromNvr;
|
||||||
|
|
||||||
|
// fromNvr为true,则返回关联NVR设备序列号,否则返回入参填的设备序列号。
|
||||||
|
private String deviceSerial;
|
||||||
|
// fromNvr为true,则返回关联NVR设备通道号,否则返回入参填的设备通道号
|
||||||
|
private String localIndex;
|
||||||
|
//是否存在更多录像文件
|
||||||
|
private Boolean hasMore;
|
||||||
|
// hasMore为true时,该参数值为下一个录像文件的开始时间。如需分页查询,该参数值可作为下一页录像文件查询的开始时间。
|
||||||
|
private String nextFileTime;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package org.dromara.manager.ys7manager.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lilemy
|
||||||
|
* @date 2025/6/12 17:14
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class DeviceLocalVideoMetaVo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应码
|
||||||
|
*/
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应信息
|
||||||
|
*/
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应信息
|
||||||
|
*/
|
||||||
|
private String moreInfo;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package org.dromara.manager.ys7manager.vo;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lilemy
|
||||||
|
* @date 2025/6/12 17:14
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class DeviceLocalVideoRecordsVo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始时间
|
||||||
|
*/
|
||||||
|
private String startTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束时间
|
||||||
|
*/
|
||||||
|
private String endTime;
|
||||||
|
|
||||||
|
//录像类型
|
||||||
|
private String type;
|
||||||
|
//录像文件大小,单位:字节
|
||||||
|
private String size;
|
||||||
|
|
||||||
|
}
|
||||||
@ -8,6 +8,7 @@ import jakarta.validation.constraints.NotEmpty;
|
|||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.common.core.domain.R;
|
import org.dromara.common.core.domain.R;
|
||||||
|
import org.dromara.common.core.exception.ServiceException;
|
||||||
import org.dromara.common.core.validate.EditGroup;
|
import org.dromara.common.core.validate.EditGroup;
|
||||||
import org.dromara.common.excel.utils.ExcelUtil;
|
import org.dromara.common.excel.utils.ExcelUtil;
|
||||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||||
@ -17,9 +18,20 @@ import org.dromara.common.mybatis.core.page.PageQuery;
|
|||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.common.web.core.BaseController;
|
import org.dromara.common.web.core.BaseController;
|
||||||
import org.dromara.manager.ys7manager.Ys7Manager;
|
import org.dromara.manager.ys7manager.Ys7Manager;
|
||||||
|
import org.dromara.manager.ys7manager.dto.DeviceLocalVideoRequstDto;
|
||||||
|
import org.dromara.manager.ys7manager.vo.DeviceLocalVideoRecordsVo;
|
||||||
import org.dromara.other.domain.dto.ys7device.*;
|
import org.dromara.other.domain.dto.ys7device.*;
|
||||||
|
import org.dromara.other.domain.dto.ys7deviceimg.AddViolattionRecordReq;
|
||||||
|
import org.dromara.other.domain.dto.ys7deviceimg.OthYs7DeviceImgCaptureReq;
|
||||||
|
import org.dromara.other.domain.dto.ys7deviceimg.OthYs7DeviceImgQueryReq;
|
||||||
|
import org.dromara.other.domain.vo.ys7device.DateAndDeviceLocalVideoVo;
|
||||||
import org.dromara.other.domain.vo.ys7device.OthYs7DeviceVo;
|
import org.dromara.other.domain.vo.ys7device.OthYs7DeviceVo;
|
||||||
|
import org.dromara.other.domain.vo.ys7deviceimg.OthYs7DeviceImgVo;
|
||||||
|
import org.dromara.other.service.IOthYs7DeviceImgService;
|
||||||
import org.dromara.other.service.IOthYs7DeviceService;
|
import org.dromara.other.service.IOthYs7DeviceService;
|
||||||
|
import org.dromara.safety.domain.vo.violationrecord.HseViolationRecordVo;
|
||||||
|
import org.dromara.safety.service.IHseViolationRecordService;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@ -46,6 +58,73 @@ public class OthYs7DeviceController extends BaseController {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private Ys7Manager ys7Manager;
|
private Ys7Manager ys7Manager;
|
||||||
|
@Resource
|
||||||
|
private IOthYs7DeviceImgService othYs7DeviceImgService;
|
||||||
|
@Lazy
|
||||||
|
@Resource
|
||||||
|
private IHseViolationRecordService hseViolationRecordService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取违规记录详细信息
|
||||||
|
*
|
||||||
|
* @param id 主键
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("other:ys7Device:list")
|
||||||
|
@GetMapping("/getViolationRecordInfo/{id}")
|
||||||
|
public R<HseViolationRecordVo> getViolationRecordInfo(@NotNull(message = "主键不能为空")
|
||||||
|
@PathVariable Long id) {
|
||||||
|
return R.ok(hseViolationRecordService.queryById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 萤石摄像头图片抓图
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("other:ys7Device:list")
|
||||||
|
@Log(title = "萤石摄像头图片", businessType = BusinessType.INSERT)
|
||||||
|
@PostMapping("/capture")
|
||||||
|
public R<Void> capture(@RequestBody OthYs7DeviceImgCaptureReq req) {
|
||||||
|
return toAjax(othYs7DeviceImgService.addHMCapturePic(req));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 萤石摄像头图片识别
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("other:ys7Device:list")
|
||||||
|
@Log(title = "萤石摄像头图片", businessType = BusinessType.INSERT)
|
||||||
|
@PostMapping("/discernImg")
|
||||||
|
public R<Void> discernImg(@RequestBody OthYs7DeviceImgCaptureReq req) {
|
||||||
|
return toAjax(othYs7DeviceImgService.discernImg(req));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下发工单
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("other:ys7Device:list")
|
||||||
|
@Log(title = "萤石摄像头图片", businessType = BusinessType.INSERT)
|
||||||
|
@PostMapping("/addViolationRecord")
|
||||||
|
public R<Void> addViolationRecord(@RequestBody AddViolattionRecordReq req) {
|
||||||
|
return toAjax(othYs7DeviceImgService.addViolationRecord(req));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 查询萤石摄像头图片列表
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("other:ys7Device:list")
|
||||||
|
@GetMapping("/getImgList")
|
||||||
|
public TableDataInfo<OthYs7DeviceImgVo> list(OthYs7DeviceImgQueryReq req, PageQuery pageQuery) {
|
||||||
|
return othYs7DeviceImgService.queryPageList(req, pageQuery);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 删除萤石摄像头图片
|
||||||
|
*
|
||||||
|
* @param ids 主键串
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("other:ys7Device:remove")
|
||||||
|
@Log(title = "萤石摄像头图片", businessType = BusinessType.DELETE)
|
||||||
|
@DeleteMapping("/img/{ids}")
|
||||||
|
public R<Void> imgRemove(@NotEmpty(message = "主键不能为空")
|
||||||
|
@PathVariable Long[] ids) {
|
||||||
|
return toAjax(othYs7DeviceImgService.deleteWithValidByIds(List.of(ids)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询萤石摄像头列表
|
* 查询萤石摄像头列表
|
||||||
@ -157,4 +236,50 @@ public class OthYs7DeviceController extends BaseController {
|
|||||||
return ResponseEntity.ok(JSONUtil.toJsonStr(result));
|
return ResponseEntity.ok(JSONUtil.toJsonStr(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取回放录像播放地址
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/getPlayBackUrl")
|
||||||
|
public R<String> getPlayBackUrl(OthYs7DevicePlayBackUrlReq req){
|
||||||
|
if (req.getDeviceSerial() == null){
|
||||||
|
throw new ServiceException("设备序列号不能为空!!!");
|
||||||
|
}
|
||||||
|
if (req.getStartTime() == null || req.getEndTime() == null){
|
||||||
|
throw new ServiceException("开始时间和结束时间不能为空!!!");
|
||||||
|
}
|
||||||
|
return R.ok(othYs7DeviceService.getPlayBackUrl(req));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询设备本地录像
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/getDeviceLocalVideo")
|
||||||
|
public R<List<DeviceLocalVideoRecordsVo>> getDeviceLocalVideo(OthYs7DevicePlayBackUrlReq req){
|
||||||
|
if (req.getDeviceSerial() == null){
|
||||||
|
throw new ServiceException("设备序列号不能为空!!!");
|
||||||
|
}
|
||||||
|
if (req.getStartTime() == null || req.getEndTime() == null){
|
||||||
|
throw new ServiceException("开始时间和结束时间不能为空!!!");
|
||||||
|
}
|
||||||
|
return R.ok(othYs7DeviceService.getDeviceLocalVideo(req));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询范围日期和设备本地录像列表
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/getDateAndDeviceLocalVideo")
|
||||||
|
public R<DateAndDeviceLocalVideoVo> getDateAndDeviceLocalVideo(OthYs7DevicePlayBackUrlReq req){
|
||||||
|
if (req.getDeviceSerial() == null){
|
||||||
|
throw new ServiceException("设备序列号不能为空!!!");
|
||||||
|
}
|
||||||
|
if (req.getStartTime() == null || req.getEndTime() == null){
|
||||||
|
throw new ServiceException("开始时间和结束时间不能为空!!!");
|
||||||
|
}
|
||||||
|
return R.ok(othYs7DeviceService.getDateAndDeviceLocalVideo(req));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,6 +72,12 @@ public class OthYs7DeviceImg implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private String recognizeUrl;
|
private String recognizeUrl;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片状态(0、未识别,1、已识别未违规,2、已识别有违规,3、已下发工单)
|
||||||
|
*/
|
||||||
|
private String imgStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 备注
|
* 备注
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
package org.dromara.other.domain.dto.ys7device;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lilemy
|
||||||
|
* @date 2025/6/13 10:19
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class OthYs7DevicePlayBackUrlReq implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备序列号
|
||||||
|
*/
|
||||||
|
private String deviceSerial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始时间
|
||||||
|
*/
|
||||||
|
private String startTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束时间
|
||||||
|
*/
|
||||||
|
private String endTime;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package org.dromara.other.domain.dto.ys7deviceimg;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lilemy
|
||||||
|
* @date 2025-10-10 19:14
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class AddViolattionRecordReq implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 项目id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "图片id不能为空")
|
||||||
|
private Long projectId;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设备序列号
|
||||||
|
*/
|
||||||
|
@NotBlank(message = "设备序列号不能为空")
|
||||||
|
private String deviceSerial;
|
||||||
|
/**
|
||||||
|
* 图片id
|
||||||
|
*/
|
||||||
|
@NotNull(message = "图片id不能为空")
|
||||||
|
private Long originalUrlId;
|
||||||
|
|
||||||
|
}
|
||||||
@ -21,4 +21,8 @@ public class OthYs7DeviceImgCaptureReq implements Serializable {
|
|||||||
*/
|
*/
|
||||||
@NotBlank(message = "设备序列号不能为空")
|
@NotBlank(message = "设备序列号不能为空")
|
||||||
private String deviceSerial;
|
private String deviceSerial;
|
||||||
|
/**
|
||||||
|
* 图片id
|
||||||
|
*/
|
||||||
|
private Long imgId;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,29 @@
|
|||||||
|
package org.dromara.other.domain.vo.ys7device;
|
||||||
|
|
||||||
|
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
|
import io.github.linpeilie.annotations.AutoMapper;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.dromara.common.translation.annotation.Translation;
|
||||||
|
import org.dromara.common.translation.constant.TransConstant;
|
||||||
|
import org.dromara.manager.ys7manager.vo.DeviceLocalVideoRecordsVo;
|
||||||
|
import org.dromara.other.domain.OthYs7Device;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询范围日期和设备本地录像列表
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class DateAndDeviceLocalVideoVo implements Serializable {
|
||||||
|
|
||||||
|
private List<String> dateList;
|
||||||
|
|
||||||
|
private List<DeviceLocalVideoRecordsVo> deviceList;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -55,6 +55,11 @@ public class OthYs7DeviceImgVo implements Serializable {
|
|||||||
@ExcelProperty(value = "图片地址")
|
@ExcelProperty(value = "图片地址")
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 识别结果图片地址
|
||||||
|
*/
|
||||||
|
private String recognizeUrl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 识别算法模型
|
* 识别算法模型
|
||||||
*/
|
*/
|
||||||
@ -77,4 +82,9 @@ public class OthYs7DeviceImgVo implements Serializable {
|
|||||||
@ExcelProperty(value = "创建时间")
|
@ExcelProperty(value = "创建时间")
|
||||||
private Date createTime;
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片状态(0、未识别,1、已识别,2、已下发工单)
|
||||||
|
*/
|
||||||
|
private String imgStatus;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
|||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.other.domain.OthYs7DeviceImg;
|
import org.dromara.other.domain.OthYs7DeviceImg;
|
||||||
|
import org.dromara.other.domain.dto.ys7deviceimg.AddViolattionRecordReq;
|
||||||
import org.dromara.other.domain.dto.ys7deviceimg.OthYs7DeviceImgCaptureReq;
|
import org.dromara.other.domain.dto.ys7deviceimg.OthYs7DeviceImgCaptureReq;
|
||||||
import org.dromara.other.domain.dto.ys7deviceimg.OthYs7DeviceImgCreateByCapture;
|
import org.dromara.other.domain.dto.ys7deviceimg.OthYs7DeviceImgCreateByCapture;
|
||||||
import org.dromara.other.domain.dto.ys7deviceimg.OthYs7DeviceImgQueryReq;
|
import org.dromara.other.domain.dto.ys7deviceimg.OthYs7DeviceImgQueryReq;
|
||||||
@ -102,4 +103,25 @@ public interface IOthYs7DeviceImgService extends IService<OthYs7DeviceImg> {
|
|||||||
* @return 是否抓拍成功
|
* @return 是否抓拍成功
|
||||||
*/
|
*/
|
||||||
Boolean capturePic(OthYs7DeviceImgCaptureReq req);
|
Boolean capturePic(OthYs7DeviceImgCaptureReq req);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手动抓拍(不需要识别)
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int addHMCapturePic(OthYs7DeviceImgCaptureReq req);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 识别抓拍图片
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int discernImg(OthYs7DeviceImgCaptureReq req);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手动下发安全工单
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
int addViolationRecord(AddViolattionRecordReq req);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,9 +5,11 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
|
import org.dromara.manager.ys7manager.vo.DeviceLocalVideoRecordsVo;
|
||||||
import org.dromara.manager.ys7manager.vo.Ys7QueryDeviceResponseVo;
|
import org.dromara.manager.ys7manager.vo.Ys7QueryDeviceResponseVo;
|
||||||
import org.dromara.other.domain.OthYs7Device;
|
import org.dromara.other.domain.OthYs7Device;
|
||||||
import org.dromara.other.domain.dto.ys7device.*;
|
import org.dromara.other.domain.dto.ys7device.*;
|
||||||
|
import org.dromara.other.domain.vo.ys7device.DateAndDeviceLocalVideoVo;
|
||||||
import org.dromara.other.domain.vo.ys7device.OthYs7DeviceVo;
|
import org.dromara.other.domain.vo.ys7device.OthYs7DeviceVo;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -143,4 +145,24 @@ public interface IOthYs7DeviceService extends IService<OthYs7Device> {
|
|||||||
*/
|
*/
|
||||||
void webhook(WebhookMessage receiveMessage);
|
void webhook(WebhookMessage receiveMessage);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取回放录像播放地址
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
String getPlayBackUrl(OthYs7DevicePlayBackUrlReq req);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询设备本地录像
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<DeviceLocalVideoRecordsVo> getDeviceLocalVideo(OthYs7DevicePlayBackUrlReq req);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询范围日期和设备本地录像列表
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
DateAndDeviceLocalVideoVo getDateAndDeviceLocalVideo(OthYs7DevicePlayBackUrlReq req);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import org.dromara.manager.ys7manager.Ys7Manager;
|
|||||||
import org.dromara.other.constant.Ys7DeviceImgConstant;
|
import org.dromara.other.constant.Ys7DeviceImgConstant;
|
||||||
import org.dromara.other.domain.OthYs7Device;
|
import org.dromara.other.domain.OthYs7Device;
|
||||||
import org.dromara.other.domain.OthYs7DeviceImg;
|
import org.dromara.other.domain.OthYs7DeviceImg;
|
||||||
|
import org.dromara.other.domain.dto.ys7deviceimg.AddViolattionRecordReq;
|
||||||
import org.dromara.other.domain.dto.ys7deviceimg.OthYs7DeviceImgCaptureReq;
|
import org.dromara.other.domain.dto.ys7deviceimg.OthYs7DeviceImgCaptureReq;
|
||||||
import org.dromara.other.domain.dto.ys7deviceimg.OthYs7DeviceImgCreateByCapture;
|
import org.dromara.other.domain.dto.ys7deviceimg.OthYs7DeviceImgCreateByCapture;
|
||||||
import org.dromara.other.domain.dto.ys7deviceimg.OthYs7DeviceImgQueryReq;
|
import org.dromara.other.domain.dto.ys7deviceimg.OthYs7DeviceImgQueryReq;
|
||||||
@ -31,14 +32,18 @@ import org.dromara.other.domain.vo.ys7deviceimg.OthYs7DeviceImgVo;
|
|||||||
import org.dromara.other.mapper.OthYs7DeviceImgMapper;
|
import org.dromara.other.mapper.OthYs7DeviceImgMapper;
|
||||||
import org.dromara.other.service.IOthYs7DeviceImgService;
|
import org.dromara.other.service.IOthYs7DeviceImgService;
|
||||||
import org.dromara.other.service.IOthYs7DeviceService;
|
import org.dromara.other.service.IOthYs7DeviceService;
|
||||||
|
import org.dromara.safety.domain.HseRecognizeRecord;
|
||||||
import org.dromara.safety.domain.HseViolationLevel;
|
import org.dromara.safety.domain.HseViolationLevel;
|
||||||
import org.dromara.safety.domain.dto.recognizerecord.HseRecognizeRecordCreateDto;
|
import org.dromara.safety.domain.dto.recognizerecord.HseRecognizeRecordCreateDto;
|
||||||
|
import org.dromara.safety.domain.dto.violationrecord.HseViolationRecordCreateDto;
|
||||||
import org.dromara.safety.domain.enums.HseRecordCategoryEnum;
|
import org.dromara.safety.domain.enums.HseRecordCategoryEnum;
|
||||||
import org.dromara.safety.service.IHseRecognizeRecordService;
|
import org.dromara.safety.service.IHseRecognizeRecordService;
|
||||||
import org.dromara.safety.service.IHseViolationLevelService;
|
import org.dromara.safety.service.IHseViolationLevelService;
|
||||||
|
import org.dromara.safety.service.IHseViolationRecordService;
|
||||||
import org.dromara.system.domain.vo.SysOssUploadVo;
|
import org.dromara.system.domain.vo.SysOssUploadVo;
|
||||||
import org.dromara.system.service.ISysOssService;
|
import org.dromara.system.service.ISysOssService;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@ -79,6 +84,10 @@ public class OthYs7DeviceImgServiceImpl extends ServiceImpl<OthYs7DeviceImgMappe
|
|||||||
@Resource
|
@Resource
|
||||||
private Ys7Manager ys7Manager;
|
private Ys7Manager ys7Manager;
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Resource
|
||||||
|
private IHseViolationRecordService violationRecordService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询萤石摄像头图片
|
* 查询萤石摄像头图片
|
||||||
*
|
*
|
||||||
@ -266,7 +275,12 @@ public class OthYs7DeviceImgServiceImpl extends ServiceImpl<OthYs7DeviceImgMappe
|
|||||||
}
|
}
|
||||||
if (CollUtil.isEmpty(recTypes)) {
|
if (CollUtil.isEmpty(recTypes)) {
|
||||||
log.error("项目:{},未设置安全等级", img.getProjectId());
|
log.error("项目:{},未设置安全等级", img.getProjectId());
|
||||||
saveList.add(othYs7DeviceImg);
|
boolean save = this.save(othYs7DeviceImg);
|
||||||
|
if (!save) {
|
||||||
|
log.error("保存图片失败:{}", othYs7DeviceImg);
|
||||||
|
} else {
|
||||||
|
saveList.add(othYs7DeviceImg);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RecognizeVo recognizeVo = null;
|
RecognizeVo recognizeVo = null;
|
||||||
@ -412,6 +426,175 @@ public class OthYs7DeviceImgServiceImpl extends ServiceImpl<OthYs7DeviceImgMappe
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public int addHMCapturePic(OthYs7DeviceImgCaptureReq req) {
|
||||||
|
OthYs7Device ys7Device = ys7DeviceService.lambdaQuery()
|
||||||
|
.eq(OthYs7Device::getDeviceSerial, req.getDeviceSerial())
|
||||||
|
.last("limit 1")
|
||||||
|
.one();
|
||||||
|
if (ys7Device == null) {
|
||||||
|
throw new ServiceException("设备不存在", HttpStatus.ERROR);
|
||||||
|
}
|
||||||
|
String deviceSerial = ys7Device.getDeviceSerial();
|
||||||
|
String url = null;
|
||||||
|
try {
|
||||||
|
url = ys7Manager.getCaptureDevicePic(deviceSerial, 1, 2);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("摄像头 {} 抓图失败:{}", deviceSerial, e.getMessage());
|
||||||
|
throw new ServiceException("摄像头 " + deviceSerial + " 抓图失败:" + e.getMessage(), HttpStatus.ERROR);
|
||||||
|
}
|
||||||
|
OthYs7DeviceImg othYs7DeviceImg = new OthYs7DeviceImg();
|
||||||
|
String originalFilename = extractFilename(url);
|
||||||
|
String deviceImgOssPath = Ys7DeviceImgConstant.getDeviceImgOssPath(originalFilename, deviceSerial);
|
||||||
|
SysOssUploadVo uploadVo = ossService.uploadFileUrlWithNoSave(url, deviceImgOssPath);
|
||||||
|
String ossUrl = uploadVo.getUrl();
|
||||||
|
if (StringUtils.isNotBlank(ossUrl)) {
|
||||||
|
othYs7DeviceImg.setProjectId(ys7Device.getProjectId());
|
||||||
|
othYs7DeviceImg.setDeviceSerial(deviceSerial);
|
||||||
|
othYs7DeviceImg.setCreateTime(new Date());
|
||||||
|
othYs7DeviceImg.setDeviceName(ys7Device.getDeviceName());
|
||||||
|
othYs7DeviceImg.setUrl(ossUrl);
|
||||||
|
othYs7DeviceImg.setImgStatus("0");
|
||||||
|
}
|
||||||
|
return baseMapper.insert(othYs7DeviceImg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public int discernImg(OthYs7DeviceImgCaptureReq req) {
|
||||||
|
OthYs7DeviceImg img = baseMapper.selectById(req.getImgId());
|
||||||
|
if (img == null) {
|
||||||
|
throw new ServiceException("识别图片不存在!!");
|
||||||
|
}
|
||||||
|
// 获取安全等级设置
|
||||||
|
List<HseViolationLevel> levelList = violationLevelService.lambdaQuery()
|
||||||
|
.eq(HseViolationLevel::getProjectId, img.getProjectId())
|
||||||
|
.list();
|
||||||
|
Map<Long, List<RecognizerTypeEnum>> level = new HashMap<>();
|
||||||
|
if (CollUtil.isNotEmpty(levelList)) {
|
||||||
|
Map<Long, List<HseViolationLevel>> levelMap = levelList.stream()
|
||||||
|
.collect(Collectors.groupingBy(HseViolationLevel::getProjectId));
|
||||||
|
for (Map.Entry<Long, List<HseViolationLevel>> entry : levelMap.entrySet()) {
|
||||||
|
List<RecognizerTypeEnum> recognizerTypeEnums = entry.getValue().stream().map(l -> {
|
||||||
|
List<String> levels = StringUtils.splitList(l.getViolationType());
|
||||||
|
return RecognizerTypeEnum.listFromCodes(levels);
|
||||||
|
}).filter(CollUtil::isNotEmpty)
|
||||||
|
.flatMap(Collection::stream)
|
||||||
|
.distinct()
|
||||||
|
.toList();
|
||||||
|
level.put(entry.getKey(), recognizerTypeEnums);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (CollUtil.isEmpty(level)) {
|
||||||
|
log.error("未设置安全等级");
|
||||||
|
}
|
||||||
|
// 将抓取的图片进行识别
|
||||||
|
List<RecognizerTypeEnum> recTypes = new ArrayList<>();
|
||||||
|
if (CollUtil.isNotEmpty(level)) {
|
||||||
|
recTypes = level.get(img.getProjectId());
|
||||||
|
}
|
||||||
|
if (CollUtil.isEmpty(recTypes)) {
|
||||||
|
log.error("项目:{},未设置安全等级", img.getProjectId());
|
||||||
|
throw new ServiceException("项目未设置安全等级无法识别,请设置安全等级之后再进行识别");
|
||||||
|
}
|
||||||
|
RecognizeVo recognizeVo = null;
|
||||||
|
try {
|
||||||
|
recognizeVo = recognizerManager.recognize(img.getUrl(), recTypes);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("图片识别异常", e);
|
||||||
|
}
|
||||||
|
if (recognizeVo != null && recognizeVo.getHasTarget().equals(RecognizerHasTargetEnum.YES.getValue())) {
|
||||||
|
// 记录识别信息
|
||||||
|
HseRecognizeRecord record = new HseRecognizeRecord();
|
||||||
|
record.setOriginalPicture(img.getUrl());
|
||||||
|
record.setOriginalUrlId(img.getId());
|
||||||
|
record.setCreateTime(new Date());
|
||||||
|
List<RecognizeTargetVo> targets = recognizeVo.getTargets();
|
||||||
|
img.setTargets(JSONUtil.toJsonStr(targets));
|
||||||
|
img.setImgSize(JSONUtil.toJsonStr(recognizeVo.getOriginalImgSize()));
|
||||||
|
img.setIsRecognize(RecognizerHasTargetEnum.YES.getValue());
|
||||||
|
List<String> recTypeList = targets.stream().map(RecognizeTargetVo::getType).distinct().toList();
|
||||||
|
img.setRecType(JSONUtil.toJsonStr(recTypeList));
|
||||||
|
String targetUrl = null;
|
||||||
|
try {
|
||||||
|
RecognizeImageStreamResult imageStreamResult = RecognizerManager.drawImageToStream(img.getUrl(), targets);
|
||||||
|
InputStream inputStream = imageStreamResult.getInputStream();
|
||||||
|
String contentType = imageStreamResult.getContentType();
|
||||||
|
String originalFilename = extractFilename(img.getUrl());
|
||||||
|
long length = imageStreamResult.getLength();
|
||||||
|
String targetImgPath = Ys7DeviceImgConstant.getTargetImgOssPath(originalFilename, img.getDeviceSerial());
|
||||||
|
SysOssUploadVo drawImageUploadVo = ossService.uploadFileUrlWithNoSave(inputStream, targetImgPath, contentType, length);
|
||||||
|
targetUrl = drawImageUploadVo.getUrl();
|
||||||
|
if (StringUtils.isNotBlank(targetUrl)) {
|
||||||
|
img.setRecognizeUrl(targetUrl);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("图片绘制失败", e);
|
||||||
|
}
|
||||||
|
List<String> codeList = targets.stream()
|
||||||
|
.map(RecognizeTargetVo::getType).distinct()
|
||||||
|
.map(RecognizerTypeEnum::fromValue).filter(Objects::nonNull)
|
||||||
|
.map(RecognizerTypeEnum::getCode).filter(Objects::nonNull)
|
||||||
|
.toList();
|
||||||
|
String codeStr = String.join(",", codeList);
|
||||||
|
record.setViolationType(codeStr);
|
||||||
|
record.setNum(targets.size());
|
||||||
|
record.setDeviceSerial(img.getDeviceSerial());
|
||||||
|
record.setDeviceName(img.getDeviceName());
|
||||||
|
record.setPicture(targetUrl);
|
||||||
|
record.setOriginalPicture(img.getUrl());
|
||||||
|
record.setRecordCategory(HseRecordCategoryEnum.MONITOR.getValue());
|
||||||
|
record.setProjectId(img.getProjectId());
|
||||||
|
// 保存识别记录
|
||||||
|
boolean result = recognizeRecordService.save(record);
|
||||||
|
if (!result) {
|
||||||
|
throw new ServiceException("保存识别记录失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
img.setImgStatus(recognizeVo.getHasTarget().equals(RecognizerHasTargetEnum.YES.getValue()) ? "2" : "1");
|
||||||
|
img.setUpdateTime(new Date());
|
||||||
|
|
||||||
|
return baseMapper.updateById(img);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public int addViolationRecord(AddViolattionRecordReq req) {
|
||||||
|
HseRecognizeRecord recognizeRecord = recognizeRecordService.getBaseMapper().selectOne(new LambdaQueryWrapper<HseRecognizeRecord>()
|
||||||
|
.eq(HseRecognizeRecord::getDeviceSerial, req.getDeviceSerial())
|
||||||
|
.eq(HseRecognizeRecord::getProjectId, req.getProjectId())
|
||||||
|
.eq(HseRecognizeRecord::getOriginalUrlId, req.getOriginalUrlId()));
|
||||||
|
if (recognizeRecord == null) {
|
||||||
|
throw new ServiceException("找不到识别记录!");
|
||||||
|
}
|
||||||
|
List<HseViolationRecordCreateDto> violationRecordList = new ArrayList<>();
|
||||||
|
|
||||||
|
String violationType = recognizeRecord.getViolationType();
|
||||||
|
if (StringUtils.isNotBlank(violationType)) {
|
||||||
|
List<String> list = StringUtils.splitList(violationType);
|
||||||
|
for (String s : list) {
|
||||||
|
if (recognizeRecord.getProjectId() != null) {
|
||||||
|
HseViolationRecordCreateDto violationRecord = new HseViolationRecordCreateDto();
|
||||||
|
violationRecord.setProjectId(recognizeRecord.getProjectId());
|
||||||
|
violationRecord.setRecognizeId(recognizeRecord.getId());
|
||||||
|
violationRecord.setViolationType(s);
|
||||||
|
violationRecord.setViolationTime(recognizeRecord.getCreateTime());
|
||||||
|
violationRecordList.add(violationRecord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (CollUtil.isNotEmpty(violationRecordList)) {
|
||||||
|
violationRecordService.insertByMonitor(violationRecordList);
|
||||||
|
}
|
||||||
|
OthYs7DeviceImg img = baseMapper.selectById(req.getOriginalUrlId());
|
||||||
|
if (img != null) {
|
||||||
|
img.setImgStatus("3");
|
||||||
|
return baseMapper.updateById(img);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提取文件名
|
* 提取文件名
|
||||||
*
|
*
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
|
|||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
@ -16,15 +17,21 @@ import org.dromara.common.mybatis.core.page.PageQuery;
|
|||||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||||
import org.dromara.manager.ys7manager.Ys7Constant;
|
import org.dromara.manager.ys7manager.Ys7Constant;
|
||||||
import org.dromara.manager.ys7manager.Ys7Manager;
|
import org.dromara.manager.ys7manager.Ys7Manager;
|
||||||
|
import org.dromara.manager.ys7manager.Ys7RequestUtils;
|
||||||
|
import org.dromara.manager.ys7manager.dto.DeviceLocalVideoRequstDto;
|
||||||
|
import org.dromara.manager.ys7manager.dto.DevicePlayBackUrlRequstDto;
|
||||||
import org.dromara.manager.ys7manager.enums.DeviceOnOffLineEnum;
|
import org.dromara.manager.ys7manager.enums.DeviceOnOffLineEnum;
|
||||||
|
import org.dromara.manager.ys7manager.vo.DeviceLocalVideoRecordsVo;
|
||||||
import org.dromara.manager.ys7manager.vo.Ys7QueryDeviceResponseVo;
|
import org.dromara.manager.ys7manager.vo.Ys7QueryDeviceResponseVo;
|
||||||
import org.dromara.other.domain.OthYs7Device;
|
import org.dromara.other.domain.OthYs7Device;
|
||||||
import org.dromara.other.domain.dto.ys7device.*;
|
import org.dromara.other.domain.dto.ys7device.*;
|
||||||
import org.dromara.other.domain.enums.OthDeviceStatusEnum;
|
import org.dromara.other.domain.enums.OthDeviceStatusEnum;
|
||||||
import org.dromara.other.domain.enums.OthVideoEncryptedEnum;
|
import org.dromara.other.domain.enums.OthVideoEncryptedEnum;
|
||||||
|
import org.dromara.other.domain.vo.ys7device.DateAndDeviceLocalVideoVo;
|
||||||
import org.dromara.other.domain.vo.ys7device.OthYs7DeviceVo;
|
import org.dromara.other.domain.vo.ys7device.OthYs7DeviceVo;
|
||||||
import org.dromara.other.mapper.OthYs7DeviceMapper;
|
import org.dromara.other.mapper.OthYs7DeviceMapper;
|
||||||
import org.dromara.other.service.IOthYs7DeviceService;
|
import org.dromara.other.service.IOthYs7DeviceService;
|
||||||
|
import org.dromara.other.utils.DateRangeUtils;
|
||||||
import org.dromara.project.domain.BusProject;
|
import org.dromara.project.domain.BusProject;
|
||||||
import org.dromara.project.service.IBusProjectService;
|
import org.dromara.project.service.IBusProjectService;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
@ -433,6 +440,53 @@ public class OthYs7DeviceServiceImpl extends ServiceImpl<OthYs7DeviceMapper, Oth
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPlayBackUrl(OthYs7DevicePlayBackUrlReq req) {
|
||||||
|
String token = ys7Manager.getToken();
|
||||||
|
DevicePlayBackUrlRequstDto dto = new DevicePlayBackUrlRequstDto();
|
||||||
|
dto.setAccessToken(token);
|
||||||
|
dto.setDeviceSerial(req.getDeviceSerial());
|
||||||
|
dto.setStartTime(req.getStartTime());
|
||||||
|
dto.setEndTime(req.getEndTime());
|
||||||
|
dto.setProtocol(1);
|
||||||
|
dto.setQuality(2);
|
||||||
|
dto.setType("2");
|
||||||
|
dto.setRecType(0);
|
||||||
|
dto.setExpireTime(36000);
|
||||||
|
return Ys7RequestUtils.getDevicePlayBackUrl(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DeviceLocalVideoRecordsVo> getDeviceLocalVideo(OthYs7DevicePlayBackUrlReq req) {
|
||||||
|
String token = ys7Manager.getToken();
|
||||||
|
DeviceLocalVideoRequstDto dto = new DeviceLocalVideoRequstDto();
|
||||||
|
dto.setAccessToken(token);
|
||||||
|
dto.setDeviceSerial(req.getDeviceSerial());
|
||||||
|
dto.setStartTime(req.getStartTime());
|
||||||
|
dto.setEndTime(req.getEndTime());
|
||||||
|
return Ys7RequestUtils.getDeviceLocalVideo(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询范围日期和设备本地录像列表
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public DateAndDeviceLocalVideoVo getDateAndDeviceLocalVideo(OthYs7DevicePlayBackUrlReq req) {
|
||||||
|
DateAndDeviceLocalVideoVo vo = new DateAndDeviceLocalVideoVo();
|
||||||
|
List<String> dateList = DateRangeUtils.getDatesBetweenStrings(req.getStartTime(), req.getEndTime());
|
||||||
|
vo.setDateList(dateList);
|
||||||
|
if (CollectionUtils.isNotEmpty(dateList) && dateList.size() > 1) {
|
||||||
|
String first = dateList.getFirst();
|
||||||
|
req.setStartTime(first+" 00:00:00");
|
||||||
|
req.setEndTime(first+" 23:59:59");
|
||||||
|
}
|
||||||
|
List<DeviceLocalVideoRecordsVo> deviceLocalVideo = getDeviceLocalVideo(req);
|
||||||
|
vo.setDeviceList(deviceLocalVideo);
|
||||||
|
return vo;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证萤石摄像对象是否发生更改
|
* 验证萤石摄像对象是否发生更改
|
||||||
*
|
*
|
||||||
|
|||||||
@ -0,0 +1,166 @@
|
|||||||
|
package org.dromara.other.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期范围工具类
|
||||||
|
*/
|
||||||
|
public class DateRangeUtils {
|
||||||
|
|
||||||
|
// 默认时区(东八区)
|
||||||
|
private static final TimeZone DEFAULT_TIME_ZONE = TimeZone.getTimeZone("GMT+8");
|
||||||
|
|
||||||
|
// 日期格式
|
||||||
|
private static final String DATE_FORMAT = "yyyy-MM-dd";
|
||||||
|
|
||||||
|
// 完整日期时间格式
|
||||||
|
private static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取两个时间戳之间的所有日期(包含起止日期)
|
||||||
|
* @param startTimestamp 开始时间戳(秒级/毫秒级字符串或数字)
|
||||||
|
* @param endTimestamp 结束时间戳(秒级/毫秒级字符串或数字)
|
||||||
|
* @return 日期列表(格式:yyyy-MM-dd)
|
||||||
|
*/
|
||||||
|
public static List<String> getDatesBetweenTimestamps(Object startTimestamp, Object endTimestamp) {
|
||||||
|
// 转换为毫秒级时间戳
|
||||||
|
long start = convertToMilliseconds(startTimestamp);
|
||||||
|
long end = convertToMilliseconds(endTimestamp);
|
||||||
|
|
||||||
|
return getDatesBetweenDates(new Date(start), new Date(end));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取两个日期之间的所有日期(包含起止日期)
|
||||||
|
* @param startDate 开始日期
|
||||||
|
* @param endDate 结束日期
|
||||||
|
* @return 日期列表(格式:yyyy-MM-dd)
|
||||||
|
*/
|
||||||
|
public static List<String> getDatesBetweenDates(Date startDate, Date endDate) {
|
||||||
|
List<String> dates = new ArrayList<>();
|
||||||
|
Calendar calendar = Calendar.getInstance(DEFAULT_TIME_ZONE);
|
||||||
|
|
||||||
|
// 设置开始日期
|
||||||
|
calendar.setTime(startDate);
|
||||||
|
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||||
|
calendar.set(Calendar.MINUTE, 0);
|
||||||
|
calendar.set(Calendar.SECOND, 0);
|
||||||
|
calendar.set(Calendar.MILLISECOND, 0);
|
||||||
|
|
||||||
|
// 循环添加日期直到结束日期
|
||||||
|
while (!calendar.getTime().after(endDate)) {
|
||||||
|
dates.add(DateUtil.format(calendar.getTime(), DATE_FORMAT));
|
||||||
|
|
||||||
|
// 日期加1天
|
||||||
|
calendar.add(Calendar.DAY_OF_MONTH, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dates;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取两个日期字符串之间的所有日期
|
||||||
|
* @param startDateStr 开始日期(yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss)
|
||||||
|
* @param endDateStr 结束日期(yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss)
|
||||||
|
* @return 日期列表
|
||||||
|
*/
|
||||||
|
public static List<String> getDatesBetweenStrings(String startDateStr, String endDateStr) {
|
||||||
|
Date startDate = parseDateString(startDateStr);
|
||||||
|
Date endDate = parseDateString(endDateStr);
|
||||||
|
|
||||||
|
return getDatesBetweenDates(startDate, endDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将时间戳转换为日期(yyyy-MM-dd)
|
||||||
|
*/
|
||||||
|
public static String timestampToDate(Object timestamp) {
|
||||||
|
long time = convertToMilliseconds(timestamp);
|
||||||
|
return DateUtil.format(new Date(time), DATE_FORMAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析日期字符串为Date对象
|
||||||
|
*/
|
||||||
|
private static Date parseDateString(String dateStr) {
|
||||||
|
try {
|
||||||
|
if (dateStr.contains(" ")) {
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat(DATETIME_FORMAT);
|
||||||
|
sdf.setTimeZone(DEFAULT_TIME_ZONE);
|
||||||
|
return sdf.parse(dateStr);
|
||||||
|
} else {
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
|
||||||
|
sdf.setTimeZone(DEFAULT_TIME_ZONE);
|
||||||
|
return sdf.parse(dateStr);
|
||||||
|
}
|
||||||
|
} catch (ParseException e) {
|
||||||
|
throw new IllegalArgumentException("日期格式错误:" + dateStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将各种时间戳格式转换为毫秒级时间戳
|
||||||
|
*/
|
||||||
|
private static long convertToMilliseconds(Object timestamp) {
|
||||||
|
if (timestamp == null) {
|
||||||
|
throw new IllegalArgumentException("时间戳不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
String timestampStr = timestamp.toString().trim();
|
||||||
|
if (StrUtil.isBlank(timestampStr)) {
|
||||||
|
throw new IllegalArgumentException("时间戳不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
long time = Long.parseLong(timestampStr);
|
||||||
|
|
||||||
|
// 10位秒级时间戳转为13位毫秒级
|
||||||
|
if (timestampStr.length() == 10) {
|
||||||
|
time *= 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return time;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new IllegalArgumentException("时间戳格式错误:" + timestampStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定日期的开始时间戳(当天00:00:00)
|
||||||
|
*/
|
||||||
|
public static long getStartOfDayTimestamp(Object timestamp) {
|
||||||
|
long time = convertToMilliseconds(timestamp);
|
||||||
|
Calendar calendar = Calendar.getInstance(DEFAULT_TIME_ZONE);
|
||||||
|
calendar.setTime(new Date(time));
|
||||||
|
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
||||||
|
calendar.set(Calendar.MINUTE, 0);
|
||||||
|
calendar.set(Calendar.SECOND, 0);
|
||||||
|
calendar.set(Calendar.MILLISECOND, 0);
|
||||||
|
|
||||||
|
return calendar.getTimeInMillis() / 1000; // 返回秒级时间戳
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定日期的结束时间戳(当天23:59:59)
|
||||||
|
*/
|
||||||
|
public static long getEndOfDayTimestamp(Object timestamp) {
|
||||||
|
long time = convertToMilliseconds(timestamp);
|
||||||
|
Calendar calendar = Calendar.getInstance(DEFAULT_TIME_ZONE);
|
||||||
|
calendar.setTime(new Date(time));
|
||||||
|
calendar.set(Calendar.HOUR_OF_DAY, 23);
|
||||||
|
calendar.set(Calendar.MINUTE, 59);
|
||||||
|
calendar.set(Calendar.SECOND, 59);
|
||||||
|
calendar.set(Calendar.MILLISECOND, 999);
|
||||||
|
|
||||||
|
return calendar.getTimeInMillis() / 1000; // 返回秒级时间戳
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -52,6 +52,11 @@ public class HseRecognizeRecord implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private String violationType;
|
private String violationType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原始图片id
|
||||||
|
*/
|
||||||
|
private Long originalUrlId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 原始图片
|
* 原始图片
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -37,6 +37,11 @@ public class HseRecognizeRecordCreateDto {
|
|||||||
*/
|
*/
|
||||||
private String recordCategory;
|
private String recordCategory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原始图片id
|
||||||
|
*/
|
||||||
|
private Long originalUrlId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 原始图片
|
* 原始图片
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -66,6 +66,11 @@ public class HseRecognizeRecordVo implements Serializable {
|
|||||||
@ExcelDictFormat(dictType = "violation_level_type")
|
@ExcelDictFormat(dictType = "violation_level_type")
|
||||||
private String violationType;
|
private String violationType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原始图片id
|
||||||
|
*/
|
||||||
|
private Long originalUrlId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 原始图片
|
* 原始图片
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user