ycl-pojo/src/main/java/com/ycl/platform/domain/entity/WorkOrderCheckImg.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ycl-pojo/src/main/java/com/ycl/platform/domain/vo/DeviceInfoVO.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ycl-server/src/main/java/com/ycl/platform/mapper/WorkOrderCheckImgMapper.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ycl-server/src/main/java/com/ycl/platform/service/WorkOrderService.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ycl-server/src/main/java/com/ycl/platform/service/impl/WorkOrderServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ycl-server/src/main/java/com/ycl/task/WorkOrderImgTask.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ycl-server/src/main/resources/mapper/zgyw/WorkOrderCheckImgMapper.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ycl-server/src/main/resources/mapper/zgyw/WorkOrderMapper.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
ycl-pojo/src/main/java/com/ycl/platform/domain/entity/WorkOrderCheckImg.java
New file @@ -0,0 +1,32 @@ package com.ycl.platform.domain.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import java.util.Date; /** * 工单检测图片 * * @author:xp * @date:2024/8/29 10:22 */ @Data @TableName("t_work_order_check_img") public class WorkOrderCheckImg { @TableId(value = "id", type = IdType.AUTO) private Integer id; @TableField("work_order_no") private String workOrderNo; @TableField("img_url") private String imgUrl; @TableField("create_time") private Date createTime; } ycl-pojo/src/main/java/com/ycl/platform/domain/vo/DeviceInfoVO.java
@@ -19,6 +19,9 @@ /** 工单ID */ private Integer workOrderId; /** 工单号 */ private String workOrderNo; /** 设备编号/国标码 */ private String deviceId; ycl-server/src/main/java/com/ycl/platform/mapper/WorkOrderCheckImgMapper.java
New file @@ -0,0 +1,27 @@ package com.ycl.platform.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ycl.platform.domain.entity.CalculateMoneyRule; import com.ycl.platform.domain.entity.WorkOrderCheckImg; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; /** * 工单图片检测 * * @author xp * @since 2024-04-26 */ @Mapper public interface WorkOrderCheckImgMapper extends BaseMapper<WorkOrderCheckImg> { /** * 批量插入 * @param list */ void insertMany(@Param("list") List<WorkOrderCheckImg> list); } ycl-server/src/main/java/com/ycl/platform/service/WorkOrderService.java
@@ -181,11 +181,12 @@ /** * 工单设备点播获取一帧图片 * * @param deviceId 设备国标码 * @param channelId 设备通道编号 * @param deviceId 国标设备国标码 * @param channelId 设备通道编号(设备国标码) * @param workOrderNo 工单号 * @return 数据 */ String getFrameImgByDevice(String deviceId, String channelId) throws FFmpegFrameGrabber.Exception; String getFrameImgByDevice(String deviceId, String channelId, String workOrderNo); /** * 查询工单:已下发、已处理、已完成的工单 @@ -195,7 +196,7 @@ List<DeviceInfoVO> hasErrorWorkOrderList(); /** * 查询工单:已下发、已处理、已完成的工单 * 更新工单图片 * * @param workOrderId 工单ID * @param imgPath 图像地址 ycl-server/src/main/java/com/ycl/platform/service/impl/WorkOrderServiceImpl.java
@@ -38,6 +38,7 @@ import com.ycl.utils.http.HttpUtils; import com.ycl.utils.redis.RedisCache; import com.ycl.utils.uuid.IdUtils; import constant.Constants; import enumeration.general.NotifyTypeEnum; import enumeration.general.UrgentLevelEnum; import enumeration.general.WorkOrderDistributeWayEnum; @@ -663,35 +664,32 @@ @Override public String getFrameImgByDevice(String deviceId, String channelId) throws FFmpegFrameGrabber.Exception { public String getFrameImgByDevice(String deviceId, String channelId, String workOrderNo) { String url = String.format(this.rtspServer + "/api/play/start/%s/%s", deviceId, channelId); String result = HttpUtils.sendGet(url); // 假设WVPResult是正确解析响应的类 WVPResult wvpResult = JSON.parseObject(result, WVPResult.class); String imgUrl = null; if (wvpResult.getCode() == 0) { System.out.println("请求成功"); JSONObject data = (JSONObject) wvpResult.getData(); String rtspUrl = data.getString("fmp4"); // 注意:通常RTSP URL不会以"fmp4"结尾,这里可能是特定API的返回格式 if (StringUtils.hasText(rtspUrl)) { System.out.println("目标地址:" + rtspUrl); FFmpegFrameGrabber grabber = null; try { grabber = FFmpegFrameGrabber.createDefault(rtspUrl); grabber.start(); Frame frame = grabber.grabImage(); // 直接捕获一帧 if (frame != null) { System.out.println("成功捕获一帧"); // 将Frame转换为Mat OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat(); Mat mat = converter.convertToMat(frame); imgUrl = workOrderNo + "_" + IdUtils.fastSimpleUUID() + ".png"; // 生成图片路径 String imgPath = PlatformConfig.getUploadPath() + deviceId + IdUtils.fastSimpleUUID() + ".png"; System.out.println("图片地址:" + imgPath); String imgPath = PlatformConfig.getUploadPath() + "/" + imgUrl; System.out.println("图片保存地址:" + imgPath); imgUrl = Constants.RESOURCE_PREFIX + "/" + imgUrl; // 保存图片 opencv_imgcodecs.imwrite(imgPath, mat); } else { @@ -714,8 +712,8 @@ } else { System.out.println("请求失败,错误码:" + wvpResult.getCode()); } return null; System.out.println("图片URL:" + imgUrl); return imgUrl; } @Override @@ -728,6 +726,7 @@ public void updateImgById(Integer workOrderId, String imgPath) { new LambdaUpdateChainWrapper<>(baseMapper) .eq(WorkOrder::getId, workOrderId) .set(WorkOrder::getYwCheckResult, imgPath); .set(WorkOrder::getYwCheckResult, imgPath) .update(); } } ycl-server/src/main/java/com/ycl/task/WorkOrderImgTask.java
@@ -2,8 +2,10 @@ import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.ycl.platform.domain.entity.DeviceInfo; import com.ycl.platform.domain.entity.WorkOrderCheckImg; import com.ycl.platform.domain.vo.DeviceInfoVO; import com.ycl.platform.mapper.DeviceInfoMapper; import com.ycl.platform.mapper.WorkOrderCheckImgMapper; import com.ycl.platform.service.WorkOrderService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -12,6 +14,8 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ExecutorService; @@ -31,6 +35,7 @@ private final WorkOrderService workOrderService; private final DeviceInfoMapper deviceInfoMapper; private final WorkOrderCheckImgMapper workOrderCheckImgMapper; private static final ExecutorService executorService = new ThreadPoolExecutor(8, 24, @@ -46,6 +51,7 @@ if (CollectionUtils.isEmpty(deviceList)) { return; } // 查出国标设备,就一条数据 List<DeviceInfo> gbDevices = new LambdaQueryChainWrapper<>(deviceInfoMapper) .orderByDesc(DeviceInfo::getUpdateTime) .last("limit 1") @@ -56,14 +62,13 @@ for (DeviceInfoVO deviceInfo : deviceList) { executorService.submit(() -> { // 国标设备的编码就是取视频流的设备编码,国标设备就一个。国标设备的每一个通道代表一个摄像头,也就是设备id是取流的通道id String frameImg = null; try { frameImg = workOrderService.getFrameImgByDevice(gbDevices.get(0).getDeviceId(), deviceInfo.getDeviceId()); } catch (FFmpegFrameGrabber.Exception e) { e.printStackTrace(); } String frameImg = workOrderService.getFrameImgByDevice(gbDevices.get(0).getDeviceId(), deviceInfo.getDeviceId(), deviceInfo.getWorkOrderNo()); if (StringUtils.hasText(frameImg)) { workOrderService.updateImgById(deviceInfo.getWorkOrderId(), frameImg); WorkOrderCheckImg img = new WorkOrderCheckImg(); img.setWorkOrderNo(deviceInfo.getWorkOrderNo()); img.setImgUrl(frameImg); img.setCreateTime(new Date()); workOrderCheckImgMapper.insert(img); } }); } ycl-server/src/main/resources/mapper/zgyw/WorkOrderCheckImgMapper.xml
New file @@ -0,0 +1,14 @@ <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ycl.platform.mapper.WorkOrderCheckImgMapper"> <insert id="insertMany"> INSERT INTO t_work_order_check_img (work_order_no, img_url, create_time) VALUES <foreach collection="list" item="img" separator=","> (#{img.workOrderNo}, #{img.imgUrl}, #{img.createTime}) </foreach> </insert> </mapper> ycl-server/src/main/resources/mapper/zgyw/WorkOrderMapper.xml
@@ -215,6 +215,7 @@ <select id="hasErrorWorkOrderList" resultType="com.ycl.platform.domain.vo.DeviceInfoVO"> SELECT wo.id as workOrderId, wo.work_order_no as workOrderNo, wo.serial_number as deviceId FROM t_work_order wo