add: 新增X21报文对华东的双验放通知脚本
正在显示
4 个修改的文件
包含
255 行增加
和
1 行删除
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; |
src/test/java/com/sy/CommandInfoTest.java
0 → 100644
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 | +} |
-
请 注册 或 登录 后发表评论