作者 朱兆平

Merge branch 'ver_bh_g2_engin_dev' into ver_bh_g2_engin

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)
log.info("[X21-同步]-success")
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;
}
}
... ...
... ... @@ -231,7 +231,7 @@ class G2X21NoticeWithTrue extends Script implements ChannelCheckScript{
return HAIGUAN_MQ_TEMPLATE.replace("#{CopMsgId}",copMsgId)
.replace("#{CreatTime}",creatTime)
.replace("#{MsgType}","QNLZ")
.replace("#{MsgType}","QGDB")
.replace("#{Data}",base64EncodeToString);
}
... ...