package com.ld.igds.inout.manager; import com.ld.igds.camera.ApiCameraManager; import com.ld.igds.camera.CameraUtil; import com.ld.igds.camera.data.ApiCameraData; import com.ld.igds.camera.data.ApiCameraResp; import com.ld.igds.camera.data.ApiSnapReq; import com.ld.igds.constant.BizType; import com.ld.igds.data.SnapImgDto; import com.ld.igds.file.CoreFileService; import com.ld.igds.inout.ApiInoutManager; import com.ld.igds.inout.ApiInoutService; import com.ld.igds.inout.InoutApiConstant; import com.ld.igds.inout.InoutConstant; import com.ld.igds.inout.dto.*; import com.ld.igds.inout.service.InoutService; import com.ld.igds.io.constant.ProtocolEnum; import com.ld.igds.m.service.InoutCommonService; import com.ld.igds.models.InoutConf; import com.ld.igds.models.SnapSer; import com.ld.igds.util.ContextUtil; import com.ld.igds.util.NumberUtil; import com.ld.igds.view.service.SnapSerService; import com.ld.igds.websocket.WebSocketPacket; import com.ld.igds.websocket.WebSocketServer; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.Date; import java.util.List; /** * @Desc: 出入库过程中,针对流程相关的设备联动控制包括,地磅、扦样机、读卡器、闸机、LED对接等 *

* 注意;当前类中事件类方法均使用异步方式实现 * @author: Andy * @update-time: 2023/7/4 重新优化 */ @Slf4j @Component public class InoutEventControlManager { @Resource private SnapSerService snapSerService; @Resource private InoutCommonService inoutCommonService; @Resource private InoutService inoutService; @Resource private CoreFileService fileService; @Resource private ApiInoutManager apiInoutManager; @Resource private ApiCameraManager apiCameraManager; /** * 页面获取车牌识别 * * @param param * @return */ public ApiInoutData getPlateNum(ApiInoutData param) { //如果使用的是地磅插件获取,则需要调整设备为地磅插件信息 if (ProtocolEnum.TCP_FZZY_WEIGHT.getCode().equals(param.getProtocol())) { InoutConf conf = this.getInoutConf(param.getCompanyId(), param.getDeptId(), param.getSort(), InoutConstant.CONF_TYPE_70); if (null == conf) { param.setErrorMsg("没有获取到当前协议插件配置配置信息,获取失败"); return param; } param.setIp(conf.getIp()); param.setPort(conf.getPort()); param.setProtocol(conf.getProtocol()); return apiInoutManager.getApiService(param.getProtocol()).getPlateNum(param); } return apiInoutManager.getApiService(param.getProtocol()).getPlateNum(param); } /** * 获取智慧卡结果 * * @param param * @return */ public ApiInoutData getIcCardNum(ApiInoutData param) { //如果使用的是地磅插件获取,则需要调整设备为地磅插件信息 if (ProtocolEnum.TCP_FZZY_WEIGHT.getCode().equals(param.getProtocol())) { InoutConf conf = this.getInoutConf(param.getCompanyId(), param.getDeptId(), param.getSort(), InoutConstant.CONF_TYPE_70); if (null == conf) { param.setErrorMsg("没有获取到当前协议插件配置配置信息,获取失败"); return param; } param.setIp(conf.getIp()); param.setPort(conf.getPort()); param.setProtocol(conf.getProtocol()); return apiInoutManager.getApiService(param.getProtocol()).getIcCardNum(param); } return apiInoutManager.getApiService(param.getProtocol()).getIcCardNum(param); } /** * 出入库登记初始化 * * @param lpr 车牌识别配置信息 */ @Async public void initInoutRegister(InoutConf lpr) { if (null == lpr) return; ApiInoutData lprData = new ApiInoutData(lpr); apiInoutManager.getApiService(lpr.getProtocol()).initLpr(lprData); } /** * 出入库抓拍 * * @param param * @return */ public SnapImgDto snapImg(SnapImgDto param) { try { InoutConf conf; SnapSer ser = snapSerService.getCacheByDeptId(param.getDeptId()); if (StringUtils.isNotEmpty(param.getId1())) { conf = inoutCommonService.getCacheInoutConf(param.getCompanyId(), param.getDeptId(), param.getId1()); param.setFileName1(this.snapImgByConf(conf, param, ser)); Thread.sleep(500); } if (StringUtils.isNotEmpty(param.getId2())) { conf = inoutCommonService.getCacheInoutConf(param.getCompanyId(), param.getDeptId(), param.getId2()); param.setFileName2(this.snapImgByConf(conf, param, ser)); Thread.sleep(500); } if (StringUtils.isNotEmpty(param.getId3())) { conf = inoutCommonService.getCacheInoutConf(param.getCompanyId(), param.getDeptId(), param.getId3()); param.setFileName3(this.snapImgByConf(conf, param, ser)); } } catch (Exception e) { log.error("---------------------出入库抓拍出现异常--------------------{}", e); } return param; } /** * 通知主控器-通知称重信息和称重完成信息 * * @param snapImgDto */ // private void noticeGatewayWeightInfo(SnapImgDto snapImgDto) { // // log.debug("-------------用户确认称重----通知称重网关----{}", snapImgDto.getWeight()); // InoutConf conf = this.getWeightGateway(snapImgDto.getCompanyId(), snapImgDto.getDeptId(), snapImgDto.getSort()); // // if (null == conf) { // log.info("-------------用户确认称重----通知称重网关---未配置网关----"); // return; // } // // ApiInoutData apiData = new ApiInoutData(conf); // apiData.setTime(new Date()); // apiData.setRepeat(2); // apiData.setWeight(snapImgDto.getWeight()); // apiData.setPlateNum(snapImgDto.getPlateNum()); // //称重信息暂时取消播放 //// apiData.setMsg("当前称重:" + apiData.getWeight() + "千克"); // apiData.setMsg("称重已完成"); // //// apiInoutManager.getApiService(apiData.getProtocol()).noticeWeightDone(apiData); // // apiInoutManager.getApiService(apiData.getProtocol()).noticeRadio(apiData); // } /** * 新增白名单给住控制器,需要注意的是,登记时候不确认使用哪个地磅系统,如果系统配置多个主控器,需要同步全部推送 * * @param imgDto */ // private void noticeGatewayAddWhitePlate(SnapImgDto imgDto) { // // List list = this.getWeightGateway(imgDto.getCompanyId(), imgDto.getDeptId()); // // if (null == list || list.isEmpty()) { // log.info("-------------称重网关增加白名单----没有获取到网关配置-----取消执行---"); // return; // } // // log.debug("-------------登记完成,增加车牌白名单-----------{}", imgDto.getPlateNum()); // // ApiInoutService inoutApiService = apiInoutManager.getApiService(list.get(0).getProtocol()); // // ApiInoutData apiData; // for (InoutConf conf : list) { // apiData = new ApiInoutData(conf); // apiData.setPlateNum(imgDto.getPlateNum()); // // inoutApiService.addWhitePlate(apiData); // } // } // public void noticeProgressComplete(InoutData data) { // log.debug("-----------------通知称重主控--------流程结束删除白名单"); // List list = this.getWeightGateway(data.getCompanyId(), data.getDeptId()); // // if (null == list || list.isEmpty()) { // return; // } // // ApiInoutService inoutApiService = apiInoutManager.getApiService(list.get(0).getProtocol()); // // ApiInoutData apiData; // for (InoutConf conf : list) { // apiData = new ApiInoutData(conf); // apiData.setPlateNum(data.getPlateNum()); // // // inoutApiService.delWhitePlate(apiData); TODO // } // } /** * 调用接口进行抓拍 * * @param conf * @param param * @param snapSer * @return */ private String snapImgByConf(InoutConf conf, SnapImgDto param, SnapSer snapSer) { if (null == conf) return null; if (null == conf.getSnapType()) { log.error("-----------抓拍执行失败:没有配置抓拍方式-----{}", conf.getName()); return null; } ApiSnapReq req = new ApiSnapReq(); req.setCompanyId(conf.getCompanyId()); req.setDeptId(conf.getDeptId()); req.setSn(conf.getSn()); req.setSnapType(conf.getSnapType()); req.setPlayType(conf.getPlayType()); req.setSerSn(null == snapSer ? null : snapSer.getSn()); req.setBizId(param.getBizId()); //若为出入库称重抓拍,则不传递业务主键。在出入库业务提交时保存文件信息 if(InoutConstant.PROGRESS_WEIGHT_TAG.equals(conf.getInoutProgress())){ req.setBizId(null); } req.setCameraName(conf.getName()); req.setMediaAddr(CameraUtil.updateMediaAddr(conf.getMediaAddr(), conf.getLoginId(), conf.getPwd(), conf.getIp(), conf.getPortCtrl(), conf.getChanNum())); String filePath = fileService.getInoutFilePath(new Date()); req.setFilePath(filePath); //调整附件名称,避免出现中文 String fileName = ContextUtil.getTimeId(100) + "_" + conf.getInoutProgress() + ".jpg"; req.setFileName(fileName); //执行抓拍 ApiCameraResp resp = apiCameraManager.getApiCameraService(conf.getPlayType()).snapImg(req); if (ApiCameraResp.CODE_ERROR.equals(resp.getCode())) { log.error("---------抓拍执行失败:{}-----{}", resp.getMsg(), conf.getName()); return null; } return fileName; } /** * 出入库视频 -- 根据播放方式获取不同的播放地址 * * @param param * @return */ public InoutCameraDto inoutVideoPlay(InoutCameraDto param) { //没有配置播放方式 if (StringUtils.isEmpty(param.getPlayType())) { param.setErrorMsg("没有配置播放方式,无法播放!"); return param; } if (StringUtils.isEmpty(param.getCompanyId())) { param.setCompanyId(ContextUtil.getCompanyId()); } //通过接口获取播放地址 ApiCameraData apiCameraData = new ApiCameraData(); apiCameraData.setCompanyId(param.getCompanyId()); apiCameraData.setSn(param.getSn()); apiCameraData.setCameraId(param.getId()); apiCameraData.setPlayType(param.getPlayType()); apiCameraData.setMediaAddr(CameraUtil.updateMediaAddr(param.getMediaAddr(), param.getLoginId(), param.getPwd(), param.getIp(), param.getPortCtrl(), param.getChanNum())); ApiCameraResp result = apiCameraManager.getApiCameraService(param.getPlayType()).getPlayAddr(apiCameraData); if (null == result) { return param; } if (ApiCameraResp.CODE_SUCCESS.equals(result.getCode())) { param.setPlayAddr(result.getPlayAddr()); } if (ApiCameraResp.CODE_ERROR.equals(result.getCode())) { param.setErrorMsg(result.getMsg()); } return param; } public String videoKeepLive(InoutCameraDto param) { ApiCameraData apiCameraData = new ApiCameraData(); apiCameraData.setSn(param.getSn()); apiCameraData.setCameraId(param.getId()); apiCameraData.setPlayType(param.getPlayType()); apiCameraManager.getApiCameraService(param.getPlayType()).keepAlive(apiCameraData); return null; } /** * 根据id获取出入库设备信息 * * @param id * @return */ public InoutConf getInoutConf(String id) { //没有配置播放方式 if (StringUtils.isEmpty(id)) { return null; } return inoutCommonService.getCacheInoutConf(ContextUtil.getCompanyId(), ContextUtil.subDeptId(null), id); } /** * @Desc: 获取称重网关设备 * @author: Andy * @update-time: 2022/11/26 */ public InoutConf getWeightGateway(String companyId, String deptId, String sort) { if (null == sort) sort = "1"; List list = inoutCommonService.getCacheInoutConf(companyId, deptId); if (null == list || list.isEmpty()) return null; for (InoutConf conf : list) { if (InoutConstant.CONF_TYPE_70.equals(conf.getType()) && sort.equals(conf.getSort())) { return conf; } } return null; } /** * @Desc: 获取称重网关设备 * @author: Andy * @update-time: 2022/11/26 */ public InoutConf getLedConf(String companyId, String deptId, String sort) { if (null == sort) sort = "1"; List list = inoutCommonService.getCacheInoutConf(companyId, deptId); if (null == list || list.isEmpty()) return null; for (InoutConf conf : list) { if (InoutConstant.CONF_TYPE_40.equals(conf.getType()) && sort.equals(conf.getSort())) { return conf; } } return null; } /** * 被动收到车牌识别结果,事件 * * @param data */ @Async public void onReceivePlateNum(ApiInoutData data) { InoutConf conf = this.getInoutConfBySn(data.getCompanyId(), data.getDeptId(), data.getSn()); if (null == conf) { log.error("没有获取到出入库配置CONF:"+data.toString()); return; } log.info(conf.toString()); if (0 == conf.getInOrder()) return; data = new ApiInoutData(conf); log.info(data.toString()); ApiInoutService inoutApiService = null; InoutConf gateconf = null; //获取车牌信息,开闸机 if (InoutApiConstant.DEVICE_CODE_1002 == data.getDeviceCode()) { gateconf = this.getWeightGateway(data.getCompanyId(), data.getDeptId(), null); if (null == gateconf) { log.info("----------没有获取到称重控制器--------------"); } data = new ApiInoutData(gateconf); //开入口处道闸 inoutApiService = apiInoutManager.getApiService(gateconf.getProtocol()); data.setDeviceCode(InoutApiConstant.DEVICE_CODE_2002); data.setActionCode(InoutApiConstant.ACTION_CODE_1); inoutApiService.gateControl(data); } if (InoutApiConstant.DEVICE_CODE_1003 == data.getDeviceCode()) { gateconf = this.getWeightGateway(data.getCompanyId(), data.getDeptId(), null); if (null == gateconf) { log.info("----------没有获取到称重控制器--------------"); } //开入口处道闸 data = new ApiInoutData(gateconf); inoutApiService = apiInoutManager.getApiService(gateconf.getProtocol()); data.setDeviceCode(InoutApiConstant.DEVICE_CODE_2003); data.setActionCode(InoutApiConstant.ACTION_CODE_1); inoutApiService.gateControl(data); } } /** * 出入库称重页面初始化,如果有SDK车牌识别,需要进行初始化操作 * * @param listInoutConf * @param sort */ @Async public void initInoutWeight(List listInoutConf, String sort) { //获取车牌配置信息 if (null == listInoutConf) return; ApiInoutData apiInoutData; ApiInoutService inoutApiService; for (InoutConf conf : listInoutConf) { if (InoutConstant.PROGRESS_WEIGHT_TAG.equals(conf.getInoutProgress())&&InoutConstant.CONF_TYPE_10.equals(conf.getType()) && sort.equals(conf.getSort())) { apiInoutData = new ApiInoutData(conf); inoutApiService = apiInoutManager.getApiService(conf.getProtocol()); inoutApiService.initLpr(apiInoutData); } } } /** * 出入库登记完成触发事件,默认为异步处理 * * @param data */ @Async public void onInoutRegister(InoutData data) { //DO Nothing } /** * 出入库称重完成,事件 * * @param data * @param curProgress * @param nextProgress */ @Async public void onInoutWeight(InoutData data, String curProgress, String nextProgress) { ApiInoutData apiData; //通知化验屏 //获取LED屏配置信息 InoutConf ledConf = this.getLedConf(data.getCompanyId(), data.getDeptId(), null); if(null != ledConf){ apiData = new ApiInoutData(ledConf); apiData.setTime(new Date()); apiData.setDeviceCode(InoutApiConstant.DEVICE_CODE_6001); ApiInoutService inoutApiService = apiInoutManager.getApiService(ledConf.getProtocol()); inoutApiService.noticeLed(apiData, data); } //获取地磅控制器 InoutConf conf = this.getWeightGateway(data.getCompanyId(), data.getDeptId(), null); if (null == conf) { log.info("----------称重完成事件,没有获取到称重控制器--------------"); } //1、通知称重显示屏,设备编号6001 apiData = new ApiInoutData(conf); apiData.setTime(new Date()); apiData.setDeviceCode(InoutApiConstant.DEVICE_CODE_6001); ApiInoutService inoutApiService = apiInoutManager.getApiService(conf.getProtocol()); inoutApiService.noticeLed(apiData, data); //2、语音通知 apiData.setDeviceCode(InoutApiConstant.DEVICE_CODE_8001); inoutApiService.noticeRadio(apiData, data); //3、开闸机 if (InoutConstant.TYPE_IN.equals(data.getType())) { //结算重量大于0表示二次称重 if (data.getNetWeight() > 0) { apiData.setDeviceCode(InoutApiConstant.DEVICE_CODE_2002); } else { apiData.setDeviceCode(InoutApiConstant.DEVICE_CODE_2003); } apiData.setActionCode(InoutApiConstant.ACTION_CODE_1); inoutApiService.gateControl(apiData); } else { //结算重量大于0表示二次称重 if (data.getNetWeight() > 0) { apiData.setDeviceCode(InoutApiConstant.DEVICE_CODE_2002); } else { apiData.setDeviceCode(InoutApiConstant.DEVICE_CODE_2003); } apiData.setActionCode(InoutApiConstant.ACTION_CODE_1); inoutApiService.gateControl(apiData); } //4、开红绿灯 if (InoutConstant.TYPE_IN.equals(data.getType())) { //结算重量大于0表示二次称重 if (data.getNetWeight() > 0) { apiData.setDeviceCode(InoutApiConstant.DEVICE_CODE_7001); } else { apiData.setDeviceCode(InoutApiConstant.DEVICE_CODE_7002); } apiData.setActionCode(InoutApiConstant.ACTION_CODE_1); inoutApiService.lightControl(apiData); } else { //结算重量大于0表示二次称重 if (data.getNetWeight() > 0) { apiData.setDeviceCode(InoutApiConstant.DEVICE_CODE_7002); } else { apiData.setDeviceCode(InoutApiConstant.DEVICE_CODE_7001); } apiData.setActionCode(InoutApiConstant.ACTION_CODE_1); inoutApiService.lightControl(apiData); } } /** * 值仓完成,事件 * * @param data * @param curProgress * @param nextProgress */ @Async public void onInoutHandle(InoutData data, String curProgress, String nextProgress) { //DO Nothing } /** * 扦样完成,事件 * * @param data */ @Async public void onInSimple(InoutCheckData data) { //DO Nothing } /** * 质检完成,事件 * * @param data * @param curProgress * @param nextProgress */ @Async public void onInCheck(InoutCheckData data, String curProgress, String nextProgress) { //1、质检大屏显示 } /** * 流程完成,事件 * * @param data */ @Async public void onInoutComplete(InoutData data) { //DO Nothing } /** * 初始化大屏 * * @param companyId 组织编码 * @param deptId 分库编码 * @param progress 流程环节 */ @Async public void initInoutScreen(String companyId, String deptId, String progress) { if (null == WebSocketServer.contextOnLineMap.get(BizType.SCREEN .getCode())) { WebSocketServer.contextOnLineMap.put(BizType.SCREEN.getCode(), false); } if (null == WebSocketServer.contextOnLineMap.get(BizType.SCREEN_INOUT .getCode())) { WebSocketServer.contextOnLineMap.put( BizType.SCREEN_INOUT.getCode(), false); } if (null == WebSocketServer.contextOnLineMap.get(BizType.SCREEN_CHECK .getCode())) { WebSocketServer.contextOnLineMap.put( BizType.SCREEN_CHECK.getCode(), false); } if (WebSocketServer.contextOnLineMap.get(BizType.SCREEN.getCode()) || WebSocketServer.contextOnLineMap.get(BizType.SCREEN_INOUT .getCode()) || WebSocketServer.contextOnLineMap.get(BizType.SCREEN_CHECK .getCode())) { // 推送到大屏 List curList = inoutService.getListInoutCache(deptId); List completeList = inoutService.getCompleteListInoutCache(deptId); notifyInoutScreen(companyId, deptId, curList, completeList); } } private void notifyInoutScreen(String companyId, String deptId, List curList, List completeList) { InoutSumDto dto = new InoutSumDto(); if (null != curList) { for (InoutData data : curList) { if (InoutConstant.TYPE_IN.equals(data.getType())) { dto.setInSumNum(dto.getInSumNum() + 1); } if (InoutConstant.TYPE_OUT.equals(data.getType())) { dto.setOutSumNum(dto.getOutSumNum() + 1); } dto.setCompanyId(companyId); dto.setDeptId(deptId); } } if (null != completeList) { for (InoutData data : completeList) { if (InoutConstant.TYPE_IN.equals(data.getType())) { dto.setInSumNum(dto.getInSumNum() + 1); dto.setInComplateNum(dto.getInComplateNum() + 1); } if (InoutConstant.TYPE_OUT.equals(data.getType())) { dto.setOutSumNum(dto.getOutSumNum() + 1); dto.setOutComplateNum(dto.getOutComplateNum() + 1); } dto.setCompanyId(data.getCompanyId()); dto.setDeptId(data.getDeptId()); } } // 调整封装 if (dto.getInSumNum() > 0) { dto.setPerInComplate(dto.getInComplateNum() / Double.valueOf(dto.getInSumNum())); dto.setPerInComplate(NumberUtil.keepPrecision( dto.getPerInComplate() * 100, 1)); } if (dto.getOutSumNum() > 0) { dto.setPerOutComplate(dto.getOutComplateNum() / Double.valueOf(dto.getOutSumNum())); dto.setPerOutComplate(NumberUtil.keepPrecision( dto.getPerOutComplate() * 100, 1)); } if (null == dto.getCompanyId()) { dto.setCompanyId(ContextUtil.getDefaultCompanyId()); } // 推送综合管理大屏 WebSocketPacket packet = new WebSocketPacket(); packet.setBizId("IN_OUT_SUMMARY"); packet.setCompanyId(dto.getCompanyId()); packet.setDeptId(dto.getDeptId()); packet.setBizType(BizType.SCREEN.getCode()); packet.setData(dto); WebSocketServer.sendByBizTag(packet); // 推送出入库大屏 dto.setCurList(curList); dto.setComplateList(completeList); packet.setBizType(BizType.SCREEN.getCode()); packet.setBizTag(WebSocketPacket.BIZ_TAG_SCREEN_INOUT); WebSocketServer.sendByBizTag(packet); // 推送化验大屏 packet.setBizType(BizType.SCREEN.getCode()); packet.setBizTag(WebSocketPacket.BIZ_TAG_SCREEN_CHECK); WebSocketServer.sendByBizTag(packet); } /** * 获取称重插件配置信息 * * @param companyId * @param deptId * @param sort * @param type * @return */ public InoutConf getInoutConf(String companyId, String deptId, String sort, String type) { // 获取出入库配置信息 List listInoutConf = inoutCommonService.getCacheInoutConf(companyId, deptId); if (null == listInoutConf) return null; InoutConf result = null; for (InoutConf conf : listInoutConf) { if (sort.equals(conf.getSort()) && type.equals(conf.getType())) { result = conf; break; } } if (null == result) return null; return result; } private InoutConf getInoutConfBySn(String companyId, String deptId, String sn) { if (null == sn) return null; // 获取出入库配置信息 List listInoutConf = inoutCommonService.getCacheInoutConf(companyId, deptId); if (null == listInoutConf) return null; for (InoutConf conf : listInoutConf) { if (null == conf.getSn()) continue; if (sn.equals(conf.getSn())) return conf; } return null; } }