| 
 | 
 | 
 package com.sy.groovy
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 import com.alibaba.fastjson.JSON
 | 
| 
 | 
 | 
 import com.alibaba.fastjson.JSONArray
 | 
| 
 | 
 | 
 import com.alibaba.fastjson.JSONObject
 | 
| 
 | 
 | 
 import com.sy.model.GatherInfo
 | 
| 
 | 
 | 
 import com.sy.model.LandBusinessTypeList
 | 
| 
 | 
 | 
 import com.sy.model.LandRoadVe
 | 
| 
 | 
 | 
 import com.sy.response.ResultJson
 | 
| 
 | 
 | 
 import com.sy.service.CommandLogService
 | 
| 
 | 
 | 
 import com.sy.service.EnginCheckService
 | 
| 
 | 
 | 
 import java.net.Socket;
 | 
| 
 | 
 | 
 import com.sy.service.feigin.StationManageFeignService
 | 
| 
 | 
 | 
 import com.sy.socket.CommandClient
 | 
| 
 | 
 | 
 import org.apache.commons.lang.StringUtils
 | 
| 
 | 
 | 
 import org.basis.enhance.groovy.entity.ExecuteParams
 | 
| 
 | 
 | 
 import org.slf4j.Logger
 | 
| 
 | 
 | 
 import org.slf4j.LoggerFactory
 | 
| 
 | 
 | 
 import org.springframework.context.ApplicationContext
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 import java.text.SimpleDateFormat
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 /**
 | 
| 
 | 
 | 
  * 同步采集信息给三宝一份
 | 
| 
 | 
 | 
  * 特殊区域本地调拨分拨验放
 | 
| 
 | 
 | 
  * 必须返回false 为异步验放,
 | 
| 
 | 
 | 
  * 将采集报文回传给三宝指定接口,后续由三宝进行海关端那边的工控机展示以及接收指令抬杆.
 | 
| 
 | 
 | 
  * todo:需要改造成验放型.返回true false,某些业务类型需要强制走金二验放,海关智能卡口配置端也是根据通道进行配置的
 | 
| 
 | 
 | 
  */
 | 
