Ver código fonte

代码同步

gao.qiang 9 meses atrás
pai
commit
be4f2ac3c7

+ 3 - 0
business-service/src/main/java/com/ozs/service/entity/BaseCameraManagement.java

@@ -212,6 +212,9 @@ public class BaseCameraManagement extends BaseEntity implements Serializable ,Co
     @Excel(name = "备注")
     private String remark;
 
+    @TableField(exist = false)
+    private Integer railwayType;
+
     @Override
     public int compareTo(BaseCameraManagement o) {
         int i =o.getRailwayName().compareTo(o.railwayName);

+ 10 - 0
business-service/src/main/java/com/ozs/service/entity/BaseDeviceDynamicManagement.java

@@ -74,4 +74,14 @@ public class BaseDeviceDynamicManagement extends BaseEntity implements Serializa
      * 相机状态(1在线2离线)
      */
     private Integer isDisable;
+
+    /**
+     *设备状态信息(1已读2未读)
+     */
+    private  Integer facilityState;
+
+    /**
+     *设备电量信息(1已读2未读)
+     */
+    private  Integer electricityState;
 }

+ 0 - 4
business-service/src/main/java/com/ozs/service/entity/BaseUser.java

@@ -1,10 +1,6 @@
 package com.ozs.service.entity;
 
 
-import com.ozs.common.annotation.Excel;
-import com.ozs.common.annotation.Excels;
-import com.ozs.common.core.domain.entity.SysDept;
-import com.ozs.common.core.domain.entity.SysRole;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;

+ 3 - 0
business-service/src/main/java/com/ozs/service/entity/vo/BaseCameraManagementHomeVo.java

@@ -143,6 +143,9 @@ public class BaseCameraManagementHomeVo extends BaseEntity implements Serializab
     @TableField(exist = false)
     private String deptName;
 
+    @TableField(exist = false)
+    private Integer railwayType;
+
     /**
      * 报警是否解除 1已解除2未解除
      */

+ 61 - 0
business-service/src/main/java/com/ozs/service/entity/vo/DeviceStateResp.java

@@ -0,0 +1,61 @@
+package com.ozs.service.entity.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ozs.common.annotation.Excel;
+import com.ozs.common.vo.PageVo;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @author Administrator
+ * 设备状态
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class DeviceStateResp extends PageVo implements Serializable {
+    private static final long serialVersionUID = 1L;
+    private Integer installMile;
+    @Excel(name = "监控相机安装里程位置(单位KM)")
+    private String installMileName;
+    @Excel(name = "测点名称")
+    private String measurePointName;
+    @Excel(name = "线路名称")
+    private String railwayName;
+    @Excel(name = "所属工务段名称")
+    private String deptName;
+    @Excel(name = "行别")
+    private String lineDir;
+    @Excel(name = "相机状态")
+    private String isDisable;
+    @Excel(name = "电量")
+    private Integer electricity;
+    @Excel(name = "相机编码")
+    private String cameraCode;
+    @Excel(name = "序列号")
+    private String cameraSn;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+    private String railwayCode;
+    private String deptId;
+    /**
+     * 设备状态信息(1已读2未读)
+     */
+    private  Integer facilityState;
+
+    /**
+     *设备电量信息(1已读2未读)
+     */
+    private  Integer electricityState;
+    /**
+     * 1电量2设备状态
+     */
+    private Integer category;
+}

+ 3 - 0
business-service/src/main/java/com/ozs/service/mapper/BaseCameraManagementMapper.java

@@ -5,6 +5,7 @@ import com.ozs.service.entity.BaseCameraManagement;
 import com.ozs.service.entity.MsgAlarm;
 import com.ozs.service.entity.vo.BaseCameraManagementHomeVo;
 import com.ozs.service.entity.vo.BaseCameraManagementVo;
+import com.ozs.service.entity.vo.DeviceStateResp;
 import com.ozs.service.entity.vo.MsgAlarmVo;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
@@ -28,4 +29,6 @@ public interface BaseCameraManagementMapper extends BaseMapper<BaseCameraManagem
     Integer countCamera(MsgAlarmVo msgAlarmVo);
 
     Map<String, Object> getCameraChannelByAlarmId(@Param("alarmId") String alarmId);
+
+    List<DeviceStateResp> deviceStatePage(DeviceStateResp deviceStateResp);
 }

+ 5 - 0
business-service/src/main/java/com/ozs/service/service/BaseCameraManagementService.java

@@ -7,6 +7,7 @@ import com.ozs.service.entity.BaseCameraManagement;
 import com.ozs.service.entity.vo.BaseCameraManagementHomeVo;
 import com.ozs.service.entity.vo.BaseCameraManagementVo;
 import com.ozs.service.entity.vo.BaseCameraManagementVos;
+import com.ozs.service.entity.vo.DeviceStateResp;
 
 import java.util.List;
 import java.util.Map;
@@ -42,4 +43,8 @@ public interface BaseCameraManagementService extends IService<BaseCameraManageme
     Map<String, Object> getCameraChannelByAlarmId(String alarmId);
 
     List<BaseCameraManagement> cameraAllList(BaseCameraManagement baseCameraManagement);
+
+    IPage<DeviceStateResp> deviceStatePage(DeviceStateResp deviceStateResp);
+
+    List<DeviceStateResp> deviceStateRespList(DeviceStateResp deviceStateResp);
 }

+ 19 - 4
business-service/src/main/java/com/ozs/service/service/impl/BaseCameraManagementServiceImpl.java

