package com.sy.service.impl; import com.alibaba.fastjson.JSONArray; import com.sy.mapper.RuleChannelConfigDao; import com.sy.model.*; import com.sy.service.*; import com.sy.socket.CommandClient; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.basis.enhance.groovy.constants.ExecutionStatus; import org.basis.enhance.groovy.entity.EngineExecutorResult; import org.basis.enhance.groovy.entity.ExecuteParams; import org.basis.enhance.groovy.entity.ScriptQuery; import org.basis.enhance.groovy.executor.EngineExecutor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.UUID; import static com.sy.service.impl.ResMessageServiceImpl.toStrArry; /** * 车辆过卡脚本引擎处理 */ @Service @Slf4j public class EnginCheckServiceImpl implements EnginCheckService { private static String PERMITTHOUGH = "直接放行"; @Autowired private EngineExecutor engineExecutor; @Autowired private BusnesslistinfoService busnesslistinfoService; @Autowired private LandBusListService landBusListService; /** * 指令日志表 */ @Autowired private CommandLogService commandLogService; @Autowired private RedisService redisService; @Autowired private LandBusListService listService; @Autowired LandRoadVeService veService; @Resource RuleChannelConfigDao ruleChannelConfigDao; @Value("${devdebug}") private Boolean debug; @Override public Boolean enginCheckByGatherInfo(GatherInfo gatherInfo,ExecuteParams executeParams) { try { //获取申请信息 LandBusinessTypeList chanelFormInfo = (LandBusinessTypeList) executeParams.get("ChanelFormInfo"); if (chanelFormInfo!=null){ //查询验放配置参数生成 RuleChannelConfig ruleChannelConfig = new RuleChannelConfig(); ruleChannelConfig.setBusinessType(chanelFormInfo.getBusinesstype()); ruleChannelConfig.setGoodsType(chanelFormInfo.getCocode()); ruleChannelConfig.setChannelNum(gatherInfo.getChnlno()); List<RuleChannelConfig> ruleChannelConfigs = ruleChannelConfigDao.selectByChannelAndBusiTypeAndGoodsType(ruleChannelConfig); if (ruleChannelConfigs!=null && !ruleChannelConfigs.isEmpty()){ for (int i = 0; i < ruleChannelConfigs.size(); i++) { /** * 核销判定需要另外执行.这里需要跳过. */ if (ruleChannelConfigs.get(i).ruleConfig != null && "核销判定".equals(ruleChannelConfigs.get(i).ruleConfig.getRuleType())){ continue; } // 执行脚本中指定的方法 changeProduct EngineExecutorResult executorResult = engineExecutor.execute( ruleChannelConfigs.get(i).ruleConfig.getScriptMethodName(), new ScriptQuery(ruleChannelConfigs.get(i).ruleConfig.getScriptKey()), executeParams); log.info("验证脚本名称:{},验证KEY-NAME:{},执行结果:{}", ruleChannelConfigs.get(i).ruleConfig.getRuleName(),ruleChannelConfigs.get(i).ruleConfig.getScriptKey(),executorResult); if (executorResult.getExecutionStatus().equals(ExecutionStatus.SUCCESS)){ if (executorResult.getContext() instanceof Boolean){ Boolean execResult = (Boolean) executorResult.getContext(); if (execResult) { log.info("[ENGIN-CHECK-SUCCESS] - 验证脚本名称:{},验证KEY-NAME:{}-[验放成功]",ruleChannelConfigs.get(i).ruleConfig.getRuleName(),ruleChannelConfigs.get(i).ruleConfig.getScriptKey()); }else { log.info("[ENGIN-CHECK-FAILD]验放失败"); return false; } } }else { log.error("[ENGIN-CHECK-FAILD]-验证脚本名称:{},验证KEY-NAME:{}-[验放失败]",ruleChannelConfigs.get(i).ruleConfig.getRuleName(),ruleChannelConfigs.get(i).ruleConfig.getScriptKey()); return false; } } return true; }else { log.error("[ENGIN-CHECK-FAILD]-[{}]-通道未配置规则,不支持此业务",gatherInfo.getChnlno()); sendBw(gatherInfo,false,"通道未配置规则,不支持此业务",executeParams); return false; } } sendBw(gatherInfo,false,"未找到流转申请信息",executeParams); log.error("[ENGIN-CHECK-FAILD]-未找到流转申请信息"); return false; }catch (Exception e){ log.error("[ENGIN-CHECK-ERR]",e); return false; } } @Override public ExecuteParams makeParaByGagherInfo(GatherInfo gatherInfo){ ExecuteParams executeParams = new ExecuteParams(); //初始化 executeParams.put("GatherInfo", gatherInfo); executeParams.put("FormList", null); executeParams.put("ChanelFormInfo", null); executeParams.put("ChanelFormBillLists", null); executeParams.put("LandRoadVe", null); executeParams.put("inAisleWT", 0.0); executeParams.put("diffVal", 0.0); executeParams.put("selfWt", 0.0); executeParams.put("goodsWt", 0.0); //车辆备案信息 LandRoadVe ve = veService.selectByFrameNo(gatherInfo.getVename()); if (ve != null) { //车辆备案重量 Double selfWt=Double.parseDouble(ve.getSelfWt()); executeParams.put("LandRoadVe", ve); executeParams.put("selfWt", selfWt); } //获取申请单表体 String landBusinessJson = ""; if (StringUtils.isNotEmpty(gatherInfo.getVename())) { log.info("[FORM-CACHE-GET]:车辆-{}核碰缓存",gatherInfo.getVename()); landBusinessJson = redisService.get(gatherInfo.getVename()); }else { log.info("[FORM-CACHE-GET]:车辆未获取到车牌号,seqno:{}",gatherInfo.getSeqno()); } if (StringUtils.isNotEmpty(landBusinessJson)) { //这个是申请单表体 List<LandBusinessTypeList> list = JSONArray.parseArray(landBusinessJson, LandBusinessTypeList.class); executeParams.put("FormList", list); //通道对应申请信息 LandBusinessTypeList chanelFormInfo = landBusListService.getLandBusinessTypeListByGather(gatherInfo); executeParams.put("ChanelFormInfo", chanelFormInfo); if (chanelFormInfo!= null){ executeParams.put("goodsWt", Double.parseDouble(chanelFormInfo.getRemark())); } //查询申请单运单列表 List<LAND_BUSINEESTYPE_LIST_INFO> chanelFormBillLists= busnesslistinfoService.selectmanilist(gatherInfo.getBarcode()); executeParams.put("ChanelFormBillLists", chanelFormBillLists); } //对应场站入场信息重量 if ("E".equals(gatherInfo.getIetype())){ List<LandBusinessTypeList> stationInChanleInfo= listService.selectwt(gatherInfo.getVename(),gatherInfo.getBarcode(),gatherInfo.getAreaid(),"I"); if (stationInChanleInfo.isEmpty()){ log.info("未查询到车辆:{}的入场信息",gatherInfo.getVename()); }else { for(LandBusinessTypeList typeList:stationInChanleInfo){ if(typeList.getAislewt()!=null){ //对应场站进场过磅重量 Double inAisleWT = typeList.getAislewt(); executeParams.put("inAisleWT", inAisleWT); //离场与入场重量差值 Double diffVal = inAisleWT- gatherInfo.getGrosswt().doubleValue(); executeParams.put("diffVal", diffVal); } } //TODO:进场校验 增加 车辆备案重量要 <= 进场过磅重量 ,要有误差判定 } } return executeParams; } /** * 发送X22指令 * @param info 过卡信息 * @param check true 抬杆,false 不抬杆 * @param reason 原因 * 调试模式 直接返回true,生产模式按业务走 */ @Override public void sendBw(GatherInfo info, boolean check, String reason,ExecuteParams executeParams) { //调试模式 直接返回true if (debug){ if (check) { record(info,executeParams); //总进出车次计数 redisService.incr("kako-total",1); } commandlog(info,check,reason,executeParams); return; } log.info(String.format("开始发送指令:车牌%s,场站%s,通道%s,重量%s",info.getVename(),info.getAreaid(),info.getChnlno(),info.getGrosswt())); if (check) { CommandClient.Client(info, PERMITTHOUGH); log.info("=============>>>>>>>>放行报文发送成功<<<<<<<<<=============="); record(info,executeParams); //总进出车次计数 redisService.incr("kako-total",1); } else { CommandClient.Client(info, reason); log.info("=============>>>>>>>>重量异常报文发送成功<<<<<<<<<=============="); } commandlog(info,check,reason,executeParams); } /** * 直接放行 */ @Override public void pass(GatherInfo info, ExecuteParams executeParams){ sendBw(info,true,PERMITTHOUGH,executeParams); } @Override public void passFaild(GatherInfo info,String reason,ExecuteParams executeParams) { sendBw(info,false,reason,executeParams); } /** * 记录进出区信息 */ @Override public void record(GatherInfo info, ExecuteParams executeParams){ LandBusinessTypeList landBusinessTypeList = executeParams.getValue("ChanelFormInfo"); Double goodsWt = executeParams.getValue("goodsWt"); Double selfWt = executeParams.getValue("selfWt"); Double diffVal = executeParams.getValue("diffVal"); if ("I".equals(info.getIetype())){ landBusinessTypeList.setAislewt(info.getGrosswt().doubleValue()); landBusinessTypeList.setUpdateDate(new Date()); landBusinessTypeList.setRemark(String.format("%.1f", goodsWt)); //车辆备案重量 landBusinessTypeList.setRemark2(String.valueOf(selfWt)); landBusinessTypeList.setContrastflag("已进站"); }else { landBusinessTypeList.setAislewt(info.getGrosswt().doubleValue()); landBusinessTypeList.setUpdateDate(new Date()); //装载货物总重量 landBusinessTypeList.setRemark(String.format("%.1f", goodsWt)); //进出差值 landBusinessTypeList.setRemark1(String.format("%.1f", diffVal)); landBusinessTypeList.setRemark2(String.valueOf(selfWt)); landBusinessTypeList.setContrastflag("已出站"); } //todo:判定放行后,插入数据库,出入区记录 landBusinessTypeList.setId(UUID.randomUUID().toString()); landBusinessTypeList.setIsvalid("1"); //todo:这里SEQN也要入库 listService.saveList(landBusinessTypeList); } /** * 放行日志记录 * @param info * @param check * @param reason */ @Override public void commandlog(GatherInfo info, boolean check, String reason,ExecuteParams executeParams){ LandBusinessTypeList land = executeParams.getValue("ChanelFormInfo"); Double selfWt = executeParams.getValue("selfWt"); Double inWt = executeParams.getValue("inWt"); Double goodsWt = executeParams.getValue("goodsWt"); Double diffVal = executeParams.getValue("diffVal"); List<LAND_BUSINEESTYPE_LIST_INFO> listInfos = executeParams.getValue("ChanelFormBillLists"); String flag="",type=""; commandLog command=new commandLog(); command.setId(UUID.randomUUID().toString()); command.setBarcode(info.getBarcode()); if(land!=null){ command.setBarcode(land.getBarcode()); command.setBusnessType(land.getBusinesstype()); } command.setAreaId(info.getAreaid()); command.setChnlNo(info.getChnlno()); if (check){ flag = "00"; } else{ flag = "11"; } if("I".equals(info.getIetype())){ type="000000200000000000"; }else{ type="000000100000000000"; } command.setReasonCode(flag+type); command.setReasonText(reason); command.setVeName(info.getVename()); command.setVeWeight(selfWt); command.setIeType(info.getIetype()); if(info.getGrosswt()!=null){ command.setExitGrossWeight(info.getGrosswt().doubleValue()); }else { command.setExitGrossWeight(0.0); } command.setInGrossWeight(inWt); command.setGoodsWeight(goodsWt); command.setActualGoodsWeight(diffVal); if(listInfos !=null && listInfos.size()>0){ command.setMasterList(Arrays.toString(toStrArry(listInfos))); } commandLogService.insert(command); } @Override public void formRelease(GatherInfo gatherInfo, ExecuteParams executeParams) { //获取申请信息 LandBusinessTypeList chanelFormInfo = (LandBusinessTypeList) executeParams.get("ChanelFormInfo"); if (chanelFormInfo!=null) { //查询验放配置参数生成 RuleChannelConfig ruleChannelConfig = new RuleChannelConfig(); ruleChannelConfig.setBusinessType(chanelFormInfo.getBusinesstype()); ruleChannelConfig.setGoodsType(chanelFormInfo.getCocode()); ruleChannelConfig.setChannelNum(gatherInfo.getChnlno()); List<RuleChannelConfig> ruleChannelConfigs = ruleChannelConfigDao.selectByChannelAndBusiTypeAndGoodsType(ruleChannelConfig); if (ruleChannelConfigs!=null && !ruleChannelConfigs.isEmpty()){ for (int i = 0; i < ruleChannelConfigs.size(); i++) { //核销判定 if (ruleChannelConfigs.get(i).ruleConfig != null && "核销判定".equals(ruleChannelConfigs.get(i).ruleConfig.getRuleType())){ // 执行脚本中指定的方法 changeProduct EngineExecutorResult executorResult = engineExecutor.execute( ruleChannelConfigs.get(i).ruleConfig.getScriptMethodName(), new ScriptQuery(ruleChannelConfigs.get(i).ruleConfig.getScriptKey()), executeParams); log.info("核销判定验证脚本名称:{},验证KEY-NAME:{}", ruleChannelConfigs.get(i).ruleConfig.getRuleName(),ruleChannelConfigs.get(i).ruleConfig.getScriptKey()); log.info("核销判定判定放行结果=========>>>>>>>>>>>{}", executorResult); } } } }else { log.error("核销判定通道申请信息无效"); } } @Override public void lockNoticeContinueCheck(GatherInfo gatherInfo) { ExecuteParams executeParams = makeParaByGagherInfo(gatherInfo); Boolean check = enginCheckByLockNotice(gatherInfo,executeParams); if (check){ log.info("脚本验放通过"); //放行 pass(gatherInfo,executeParams); formRelease(gatherInfo,executeParams); }else { log.error("验放失败"); } } private Boolean enginCheckByLockNotice(GatherInfo gatherInfo,ExecuteParams executeParams) { //获取申请信息 LandBusinessTypeList chanelFormInfo = (LandBusinessTypeList) executeParams.get("ChanelFormInfo"); if (chanelFormInfo!=null){ //查询验放配置参数生成 RuleChannelConfig ruleChannelConfig = new RuleChannelConfig(); ruleChannelConfig.setBusinessType(chanelFormInfo.getBusinesstype()); ruleChannelConfig.setGoodsType(chanelFormInfo.getCocode()); ruleChannelConfig.setChannelNum(gatherInfo.getChnlno()); List<RuleChannelConfig> ruleChannelConfigs = ruleChannelConfigDao.selectByChannelAndBusiTypeAndGoodsType(ruleChannelConfig); if (ruleChannelConfigs!=null && !ruleChannelConfigs.isEmpty()){ for (int i = 0; i < ruleChannelConfigs.size(); i++) { /** * 核销判定需要另外执行.这里需要跳过. */ if (ruleChannelConfigs.get(i).ruleConfig != null && "核销判定".equals(ruleChannelConfigs.get(i).ruleConfig.getRuleType())){ continue; } if (ruleChannelConfigs.get(i).ruleConfig != null && ruleChannelConfigs.get(i).ruleConfig.getRuleType().contains("关锁")){ continue; } // 执行脚本中指定的方法 changeProduct EngineExecutorResult executorResult = engineExecutor.execute( ruleChannelConfigs.get(i).ruleConfig.getScriptMethodName(), new ScriptQuery(ruleChannelConfigs.get(i).ruleConfig.getScriptKey()), executeParams); log.info("验证脚本名称:{},验证KEY-NAME:{}", ruleChannelConfigs.get(i).ruleConfig.getRuleName(),ruleChannelConfigs.get(i).ruleConfig.getScriptKey()); log.info("使用groovy脚本来验证过卡判定放行结果=========>>>>>>>>>>>执行结果:{}", executorResult); if (executorResult.getExecutionStatus().equals(ExecutionStatus.SUCCESS)){ if (executorResult.getContext() instanceof Boolean){ Boolean execResult = (Boolean) executorResult.getContext(); if (execResult) { log.info("验证脚本名称:{},验证KEY-NAME:{}-[验放成功]",ruleChannelConfigs.get(i).ruleConfig.getRuleName(),ruleChannelConfigs.get(i).ruleConfig.getScriptKey()); }else { log.info("验放失败"); return false; } } }else { log.error("验证脚本名称:{},验证KEY-NAME:{}-[验放失败]",ruleChannelConfigs.get(i).ruleConfig.getRuleName(),ruleChannelConfigs.get(i).ruleConfig.getScriptKey()); return false; } } return true; }else { log.error("[{}]-通道未配置规则,不支持此业务",gatherInfo.getChnlno()); sendBw(gatherInfo,false,"通道未配置规则,不支持此业务",executeParams); return false; } } sendBw(gatherInfo,false,"未找到流转申请信息",executeParams); log.error("未找到流转申请信息"); return false; } }