作者 朱兆平

新增了一些验放规则

... ... @@ -10,6 +10,7 @@ spring.cloud.discovery.client.health-indicator.enabled=false
spring.cloud.service-registry.auto-registration.register-management=false
spring.cloud.features.enabled=false
spring.cloud.discovery.enabled=false
spring.cloud.config.enabled=false
spring.devtools.restart.enabled=true
... ...
... ... @@ -5,7 +5,7 @@
<groupId>com.sy</groupId>
<artifactId>analysis_imf</artifactId>
<version>4.5-ENGINE-SNAPSHOT</version>
<version>5.0.0-ENGIN-SNAPSHOT</version>
<packaging>jar</packaging>
<name>analysis_imf</name>
<description>北货集成金二抬杆指令判定</description>
... ...
... ... @@ -8,8 +8,11 @@ import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.context.ApplicationContext
//通道申请信息验放
class BaseFormCacheCheck extends Script {
/**
* 基本验放
* 流转申请信息验放
*/
class BaseFormCacheCheck extends Script implements ChannelCheckScript {
private final Logger logger = LoggerFactory.getLogger(getClass());
private final String CHANEL_ERR= "无对应通道流转申请,走错通道";
... ...
... ... @@ -10,8 +10,11 @@ import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.context.ApplicationContext
//基本信息验放
class BaseVeCheck extends Script {
/**
* 基本验放
* 车辆备案验放
*/
class BaseVeCheck extends Script implements ChannelCheckScript {
private final Logger logger = LoggerFactory.getLogger(getClass());
private final String NORECORD = "车辆未备案或者识别错误,车牌号:";
... ...
... ... @@ -8,8 +8,11 @@ import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.context.ApplicationContext
//基本信息验放
class BaseX21GatherInfoCheck extends Script {
/**
* 基本验放
* 过卡信息验放
*/
class BaseX21GatherInfoCheck extends Script implements ChannelCheckScript {
private final Logger logger = LoggerFactory.getLogger(getClass());
private final String X21_WEIGHT_ERR = "车辆过卡重量异常";
... ...
package com.sy.groovy
import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONArray
import com.alibaba.fastjson.JSONObject
import com.sy.model.Feign_Allocate_Search
import com.sy.model.GatherInfo
import com.sy.model.LAND_BUSINEESTYPE_LIST_INFO
import com.sy.model.LandBusinessTypeList
import com.sy.service.NmmsService
import com.sy.service.impl.GatherInfoHandle
import org.basis.enhance.groovy.entity.ExecuteParams
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.context.ApplicationContext
import javax.validation.constraints.NotNull
/**
* 单证验放
* 舱单分拨申请验放
*/
class BillAllocateCheck extends Script implements ChannelCheckScript {
private final Logger logger = LoggerFactory.getLogger(getClass());
private final String FENBO = "装载运单的分拨申请舱单未通过校验";
/**过磅重量判定
* 传入gatherInfo,三大属性验证,二维码/车牌/过卡重量
* 适用于分拨业务或者调拨业务
*/
Boolean check(ExecuteParams executeParams) {
try{
GatherInfo gatherInfo = (GatherInfo) executeParams.get("gatherInfo");
LandBusinessTypeList landBusinessTypeList = (LandBusinessTypeList) executeParams.get("ChanelFormInfo");
List<LAND_BUSINEESTYPE_LIST_INFO> listinfos = (List<LAND_BUSINEESTYPE_LIST_INFO>) executeParams.get("ChanelFormBillLists");
// 调用方法
ApplicationContext context = getContext();
// 获取容器中的bean
GatherInfoHandle gatherInfoHandle = context.getBean(GatherInfoHandle.class);
boolean allocatCheck = checkNmmsAllocate(landBusinessTypeList.getMasterList());
if(!allocatCheck){
logger.error("[分拨业务]-分拨申请舱单未通过校验:"+FENBO);
gatherInfoHandle.sendBw(gatherInfo,false,FENBO,landBusinessTypeList,listinfos);
return false;
}
return true;
}catch (Exception e){
e.printStackTrace();
logger.error("[BillAllocateCheck-ERROR]:",e);
return false;
}
}
@Override
Object run() {
return null
}
// 获取spring容器
ApplicationContext getContext() {
// 获取spring IOC容器
ApplicationContext context = applicationContext;
return context;
}
/**
* 新舱单分拨申请数据查询
* @param waybill 查询的运单号
* @return
*/
private Map nmmsAllocate(@NotNull String waybill){
logger.info("新舱单查询分拨申请数据开始");
Feign_Allocate_Search feignAllocateSearch = new Feign_Allocate_Search(waybill,0,10);
ApplicationContext context = getContext();
NmmsService nmmsService = context.getBean(NmmsService.class)
Map map = nmmsService.getAllocate(feignAllocateSearch);
logger.info(""+map);
return map;
}
/**
* 分拨申请查询
* @param waybill
* @return
*/
private boolean checkNmmsAllocate(String waybill){
if (waybill.length() < 1) {
return false;
}
waybill = waybill.replace("-", "");
//中文逗号替换
waybill = waybill.replace(",", ",");
String[] maifest = waybill.split(",");
logger.info("运单列表:" + waybill);
boolean flag = false;
for (String awb : maifest) {
Map map= nmmsAllocate(awb);
if (map.containsKey("reslut")){
String result = map.get("reslut").toString();
JSONObject jsonObject = JSON.parseObject(result);
if (jsonObject.containsKey("ds")) {
JSONArray ds = jsonObject.getJSONArray("ds");
JSONObject awbinfo = ds.getJSONObject(0);
if (awbinfo.containsKey("RECEIPTINFORMATION")){
if (awbinfo.getString("RECEIPTINFORMATION").contains("39301") || awbinfo.getString("RECEIPTINFORMATION").contains("39103")){
log.info("运单:{},分拨回执查询结果:{}",awb,awbinfo.getString("RECEIPTINFORMATION"));
}else {
log.info("运单{}分拨申请回执不正常:{}",awb,awbinfo.getString("RECEIPTINFORMATION"));
return false;
}
}
}else {
logger.info("运单:{}分拨申请回执未查询到,或未进行分拨申请",awb);
return false;
}
}else{
logger.info("运单:{}分拨申请回执未查询到,或未进行分拨申请",awb);
return false;
}
}
return true;
}
}
... ...
... ... @@ -11,8 +11,11 @@ import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.context.ApplicationContext
//过卡单证验放-放行验放
class ReleaseCheck extends Script {
/**
* 单证验放
* 放行验放
*/
class BillReleaseCheck extends Script implements ChannelCheckScript {
private final Logger logger = LoggerFactory.getLogger(getClass());
private final String FANGXING= "有运单未放行";
... ...
... ... @@ -3,11 +3,14 @@ package com.sy.groovy;
import org.basis.enhance.groovy.entity.ExecuteParams;
/**
* @author mrz
* @date 2023-05-01
* 规则脚本对应通道验放规则接口类声明
* 通道规则验放必须包含check方法,且方法结果为布尔类型,验放通过为true.否则为false
* 验放接口
*/
public abstract class ChannelCheckScript {
public abstract Boolean check(ExecuteParams executeParams);
public interface ChannelCheckScript {
/**
* 验放接口方法
* @param executeParams 过卡信息+申报信息+车辆备案+入卡信息
* @return true 通过,false 禁行
*/
Boolean check(ExecuteParams executeParams);
}
... ...
package com.sy.groovy
/**
* 关锁验放规则
*/
class CustomsLockCheck extends Script {
@Override
Object run() {
return null
}
}
package com.sy.groovy
import com.alibaba.fastjson.JSON
import com.sy.mapper.LandRouterConfigDao
import com.sy.model.*
import com.sy.service.CommandLogService
import com.sy.service.RedisService
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
/**
* 金二验放
* 金二通知验放规则
* todo:需要改造成验放型.返回true false,某些业务类型需要强制走金二验放,海关智能卡口配置端也是根据通道进行配置的
*/
class G2Notice extends Script implements ChannelCheckScript {
private final Logger log = LoggerFactory.getLogger(getClass());
@Override
Object run() {
return null
}
Boolean check(ExecuteParams executeParams) {
try{
/**
* X21通道信息与流转信息比对
* 1. 从缓存获取车辆进出场申请信息,有流转信息再进行通道对碰.
* 无流转信息则说明缓存失效或者二维码不对.
*/
GatherInfo info = (GatherInfo) executeParams.get("gatherInfo");
LandBusinessTypeList landBusinessTypeList = (LandBusinessTypeList) executeParams.get("chanelFormInfo");
if (landBusinessTypeList!=null){
rightChnelCheck(landBusinessTypeList.getBusinesstype(),info);
}else {
/**
* 对应进出场申请数据
*/
log.error("[G2]-X21与流转信息核碰失败,未有流转缓存或者二维码对碰不成功");
CommandClient.Client(info,"未找到通道对应申报信息,或二维码信息不一致");
record(info,false,"[FormCheck]-未找到通道对应申报信息",null);
}
}catch (Exception e){
e.printStackTrace();
log.error("[LockNoticeCheck-ERR]:",e);
return false;
}
}
// 获取spring容器
ApplicationContext getContext() {
// 获取spring IOC容器
ApplicationContext context = applicationContext;
return context;
}
void rightChnelCheck(String businessType,GatherInfo info){
LandRouterConfig landRouterConfig = new LandRouterConfig();
landRouterConfig.setBusinessType(businessType);
landRouterConfig.setAreaId(info.getAreaid());
ApplicationContext context = getContext();
LandRouterConfigDao landRouterConfigDao = context.getBean(LandRouterConfigDao.class);
//查询此场站此业务类型有无金二业务配置
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);
log.info("[G2Notice-CHECK]-通道[{}]没有G2配置",info.getChnlno())
}
}else {
//没有金二配置,走本地
// X21Local(info);
log.info("[G2Notice-CHECK]-通道[{}]没有G2配置",info.getChnlno())
}
}
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);
}
void sendToSample(GatherInfo info){
CommandClient.gatherInfoBuildAndSend(info);
}
void cacheWithSeqno(GatherInfo info){
ApplicationContext context = getContext();
RedisService redisService = context.getBean(RedisService.class);
if (info!=null && StringUtils.isNotEmpty(info.getSeqno())) {
redisService.set(info.getSeqno(), JSON.toJSONString(info),60*60*24*3);
}
}
}
... ...
package com.sy.groovy
import com.sy.mapper.LandListDao
import com.sy.model.GatherInfo
import com.sy.model.LandBusinessTypeList
import com.sy.model.LandList
import com.sy.model.LockFeignResponse
import com.sy.model.NoticeLock
import com.sy.service.CommandLogService
import com.sy.service.CustomsLockService
import com.sy.service.feigin.LockFeignService
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
/**
* 关锁验放
* 关锁通知验放规则
*/
class LockNoticeCheck extends Script implements ChannelCheckScript {
private final Logger log = LoggerFactory.getLogger(getClass());
@Override
Object run() {
return null
}
@Override
Boolean check(ExecuteParams executeParams) {
try{
/**
* 入场标识
*/
String IN_TYPE="I";
/**
* 离场标识
*/
String OUT_TYPE="E";
GatherInfo info = (GatherInfo) executeParams.get("gatherInfo");
// 获取容器中的bean
// 调用方法
ApplicationContext context = getContext();
CustomsLockService customsLockService = context.getBean(CustomsLockService.class);
LandListDao landListDao = context.getBean(LandListDao.class);
LockFeignService lockFeignService = context.getBean(LockFeignService.class);
//需要关锁业务通知
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 {
CommandClient.Client(info,"流转业务-未申请关锁号");
record(info,false,"业务异常:流转业务-未申请关锁号",null);
//这里需要返回true,是关锁业务,但是中断,不抬杆不放行,给予关锁业务异常通知
return true;
}
}
return false;
}catch (Exception e){
e.printStackTrace();
log.error("[LockNoticeCheck-ERR]:",e);
return false;
}
}
// 获取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);
}
}
... ...
... ... @@ -10,8 +10,11 @@ import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.context.ApplicationContext
//过卡重量验放-分拨调拨验放
class WeightCheckAllocateOrDispatch extends Script {
/**
* 重量验放
* 分拨调拨流转验放
*/
class WeightCheckAllocateOrDispatch extends Script implements ChannelCheckScript {
private final Logger logger = LoggerFactory.getLogger(getClass());
private final String GROWSSEXCETION = "禁止通行,重量不在可控范围";
... ...
... ... @@ -10,8 +10,11 @@ import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.context.ApplicationContext
//过卡重量验放-提货验放
class WeightCheckEmpty extends Script {
/**
* 重量验放
* 空车验放
*/
class WeightCheckEmpty extends Script implements ChannelCheckScript {
private final Logger logger = LoggerFactory.getLogger(getClass());
private final String GROWSSEXCETION = "禁止通行,重量不在可控范围";
... ...
... ... @@ -10,8 +10,11 @@ import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.context.ApplicationContext
//过卡重量验放-送货验放
class WeightCheckExportUnload extends Script {
/**
* 重量验放
* 卸货验放
*/
class WeightCheckExportUnload extends Script implements ChannelCheckScript {
private final Logger logger = LoggerFactory.getLogger(getClass());
private final String GROWSSEXCETION = "禁止通行,重量不在可控范围";
... ...
... ... @@ -10,8 +10,11 @@ import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.context.ApplicationContext
//过卡重量验放-提货验放
class WeightCheckImportDlv extends Script {
/**
* 重量验放
* 提货验放
*/
class WeightCheckImportDlv extends Script implements ChannelCheckScript {
private final Logger logger = LoggerFactory.getLogger(getClass());
private final String GROWSSEXCETION = "禁止通行,重量不在可控范围";
... ...
... ... @@ -9,7 +9,11 @@ import org.slf4j.LoggerFactory
import org.springframework.context.ApplicationContext
import java.util.stream.Collectors
//申请单核销判定
/**
* 流转申请-核销
* 1. 所有申请单中的场站出通道出了,可以核销
* 2. 根据申请单中的通道类型及通道信息判定没有未走完的通道类型,可以核销.比如 申请单证的通道只有进通道,车可以走进一,进二,进二入场,走完进一,即可核销.(一线进)
*/
class X21FormReleaseCheck extends Script {
private final Logger logger = LoggerFactory.getLogger(getClass());
... ...