修复时间上报

This commit is contained in:
lxj
2025-09-08 17:50:05 +08:00
parent 71c82fa345
commit ba206c4d32
16 changed files with 249 additions and 29 deletions

View File

@@ -16,4 +16,8 @@ public class HikEqpConfig {
private String host;
/**
* 视频回放地址 需要以/结尾
*/
private String playBackUrl;
}

View File

@@ -6,6 +6,7 @@ import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.TreeNode;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.excel.utils.ExcelUtil;
@@ -183,4 +184,18 @@ public class SisAlarmEventsController extends BaseController {
List<QueryStatisticsAlarmVo> vo = sisAlarmEventsService.queryStatistics();
return R.ok(vo);
}
/**
* 查询事件树
* 大类
* - 小类
*
* @param bigType 事件大类, -1 代表查询全部
* @return 返回事件树
*/
@GetMapping("/query/eventType/{bigType}")
public R<List<TreeNode<String>>> queryEventType(@PathVariable("bigType") String bigType) {
List<TreeNode<String>> tree = sisAlarmEventsService.queryEventType(bigType);
return R.ok(tree);
}
}

View File

@@ -2,9 +2,11 @@ package org.dromara.sis.controller.zkmedia;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.dromara.sis.sdk.zkmedia.ZLMediaKitService;
import org.dromara.sis.sdk.hik.PlayBackBo;
import org.dromara.sis.sdk.zkmedia.MediaService;
import org.dromara.sis.sdk.zkmedia.model.AddStreamProxy;
import org.dromara.sis.sdk.zkmedia.model.AddStreamProxyResp;
import org.dromara.sis.sdk.zkmedia.model.SdkPlayBackResp;
import org.dromara.sis.sdk.zkmedia.model.StreamPlay;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
@@ -26,7 +28,7 @@ import javax.annotation.Resource;
public class ZKLmediaController {
@Resource
private ZLMediaKitService zlMediaKitService;
private MediaService mediaService;
/**
* 创建拉流任务返回null代表创建拉流任务失败
@@ -36,7 +38,7 @@ public class ZKLmediaController {
*/
@PostMapping("/realtime/add")
public R<AddStreamProxyResp> addStreamProxy(@RequestBody @Validated AddStreamProxy data) {
AddStreamProxyResp addStreamProxyResp = zlMediaKitService.addStreamProxy(data);
AddStreamProxyResp addStreamProxyResp = mediaService.addStreamProxy(data);
if (addStreamProxyResp != null) {
return R.ok(addStreamProxyResp);
}
@@ -52,7 +54,7 @@ public class ZKLmediaController {
*/
@PostMapping("/proxy")
public R<AddStreamProxyResp> addStreamProxy(@RequestBody @Validated StreamPlay streamPlay) {
AddStreamProxyResp addStreamProxyResp = zlMediaKitService.addStreamProxy(streamPlay);
AddStreamProxyResp addStreamProxyResp = mediaService.addStreamProxy(streamPlay);
if (addStreamProxyResp != null) {
return R.ok(addStreamProxyResp);
}
@@ -67,7 +69,7 @@ public class ZKLmediaController {
*/
@PostMapping("/FFmpeg/proxy")
public R<AddStreamProxyResp> addFfmpegStreamProxy(@RequestBody @Validated AddStreamProxy data) {
AddStreamProxyResp addStreamProxyResp = zlMediaKitService.addFfmpegStreamProxy(data);
AddStreamProxyResp addStreamProxyResp = mediaService.addFfmpegStreamProxy(data);
if (addStreamProxyResp != null) {
return R.ok(addStreamProxyResp);
}
@@ -83,10 +85,16 @@ public class ZKLmediaController {
*/
@PostMapping("/ffmpeg/proxy")
public R<AddStreamProxyResp> addFfmpegProxy(@RequestBody @Validated StreamPlay data) {
AddStreamProxyResp addStreamProxyResp = zlMediaKitService.addFfmpegStreamProxy(data);
AddStreamProxyResp addStreamProxyResp = mediaService.addFfmpegStreamProxy(data);
if (addStreamProxyResp != null) {
return R.ok(addStreamProxyResp);
}
return R.fail();
}
@PostMapping("/sdk/plackBack")
public R<SdkPlayBackResp> playBack(@RequestBody @Validated PlayBackBo playBackBo) {
SdkPlayBackResp res = mediaService.playBack(playBackBo);
return R.ok(res);
}
}

View File

@@ -8,6 +8,7 @@ import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.sis.domain.SisAlarmEvents;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
import java.util.List;
@@ -69,6 +70,7 @@ public class SisAlarmEventsBo extends BaseEntity {
* 设备告警时间
*/
@NotNull(message = "设备告警时间不能为空", groups = {AddGroup.class, EditGroup.class})
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date reportTime;
/**

View File

@@ -1,8 +1,9 @@
package org.dromara.sis.mapper;
import org.apache.ibatis.annotations.Param;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.sis.domain.SisDeviceChannel;
import org.dromara.sis.domain.vo.SisDeviceChannelVo;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 设备通道管理Mapper接口
@@ -12,4 +13,5 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
*/
public interface SisDeviceChannelMapper extends BaseMapperPlus<SisDeviceChannel, SisDeviceChannelVo> {
SisDeviceChannel queryChannels(@Param("deviceIp") String deviceIp, @Param("channelNo") String channelNo);
}

View File

@@ -40,7 +40,7 @@ public class HikDeviceApplicationRunner implements ApplicationRunner {
// 梯控登录
// runner.hikElevatorInfoLogin();
// 网络摄像头登录
runner.hikNetCameraLogin();
// runner.hikNetCameraLogin();
}
@Async

View File

@@ -26,6 +26,7 @@ public class HikApiService {
private static final String LOGOUT_URI = "logout";
private static final String CHANNEL_LIST = "channel/list";
private static final String FACE_UPLOAD = "flib/add";
private static final String PLAY_BACK = "stream/playback";
/**
* 发起海康设备对接模块请求
@@ -115,7 +116,11 @@ public class HikApiService {
* @return 返回上传文件名称
*/
public String fdLibUpload(FlibFaceAddBo addBo) {
return request("FACE_UPLOAD", JSONObject.toJSONString(addBo), String.class);
return request(FACE_UPLOAD, JSONObject.toJSONString(addBo), String.class);
}
public Integer playBack(PlayBackBo playBackBo) {
return request(PLAY_BACK, JSONObject.toJSONString(playBackBo), Integer.class);
}
}

View File

@@ -0,0 +1,63 @@
package org.dromara.sis.sdk.hik;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.Date;
@Data
public class PlayBackBo {
/**
* 设备ip
*/
@NotEmpty(message = "设备ip不能为null")
private String deviceIp;
/**
* 设备端口
*/
private short port = 554;
/**
* 设备厂商编号
*/
private Integer factoryNo;
/**
* 设备访问账号
*/
private String deviceAccount;
/**
* 设备访问密码
*/
private String devicePwd;
/**
* 设备通道编码
*/
@NotNull(message = "通道编码不能为null")
private Integer channelNo;
/**
* 码流类型
* 1主码流
* 2辅码流
*/
private Byte streamType = 1;
/**
* 开始时间
*/
@NotNull(message = "开始时间不能为null")
private Date startTime;
/**
* 结束时间
*/
@NotNull(message = "结束时间不能为null")
private Date endTime;
}

View File

@@ -1,16 +1,14 @@
package org.dromara.sis.sdk.zkmedia;
import org.dromara.sis.sdk.zkmedia.model.AddStreamProxy;
import org.dromara.sis.sdk.zkmedia.model.AddStreamProxyResp;
import org.dromara.sis.sdk.zkmedia.model.StartStreamProxy;
import org.dromara.sis.sdk.zkmedia.model.StreamPlay;
import org.dromara.sis.sdk.hik.PlayBackBo;
import org.dromara.sis.sdk.zkmedia.model.*;
/**
* 拉流服务
* @author lxj
*/
public interface ZLMediaKitService {
public interface MediaService {
/**
* 创建视频流拉流代理
@@ -58,4 +56,10 @@ public interface ZLMediaKitService {
Boolean delFfmpegSource(String key);
/**
* 通过sdk进行视频回放
* @param playBackBo 回放参数
* @return 返回播放地址
*/
SdkPlayBackResp playBack(PlayBackBo playBackBo);
}

View File

@@ -4,8 +4,11 @@ import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.dromara.sis.api.enums.FactoryNoEnum;
import org.dromara.sis.config.HikEqpConfig;
import org.dromara.sis.config.ZLMediaKitConfig;
import org.dromara.sis.domain.SisDeviceChannel;
import org.dromara.sis.sdk.hik.HikApiService;
import org.dromara.sis.sdk.hik.PlayBackBo;
import org.dromara.sis.sdk.zkmedia.model.*;
import org.dromara.sis.service.ISisDeviceChannelService;
import org.jetbrains.annotations.Nullable;
@@ -22,12 +25,16 @@ import java.util.Map;
*/
@Slf4j
@Service
public class ZLMediaKitServiceImpl implements ZLMediaKitService {
public class MediaServiceImpl implements MediaService {
@Resource
private ZLMediaKitConfig zlmConfig;
@Resource
private ISisDeviceChannelService deviceChannelService;
@Resource
private HikApiService hikApiService;
@Resource
private HikEqpConfig hikEqpConfig;
// 海康实时流取流模板
private static final String HIK_REALTIME_RTSP_TEMPLATE = "rtsp://%s:%s@%s:%s/Streaming/Channels/%s";
@@ -58,7 +65,7 @@ public class ZLMediaKitServiceImpl implements ZLMediaKitService {
public String getRequestUrl(String uri) {
if (ZLM_REQUEST_PREFIX == null) {
synchronized (ZLMediaKitServiceImpl.class) {
synchronized (this) {
if (ZLM_REQUEST_PREFIX == null) {
ZLM_REQUEST_PREFIX = String.format(STREAM_REQUEST_TEMLATE, zlmConfig.getIp(), zlmConfig.getHttpPort());
}
@@ -331,4 +338,31 @@ public class ZLMediaKitServiceImpl implements ZLMediaKitService {
return result != null && result.getCode() == 0;
}
@Override
public SdkPlayBackResp playBack(PlayBackBo playBackBo) {
// 根据设备ip + 通道编码查询通道信息
SisDeviceChannel deviceChannel = deviceChannelService.queryByNvrIpAndChannelNo(playBackBo.getDeviceIp(), playBackBo.getChannelNo());
// 回放默认走录像机拉流
playBackBo.setPort((short) 8000);
playBackBo.setDeviceIp(deviceChannel.getNvrIp());
playBackBo.setDeviceAccount(deviceChannel.getNvrAccount());
playBackBo.setDevicePwd(deviceChannel.getNvrPwd());
if (deviceChannel.getFactoryNo().equals(FactoryNoEnum.HIK.getCode())) {
// 海康通道编码在系统中为 通道编码 + 0 + 码流类型所以需要去掉最后2为
if (StrUtil.isEmpty(deviceChannel.getChannelNo())) {
throw new RuntimeException("通道配置错误。");
} else {
String channelNo = deviceChannel.getNvrChannelNo();
channelNo = channelNo.substring(0, channelNo.length() - 2);
playBackBo.setChannelNo(Integer.valueOf(channelNo));
}
}
Integer i = hikApiService.playBack(playBackBo);
SdkPlayBackResp resp = new SdkPlayBackResp();
if (i != null && i > -1) {
resp.setWsUrl(hikEqpConfig.getPlayBackUrl() + i);
}
return resp;
}
}

View File

@@ -0,0 +1,10 @@
package org.dromara.sis.sdk.zkmedia.model;
import lombok.Data;
@Data
public class SdkPlayBackResp {
private String wsUrl;
}

View File

@@ -1,5 +1,6 @@
package org.dromara.sis.service;
import org.dromara.common.core.domain.TreeNode;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.sis.domain.SisAlarmEvents;
@@ -121,5 +122,10 @@ public interface ISisAlarmEventsService {
*/
List<QueryStatisticsAlarmVo> queryStatistics();
/**
* 查询事件树
* @param bigType 事件大类,-1 查询全部
* @return 返回事件树
*/
List<TreeNode<String>> queryEventType(String bigType);
}

View File

@@ -4,7 +4,6 @@ import jakarta.validation.constraints.NotEmpty;
import org.dromara.common.core.domain.TreeNode;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.sis.api.domain.RemoteSisDeviceChannel;
import org.dromara.sis.domain.SisDeviceChannel;
import org.dromara.sis.domain.bo.SisDeviceChannelBo;
import org.dromara.sis.domain.bo.SisDeviceManageBo;
@@ -140,4 +139,11 @@ public interface ISisDeviceChannelService {
*/
SisDeviceChannel queryChannels(@NotEmpty String deviceIp, @NotEmpty String channelNo);
/**
* 通过录像机ip和通道编码获取通道信息
* @param deviceIp 设备ip
* @param channelNo 通道编码
* @return 返回通道信息
*/
SisDeviceChannel queryByNvrIpAndChannelNo(String deviceIp, Integer channelNo);
}

View File

@@ -9,11 +9,14 @@ import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.common.core.domain.TreeNode;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.core.utils.TreeUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
@@ -38,14 +41,13 @@ import org.dromara.sis.service.ISisAlarmEventAttachmentsService;
import org.dromara.sis.service.ISisAlarmEventProcessService;
import org.dromara.sis.service.ISisAlarmEventsService;
import org.dromara.sis.service.ISisDeviceManageService;
import org.dromara.system.api.RemoteDictService;
import org.dromara.system.api.domain.vo.RemoteDictDataVo;
import org.dromara.system.api.model.LoginUser;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.*;
/**
* 告警Service业务层处理
@@ -67,6 +69,8 @@ public class SisAlarmEventsServiceImpl implements ISisAlarmEventsService {
private RemoteFileService remoteFileService;
@DubboReference
private RemoteAttendanceService remoteAttendanceService;
@DubboReference
private RemoteDictService remoteDictService;
/**
* 查询告警
@@ -124,7 +128,11 @@ public class SisAlarmEventsServiceImpl implements ISisAlarmEventsService {
lqw.like(StringUtils.isNotBlank(bo.getDeviceName()), SisAlarmEvents::getDeviceName, bo.getDeviceName());
lqw.eq(bo.getDeviceGroupId() != null, SisAlarmEvents::getDeviceGroupId, bo.getDeviceGroupId());
lqw.like(StringUtils.isNotBlank(bo.getDeviceGroupName()), SisAlarmEvents::getDeviceGroupName, bo.getDeviceGroupName());
lqw.eq(bo.getReportTime() != null, SisAlarmEvents::getReportTime, bo.getReportTime());
if (bo.getReportTime() != null) {
Date start = DateUtil.beginOfDay(bo.getReportTime());
Date end = DateUtil.endOfDay(bo.getReportTime());
lqw.between(SisAlarmEvents::getReportTime, start, end);
}
return lqw;
}
@@ -207,7 +215,7 @@ public class SisAlarmEventsServiceImpl implements ISisAlarmEventsService {
// 默认服务时间为2个小时
alarmEvents.setServBeginTime(now);
alarmEvents.setServEndTime(DateUtil.offset(now, DateField.HOUR, 2));
alarmEvents.setDescription(EventSmallTypeEnum.SMART_REPORT_ZJCR.getDesc());
alarmEvents.setDescription(type.getDesc());
int insert = this.baseMapper.insert(alarmEvents);
log.info("写入报警事件表完成num={}", insert);
@@ -364,4 +372,46 @@ public class SisAlarmEventsServiceImpl implements ISisAlarmEventsService {
public List<QueryStatisticsAlarmVo> queryStatistics() {
return this.baseMapper.queryStatistics();
}
@Override
public List<TreeNode<String>> queryEventType(String bigType) {
// 查询事件大类
List<RemoteDictDataVo> eventBigType = remoteDictService.selectDictDataByType("event_big_type");
if (CollUtil.isEmpty(eventBigType)) {
return List.of();
}
// 查询事件小类
List<RemoteDictDataVo> eventSmallType = remoteDictService.selectDictDataByType("event_small_type");
if (CollUtil.isEmpty(eventSmallType)) {
return List.of();
}
List<TreeNode<String>> all = new ArrayList<>(eventBigType.size() + eventSmallType.size());
Map<String, TreeNode<String>> bigTypeCache = new HashMap<>();
eventSmallType.forEach(item -> {
TreeNode<String> node = new TreeNode<>();
node.setCode(item.getDictValue());
node.setParentCode("-1");
node.setLabel(item.getDictLabel());
node.setTitle(item.getDictLabel());
node.setChildren(Lists.newArrayList());
bigTypeCache.put(item.getDictValue(), node);
all.add(node);
});
eventBigType.forEach(item -> {
TreeNode<String> node = new TreeNode<>();
node.setCode(item.getDictValue());
node.setLabel(item.getDictLabel());
node.setTitle(item.getDictLabel());
node.setChildren(Lists.newArrayList());
bigTypeCache.keySet().forEach(key -> {
if (item.getDictValue().startsWith(key)) {
node.setParentCode(bigTypeCache.get(key).getCode());
}
});
all.add(node);
});
return TreeUtils.build(all, bigType);
}
}

View File

@@ -50,7 +50,6 @@ public class SisDeviceChannelServiceImpl implements ISisDeviceChannelService {
private final HikApiService hikApiService;
/**
* 查询设备通道管理
*
@@ -336,10 +335,14 @@ public class SisDeviceChannelServiceImpl implements ISisDeviceChannelService {
@Override
public SisDeviceChannel queryChannels(String deviceIp, String channelNo) {
LambdaQueryWrapper<SisDeviceChannel> lqw = new LambdaQueryWrapper<>();
lqw.eq(SisDeviceChannel::getDeviceIp, deviceIp);
lqw.eq(SisDeviceChannel::getChannelNo, channelNo)
.or().eq(SisDeviceChannel::getNvrChannelNo, channelNo);
return baseMapper.queryChannels(deviceIp, channelNo);
}
@Override
public SisDeviceChannel queryByNvrIpAndChannelNo(String deviceIp, Integer channelNo) {
LambdaUpdateWrapper<SisDeviceChannel> lqw = new LambdaUpdateWrapper<>();
lqw.eq(SisDeviceChannel::getNvrIp, deviceIp);
lqw.eq(SisDeviceChannel::getNvrChannelNo, channelNo);
return baseMapper.selectOne(lqw);
}
}

View File

@@ -4,4 +4,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.sis.mapper.SisDeviceChannelMapper">
<select id="queryChannels" resultType="org.dromara.sis.domain.SisDeviceChannel">
SELECT *
FROM sis_device_channel
WHERE device_ip = #{deviceIp}
AND (channel_no = #{channelNo} OR nvr_channel_no = #{channelNo})
</select>
</mapper>