作者 朱兆平

add: 新增X21报文对华东的双验放通知脚本

  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 G2X21Notice 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 = x21TransToX81(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 + record(info,true,"特殊区域接口访问失败",null);
  78 + log.error("[G2-X81-API-ERR]-特殊区域接口访问出错")
  79 + }
  80 + }else {
  81 + record(info,true,"金二验放失败,未有相关通道流转申请信息",null);
  82 + CommandClient.Client(info,"金二验放失败,未有相关通道流转申请信息");
  83 + }
  84 +
  85 + }catch (Exception e){
  86 + e.printStackTrace();
  87 + log.error("[G2-ROUTER-ERR]:",e);
  88 + }
  89 + return false;
  90 + }
  91 +
  92 + // 获取spring容器
  93 + ApplicationContext getContext() {
  94 + // 获取spring IOC容器
  95 + ApplicationContext context = applicationContext;
  96 + return context;
  97 + }
  98 +
  99 +
  100 +
  101 + void record(GatherInfo info, boolean result, String reason, LandBusinessTypeList landBusinessTypeList){
  102 + ApplicationContext context = getContext();
  103 + CommandLogService commandLogService = context.getBean(CommandLogService.class);
  104 + commandLogService.commandlog(info,result,reason,landBusinessTypeList,null,0.0,0.0,0.0,0.0);
  105 + }
  106 +
  107 +
  108 +
  109 + String x21TransToX81(GatherInfo gatherInfo,LandRoadVe ve){
  110 + log.info("[SEQN]-处理X21报文:{}",gatherInfo.getSeqno());
  111 + //当前时间作为X81申报时间
  112 + final SimpleDateFormat sdf = new SimpleDateFormat(
  113 + "yyyy-MM-dd HH:mm:ss");
  114 + final String startTime = sdf.format(new Date());
  115 +
  116 + //金二场站ID与通道ID替换
  117 + ApplicationContext context = getContext();
  118 + StationManageFeignService stationManageFeignService = context.getBean(StationManageFeignService.class);
  119 + log.info("[LOCAL-CHANNEL-NO]-{}",gatherInfo.getChnlno());
  120 + ResultJson resultJson = stationManageFeignService.getChanels(gatherInfo.getChnlno(),1,1);
  121 + log.info("[SERVICE-API-RES]-{}",JSON.toJSONString(resultJson))
  122 +
  123 + if ("200".equals(resultJson.getCode())){
  124 + JSONObject jsonObject = resultJson.getData();
  125 + int total = jsonObject.getInteger("total");
  126 + if (total>0){
  127 + JSONArray jsonArray = jsonObject.getJSONArray("list");
  128 + JSONObject chanel = jsonArray.getJSONObject(0);
  129 + String channelG2 = chanel.getString("channelG2");
  130 + log.info("[G2-CHANNEL]-{}",channelG2);
  131 + JSONObject yard = chanel.getJSONObject("yard");
  132 + String stationG2 = yard.getString("stationIdG2");
  133 + log.info("[G2-YARD]-{}",stationG2);
  134 + //todo: 这里取的是车辆备案电子车牌字段.实际上 IC卡号应该是一个字段
  135 + log.info("[VE-RFID-NO]:车辆电子车牌号:{}",ve.getVeCustomsNo());
  136 +
  137 + String x21XML= G2X81Template.X21Template.replace("#{ie_flag}",gatherInfo.getIetype())
  138 + .replace("#{area_id}",stationG2)
  139 + .replace("#{chnl_no}",channelG2)
  140 + .replace("#{session_id}",gatherInfo.getSeqno())
  141 + .replace("#{ve_license_no}",gatherInfo.getVename())
  142 + .replace("#{gross_wt}",gatherInfo.getGrosswt().toString())
  143 + .replace("#{rfid_id}",ve.getVeCustomsNo())
  144 + .replace("#{ve_wt}",ve.getSelfWt())
  145 + .replace("#{bar_code}",gatherInfo.getBarcode());
  146 + log.info("[X21]-{}",x21XML);
  147 + String mqXMLStr = mqXMLMake(x21XML,gatherInfo.getSeqno(),startTime);
  148 + log.info("[X21]-加密后的报文为:{}",mqXMLStr)
  149 + return mqXMLStr;
  150 +
  151 + }else {
  152 + throw new Exception("未获取到通道金二配置信息")
  153 + }
  154 +
  155 + }else {
  156 + log.error("场站管理服务接口访问失败")
  157 + }
  158 +
  159 + return "";
  160 + }
  161 +
  162 + String mqXMLMake(String xmlStr,String copMsgId,String creatTime){
  163 + String base64EncodeToString = Base64.getEncoder().encodeToString(xmlStr.getBytes(Charset.forName("utf-8")));
  164 + log.info("[SEND-BASE64-ENCODE]-{}",base64EncodeToString)
  165 +
  166 + return G2X81Template.mq_template.replace("#{CopMsgId}",copMsgId)
  167 + .replace("#{CreatTime}",creatTime)
  168 + .replace("#{MsgType}","QNLZ")
  169 + .replace("#{Data}",base64EncodeToString);
  170 + }
  171 +
  172 + void cacheWithSeqno(GatherInfo info){
  173 + ApplicationContext context = getContext();
  174 + RedisService redisService = context.getBean(RedisService.class);
  175 + if (info!=null && StringUtils.isNotEmpty(info.getSeqno())) {
  176 + redisService.set(info.getSeqno(), JSON.toJSONString(info),60*60*24*3);
  177 + }
  178 + }
  179 +}
