作者 朱兆平

FHL分单报文解析并校验

FROM java:8u111
VOLUME /tmp
ARG PINPOINT_VERSION
ARG AGENT_ID
ARG APP_NAME
ENV JAVA_OPTS="-javaagent:/pinpoint-agent/pinpoint-bootstrap-${PINPOINT_VERSION}.jar -Dpinpoint.agentId=${AGENT_ID} -Dpinpoint.applicationName=${APP_NAME} -Dspring.profiles.active=${SPRING_PROFILES}"
ADD *.jar app.jar
EXPOSE 10001
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo "Asia/Shanghai" > /etc/timezone && dpkg-reconfigure -f noninteractive tzdata
COPY xsd /xsd
ENTRYPOINT ["java","-jar","/app.jar"]
#ENTRYPOINT ["java","$JAVA_OPTS","-jar","/app.jar"]
ENTRYPOINT java $JAVA_OPTS -jar /app.jar
# Ubuntu 时区
... ...
package com.tianbo.analysis.controller;
import com.tianbo.analysis.model.Originmanifestsecondary;
import com.tianbo.analysis.model.ResultJson;
import com.tianbo.analysis.service.FHLResolve;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/fhl")
@Slf4j
public class FHLController {
@Autowired
FHLResolve resolve;
@PostMapping("resolve")
public ResultJson resolve(@RequestParam String ffm){
Originmanifestsecondary fhlInfo = new Originmanifestsecondary();
fhlInfo.text = ffm;
boolean result = resolve.resolve(fhlInfo);
return result? new ResultJson("200","success"):new ResultJson("400","解析失败");
}
}
... ...
... ... @@ -17,6 +17,7 @@ public class SendPlanController {
@Resource
SENDPLANMapper sendplanMapper;
@ReSubmitCheck
@UserPermissionCheck
@PostMapping("add")
public ResultJson add(@RequestBody SENDPLAN sendplan,@CookieValue("username") String username,@CookieValue("userid") String userid){
... ...
package com.tianbo.analysis.model;
import com.tianbo.analysis.exception.FFMResolveException;
import com.tianbo.analysis.tools.WaybillTools;
import com.tianbo.util.Date.DateUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import java.util.Date;
import java.util.List;
import javax.validation.constraints.NotNull;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Data
@Slf4j
... ... @@ -78,6 +85,15 @@ public class Originmanifestsecondary {
private ORIGINMANIFESTMASTER master;
public String text;
public List<String> lineList;
private static final String KEY_WORD = "FHL,MBI,HBS,TXT,HTS,SHP,CNE,NAM,ADR,LOC,CVD,OSI,COR,OCI,DEG,DIM";
private String TEMP_KEY_WORD="";
private int CURRENT_LINE=0;
public String getAutoid() {
return autoid;
}
... ... @@ -343,4 +359,634 @@ public class Originmanifestsecondary {
this.waybillnosecondary = waybillnosecondary;
this.originmanifestmasterautoid = originmanifestmasterautoid;
}
}
\ No newline at end of file
/**
* 校验报文结尾标识
* 将报文字符窜转换成行数组
* @return
* @throws IOException
* @throws FFMResolveException
*/
public boolean textToStringList() throws IOException, FFMResolveException {
if (StringUtils.isNotBlank(text) && text.contains("FHL/")) {
lineList = new ArrayList<>();
BufferedReader reader = new BufferedReader(new StringReader(text));
log.info(this.toString());
for (String lineStr = reader.readLine();
lineStr != null;
lineStr = reader.readLine()) {
if (StringUtils.isNotEmpty(lineStr)){
lineList.add(lineStr);
}
}
return true;
}
log.error("[FHL]-{}->报文不属于分单报",text);
return false;
}
/**
* 开始解析
* * Cargo-IMP Messages may only contain the following approved characters:
* * the letters A to Z (upper case only)
* * the numerals 0 to 9
* * the special characters / -. Space < =
*/
public boolean startParse() throws FFMResolveException {
if (!lineList.isEmpty()){
int keyword_i = 0;
for (int i = 0; i < lineList.size(); i++) {
String pattern = "[^A-Z0-9/\\.\\-<=\\s]+";
// 创建 Pattern 对象
Pattern r = Pattern.compile(pattern);
// 现在创建 matcher 对象
Matcher m = r.matcher(text);
if(m.find()){
log.error("[FHL] 行[{}]中包含非允许特殊字符,报文中只允许包含-[{}]等特殊字符",i," / -. Space < =");
throw new FFMResolveException("[FHL] 报文中包含特殊字符,报文中只允许包含 / -. Space < = 等特殊字符");
}
//根据行关键字走相应的解析逻辑
String line = lineList.get(i);
log.debug("[TEXT] 开始处理行[{}]-[{}]",i,line);
String keyword = keyword(line);
CURRENT_LINE = i;
if (!"NOT_KEYWORD".equals(keyword)){
TEMP_KEY_WORD = "";
keywordParse(keyword,line,i);
}else{
log.debug("[[TEXT-LINE-{}]当前行不属于关键字解析行,根据缓存关键字解析下行信息",i);
keywordNextLineParse(line,i);
}
}
}
return false;
}
/**
* 根据关键字适配解析方法
* @param keyword 关键字
* @param line 当前行内容
* @param current 当前行数
*/
public void keywordParse(String keyword,String line,int current) throws FFMResolveException {
log.debug("[TEXT] 行[{}]包含关键字{},开始处理",current,keyword);
switch (keyword){
case "FHL":
fhlInfoParse(line);
break;
case "MBI":
mbiInfoParse(line);
break;
case "HBS":
hbsInfoParse(line);
break;
case "TXT":
textInfoParse(line);
break;
case "HTS":
htsInfoParse(line);
break;
case "SHP":
shipperHasSplitParse(line,"SHP");
break;
case "CNE":
shipperHasSplitParse(line,"CNE");
break;
case "OCI":
ociInfoParse(line);
break;
case "CVD":
cvdParse(line);
break;
default:
break;
}
}
/**
* 根据关键字适配解析方法
* @param line 当前行内容
* @param current 当前行数
*/
public void keywordNextLineParse(String line,int current) throws FFMResolveException {
log.info("行[{}]当前临时关键字-[{}]",current,TEMP_KEY_WORD);
switch (TEMP_KEY_WORD){
case "HBS-SHC":
hbsOtherInfoParse(line);
break;
case "TXT":
textInfoParse(line);
break;
case "HTS":
htsInfoParse(line);
break;
case "CNE-NAM":
case "SHP-NAM":
//SHP下的第一行地址行
shipperNamV2Parse(line);
break;
case "CNE-ADR":
case "SHP-ADR":
//SHP下的第一行地址行
shipperAdrV1Parse(line);
break;
case "CNE-LOC":
case "SHP-LOC":
//SHP下的第一行地址行
shipperLocV1Parse(line);
break;
case "CNE-CON":
case "SHP-CON":
//SHP下的第一行地址行
shipperContactV1Parse(line);
break;
case "OCI":
ociInfoParse(line);
break;
default:
break;
}
}
/**
* 关键字识别
* @param text 每行的内容
* @return 识别为关键字的返回关键字,未被识别为关键字的返回NOT_KEYWORD;
* 返回的关键字 三字码关键字 机场代码关键字 文件结尾关键字 CONT,LAST
*/
public String keyword(@NotNull String text){
//取每行前三位
if (StringUtils.isNotBlank(text) && text.length()>3){
String s_3 = text.substring(0,3);
if(KEY_WORD.contains(s_3)){
return s_3;
}
}
return "NOT_KEYWORD";
}
/**
* FHL信息解析
* @param verlLine FHL-报文版本行信息解析
*/
public boolean fhlInfoParse(String verlLine) throws FFMResolveException {
log.debug("[TEXT] 找到FHL开头节点");
//校验正则1,取前三位验证是否是机场代码
String pattern = "^FHL/\\d{1,3}";
// 创建 Pattern 对象
Pattern r = Pattern.compile(pattern);
// 现在创建 matcher 对象
Matcher m = r.matcher(verlLine);
//格式正则校验
if(m.find()){
String ver = verlLine.split("/")[1];
log.info("[VER] 报文版本{}",ver.trim());
return true;
}
throw new FFMResolveException("[FLIGHT] FHL版本信息错误");
}
/**
* 主单行信息解析
* @param mbiLine MBI-主单行信息解析
*/
public boolean mbiInfoParse(String mbiLine) throws FFMResolveException {
log.debug("[TEXT] 找到MBI主单开头节点");
//校验正则1,取前三位验证是否是机场代码
String pattern = "^MBI/(\\d{3}-\\d{8})([A-Z]{3})([A-Z]{3})/T(\\d{1,4})[A-Z0-9]([0-9\\.]{1,7})";
// 创建 Pattern 对象
Pattern r = Pattern.compile(pattern);
// 现在创建 matcher 对象
Matcher m = r.matcher(mbiLine);
//格式正则校验
if(m.find()){
waybillnomaster = m.group(1);
//主单模七校验
if(WaybillTools.model7Check(waybillnomaster)){
log.debug("[AWB] 运单-({})模七校验通过",waybillnomaster);
}else {
log.error("{}运单模七校验不通过",waybillnomaster);
throw new FFMResolveException(waybillnomaster+"运单模七校验不通过");
}
String masterOringStation = m.group(2);
String masterDestinationStation = m.group(3);
String masterTotalPiece = m.group(4);
String masterTotalWeight = m.group(5);
return true;
}
throw new FFMResolveException("[MBI] MBI主单节点信息错误");
}
/**
* 分单行信息解析,分单信息可以重复,要考虑重复解析如果报文中不存在收发货人的话,目前按单一分单信息解析
* @param fhlLine HBS-分单行信息解析,
*/
public boolean hbsInfoParse(String fhlLine) throws FFMResolveException {
log.debug("[TEXT] 找到HBS分单开头节点");
//校验正则1,取前三位验证是否是机场代码
String pattern = "^HBS/([A-Z0-9]{1,12})/([A-Z]{3})([A-Z]{3})/(\\d{1,4})/[A-Z0-9]([0-9\\.]{1,7})/(\\d{1,5})?/(.{1,15})";
// 创建 Pattern 对象
Pattern r = Pattern.compile(pattern);
// 现在创建 matcher 对象
Matcher m = r.matcher(fhlLine);
//格式正则校验
if(m.find()){
String strList[] = fhlLine.split("/");
waybillnosecondary = m.group(1);
originatingstationBill = m.group(2);
destinationstationBill = m.group(3);
piece = manifestpiece = m.group(4);
weight = manifestweight = m.group(5);
String SLAC = strList[5];
productname = strList[6];
log.debug("[HBS] 分单信息节点解析完毕");
TEMP_KEY_WORD = "HBS-SHC";
return true;
}
throw new FFMResolveException("[HBS] HBS分单节点信息错误");
}
/**
* 分单其他信息解析
* @param line HBS-分单其他行信息解析
*/
public boolean hbsOtherInfoParse(String line) throws FFMResolveException {
if (line.startsWith("/") && "HBS-SHC".equals(TEMP_KEY_WORD)){
log.debug("适配到分单特货代码节点");
//校验正则1,取前三位验证是否是机场代码
String pattern = "(/[A-Z]{3})+";
// 创建 Pattern 对象
Pattern r = Pattern.compile(pattern);
// 现在创建 matcher 对象
Matcher m = r.matcher(line);
if (m.find()){
String strList[] = line.split("/");
log.info("[HBS-SHC]-特货代码为-{}",line);
return true;
}
throw new FFMResolveException("[HBS] HBS-分单特货代码节点信息错误");
}else{
return false;
}
}
/**
* 分单备注描述信息解析
* @param line TXT
*/
public boolean textInfoParse(String line) throws FFMResolveException {
log.debug("[TEXT] 找到TXT开头节点");
//校验正则1,取前三位验证是否是机场代码
String pattern = "(TXT)?/(.{1,65})";
// 创建 Pattern 对象
Pattern r = Pattern.compile(pattern);
// 现在创建 matcher 对象
Matcher m = r.matcher(line);
//格式正则校验
if(m.find()){
String strList[] = line.split("/");
String freeText = strList[1].trim();
log.info("[TXT]-{}",freeText);
TEMP_KEY_WORD = "TXT";
return true;
}
throw new FFMResolveException("[TXT] TXT节点信息错误,字数不能超过65");
}
/**
* HTS国际协调关税表信息解析
* @param line HTS
*/
public boolean htsInfoParse(String line) throws FFMResolveException {
log.debug("[TEXT] 找到HTS开头节点");
//校验正则1,取前三位验证是否是机场代码
String pattern = "^(HTS)?/[A-Z0-9]{6,18}";
// 创建 Pattern 对象
Pattern r = Pattern.compile(pattern);
// 现在创建 matcher 对象
Matcher m = r.matcher(line);
//格式正则校验
if(m.find()){
String strList[] = line.split("/");
String htsText = strList[1];
log.debug("[HTS] 信息为:{}",htsText);
TEMP_KEY_WORD = "HTS";
return true;
}
throw new FFMResolveException("[HTS] HTS国际协调关税表信息错误,字数为6-18位,最多9次");
}
/**
* 收货人信息解析
* @param consigneLine CNE-收货人行信息解析
*/
public void consigneeInfoParse(String consigneLine){
}
/**
* 发货人信息解析1版本包含分割符解析
* 节点有两种表现 一种是SHP标识后就换行发货人名称,一种是SHP/发货人名称
* @param line SHP-发货人行信息解析
*/
public void shipperHasSplitParse(String line,String SHP_OR_CNE) throws FFMResolveException {
log.debug("[TEXT] 找到SHP|CNE分单开头节点");
//SHP/发货人名称 - 正则适配
String keyword = "^(SHP|CNE)(/.{1,35})?";
// 创建 Pattern 对象
Pattern r = Pattern.compile(keyword);
// 现在创建 matcher 对象
Matcher m = r.matcher(line);
if (m.find()){
String strList[] = line.split("/");
if (strList.length>1){
if("SHP".equals(SHP_OR_CNE)){
shippername = strList[1];
log.debug("[SHP] 发货人信息为:{}",shippername);
TEMP_KEY_WORD= "SHP-ADR";
}else{
consigneename = strList[1];
log.debug("[CNE] 收货人信息为:{}",consigneename);
TEMP_KEY_WORD= "CNE-ADR";
}
}else {
if("SHP".equals(SHP_OR_CNE)){
log.info("[SHP]主节点为分单数据标识节点,下面几行解析具体信息");
TEMP_KEY_WORD= "SHP-NAM";
}else {
log.info("[CNE] 主节点为分单数据标识节点,下面几行解析具体信息");
TEMP_KEY_WORD= "CNE-NAM";
}
}
}else {
throw new FFMResolveException("[SHP|CNE] 收发货人信息格式校验错误");
}
}
/**
* 发货人名称2版本解析
* @param line NAM-发货人行信息解析
*/
public void shipperNamV2Parse(String line) throws FFMResolveException {
if ("SHP-NAM".equals(TEMP_KEY_WORD) || "CNE-NAM".equals(TEMP_KEY_WORD)){
log.debug("[TEXT] 找到收发货人名称节点");
//SHP/发货人名称 - 正则适配
String keyword = "^(NAM)?/.{1,35}";
// 创建 Pattern 对象
Pattern r = Pattern.compile(keyword);
// 现在创建 matcher 对象
Matcher m = r.matcher(line);
if (m.find()){
String strList[] = line.split("/");
if("SHP-NAM".equals(TEMP_KEY_WORD)){
shippername = strList[1];
log.debug("[SHP] 发货人名称为:{}",shippername);
TEMP_KEY_WORD= "SHP-ADR";
}else{
consigneename = strList[1];
log.debug("[CNE] 收货人地址为:{}",consigneename);
TEMP_KEY_WORD= "CNE-ADR";
}
}else {
throw new FFMResolveException("[SHP|CNE] 收发货人名称格式校验错误");
}
}
}
/**
* 发货人地址1版本解析
* @param line NAM-发货人行信息解析
*/
public void shipperAdrV1Parse(String line) throws FFMResolveException {
if ("SHP-ADR".equals(TEMP_KEY_WORD)|| "CNE-ADR".equals(TEMP_KEY_WORD)){
log.debug("[TEXT] 找到发货人地址节点");
//SHP/发货人名称 - 正则适配
String keyword = "^(ADR)?/.{1,35}";
// 创建 Pattern 对象
Pattern r = Pattern.compile(keyword);
// 现在创建 matcher 对象
Matcher m = r.matcher(line);
if (m.find()){
String strList[] = line.split("/");
if("SHP-ADR".equals(TEMP_KEY_WORD)){
shipperaddress = strList[1];
log.debug("[SHP] 发货人地址为:{}",shipperaddress);
TEMP_KEY_WORD= "SHP-LOC";
}else {
consigneeaddress = strList[1];
log.debug("[CNE] 收货人地址为:{}",consigneeaddress);
TEMP_KEY_WORD= "CNE-LOC";
}
}else {
throw new FFMResolveException("[SHP|CNE] 收发货人地址格式校验错误");
}
}
}
/**
* 发货人城市省份1版本解析
* @param line LOC-发货人行信息解析
*/
public void shipperLocV1Parse(String line) throws FFMResolveException {
if ("SHP-LOC".equals(TEMP_KEY_WORD) || "CNE-LOC".equals(TEMP_KEY_WORD)){
log.debug("[TEXT] 找到发货人城市省份节点");
//SHP/发货人名称 - 正则适配
String keyword = "^(LOC)?/.{0,17}(/.{0,9})?";
// 创建 Pattern 对象
Pattern r = Pattern.compile(keyword);
// 现在创建 matcher 对象
Matcher m = r.matcher(line);
if (m.find()){
String strList[] = line.split("/");
if("SHP-LOC".equals(TEMP_KEY_WORD)){
String cityName = strList[1];
log.debug("[SHP] 发货人城市为:{}",cityName);
if (strList.length>2){
log.debug("[SHP] 发货人省份信息为:{}",strList[2]);
}
TEMP_KEY_WORD= "SHP-CON";
}else{
String cityName = strList[1];
log.debug("[CNE] 收货人城市为:{}",cityName);
if (strList.length>2){
log.debug("[CNE] 收货人省份信息为:{}",strList[2]);
}
TEMP_KEY_WORD= "CNE-CON";
}
}else {
throw new FFMResolveException("[SHP|CNE] 发货人地址格式校验错误");
}
}
}
/**
* 发货人国家及联系信息1版本解析
* @param line LOC-发货人行信息解析
*/
public void shipperContactV1Parse(String line) throws FFMResolveException {
if ("SHP-CON".equals(TEMP_KEY_WORD)||"CNE-CON".equals(TEMP_KEY_WORD)){
log.debug("[TEXT] 找到收发货人国家及联系信息节点");
//SHP/发货人名称 - 正则适配
String keyword = "^/[A-Z]{2}(/.{1,9})?((/[TEFXL]{2}/.{1,25})+)?";
// 创建 Pattern 对象
Pattern r = Pattern.compile(keyword);
// 现在创建 matcher 对象
Matcher m = r.matcher(line);
if (m.find()){
String strList[] = line.split("/");
if("SHP-CON".equals(TEMP_KEY_WORD)){
shipperCountrycode = strList[1];
log.debug("[SHP] 发货人国家为:{}",shipperCountrycode);
if (strList.length>3){
log.debug("[SHP] 发货人邮编信息为:{}",strList[2]);
if ("TE".equals(strList[3])){
shipperPhone = strList[4];
log.debug("[SHP] 发货人电话信息为:{}",shipperPhone);
}
if ("FX".equals(strList[3])){
shipperFax = strList[4];
log.debug("[SHP] 发货人传真信息为:{}",consigneeFax);
}
}
}else{
consigneeCountrycode = strList[1];
log.debug("[CNE] 收货人国家为:{}",consigneeCountrycode);
if (strList.length>3){
log.debug("[CNE] 收货人邮编信息为:{}",strList[2]);
if ("TE".equals(strList[3])){
consigneePhone = strList[4];
log.debug("[CNE] 收货人电话信息为:{}",consigneePhone);
}
if ("FX".equals(strList[3])){
consigneeFax = strList[4];
log.debug("[CNE] 收货人传真信息为:{}",consigneeFax);
}
}
}
}else {
throw new FFMResolveException("[SHP|CNE] 收发货人国家及联系信息格式校验错误");
}
}
}
/**
* OCI其他海关信息节点解析
* @param line OCI行
*/
public void ociInfoParse(String line) throws FFMResolveException {
String keyword = "^(OCI)?/([A-Z]{2})?/([A-Z]{3})?/([A-Z]{0,2})?/(.{1,35})";
// 创建 Pattern 对象
Pattern r = Pattern.compile(keyword);
// 现在创建 matcher 对象
Matcher m = r.matcher(line);
if (m.find()){
//二位国家代码
String countryCode = line.split("/")[1];
//三位信息标识
String infoCode = line.split("/")[2];
//二位海关信息标识
String customsCode =line.split("/")[3];
//补充海关信息
String customMsg = line.split("/")[4];
log.debug("[AWB-OTHER-OCI] 运单OCI海关其他信息,国家代码:{} , 信息标识:{}, 海关信息标识:{}, 补充海关信息:{} ",
countryCode,
infoCode,
customsCode,
customMsg);
if (customMsg.length()>35){
throw new FFMResolveException(customMsg+"-OCI海关其他信息长度超过35,解析错误");
}
ociInfoLineParse(countryCode,infoCode,customsCode,customMsg);
TEMP_KEY_WORD= "OCI";
}else {
throw new FFMResolveException("OCI海关其他信息格式校验错误");
}
}
/**
* OCI 信息标识节点解析与判定
* @param countryCode 国家代码儿子
* @param infoCode 信息代码识别码三字码
* @param customsCode 海关标识代码
* @param customMsg 具体标识信息
*/
public boolean ociInfoLineParse(String countryCode,String infoCode,String customsCode,String customMsg){
log.info("[OCI] - 国家代码[{}],信息代码三字码[{}],海关标识代码[{}],具体标识内容[{}]",countryCode,infoCode,customsCode,customMsg);
switch (customsCode){
//具体收货人姓名
case "CP":
case "KC":
case "ST":
specificConsigneename = customMsg;
log.info("收货具体联系人名称[{}]",customMsg);
break;
//具体收货人电话
case "CT":
case "U":
specificConsigneePhone = customMsg;
log.info("收货具体联系人电话[{}]",customMsg);
break;
//海关企业注册代码
case "T":
String enterpriseCode= customMsg;
if ("CNE".equals(infoCode)){
consigneeCode = customMsg;
log.info("收货人国家[{}]企业代码[{}]",countryCode,customMsg);
}else if ("SHP".equals(infoCode)){
shipperCode = customMsg;
log.info("发货人国家[{}]企业代码[{}]",countryCode,customMsg);
}
break;
default:
break;
}
return true;
}
/**
* CVD 计费声明节点解析
* @param line
*/
public void cvdParse(String line){
String keyword = "^CVD/([A-Z]{3})/([PC]{2})/([0-9\\.]{1,12}|NVD)/(NCV|[0-9\\.]{1,12})/(XXX|[0-9\\.]{1,11})";
// 创建 Pattern 对象
Pattern r = Pattern.compile(keyword);
// 现在创建 matcher 对象
Matcher m = r.matcher(line);
if (m.find()){
String ISO_Currency_Code = m.group(1);
paymode = m.group(2);
String Declared_Value_for_Carriage = m.group(3);
String Declared_Value_for_Customs = m.group(4);
String Declared_Value_for_Insurance = m.group(5);
log.info("[CVD]-计费声明:货币代码[{}]-付费模式[{}]-运输申报价值[{}]-海关申报价值[{}]-保险申报价值[{}]",
ISO_Currency_Code,paymode,Declared_Value_for_Carriage,Declared_Value_for_Customs,Declared_Value_for_Insurance);
}
}
}
... ...
package com.tianbo.analysis.service;
import com.tianbo.analysis.model.FFMInfo;
import com.tianbo.analysis.model.Originmanifestsecondary;
public interface FHLResolve {
boolean resolve(Originmanifestsecondary var1);
}
... ...
package com.tianbo.analysis.service.imp;
import com.tianbo.analysis.dao.OriginmanifestsecondaryMapper;
import com.tianbo.analysis.dao.TBBaseAirportInfoDao;
import com.tianbo.analysis.model.Originmanifestsecondary;
import com.tianbo.analysis.service.FHLResolve;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service("nmmsV1FHLResolve")
public class FHLResolveImpl implements FHLResolve {
@Resource
TBBaseAirportInfoDao airportInfoDao;
@Resource
OriginmanifestsecondaryMapper mapper;
@Override
public boolean resolve(Originmanifestsecondary fhl) {
try{
fhl.textToStringList();
fhl.startParse();
}catch (Exception e){
e.printStackTrace();
}
return false;
}
}
... ...
package com.tianbo.analysis.tools;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author mrz
* 关于运单的工具类
*/
@Slf4j
public class WaybillTools {
/**
... ... @@ -50,4 +53,32 @@ public class WaybillTools {
}
return "";
}
/**
* 模七校验
* @param waybillNo
* @return
*/
public static boolean model7Check(String waybillNo){
String pattern = "\\d{3}-\\d{8}";
// 创建 Pattern 对象
Pattern r = Pattern.compile(pattern);
// 现在创建 matcher 对象
Matcher m = r.matcher(waybillNo);
if (m.find()){
String num = waybillNo.split("-")[1];
String num_7 = num.substring(0,7);
String num_end = num.substring(7,8);
if (Integer.parseInt(num_7)% 7 == Integer.parseInt(num_end)){
return true;
}else {
log.error("{}模七不通过",waybillNo);
}
}else {
log.error("{}运单格式不正确",waybillNo);
}
return false;
}
}
... ...
import com.tianbo.analysis.NmmsAdminApplication;
import com.tianbo.analysis.exception.FFMResolveException;
import com.tianbo.analysis.model.Originmanifestsecondary;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
//@RunWith(SpringRunner.class)
@SpringBootTest(classes = NmmsAdminApplication.class)
public class FHLTest {
private static Logger logger = LogManager.getLogger(FHLTest.class);
private static String FHL = "ZCZC\n" +
"QK CGOFD1E \n" +
".AUHFMEY 130837\n" +
"FHL/4 \n" +
"MBI/607-23719323PVGDWC/T15K1058 \n" +
"HBS/8KR6230/PVGDWC/1/K119/50/LAPTOP COMPUTER\n" +
"/ELI \n" +
"TXT/LAPTOP COMPUTERNO FREE TEXT DESCRIPTION OF GOODS SUPPLIED \n" +
"SHP/YCH LOGISTICS KUNSHAN CO. LTD. \n" +
"/NO 5 TAOYUAN ROAD KUNSHAN FREE TRAD \n" +
"/KUNSHAN/32 \n" +
"/CN/215300/FX/112321-0 \n" +
"CNE/MINDWARE FZ LLC \n" +
"/PLOT WF07 DUBAI LOGISTICS CITY \n" +
"/DUBAI WORLD CENTR/DU \n" +
"/AE/55609/TE/112321-0 \n" +
"CVD/USD/PP/NVD/NCV/XXX\n" +
"HTS/82089000 \n" +
"/84419010 \n"+
"OCI/KR/SHP/T/VAT NUMBER1058174316 \n" +
"/KR/SHP/KC/WILSON KIM \n" +
"/KR/SHP/U/821071510907 \n" +
"/CN/CNE/T/USCI91140100792221652P \n" +
"/CN/CNE/KC/AMY LI \n" +
"/CN/CNE/U/53214229437 \n" +
"/CN/NFY/T/USCI91140100792221652P \n" +
"/CN/NFY/KC/AMY LI \n" +
"/CN/NFY/U/03517198188 \n" +
"=\n" +
"NNNN";
@org.junit.jupiter.api.Test
public void send() {
try{
Originmanifestsecondary fhl= new Originmanifestsecondary() ;
fhl.text = FHL;
fhl.textToStringList();
fhl.startParse();
}catch (Exception e){
e.printStackTrace();
}
}
}
... ...