From 6821240f1c86b6bbb700a125c081dedfad61bb17 Mon Sep 17 00:00:00 2001 From: zhangzq Date: Thu, 18 Sep 2025 16:00:57 +0800 Subject: [PATCH] =?UTF-8?q?add:=E5=9B=BE=E7=89=87=E9=A2=84=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/constant/DictConstantPool.java | 8 +++ .../hikvision/HikvisionSnapshotUtil.java | 51 ++++++++++++++++++- .../common/hikvision/Hikvision截图Demo.java | 2 +- .../org/nl/common/hikvision/接入文档.md | 1 + .../config/thread/ThreadPoolExecutorUtil.java | 15 +++--- .../controller/BsrealStorattrController.java | 29 +++++++++++ .../ext/service/impl/AcsToWmsServiceImpl.java | 7 ++- .../main/resources/config/application-dev.yml | 4 +- .../views/wms/statement/structivt/index.vue | 20 +++++++- .../wms/statement/structivt/structivt.js | 10 +++- 10 files changed, 133 insertions(+), 14 deletions(-) diff --git a/wms/nladmin-system/nlsso-server/src/main/java/org/nl/common/domain/constant/DictConstantPool.java b/wms/nladmin-system/nlsso-server/src/main/java/org/nl/common/domain/constant/DictConstantPool.java index 614ae0d..c0cd470 100644 --- a/wms/nladmin-system/nlsso-server/src/main/java/org/nl/common/domain/constant/DictConstantPool.java +++ b/wms/nladmin-system/nlsso-server/src/main/java/org/nl/common/domain/constant/DictConstantPool.java @@ -3,12 +3,16 @@ package org.nl.common.domain.constant; import lombok.Data; import lombok.ToString; import org.nl.common.hikvision.HikvisionSnapshotUtil; +import org.nl.config.thread.ThreadPoolExecutorUtil; import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; +import javax.annotation.Resource; +import java.util.concurrent.ThreadPoolExecutor; /** * s @@ -36,6 +40,9 @@ public class DictConstantPool { @Value("${hikvison.channelSdk}") public Integer channel; + @Resource( name = "meshandlerPool") + private ThreadPoolExecutor threadPoolExecutor; + public static final String DICT_SYS_CODE = "system_type"; public static final String DICT_SYS_NAME = "所属系统"; @@ -49,5 +56,6 @@ public class DictConstantPool { HikvisionSnapshotUtil.username = this.username; HikvisionSnapshotUtil.channelHttp = this.channelHttp; HikvisionSnapshotUtil.channel = this.channel; + HikvisionSnapshotUtil.threadPoolExecutor = this.threadPoolExecutor; } } diff --git a/wms/nladmin-system/nlsso-server/src/main/java/org/nl/common/hikvision/HikvisionSnapshotUtil.java b/wms/nladmin-system/nlsso-server/src/main/java/org/nl/common/hikvision/HikvisionSnapshotUtil.java index cb3dd27..00e5eb8 100644 --- a/wms/nladmin-system/nlsso-server/src/main/java/org/nl/common/hikvision/HikvisionSnapshotUtil.java +++ b/wms/nladmin-system/nlsso-server/src/main/java/org/nl/common/hikvision/HikvisionSnapshotUtil.java @@ -1,12 +1,17 @@ package org.nl.common.hikvision; +import cn.hutool.core.date.DateUtil; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Structure; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; +import java.util.concurrent.ThreadPoolExecutor; + @Service +@Slf4j public class HikvisionSnapshotUtil { public static String ins; //HCNetSDK.dll文件路径 @@ -17,6 +22,7 @@ public class HikvisionSnapshotUtil { public static String password;//海康威视设备网络搜索应用中摄像头管理账密码nl1314520 public static String channelHttp;//默认 public static Integer channel;//默认1 + public static ThreadPoolExecutor threadPoolExecutor; // HCNetSDK 接口映射 public interface HCNetSDK extends Library { Hikvision截图Demo.HCNetSDK INSTANCE = Native.load(ins, Hikvision截图Demo.HCNetSDK.class); @@ -68,7 +74,8 @@ public class HikvisionSnapshotUtil { } //HCNetSDK 抓图,图片路径允许指定,不指定则走配置 - public static SdkResponse 截图(String imagePath, String imageName) { + public static SdkResponse 截图( String imageName) { + String imagePath = "D://vehicle/"+DateUtil.thisYear(); if (StringUtils.isEmpty(imageName)){ return SdkResponse.requestFail("图片名称未知"); } @@ -104,4 +111,46 @@ public class HikvisionSnapshotUtil { Hikvision截图Demo.HCNetSDK.INSTANCE.NET_DVR_Cleanup(); return result?SdkResponse.requestOk():SdkResponse.requestFail("[SDK] 最终抓图失败"); } + public static void sync截图(String imageName,String taskCode) { + if (threadPoolExecutor!=null){ + if (StringUtils.isEmpty(imageName)){ + log.warn("图片名称未定义"); + } + String imagePath = HikvisionSnapshotUtil.path+DateUtil.thisYear(); + String sFileUrl = imagePath+"\\"+imageName+"_"+taskCode; + String newFileUrl = imagePath+"\\"+imageName; + if (!Hikvision截图Demo.HCNetSDK.INSTANCE.NET_DVR_Init()) { + + } + Hikvision截图Demo.NET_DVR_DEVICEINFO_V30 deviceInfo = new Hikvision截图Demo.NET_DVR_DEVICEINFO_V30(); + int userId = Hikvision截图Demo.HCNetSDK.INSTANCE.NET_DVR_Login_V30(ip, port, username, password, deviceInfo); + if (userId < 0) { + log.warn("[SDK] 登录失败"); + Hikvision截图Demo.HCNetSDK.INSTANCE.NET_DVR_Cleanup(); + } + Hikvision截图Demo.NET_DVR_JPEGPARA jpegPara = new Hikvision截图Demo.NET_DVR_JPEGPARA(); + // D1 + jpegPara.wPicSize = 2; + // 一般质量 + jpegPara.wPicQuality = 0; + //命名规则:任务号+载具号+时间.jpg + try { + boolean result = Hikvision截图Demo.HCNetSDK.INSTANCE.NET_DVR_CaptureJPEGPicture(userId, channel, jpegPara, sFileUrl); + if (!result) { + result = Hikvision截图Demo.HCNetSDK.INSTANCE.NET_DVR_CaptureJPEGPicture(userId, channel, jpegPara, sFileUrl); + if (result) { + boolean result2 = Hikvision截图Demo.HCNetSDK.INSTANCE.NET_DVR_CaptureJPEGPicture(userId, channel, jpegPara, newFileUrl); + log.info("[SDK] 抓图成功"+imagePath+":"+imageName); + } else { + log.warn("[SDK] 抓图失败"); + } + } + }finally { + Hikvision截图Demo.HCNetSDK.INSTANCE.NET_DVR_Logout(userId); + Hikvision截图Demo.HCNetSDK.INSTANCE.NET_DVR_Cleanup(); + } + }else { + log.warn("线程池未定义"); + } + } } diff --git a/wms/nladmin-system/nlsso-server/src/main/java/org/nl/common/hikvision/Hikvision截图Demo.java b/wms/nladmin-system/nlsso-server/src/main/java/org/nl/common/hikvision/Hikvision截图Demo.java index 7650b8d..be0ef0b 100644 --- a/wms/nladmin-system/nlsso-server/src/main/java/org/nl/common/hikvision/Hikvision截图Demo.java +++ b/wms/nladmin-system/nlsso-server/src/main/java/org/nl/common/hikvision/Hikvision截图Demo.java @@ -114,7 +114,7 @@ public class Hikvision截图Demo { int channelSdk = 1; Hikvision截图Demo.snapshotSdk(ip, (short) port, username, password, channelSdk); - SdkResponse response = HikvisionSnapshotUtil.截图("C://12312/dd", "照片名字"); + SdkResponse response = HikvisionSnapshotUtil.截图("照片名字"); if (!response.getSuc()){ System.out.println(response.getMessage()); } diff --git a/wms/nladmin-system/nlsso-server/src/main/java/org/nl/common/hikvision/接入文档.md b/wms/nladmin-system/nlsso-server/src/main/java/org/nl/common/hikvision/接入文档.md index 7f054c3..f4d9777 100644 --- a/wms/nladmin-system/nlsso-server/src/main/java/org/nl/common/hikvision/接入文档.md +++ b/wms/nladmin-system/nlsso-server/src/main/java/org/nl/common/hikvision/接入文档.md @@ -5,6 +5,7 @@ ## 2.测试 1.输入配置摄像头配置ip及账号密码,调用Main测试代码确认能否获取到照片 2.如果照片指定的目录不存在,照片捕捉会失败 +3.照片路径默认:String imagePath = "D://vehicle/"+DateUtil.thisYear(); ## 3.项目 yml配置 ### hikvision: diff --git a/wms/nladmin-system/nlsso-server/src/main/java/org/nl/config/thread/ThreadPoolExecutorUtil.java b/wms/nladmin-system/nlsso-server/src/main/java/org/nl/config/thread/ThreadPoolExecutorUtil.java index 00c1bfe..0d98dea 100644 --- a/wms/nladmin-system/nlsso-server/src/main/java/org/nl/config/thread/ThreadPoolExecutorUtil.java +++ b/wms/nladmin-system/nlsso-server/src/main/java/org/nl/config/thread/ThreadPoolExecutorUtil.java @@ -17,6 +17,8 @@ package org.nl.config.thread; import org.nl.config.SpringContextHolder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; @@ -27,16 +29,17 @@ import java.util.concurrent.TimeUnit; * @author Zheng Jie * @date 2019年10月31日18:16:47 */ +@Configuration public class ThreadPoolExecutorUtil { - public static ThreadPoolExecutor getPoll(){ - AsyncTaskProperties properties = SpringContextHolder.getBean(AsyncTaskProperties.class); + @Bean(name = "meshandlerPool") + public ThreadPoolExecutor meshandlerPool(){ return new ThreadPoolExecutor( - properties.getCorePoolSize(), - properties.getMaxPoolSize(), - properties.getKeepAliveSeconds(), + 4, + 16, + 30, TimeUnit.SECONDS, - new ArrayBlockingQueue<>(properties.getQueueCapacity()), + new ArrayBlockingQueue<>(64), new TheadFactoryName() ); } diff --git a/wms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/basedata_manage/controller/BsrealStorattrController.java b/wms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/basedata_manage/controller/BsrealStorattrController.java index 67b911c..9173b5d 100644 --- a/wms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/basedata_manage/controller/BsrealStorattrController.java +++ b/wms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/basedata_manage/controller/BsrealStorattrController.java @@ -1,22 +1,31 @@ package org.nl.wms.basedata_manage.controller; +import cn.dev33.satoken.annotation.SaIgnore; +import cn.hutool.core.date.DateUtil; import com.alibaba.fastjson.JSONObject; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.nl.common.base.TableDataInfo; import org.nl.common.domain.query.PageQuery; +import org.nl.common.exception.BadRequestException; +import org.nl.common.hikvision.HikvisionSnapshotUtil; import org.nl.common.logging.annotation.Log; import org.nl.wms.basedata_manage.service.IBsrealStorattrService; import org.nl.wms.basedata_manage.service.dao.BsrealStorattr; +import org.springframework.core.io.UrlResource; import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Map; @@ -75,4 +84,24 @@ public class BsrealStorattrController { iBsrealStorattrService.changeActive(json); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } + + + @GetMapping(value = "/image/{filename}") + @SaIgnore + public ResponseEntity getFile(@PathVariable String filename) { + try { + String imagePath = HikvisionSnapshotUtil.path+ DateUtil.thisYear(); + Path file = Paths.get(imagePath).resolve(filename+".jpg"); + org.springframework.core.io.Resource resource = new UrlResource(file.toUri()); + if (resource.exists() && resource.isReadable()) { + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_TYPE, Files.probeContentType(file)) + .body(resource); + } else { + throw new BadRequestException("文件不存在"); + } + } catch (Exception e) { + throw new BadRequestException(e.getMessage()); + } + } } diff --git a/wms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/service/impl/AcsToWmsServiceImpl.java b/wms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/service/impl/AcsToWmsServiceImpl.java index 79770ed..79dbd81 100644 --- a/wms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/service/impl/AcsToWmsServiceImpl.java +++ b/wms/nladmin-system/nlsso-server/src/main/java/org/nl/wms/ext/service/impl/AcsToWmsServiceImpl.java @@ -1,11 +1,15 @@ package org.nl.wms.ext.service.impl; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.io.unit.DataUnit; import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; +import lombok.Data; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.nl.common.exception.BadRequestException; +import org.nl.common.hikvision.HikvisionSnapshotUtil; import org.nl.wms.basedata_manage.service.IMdPbStoragevehicleinfoService; import org.nl.wms.basedata_manage.service.dao.MdPbStoragevehicleinfo; import org.nl.wms.ext.enums.ResultAcsStatus; @@ -176,7 +180,8 @@ public class AcsToWmsServiceImpl implements AcsToWmsService { // 调用任务类重量反馈方法 AbstractTask task = taskFactory.getTask(taskDao.getConfig_code()); JSONObject resultWeigh = task.resultWeigh(taskDao); - + //调用相机服务保存照片 + HikvisionSnapshotUtil.sync截图(vehicleDao.getStoragevehicle_code(),taskDao.getTask_code()); log.info("ACS向WMS反馈重量,返回参数:--------------------------------------" + BaseResponse.responseOk(resultWeigh).toString()); return BaseResponse.responseOk(resultWeigh); } diff --git a/wms/nladmin-system/nlsso-server/src/main/resources/config/application-dev.yml b/wms/nladmin-system/nlsso-server/src/main/resources/config/application-dev.yml index 3cb6ee8..f54fb1f 100644 --- a/wms/nladmin-system/nlsso-server/src/main/resources/config/application-dev.yml +++ b/wms/nladmin-system/nlsso-server/src/main/resources/config/application-dev.yml @@ -4,10 +4,10 @@ server: nl: config: mysql: - ip: 127.0.0.1 + ip: 192.168.81.251 port: 3306 username: root - password: root + password: P@ssw0rd. database: xujiang_hanyun_wms redis: ip: 127.0.0.1 diff --git a/wms/nladmin-ui/src/views/wms/statement/structivt/index.vue b/wms/nladmin-ui/src/views/wms/statement/structivt/index.vue index f75f304..f4364c3 100644 --- a/wms/nladmin-ui/src/views/wms/statement/structivt/index.vue +++ b/wms/nladmin-ui/src/views/wms/statement/structivt/index.vue @@ -86,7 +86,11 @@ - + + + @@ -98,6 +102,7 @@ + @@ -111,10 +116,11 @@ import pagination from '@crud/Pagination' import crudSectattr from '@/views/wms/basedata/sectattr/sectattr' import { download } from '@/api/data' import { downloadFile } from '@/utils' +import imageModal from './image' export default { name: 'Structivt', - components: { pagination, crudOperation, rrOperation }, + components: { pagination, crudOperation, rrOperation, imageModal }, mixins: [presenter(), header(), crud()], cruds() { return CRUD({ @@ -133,6 +139,8 @@ export default { data() { return { sects: [], + showModal: false, + imageUrl: '', permission: {}, rules: {} } @@ -150,6 +158,14 @@ export default { hand(value) { this.crud.toQuery() }, + toView(vehicle) { + this.showModal = true + crudStructivt.imageLoad('110').then(response => { + const blob = new Blob([response]) // 尽可能根据响应头确定类型 + this.imageUrl = URL.createObjectURL(blob) + } + ) + }, sectQueryChange(val) { if (val.length === 1) { this.query.stor_id = val[0] diff --git a/wms/nladmin-ui/src/views/wms/statement/structivt/structivt.js b/wms/nladmin-ui/src/views/wms/statement/structivt/structivt.js index cea59b8..d2bc78e 100644 --- a/wms/nladmin-ui/src/views/wms/statement/structivt/structivt.js +++ b/wms/nladmin-ui/src/views/wms/statement/structivt/structivt.js @@ -86,4 +86,12 @@ export function unIvtLock(data) { }) } -export default { add, edit, del, getStruct, getStructById, getUnits, save, excelImport, statusChange, ivtLock, unIvtLock } +export function imageLoad(name) { + return request({ + url: '/api/Storattr/image/' + name, + method: 'get', + responseType: 'blob' + }) +} + +export default { add, edit, del, getStruct, imageLoad, getStructById, getUnits, save, excelImport, statusChange, ivtLock, unIvtLock }