@@ -11,10 +11,7 @@ import com.ozs.common.utils.StringUtils;
 import com.ozs.common.utils.bean.BeanUtils;
 import com.ozs.common.utils.bean.BeanValidators;
 import com.ozs.service.entity.*;
-import com.ozs.service.entity.vo.BaseCameraManagementHomeVo;
-import com.ozs.service.entity.vo.BaseCameraManagementVo;
-import com.ozs.service.entity.vo.BaseCameraManagementVos;
-import com.ozs.service.entity.vo.BaseCameraVersionVo;
+import com.ozs.service.entity.vo.*;
 import com.ozs.service.mapper.*;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ozs.service.service.BaseCameraManagementService;
@@ -356,4 +353,22 @@ public class BaseCameraManagementServiceImpl extends ServiceImpl<BaseCameraManag
         }
         return baseCameraManagements;
     }
+
+    @Override
+    public IPage<DeviceStateResp> deviceStatePage(DeviceStateResp deviceStateResp) {
+        int pageNum = Integer.parseInt(deviceStateResp.getPageNum().toString());
+        int pageSize = Integer.parseInt(deviceStateResp.getPageSize().toString());
+        com.github.pagehelper.Page<DeviceStateResp> page = PageHelper.startPage(pageNum, pageSize)
+                .doSelectPage(() -> baseCameraManagementMapper.deviceStatePage(deviceStateResp));
+        com.baomidou.mybatisplus.extension.plugins.pagination.Page<DeviceStateResp> pageR =
+                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(pageNum, pageSize);
+        pageR.setRecords(page.getResult());
+        pageR.setTotal(page.getTotal());
+        return pageR;
+    }
+
+    @Override
+    public List<DeviceStateResp> deviceStateRespList(DeviceStateResp deviceStateResp) {
+        return baseCameraManagementMapper.deviceStatePage(deviceStateResp);
+    }
 }

+ 19 - 6
business-service/src/main/java/com/ozs/service/service/impl/BaseDeviceDynamicManagementServiceImpl.java

@@ -59,6 +59,19 @@ public class BaseDeviceDynamicManagementServiceImpl extends ServiceImpl<BaseDevi
                     cameraTree.getChildren().add(build);
                     map.put(o.getRailwayCode(), build);
                 }
+               //工务段
+                CameraTree build3 = CameraTree.builder()
+                        .code(o.getRailwayCode())
+                        .name(o.getRailwayName())
+                        .flay(true)
+                        .publicWorksSection(o.getPublicWorksSection())
+                        .children(new ArrayList<>())
+                        .build();
+                if (!ObjectUtils.isEmpty(map.get(o.getRailwayCode()))) {
+                    map.put(o.getRailwayCode()+"-"+o.getPublicWorksSection(), build3);
+                    map.get(o.getRailwayCode()).getChildren().add(build3);
+                }
+
                 // 里程
                 String mils = AppendUtils.stringAppend(o.getInstallMile());
                 CameraTree build1 = CameraTree.builder()
@@ -69,11 +82,11 @@ public class BaseDeviceDynamicManagementServiceImpl extends ServiceImpl<BaseDevi
                         .mileage(o.getInstallMile())
                         .children(new ArrayList<>())
                         .build();
-                if (!ObjectUtils.isEmpty(map.get(o.getRailwayCode()))) {
-                    CameraTree cameraTree1 = map.get(o.getRailwayCode()+"-"+o.getInstallMile() + "-" + (o.getLineDir().equals("1") ? "上行" : "下行"));
+                if (!ObjectUtils.isEmpty(map.get(o.getRailwayCode()+"-"+o.getPublicWorksSection()))) {
+                    CameraTree cameraTree1 = map.get(o.getRailwayCode()+"-"+o.getPublicWorksSection()+"-"+o.getInstallMile() + "-" + (o.getLineDir().equals("1") ? "上行" : "下行"));
                     if (ObjectUtils.isEmpty(cameraTree1)) {
-                        map.put(o.getRailwayCode()+"-"+o.getInstallMile() + "-" + (o.getLineDir().equals("1") ? "上行" : "下行"), build1);
-                        map.get(o.getRailwayCode()).getChildren().add(build1);
+                        map.put(o.getRailwayCode()+"-"+o.getPublicWorksSection()+"-"+o.getInstallMile() + "-" + (o.getLineDir().equals("1") ? "上行" : "下行"), build1);
+                        map.get(o.getRailwayCode()+"-"+o.getPublicWorksSection()).getChildren().add(build1);
                     }
                 }
                 // 摄像头
@@ -84,8 +97,8 @@ public class BaseDeviceDynamicManagementServiceImpl extends ServiceImpl<BaseDevi
                         .publicWorksSection(o.getPublicWorksSection())
                         .children(new ArrayList<>())
                         .build();
-                if (!ObjectUtils.isEmpty(map.get(o.getRailwayCode()+"-"+o.getInstallMile() + "-" + (o.getLineDir().equals("1") ? "上行" : "下行")))) {
-                    map.get(o.getRailwayCode()+"-"+o.getInstallMile() + "-" + (o.getLineDir().equals("1") ? "上行" : "下行")).getChildren().add(build2);
+                if (!ObjectUtils.isEmpty(map.get(o.getRailwayCode()+"-"+o.getPublicWorksSection()+"-"+o.getInstallMile() + "-" + (o.getLineDir().equals("1") ? "上行" : "下行")))) {
+                    map.get(o.getRailwayCode()+"-"+o.getPublicWorksSection()+"-"+o.getInstallMile() + "-" + (o.getLineDir().equals("1") ? "上行" : "下行")).getChildren().add(build2);
                 }
             }
         }

