作者 xudada

FWB校验

  1 +package com.tianbo.analysis.controller;
  2 +
  3 +import com.tianbo.analysis.model.FWBinfo;
  4 +import com.tianbo.analysis.model.Originmanifestsecondary;
  5 +import com.tianbo.analysis.model.ResultJson;
  6 +import com.tianbo.analysis.service.FWBResolve;
  7 +import lombok.extern.slf4j.Slf4j;
  8 +import org.springframework.beans.factory.annotation.Autowired;
  9 +import org.springframework.web.bind.annotation.PostMapping;
  10 +import org.springframework.web.bind.annotation.RequestMapping;
  11 +import org.springframework.web.bind.annotation.RequestParam;
  12 +import org.springframework.web.bind.annotation.RestController;
  13 +
  14 +@RestController
  15 +@RequestMapping("/fwb")
  16 +@Slf4j
  17 +public class FWBController {
  18 + @Autowired
  19 + FWBResolve resolve;
  20 +
  21 + @PostMapping("resolve")
  22 + public ResultJson resolve(@RequestParam String fwb){
  23 + FWBinfo fwBinfo = new FWBinfo();
  24 + fwBinfo.text = fwb;
  25 + boolean result = resolve.resolve(fwBinfo);
  26 + return result? new ResultJson("200","success"):new ResultJson("400","解析失败");
  27 + }
  28 +}
  1 +package com.tianbo.analysis.dao;
  2 +
  3 +import com.tianbo.analysis.model.FWBinfo;
  4 +
  5 +public interface FWBinfoDao {
  6 + int insert(FWBinfo record);
  7 +
  8 + int insertSelective(FWBinfo record);
  9 +}
  1 +package com.tianbo.analysis.model;
  2 +
  3 +import com.tianbo.analysis.exception.FFMResolveException;
  4 +import com.tianbo.analysis.tools.WaybillTools;
  5 +import lombok.Data;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +import org.apache.commons.lang.StringUtils;
  8 +import org.apache.poi.hssf.util.HSSFColor;
  9 +
  10 +import javax.validation.constraints.NotNull;
  11 +import java.io.BufferedReader;
  12 +import java.io.IOException;
  13 +import java.io.Serializable;
  14 +import java.io.StringReader;
  15 +import java.text.ParseException;
  16 +import java.util.ArrayList;
  17 +import java.util.Date;
  18 +import java.util.List;
  19 +import java.util.UUID;
  20 +import java.util.regex.Matcher;
  21 +import java.util.regex.Pattern;
  22 +
  23 +@Data
  24 +@Slf4j
  25 +public class FWBinfo implements Serializable {
  26 + private String autoid;
  27 +
  28 + private String waybillnomaster;
  29 +
  30 + private String totalweight;
  31 +
  32 + private String totalpiece;
  33 +
  34 + private String productname;
  35 +
  36 + private String carrier1;
  37 +
  38 + private String arrivalstation1;
  39 +
  40 + private String carrier2;
  41 +
  42 + private String arrivalstation2;
  43 +
  44 + private String carrier3;
  45 +
  46 + private String arrivalstation3;
  47 +
  48 + private String paymode;
  49 +
  50 + private String specialgoodscode;
  51 +
  52 + private String shippername;
  53 +
  54 + private String shipperaddress;
  55 +
  56 + private String consigneename;
  57 +
  58 + private String consigneeaddress;
  59 +
  60 + private Date createdate;
  61 +
  62 + private String istransfer;
  63 +
  64 + private String shipperCode;
  65 +
  66 + private String shipperCountrycode;
  67 +
  68 + private String shipperPhone;
  69 +
  70 + private String shipperFax;
  71 +
  72 + private String consigneeCode;
  73 +
  74 + private String consigneeCountrycode;
  75 +
  76 + private String consigneeFax;
  77 +
  78 + private String specificConsigneename;
  79 +
  80 + private String specificConsigneePhone;
  81 +
  82 + private String consigneePhone;
  83 +
  84 +
  85 + //报文内容
  86 + public String text;
  87 + public Object tests;
  88 + public List<String> lineList;
  89 + public String order;
  90 + public String planeNo;
  91 + public int wayBillParseStartLine =0;
  92 + private static final String KEY_WORD_3 = "FWB,FLT,RTG,SHP,NAM,ADR,LOC,CNE,AGT,ATG,SSR,NFY,ACC,CVD,RTD,OTH,PPD,COL,CER,ISU,OSI,CDC,REF,COR,COI,SII,ARD,SPH,NOM,SRI,OPI,OCI";
  93 + private static final String KEY_WORD_FWB="FWB";
  94 + private static final long serialVersionUID = 1L;
  95 + private static String END_WORD= "=";
  96 + private String TEMP_KEY_WORD="";
  97 +
  98 +
  99 +
  100 +
  101 + public FWBinfo(){}
  102 +
  103 +
  104 + public FWBinfo(String autoid,String waybillnomaster,String totalweight,String totalpiece,String productname,String carrier1,String arrivalstation1,String carrier2,String arrivalstation2,
  105 + String specialgoodscode,String carrier3,String arrivalstation3,String paymode,String shippername,String shipperaddress,String consigneename,String consigneeaddress,
  106 + Date createdate,String istransfer,String shipperCode,String shipperCountrycode,String shipperPhone,String shipperFax,String consigneeCode,
  107 + String consigneeCountrycode,String consigneeFax,String specificConsigneename,String specificConsigneePhone,String consigneePhone){
  108 + this.autoid=autoid;
  109 + this.waybillnomaster=waybillnomaster;
  110 + this.totalweight=totalweight;
  111 + this.totalpiece=totalpiece;
  112 + this.productname=productname;
  113 + this.carrier1=carrier1;
  114 + this.arrivalstation1=arrivalstation1;
  115 + this.carrier2=carrier2;
  116 + this.arrivalstation2=arrivalstation2;
  117 + this.specialgoodscode=specialgoodscode;
  118 + this.carrier3=carrier3;
  119 + this.arrivalstation3=arrivalstation3;
  120 + this.paymode=paymode;
  121 + this.shippername=shippername;
  122 + this.shipperaddress=shipperaddress;
  123 + this.consigneename=consigneename;
  124 + this.consigneeaddress=consigneeaddress;
  125 + this.createdate=createdate;
  126 + this.istransfer=istransfer;
  127 + this.shipperCode=shipperCode;
  128 + this.shipperCountrycode=shipperCountrycode;
  129 + this.shipperPhone=shipperPhone;
  130 + this.shipperFax=shipperFax;
  131 + this.consigneeCode=consigneeCode;
  132 + this.consigneeCountrycode=consigneeCountrycode;
  133 + this.consigneeFax=consigneeFax;
  134 + this.specificConsigneename=specificConsigneename;
  135 + this.specificConsigneePhone=specificConsigneePhone;
  136 + this.consigneePhone=consigneePhone;
  137 + }
  138 +
  139 + @Override
  140 + public String toString() {
  141 + StringBuilder sb = new StringBuilder();
  142 + sb.append(getClass().getSimpleName());
  143 + sb.append(" [");
  144 + sb.append("Hash = ").append(hashCode());
  145 + sb.append(", autoid=").append(autoid);
  146 + sb.append(", waybillnomaster=").append(waybillnomaster);
  147 + sb.append(", totalweight=").append(totalweight);
  148 + sb.append(", totalpiece=").append(totalpiece);
  149 + sb.append(", productname=").append(productname);
  150 + sb.append(", carrier1=").append(carrier1);
  151 + sb.append(", arrivalstation1=").append(arrivalstation1);
  152 + sb.append(", carrier2=").append(carrier2);
  153 + sb.append(", arrivalstation2=").append(arrivalstation2);
  154 + sb.append(", carrier3=").append(carrier3);
  155 + sb.append(", arrivalstation3=").append(arrivalstation3);
  156 + sb.append(", paymode=").append(paymode);
  157 + sb.append(", specialgoodscode=").append(specialgoodscode);
  158 + sb.append(", shippername=").append(shippername);
  159 + sb.append(", shipperaddress=").append(shipperaddress);
  160 + sb.append(", consigneename=").append(consigneename);
  161 + sb.append(", consigneeaddress=").append(consigneeaddress);
  162 + sb.append(", createdate=").append(createdate);
  163 + sb.append(", istransfer=").append(istransfer);
  164 + sb.append(", shipperCode=").append(shipperCode);
  165 + sb.append(", shipperCountrycode=").append(shipperCountrycode);
  166 + sb.append(", shipperPhone=").append(shipperPhone);
  167 + sb.append(", shipperFax=").append(shipperFax);
  168 + sb.append(", consigneeCode=").append(consigneeCode);
  169 + sb.append(", consigneeCountrycode=").append(consigneeCountrycode);
  170 + sb.append(", consigneeFax=").append(consigneeFax);
  171 + sb.append(", specificConsigneename=").append(specificConsigneename);
  172 + sb.append(", specificConsigneePhone=").append(specificConsigneePhone);
  173 + sb.append(", consigneePhone=").append(consigneePhone);
  174 + sb.append(", serialVersionUID=").append(serialVersionUID);
  175 + sb.append("]");
  176 + return sb.toString();
  177 + }
  178 + /**
  179 + * 校验报文结尾标识
  180 + * 将报文字符窜转换成行数组
  181 + * @return
  182 + * @throws IOException
  183 + * @throws FFMResolveException
  184 + */
  185 + public boolean textToStringList() throws IOException, FFMResolveException {
  186 + if(StringUtils.isNotBlank(text)){
  187 + /**
  188 + * 检查报文是否为FWB报
  189 + */
  190 + lineList = new ArrayList<>();
  191 + if(text.contains(KEY_WORD_FWB)){
  192 + BufferedReader reader = new BufferedReader(new StringReader(text));
  193 + log.info(this.toString());
  194 + for (String lineStr = reader.readLine();
  195 + lineStr != null;
  196 + lineStr = reader.readLine()) {
  197 + if (StringUtils.isNotEmpty(lineStr)){
  198 + lineList.add(lineStr);
  199 + }
  200 + }
  201 + return true;
  202 + }else{
  203 + throw new FFMResolveException("报文不是FWB报");
  204 + }
  205 + }
  206 + return false;
  207 + }
  208 + /**
  209 + * 开始解析
  210 + * * Cargo-IMP Messages may only contain the following approved characters:
  211 + * * the letters A to Z (upper case only)
  212 + * * the numerals 0 to 9
  213 + * * the special characters / -. Space < =
  214 + */
  215 + public boolean startParse() throws FFMResolveException {
  216 + if (!lineList.isEmpty()){
  217 + int keyword_i = 0;
  218 + for (int i = 0; i < lineList.size(); i++) {
  219 +
  220 + String pattern = "[^A-Z0-9/\\.\\-<=\\s]+";
  221 + Pattern r = Pattern.compile(pattern);
  222 +
  223 +
  224 + //根据行关键字走相应的解析逻辑
  225 + String line = lineList.get(i);
  226 + Matcher m = r.matcher(line);
  227 + if(m.find()){
  228 + log.error("[FWB] 行[{}]中包含非允许特殊字符,报文中只允许包含-[{}]等特殊字符",i," / -. Space < =");
  229 + throw new FFMResolveException("[FWB] 报文中包含特殊字符,报文中只允许包含 / -. Space < = 等特殊字符");
  230 + }
  231 +
  232 +
  233 + log.debug("[TEXT] 开始处理行[{}]-[{}]",i,line);
  234 + if(line.equals(END_WORD)){
  235 + log.info("[END]- 当前行为结束行,解析结束");
  236 + return true;
  237 + }
  238 +
  239 + String keyword = keyword(line);
  240 + if (!"NOT_KEYWORD".equals(keyword)){
  241 + TEMP_KEY_WORD = "";
  242 + keywordParse(keyword,line,i);
  243 + }else{
  244 + log.debug("[[TEXT-LINE-{}]当前行不属于关键字解析行,根据缓存关键字解析下行信息",i);
  245 + keywordNextLineParse(line,i);
  246 + }
  247 +
  248 + }
  249 + }
  250 + return false;
  251 + }
  252 + public FWBinfo resolve(){
  253 + istransfer="1";
  254 + autoid=UUID.randomUUID().toString();
  255 + return new FWBinfo(autoid, waybillnomaster, totalweight, totalpiece, productname, carrier1, arrivalstation1, carrier2, arrivalstation2,
  256 + specialgoodscode, carrier3, arrivalstation3, paymode, shippername, shipperaddress, consigneename, consigneeaddress,
  257 + new Date(), istransfer, shipperCode, shipperCountrycode, shipperPhone, shipperFax, consigneeCode,
  258 + consigneeCountrycode, consigneeFax, specificConsigneename, specificConsigneePhone, consigneePhone);
  259 + }
  260 + /**
  261 + * 根据关键字适配解析方法
  262 + * @param keyword 关键字
  263 + * @param line 当前行内容
  264 + * @param current 当前行数
  265 + */
  266 + public void keywordParse(String keyword,String line,int current) throws FFMResolveException {
  267 + log.debug("[TEXT] 行[{}]包含关键字{},开始处理",current,keyword);
  268 + switch (keyword){
  269 + case "FWB"://BY:XYH
  270 + fwbInfoParse(line);
  271 + break;
  272 + case "FLT"://BY:XYH
  273 + fltparse(line);
  274 + break;
  275 + case "RTG"://BY:XYH
  276 + rtgparse(line);
  277 + break;
  278 + case "SHP":
  279 + shipperHasSplitParse(line,"SHP");
  280 + break;
  281 + case "CNE":
  282 + shipperHasSplitParse(line,"CNE");
  283 + break;
  284 + case "AGT":
  285 + agtParse(line);
  286 + break;
  287 + case "SSR":
  288 + ssrParse(line);
  289 + break;
  290 + case "ACC":
  291 + accParse(line);
  292 + break;
  293 + case "CVD":
  294 + cvdParse(line);
  295 + break;
  296 + case "OTH":
  297 + othParse(line);
  298 + break;
  299 + case "PDD":
  300 + ppdParse(line);
  301 + break;
  302 + case "CER":
  303 + cerParse(line);
  304 + break;
  305 + case "ISU":
  306 + ISUParse(line);
  307 + break;
  308 + case "OSI":
  309 + osiParse(line);
  310 + break;
  311 + case "CDC":
  312 + cdcParse(line);
  313 + break;
  314 + case "REF":
  315 + refParse(line);
  316 + break;
  317 + case "COR":
  318 + corParse(line);
  319 + break;
  320 + case "SII":
  321 + siiParse(line);
  322 + break;
  323 + case "ARD":
  324 + ardParse(line);
  325 + break;
  326 + case "SPH":
  327 + sphParse(line);
  328 + break;
  329 + case "NOM":
  330 + nomParse(line);
  331 + break;
  332 + case "SRI":
  333 + sriParse(line);
  334 + break;
  335 + case "OCI":
  336 + ociInfoParse(line);
  337 + break;
  338 + case "RTD":
  339 + rtdParse(line);
  340 + break;
  341 + default:
  342 + break;
  343 + }
  344 +
  345 + }
  346 +
  347 + /**
  348 + * 根据关键字适配解析方法
  349 + * @param line 当前行内容
  350 + * @param current 当前行数
  351 + */
  352 + public void keywordNextLineParse(String line,int current) throws FFMResolveException {
  353 + log.info("行[{}]当前临时关键字-[{}]",current,TEMP_KEY_WORD);
  354 + switch (TEMP_KEY_WORD){
  355 + case "FWB-WAY"://by:xyh
  356 + waybill(line);
  357 + break;
  358 + case "CNE-NAM":
  359 + case "SHP-NAM":
  360 + //SHP下的第一行地址行
  361 + shipperNamV2Parse(line);
  362 + break;
  363 + case "CNE-ADR":
  364 + case "SHP-ADR":
  365 + //SHP下的第一行地址行
  366 + shipperAdrV1Parse(line);
  367 + break;
  368 + case "CNE-LOC":
  369 + case "SHP-LOC":
  370 + //SHP下的第一行地址行
  371 + shipperLocV1Parse(line);
  372 + break;
  373 + case "CNE-CON":
  374 + case "SHP-CON":
  375 + //SHP下的第一行地址行
  376 + shipperContactV1Parse(line);
  377 + break;
  378 + case "AGT-NAME":
  379 + agtNameParse(line);
  380 + break;
  381 + case "AGT-PLACE":
  382 + agtPlaceParse(line);
  383 + break;
  384 + case "PDD-DUE":
  385 + ppdDueParse(line);
  386 + break;
  387 + case "RTD-GOD":
  388 + rtdgodParse(line);
  389 + break;
  390 + default:
  391 + break;
  392 + }
  393 + }
  394 +
  395 + /**
  396 + * 关键字识别
  397 + * @param text 每行的内容
  398 + * @return 识别为关键字的返回关键字,未被识别为关键字的返回NOT_KEYWORD;
  399 + * 返回的关键字 三字码关键字 机场代码关键字 文件结尾关键字 CONT,LAST
  400 + */
  401 + public String keyword(@NotNull String text){
  402 + //取每行前三位
  403 + if (StringUtils.isNotBlank(text) && text.length()>=3){
  404 + String s_3 = text.substring(0,3);
  405 + if(KEY_WORD_3.contains(s_3)){
  406 + return s_3;
  407 + }
  408 + }
  409 + return "NOT_KEYWORD";
  410 + }
  411 +
  412 + /**
  413 + * FWB信息解析
  414 + * @param verlLine FWB-报文版本行信息解析
  415 + */
  416 + public boolean fwbInfoParse(String verlLine) throws FFMResolveException {
  417 + log.debug("[TEXT] 找到FWB开头节点");
  418 + //校验正则1,取前三位验证是否是机场代码
  419 + String pattern = "^FWB/\\d{1,3}";
  420 + // 创建 Pattern 对象
  421 + Pattern r = Pattern.compile(pattern);
  422 + // 现在创建 matcher 对象
  423 + Matcher m = r.matcher(verlLine);
  424 + //格式正则校验
  425 + if(m.find()){
  426 + String ver = verlLine.split("/")[1];
  427 + log.info("[VER] 报文版本{}",ver.trim());
  428 + TEMP_KEY_WORD="FWB-WAY";
  429 + return true;
  430 + }
  431 + throw new FFMResolveException("[FLIGHT] FWB版本信息错误");
  432 + }
  433 + /**
  434 + * FWB信息解析
  435 + * @param verlLine FWB-报文运单行信息解析
  436 + * by:xyh
  437 + */
  438 + public boolean waybill(String verlLine) throws FFMResolveException {
  439 + log.debug("[TEXT] 找到运单信息行");
  440 + //校验正则1,取前三位验证是否是机场代码
  441 + String pattern = "^(\\d{3}-\\d{8})([A-Z]{3})([A-Z]{3})/T(\\d{1,4})[A-Z0-9]([0-9\\.]{1,7})";
  442 + // 创建 Pattern 对象
  443 + Pattern r = Pattern.compile(pattern);
  444 + // 现在创建 matcher 对象
  445 + Matcher m = r.matcher(verlLine);
  446 + //格式正则校验
  447 + if(m.find()){
  448 + waybillnomaster = m.group(1);
  449 + //主单模七校验
  450 + if(WaybillTools.model7Check(waybillnomaster)){
  451 + log.debug("[AWB] 运单-({})模七校验通过",waybillnomaster);
  452 + }else {
  453 + log.error("{}运单模七校验不通过",waybillnomaster);
  454 + throw new FFMResolveException(waybillnomaster+"运单模七校验不通过");
  455 + }
  456 + totalpiece=m.group(4);
  457 + totalweight = m.group(5);
  458 + log.info("[FWB]运单处理结果[{}]-[{}]-[{}]-[{}]-[{}]",waybillnomaster,arrivalstation1,arrivalstation3,totalpiece,totalweight);
  459 + return true;
  460 + }
  461 + throw new FFMResolveException("[FLIGHT] FWB运单信息节点错误");
  462 + }
  463 + /**
  464 + * FWB信息解析
  465 + * @param verlLine FLT-报文运单行信息解析
  466 + * by:xyh
  467 + */
  468 + public boolean fltparse(String verlLine) throws FFMResolveException {
  469 + log.debug("[TEXT] 找到FLT信息行");
  470 + //校验正则1,取前三位验证是否是机场代码
  471 + String pattern = "^FLT(/[A-Z0-9]{2}[0-9]{3,4}[A-Z]?/\\d{2})+";
  472 + // 创建 Pattern 对象
  473 + Pattern r = Pattern.compile(pattern);
  474 + // 现在创建 matcher 对象
  475 + Matcher m = r.matcher(verlLine);
  476 + //格式正则校验
  477 + if(m.find()){
  478 + String strList[] = verlLine.split("/");
  479 + if(strList.length>3){
  480 + carrier1=strList[1].substring(0,2);
  481 + carrier2=strList[3].substring(0,2);
  482 + }else{
  483 + carrier1=strList[1].substring(0,2);
  484 + }
  485 + log.debug("[FLT] 承运人信息,carrier1:{} , carrier2:{}", carrier1, carrier2);
  486 + return true;
  487 + }
  488 + throw new FFMResolveException("[FLIGHT] FLT运单信息节点错误");
  489 + }
  490 + /**
  491 + * FWB信息解析
  492 + * @param verlLine RTG-RTG信息解析
  493 + * by:xyh
  494 + */
  495 + public boolean rtgparse(String verlLine)throws FFMResolveException{
  496 + log.debug("[TEXT] 找到RTG信息行");
  497 + //校验正则1,取前三位验证是否是机场代码
  498 + String pattern = "^RTG(/[A-Z0-9]{5}/[A-Z0-9]{5})+";
  499 + // 创建 Pattern 对象
  500 + Pattern r = Pattern.compile(pattern);
  501 + // 现在创建 matcher 对象
  502 + Matcher m = r.matcher(verlLine);
  503 + //格式正则校验
  504 + if(m.find()){
  505 + String strList[]=verlLine.split("/");
  506 + if(strList.length>1){
  507 + arrivalstation1=strList[1].substring(0,3);
  508 + arrivalstation2=strList[2].substring(0,3);
  509 + }else{
  510 + arrivalstation1=strList[1].substring(0,3);
  511 + }
  512 + log.info("[RTG]节点处理结果[{}]-[{}]",arrivalstation1,arrivalstation2);
  513 + return true;
  514 + }
  515 + throw new FFMResolveException("[FLIGHT] RTG 运单信息节点错误");
  516 + }
  517 +
  518 +
  519 + /**
  520 + * 发货人信息解析1版本包含分割符解析
  521 + * 节点有两种表现 一种是SHP标识后就换行发货人名称,一种是SHP/发货人名称
  522 + * @param line SHP-发货人行信息解析
  523 + */
  524 + public void shipperHasSplitParse(String line,String SHP_OR_CNE) throws FFMResolveException {
  525 + log.debug("[TEXT] 找到SHP|CNE分单开头节点");
  526 + //SHP/发货人名称 - 正则适配
  527 + String keyword = "^(SHP|CNE)(/.{1,35})?";
  528 + // 创建 Pattern 对象
  529 + Pattern r = Pattern.compile(keyword);
  530 + // 现在创建 matcher 对象
  531 + Matcher m = r.matcher(line);
  532 + if (m.find()){
  533 + /*String strList[] = line.split("/");
  534 + if (strList.length>1){
  535 + if("SHP".equals(SHP_OR_CNE)){
  536 + shippername = strList[1];
  537 + log.debug("[SHP] 发货人信息为:{}",shippername);
  538 + TEMP_KEY_WORD= "SHP-ADR";
  539 + }else{
  540 + consigneename = strList[1];
  541 + log.debug("[CNE] 收货人信息为:{}",consigneename);
  542 + TEMP_KEY_WORD= "CNE-ADR";
  543 + }
  544 +
  545 + }else {
  546 + if("SHP".equals(SHP_OR_CNE)){
  547 +
  548 + log.info("[SHP]主节点为分单数据标识节点,下面几行解析具体信息");
  549 + TEMP_KEY_WORD= "SHP-NAM";
  550 + }else {
  551 + log.info("[CNE] 主节点为分单数据标识节点,下面几行解析具体信息");
  552 + TEMP_KEY_WORD= "CNE-NAM";
  553 + }
  554 +
  555 + }*/
  556 + if("SHP".equals(SHP_OR_CNE)){
  557 + TEMP_KEY_WORD="SHP-NAM";
  558 + }else{
  559 + TEMP_KEY_WORD="CNE-NAM";
  560 + }
  561 + }else {
  562 + throw new FFMResolveException("[SHP|CNE] 收发货人信息格式校验错误");
  563 + }
  564 + }
  565 +
  566 + /**
  567 + * 发货人名称2版本解析
  568 + * @param line NAM-发货人行信息解析
  569 + */
  570 + public void shipperNamV2Parse(String line) throws FFMResolveException {
  571 + if ("SHP-NAM".equals(TEMP_KEY_WORD) || "CNE-NAM".equals(TEMP_KEY_WORD)){
  572 + log.debug("[TEXT] 找到收发货人名称节点");
  573 + //SHP/发货人名称 - 正则适配
  574 + String keyword = "^(NAM)?/.{1,35}";
  575 + // 创建 Pattern 对象
  576 + Pattern r = Pattern.compile(keyword);
  577 + // 现在创建 matcher 对象
  578 + Matcher m = r.matcher(line);
  579 + if (m.find()){
  580 + String strList[] = line.split("/");
  581 + if("SHP-NAM".equals(TEMP_KEY_WORD)){
  582 + shippername = strList[1];
  583 + log.info("收货人的名称打印{}-{}",strList[1],strList);
  584 + log.debug("[SHP] 发货人名称为:{}",shippername);
  585 + TEMP_KEY_WORD= "SHP-ADR";
  586 + }else{
  587 + consigneename = strList[1];
  588 + log.debug("[CNE] 收货人地址为:{}",consigneename);
  589 + TEMP_KEY_WORD= "CNE-ADR";
  590 + }
  591 +
  592 + }else {
  593 + throw new FFMResolveException("[SHP|CNE] 收发货人名称格式校验错误");
  594 + }
  595 + }
  596 + }
  597 +
  598 +
  599 + /**
  600 + * 发货人地址1版本解析
  601 + * @param line NAM-发货人行信息解析
  602 + */
  603 + public void shipperAdrV1Parse(String line) throws FFMResolveException {
  604 + if ("SHP-ADR".equals(TEMP_KEY_WORD)|| "CNE-ADR".equals(TEMP_KEY_WORD)){
  605 + log.debug("[TEXT] 找到发货人地址节点");
  606 + //SHP/发货人名称 - 正则适配
  607 + String keyword = "^(ADR)?/.{1,35}";
  608 + // 创建 Pattern 对象
  609 + Pattern r = Pattern.compile(keyword);
  610 + // 现在创建 matcher 对象
  611 + Matcher m = r.matcher(line);
  612 + if (m.find()){
  613 + String strList[] = line.split("/");
  614 + if("SHP-ADR".equals(TEMP_KEY_WORD)){
  615 + shipperaddress = strList[1];
  616 + log.debug("[SHP] 发货人地址为:{}",shipperaddress);
  617 + TEMP_KEY_WORD= "SHP-LOC";
  618 + }else {
  619 + consigneeaddress = strList[1];
  620 + log.debug("[CNE] 收货人地址为:{}",consigneeaddress);
  621 + TEMP_KEY_WORD= "CNE-LOC";
  622 + }
  623 +
  624 + }else {
  625 + throw new FFMResolveException("[SHP|CNE] 收发货人地址格式校验错误");
  626 + }
  627 + }
  628 + }
  629 +
  630 + /**
  631 + * 发货人城市省份1版本解析
  632 + * @param line LOC-发货人行信息解析
  633 + */
  634 + public void shipperLocV1Parse(String line) throws FFMResolveException {
  635 + if ("SHP-LOC".equals(TEMP_KEY_WORD) || "CNE-LOC".equals(TEMP_KEY_WORD)){
  636 + log.debug("[TEXT] 找到发货人城市省份节点");
  637 + //SHP/发货人名称 - 正则适配
  638 + String keyword = "^(LOC)?/.{0,17}(/.{0,9})?";
  639 + // 创建 Pattern 对象
  640 + Pattern r = Pattern.compile(keyword);
  641 + // 现在创建 matcher 对象
  642 + Matcher m = r.matcher(line);
  643 + if (m.find()){
  644 + String strList[] = line.split("/");
  645 + if("SHP-LOC".equals(TEMP_KEY_WORD)){
  646 + String cityName = strList[1];
  647 + log.debug("[SHP] 发货人城市为:{}",cityName);
  648 + if (strList.length>2){
  649 + log.debug("[SHP] 发货人省份信息为:{}",strList[2]);
  650 + }
  651 + TEMP_KEY_WORD= "SHP-CON";
  652 + }else{
  653 + String cityName = strList[1];
  654 + log.debug("[CNE] 收货人城市为:{}",cityName);
  655 + if (strList.length>2){
  656 + log.debug("[CNE] 收货人省份信息为:{}",strList[2]);
  657 + }
  658 + TEMP_KEY_WORD= "CNE-CON";
  659 + }
  660 +
  661 + }else {
  662 + throw new FFMResolveException("[SHP|CNE] 发货人地址格式校验错误");
  663 + }
  664 + }
  665 + }
  666 +
  667 + /**
  668 + * 发货人国家及联系信息1版本解析
  669 + * @param line LOC-发货人行信息解析
  670 + */
  671 + public void shipperContactV1Parse(String line) throws FFMResolveException {
  672 + if ("SHP-CON".equals(TEMP_KEY_WORD)||"CNE-CON".equals(TEMP_KEY_WORD)){
  673 + log.debug("[TEXT] 找到收发货人国家及联系信息节点");
  674 + //SHP/发货人名称 - 正则适配
  675 + String keyword = "^/[A-Z]{2}(/.{1,9})?((/[TEFXL]{2}/.{1,25})+)?";
  676 + // 创建 Pattern 对象
  677 + Pattern r = Pattern.compile(keyword);
  678 + // 现在创建 matcher 对象
  679 + Matcher m = r.matcher(line);
  680 + if (m.find()){
  681 + String strList[] = line.split("/");
  682 + if("SHP-CON".equals(TEMP_KEY_WORD)){
  683 + shipperCountrycode = strList[1];
  684 + log.debug("[SHP] 发货人国家为:{}",shipperCountrycode);
  685 + if (strList.length>3){
  686 + log.debug("[SHP] 发货人邮编信息为:{}",strList[2]);
  687 + if ("TE".equals(strList[3])){
  688 + shipperPhone = strList[4];
  689 + log.debug("[SHP] 发货人电话信息为:{}",shipperPhone);
  690 + }
  691 + if ("FX".equals(strList[3])){
  692 + shipperFax = strList[4];
  693 + log.debug("[SHP] 发货人传真信息为:{}",consigneeFax);
  694 + }
  695 + }
  696 + }else{
  697 + consigneeCountrycode = strList[1];
  698 + log.debug("[CNE] 收货人国家为:{}",consigneeCountrycode);
  699 + if (strList.length>3){
  700 + log.debug("[CNE] 收货人邮编信息为:{}",strList[2]);
  701 + if ("TE".equals(strList[3])){
  702 + consigneePhone = strList[4];
  703 + log.debug("[CNE] 收货人电话信息为:{}",consigneePhone);
  704 + }
  705 + if ("FX".equals(strList[3])){
  706 + consigneeFax = strList[4];
  707 + log.debug("[CNE] 收货人传真信息为:{}",consigneeFax);
  708 + }
  709 + }
  710 + }
  711 +
  712 + }else {
  713 + throw new FFMResolveException("[SHP|CNE] 收发货人国家及联系信息格式校验错误");
  714 + }
  715 + }
  716 + }
  717 + /**
  718 + * AGT版本解析
  719 + * @param line AGT-代理人行信息解析
  720 + */
  721 + public boolean agtParse(String line)throws FFMResolveException{
  722 + log.debug("[TEXT] 找到AGT信息行");
  723 + String pattern = "^AGT/?(.{0,14})/([0-9]{7})/?([0-9]{0,4})/?([A-Z0-9]{0,3})";
  724 + // 创建 Pattern 对象
  725 + Pattern r = Pattern.compile(pattern);
  726 + // 现在创建 matcher 对象
  727 + Matcher m = r.matcher(line);
  728 + //格式正则校验
  729 + if(m.find()){
  730 + TEMP_KEY_WORD="AGT-NAME";
  731 + log.info("[AGT]节点处理结果[{}]-[{}]-[{}]",m.group(2),m.group(3),m.group(4));
  732 + return true;
  733 + }
  734 + throw new FFMResolveException("[FLIGHT] AGT 运单信息节点错误");
  735 + }
  736 + /**
  737 + * AGT版本解析
  738 + * @param line AGT-NAME代理人行信息解析
  739 + */
  740 + public boolean agtNameParse(String line)throws FFMResolveException{
  741 + log.debug("[TEXT] 找到AGT-NAME信息行");
  742 + String pattern = "^(/.{1,35})";
  743 + // 创建 Pattern 对象
  744 + Pattern r = Pattern.compile(pattern);
  745 + // 现在创建 matcher 对象
  746 + Matcher m = r.matcher(line);
  747 + //格式正则校验
  748 + if(m.find()){
  749 + TEMP_KEY_WORD="AGT-PLACE";
  750 + log.info("[AGT-NAME]节点处理结果[{}]",m.group(1));
  751 + return true;
  752 + }
  753 + throw new FFMResolveException("[FLIGHT] AGT-NAME 运单信息节点错误");
  754 + }
  755 + /**
  756 + * AGT版本解析
  757 + * @param line AGT-PLACE代理人行信息解析
  758 + */
  759 + public boolean agtPlaceParse(String line)throws FFMResolveException{
  760 + log.debug("[TEXT] 找到AGT-PLACE信息行");
  761 + String pattern = "^(/.{1,17})";
  762 + // 创建 Pattern 对象
  763 + Pattern r = Pattern.compile(pattern);
  764 + // 现在创建 matcher 对象
  765 + Matcher m = r.matcher(line);
  766 + //格式正则校验
  767 + if(m.find()){
  768 + log.info("[AGT-PLACE]节点处理结果[{}]",m.group(1));
  769 + return true;
  770 + }
  771 + throw new FFMResolveException("[FLIGHT] AGT-PLACE 运单信息节点错误");
  772 + }
  773 + /**
  774 + * SSR版本解析
  775 + * @param line SSR特别服务请求行信息解析
  776 + */
  777 + public boolean ssrParse(String line)throws FFMResolveException{
  778 + log.debug("[TEXT] 找到SSR信息行");
  779 + String pattern = "^SSR(/.{1,65})+";
  780 + // 创建 Pattern 对象
  781 + Pattern r = Pattern.compile(pattern);
  782 + // 现在创建 matcher 对象
  783 + Matcher m = r.matcher(line);
  784 + //格式正则校验
  785 + if(m.find()){
  786 + log.info("[SSR]节点处理结果[{}]",m.group(1));
  787 + return true;
  788 + }
  789 + throw new FFMResolveException("[FLIGHT] SSR 运单信息节点错误");
  790 + }
  791 + /**
  792 + * ACC版本解析
  793 + * @param line ACC会计信息行信息解析
  794 + */
  795 + public boolean accParse(String line)throws FFMResolveException{
  796 + log.debug("[TEXT] 找到ACC信息行");
  797 + String pattern = "^(ACC/([A-Z]{3})/(.{1,34}))+";
  798 + // 创建 Pattern 对象
  799 + Pattern r = Pattern.compile(pattern);
  800 + // 现在创建 matcher 对象
  801 + Matcher m = r.matcher(line);
  802 + //格式正则校验
  803 + if(m.find()){
  804 + log.info("[ACC]节点处理结果[{}]-[{}]",m.group(2),m.group(3));
  805 + return true;
  806 + }
  807 + throw new FFMResolveException("[FLIGHT] ACC 运单信息节点错误");
  808 + }
  809 + /**
  810 + * CVD 计费声明节点解析
  811 + * @param line
  812 + */
  813 + public void cvdParse(String line){
  814 + String keyword = "^CVD/([A-Z]{3})/([A-Z]{2})/([A-Z]{2})/([0-9\\.]{1,12}|NVD)/(NCV|[0-9\\.]{1,12})/(XXX|[0-9\\.]{1,11})";
  815 + // 创建 Pattern 对象
  816 + Pattern r = Pattern.compile(keyword);
  817 + // 现在创建 matcher 对象
  818 + Matcher m = r.matcher(line);
  819 + if (m.find()){
  820 + String ISO_Currency_Code = m.group(1);
  821 + paymode = m.group(3);
  822 + String Declared_Value_for_Carriage = m.group(4);
  823 + String Declared_Value_for_Customs = m.group(5);
  824 + String Declared_Value_for_Insurance = m.group(6);
  825 + log.info("[CVD]-计费声明:货币代码[{}]-付费模式[{}]-运输申报价值[{}]-海关申报价值[{}]-保险申报价值[{}]",
  826 + ISO_Currency_Code,paymode,Declared_Value_for_Carriage,Declared_Value_for_Customs,Declared_Value_for_Insurance);
  827 + }
  828 + }
  829 + /**
  830 + * OTH版本解析
  831 + * @param line OTH其它收费行信息解析
  832 + */
  833 + public boolean othParse(String line)throws FFMResolveException{
  834 + log.debug("[TEXT] 找到OTH信息行");
  835 + String pattern = "^OTH/([A-Z]{1})/(([A-Z]{2}[A-Z]{1}[0-9\\.]{1,12}))+";
  836 + // 创建 Pattern 对象
  837 + Pattern r = Pattern.compile(pattern);
  838 + // 现在创建 matcher 对象
  839 + Matcher m = r.matcher(line);
  840 + //格式正则校验
  841 + if(m.find()){
  842 + log.info("[OTH]节点处理结果[{}]-[{}]",m.group(1),m.group(2));
  843 + return true;
  844 + }
  845 + throw new FFMResolveException("[FLIGHT] OTH 运单信息节点错误");
  846 + }
  847 + /**
  848 + * PPD版本解析
  849 + * @param line PPD预付费用汇总表行信息解析
  850 + */
  851 + public boolean ppdParse(String line)throws FFMResolveException{
  852 + log.debug("[TEXT] 找到PPD信息行");
  853 + String pattern = "^PPD(/WT[0-9\\.]{1,12})?(/VC[0-9\\.]{0,12})?(/TX[0-9\\.]{0,12})?\n";
  854 + // 创建 Pattern 对象
  855 + Pattern r = Pattern.compile(pattern);
  856 + // 现在创建 matcher 对象
  857 + Matcher m = r.matcher(line);
  858 + //格式正则校验
  859 + if(m.find()){
  860 + TEMP_KEY_WORD="PDD-DUE";
  861 + log.info("[PPD]节点处理结果[{}]-[{}]-[{}]",m.group(1),m.group(2),m.group(3));
  862 + return true;
  863 + }
  864 + throw new FFMResolveException("[FLIGHT] PPD 运单信息节点错误");
  865 + }
  866 + /**
  867 + * PPD版本解析
  868 + * @param line PPD-DUE预付费用汇总表信息解析
  869 + */
  870 + public boolean ppdDueParse(String line)throws FFMResolveException{
  871 + log.debug("[TEXT] 找到PPD-DUE信息行");
  872 + String pattern = "^(/OA[0-9\\.]{1,12})?(/OC[0-9\\.]{0,12})?(/CT[0-9\\.]{0,12})?";
  873 + // 创建 Pattern 对象
  874 + Pattern r = Pattern.compile(pattern);
  875 + // 现在创建 matcher 对象
  876 + Matcher m = r.matcher(line);
  877 + //格式正则校验
  878 + if(m.find()){
  879 + log.info("[PPD]节点处理结果[{}]-[{}]-[{}]",m.group(1),m.group(2),m.group(3));
  880 + return true;
  881 + }
  882 + throw new FFMResolveException("[FLIGHT] PPD-DUE 运单信息节点错误");
  883 + }
  884 + /**
  885 + * CER版本解析
  886 + * @param line CER收货人签名行信息解析
  887 + */
  888 + public boolean cerParse(String line)throws FFMResolveException{
  889 + log.debug("[TEXT] 找到CER信息行");
  890 + String pattern = "^CER/(.{0,20})";
  891 + // 创建 Pattern 对象
  892 + Pattern r = Pattern.compile(pattern);
  893 + // 现在创建 matcher 对象
  894 + Matcher m = r.matcher(line);
  895 + //格式正则校验
  896 + if(m.find()){
  897 + log.info("[CER]节点处理结果[{}]",m.group(1));
  898 + return true;
  899 + }
  900 + throw new FFMResolveException("[FLIGHT] CER 运单信息节点错误");
  901 + }
  902 +
  903 + /**
  904 + * ISU版本解析
  905 + * @param line ISU承运人行信息解析
  906 + */
  907 + public boolean ISUParse(String line)throws FFMResolveException{
  908 + log.debug("[TEXT] 找到ISU信息行");
  909 + String pattern = "^ISU/([0-9]{2}[A-Z]{3}[0-9]{2})/(.{0,17}|[A-Z]{3})?(/.{0,20})?";
  910 + // 创建 Pattern 对象
  911 + Pattern r = Pattern.compile(pattern);
  912 + // 现在创建 matcher 对象
  913 + Matcher m = r.matcher(line);
  914 + //格式正则校验
  915 + if(m.find()){
  916 + log.info("[ISU]节点处理结果[{}]-[{}]-[{}]",m.group(1),m.group(2),m.group(3));
  917 + return true;
  918 + }
  919 + throw new FFMResolveException("[FLIGHT] ISU 运单信息节点错误");
  920 + }
  921 + /**
  922 + * OSI版本解析
  923 + * @param line OSI其他服务资料行信息解析
  924 + */
  925 + public boolean osiParse(String line)throws FFMResolveException{
  926 + log.debug("[TEXT] 找到OSI信息行");
  927 + String pattern = "^OSI(/.{1,65})+";
  928 + // 创建 Pattern 对象
  929 + Pattern r = Pattern.compile(pattern);
  930 + // 现在创建 matcher 对象
  931 + Matcher m = r.matcher(line);
  932 + //格式正则校验
  933 + if(m.find()){
  934 + log.info("[OSI]节点处理结果[{}]",m.group(1));
  935 + return true;
  936 + }
  937 + throw new FFMResolveException("[FLIGHT] OSI 运单信息节点错误");
  938 + }
  939 + /**
  940 + * CDC版本解析
  941 + * @param line CDC目标货币的抄送费用行信息解析
  942 + */
  943 + public boolean cdcParse(String line)throws FFMResolveException{
  944 + log.debug("[TEXT] 找到CDC信息行");
  945 + String pattern = "^CDC/([A-Z]{3}[0-9\\.]{1,11})/([0-9\\.]{1,12})/([0-9\\.]{1,12})/([0-9\\.]{1,12})";
  946 + // 创建 Pattern 对象
  947 + Pattern r = Pattern.compile(pattern);
  948 + // 现在创建 matcher 对象
  949 + Matcher m = r.matcher(line);
  950 + //格式正则校验
  951 + if(m.find()){
  952 + log.info("[CDC]节点处理结果[{}]-[{}]-[{}]-[{}]",m.group(1),m.group(2),m.group(3),m.group(4));
  953 + return true;
  954 + }
  955 + throw new FFMResolveException("[FLIGHT] CDC 运单信息节点错误");
  956 + }
  957 + /**
  958 + * REF版本解析
  959 + * @param line REF发件人参考行信息解析
  960 + */
  961 + public boolean refParse(String line)throws FFMResolveException{
  962 + log.debug("[TEXT] 找到 REF 信息行");
  963 + String pattern = "^REF/([A-Z]{3}[A-Z0-9]{4})?/.{0,15}/([A-Z0-9]{0,3}/[A-Z0-9]{0,17}/[A-Z]{3})? |^REF/([A-Z]{3}[A-Z0-9]{4})?/.{0,15}|^REF/([A-Z]{3}[A-Z0-9]{4})?";
  964 + // 创建 Pattern 对象
  965 + Pattern r = Pattern.compile(pattern);
  966 + // 现在创建 matcher 对象
  967 + Matcher m = r.matcher(line);
  968 + //格式正则校验
  969 + if(m.find()){
  970 + log.info("[REF]节点处理结果[{}]-[{}]-[{}]-[{}]",m.group(1),m.group(2),m.group(3),m.group(4));
  971 + return true;
  972 + }
  973 + throw new FFMResolveException("[FLIGHT] REF 运单信息节点错误");
  974 + }
  975 + /**
  976 + * COR版本解析
  977 + * @param line COR发件人参考行信息解析
  978 + */
  979 + public boolean corParse(String line)throws FFMResolveException{
  980 + log.debug("[TEXT] 找到 COR 信息行");
  981 + String pattern = "^COR/([A-Z0-9]{0,2})";
  982 + // 创建 Pattern 对象
  983 + Pattern r = Pattern.compile(pattern);
  984 + // 现在创建 matcher 对象
  985 + Matcher m = r.matcher(line);
  986 + //格式正则校验
  987 + if(m.find()){
  988 + log.info("[REF]节点处理结果[{}]",m.group(1));
  989 + return true;
  990 + }
  991 + throw new FFMResolveException("[FLIGHT] COR 运单信息节点错误");
  992 + }
  993 + /**
  994 + * sii版本解析
  995 + * @param line SII销售激励信息行信息解析
  996 + */
  997 + public boolean siiParse(String line)throws FFMResolveException{
  998 + log.debug("[TEXT] 找到 SII 信息行");
  999 + String pattern = "^SII/([0-9./]{1,12})?/([A-Z]{0,2})?|^SII/([0-9./]{1,12})?";
  1000 + // 创建 Pattern 对象
  1001 + Pattern r = Pattern.compile(pattern);
  1002 + // 现在创建 matcher 对象
  1003 + Matcher m = r.matcher(line);
  1004 + //格式正则校验
  1005 + if(m.find()){
  1006 + log.info("[SII]节点处理结果[{}]",m.group(1));
  1007 + return true;
  1008 + }
  1009 + throw new FFMResolveException("[FLIGHT] SII 运单信息节点错误");
  1010 + }
  1011 + /**
  1012 + * ard版本解析
  1013 + * @param line ARD代理参考数据行信息解析
  1014 + */
  1015 + public boolean ardParse(String line)throws FFMResolveException{
  1016 + log.debug("[TEXT] 找到 ARD 信息行");
  1017 + String pattern = "^ARD/(.{0,15})";
  1018 + // 创建 Pattern 对象
  1019 + Pattern r = Pattern.compile(pattern);
  1020 + // 现在创建 matcher 对象
  1021 + Matcher m = r.matcher(line);
  1022 + //格式正则校验
  1023 + if(m.find()){
  1024 + log.info("[ARD]节点处理结果[{}]",m.group(1));
  1025 + return true;
  1026 + }
  1027 + throw new FFMResolveException("[FLIGHT] ARD 运单信息节点错误");
  1028 + }
  1029 + /**
  1030 + * SPH版本解析
  1031 + * @param line SPH特别处理细节行信息解析
  1032 + */
  1033 + public boolean sphParse(String line)throws FFMResolveException{
  1034 + log.debug("[TEXT] 找到 SPH 信息行");
  1035 + String pattern = "^SPH/([A-Z]{3})+";
  1036 + // 创建 Pattern 对象
  1037 + Pattern r = Pattern.compile(pattern);
  1038 + // 现在创建 matcher 对象
  1039 + Matcher m = r.matcher(line);
  1040 + //格式正则校验
  1041 + if(m.find()){
  1042 + log.info("[SPH]节点处理结果[{}]",m.group(1));
  1043 + specialgoodscode=m.group(1);
  1044 + return true;
  1045 + }
  1046 + throw new FFMResolveException("[FLIGHT] SPH 运单信息节点错误");
  1047 + }
  1048 + /**
  1049 + * NOM版本解析
  1050 + * @param line NOM指定经办方行信息解析
  1051 + */
  1052 + public boolean nomParse(String line)throws FFMResolveException{
  1053 + log.debug("[TEXT] 找到 NOM 信息行");
  1054 + String pattern = "^NOM/(.{1,35})/(.{1,17})?";
  1055 + // 创建 Pattern 对象
  1056 + Pattern r = Pattern.compile(pattern);
  1057 + // 现在创建 matcher 对象
  1058 + Matcher m = r.matcher(line);
  1059 + //格式正则校验
  1060 + if(m.find()){
  1061 + log.info("[NOM]节点处理结果[{}]-[{}]",m.group(1),m.group(2));
  1062 + return true;
  1063 + }
  1064 + throw new FFMResolveException("[FLIGHT] NOM 运单信息节点错误");
  1065 + }
  1066 + /**
  1067 + * SRI版本解析
  1068 + * @param line SRI装运参考信息行信息解析
  1069 + */
  1070 + public boolean sriParse(String line)throws FFMResolveException{
  1071 + log.debug("[TEXT] 找到 SRI 信息行");
  1072 + String pattern = "^SRI/?(.{0,14})?(/.{0,12})?(/.{0,12})|^SRI/?(.{0,14})|^SRI/?(.{0,14})?(/.{0,12})";
  1073 + // 创建 Pattern 对象
  1074 + Pattern r = Pattern.compile(pattern);
  1075 + // 现在创建 matcher 对象
  1076 + Matcher m = r.matcher(line);
  1077 + //格式正则校验
  1078 + if(m.find()){
  1079 + log.info("[SRI]节点处理结果[{}]-[{}]",m.group(1),m.group(2));
  1080 + return true;
  1081 + }
  1082 + throw new FFMResolveException("[FLIGHT] SRI 运单信息节点错误");
  1083 + }
  1084 + /**
  1085 + * RTD版本解析
  1086 + * @param line RTD费率说明行信息解析
  1087 + */
  1088 + public boolean rtdParse(String line)throws FFMResolveException{
  1089 + log.debug("[TEXT] 找到 RTD 信息行");
  1090 + String pattern = "^RTD/([0-9]{1,2})?(/[A-Z]{1}[0-9]{1,4})?(/[A-Z]{1}[0-9./]{1,7})?(/[A-Z]{1}[A-Z]{1})?(/[A-Z]{1}[0-9./]{4,7}|[0-9./]{1,3}|[A-Z]{1}|[0-9./]{1,2})?(|/[A-Z]{1}][0-9./]{1,7})?(/[A-Z]{1}[0-9./]{1,8})?(/[A-Z]{1}[0-9./]{1,12})";
  1091 + // 创建 Pattern 对象
  1092 + Pattern r = Pattern.compile(pattern);
  1093 + // 现在创建 matcher 对象
  1094 + Matcher m = r.matcher(line);
  1095 + //格式正则校验
  1096 + if(m.find()){
  1097 + log.info("[RTD]节点处理结果[{}]-[{}]",m.group(2),m.group(3));
  1098 + TEMP_KEY_WORD="RTD-GOD";
  1099 + return true;
  1100 + }
  1101 + throw new FFMResolveException("[FLIGHT] RTD 运单信息节点错误");
  1102 + }
  1103 + /**
  1104 + * RTD版本解析
  1105 + * @param line RTD-GOD费率说明行信息解析
  1106 + */
  1107 + public boolean rtdgodParse(String line)throws FFMResolveException{
  1108 + log.debug("[TEXT] 找到 RTD-GOD 信息行");
  1109 + String pattern = "^(/([A-Z]{1}[A-Z]{1})/(.{1,20}))";
  1110 + // 创建 Pattern 对象
  1111 + Pattern r = Pattern.compile(pattern);
  1112 + // 现在创建 matcher 对象
  1113 + Matcher m = r.matcher(line);
  1114 + //格式正则校验
  1115 + if(m.find()){
  1116 + log.info("[RTD-GOD]节点处理结果[{}]",m.group(3));
  1117 + productname=m.group(3);
  1118 + TEMP_KEY_WORD = "";
  1119 + return true;
  1120 + }
  1121 + throw new FFMResolveException("[FLIGHT] RTD-GOD 运单信息节点错误");
  1122 + }
  1123 + /**
  1124 + * OCI其他海关信息节点解析
  1125 + * @param line OCI行
  1126 + */
  1127 + public void ociInfoParse(String line) throws FFMResolveException {
  1128 + String keyword = "^(OCI)?/([A-Z]{2})?/([A-Z]{3})?/([A-Z]{0,2})?/(.{1,35})";
  1129 + // 创建 Pattern 对象
  1130 + Pattern r = Pattern.compile(keyword);
  1131 + // 现在创建 matcher 对象
  1132 + Matcher m = r.matcher(line);
  1133 + if (m.find()){
  1134 + //二位国家代码
  1135 + String countryCode = line.split("/")[1];
  1136 + //三位信息标识
  1137 + String infoCode = line.split("/")[2];
  1138 + //二位海关信息标识
  1139 + String customsCode =line.split("/")[3];
  1140 + //补充海关信息
  1141 + String customMsg = line.split("/")[4];
  1142 + log.debug("[AWB-OTHER-OCI] 运单OCI海关其他信息,国家代码:{} , 信息标识:{}, 海关信息标识:{}, 补充海关信息:{} ",
  1143 + countryCode,
  1144 + infoCode,
  1145 + customsCode,
  1146 + customMsg);
  1147 + if (customMsg.length()>35){
  1148 + throw new FFMResolveException(customMsg+"-OCI海关其他信息长度超过35,解析错误");
  1149 + }
  1150 + ociInfoLineParse(countryCode,infoCode,customsCode,customMsg);
  1151 + TEMP_KEY_WORD= "OCI";
  1152 + }else {
  1153 + throw new FFMResolveException("OCI海关其他信息格式校验错误");
  1154 + }
  1155 + }
  1156 + /**
  1157 + * OCI 信息标识节点解析与判定
  1158 + * @param countryCode 国家代码儿子
  1159 + * @param infoCode 信息代码识别码三字码
  1160 + * @param customsCode 海关标识代码
  1161 + * @param customMsg 具体标识信息
  1162 + */
  1163 + public boolean ociInfoLineParse(String countryCode,String infoCode,String customsCode,String customMsg){
  1164 +
  1165 + log.info("[OCI] - 国家代码[{}],信息代码三字码[{}],海关标识代码[{}],具体标识内容[{}]",countryCode,infoCode,customsCode,customMsg);
  1166 + switch (customsCode){
  1167 + //具体收货人姓名
  1168 + case "CP":
  1169 + case "KC":
  1170 + case "ST":
  1171 + specificConsigneename = customMsg;
  1172 + log.info("收货具体联系人名称[{}]",customMsg);
  1173 + break;
  1174 + //具体收货人电话
  1175 + case "CT":
  1176 + case "U":
  1177 + specificConsigneePhone = customMsg;
  1178 + log.info("收货具体联系人电话[{}]",customMsg);
  1179 + break;
  1180 + //海关企业注册代码
  1181 + case "T":
  1182 + String enterpriseCode= customMsg;
  1183 + if ("CNE".equals(infoCode)){
  1184 + consigneeCode = customMsg;
  1185 + log.info("收货人国家[{}]企业代码[{}]",countryCode,customMsg);
  1186 + }else if ("SHP".equals(infoCode)){
  1187 + shipperCode = customMsg;
  1188 + log.info("发货人国家[{}]企业代码[{}]",countryCode,customMsg);
  1189 + }
  1190 + break;
  1191 + default:
  1192 + break;
  1193 + }
  1194 +
  1195 + return true;
  1196 + }
  1197 +
  1198 +}
  1 +package com.tianbo.analysis.service;
  2 +
  3 +import com.tianbo.analysis.model.FWBinfo;
  4 +
  5 +public interface FWBResolve {
  6 + boolean resolve(FWBinfo fwBinfo);
  7 +}
  1 +package com.tianbo.analysis.service.imp;
  2 +
  3 +import com.tianbo.analysis.dao.FWBinfoDao;
  4 +import com.tianbo.analysis.model.FWBinfo;
  5 +import com.tianbo.analysis.service.FWBResolve;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +import org.springframework.beans.factory.annotation.Autowired;
  8 +import org.springframework.stereotype.Service;
  9 +
  10 +import javax.annotation.Resource;
  11 +@Slf4j
  12 +@Service
  13 +public class FWBResolveImpl implements FWBResolve {
  14 + @Resource
  15 + FWBinfoDao fwBinfoDao;
  16 + @Override
  17 + public boolean resolve(FWBinfo fwBinfo) {
  18 + try{
  19 + fwBinfo.textToStringList();
  20 + fwBinfo.startParse();
  21 + FWBinfo info=fwBinfo.resolve();
  22 + if(info!=null){
  23 + log.info("FWB解析成功返回FWBinfo对象{}",info);
  24 + int result=fwBinfoDao.insertSelective(fwBinfo);
  25 + if(result>0){
  26 + log.info("FWB入库成功");
  27 + return true;
  28 + }else{
  29 + log.info("FWB入库失败");
  30 + }
  31 + }else{
  32 + return false;
  33 + }
  34 + }catch (Exception e){
  35 + e.printStackTrace();
  36 + }
  37 + return false;
  38 + }
  39 +}
  1 +<?xml version="1.0" encoding="UTF-8" ?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  3 +<mapper namespace="com.tianbo.analysis.dao.FWBinfoDao" >
  4 + <resultMap id="BaseResultMap" type="com.tianbo.analysis.model.FWBinfo" >
  5 + <result column="AUTOID" property="autoid" jdbcType="VARCHAR" />
  6 + <result column="WAYBILLNOMASTER" property="waybillnomaster" jdbcType="VARCHAR" />
  7 + <result column="TOTALWEIGHT" property="totalweight" jdbcType="VARCHAR" />
  8 + <result column="TOTALPIECE" property="totalpiece" jdbcType="VARCHAR" />
  9 + <result column="PRODUCTNAME" property="productname" jdbcType="VARCHAR" />
  10 + <result column="CARRIER1" property="carrier1" jdbcType="VARCHAR" />
  11 + <result column="ARRIVALSTATION1" property="arrivalstation1" jdbcType="VARCHAR" />
  12 + <result column="CARRIER2" property="carrier2" jdbcType="VARCHAR" />
  13 + <result column="ARRIVALSTATION2" property="arrivalstation2" jdbcType="VARCHAR" />
  14 + <result column="CARRIER3" property="carrier3" jdbcType="VARCHAR" />
  15 + <result column="ARRIVALSTATION3" property="arrivalstation3" jdbcType="VARCHAR" />
  16 + <result column="PAYMODE" property="paymode" jdbcType="VARCHAR" />
  17 + <result column="SPECIALGOODSCODE" property="specialgoodscode" jdbcType="VARCHAR" />
  18 + <result column="SHIPPERNAME" property="shippername" jdbcType="VARCHAR" />
  19 + <result column="SHIPPERADDRESS" property="shipperaddress" jdbcType="VARCHAR" />
  20 + <result column="CONSIGNEENAME" property="consigneename" jdbcType="VARCHAR" />
  21 + <result column="CONSIGNEEADDRESS" property="consigneeaddress" jdbcType="VARCHAR" />
  22 + <result column="CREATEDATE" property="createdate" jdbcType="TIMESTAMP" />
  23 + <result column="ISTRANSFER" property="istransfer" jdbcType="VARCHAR" />
  24 + <result column="SHIPPER_CODE" property="shipperCode" jdbcType="VARCHAR" />
  25 + <result column="SHIPPER_COUNTRYCODE" property="shipperCountrycode" jdbcType="VARCHAR" />
  26 + <result column="SHIPPER_PHONE" property="shipperPhone" jdbcType="VARCHAR" />
  27 + <result column="SHIPPER_FAX" property="shipperFax" jdbcType="VARCHAR" />
  28 + <result column="CONSIGNEE_CODE" property="consigneeCode" jdbcType="VARCHAR" />
  29 + <result column="CONSIGNEE_COUNTRYCODE" property="consigneeCountrycode" jdbcType="VARCHAR" />
  30 + <result column="CONSIGNEE_FAX" property="consigneeFax" jdbcType="VARCHAR" />
  31 + <result column="SPECIFIC_CONSIGNEENAME" property="specificConsigneename" jdbcType="VARCHAR" />
  32 + <result column="SPECIFIC_CONSIGNEE_PHONE" property="specificConsigneePhone" jdbcType="VARCHAR" />
  33 + <result column="CONSIGNEE_PHONE" property="consigneePhone" jdbcType="VARCHAR" />
  34 + </resultMap>
  35 + <insert id="insert" keyColumn="AUTOID" keyProperty="autoid" parameterType="com.tianbo.analysis.model.FWBinfo" useGeneratedKeys="true">
  36 + insert into CGONMS.FWB_INFO (AUTOID, WAYBILLNOMASTER, TOTALWEIGHT,
  37 + TOTALPIECE, PRODUCTNAME, CARRIER1,
  38 + ARRIVALSTATION1, CARRIER2, ARRIVALSTATION2,
  39 + CARRIER3, ARRIVALSTATION3, PAYMODE,
  40 + SPECIALGOODSCODE, SHIPPERNAME, SHIPPERADDRESS,
  41 + CONSIGNEENAME, CONSIGNEEADDRESS, CREATEDATE,
  42 + ISTRANSFER, SHIPPER_CODE, SHIPPER_COUNTRYCODE,
  43 + SHIPPER_PHONE, SHIPPER_FAX, CONSIGNEE_CODE,
  44 + CONSIGNEE_COUNTRYCODE, CONSIGNEE_FAX, SPECIFIC_CONSIGNEENAME,
  45 + SPECIFIC_CONSIGNEE_PHONE, CONSIGNEE_PHONE)
  46 + values (#{autoid,jdbcType=VARCHAR}, #{waybillnomaster,jdbcType=VARCHAR}, #{totalweight,jdbcType=VARCHAR},
  47 + #{totalpiece,jdbcType=VARCHAR}, #{productname,jdbcType=VARCHAR}, #{carrier1,jdbcType=VARCHAR},
  48 + #{arrivalstation1,jdbcType=VARCHAR}, #{carrier2,jdbcType=VARCHAR}, #{arrivalstation2,jdbcType=VARCHAR},
  49 + #{carrier3,jdbcType=VARCHAR}, #{arrivalstation3,jdbcType=VARCHAR}, #{paymode,jdbcType=VARCHAR},
  50 + #{specialgoodscode,jdbcType=VARCHAR}, #{shippername,jdbcType=VARCHAR}, #{shipperaddress,jdbcType=VARCHAR},
  51 + #{consigneename,jdbcType=VARCHAR}, #{consigneeaddress,jdbcType=VARCHAR}, #{createdate,jdbcType=TIMESTAMP},
  52 + #{istransfer,jdbcType=VARCHAR}, #{shipperCode,jdbcType=VARCHAR}, #{shipperCountrycode,jdbcType=VARCHAR},
  53 + #{shipperPhone,jdbcType=VARCHAR}, #{shipperFax,jdbcType=VARCHAR}, #{consigneeCode,jdbcType=VARCHAR},
  54 + #{consigneeCountrycode,jdbcType=VARCHAR}, #{consigneeFax,jdbcType=VARCHAR}, #{specificConsigneename,jdbcType=VARCHAR},
  55 + #{specificConsigneePhone,jdbcType=VARCHAR}, #{consigneePhone,jdbcType=VARCHAR})
  56 + </insert>
  57 + <insert id="insertSelective" keyColumn="AUTOID" keyProperty="autoid" parameterType="com.tianbo.analysis.model.FWBinfo" useGeneratedKeys="true">
  58 + insert into CGONMS.FWB_INFO
  59 + <trim prefix="(" suffix=")" suffixOverrides="," >
  60 + <if test="autoid != null" >
  61 + AUTOID,
  62 + </if>
  63 + <if test="waybillnomaster != null" >
  64 + WAYBILLNOMASTER,
  65 + </if>
  66 + <if test="totalweight != null" >
  67 + TOTALWEIGHT,
  68 + </if>
  69 + <if test="totalpiece != null" >
  70 + TOTALPIECE,
  71 + </if>
  72 + <if test="productname != null" >
  73 + PRODUCTNAME,
  74 + </if>
  75 + <if test="carrier1 != null" >
  76 + CARRIER1,
  77 + </if>
  78 + <if test="arrivalstation1 != null" >
  79 + ARRIVALSTATION1,
  80 + </if>
  81 + <if test="carrier2 != null" >
  82 + CARRIER2,
  83 + </if>
  84 + <if test="arrivalstation2 != null" >
  85 + ARRIVALSTATION2,
  86 + </if>
  87 + <if test="carrier3 != null" >
  88 + CARRIER3,
  89 + </if>
  90 + <if test="arrivalstation3 != null" >
  91 + ARRIVALSTATION3,
  92 + </if>
  93 + <if test="paymode != null" >
  94 + PAYMODE,
  95 + </if>
  96 + <if test="specialgoodscode != null" >
  97 + SPECIALGOODSCODE,
  98 + </if>
  99 + <if test="shippername != null" >
  100 + SHIPPERNAME,
  101 + </if>
  102 + <if test="shipperaddress != null" >
  103 + SHIPPERADDRESS,
  104 + </if>
  105 + <if test="consigneename != null" >
  106 + CONSIGNEENAME,
  107 + </if>
  108 + <if test="consigneeaddress != null" >
  109 + CONSIGNEEADDRESS,
  110 + </if>
  111 + <if test="createdate != null" >
  112 + CREATEDATE,
  113 + </if>
  114 + <if test="istransfer != null" >
  115 + ISTRANSFER,
  116 + </if>
  117 + <if test="shipperCode != null" >
  118 + SHIPPER_CODE,
  119 + </if>
  120 + <if test="shipperCountrycode != null" >
  121 + SHIPPER_COUNTRYCODE,
  122 + </if>
  123 + <if test="shipperPhone != null" >
  124 + SHIPPER_PHONE,
  125 + </if>
  126 + <if test="shipperFax != null" >
  127 + SHIPPER_FAX,
  128 + </if>
  129 + <if test="consigneeCode != null" >
  130 + CONSIGNEE_CODE,
  131 + </if>
  132 + <if test="consigneeCountrycode != null" >
  133 + CONSIGNEE_COUNTRYCODE,
  134 + </if>
  135 + <if test="consigneeFax != null" >
  136 + CONSIGNEE_FAX,
  137 + </if>
  138 + <if test="specificConsigneename != null" >
  139 + SPECIFIC_CONSIGNEENAME,
  140 + </if>
  141 + <if test="specificConsigneePhone != null" >
  142 + SPECIFIC_CONSIGNEE_PHONE,
  143 + </if>
  144 + <if test="consigneePhone != null" >
  145 + CONSIGNEE_PHONE,
  146 + </if>
  147 + </trim>
  148 + <trim prefix="values (" suffix=")" suffixOverrides="," >
  149 + <if test="autoid != null" >
  150 + #{autoid,jdbcType=VARCHAR},
  151 + </if>
  152 + <if test="waybillnomaster != null" >
  153 + #{waybillnomaster,jdbcType=VARCHAR},
  154 + </if>
  155 + <if test="totalweight != null" >
  156 + #{totalweight,jdbcType=VARCHAR},
  157 + </if>
  158 + <if test="totalpiece != null" >
  159 + #{totalpiece,jdbcType=VARCHAR},
  160 + </if>
  161 + <if test="productname != null" >
  162 + #{productname,jdbcType=VARCHAR},
  163 + </if>
  164 + <if test="carrier1 != null" >
  165 + #{carrier1,jdbcType=VARCHAR},
  166 + </if>
  167 + <if test="arrivalstation1 != null" >
  168 + #{arrivalstation1,jdbcType=VARCHAR},
  169 + </if>
  170 + <if test="carrier2 != null" >
  171 + #{carrier2,jdbcType=VARCHAR},
  172 + </if>
  173 + <if test="arrivalstation2 != null" >
  174 + #{arrivalstation2,jdbcType=VARCHAR},
  175 + </if>
  176 + <if test="carrier3 != null" >
  177 + #{carrier3,jdbcType=VARCHAR},
  178 + </if>
  179 + <if test="arrivalstation3 != null" >
  180 + #{arrivalstation3,jdbcType=VARCHAR},
  181 + </if>
  182 + <if test="paymode != null" >
  183 + #{paymode,jdbcType=VARCHAR},
  184 + </if>
  185 + <if test="specialgoodscode != null" >
  186 + #{specialgoodscode,jdbcType=VARCHAR},
  187 + </if>
  188 + <if test="shippername != null" >
  189 + #{shippername,jdbcType=VARCHAR},
  190 + </if>
  191 + <if test="shipperaddress != null" >
  192 + #{shipperaddress,jdbcType=VARCHAR},
  193 + </if>
  194 + <if test="consigneename != null" >
  195 + #{consigneename,jdbcType=VARCHAR},
  196 + </if>
  197 + <if test="consigneeaddress != null" >
  198 + #{consigneeaddress,jdbcType=VARCHAR},
  199 + </if>
  200 + <if test="createdate != null" >
  201 + #{createdate,jdbcType=TIMESTAMP},
  202 + </if>
  203 + <if test="istransfer != null" >
  204 + #{istransfer,jdbcType=VARCHAR},
  205 + </if>
  206 + <if test="shipperCode != null" >
  207 + #{shipperCode,jdbcType=VARCHAR},
  208 + </if>
  209 + <if test="shipperCountrycode != null" >
  210 + #{shipperCountrycode,jdbcType=VARCHAR},
  211 + </if>
  212 + <if test="shipperPhone != null" >
  213 + #{shipperPhone,jdbcType=VARCHAR},
  214 + </if>
  215 + <if test="shipperFax != null" >
  216 + #{shipperFax,jdbcType=VARCHAR},
  217 + </if>
  218 + <if test="consigneeCode != null" >
  219 + #{consigneeCode,jdbcType=VARCHAR},
  220 + </if>
  221 + <if test="consigneeCountrycode != null" >
  222 + #{consigneeCountrycode,jdbcType=VARCHAR},
  223 + </if>
  224 + <if test="consigneeFax != null" >
  225 + #{consigneeFax,jdbcType=VARCHAR},
  226 + </if>
  227 + <if test="specificConsigneename != null" >
  228 + #{specificConsigneename,jdbcType=VARCHAR},
  229 + </if>
  230 + <if test="specificConsigneePhone != null" >
  231 + #{specificConsigneePhone,jdbcType=VARCHAR},
  232 + </if>
  233 + <if test="consigneePhone != null" >
  234 + #{consigneePhone,jdbcType=VARCHAR},
  235 + </if>
  236 + </trim>
  237 + </insert>
  238 +</mapper>