package com.sy.service.router; import com.alibaba.fastjson.JSON; import com.sy.bwAnalysis.GatherInfoAnalysis; import com.sy.bwAssist.Message; import com.sy.mapper.LandRouterConfigDao; import com.sy.model.G2Bean; import com.sy.model.GatherInfo; import com.sy.model.LandBusinessTypeList; import com.sy.model.LandRouterConfig; import com.sy.service.CommandLogService; import com.sy.service.LandBusListService; import com.sy.service.RedisService; import com.sy.service.impl.GatherInfoHandle; import com.sy.socket.CommandClient; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; 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; @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); } } /** * 判断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); } }else { //没有金二配置,走本地 X21Local(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){ GatherInfoHandle gatherInfoHandle = new GatherInfoHandle(); gatherInfoHandle.handel(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); } }