+ 76 - 1
business-service/src/main/resources/mapper/service/BaseCameraManagementMapper.xml

@@ -26,7 +26,8 @@
         a.version_name AS versionName,
         a.last_version_num AS lastVersionNum,
         a.measure_point_name AS measurePointName,
-        a.camera_sn AS cameraSn
+        a.camera_sn AS cameraSn,
+        r.railway_type AS railwayType
         FROM
         base_camera_management a join base_railway_management r
         on a.railway_code=r.railway_code
@@ -115,4 +116,78 @@
              base_camera_management b on ma.camera_code = b.camera_code
         where ma.alarm_id = #{alarmId}
     </select>
+    <select id="deviceStatePage" resultType="com.ozs.service.entity.vo.DeviceStateResp" parameterType="com.ozs.service.entity.vo.DeviceStateResp">
+        SELECT
+        ca.install_mile AS installMile,
+        ca.measure_point_name AS measurePointName,
+        ra.railway_name AS railwayName,
+        de.dept_name AS deptName,
+        CASE
+        line_dir
+        WHEN 1 THEN
+        '上行'
+        WHEN 2 THEN
+        '下行'
+        END AS lineDir,
+        CASE
+        man.is_disable
+        WHEN 1 THEN
+        '正常'
+        WHEN 2 THEN
+        '故障'
+        END AS isDisable,
+        man.electricity,
+        ca.camera_code AS cameraCode,
+        ca.camera_sn AS cameraSn,
+        man.update_time AS updateTime,
+        man.facility_state AS facilityState,
+        man.electricity_state AS electricityState
+        FROM
+        base_camera_management AS ca
+        LEFT JOIN base_railway_management AS ra ON ca.railway_code = ra.railway_code
+        LEFT JOIN sys_dept AS de ON ca.dept_id = de.dept_id
+        LEFT JOIN base_device_dynamic_management AS man ON ca.camera_code = man.camera_code
+        <where>
+            <if test="railwayCode != null and railwayCode != ''">
+                and ca.railway_code=#{railwayCode}
+            </if>
+            <if test="isDisable != null and isDisable != ''">
+                and man.is_disable=#{isDisable}
+            </if>
+            <if test="electricity != null and electricity != ''">
+                and man.electricity &lt;=#{electricity}
+            </if>
+            <if test="facilityState != null and facilityState != 0">
+                and man.facility_state =#{facilityState}
+            </if>
+            <if test="electricityState != null and electricityState != 0">
+                and man.electricity_state =#{electricityState}
+            </if>
+            <if test="lineDir != null and lineDir != 0">
+                and ca.line_dir =#{lineDir}
+            </if>
+            <if test="deptId != null and deptId != 0">
+                and ca.dept_id =#{deptId}
+            </if>
+            <if test="!dsFlay">
+                and
+                <trim prefix="(" prefixOverrides="or" suffix=")">
+                    <if test="dsUserId != null and dsUserId != ''">
+                        or a.create_by=#{dsUserId}
+                    </if>
+                    <if test="dsDeptId != null and dsDeptId != 0">
+                        or a.dept_id=#{dsDeptId}
+                    </if>
+                    <if test="dsDeptIds != null">
+                        or a.dept_id in
+                        <foreach item="item" collection="dsDeptIds" separator="," open="(" close=")" index="">
+                            #{item}
+                        </foreach>
+                    </if>
+                </trim>
+            </if>
+        </where>
+        ORDER BY
+        man.electricity
+    </select>
 </mapper>

+ 123 - 41
hazard-admin/src/main/java/com/ozs/web/controller/accountmanagment/BaseCameraManagementController.java

@@ -9,6 +9,7 @@ import com.ozs.common.core.controller.BaseController;
 import com.ozs.common.core.domain.AjaxResult;
 import com.ozs.common.core.domain.entity.SysDept;
 import com.ozs.common.core.domain.entity.SysDictData;
+import com.ozs.common.core.domain.entity.SysRole;
 import com.ozs.common.core.redis.RedisCache;
 import com.ozs.common.enums.BusinessType;
 import com.ozs.common.exception.base.BaseException;
