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;
}
/**
* 被动收到车牌识别结果,事件
*
* @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) {
//获取地磅控制器
InoutConf conf = this.getWeightGateway(data.getCompanyId(), data.getDeptId(), null);
if (null == conf) {
log.info("----------称重完成事件,没有获取到称重控制器--------------");
}
//1、通知称重显示屏,设备编号6001
ApiInoutData 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;
}
}