作者 朱兆平

验放规则优化

新增非保业务验放脚本
@@ -50,7 +50,7 @@ class BillDomTransportCheck extends Script implements ChannelCheckScript { @@ -50,7 +50,7 @@ class BillDomTransportCheck extends Script implements ChannelCheckScript {
50 50
51 if (listinfos!=null && !listinfos.isEmpty()){ 51 if (listinfos!=null && !listinfos.isEmpty()){
52 //数组过滤,只要单证,不要其他 板箱之类 52 //数组过滤,只要单证,不要其他 板箱之类
53 - List<LAND_BUSINEESTYPE_LIST_INFO> list_infos = listinfos.stream().filter({ listInfo -> 53 + listinfos = listinfos.stream().filter({ listInfo ->
54 if ("B".equals(listInfo.getExt4())) { 54 if ("B".equals(listInfo.getExt4())) {
55 return true; 55 return true;
56 } else { 56 } else {
@@ -58,11 +58,11 @@ class BillDomTransportCheck extends Script implements ChannelCheckScript { @@ -58,11 +58,11 @@ class BillDomTransportCheck extends Script implements ChannelCheckScript {
58 } 58 }
59 }).collect(Collectors.toList()); 59 }).collect(Collectors.toList());
60 60
61 - list_infos.forEach({bill-> 61 + listinfos.forEach({bill->
62 // 创建 Feign Client 62 // 创建 Feign Client
63 //https://nmms.zzcargo.com:8443/api/wlpt-nmms-manage/trans/dom?originFlightno=&originFlightdate=&originFlightdateEnd=&originMasterwaybill=ML66158691&agentName=&transType=dom&pageNum=1&pageSize=10 63 //https://nmms.zzcargo.com:8443/api/wlpt-nmms-manage/trans/dom?originFlightno=&originFlightdate=&originFlightdateEnd=&originMasterwaybill=ML66158691&agentName=&transType=dom&pageNum=1&pageSize=10
64 MyFeignClient myFeignClient = createFeignClient(MyFeignClient, ServiceAdr,cookieUserName,cookieUserId); 64 MyFeignClient myFeignClient = createFeignClient(MyFeignClient, ServiceAdr,cookieUserName,cookieUserId);
65 - 65 + logger.info("[TRANS-CHECK-BILL]-{}",bill.getAwba())
66 // 调用第三方接口 66 // 调用第三方接口
67 String response = myFeignClient.callThirdPartyApi(bill.getAwba(),cookieUserName,cookieUserId); 67 String response = myFeignClient.callThirdPartyApi(bill.getAwba(),cookieUserName,cookieUserId);
68 logger.info("[TRANS-API-RESPONSE]-{}",response) 68 logger.info("[TRANS-API-RESPONSE]-{}",response)
@@ -115,10 +115,10 @@ class BillDomTransportCheck extends Script implements ChannelCheckScript { @@ -115,10 +115,10 @@ class BillDomTransportCheck extends Script implements ChannelCheckScript {
115 }else{ 115 }else{
116 gatherInfoHandle.sendBw(gatherInfo,false,"缺少申请单证信息",landBusinessTypeList,listinfos); 116 gatherInfoHandle.sendBw(gatherInfo,false,"缺少申请单证信息",landBusinessTypeList,listinfos);
117 return checkFlag = false; 117 return checkFlag = false;
118 - } 118 + };
119 if (checkFlag){ 119 if (checkFlag){
120 commandLog(gatherInfo,true,"转运业务单证核放成功",executeParams) 120 commandLog(gatherInfo,true,"转运业务单证核放成功",executeParams)
121 - } 121 + };
122 return checkFlag; 122 return checkFlag;
123 123
124 } catch (Exception e) { 124 } catch (Exception e) {
@@ -165,6 +165,7 @@ class BillDomTransportCheck extends Script implements ChannelCheckScript { @@ -165,6 +165,7 @@ class BillDomTransportCheck extends Script implements ChannelCheckScript {
165 String callThirdPartyApi(@Param("originMasterwaybill") String originMasterwaybill, 165 String callThirdPartyApi(@Param("originMasterwaybill") String originMasterwaybill,
166 @Param("username") String username, 166 @Param("username") String username,
167 @Param("userid") String userid); 167 @Param("userid") String userid);
  168 +
168 } 169 }
169 170
170 class MyFallbackFactory implements FallbackFactory<MyFeignClient> { 171 class MyFallbackFactory implements FallbackFactory<MyFeignClient> {
@@ -161,6 +161,7 @@ class G2X81Notice extends Script implements ChannelCheckScript{ @@ -161,6 +161,7 @@ class G2X81Notice extends Script implements ChannelCheckScript{
161 161
162 return G2X81Template.mq_template.replace("#{CopMsgId}",copMsgId) 162 return G2X81Template.mq_template.replace("#{CopMsgId}",copMsgId)
163 .replace("#{CreatTime}",creatTime) 163 .replace("#{CreatTime}",creatTime)
  164 + .replace("#{MsgType}","JCKK")
164 .replace("#{Data}",base64EncodeToString); 165 .replace("#{Data}",base64EncodeToString);
165 } 166 }
166 167
@@ -76,6 +76,7 @@ class WeightCheckImportDlv extends Script implements ChannelCheckScript { @@ -76,6 +76,7 @@ class WeightCheckImportDlv extends Script implements ChannelCheckScript {
76 76
77 //重量校验算法 77 //重量校验算法
78 WeightCheckHandleService weightCheckHandleService = context.getBean(WeightCheckHandleService.class); 78 WeightCheckHandleService weightCheckHandleService = context.getBean(WeightCheckHandleService.class);
  79 + grossWt = Double.parseDouble(String.format("%.1f", grossWt));
79 80
80 DecimalFormat df = new DecimalFormat("0.00"); 81 DecimalFormat df = new DecimalFormat("0.00");
81 boolean flag = false; 82 boolean flag = false;
  1 +package com.sy.groovy
  2 +
  3 +import com.sy.model.GatherInfo
  4 +import com.sy.model.LAND_BUSINEESTYPE_LIST_INFO
  5 +import com.sy.model.LandBusinessTypeList
  6 +import com.sy.service.WeightCheckHandleService
  7 +import com.sy.service.impl.GatherInfoHandle
  8 +import org.basis.enhance.groovy.entity.ExecuteParams
  9 +import org.slf4j.Logger
  10 +import org.slf4j.LoggerFactory
  11 +import org.springframework.context.ApplicationContext
  12 +
  13 +import java.text.DecimalFormat
  14 +
  15 +/**
  16 + * 重量验放
  17 + * 提货验放
  18 + */
  19 +class WeightCheckImportDlvLitle extends Script implements ChannelCheckScript {
  20 +
  21 + private final Logger logger = LoggerFactory.getLogger(getClass());
  22 + private final String GROWSSEXCETION = "禁止通行,重量不在可控范围";
  23 +
  24 + /**x21指令判定
  25 + * 传入gatherInfo,三大属性验证,二维码/车牌/过卡重量
  26 + * 车辆备案实体
  27 + * 从redis读取的申请表体实体
  28 + * 适用于进口转关,进口提货业务类型
  29 + */
  30 + Boolean check(ExecuteParams executeParams) {
  31 + try{
  32 + GatherInfo gatherInfo = (GatherInfo) executeParams.get("GatherInfo");
  33 + LandBusinessTypeList landBusinessTypeList = (LandBusinessTypeList) executeParams.get("ChanelFormInfo");
  34 + Double selfWt = (Double) executeParams.get("selfWt");
  35 + Double goodsWt = (Double) executeParams.get("goodsWt");
  36 + Double inAisleWT = (Double) executeParams.get("inAisleWT");
  37 + List<LAND_BUSINEESTYPE_LIST_INFO> listinfos = (List<LAND_BUSINEESTYPE_LIST_INFO>) executeParams.get("ChanelFormBillLists");
  38 +
  39 + //3.车辆备案验证
  40 + // 调用方法
  41 + ApplicationContext context = getContext();
  42 + // 获取容器中的bean
  43 + GatherInfoHandle gatherInfoHandle = context.getBean(GatherInfoHandle.class);
  44 +
  45 + logger.info("[进出场申请]-业务类型为:{}-{}",landBusinessTypeList.getCocode(),landBusinessTypeList.getBusinesstype());
  46 + if (checkImportDlv(gatherInfo.getGrosswt(), selfWt, goodsWt,inAisleWT)){
  47 + return true;
  48 + }else {
  49 + logger.error("[进口提货]-出场重量未通过校验:"+GROWSSEXCETION);
  50 + gatherInfoHandle.sendBw(gatherInfo,false,GROWSSEXCETION,landBusinessTypeList,listinfos);
  51 + return false;
  52 + }
  53 + }catch (Exception e){
  54 + e.printStackTrace();
  55 + logger.error("[DLV_WEIGHT-CHECK-ERROR]:",e);
  56 + return false;
  57 + }
  58 + }
  59 +
  60 + @Override
  61 + Object run() {
  62 + return null
  63 + }
  64 +
  65 + // 获取spring容器
  66 + ApplicationContext getContext() {
  67 + // 获取spring IOC容器
  68 + ApplicationContext context = applicationContext;
  69 + return context;
  70 + }
  71 +
  72 + boolean checkImportDlv(double grossWt, double wt, double goodsWt,double inWt){
  73 +
  74 + // 调用方法
  75 + ApplicationContext context = getContext();
  76 +
  77 + //重量校验算法
  78 + WeightCheckHandleService weightCheckHandleService = context.getBean(WeightCheckHandleService.class);
  79 +
  80 + grossWt = Double.parseDouble(String.format("%.1f", grossWt));
  81 +
  82 + DecimalFormat df = new DecimalFormat("0.00");
  83 + boolean flag = false;
  84 + double result= 0.00;
  85 + double result1= 0.00;
  86 + double result2= 0.00;
  87 + double emptyOut= 0.00;
  88 + double goodCheckResult= 0.00;
  89 + double goodCheckResultAdd= 0.00;
  90 + double goodCheckResultSub= 0.00;
  91 + double goodCheckResult1= 0.00;
  92 + //针对轻量货物 加减20KG
  93 + double addAndSub = 20.00;
  94 + if(Double.doubleToLongBits(grossWt)>Double.doubleToLongBits(0)){
  95 + //进场过磅重量+带货重量 = 出场过磅重量
  96 +// result = Double.parseDouble(df.format(Math.abs((inWt + goodsWt - grossWt)) / grossWt));
  97 + result = Double.parseDouble(df.format(Math.abs((grossWt-wt-goodsWt)) / goodsWt));
  98 +
  99 + //带货提货,不提货判定,非空车离场
  100 + result2 = Double.parseDouble(df.format(Math.abs((inWt - grossWt)) / grossWt));
  101 +
  102 + //个别原因不提货了,空车离场
  103 + emptyOut = Double.parseDouble(df.format(Math.abs((wt - grossWt)) / grossWt));
  104 +
  105 + //车辆备案重量+货物重量 = 出场过磅重量,测试用,生产关闭
  106 + result1 = Double.parseDouble(df.format(Math.abs((wt + goodsWt - grossWt)) / grossWt));
  107 +
  108 + //带货提货,货重误差
  109 + goodCheckResult = Double.parseDouble(df.format(Math.abs((grossWt-inWt-goodsWt)) / goodsWt));
  110 + //带货提货,货重误差 加20
  111 + goodCheckResultAdd = Double.parseDouble(df.format(Math.abs((grossWt-inWt-goodsWt+addAndSub)) / goodsWt));
  112 + //带货提货,货重误差 减20
  113 + goodCheckResultSub = Double.parseDouble(df.format(Math.abs((grossWt-inWt-goodsWt-addAndSub)) / goodsWt));
  114 +
  115 + goodCheckResult1 = Double.parseDouble(df.format(Math.abs((grossWt-inWt-goodsWt))));
  116 +
  117 +
  118 +
  119 + double range = weightCheckHandleService.valueDob();
  120 + logger.info("[WEIGHT-CHECK]-实际离场拉货重量:{},申请离场拉货重量:{},货重差值:{},货重误差:{}",grossWt-inWt,goodsWt,grossWt-inWt-goodsWt,goodCheckResult);
  121 + logger.info("[WEIGHT-CHECK]-进出场比对差值:{},提货离场差值:{},进出场比对重量差:{}",result,result1,Math.abs(inWt - grossWt));
  122 +
  123 + if (goodCheckResult<=range || goodCheckResultAdd<=range || goodCheckResultSub<=range || goodCheckResult1<=addAndSub) {
  124 +
  125 + flag = true;
  126 + }
  127 +
  128 + }
  129 + return flag;
  130 + }
  131 +
  132 +}
  1 +package com.sy.groovy
  2 +
  3 +import com.alibaba.fastjson.JSON
  4 +import com.alibaba.fastjson.JSONArray
  5 +import com.alibaba.fastjson.JSONObject
  6 +import com.sy.model.G2X81Template
  7 +import com.sy.model.GatherInfo
  8 +import com.sy.model.LandBusinessTypeList
  9 +import com.sy.model.LandRoadVe
  10 +import com.sy.response.ResultJson
  11 +import com.sy.service.CommandLogService
  12 +import com.sy.service.EnginCheckService
  13 +import com.sy.service.RedisService
  14 +import com.sy.service.feigin.G2X81FeignService
  15 +import com.sy.service.feigin.StationManageFeignService
  16 +import com.sy.socket.CommandClient
  17 +import org.apache.commons.lang.StringUtils
  18 +import org.basis.enhance.groovy.entity.ExecuteParams
  19 +import org.slf4j.Logger
  20 +import org.slf4j.LoggerFactory
  21 +import org.springframework.context.ApplicationContext
  22 +
  23 +import java.nio.charset.Charset
  24 +import java.text.SimpleDateFormat
  25 +
  26 +/**
  27 + * 金二特殊区域验放
  28 + * 必须返回false 为异步验放 由X82判定抬杆 ,验放排序放最后
  29 + * todo:需要改造成验放型.返回true false,某些业务类型需要强制走金二验放,海关智能卡口配置端也是根据通道进行配置的
  30 + */
  31 +class ZBQX81Notice extends Script implements ChannelCheckScript{
  32 + private final Logger log = LoggerFactory.getLogger(getClass());
  33 + @Override
  34 + Object run() {
  35 + return null
  36 + }
  37 +
  38 +
  39 + /**
  40 + * 此接口不做抬杆判定,只做报文通知,返回只有false
  41 + */
  42 + Boolean check(ExecuteParams executeParams) {
  43 + try{
  44 + /**
  45 + * X21通道信息与流转信息比对
  46 + * 1. 从缓存获取车辆进出场申请信息,有流转信息再进行通道对碰.
  47 + * 无流转信息则说明缓存失效或者二维码不对.
  48 + */
  49 + GatherInfo info = (GatherInfo) executeParams.get("GatherInfo");
  50 + LandRoadVe ve = (LandRoadVe) executeParams.get("LandRoadVe");
  51 +
  52 + ApplicationContext context = getContext();
  53 + G2X81FeignService g2X81FeignService = context.getBean(G2X81FeignService.class);
  54 +
  55 + EnginCheckService enginCheckService = context.getBean(EnginCheckService.class);
  56 +
  57 + /**
  58 + * 写入本地验放通过信息
  59 + */
  60 + enginCheckService.commandlog(info,true,"双验放:本地验放通过:等待金二验放指令",executeParams);
  61 +
  62 +
  63 +
  64 + if (info!=null){
  65 + //缓存X21 的 seqn 需要作为异步X82回执验放时用到的信息
  66 + cacheWithSeqno(info);
  67 + log.info("[G2-X81-CACHE]-车辆[{}]特殊区域流转已缓存[SEQNO]:{}",info.getVename(),info.getSeqno());
  68 + //将X21报文转换成X81格式
  69 + String xmlStr = x22TransToX81(info,ve);
  70 + //调用本地X81申报接口
  71 + ResultJson g2ResultJson = g2X81FeignService.send(xmlStr);
  72 + log.info("[G2-X81-API-RSP]-金二通知接口返回,code:{},message:{},err:{}",g2ResultJson.getCode(),g2ResultJson.getMsg(),g2ResultJson.getError());
  73 + if ("200".equals(g2ResultJson.getCode())){
  74 + record(info,true,"已转金二验放-[SEQN]:"+info.getSeqno(),null);
  75 + log.info("[G2-ROUTER-SUCCESS]-已转金二验放路由成功-规则验放成功-需要忽略下方报错,SEQNO:{}",info.getSeqno());
  76 + }else{
  77 + log.error("[G2-X81-API-ERR]-金二路由接口访问出错")
  78 + }
  79 + }else {
  80 + record(info,true,"金二验放失败,未有相关通道流转申请信息",null);
  81 + CommandClient.Client(info,"金二验放失败,未有相关通道流转申请信息");
  82 + }
  83 +
  84 + }catch (Exception e){
  85 + e.printStackTrace();
  86 + log.error("[G2-ROUTER-ERR]:",e);
  87 + }
  88 + return false;
  89 + }
  90 +
  91 + // 获取spring容器
  92 + ApplicationContext getContext() {
  93 + // 获取spring IOC容器
  94 + ApplicationContext context = applicationContext;
  95 + return context;
  96 + }
  97 +
  98 +
  99 +
  100 + void record(GatherInfo info, boolean result, String reason, LandBusinessTypeList landBusinessTypeList){
  101 + ApplicationContext context = getContext();
  102 + CommandLogService commandLogService = context.getBean(CommandLogService.class);
  103 + commandLogService.commandlog(info,result,reason,landBusinessTypeList,null,0.0,0.0,0.0,0.0);
  104 + }
  105 +
  106 +
  107 +
  108 + String x22TransToX81(GatherInfo gatherInfo,LandRoadVe ve){
  109 + log.info("[SEQN]-处理X21报文:{}",gatherInfo.getSeqno());
  110 + //当前时间作为X81申报时间
  111 + final SimpleDateFormat sdf = new SimpleDateFormat(
  112 + "yyyy-MM-dd HH:mm:ss");
  113 + final String startTime = sdf.format(new Date());
  114 +
  115 + //金二场站ID与通道ID替换
  116 + ApplicationContext context = getContext();
  117 + StationManageFeignService stationManageFeignService = context.getBean(StationManageFeignService.class);
  118 + ResultJson resultJson = stationManageFeignService.getChanels(gatherInfo.getChnlno(),1,1);
  119 +
  120 + if ("200".equals(resultJson.getCode())){
  121 + JSONObject jsonObject = resultJson.getData();
  122 + int total = jsonObject.getInteger("total");
  123 + if (total>0){
  124 + JSONArray jsonArray = jsonObject.getJSONArray("list");
  125 + JSONObject chanel = jsonArray.getJSONObject(0);
  126 + String channelG2 = chanel.getString("channelG2");
  127 + log.info("[G2-CHANNEL]-{}",channelG2);
  128 + JSONObject yard = chanel.getJSONObject("yard");
  129 + String stationG2 = yard.getString("stationIdG2");
  130 + log.info("[G2-YARD]-{}",stationG2);
  131 + log.info("[VE-RFID-NO]:车辆电子车牌号:{}",ve.getVeCustomsNo());
  132 +
  133 + String x81XML= G2X81Template.template.replace("#{ie_flag}",gatherInfo.getIetype())
  134 + .replace("#{area_id}",stationG2)
  135 + .replace("#{chnl_no}",channelG2)
  136 + .replace("#{session_id}",gatherInfo.getSeqno())
  137 + .replace("#{ve_license_no}",gatherInfo.getVename())
  138 + .replace("#{gross_wt}",gatherInfo.getGrosswt().toString())
  139 + .replace("#{rfid_id}",ve.getVeCustomsNo())
  140 + .replace("#{ve_wt}",ve.getSelfWt())
  141 + .replace("#{operate_time}",startTime);
  142 + log.info("[X21-TO-X81]-{}",x81XML);
  143 + String mqXMLStr = mqXMLMake(x81XML,gatherInfo.getSeqno(),startTime);
  144 + log.info("[X21-TO-X81]-加密后的报文为:{}",mqXMLStr)
  145 + return mqXMLStr;
  146 +
  147 + }else {
  148 + throw new Exception("未获取到通道金二配置信息")
  149 + }
  150 +
  151 + }else {
  152 + log.error("场站管理服务接口访问失败")
  153 + }
  154 +
  155 + return "";
  156 + }
  157 +
  158 + String mqXMLMake(String xmlStr,String copMsgId,String creatTime){
  159 + String base64EncodeToString = Base64.getEncoder().encodeToString(xmlStr.getBytes(Charset.forName("utf-8")));
  160 + log.info("[SEND-BASE64-ENCODE]-{}",base64EncodeToString)
  161 +
  162 + return G2X81Template.mq_template.replace("#{CopMsgId}",copMsgId)
  163 + .replace("#{CreatTime}",creatTime)
  164 + .replace("#{MsgType}","FBYF")
  165 + .replace("#{Data}",base64EncodeToString);
  166 + }
  167 +
  168 + void cacheWithSeqno(GatherInfo info){
  169 + ApplicationContext context = getContext();
  170 + RedisService redisService = context.getBean(RedisService.class);
  171 + if (info!=null && StringUtils.isNotEmpty(info.getSeqno())) {
  172 + redisService.set(info.getSeqno(), JSON.toJSONString(info),60*60*24*3);
  173 + }
  174 + }
  175 +}
@@ -61,7 +61,7 @@ public class G2X81Template { @@ -61,7 +61,7 @@ public class G2X81Template {
61 " <TransInfo>\n" + 61 " <TransInfo>\n" +
62 " <CopMsgId>#{CopMsgId}</CopMsgId>\n" + 62 " <CopMsgId>#{CopMsgId}</CopMsgId>\n" +
63 " <SenderId>GDXPKK0000000002</SenderId>\n" + 63 " <SenderId>GDXPKK0000000002</SenderId>\n" +
64 - " <MsgType>JCKK</MsgType>\n" + 64 + " <MsgType>#{MsgType}</MsgType>\n" +
65 " <CreatTime>#{CreatTime}</CreatTime>\n" + 65 " <CreatTime>#{CreatTime}</CreatTime>\n" +
66 " <ReceiverIds>\n" + 66 " <ReceiverIds>\n" +
67 " <ReceiverId>GJCKK00000000001</ReceiverId>\n" + 67 " <ReceiverId>GJCKK00000000001</ReceiverId>\n" +
@@ -367,13 +367,13 @@ public class EnginCheckServiceImpl implements EnginCheckService { @@ -367,13 +367,13 @@ public class EnginCheckServiceImpl implements EnginCheckService {
367 ExecuteParams executeParams = makeParaByGagherInfo(gatherInfo); 367 ExecuteParams executeParams = makeParaByGagherInfo(gatherInfo);
368 Boolean check = enginCheckByLockNotice(gatherInfo,executeParams); 368 Boolean check = enginCheckByLockNotice(gatherInfo,executeParams);
369 if (check){ 369 if (check){
370 - log.info("脚本验放测试通过"); 370 + log.info("脚本验放通过");
371 //放行 371 //放行
372 pass(gatherInfo,executeParams); 372 pass(gatherInfo,executeParams);
373 373
374 formRelease(gatherInfo,executeParams); 374 formRelease(gatherInfo,executeParams);
375 }else { 375 }else {
376 - log.error("脚本验放测试失败"); 376 + log.error("验放失败");
377 } 377 }
378 } 378 }
379 379