@@ -743,30 +744,33 @@ public class BaseCameraManagementController extends BaseController {
         });
         for (CameraTree child : children) {
             List<CameraTree> children1 = child.getChildren();
-            children1.sort(new Comparator<CameraTree>() {
-                @Override
-                public int compare(CameraTree o1, CameraTree o2) {
-                    int i = o1.getMileage() - o2.getMileage();
-                    if (i == 0) {
-                        String[] split = o1.getName().split("-");
-                        return "上行".equals(split[1]) ? -1 : 1;
-                    } else {
-                        return i;
+            for (CameraTree tree3 : children1) {
+                List<CameraTree> cameraTreeList = tree3.getChildren();
+                cameraTreeList.sort(new Comparator<CameraTree>() {
+                    @Override
+                    public int compare(CameraTree o1, CameraTree o2) {
+                        int i = o1.getMileage() - o2.getMileage();
+                        if (i == 0) {
+                            String[] split = o1.getName().split("-");
+                            return "上行".equals(split[1]) ? -1 : 1;
+                        } else {
+                            return i;
+                        }
                     }
-                }
-            });
-            for (CameraTree tree : children1) {
-                List<CameraTree> children2 = tree.getChildren();
-                if (children2.size() < 2) {
-                    String code = children2.get(0).getCode();
-                    tree.setCode(code);
-                    children2.remove(0);
-                } else {
-                    for (CameraTree cameraTree1 : children2) {
-                        count = count + 1;
-                        cameraTree1.setName("相机" + count);
+                });
+                for (CameraTree tree : cameraTreeList) {
+                    List<CameraTree> children2 = tree.getChildren();
+                    if (children2.size() < 2) {
+                        String code = children2.get(0).getCode();
+                        tree.setCode(code);
+                        children2.remove(0);
+                    } else {
+                        for (CameraTree cameraTree1 : children2) {
+                            count = count + 1;
+                            cameraTree1.setName("相机" + count);
+                        }
+                        count = 0;
                     }
-                    count = 0;
                 }
             }
         }
@@ -929,7 +933,12 @@ public class BaseCameraManagementController extends BaseController {
         if (ObjectUtils.isEmpty(one)) {
             throw new BaseException("相机编号【" + vo.getCameraCode() + "】不存在");
         }
-        return new AjaxResult(200, "ok", CameraUtil.getRecordList(one.getChannel(), vo.getStartTime(), vo.getEntTime()));
+        String recordUrl = CameraUtil.getRecordUrl(one.getCameraCode(), one.getChannel(), vo.getStartTime(), vo.getEntTime());
+        if (recordUrl.contains("当前相机暂无回放视频")) {
+            return  AjaxResult.error(recordUrl);
+        }else {
+            return AjaxResult.success("ok",recordUrl);
+        }
     }
 
     @GetMapping("/api/getRecordByAlarmId")
@@ -940,24 +949,7 @@ public class BaseCameraManagementController extends BaseController {
         wrapper.eq(MsgAlarm::getAlarmId, alarmId);
         MsgAlarm msgAlarm = msgAlarmService.getOne(wrapper);
         if (ObjectUtils.isEmpty(msgAlarm.getReleasedUrl())) {
-            Map<String, Object> map = baseCameraManagementService.getCameraChannelByAlarmId(alarmId);
-            if (!ObjectUtils.isEmpty(map)
-                    && map.size() > 0
-                    && !org.apache.commons.lang3.StringUtils.isBlank(map.get("channel").toString())) {
-                String url = null;
-                if (map.get("isLock").toString().equals("1")) {
-                    url = com.ozs.web.core.util.CameraUtil.historyPlayListStr(map.get("channel").toString(),
-                            (Date) map.get("alarmTime"),
-                            (Date) map.get("releasedTime"),
-                            true);
-                    msgAlarm.setReleasedUrl(url);
-                    msgAlarmService.updateById(msgAlarm);
-                }
-                return error("报警ID为:【" + alarmId + "】的相机信息还未生成报警回放视频");
-            } else {
-                return error("报警ID为:【" + alarmId + "】的相机信息不存在");
-            }
-
+            return error("当前相机暂无回放视频");
         } else {
             return new AjaxResult(200, "ok", caneraConfig.getRecordUrl() + msgAlarm.getReleasedUrl());
         }
@@ -965,6 +957,7 @@ public class BaseCameraManagementController extends BaseController {
 
     /**
      * 测试minio删除图片
+     *
      * @return
      */
     @GetMapping("/removePrice")
@@ -974,5 +967,94 @@ public class BaseCameraManagementController extends BaseController {
         return success();
     }
 
+    /**
+     * 设备状态页面
+     *
+     * @param deviceStateResp
+     * @return
+     */
+    @PostMapping("/deviceState/page")
+    @Log(title = "相机台账管理", businessType = BusinessType.SELECT)
+    public AjaxResult deviceStatePage(@RequestBody DeviceStateResp deviceStateResp) {
+        deviceStateResp = (DeviceStateResp) dataScoreUtil.setDataScore(getUserId(), deviceStateResp);
+        IPage<DeviceStateResp> page = baseCameraManagementService.deviceStatePage(deviceStateResp);
+        page.setTotal(page.getTotal());
+        page.setCurrent(page.getCurrent());
+        page.setPages(page.getPages());
+        if (!ObjectUtils.isEmpty(page) && page.getRecords().size() > 0) {
+            List<DeviceStateResp> dto1 = page.getRecords().stream().map(o -> {
+                String mils = AppendUtils.stringAppend(o.getInstallMile());
+                o.setInstallMileName(mils);
+                return o;
+            }).collect(Collectors.toList());
+            page.setRecords(dto1);
+        }
+        return AjaxResult.success(page);
+    }
+
+
+    /**
+     * 导出设备状态页面
+     *
+     * @param response
+     */
+    @PostMapping("/exportDeviceState")
+    @Log(title = "相机台账管理", businessType = BusinessType.EXPORT)
+    public void exportDeviceState(HttpServletResponse response, @RequestBody DeviceStateResp deviceStateResp) {
+        deviceStateResp = (DeviceStateResp) dataScoreUtil.setDataScore(getUserId(), deviceStateResp);
+        List<DeviceStateResp> deviceStateRespList = baseCameraManagementService.deviceStateRespList(deviceStateResp);
+        for (DeviceStateResp deviceStateResp1 : deviceStateRespList) {
+            String mils = AppendUtils.stringAppend(deviceStateResp1.getInstallMile());
+            deviceStateResp1.setInstallMileName(mils);
+        }
+        ExcelUtil<DeviceStateResp> util = new ExcelUtil<>(DeviceStateResp.class);
+        util.exportExcel(response, deviceStateRespList, "台账设备状态数据失败");
+    }
+
+    /**
+     * 获取离线相机和电量低的相机
+     */
+    @GetMapping("/getMalfunctionAndLowCameraManagement")
+    public AjaxResult getMalfunctionAndLowCameraManagement() {
+        HashMap<String, Integer> map = new HashMap<>();
+        LambdaQueryWrapper<BaseDeviceDynamicManagement> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(BaseDeviceDynamicManagement::getIsDisable, 2);
+        List<BaseDeviceDynamicManagement> isDisable = baseDeviceDynamicManagementService.list(wrapper);
+        map.put("isDisable", isDisable.size());
+        LambdaQueryWrapper<BaseDeviceDynamicManagement> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.le(BaseDeviceDynamicManagement::getElectricity, 10);
+        List<BaseDeviceDynamicManagement> electricity = baseDeviceDynamicManagementService.list(queryWrapper);
+
+        List<BaseDeviceDynamicManagement> collect = isDisable.stream().filter(f -> f.getFacilityState()==2).collect(Collectors.toList());
+        List<BaseDeviceDynamicManagement> collect1 = electricity.stream().filter(f -> f.getElectricityState()==2).collect(Collectors.toList());
+
+
+        map.put("electricity", electricity.size());
+        map.put("count", isDisable.size() + electricity.size());
+        map.put("readCount", collect.size()+collect1.size());
+        return AjaxResult.success(map);
+    }
+
+    /**
+     * 修改设备状态信息(1已读2未读)
+     */
+    @PostMapping("/updateState")
+    public AjaxResult updateState(@RequestBody List<DeviceStateResp> deviceStateRespList) {
+        List<String> list = deviceStateRespList.stream().map(DeviceStateResp::getCameraCode).collect(Collectors.toList());
+        BaseDeviceDynamicManagement dynamicManagement = new BaseDeviceDynamicManagement();
+        LambdaQueryWrapper<BaseDeviceDynamicManagement> wrapper = new LambdaQueryWrapper<BaseDeviceDynamicManagement>();
+        wrapper.in(BaseDeviceDynamicManagement::getCameraCode, list);
+        if (deviceStateRespList.get(0).getCategory()==1){
+            dynamicManagement.setElectricityState(1);
+        }else {
+            dynamicManagement.setFacilityState(1);
+        }
+        boolean update = baseDeviceDynamicManagementService.update(dynamicManagement, wrapper);
+        if (update) {
+            return AjaxResult.success();
+        } else {
+            return AjaxResult.error();
+        }
+    }
 }
 

+ 137 - 1
hazard-admin/src/main/java/com/ozs/web/core/util/CameraUtil.java

@@ -2,14 +2,18 @@ package com.ozs.web.core.util;
 
 
 import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.ozs.common.config.BaseConfig;
 import com.ozs.common.constant.Constants;
 import com.ozs.common.core.domain.entity.SysDictData;
 import com.ozs.common.core.redis.RedisCache;
 import com.ozs.common.exception.base.BaseException;
 import com.ozs.common.utils.DateUtils;
+import com.ozs.common.utils.HttpClientUtil;
 import com.ozs.common.utils.http.HttpUtils;
 import com.ozs.framework.config.ServerConfig;
 import com.ozs.service.entity.BaseCameraManagement;
@@ -44,7 +48,8 @@ import javax.annotation.Resource;
 import java.io.*;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.time.ZonedDateTime;
+import java.time.*;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -478,6 +483,76 @@ ffmpeg -i "concat:1.ts|2.ts" -c copy output.mp4
         return filterRecordList(channel, startTm, endTm, filePath, recordUrl + "/profile/");
     }
 
+    /**
+     * 新的视频服务的回放视频接口
+     *
+     * @param cameraCode
+     * @param channel
+     * @param startTm
+     * @param endTm
+     * @return
+     */
+    public static String getRecordUrl(String cameraCode, String channel, Date startTm, Date endTm) {
+        String result = null;
+        String url = webUrl + "/gb28181/api/invite?id=" + cameraCode + "&channel=" + channel + "&startTime=" + startTm.getTime()/1000 + "&endTime=" + endTm.getTime()/1000;
+        try {
+            result = HttpClientUtil.get(url);
+            if (result.equals("200")) {
+                String path = apiSummary(cameraCode + "/" + channel+"/"+startTm.getTime()/1000+"-"+endTm.getTime()/1000);
+                if (StringUtils.isNotEmpty(path)){
+                    return path;
+                }else {
+                    return "当前相机暂无回放视频";
+                }
+            }
+        } catch (Exception e) {
+            log.info(e.getMessage());
+            e.printStackTrace();
+        }
+        return "当前相机暂无回放视频";
+    }
+
+    /**
+     * 调用流媒体获取流列表信息
+     *
+     * @return
+     */
+    public static String apiSummary(String path) {
+        int maxRetries = 5;
+        int retryCount = 0;
+        boolean success = false;
+        JSONArray streamArray = null;
+        while (!success && retryCount < maxRetries) {
+            try {
+                String data = HttpClientUtil.gets(webUrl + "/api/summary");
+                log.info("data------------------>" + data);
+                if (StringUtils.isNotEmpty(data)) {
+                    JSONObject jsonObject = JSONObject.parseObject(data);
+                    streamArray = jsonObject.getJSONArray("Streams");
+                    success = true;
+                }
+            } catch (Exception e) {
+                log.info("Exception caught: " + e.getMessage());
+                // 增加重试计数
+                retryCount++;
+            }
+        }
+        if (!ObjectUtils.isEmpty(streamArray)) {
+            for (int i = 0; i < streamArray.size(); i++) {
+                JSONObject subObj = streamArray.getJSONObject(i);
+                String streamPath = subObj.getString("StreamPath");
+                if (streamPath.equals(path)) {
+                    //取出VideoTracks
+                    JSONArray videoJson = subObj.getJSONArray("VideoTracks");
+                    if (videoJson != null && videoJson.size() > 0) {
+                        return wsUrl + "/ws/" + streamPath;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
     /**
      * 定时任务参数flv文件
      * -----------------------------废弃
@@ -701,6 +776,16 @@ ffmpeg -i "concat:1.ts|2.ts" -c copy output.mp4
         }
     }
 
+    /**
+     * 旧的视频回放的接口
+     *
+     * @param channel
+     * @param startTm
+     * @param endTm
+     * @param mappingUrl
+     * @param wUrl
+     * @return
+     */
     public static List<Map<String, Object>> filterRecordList(String channel,
                                                              Date startTm,
                                                              Date endTm,
@@ -928,6 +1013,57 @@ ffmpeg -i "concat:1.ts|2.ts" -c copy output.mp4
 
     }
 
+    /**
+     * 修改相机状态
+     */
+    public void updateCameraManagementState() {
+        //离线的
+        ArrayList<String> offLine = new ArrayList<>();
+        List<BaseDeviceDynamicManagement> list = baseDeviceDynamicManagementService.list();
+        for (BaseDeviceDynamicManagement baseDeviceDynamicManagement : list) {
+            // 格式化输入时间
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+            Instant instant = baseDeviceDynamicManagement.getUpdateTime().toInstant();
+            // 将Instant对象转换为LocalDateTime对象
+            LocalDateTime localDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
+
+
+            // 获取当前时间
+            LocalDateTime currentTime = LocalDateTime.now();
+
+            // 计算时间差
+            Duration duration = Duration.between(localDateTime, currentTime);
+
+            // 检查时间差是否大于3小时
+            if (duration.toHours() >= 3) {
+                offLine.add(baseDeviceDynamicManagement.getCameraCode());
+            }
+        }
+        //修改离线相机
+        if (!ObjectUtils.isEmpty(offLine)) {
+            LambdaUpdateWrapper<BaseDeviceDynamicManagement> updateWrapper = Wrappers.lambdaUpdate();
+            updateWrapper.in(BaseDeviceDynamicManagement::getCameraCode, offLine);
+
+            // 执行批量修改操作
+            BaseDeviceDynamicManagement update = new BaseDeviceDynamicManagement();
+            update.setIsDisable(2);
+            update.setFacilityState(2);
+            baseDeviceDynamicManagementService.update(update, updateWrapper);
+        }
+
+        //修改在线相机
+        LambdaUpdateWrapper<BaseDeviceDynamicManagement> wrapper = Wrappers.lambdaUpdate();
+        if (!ObjectUtils.isEmpty(offLine)) {
+            wrapper.notIn(BaseDeviceDynamicManagement::getCameraCode, offLine);
+        }
+
+        // 执行批量修改操作
+        BaseDeviceDynamicManagement baseDeviceDynamicManagement = new BaseDeviceDynamicManagement();
+        baseDeviceDynamicManagement.setIsDisable(1);
+        baseDeviceDynamicManagement.setFacilityState(2);
+        baseDeviceDynamicManagementService.update(baseDeviceDynamicManagement, wrapper);
+    }
+
     /**
      * 删除录制视频的零时文件
      */

+ 214 - 15
hazard-sdk/src/main/java/com/ozs/controller/upload/GeoHazardMonitorTokenController.java

@@ -1,8 +1,10 @@
 package com.ozs.controller.upload;
 
 import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONArray;
 import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.ozs.common.annotation.SdkLog;
 import com.ozs.common.constant.Constants;
 import com.ozs.common.core.redis.RedisCache;
@@ -11,6 +13,7 @@ import com.ozs.common.enums.BusinessTypeSdk;
 import com.ozs.common.utils.ApiTokenUtils;
 import com.ozs.common.utils.HttpClientUtil;
 import com.ozs.common.utils.StringUtils;
+import com.ozs.common.utils.http.HttpUtils;
 import com.ozs.common.utils.stateSecrets.SM4Utils;
 import com.ozs.service.entity.BaseCameraManagement;
 import com.ozs.service.entity.BaseDeviceDynamicManagement;
@@ -28,6 +31,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.SetOperations;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.ObjectUtils;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -39,7 +43,16 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import java.nio.charset.StandardCharsets;
 import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 /**
  * 1. 获取身份认证控制层
@@ -70,7 +83,12 @@ public class GeoHazardMonitorTokenController {
     private RedisCache redisCache;
     @Autowired
     private RedisService redisService;
-
+    @Value("${base.webUrl}")
+    private String webUrl;
+    @Value("${base.wsUrl}")
+    private String wsUrl;
+    @Value("${base.recordUrl}")
+    private String recordUrl;
 
     /**
      * 获取web访问令牌
@@ -211,15 +229,12 @@ public class GeoHazardMonitorTokenController {
                 respMsgAlarmVo.setCameraCode(reqMsgAlarmVo.getAlarmCamera());
                 respMsgAlarmVo.setIsCancel(2);
                 respMsgAlarmVo.setCancelTime(null);
-                // 记录要合成报警视频的报警id
-//                Map<String, Object> map = redisCache.getCacheMap(RedisConstant.key);
-//                if (ObjectUtils.isEmpty(map)) {
-//                    map = new HashMap<>();
-//                }
-//                map.put(msgAlarm.getAlarmId(), msgAlarm.getAlarmTime());
-//                log.info("map:{}", map);
-//                redisCache.deleteObject(RedisConstant.key);
-//                redisCache.setCacheMap(RedisConstant.key, map);
+                // 合成报警视频
+                CompletableFuture.runAsync(() -> {
+                    String alarmUrl = alarmHistoryPlay(baseCameraManagement.getCameraCode(), baseCameraManagement.getChannel(), msgAlarm.getAlarmTime());
+                    msgAlarm.setReleasedUrl(alarmUrl);
+                    msgAlarmService.updateById(msgAlarm);
+                });
             } else {
                 BeanUtils.copyProperties(reqMsgAlarmVo, msgAlarmVice);
                 String[] imageUrl = reqMsgAlarmVo.getImageUrls();
@@ -296,17 +311,13 @@ public class GeoHazardMonitorTokenController {
             BaseUser admin = baseUserService.getUserName("admin");
             lw.eq(BaseDeviceDynamicManagement::getCameraCode, reqDeviceVo.getCameraCode());
             BaseDeviceDynamicManagement baseDynamicManagement = baseDeviceDynamicManagementService.getOne(lw);
-            if (ObjectUtils.isEmpty(baseDynamicManagement)) {
-                jsonObject.put("resultCode", 0);
-                jsonObject.put("message", "相机编码不存在!");
-                return SM4Utils.encryptData_ECB(JSONObject.toJSONString(jsonObject), "4370780c9a8c43e5");
-            }
             baseDynamicManagement.setElectricity(reqDeviceVo.getElectricity());
             if (reqDeviceVo.getTime().toString().length() == 10) {
                 reqDeviceVo.setTime(reqDeviceVo.getTime() * 1000);
             }
             baseDynamicManagement.setUpdateTime(new Date(reqDeviceVo.getTime()));
             baseDynamicManagement.setUpdateBy(admin.getUserId());
+            baseDynamicManagement.setElectricityState(2);
             log.info("reqDeviceVo:{}", baseDynamicManagement);
             if (baseDeviceDynamicManagementService.updateById(baseDynamicManagement)) {
                 jsonObject.put("resultCode", 1);
@@ -323,6 +334,194 @@ public class GeoHazardMonitorTokenController {
         }
     }
 
+
+    /**
+     * 报警视频回放新
+     * @param channel
+     * @param cameraCode
+     * @return
+     */
+    public  String alarmHistoryPlay(String channel,String cameraCode,Date alarmDate) {
+        // 获取当前时间
+        // 将Date对象转换为Instant对象
+        Instant instant = alarmDate.toInstant();
+
+        OffsetDateTime currentTime = instant.atOffset(ZoneOffset.ofHours(8));
+        log.info("currentTime------------->" + currentTime);
+        // 获取报警前的时间
+        OffsetDateTime beforeTenMinutes = currentTime.minusMinutes(Long.parseLong("5"));
+        log.info("beforeTenMinutes------------->" + beforeTenMinutes);
+        // 获取报警后的时间
+        OffsetDateTime afterTenMinutes = currentTime.plusMinutes(Long.parseLong("5"));
+        log.info("afterTenMinutes------------->" + afterTenMinutes);
+        // 格式化时间
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        // 将字符串解析为LocalDateTime对象(指定时区为东八区)
+        LocalDateTime startTime = LocalDateTime.parse(beforeTenMinutes.format(formatter), formatter).atOffset(ZoneOffset.ofHours(8)).toLocalDateTime();
+        LocalDateTime endTime = LocalDateTime.parse(afterTenMinutes.format(formatter), formatter).atOffset(ZoneOffset.ofHours(8)).toLocalDateTime();
+        // 将LocalDateTime转换为秒数
+        long seconds = startTime.toEpochSecond(ZoneOffset.ofHours(8));
+        long second = endTime.toEpochSecond(ZoneOffset.ofHours(8));
+        try {
+            TimeUnit.SECONDS.sleep(65 * 5);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+        String result;
+        String url = webUrl + "/gb28181/api/invite?id=" + cameraCode + "&channel=" + channel + "&startTime=" + seconds + "&endTime=" + second;
+        try {
+            result = HttpClientUtil.get(url);
+            if ("200".equals(result)) {
+                String path = apiSummary(cameraCode + "/" + channel+"/"+seconds+"-"+second);
+                if (org.apache.commons.lang3.StringUtils.isNotEmpty(path)){
+                    String codes = HttpUtils.sendGet(startRecording(cameraCode, "playback"));
+                    log.info("codes------>" + codes);
+                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+                    // 使用SimpleDateFormat将Date对象格式化为指定样式的字符串
+                    String formattedDate = sdf.format(alarmDate);
+                    log.info("-----formattedDate-----------" + formattedDate);
+                    String records = getQueryRecords(alarmDate + "/playback", formattedDate,"flv");
+                    log.info("-----records-----------" + records);
+                    return records;
+                }
+            }
+        } catch (Exception e) {
+            log.info(e.getMessage());
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 调用流媒体获取流列表信息
+     *
+     * @return
+     */
+    public  String apiSummary(String path) {
+        int maxRetries = 5;
+        int retryCount = 0;
+        boolean success = false;
+        JSONArray streamArray = null;
+        while (!success && retryCount < maxRetries) {
+            try {
+                String data = HttpClientUtil.gets(webUrl + "/api/summary");
+                log.info("data------------------>" + data);
+                if (org.apache.commons.lang3.StringUtils.isNotEmpty(data)) {
+                    JSONObject jsonObject = JSONObject.parseObject(data);
+                    streamArray = jsonObject.getJSONArray("Streams");
+                    success = true;
+                }
+            } catch (Exception e) {
+                log.info("Exception caught: " + e.getMessage());
+                // 增加重试计数
+                retryCount++;
+            }
+        }
+        if (!ObjectUtils.isEmpty(streamArray)) {
+            for (int i = 0; i < streamArray.size(); i++) {
+                JSONObject subObj = streamArray.getJSONObject(i);
+                String streamPath = subObj.getString("StreamPath");
+                if (streamPath.equals(path)) {
+                    //取出VideoTracks
+                    JSONArray videoJson = subObj.getJSONArray("VideoTracks");
+                    if (videoJson != null && !videoJson.isEmpty()) {
+                        return wsUrl + "/ws/" + streamPath;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 开启录制功能
+     *
+     * @param cameraCode 相机编码
+     * @param channel    相机通道
+     * @return
+     */
+    public  String startRecording(String cameraCode, String channel) {
+        log.info("-----startRecording------" + webUrl + "/recordpro/api/start?streamPath=" + cameraCode + "/" + channel + "&type=mp4");
+        return webUrl + "/recordpro/api/start?streamPath=" + cameraCode + "/" + channel + "&type=mp4";
+    }
+
+    /**
+     * 根据设备id和通道ID和日期获取设备录像文件
+     *
+     */
+    public String getQueryRecords(String streamPath, String date, String type) {
+
+        log.info("-----getQueryRecords------streamPath-----" + streamPath);
+        log.info("-----getQueryRecords-------date----" + date);
+        log.info("-----getQueryRecords-------type----" + type);
+        try {
+            TimeUnit.SECONDS.sleep(60 * 10);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        String param = "{\n" +
+                "    \"streamPath\":\"" + streamPath + "\",\n" +
+                "    \"date\":\"" + date + "\",\n" +
+                "    \"type\":\"" + type + "\"\n" +
+                "}";
+
+        String jsonStr = HttpUtils.sendPost(webUrl + "/recordpro/api/query/records", param);
+        log.info("-----getQueryRecords-------jsonStr----" + jsonStr);
+        JSONObject jsonObj = JSON.parseObject(jsonStr);
+        log.info("-----getQueryRecords-------jsonObj----" + jsonObj);
+        JSONArray resultArray = jsonObj.getJSONArray("result");
+        log.info("-----getQueryRecords-------resultArray----" + resultArray);
+
+        if (!ObjectUtils.isEmpty(resultArray)) {
+            ArrayList<String> list = new ArrayList<>();
+            for (int i = 0; i < resultArray.size(); i++) {
+                JSONObject subObj = resultArray.getJSONObject(i);
+                String size = subObj.getString("Size");
+                String path = subObj.getString("Path");
+                Object created = subObj.get("Created");
+                //从缓存取出预拉的流的集合
+                log.info("size------------------>" + size);
+                log.info("path------------------>" + path);
+                log.info("created------------------>" + created);
+                //判断主码流是否订阅者是2
+                if (Integer.valueOf(size) > 1000) {
+                    list.add(created + "=" + path);
+                }
+            }
+            String records = records(list);
+            log.info("-----getQueryRecords-------records----" + records);
+            String[] split = records.split("=");
+            return recordUrl + Constants.RESOURCE_PREFIX + split[1];
+        }
+        return null;
+    }
+
+    public String records(List<String> objects) {
+
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSXXX");
+        OffsetDateTime maxTime = null;
+
+        for (String timeString : objects) {
+            String[] split = timeString.split("=");
+            OffsetDateTime time = OffsetDateTime.parse(split[0], formatter);
+            if (maxTime == null || time.isAfter(maxTime)) {
+                maxTime = time;
+            }
+        }
+
+        Iterator<String> iter = objects.iterator();
+        while (iter.hasNext()) {
+            String timeString = iter.next();
+            String[] split = timeString.split("=");
+            OffsetDateTime time = OffsetDateTime.parse(split[0], formatter);
+            if (!time.isEqual(maxTime)) {
+                iter.remove();
+            }
+        }
+        return objects.get(0);
+    }
+
+
     public static void main(String[] args) {
 //        String parameter = "rjW9XcaNdY1M2rtUj4rYsW+3nqcJUDBuE6Orqvd4vyMhOh3fQGPNava0aOcUA7h0wuxoQtHE3bUP5imxqbRd/iBT7QDkrqtdPP5QLEhQodT8v0l8YMMtb7yohAJfEThLJOJ8Odl0kuTJXEJBMD8pE//K9KpRGDY4eEKPdS26YywnIl6HwK9EweYxVGtfJOP3/N7lwum2ROv7iqYgefXd/IxGEG8eVqEUutGKpeCcM0dds/N3Uq5ri/k/BrpaKcV96GnlR4pWkBjWOW08eGJ78shuUJkC682294W4RUp3NPPR7OTErtVAh65or8pB+RGDZuZQlUJ/QVpWp2ZdCrN5Wjqsi1TIa00oGQbYmMixOF0=";
 //        String s = SM4Utils.decryptData_ECB(parameter, "4370780c9a8c43e5");

+ 3 - 0
hazard-sdk/src/main/resources/application.yml

@@ -17,6 +17,9 @@ base:
   captchaType: math
   #图片路径前缀
   imgUrl: http://183.236.39.220:18801/picbucket
+  webUrl: http://183.236.39.220:8083
+  wsUrl: ws://183.236.39.220:8083
+  recordUrl: http://183.236.39.220:18082
 
 # 开发环境配置
 server: