MessageRouterX21.java
12.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
package com.sy.service.router;
import com.alibaba.fastjson.JSON;
import com.sy.bwAnalysis.GatherInfoAnalysis;
import com.sy.bwAssist.Message;
import com.sy.mapper.LandListDao;
import com.sy.mapper.LandRouterConfigDao;
import com.sy.model.*;
import com.sy.service.*;
import com.sy.service.feigin.LockFeignService;
import com.sy.service.impl.GatherInfoHandle;
import com.sy.socket.CommandClient;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.basis.enhance.groovy.entity.ExecuteParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.net.ConnectException;
import java.util.List;
/**
* X21 车辆过卡信息与金二路由处理.
* todo: 直接从业务整表进行二维码判定是不是更合理?
*
*/
@Slf4j
@Service("X21")
public class MessageRouterX21 implements MessageRouter {
/**
* 金二与本地认证兼容性开关
* Y 是金二业务必须走金二
* N 车辆扫二维码或本地和金二都可进出区验放
*/
@Autowired
private G2Bean g2Bean;
@Resource
private LandRouterConfigDao landRouterConfigDao;
@Autowired
private LandBusListService landBusListService;
@Autowired
private RedisService redisService;
@Autowired
private CommandLogService commandLogService;
@Autowired
private CustomsLockService customsLockService;
@Autowired
private LockFeignService lockFeignService;
@Autowired
private EnginCheckService enginCheckService;
@Resource
private LandListDao landListDao;
/**
* 入场标识
*/
private static String IN_TYPE="I";
/**
* 离场标识
*/
private static String OUT_TYPE="E";
@Override
public void route(Message message) {
log.info("处理X21:gatherInfo,[switch]-G2开关状态:[{}]",g2Bean.getOnoff());
GatherInfoAnalysis gatherInfoAnalysis = new GatherInfoAnalysis();
GatherInfo info = gatherInfoAnalysis.toJavaBean(message);
if (g2Bean.getOnoff()){
//金二判断,业务类型,通道,路由目的地
routerCheckG2(info);
}else {
/**
* 取消原来验放模式,改为动态规则引擎验放
*/
// X21Local(info);
enginCheck(info);
}
}
/**
* 判断X21报文是否给金二
* @param info 过卡信息
*
* @return true 给金二 false 不给金二
*/
private void routerCheckG2(GatherInfo info){
/**
* X21通道信息与流转信息比对
* 1. 从缓存获取车辆进出场申请信息,有流转信息再进行通道对碰.
* 无流转信息则说明缓存失效或者二维码不对.
*/
LandBusinessTypeList landBusinessTypeList = landBusListService.getLandBusinessTypeListByGather(info);
if (landBusinessTypeList!=null){
rightChnelCheck(landBusinessTypeList.getBusinesstype(),info);
}else {
/**
* 对应进出场申请数据
*/
log.error("[G2]-X21与流转信息核碰失败,未有流转缓存或者二维码对碰不成功");
CommandClient.Client(info,"未找到通道对应申报信息,或二维码信息不一致");
record(info,false,"[FormCheck]-未找到通道对应申报信息",null);
}
/**
* 通过X21的通道进行核对.暂时不用这个
*/
// LandRouterConfig config = new LandRouterConfig();
// config.setChanelId(info.getChnlno());
// config.setBusinessType(landBusinessTypeList.getBusinesstype());
// config.setChanelType(info.getIetype());
// config.setGatherReceiver("G2");
// config.setStatus("Y");
//
// List<LandRouterConfig> routerConfigs = landRouterConfigDao.selectByGatherInfo(config);
// return !routerConfigs.isEmpty();
}
/**
* 有金二通道配置 ,但是车辆没走金二通道进行验放,用这个方法验证
* G2_SWITCH 开关为Y的时候.进行此校验.
* G2_SWITCH 开关为N时此校验永远返回true
* 金二业务的正确性校验
* 比如进口提货业务,走金二的应该是出一通道验放金二.但是车辆从出二扫二维码出区了,也是不允许的.
* 要返回走错通道G2.
* 逻辑:查询路由表 流转业务类型 目的核放处理方是G2 反向查找得到 通道列表,车辆没走此列表中的通道 视为走错通道.
* @param businessType 业务类型
* @param info 过卡信息
* @return true 走对通道 false 走错通道
*/
private void rightChnelCheck(String businessType,GatherInfo info){
LandRouterConfig landRouterConfig = new LandRouterConfig();
landRouterConfig.setBusinessType(businessType);
landRouterConfig.setAreaId(info.getAreaid());
//查询此场站此业务类型有无金二业务配置
List<LandRouterConfig> routerConfigs = landRouterConfigDao.selectByBussType(landRouterConfig);
//有金二与业务类型绑定
if (!routerConfigs.isEmpty()){
/**
* 路由配置的卡口 是进出卡口都有 还是只有进或者出
* 根据X21过的通道类型(进卡口/出卡口)来判定,对应流转申报业务类型 的 进出卡口业务是否有金二通道配置
*/
boolean anyMatch = routerConfigs.stream().anyMatch(router-> router.getChanelType().equals(info.getIetype()));
/**
* 有对应卡口进出类型的配置
* 继续判定
* 1 通道是否走对. 走对 将X21报文给金二,由三宝转成X81
* 2 没走对 返回 走错通道.业务结束.
*/
if (anyMatch){
//是否走对通道的判定
for (LandRouterConfig routerConfig : routerConfigs) {
if (routerConfig.getChanelId().equals(info.getChnlno())){
/**
* 查找到金二与通道的验放配置
*/
log.info("[G2-ROUTER]-车辆[{}]流转为金二业务,转金二处理",info.getVename());
//缓存X21,用来接收海关的x82指令核对.收到X22指令后进行核销此缓存.走金二验放的才缓存
cacheWithSeqno(info);
log.debug("[G2-ROUTER-CACHE]-车辆[{}]流转已缓存[SEQNO]:{}",info.getVename(),info.getSeqno());
//将X21报文发给三宝,让三宝发给金二
sendToSample(info);
record(info,true,"已转金二验放-[SEQN]:"+info.getSeqno(),null);
log.info("[G2]>>为[金二业务],已将[{}]过卡信息发送与金二",info.getVename());
return;
}
}
/**
* 没适配上 为走错通道,走错通道直接给指令,不走本地验放.
* 为提高抬杆效率
*/
//todo:走错通道的回执指令处理
log.info("[rightChnelCheck]-走错通道");
CommandClient.Client(info,"G2-走错通道,未找到通道对应申报信息,或二维码信息不一致");
record(info,false,"走错通道-[SEQN]:"+info.getSeqno(),null);
}
/**
* 有对应卡口进出类型的配置.
* 说明没有金二配置
* 走本地
*/
else{
//没有金二配置,走本地
// X21Local(info);
enginCheck(info);
}
}else {
//没有金二配置,走本地
// X21Local(info);
enginCheck(info);
}
}
/**
* 如果是金二将报文发送给三宝接口
*/
private void sendToSample(GatherInfo info){
CommandClient.gatherInfoBuildAndSend(info);
}
/**
* 缓存X21信息,如果走金二,KEY 为SEQN_NO
*/
private void cacheWithSeqno(GatherInfo info){
if (info!=null && StringUtils.isNotEmpty(info.getSeqno())) {
redisService.set(info.getSeqno(), JSON.toJSONString(info),60*60*24*3);
}
}
/**
* 本地处理
*/
private void X21Local(GatherInfo info){
//先判定关锁业务
if (lockHandle(info)) {
log.info("[{}]-关锁通知,等待回调",info.getBarcode());
}else {
GatherInfoHandle gatherInfoHandle = new GatherInfoHandle();
gatherInfoHandle.handel(info);
}
}
private void enginCheck(GatherInfo gatherInfo){
ExecuteParams executeParams = enginCheckService.makeParaByGagherInfo(gatherInfo);
Boolean check = enginCheckService.enginCheckByGatherInfo(gatherInfo,executeParams);
if (check){
enginCheckService.pass(gatherInfo,executeParams);
enginCheckService.formRelease(gatherInfo,executeParams);
}else {
log.error("脚本验放测试失败或等待关锁施解封");
}
log.info("引擎验放完结");
}
/**
* 车辆过卡指令日志记录
*/
private void record(GatherInfo info,boolean result,String reason,LandBusinessTypeList landBusinessTypeList){
commandLogService.commandlog(info,result,reason,landBusinessTypeList,null,0.0,0.0,0.0,0.0);
}
//关锁施解封通知判定
private boolean lockHandle(GatherInfo info){
//需要关锁业务通知
if (customsLockService.lockNoticeCheck(info)){
/**
* 关锁号申请检查
* 根据二维码查申请是否有关锁信息,没有查到实体返回null
*/
LandList landList = landListDao.selectLockInfoByBarcode(info.getBarcode());
if (landList!=null && StringUtils.isNotEmpty(landList.getLockNum())) {
log.info("[LOCK-CHECK]-流转申请携带关锁,二维码:{}",info.getBarcode());
NoticeLock noticeLock = new NoticeLock();
noticeLock.barcode = info.getBarcode();
noticeLock.areaId = info.getAreaid();
noticeLock.chnlNo = info.getChnlno();
noticeLock.vehicleNo = info.getVename();
//1. 判定是上锁通知还是解锁通知
if (OUT_TYPE.equals(info.getIetype()) && customsLockService.lockCheck(info)) {
//写入缓存
customsLockService.cacheWrite(info);
//接口通知
noticeLock.lockNo =landList.getLockNum();
noticeLock.type = "1";
LockFeignResponse lockFeignResponse = lockFeignService.noticeLock(noticeLock);
log.info("[LOCK-API-RSP]-关锁通知接口返回,code:{},message:{},success:{}",lockFeignResponse.code,lockFeignResponse.message,lockFeignResponse.success);
record(info,false,"关锁施封通知中,等待下一步指令",null);
return true;
}else {
if (IN_TYPE.equals(info.getIetype()) && customsLockService.unLockCheck(info)) {
customsLockService.cacheWrite(info);
//接口通知
noticeLock.lockNo =landList.getLockNum();
noticeLock.type = "2";
LockFeignResponse lockFeignResponse = lockFeignService.noticeLock(noticeLock);
log.info("[LOCK-API-RSP]-关锁通知接口返回,code:{},message:{},success:{}",lockFeignResponse.code,lockFeignResponse.message,lockFeignResponse.success);
record(info,false,"关锁解封通知中,等待下一步指令",null);
return true;
}
}
}else {
log.error("[LOCK-ERROR]-流转业务未申请关锁号");
record(info,false,"业务异常:流转业务-未申请关锁号",null);
CommandClient.Client(info,"流转业务-未申请关锁号");
//这里需要返回true,是关锁业务,但是中断,不抬杆不放行,给予关锁业务异常通知
return true;
}
}
return false;
}
}