| 
 | 
 | 
 class G2X21NoticeToSamples extends Script implements ChannelCheckScript{
 | 
| 
 | 
 | 
     private final Logger log = LoggerFactory.getLogger(getClass());
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     private static final String X21Template = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
 | 
| 
 | 
 | 
             "<GATHER_INFO AREA_ID=\"#{area_id}\" CHNL_NO=\"#{chnl_no}\" I_E_TYPE=\"#{ie_flag}\" SEQ_NO=\"#{session_id}\">\n" +
 | 
| 
 | 
 | 
             "        <IC>\n" +
 | 
| 
 | 
 | 
             "            <DR_IC_NO/>\n" +
 | 
| 
 | 
 | 
             "            <IC_DR_CUSTOMS_NO/>\n" +
 | 
| 
 | 
 | 
             "            <IC_CO_CUSTOMS_NO/>\n" +
 | 
| 
 | 
 | 
             "            <IC_BILL_NO/>\n" +
 | 
| 
 | 
 | 
             "            <IC_GROSS_WT/>\n" +
 | 
| 
 | 
 | 
             "            <IC_VE_CUSTOMS_NO/>\n" +
 | 
| 
 | 
 | 
             "            <IC_VE_NAME/>\n" +
 | 
| 
 | 
 | 
             "            <IC_CONTA_ID/>\n" +
 | 
| 
 | 
 | 
             "            <IC_ESEAL_ID/>\n" +
 | 
| 
 | 
 | 
             "            <IC_EX_DATA/>\n" +
 | 
| 
 | 
 | 
             "        </IC>\n" +
 | 
| 
 | 
 | 
             "        <WEIGHT>\n" +
 | 
| 
 | 
 | 
             "            <GROSS_WT>#{gross_wt}</GROSS_WT>\n" +
 | 
| 
 | 
 | 
             "        </WEIGHT>\n" +
 | 
| 
 | 
 | 
             "        <CAR>\n" +
 | 
| 
 | 
 | 
             "            <VE_NAME>#{ve_license_no}</VE_NAME>\n" +
 | 
| 
 | 
 | 
             "            <CAR_EC_NO>#{rfid_id}</CAR_EC_NO>\n" +
 | 
| 
 | 
 | 
             "            <CAR_EC_NO2/>\n" +
 | 
| 
 | 
 | 
             "            <VE_CUSTOMS_NO/>\n" +
 | 
| 
 | 
 | 
             "            <VE_WT/>\n" +
 | 
| 
 | 
 | 
             "        </CAR>\n" +
 | 
| 
 | 
 | 
             "        <CONTA>\n" +
 | 
| 
 | 
 | 
             "            <CONTA_NUM/>\n" +
 | 
| 
 | 
 | 
             "            <CONTA_RECO>1</CONTA_RECO>\n" +
 | 
| 
 | 
 | 
             "            <CONTA_MODEL_F/>\n" +
 | 
| 
 | 
 | 
             "            <CONTA_MODEL_B/>\n" +
 | 
| 
 | 
 | 
             "            <CONTA_ID_F/>\n" +
 | 
| 
 | 
 | 
             "            <CONTA_ID_B/>\n" +
 | 
| 
 | 
 | 
             "        </CONTA>\n" +
 | 
| 
 | 
 | 
             "        <SEAL>\n" +
 | 
| 
 | 
 | 
             "            <ESEAL_ID/>\n" +
 | 
| 
 | 
 | 
             "        </SEAL>\n" +
 | 
| 
 | 
 | 
             "        <BAR_CODE>#{bar_code}</BAR_CODE>\n" +
 | 
| 
 | 
 | 
             "    </GATHER_INFO>";
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     @Override
 | 
| 
 | 
 | 
     Object run() {
 | 
| 
 | 
 | 
         return null
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     /**
 | 
| 
 | 
 | 
      * 此接口不做抬杆判定,只做报文通知,返回只有false
 | 
| 
 | 
 | 
      */
 | 
| 
 | 
 | 
     Boolean check(ExecuteParams executeParams) {
 | 
| 
 | 
 | 
         try{
 | 
| 
 | 
 | 
             /**
 | 
| 
 | 
 | 
              * X21通道信息与流转信息比对
 | 
| 
 | 
 | 
              * 1. 从缓存获取车辆进出场申请信息,有流转信息再进行通道对碰.
 | 
| 
 | 
 | 
              *                             无流转信息则说明缓存失效或者二维码不对.
 | 
| 
 | 
 | 
              */
 | 
| 
 | 
 | 
             GatherInfo info = (GatherInfo) executeParams.get("GatherInfo");
 | 
| 
 | 
 | 
             LandRoadVe ve = (LandRoadVe) executeParams.get("LandRoadVe");
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             ApplicationContext context = getContext();
 | 
| 
 | 
 | 
             EnginCheckService enginCheckService = context.getBean(EnginCheckService.class);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             /**
 | 
| 
 | 
 | 
              * 写入本地验放通过信息
 | 
| 
 | 
 | 
              */
 | 
| 
 | 
 | 
             enginCheckService.commandlog(info,true,"同步采集信息通知",executeParams);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             if (info!=null){
 | 
| 
 | 
 | 
                 //将X21报文转换成X81格式
 | 
| 
 | 
 | 
                 String xmlStr = x21TransToX81(info,ve);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             }else {
 | 
| 
 | 
 | 
                 record(info,false,"特殊区域验放失败,未有相关通道流转申请信息",null);
 | 
| 
 | 
 | 
                 CommandClient.Client(info,"特殊区域验放失败,未有相关通道流转申请信息");
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         }catch (Exception e){
 | 
| 
 | 
 | 
             e.printStackTrace();
 | 
| 
 | 
 | 
             log.error("[G2-ROUTER-ERR]:",e);
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
         return true;
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     // 获取spring容器
 | 
| 
 | 
 | 
     ApplicationContext getContext() {
 | 
| 
 | 
 | 
         // 获取spring IOC容器
 | 
| 
 | 
 | 
         ApplicationContext context = applicationContext;
 | 
| 
 | 
 | 
         return context;
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     void record(GatherInfo info, boolean result, String reason, LandBusinessTypeList landBusinessTypeList){
 | 
| 
 | 
 | 
         ApplicationContext context = getContext();
 | 
| 
 | 
 | 
         CommandLogService commandLogService = context.getBean(CommandLogService.class);
 | 
| 
 | 
 | 
         commandLogService.commandlog(info,result,reason,landBusinessTypeList,null,0.0,0.0,0.0,0.0);
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     String x21TransToX81(GatherInfo gatherInfo,LandRoadVe ve){
 | 
| 
 | 
 | 
         log.info("[SEQN]-处理X21报文:{}",gatherInfo.getSeqno());
 | 
| 
 | 
 | 
         //当前时间作为X81申报时间
 | 
| 
 | 
 | 
         final SimpleDateFormat sdf = new SimpleDateFormat(
 | 
| 
 | 
 | 
                 "yyyy-MM-dd HH:mm:ss");
 | 
| 
 | 
 | 
         final  String startTime = sdf.format(new Date());
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         //金二场站ID与通道ID替换
 | 
| 
 | 
 | 
         ApplicationContext context = getContext();
 | 
| 
 | 
 | 
         StationManageFeignService stationManageFeignService = context.getBean(StationManageFeignService.class);
 | 
| 
 | 
 | 
         log.info("[LOCAL-CHANNEL-NO]-{}",gatherInfo.getChnlno());
 | 
| 
 | 
 | 
         ResultJson resultJson = stationManageFeignService.getChanels(gatherInfo.getChnlno(),1,1);
 | 
| 
 | 
 | 
         log.info("[SERVICE-API-RES]-{}",JSON.toJSONString(resultJson))
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         if ("200".equals(resultJson.getCode())){
 | 
| 
 | 
 | 
             JSONObject jsonObject = (JSONObject) resultJson.getData();
 | 
| 
 | 
 | 
             int total = jsonObject.getInteger("total");
 | 
| 
 | 
 | 
             if (total>0){
 | 
| 
 | 
 | 
                 JSONArray jsonArray = jsonObject.getJSONArray("list");
 | 
| 
 | 
 | 
                 JSONObject chanel = jsonArray.getJSONObject(0);
 | 
| 
 | 
 | 
                 String channelG2 = chanel.getString("channelG2");
 | 
| 
 | 
 | 
                 log.info("[G2-CHANNEL]-{}",channelG2);
 | 
| 
 | 
 | 
                 JSONObject yard = chanel.getJSONObject("yard");
 | 
| 
 | 
 | 
                 String stationG2 = yard.getString("stationIdG2");
 | 
| 
 | 
 | 
                 log.info("[G2-YARD]-{}",stationG2);
 | 
| 
 | 
 | 
                 String rfidNo = ve.getVeCustomsNo();
 | 
| 
 | 
 | 
                 if (StringUtils.isEmpty(rfidNo)){
 | 
| 
 | 
 | 
                     log.error("[VE-RFID-NO-ERR]:车辆-{}电子车牌信息未备案",gatherInfo.getVename());
 | 
| 
 | 
 | 
                     record(gatherInfo,false,"车辆电子车牌信息未备案",null);
 | 
| 
 | 
 | 
                 }else {
 | 
| 
 | 
 | 
                     //todo: 这里取的是车辆备案电子车牌字段.实际上 IC卡号应该是一个字段
 | 
| 
 | 
 | 
                     log.info("[VE-RFID-NO]:车辆电子车牌号:{}",rfidNo);
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
                 String IE_TYPE="I";
 | 
| 
 | 
 | 
                 if ("I".equals(gatherInfo.getIetype())){
 | 
| 
 | 
 | 
                     IE_TYPE = "E"
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 if ("E".equals(gatherInfo.getIetype())){
 | 
| 
 | 
 | 
                     IE_TYPE = "I"
 | 
| 
 | 
 | 
                 }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 //各脚本维护各脚本的模板吧
 | 
| 
 | 
 | 
                 String x21XML= X21Template.replace("#{ie_flag}",IE_TYPE)
 | 
| 
 | 
 | 
                         .replace("#{area_id}","4612329012")
 | 
| 
 | 
 | 
                         .replace("#{chnl_no}",channelG2)
 | 
| 
 | 
 | 
                         .replace("#{session_id}",gatherInfo.getSeqno())
 | 
| 
 | 
 | 
                         .replace("#{ve_license_no}",gatherInfo.getVename())
 | 
| 
 | 
 | 
                         .replace("#{gross_wt}",gatherInfo.getGrosswt().toString())
 | 
| 
 | 
 | 
                         .replace("#{rfid_id}",rfidNo)
 | 
| 
 | 
 | 
                         .replace("#{ve_wt}",ve.getSelfWt())
 | 
| 
 | 
 | 
                         .replace("#{bar_code}",gatherInfo.getBarcode());
 | 
| 
 | 
 | 
                 log.info("[X21]-{}",x21XML);
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
                 sendWithSocket_x21(x21XML,"4612329012",channelG2,IE_TYPE)
 | 
| 
 | 
 | 
                 return x21XML;
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
             }else {
 | 
| 
 | 
 | 
                 throw new Exception("未获取到通道金二配置信息")
 | 
| 
 | 
 | 
             }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         }else {
 | 
| 
 | 
 | 
             log.error("场站管理服务接口访问失败")
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
         return "";
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     void sendWithSocket_x21(String xmlBody,String areaID,String chnlNo,String IEtype){
 | 
| 
 | 
 | 
         Socket socket =null;
 | 
| 
 | 
 | 
         OutputStream op = null;
 | 
| 
 | 
 | 
         try {
 | 
| 
 | 
 | 
             //ip+端口
 | 
| 
 | 
 | 
             socket = new Socket("10.50.28.38", 9072);
 | 
| 
 | 
 | 
             log.info("socket通讯创建连接成功");
 | 
| 
 | 
 | 
             op = socket.getOutputStream();
 | 
| 
 | 
 | 
             //xml字节流
 | 
| 
 | 
 | 
             byte[]xBody =xmlBody.getBytes("GB2312");
 | 
| 
 | 
 | 
             //包头
 | 
| 
 | 
 | 
             byte[] head = new byte[4];
 | 
| 
 | 
 | 
             head[0]=(byte)0xE2;
 | 
| 
 | 
 | 
             head[1]=(byte)0x5C;
 | 
| 
 | 
 | 
             head[2]=(byte)0x4B;
 | 
| 
 | 
 | 
             head[3]=(byte)0x89;
 | 
| 
 | 
 | 
             //消息类型,0x21为gatherInfo 0x22为commandInfo
 | 
| 
 | 
 | 
             byte[] mType = new byte[1];
 | 
| 
 | 
 | 
             mType[0] = (byte)0x21;
 | 
| 
 | 
 | 
             //场站号
 | 
| 
 | 
 | 
             byte[]station =areaID.getBytes("ASCII");
 | 
| 
 | 
 | 
             //通道号
 | 
| 
 | 
 | 
             byte[]aisle =chnlNo.getBytes("ASCII");
 | 
| 
 | 
 | 
             //进出标识
 | 
| 
 | 
 | 
             byte[]eType =IEtype.getBytes("ASCII");
 | 
| 
 | 
 | 
             //标识符
 | 
| 
 | 
 | 
             byte[] bwFlag = new byte[4];
 | 
| 
 | 
 | 
             bwFlag[0]=(byte)0x00;
 | 
| 
 | 
 | 
             bwFlag[1]=(byte)0x00;
 | 
| 
 | 
 | 
             bwFlag[2]=(byte)0x00;
 | 
| 
 | 
 | 
             bwFlag[3]=(byte)0x00;
 | 
| 
 | 
 | 
             //xml字节流长度
 | 
| 
 | 
 | 
             byte[]xmlLength = intToByte4(xBody.length);
 | 
| 
 | 
 | 
             //包尾
 | 
| 
 | 
 | 
             byte[]end = new byte[2];
 | 
| 
 | 
 | 
             end[0]=(byte)0xFF;
 | 
| 
 | 
 | 
             end[1]=(byte)0xFF;
 | 
| 
 | 
 | 
             System.out.println();
 | 
| 
 | 
 | 
             //总长 4为总长的length
 | 
| 
 | 
 | 
             byte [] packge = intToByte4((head.length+xBody.length+mType.length+station.length+aisle.length+eType
 | 
| 
 | 
 | 
                     .length+bwFlag.length+xmlLength.length+end.length+4));
 | 
| 
 | 
 | 
             byte[]allByte = byteMergerAll(head,packge,mType,station,aisle,eType,bwFlag,xmlLength,xBody,end);
 | 
| 
 | 
 | 
             op.write(allByte);
 | 
| 
 | 
 | 
             op.flush();
 | 
| 
 | 
 | 
             op.close();
 | 
| 
 | 
 | 
             log.info("发送完毕");
 | 
| 
 | 
 | 
             socket.close();
 | 
| 
 | 
 | 
         } catch (UnknownHostException e) {
 | 
| 
 | 
 | 
             e.printStackTrace();
 | 
| 
 | 
 | 
             log.info("创建连接失败"+e.getMessage());
 | 
| 
 | 
 | 
         } catch (IOException e) {
 | 
| 
 | 
 | 
             e.printStackTrace();
 | 
| 
 | 
 | 
             log.info("文件发送失败"+e.getMessage());
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     //int转byte
 | 
| 
 | 
 | 
     byte[] intToByte4(int i) {
 | 
| 
 | 
 | 
         byte[] targets = new byte[4];
 | 
| 
 | 
 | 
         //低位到高位
 | 
| 
 | 
 | 
         targets[0] = (byte) (i & 0xFF);
 | 
| 
 | 
 | 
         targets[1] = (byte) (i >> 8 & 0xFF);
 | 
| 
 | 
 | 
         targets[2] = (byte) (i >> 16 & 0xFF);
 | 
| 
 | 
 | 
         targets[3] = (byte) (i >> 24 & 0xFF);
 | 
| 
 | 
 | 
         return targets;
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
     //合并byte数据
 | 
| 
 | 
 | 
     private static byte[] byteMergerAll(byte[]... values) {
 | 
| 
 | 
 | 
         int length_byte = 0;
 | 
| 
 | 
 | 
         for (int i = 0; i < values.length; i++) {
 | 
| 
 | 
 | 
             length_byte += values[i].length;
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
         byte[] all_byte = new byte[length_byte];
 | 
| 
 | 
 | 
         int countLength = 0;
 | 
| 
 | 
 | 
         for (int i = 0; i < values.length; i++) {
 | 
| 
 | 
 | 
             byte[] b = values[i];
 | 
| 
 | 
 | 
             System.arraycopy(b, 0, all_byte, countLength, b.length);
 | 
| 
 | 
 | 
             countLength += b.length;
 | 
| 
 | 
 | 
         }
 | 
| 
 | 
 | 
         return all_byte;
 | 
| 
 | 
 | 
     }
 | 
| 
 | 
 | 
 
 | 
| 
 | 
 | 
 } | 
...
 | 
...
 | 
 |