@@ -53,6 +53,44 @@ public class G2X81Template { @@ -53,6 +53,44 @@ public class G2X81Template {
53 "<OPERATE_TIME>2016-11-24 11:31:52</OPERATE_TIME>\n" + 53 "<OPERATE_TIME>2016-11-24 11:31:52</OPERATE_TIME>\n" +
54 "</GATHER_INFO>"; 54 "</GATHER_INFO>";
55 55
  56 + private static final String X21Template = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
  57 + "<GATHER_INFO AREA_ID=\"#{area_id}\" CHNL_NO=\"#{chnl_no}\" I_E_TYPE=\"#{ie_flag}\" SEQ_NO=\"#{session_id}\">\n" +
  58 + " <IC>\n" +
  59 + " <DR_IC_NO/>\n" +
  60 + " <IC_DR_CUSTOMS_NO/>\n" +
  61 + " <IC_CO_CUSTOMS_NO/>\n" +
  62 + " <IC_BILL_NO/>\n" +
  63 + " <IC_GROSS_WT/>\n" +
  64 + " <IC_VE_CUSTOMS_NO/>\n" +
  65 + " <IC_VE_NAME/>\n" +
  66 + " <IC_CONTA_ID/>\n" +
  67 + " <IC_ESEAL_ID/>\n" +
  68 + " <IC_EX_DATA/>\n" +
  69 + " </IC>\n" +
  70 + " <WEIGHT>\n" +
  71 + " <GROSS_WT>#{gross_wt}</GROSS_WT>\n" +
  72 + " </WEIGHT>\n" +
  73 + " <CAR>\n" +
  74 + " <VE_NAME>#{ve_license_no}</VE_NAME>\n" +
  75 + " <CAR_EC_NO>#{rfid_id}</CAR_EC_NO>\n" +
  76 + " <CAR_EC_NO2/>\n" +
  77 + " <VE_CUSTOMS_NO/>\n" +
  78 + " <VE_WT/>\n" +
  79 + " </CAR>\n" +
  80 + " <CONTA>\n" +
  81 + " <CONTA_NUM/>\n" +
  82 + " <CONTA_RECO>1</CONTA_RECO>\n" +
  83 + " <CONTA_MODEL_F/>\n" +
  84 + " <CONTA_MODEL_B/>\n" +
  85 + " <CONTA_ID_F/>\n" +
  86 + " <CONTA_ID_B/>\n" +
  87 + " </CONTA>\n" +
  88 + " <SEAL>\n" +
  89 + " <ESEAL_ID/>\n" +
  90 + " </SEAL>\n" +
  91 + " <BAR_CODE>#{bar_code}</BAR_CODE>\n" +
  92 + " </GATHER_INFO>";
  93 +
56 /** 94 /**
57 * 发送报文封装模板 95 * 发送报文封装模板
58 */ 96 */
@@ -60,7 +60,10 @@ public class X82ServiceImpl implements X82Service { @@ -60,7 +60,10 @@ public class X82ServiceImpl implements X82Service {
60 @Override 60 @Override
61 public Boolean X82ReleaseCheck(X82Feedback var) { 61 public Boolean X82ReleaseCheck(X82Feedback var) {
62 log.info("[X82-Result]金二验放结果-{}-{}",var.getCheckResult(),var.getOpHint()); 62 log.info("[X82-Result]金二验放结果-{}-{}",var.getCheckResult(),var.getOpHint());
63 - if ("Y".equals(var.getCheckResult().trim()) || "1".equals(var.getCheckResult().trim())) { 63 + if ("Y".equals(var.getCheckResult().trim())
  64 + || "1".equals(var.getCheckResult().trim())
  65 + || "200".equals(var.getCheckResult().trim())
  66 + ) {
64 return true; 67 return true;
65 } 68 }
66 return false; 69 return false;
  1 +package com.sy;
  2 +
  3 +import com.sy.model.GatherInfo;
  4 +import com.sy.socket.CommandClient;
  5 +import lombok.extern.slf4j.Slf4j;
  6 +import org.junit.Test;
  7 +import org.junit.runner.RunWith;
  8 +import org.springframework.boot.test.context.SpringBootTest;
  9 +import org.springframework.test.context.junit4.SpringRunner;
  10 +
  11 +import java.math.BigDecimal;
  12 +
  13 +@RunWith(SpringRunner.class)
  14 +@SpringBootTest
  15 +@Slf4j
  16 +public class CommandInfoTest {
  17 +
  18 + @Test
  19 + public void makeX21Test(){
  20 + GatherInfo gatherInfo = new GatherInfo();
  21 + gatherInfo.setSeqno("111");
  22 + gatherInfo.setSeqn("222");
  23 + gatherInfo.setIetype("E");
  24 + gatherInfo.setChnlno("4604333311");
  25 + gatherInfo.setAreaid("4604000000");
  26 + gatherInfo.setGrosswt(new BigDecimal("5033"));
  27 + gatherInfo.setVename("豫A61CR7");
  28 + gatherInfo.setBarcode("abc01");
  29 + gatherInfo.setCarecno("RFID61CR7");
  30 + gatherInfo.setContareco("1");
  31 +
  32 + CommandClient.gatherInfoBuildAndSend(gatherInfo);
  33 + }
  34 +}