作者 朱兆平

验放规则优化

新增非保业务验放脚本
... ... @@ -50,7 +50,7 @@ class BillDomTransportCheck extends Script implements ChannelCheckScript {
if (listinfos!=null && !listinfos.isEmpty()){
//数组过滤,只要单证,不要其他 板箱之类
List<LAND_BUSINEESTYPE_LIST_INFO> list_infos = listinfos.stream().filter({ listInfo ->
listinfos = listinfos.stream().filter({ listInfo ->
if ("B".equals(listInfo.getExt4())) {
return true;
} else {
... ... @@ -58,11 +58,11 @@ class BillDomTransportCheck extends Script implements ChannelCheckScript {
}
}).collect(Collectors.toList());
list_infos.forEach({bill->
listinfos.forEach({bill->
// 创建 Feign Client
//https://nmms.zzcargo.com:8443/api/wlpt-nmms-manage/trans/dom?originFlightno=&originFlightdate=&originFlightdateEnd=&originMasterwaybill=ML66158691&agentName=&transType=dom&pageNum=1&pageSize=10
MyFeignClient myFeignClient = createFeignClient(MyFeignClient, ServiceAdr,cookieUserName,cookieUserId);
logger.info("[TRANS-CHECK-BILL]-{}",bill.getAwba())
// 调用第三方接口
String response = myFeignClient.callThirdPartyApi(bill.getAwba(),cookieUserName,cookieUserId);
logger.info("[TRANS-API-RESPONSE]-{}",response)
... ... @@ -115,10 +115,10 @@ class BillDomTransportCheck extends Script implements ChannelCheckScript {
}else{
gatherInfoHandle.sendBw(gatherInfo,false,"缺少申请单证信息",landBusinessTypeList,listinfos);
return checkFlag = false;
}
};
if (checkFlag){
commandLog(gatherInfo,true,"转运业务单证核放成功",executeParams)
}
};
return checkFlag;
} catch (Exception e) {
... ... @@ -165,6 +165,7 @@ class BillDomTransportCheck extends Script implements ChannelCheckScript {
String callThirdPartyApi(@Param("originMasterwaybill") String originMasterwaybill,
@Param("username") String username,
@Param("userid") String userid);
}
class MyFallbackFactory implements FallbackFactory<MyFeignClient> {
... ...
... ... @@ -161,6 +161,7 @@ class G2X81Notice extends Script implements ChannelCheckScript{
return G2X81Template.mq_template.replace("#{CopMsgId}",copMsgId)
.replace("#{CreatTime}",creatTime)
.replace("#{MsgType}","JCKK")
.replace("#{Data}",base64EncodeToString);
}
... ...
... ... @@ -76,6 +76,7 @@ class WeightCheckImportDlv extends Script implements ChannelCheckScript {
//重量校验算法
WeightCheckHandleService weightCheckHandleService = context.getBean(WeightCheckHandleService.class);
grossWt = Double.parseDouble(String.format("%.1f", grossWt));
DecimalFormat df = new DecimalFormat("0.00");
boolean flag = false;
... ...
package com.sy.groovy
import com.sy.model.GatherInfo
import com.sy.model.LAND_BUSINEESTYPE_LIST_INFO
import com.sy.model.LandBusinessTypeList
import com.sy.service.WeightCheckHandleService
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 java.text.DecimalFormat
/**
* 重量验放
* 提货验放
*/
class WeightCheckImportDlvLitle extends Script implements ChannelCheckScript {
private final Logger logger = LoggerFactory.getLogger(getClass());
private final String GROWSSEXCETION = "禁止通行,重量不在可控范围";
/**x21指令判定
* 传入gatherInfo,三大属性验证,二维码/车牌/过卡重量
* 车辆备案实体
* 从redis读取的申请表体实体
* 适用于进口转关,进口提货业务类型
*/
Boolean check(ExecuteParams executeParams) {
try{
GatherInfo gatherInfo = (GatherInfo) executeParams.get("GatherInfo");
LandBusinessTypeList landBusinessTypeList = (LandBusinessTypeList) executeParams.get("ChanelFormInfo");
Double selfWt = (Double) executeParams.get("selfWt");
Double goodsWt = (Double) executeParams.get("goodsWt");
Double inAisleWT = (Double) executeParams.get("inAisleWT");
List<LAND_BUSINEESTYPE_LIST_INFO> listinfos = (List<LAND_BUSINEESTYPE_LIST_INFO>) executeParams.get("ChanelFormBillLists");
//3.车辆备案验证
// 调用方法
ApplicationContext context = getContext();
// 获取容器中的bean
GatherInfoHandle gatherInfoHandle = context.getBean(GatherInfoHandle.class);
logger.info("[进出场申请]-业务类型为:{}-{}",landBusinessTypeList.getCocode(),landBusinessTypeList.getBusinesstype());
if (checkImportDlv(gatherInfo.getGrosswt(), selfWt, goodsWt,inAisleWT)){
return true;
}else {
logger.error("[进口提货]-出场重量未通过校验:"+GROWSSEXCETION);
gatherInfoHandle.sendBw(gatherInfo,false,GROWSSEXCETION,landBusinessTypeList,listinfos);
return false;
}
}catch (Exception e){
e.printStackTrace();
logger.error("[DLV_WEIGHT-CHECK-ERROR]:",e);
return false;
}
}
@Override
Object run() {
return null
}
// 获取spring容器
ApplicationContext getContext() {
// 获取spring IOC容器
ApplicationContext context = applicationContext;
return context;
}
boolean checkImportDlv(double grossWt, double wt, double goodsWt,double inWt){
// 调用方法
ApplicationContext context = getContext();
//重量校验算法
WeightCheckHandleService weightCheckHandleService = context.getBean(WeightCheckHandleService.class);
grossWt = Double.parseDouble(String.format("%.1f", grossWt));
DecimalFormat df = new DecimalFormat("0.00");
boolean flag = false;
double result= 0.00;
double result1= 0.00;
double result2= 0.00;
double emptyOut= 0.00;
double goodCheckResult= 0.00;
double goodCheckResultAdd= 0.00;
double goodCheckResultSub= 0.00;
double goodCheckResult1= 0.00;
//针对轻量货物 加减20KG
double addAndSub = 20.00;
if(Double.doubleToLongBits(grossWt)>Double.doubleToLongBits(0)){
//进场过磅重量+带货重量 = 出场过磅重量
// result = Double.parseDouble(df.format(Math.abs((inWt + goodsWt - grossWt)) / grossWt));
result = Double.parseDouble(df.format(Math.abs((grossWt-wt-goodsWt)) / goodsWt));
//带货提货,不提货判定,非空车离场
result2 = Double.parseDouble(df.format(Math.abs((inWt - grossWt)) / grossWt));
//个别原因不提货了,空车离场
emptyOut = Double.parseDouble(df.format(Math.abs((wt - grossWt)) / grossWt));
//车辆备案重量+货物重量 = 出场过磅重量,测试用,生产关闭
result1 = Double.parseDouble(df.format(Math.abs((wt + goodsWt - grossWt)) / grossWt));
//带货提货,货重误差
goodCheckResult = Double.parseDouble(df.format(Math.abs((grossWt-inWt-goodsWt)) / goodsWt));
//带货提货,货重误差 加20
goodCheckResultAdd = Double.parseDouble(df.format(Math.abs((grossWt-inWt-goodsWt+addAndSub)) / goodsWt));
//带货提货,货重误差 减20
goodCheckResultSub = Double.parseDouble(df.format(Math.abs((grossWt-inWt-goodsWt-addAndSub)) / goodsWt));
goodCheckResult1 = Double.parseDouble(df.format(Math.abs((grossWt-inWt-goodsWt))));
double range = weightCheckHandleService.valueDob();
logger.info("[WEIGHT-CHECK]-实际离场拉货重量:{},申请离场拉货重量:{},货重差值:{},货重误差:{}",grossWt-inWt,goodsWt,grossWt-inWt-goodsWt,goodCheckResult);
logger.info("[WEIGHT-CHECK]-进出场比对差值:{},提货离场差值:{},进出场比对重量差:{}",result,result1,Math.abs(inWt - grossWt));
if (goodCheckResult<=range || goodCheckResultAdd<=range || goodCheckResultSub<=range || goodCheckResult1<=addAndSub) {
flag = true;
}
}
return flag;
}
}
... ...
package com.sy.groovy
import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONArray
import com.alibaba.fastjson.JSONObject
import com.sy.model.G2X81Template
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 com.sy.service.RedisService
import com.sy.service.feigin.G2X81FeignService
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.nio.charset.Charset
import java.text.SimpleDateFormat
/**
* 金二特殊区域验放
* 必须返回false 为异步验放 由X82判定抬杆 ,验放排序放最后
* todo:需要改造成验放型.返回true false,某些业务类型需要强制走金二验放,海关智能卡口配置端也是根据通道进行配置的
*/
class ZBQX81Notice extends Script implements ChannelCheckScript{
private final Logger log = LoggerFactory.getLogger(getClass());
@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();
G2X81FeignService g2X81FeignService = context.getBean(G2X81FeignService.class);
EnginCheckService enginCheckService = context.getBean(EnginCheckService.class);
/**
* 写入本地验放通过信息
*/
enginCheckService.commandlog(info,true,"双验放:本地验放通过:等待金二验放指令",executeParams);
if (info!=null){
//缓存X21 的 seqn 需要作为异步X82回执验放时用到的信息
cacheWithSeqno(info);
log.info("[G2-X81-CACHE]-车辆[{}]特殊区域流转已缓存[SEQNO]:{}",info.getVename(),info.getSeqno());
//将X21报文转换成X81格式
String xmlStr = x22TransToX81(info,ve);
//调用本地X81申报接口
ResultJson g2ResultJson = g2X81FeignService.send(xmlStr);
log.info("[G2-X81-API-RSP]-金二通知接口返回,code:{},message:{},err:{}",g2ResultJson.getCode(),g2ResultJson.getMsg(),g2ResultJson.getError());
if ("200".equals(g2ResultJson.getCode())){
record(info,true,"已转金二验放-[SEQN]:"+info.getSeqno(),null);
log.info("[G2-ROUTER-SUCCESS]-已转金二验放路由成功-规则验放成功-需要忽略下方报错,SEQNO:{}",info.getSeqno());
}else{
log.error("[G2-X81-API-ERR]-金二路由接口访问出错")
}
}else {
record(info,true,"金二验放失败,未有相关通道流转申请信息",null);
CommandClient.Client(info,"金二验放失败,未有相关通道流转申请信息");
}
}catch (Exception e){
e.printStackTrace();
log.error("[G2-ROUTER-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);
}
String x22TransToX81(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);
ResultJson resultJson = stationManageFeignService.getChanels(gatherInfo.getChnlno(),1,1);
if ("200".equals(resultJson.getCode())){
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);
log.info("[VE-RFID-NO]:车辆电子车牌号:{}",ve.getVeCustomsNo());
String x81XML= G2X81Template.template.replace("#{ie_flag}",gatherInfo.getIetype())
.replace("#{area_id}",stationG2)
.replace("#{chnl_no}",channelG2)
.replace("#{session_id}",gatherInfo.getSeqno())
.replace("#{ve_license_no}",gatherInfo.getVename())
.replace("#{gross_wt}",gatherInfo.getGrosswt().toString())
.replace("#{rfid_id}",ve.getVeCustomsNo())
.replace("#{ve_wt}",ve.getSelfWt())
.replace("#{operate_time}",startTime);
log.info("[X21-TO-X81]-{}",x81XML);
String mqXMLStr = mqXMLMake(x81XML,gatherInfo.getSeqno(),startTime);
log.info("[X21-TO-X81]-加密后的报文为:{}",mqXMLStr)
return mqXMLStr;
}else {
throw new Exception("未获取到通道金二配置信息")
}
}else {
log.error("场站管理服务接口访问失败")
}
return "";
}
String mqXMLMake(String xmlStr,String copMsgId,String creatTime){
String base64EncodeToString = Base64.getEncoder().encodeToString(xmlStr.getBytes(Charset.forName("utf-8")));
log.info("[SEND-BASE64-ENCODE]-{}",base64EncodeToString)
return G2X81Template.mq_template.replace("#{CopMsgId}",copMsgId)
.replace("#{CreatTime}",creatTime)
.replace("#{MsgType}","FBYF")
.replace("#{Data}",base64EncodeToString);
}
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);
}
}
}
... ...
... ... @@ -61,7 +61,7 @@ public class G2X81Template {
" <TransInfo>\n" +
" <CopMsgId>#{CopMsgId}</CopMsgId>\n" +
" <SenderId>GDXPKK0000000002</SenderId>\n" +
" <MsgType>JCKK</MsgType>\n" +
" <MsgType>#{MsgType}</MsgType>\n" +
" <CreatTime>#{CreatTime}</CreatTime>\n" +
" <ReceiverIds>\n" +
" <ReceiverId>GJCKK00000000001</ReceiverId>\n" +
... ...
... ... @@ -367,13 +367,13 @@ public class EnginCheckServiceImpl implements EnginCheckService {
ExecuteParams executeParams = makeParaByGagherInfo(gatherInfo);
Boolean check = enginCheckByLockNotice(gatherInfo,executeParams);
if (check){
log.info("脚本验放测试通过");
log.info("脚本验放通过");
//放行
pass(gatherInfo,executeParams);
formRelease(gatherInfo,executeParams);
}else {
log.error("脚本验放测试失败");
log.error("验放失败");
}
}
... ...