作者 朱兆平

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.GatherInfo
  7 +import com.sy.model.LandBusinessTypeList
  8 +import com.sy.model.LandRoadVe
  9 +import com.sy.response.ResultJson
  10 +import com.sy.service.CommandLogService
  11 +import com.sy.service.EnginCheckService
  12 +import java.net.Socket;
  13 +import com.sy.service.feigin.StationManageFeignService
  14 +import com.sy.socket.CommandClient
  15 +import org.apache.commons.lang.StringUtils
  16 +import org.basis.enhance.groovy.entity.ExecuteParams
  17 +import org.slf4j.Logger
  18 +import org.slf4j.LoggerFactory
  19 +import org.springframework.context.ApplicationContext
  20 +
  21 +import java.text.SimpleDateFormat
  22 +
  23 +/**
  24 + * 同步采集信息给三宝一份
  25 + * 特殊区域本地调拨分拨验放
  26 + * 必须返回false 为异步验放,
  27 + * 将采集报文回传给三宝指定接口,后续由三宝进行海关端那边的工控机展示以及接收指令抬杆.
  28 + * todo:需要改造成验放型.返回true false,某些业务类型需要强制走金二验放,海关智能卡口配置端也是根据通道进行配置的
  29 + */
  30 +class G2X21NoticeToSamples extends Script implements ChannelCheckScript{
  31 + private final Logger log = LoggerFactory.getLogger(getClass());
  32 +
  33 + private static final String X21Template = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
  34 + "<GATHER_INFO AREA_ID=\"#{area_id}\" CHNL_NO=\"#{chnl_no}\" I_E_TYPE=\"#{ie_flag}\" SEQ_NO=\"#{session_id}\">\n" +
  35 + " <IC>\n" +
  36 + " <DR_IC_NO/>\n" +
  37 + " <IC_DR_CUSTOMS_NO/>\n" +
  38 + " <IC_CO_CUSTOMS_NO/>\n" +
  39 + " <IC_BILL_NO/>\n" +
  40 + " <IC_GROSS_WT/>\n" +
  41 + " <IC_VE_CUSTOMS_NO/>\n" +
  42 + " <IC_VE_NAME/>\n" +
  43 + " <IC_CONTA_ID/>\n" +
  44 + " <IC_ESEAL_ID/>\n" +
  45 + " <IC_EX_DATA/>\n" +
  46 + " </IC>\n" +
  47 + " <WEIGHT>\n" +
  48 + " <GROSS_WT>#{gross_wt}</GROSS_WT>\n" +
  49 + " </WEIGHT>\n" +
  50 + " <CAR>\n" +
  51 + " <VE_NAME>#{ve_license_no}</VE_NAME>\n" +
  52 + " <CAR_EC_NO>#{rfid_id}</CAR_EC_NO>\n" +
  53 + " <CAR_EC_NO2/>\n" +
  54 + " <VE_CUSTOMS_NO/>\n" +
  55 + " <VE_WT/>\n" +
  56 + " </CAR>\n" +
  57 + " <CONTA>\n" +
  58 + " <CONTA_NUM/>\n" +
  59 + " <CONTA_RECO>1</CONTA_RECO>\n" +
  60 + " <CONTA_MODEL_F/>\n" +
  61 + " <CONTA_MODEL_B/>\n" +
  62 + " <CONTA_ID_F/>\n" +
  63 + " <CONTA_ID_B/>\n" +
  64 + " </CONTA>\n" +
  65 + " <SEAL>\n" +
  66 + " <ESEAL_ID/>\n" +
  67 + " </SEAL>\n" +
  68 + " <BAR_CODE>#{bar_code}</BAR_CODE>\n" +
  69 + " </GATHER_INFO>";
  70 +
  71 +
  72 + @Override
  73 + Object run() {
  74 + return null
  75 + }
  76 +
  77 +
  78 + /**
  79 + * 此接口不做抬杆判定,只做报文通知,返回只有false
  80 + */
  81 + Boolean check(ExecuteParams executeParams) {
  82 + try{
  83 + /**
  84 + * X21通道信息与流转信息比对
  85 + * 1. 从缓存获取车辆进出场申请信息,有流转信息再进行通道对碰.
  86 + * 无流转信息则说明缓存失效或者二维码不对.
  87 + */
  88 + GatherInfo info = (GatherInfo) executeParams.get("GatherInfo");
  89 + LandRoadVe ve = (LandRoadVe) executeParams.get("LandRoadVe");
  90 +
  91 + ApplicationContext context = getContext();
  92 + EnginCheckService enginCheckService = context.getBean(EnginCheckService.class);
  93 +
  94 + /**
  95 + * 写入本地验放通过信息
  96 + */
  97 + enginCheckService.commandlog(info,true,"同步采集信息通知",executeParams);
  98 +
  99 + if (info!=null){
  100 + //将X21报文转换成X81格式
  101 + String xmlStr = x21TransToX81(info,ve);
  102 +
  103 + }else {
  104 + record(info,false,"特殊区域验放失败,未有相关通道流转申请信息",null);
  105 + CommandClient.Client(info,"特殊区域验放失败,未有相关通道流转申请信息");
  106 + }
  107 +
  108 + }catch (Exception e){
  109 + e.printStackTrace();
  110 + log.error("[G2-ROUTER-ERR]:",e);
  111 + }
  112 + return true;
  113 + }
  114 +
  115 + // 获取spring容器
  116 + ApplicationContext getContext() {
  117 + // 获取spring IOC容器
  118 + ApplicationContext context = applicationContext;
  119 + return context;
  120 + }
  121 +
  122 +
  123 +
  124 + void record(GatherInfo info, boolean result, String reason, LandBusinessTypeList landBusinessTypeList){
  125 + ApplicationContext context = getContext();
  126 + CommandLogService commandLogService = context.getBean(CommandLogService.class);
  127 + commandLogService.commandlog(info,result,reason,landBusinessTypeList,null,0.0,0.0,0.0,0.0);
  128 + }
  129 +
  130 +
  131 +
  132 + String x21TransToX81(GatherInfo gatherInfo,LandRoadVe ve){
  133 + log.info("[SEQN]-处理X21报文:{}",gatherInfo.getSeqno());
  134 + //当前时间作为X81申报时间
  135 + final SimpleDateFormat sdf = new SimpleDateFormat(
  136 + "yyyy-MM-dd HH:mm:ss");
  137 + final String startTime = sdf.format(new Date());
  138 +
  139 + //金二场站ID与通道ID替换
  140 + ApplicationContext context = getContext();
  141 + StationManageFeignService stationManageFeignService = context.getBean(StationManageFeignService.class);
  142 + log.info("[LOCAL-CHANNEL-NO]-{}",gatherInfo.getChnlno());
  143 + ResultJson resultJson = stationManageFeignService.getChanels(gatherInfo.getChnlno(),1,1);
  144 + log.info("[SERVICE-API-RES]-{}",JSON.toJSONString(resultJson))
  145 +
  146 + if ("200".equals(resultJson.getCode())){
  147 + JSONObject jsonObject = (JSONObject) resultJson.getData();
  148 + int total = jsonObject.getInteger("total");
  149 + if (total>0){
  150 + JSONArray jsonArray = jsonObject.getJSONArray("list");
  151 + JSONObject chanel = jsonArray.getJSONObject(0);
  152 + String channelG2 = chanel.getString("channelG2");
  153 + log.info("[G2-CHANNEL]-{}",channelG2);
  154 + JSONObject yard = chanel.getJSONObject("yard");
  155 + String stationG2 = yard.getString("stationIdG2");
  156 + log.info("[G2-YARD]-{}",stationG2);
  157 + String rfidNo = ve.getVeCustomsNo();
  158 + if (StringUtils.isEmpty(rfidNo)){
  159 + log.error("[VE-RFID-NO-ERR]:车辆-{}电子车牌信息未备案",gatherInfo.getVename());
  160 + record(gatherInfo,false,"车辆电子车牌信息未备案",null);
  161 + }else {
  162 + //todo: 这里取的是车辆备案电子车牌字段.实际上 IC卡号应该是一个字段
  163 + log.info("[VE-RFID-NO]:车辆电子车牌号:{}",rfidNo);
  164 + }
  165 + String IE_TYPE="I";
  166 + if ("I".equals(gatherInfo.getIetype())){
  167 + IE_TYPE = "E"
  168 + }
  169 +
  170 + if ("E".equals(gatherInfo.getIetype())){
  171 + IE_TYPE = "I"
  172 + }
  173 +
  174 +
  175 +
  176 + //各脚本维护各脚本的模板吧
  177 + String x21XML= X21Template.replace("#{ie_flag}",IE_TYPE)
  178 + .replace("#{area_id}","4612329012")
  179 + .replace("#{chnl_no}",channelG2)
  180 + .replace("#{session_id}",gatherInfo.getSeqno())
  181 + .replace("#{ve_license_no}",gatherInfo.getVename())
  182 + .replace("#{gross_wt}",gatherInfo.getGrosswt().toString())
  183 + .replace("#{rfid_id}",rfidNo)
  184 + .replace("#{ve_wt}",ve.getSelfWt())
  185 + .replace("#{bar_code}",gatherInfo.getBarcode());
  186 + log.info("[X21]-{}",x21XML);
  187 +
  188 + sendWithSocket_x21(x21XML,"4612329012",channelG2,IE_TYPE)
  189 + return x21XML;
  190 +
  191 + }else {
  192 + throw new Exception("未获取到通道金二配置信息")
  193 + }
  194 +
  195 + }else {
  196 + log.error("场站管理服务接口访问失败")
  197 + }
  198 +
  199 + return "";
  200 + }
  201 +
  202 + void sendWithSocket_x21(String xmlBody,String areaID,String chnlNo,String IEtype){
  203 + Socket socket =null;
  204 + OutputStream op = null;
  205 + try {
  206 + //ip+端口
  207 + socket = new Socket("10.50.28.38", 9072);
  208 + log.info("socket通讯创建连接成功");
  209 + op = socket.getOutputStream();
  210 + //xml字节流
  211 + byte[]xBody =xmlBody.getBytes("GB2312");
  212 + //包头
  213 + byte[] head = new byte[4];
  214 + head[0]=(byte)0xE2;
  215 + head[1]=(byte)0x5C;
  216 + head[2]=(byte)0x4B;
  217 + head[3]=(byte)0x89;
  218 + //消息类型,0x21为gatherInfo 0x22为commandInfo
  219 + byte[] mType = new byte[1];
  220 + mType[0] = (byte)0x21;
  221 + //场站号
  222 + byte[]station =areaID.getBytes("ASCII");
  223 + //通道号
  224 + byte[]aisle =chnlNo.getBytes("ASCII");
  225 + //进出标识
  226 + byte[]eType =IEtype.getBytes("ASCII");
  227 + //标识符
  228 + byte[] bwFlag = new byte[4];
  229 + bwFlag[0]=(byte)0x00;
  230 + bwFlag[1]=(byte)0x00;
  231 + bwFlag[2]=(byte)0x00;
  232 + bwFlag[3]=(byte)0x00;
  233 + //xml字节流长度
  234 + byte[]xmlLength = intToByte4(xBody.length);
  235 + //包尾
  236 + byte[]end = new byte[2];
  237 + end[0]=(byte)0xFF;
  238 + end[1]=(byte)0xFF;
  239 + System.out.println();
  240 + //总长 4为总长的length
  241 + byte [] packge = intToByte4((head.length+xBody.length+mType.length+station.length+aisle.length+eType
  242 + .length+bwFlag.length+xmlLength.length+end.length+4));
  243 + byte[]allByte = byteMergerAll(head,packge,mType,station,aisle,eType,bwFlag,xmlLength,xBody,end);
  244 + op.write(allByte);
  245 + op.flush();
  246 + op.close();
  247 + log.info("发送完毕");
  248 + socket.close();
  249 + } catch (UnknownHostException e) {
  250 + e.printStackTrace();
  251 + log.info("创建连接失败"+e.getMessage());
  252 + } catch (IOException e) {
  253 + e.printStackTrace();
  254 + log.info("文件发送失败"+e.getMessage());
  255 + }
  256 + }
  257 +
  258 + //int转byte
  259 + byte[] intToByte4(int i) {
  260 + byte[] targets = new byte[4];
  261 + //低位到高位
  262 + targets[0] = (byte) (i & 0xFF);
  263 + targets[1] = (byte) (i >> 8 & 0xFF);
  264 + targets[2] = (byte) (i >> 16 & 0xFF);
  265 + targets[3] = (byte) (i >> 24 & 0xFF);
  266 + return targets;
  267 + }
  268 +
  269 + //合并byte数据
  270 + private static byte[] byteMergerAll(byte[]... values) {
  271 + int length_byte = 0;
  272 + for (int i = 0; i < values.length; i++) {
  273 + length_byte += values[i].length;
  274 + }
  275 + byte[] all_byte = new byte[length_byte];
  276 + int countLength = 0;
  277 + for (int i = 0; i < values.length; i++) {
  278 + byte[] b = values[i];
  279 + System.arraycopy(b, 0, all_byte, countLength, b.length);
  280 + countLength += b.length;
  281 + }
  282 + return all_byte;
  283 + }
  284 +
  285 +}