package com.sy.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sy.crossDomain.BuildBarCode;
import com.sy.mapper.LandListDao;
import com.sy.model.*;
import com.sy.service.*;
import com.sy.socket.CommandClient;
import com.sy.utils.FileTool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.sy.service.impl.ResMessageServiceImpl.toStrArry;

@Slf4j
@Component("GatherInfoHandle")
public class GatherInfoHandle implements GatherInfoService {

    private static GatherInfoHandle gatherInfoHandle;

    //逻辑判断后的返回信息定义
    private static String PERMITTHOUGH =        "直接放行";
    private static String GROWSSEXCETION =      "禁止通行,重量不在可控范围";
    private static String NORECORD =            "车辆未备案或者识别错误,车牌号:";
    private static String NO_CHEPAI =           "未识别到车牌号:";
    private static String INPUTSTATION =        "此车辆未做进站申请";
    private static String ENTERSTATION =        "此车辆未做出站申请";
    private static String ISVALID =             "二维码数据异常,请使用正确的二维码数据";
    private static String ERRORWT =             "出起始场站的重量和进目的场站的重量不一致";
    private static String IEPORSE =             "无相对应进出场申请";
    private static String FANGXING=             "有运单未放行";
    private static String FENBO =               "装载运单的分拨申请舱单未通过校验";
    private static String NOGrossWt =           "过磅重量异常";
    private static String BLACKLIST=            "车辆已被拉进黑名单,不允许出区";
    private static String CHANEL_ERR=           "无对应通道流转申请,走错通道";
    private static String TUIKU=           "车辆装载有退库货物,人工放行";
    private static String CHECKINNOEMPTY=           "提货业务禁止非空车驶入";


    @Autowired
    private NmmsService nmmsService;

    /**
     *  车辆信息备案表
     */
    @Autowired
    private LandRoadVeService veService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private BusnesslistinfoService busnesslistinfoService;

    @Resource
    private LandListDao landListDao;

    @Value("${devdebug}")
    private Boolean debug;


    /**
     * 进出场申请表
     */
    @Autowired
    private LandBusListService listService;

    /**
     * 重量校验算法
     */
    @Autowired
    private WeightCheckHandleService weightCheckHandleService;

    /**
     * 查询运单放行表
     */
    @Autowired
    private ResMessageService resMessageService;

    /**
     * 指令日志表
     */
    @Autowired
    private CommandLogService commandLogService;

    /**
     * 车辆过卡信息
     */
    private GatherInfo info;

    /**
     * 车辆流转申请表头信息
     */
    private LandBusinessTypeList landBusinessTypeList;

    private List<LandBusinessTypeList> landBusinessTypeListList;

    /**
     * 车辆申请表体信息
     */
    private List<LAND_BUSINEESTYPE_LIST_INFO> listinfos;



    /**
     *  过磅重量
     */
    private double growssWt=0.0;
    /**
     *  车牌号
     */
    private String vaName;

    /**
     *  车辆备案重量
     */
    private double selfWt=0.0;

    /**
     * 初始化装载货物重量
     */
    private double goodsWt=0.0;
    /**
     * 车辆入场时的重量
     */
    private double inWt=0.0;

    /**
     * 计算后的车辆进出场差值
     */
    private double diffVal=0.0;


    @PostConstruct
    public void init() {
        gatherInfoHandle = this;
    }

    @Override
    public int save(GatherInfo info) {
        return 0;
    }

    @Override
    public void handel(GatherInfo gatherInfo) {
        try {
            this.info = gatherInfo;
            //获取过磅重量
            growssWt = info.getGrosswt().doubleValue();

            //取车牌号,判定卡口是否取到车牌号
            vaName = info.getVename();


                                                //车牌校验
            if (veNameCheck(vaName)
                    && veRecordCheck()          //车辆备案
                    && LandBusinessFormCheck()  //流转申请校验
                    && weightCheck(info)        //过磅重量校验
            ){

                //  场站白名单放行验证
                if (areaWhiteListCheck()){
                    pass();
                    releaseFormCheck();     //流转申请单核销
                    return;
                }
                //入区核放
                if(chanelInCheck()){

                    switch (landBusinessTypeList.getBusinesstype()){
                        case "进口转关":
                        case "进口提货":
                            if (gatherInfoHandle.weightCheckHandleService.checkImportAtCheckIN(growssWt, selfWt, goodsWt,inWt)){
                                pass();
                                log.info("[X21-SUCCESS]:[IN]-进口提货放行");
                            }else{
                                sendBw(info,false,CHECKINNOEMPTY,landBusinessTypeList,listinfos);
                                log.info("[X21-ERR]:[IN]-进口提货-非空车驶入");
                            }
                            break;
                        default:
                            pass();
                            log.info("[X21-SUCCESS]:[IN]-车辆入区直接放行");
                    }

                    /**
                     * 华东区内流转-进口分拨核销部分.
                     * 核销已转为从华东申报回执那里确定
                     */
//                    if ("区内分拨".equals(landBusinessTypeList.getBusinesstype())) {
//                        //入区后 核销
//                        //todo:测试注释掉,二维码释放
//                        if (!gatherInfoHandle.debug){
//                            buildBarCode.cancleBarCode(vaName);
//                            log.info("[流转申请]-二维码已释放:"+vaName);
//                        }
//
//                        //分拨申请验放
////                        boolean allocatCheck = checkNmmsAllocate(landBusinessTypeList.getMasterList());
////                        if(!allocatCheck){
////                            log.error("[分拨业务]-分拨申请舱单未通过校验:"+FENBO);
////                            sendBw(info,false,FENBO,landBusinessTypeList,listinfos);
////                            return;
////                        }
//
//                        int rc = gatherInfoHandle.landListDao.releaseBarcode(info.getBarcode());
//                        if (rc>0) {
//                            log.info("[进出场核销]-{}[区内分拨]-流转已核销:{}",vaName,info.getBarcode());
//                        }else{
//                            log.error("[进出场核销-ERROR]-{}[区内分拨]-流转未核销成功:{}",vaName,info.getBarcode());
//                        }
//                        //车辆流转申请缓存删除
//                        releaseCache();
//                    }
                    return;
                }else{
                    inStationInfo();            //入场信息获取
                    setListinfos();             //流转申请表体获取

                    if (goodsWhiteListCheck() && !"调拨业务".equals(landBusinessTypeList.getBusinesstype()) && !"分拨业务".equals(landBusinessTypeList.getBusinesstype())){ //货物类型白名单
                        pass();
                        log.info("[SPECIAL]-特殊业务出区验放通过:{}",landBusinessTypeList.getCocode());
                        releaseFormCheck();     //流转申请单核销
                        return;
                    }

                    if(checkRelease()){         //出区核放
                        sendBw(info, true,PERMITTHOUGH,landBusinessTypeList,listinfos);
                        log.info("[SUCCESS]:{}车辆验放成功出区",info.getVename());
                        releaseFormCheck();     //流转申请单核销
                    }

                }
            }else{
                log.info("[X21-ERROR]:{}车辆验放失败",info.getVename());
            }


        }catch (Exception e){
            log.error("放行判定异常",e);
            CommandClient.Client(gatherInfo, "放行判定程序异常");
        }



    }


    /**
     * 一.
     * 场站白名单,顺丰
     * @return 白名单 true. 其他走校验
     */
    private boolean areaWhiteListCheck(){
        if(FileTool.readProperties("stationsf").equals(info.getAreaid())) {
            return true;
        }
        if (zbqAreaWhiteListCheck()) {
            return true;
        }
        return false;
    }

    /**
     * 一.
     * 场站白名单,综保区白名单特殊验放
     * 综保区不做重量验放,但是还要进行单证放行验放
     * @return 白名单 true. 其他走校验
     */
    private boolean zbqAreaWhiteListCheck(){
        if(FileTool.readProperties("station").contains(info.getAreaid())) {
            log.info("[ZBQ]-综保区核验放行");
            if ("E".equals(info.getIetype())){

                inStationInfo();            //入场信息获取
                setListinfos();             //流转申请表体获取

                //业务类型及放行判定
                switch (landBusinessTypeList.getBusinesstype()){
                    case "进口提货":
                        if ("退库货物".equals(landBusinessTypeList.getCocode()) || "换单货物".equals(landBusinessTypeList.getCocode())){
                            return true;
                        }else {
                            //检查运单放行
                            if (gatherInfoHandle.resMessageService.checkManifestRelease(info,listinfos)){
                                return true;
                            }else {
                                //有运单未放行
                                log.error("[进口提货]-出场未通过校验:"+FANGXING+landBusinessTypeList.getMasterList());
                                sendBw(info,false,FANGXING,landBusinessTypeList,listinfos);
                                return false;
                            }
                        }

                    case "调拨业务":
                        if (goodsWhiteListCheck()){
                            return true;
                        }else {
                            //检查运单放行,拉板可出
                            if (gatherInfoHandle.resMessageService.checkManifestRelease(info,listinfos)){
                                return true;
                            }else {
                                //有运单未放行
                                log.error("[调拨业务]-出场未通过校验:"+FANGXING+landBusinessTypeList.getMasterList());
                                sendBw(info,false,FANGXING,landBusinessTypeList,listinfos);
                                return false;
                            }
                        }

                    default:
                        return true;
                }
            }
            return true;
        }
        return false;
    }




    /**
     * 1. 车牌信息校验
     */
    private boolean veNameCheck(String veName){
        //1. 若无车牌号,返回未识别错误
        if (StringUtils.isEmpty(vaName)) {
            log.error(NO_CHEPAI+vaName);
            sendBw(info,false,NO_CHEPAI + vaName,null,listinfos);
            //CommandClient.Client(info, NO_CHEPAI + vaName);
            return false;
        }
        return true;
    }

    /**
     * 2. 车辆备案信息校验
     */
    private boolean veRecordCheck(){
        //2. 校验车辆是否备案
        LandRoadVe ve = gatherInfoHandle.veService.selectByFrameNo(vaName);
        //若无备案信息或者黑名单,返回车辆未备案或者识别错误,
        if (ve == null) {
            log.error(NORECORD+vaName);
            sendBw(info,false,NORECORD + vaName,null,listinfos);
            //CommandClient.Client(info, NORECORD + vaName);
            return false;
        }

        if (!veBlackListCheck(ve)){
            return false;
        }

        //车辆备案重量
        selfWt=Double.parseDouble(ve.getSelfWt());
        return true;

    }

    /**
     * 3. 车辆黑名单校验
     */
    private boolean veBlackListCheck(LandRoadVe ve){
        if("Y".equals(ve.getVeState())){
            log.info(vaName+BLACKLIST);
            sendBw(info,false,vaName+BLACKLIST,null,listinfos);
            return false;
        }
        return true;
    }

    /**
     * 4. 车辆进出场流转申请单信息校验
     * 二维码不用校验了,二维码失效会删除redis缓存
     * @return
     */
    private boolean LandBusinessFormCheck(){
        try {
            log.info("车辆-{}核碰缓存",info.getVename());
            landBusinessTypeListList = new ArrayList<>();
            //通过车牌号,二维码,场站,通道号,进出类型查询进出场站申请列表
            if (info==null){
                log.error("info 实体为NULL");
                return false;
            }

            String landBusinessJson = gatherInfoHandle.redisService.get(info.getVename());
            List<LandBusinessTypeList> list = new ArrayList<>();
            if (StringUtils.isNotEmpty(landBusinessJson)){

                 list =  JSONArray.parseArray(landBusinessJson,LandBusinessTypeList.class);

                landBusinessTypeListList  = list;
                //4. 若查询结果为null,返回无相对应进出场申请
                if (list == null || list.isEmpty()) {
                    log.error(vaName+IEPORSE);
                    sendBw(info,false,vaName+IEPORSE,null,listinfos);
                    return false;
                }

                for (LandBusinessTypeList item : list) {

                    if (item.getAisle().equals(info.getChnlno()) && item.getBarcode().equals(info.getBarcode())){
                        landBusinessTypeList = item;
                        //离场装载货物重量
                        goodsWt = Double.parseDouble(landBusinessTypeList.getRemark());
                        log.info("车辆-{}的申请缓存信息核碰成功,通道:{}",info.getVename(),info.getChnlno());
                        return true;
                    }
                }

                //核碰流转申请失败
                log.info("[CACHE]:车辆-{}的流转申请校验失败,无对应流转申请信息",info.getVename());
                sendBw(info,false,info.getVename()+CHANEL_ERR,null,listinfos);
            }else {
                log.error("[CACHE-ERROR]:未找到车辆-{}的申请缓存信息",info.getVename());
                log.info("[CACHE-ERROR]:未找到车辆-{}的申请缓存信息,或者流转已超期失效",info.getVename());
                sendBw(info,false,info.getVename()+IEPORSE+",或者流转已超期失效",null,listinfos);
                return false;
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("[CACHE-PARSE-ERROR]:",e);
            return false;
        }

        return false;
    }




    /**
     * 5. 车辆过磅重量校验
     * @return true 通过 false 不通过
     */
    private boolean weightCheck(GatherInfo info){
        if(info.getGrosswt().compareTo(BigDecimal.ZERO) > 0){
            log.info("过磅重量校验通过,过磅重量大于0");
        }else{
            sendBw(info,false,NOGrossWt + growssWt,new LandBusinessTypeList(),listinfos);
            return false;
        }
        return true;
    }

    /**
     * 流转申请-货物类型白名单,白名单的货物类型目前直接放行
     * @return true 白名单货物直接放行   false 非白名单 需要验放
     */
    private boolean goodsWhiteListCheck(){
        if(!"普通货物".equals(landBusinessTypeList.getCocode())
                && !"转关货物".equals(landBusinessTypeList.getCocode())
                && !"退库货物".equals(landBusinessTypeList.getCocode())
                && !"换单货物".equals(landBusinessTypeList.getCocode())
        ) {
            //todo:比如货物类型为快件货物,只走重量校验,不走放行信息等校验.
            //todo:退库货物可以关联货运系统,得到退库信息进行比对
            //todo:查验货物走查验信息比对
            //todo:快件暂不校验直接放行,不过得录单
            //todo:换单货物校验逻辑待定
            //todo:未来取消货物类型判定.
            log.info("车辆装载货物为:" + landBusinessTypeList.getCocode());
            return true;
        }
        return false;
    }

    /**
     * todo:通道及金二路由判定,是金二通道的话,等金二X22
     * 目前宽进严出策略,本地判定
     *
     */
    private boolean chanelInCheck(){
        if ("I".equals(info.getIetype())){
            return true;
        }else {
            return false;
        }
    }

    /**
     * 离场时需要获取的车辆进场信息,入场重量,进出场差值
     */
    private void inStationInfo(){
        List<LandBusinessTypeList> stationInChanleInfo= gatherInfoHandle.listService.selectwt(info.getVename(),info.getBarcode(),info.getAreaid(),"I");
        if (stationInChanleInfo.isEmpty()){
            log.info("未查询到车辆:{}的入场信息",info.getVename());
        }else {
            for(LandBusinessTypeList typeList:stationInChanleInfo){
                if(typeList.getAislewt()!=null){
                    //对应场站进场过磅重量
                    inWt=typeList.getAislewt();
                }
                diffVal = inWt- growssWt;
            }

            //TODO:进场校验 增加 车辆备案重量要 <= 进场过磅重量 ,要有误差判定
        }
    }



    /**
     * 此通道对应的流转申请货物重量.
     */
    private void setGoodsWt(LandBusinessTypeList list){

    }



    /**
     * 设置表体全局变量
     */
    private void setListinfos(){
        //查询运单列表
        listinfos=gatherInfoHandle.busnesslistinfoService.selectmanilist(info.getBarcode());
    }

    /**
     * todo:与金二指令一起核碰
     * 出区抬杆放行判定
     * @return true 抬杆放行
     */
    private boolean checkRelease(){
        log.info("[进出场申请]-业务类型为:"+landBusinessTypeList.getCocode()+landBusinessTypeList.getBusinesstype());
        switch (landBusinessTypeList.getBusinesstype()){
            case "空车业务":
                if(gatherInfoHandle.weightCheckHandleService.checkEmpty(growssWt,selfWt)){
                    return true;
                }else{
                    log.error("[空车业务]-出场重量未通过校验:"+GROWSSEXCETION);
                    sendBw(info,false,GROWSSEXCETION,landBusinessTypeList,listinfos);
                    return false;
                }
            case "出口转关":
            case "出口送货":
                if (gatherInfoHandle.weightCheckHandleService.checkExportDownLoading(growssWt, selfWt, goodsWt,inWt)){
                    return true;
                }else{
                    log.error("[出口送货]-出场重量未通过校验:"+GROWSSEXCETION);
                    sendBw(info,false,GROWSSEXCETION,landBusinessTypeList,listinfos);
                    return false;
                }
            case "进口转关":
            case "进口提货":
                if (gatherInfoHandle.weightCheckHandleService.checkImportDlv(growssWt, selfWt, goodsWt,inWt)){
                    if ("退库货物".equals(landBusinessTypeList.getCocode()) || "换单货物".equals(landBusinessTypeList.getCocode())){
                        /**
                         * 退库货物不校验运单放行.
                         * @chenageNew 退库货物不自动抬杆放行,改为人工验放模式
                         */
                        log.info("[退库业务]-人工验放模式.");
                        sendBw(info,false,TUIKU,landBusinessTypeList,listinfos);
                        return false;
                    }else{
                        //检查运单放行
                        if (gatherInfoHandle.resMessageService.checkManifestRelease(info,listinfos)){
                            return true;
                        }else {
                            //有运单未放行
                            log.error("[进口提货]-出场未通过校验:"+FANGXING+landBusinessTypeList.getMasterList());
                            sendBw(info,false,FANGXING,landBusinessTypeList,listinfos);
                            return false;
                        }
                    }
                    //todo:装载运单历史数据累加超重判定
                }else{
                    log.error("[进口提货]-出场重量未通过校验:"+GROWSSEXCETION);
                    sendBw(info,false,GROWSSEXCETION,landBusinessTypeList,listinfos);
                    return false;
                }
            case "分拨业务":
                if (gatherInfoHandle.weightCheckHandleService.checkAllocateOrDispatch(growssWt, selfWt, goodsWt,inWt)){
                    /**
                     * 分拨业务如果空车出,可出.(就是申请不带运单的)
                     */
                    if (listinfos!=null && listinfos.isEmpty()){
                        log.info("[分拨-空车]-{}空车离场",info.getVename());
                        return true;
                    }
                    //todo:检查分拨申请
                    boolean allocatCheck = checkNmmsAllocate(landBusinessTypeList.getMasterList());
                    if(!allocatCheck){
                        log.error("[分拨业务]-分拨申请舱单未通过校验:"+FENBO);
                        sendBw(info,false,FENBO,landBusinessTypeList,listinfos);
                        return false;
                    }
                    return true;
                    //todo:分拨运抵通知,重车入场视为运抵
                }else{
                    log.error("[分拨业务]-出场重量未通过校验:"+GROWSSEXCETION);
                    sendBw(info,false,GROWSSEXCETION,landBusinessTypeList,listinfos);
                    return false;
                }
            case "区内调拨":
            case "调拨业务":
                if (gatherInfoHandle.weightCheckHandleService.checkAllocateOrDispatch(growssWt, selfWt, goodsWt,inWt)){
                    /**
                     * 调拨业务如果空车出,可出.(就是申请不带运单的)
                     */
                    if (listinfos!=null && listinfos.isEmpty()){
                        log.info("[调拨-空车]-{}空车离场",info.getVename());
                        return true;
                    }

                    //白名单货物不检查放行
                    if (goodsWhiteListCheck()) {
                        return true;
                    }else{
                        //检查运单放行,拉板可出
                        if (gatherInfoHandle.resMessageService.checkManifestRelease(info,listinfos)){
                            return true;
                        }else {
                            //有运单未放行
                            log.error("[调拨业务]-出场未通过校验:"+FANGXING+landBusinessTypeList.getMasterList());
                            sendBw(info,false,FANGXING,landBusinessTypeList,listinfos);
                            return false;
                        }
                        //todo:检查ULD放行.
                    }

                }else{
                    log.error("[调拨业务]-出场未通过校验:"+GROWSSEXCETION);
                    sendBw(info,false,GROWSSEXCETION,landBusinessTypeList,listinfos);
                    return false;
                }
            default:
                log.error("[未知业务类型]-出场未通过校验");
                break;
        }

        return false;
    }

    /**
     * 记录进出区信息
     */
    private void record(){
        if ("I".equals(info.getIetype())){
            landBusinessTypeList.setAislewt(info.getGrosswt().doubleValue());
            landBusinessTypeList.setUpdateDate(new Date());
            landBusinessTypeList.setRemark(String.format("%.1f", goodsWt));
            //车辆备案重量
            landBusinessTypeList.setRemark2(String.valueOf(selfWt));
            landBusinessTypeList.setContrastflag("已进站");
        }else {
            landBusinessTypeList.setAislewt(info.getGrosswt().doubleValue());
            landBusinessTypeList.setUpdateDate(new Date());
            //装载货物总重量
            landBusinessTypeList.setRemark(String.format("%.1f", goodsWt));
            //进出差值
            landBusinessTypeList.setRemark1(String.format("%.1f", diffVal));
            landBusinessTypeList.setRemark2(String.valueOf(selfWt));
            landBusinessTypeList.setContrastflag("已出站");
        }

        //todo:判定放行后,插入数据库,出入区记录
        landBusinessTypeList.setId(UUID.randomUUID().toString());
        landBusinessTypeList.setIsvalid("1");
        //todo:这里SEQN也要入库
        gatherInfoHandle.listService.saveList(landBusinessTypeList);
    }

    /**
     * 核销记录
     */
    private void releaseRecord(){
        commandlog(info,true,"流转核销",landBusinessTypeList,null);
    }

    /**
     * 流转申请是否进行核销判定
     */
    private void releaseFormCheck(){
        List<LandBusinessTypeList> temp =  landBusinessTypeListList;
        //二维码已出区的记录
        List<LandBusinessTypeList> havenCrossList = gatherInfoHandle.listService.selectByBarcodeWithE(info.getBarcode());

        if (landBusinessTypeListList.isEmpty() && havenCrossList.isEmpty()){
            log.error("[releaseFormCheck-CACHE-CHECK]-车辆进出场对应申请缓存数据为空:{}",info.getBarcode());
            return;
        }

        //申请核销判定,已出区的记录与流转申请数据核碰.如果流转申请列表核碰完,还剩下的需要出区的场站则不核销.
        for (LandBusinessTypeList businessTypeList : havenCrossList) {
            List<LandBusinessTypeList> r =  landBusinessTypeListList.stream().filter(item ->{
                //判断还有没有没有出区的场站,还有没有出区的场站就不核销
                log.debug("[releaseFormCheck-Stream-loop]-缓存与已出核碰,缓存元素场站:[{}],已出记录场站:[{}]",item.getEndstation(),businessTypeList.getEndstation());
                //解决缓存那里存储有不一样的把人错的的有问题的点,二维码不一致也把缓存删除
                if (!item.getBarcode().equals(businessTypeList.getBarcode())){
                    return true;
                }
                 if(item.getEndstation().equals(businessTypeList.getEndstation())) {
                     log.info("[releaseFormCheck-Stream-loop]-缓存元素场站:[{}],已出记录场站:[{}]-核销判定对碰成功",item.getEndstation(),businessTypeList.getEndstation());
                     return true;
                 }else {
                     return false;
                 }
            })
            .collect(Collectors.toList());
            temp.removeAll(r);
        }
        log.info("[releaseFormCheck]-核销判定结果:{}",temp.size());
        if (temp.isEmpty()){
            //todo:流转申请状态核销
            log.info("[进出场申请]-流转申请开始核销:"+vaName);
            //二维码核销
            releaseBarCode();
            log.info("[进出场申请]-流转申请已核销:"+vaName);
        }

    }

    /**
     * 二维码失效核销->判定及失效通知.
     */
    private void releaseBarCode(){
        //是否有未驶离的流转记录二维码判定
        int count=gatherInfoHandle.listService.selectlaststation(info.getVename(),info.getBarcode());
        //二维码失效通知,已进入场站的与缓存比较.
        if(count==0){
            //todo:测试注释掉,二维码释放
            if (!gatherInfoHandle.debug){
                BuildBarCode.cancleBarCode(vaName);
                log.info("[流转申请]-二维码已释放:"+vaName);
            }

            int rc = gatherInfoHandle.landListDao.releaseBarcode(info.getBarcode());
            if (rc>0) {
                log.info("[进出场核销]-{}流转已核销:{}",vaName,info.getBarcode());
            }else{
                log.error("[进出场核销-ERROR]-{}流转未核销成功:{}",vaName,info.getBarcode());
            }
            //车辆流转申请缓存删除
            releaseCache();
        }else{
            log.error("[进出场核销-ERROR]-{}二维码应该核销,但是不符合核销条件:{}",vaName,info.getBarcode());
        }
    }

    private void releaseCache(){
        //车辆流转申请缓存删除
        gatherInfoHandle.redisService.del(info.getVename());
        //流转申请时生成的临时核碰场站代码列表
        gatherInfoHandle.redisService.del(info.getVename()+"_endstationList");
        //车辆过卡信息缓存删除-X22金二判定时候生成的这个缓存
        gatherInfoHandle.redisService.del(info.getSeqno());
        log.info("[流转缓存]-{}缓存已核销",vaName);
        //核销记录
        releaseRecord();
    }

    /**
     * todo:车单关系绑定报文
     */

    /**
     * 发送X22指令
     * @param info          过卡信息
     * @param check         true 抬杆,false 不抬杆
     * @param reason        原因
     * @param land          流转申请表头信息
     * @param list_infos    流转申请表体信息
     * @return              调试模式 直接返回true,生产模式按业务走
     */
    private boolean sendBw(GatherInfo info, boolean check, String reason, LandBusinessTypeList land, List<LAND_BUSINEESTYPE_LIST_INFO> list_infos) {
        //调试模式 直接返回true
        if (gatherInfoHandle.debug){
            if (check) {
                record();
                //总进出车次计数
                gatherInfoHandle.redisService.incr("kako-total",1);
            }
            commandlog(info,check,reason,land,list_infos);
            return check;
        }

        log.info(String.format("开始发送指令:车牌%s,场站%s,通道%s,重量%s",info.getVename(),info.getAreaid(),info.getChnlno(),info.getGrosswt()));
        boolean flag = false;
        if (check) {
            CommandClient.Client(info, PERMITTHOUGH);
            log.info("=============>>>>>>>>放行报文发送成功<<<<<<<<<==============");
            flag = true;
            record();

            //总进出车次计数
            gatherInfoHandle.redisService.incr("kako-total",1);
        } else {
            CommandClient.Client(info, reason);
            log.info("=============>>>>>>>>重量异常报文发送成功<<<<<<<<<==============");
        }
        commandlog(info,check,reason,land,list_infos);
        return flag;
    }

    /**
     * 直接放行
     */
    private void pass(){
        sendBw(info,true,PERMITTHOUGH,landBusinessTypeList,listinfos);
    }

    /**
     * 放行日志记录
     * @param info
     * @param check
     * @param reason
     * @param land
     * @param list_infos
     */
    private void commandlog(GatherInfo info,boolean check,String reason,LandBusinessTypeList land,List<LAND_BUSINEESTYPE_LIST_INFO> list_infos){
        String flag="",type="";
        commandLog command=new commandLog();
        command.setId(UUID.randomUUID().toString());
        command.setBarcode(info.getBarcode());

        if(land!=null){
            command.setBarcode(land.getBarcode());
            command.setBusnessType(land.getBusinesstype());
        }
        command.setAreaId(info.getAreaid());
        command.setChnlNo(info.getChnlno());
        if (check){
            flag = "00";
        } else{
            flag = "11";
        }
        if("I".equals(info.getIetype())){
            type="000000200000000000";
        }else{
            type="000000100000000000";
        }
        command.setReasonCode(flag+type);
        command.setReasonText(reason);
        command.setVeName(info.getVename());
        command.setVeWeight(selfWt);
        command.setIeType(info.getIetype());
        command.setExitGrossWeight(info.getGrosswt().doubleValue());
        command.setInGrossWeight(inWt);
        command.setGoodsWeight(goodsWt);
        command.setActualGoodsWeight(diffVal);
        if(list_infos !=null && list_infos.size()>0){
            command.setMasterList(Arrays.toString(toStrArry(list_infos)));
        }
        gatherInfoHandle.commandLogService.insert(command);
    }

    /**
     * 新舱单分拨申请数据查询
     * @param waybill 查询的运单号
     * @return
     */
    private Map nmmsAllocate(@NotNull String waybill){
        log.info("新舱单查询分拨申请数据开始");
        Feign_Allocate_Search feignAllocateSearch = new Feign_Allocate_Search(waybill,0,10);
        Map map = gatherInfoHandle.nmmsService.getAllocate(feignAllocateSearch);
        log.info(""+map);
        return map;
    }


    /**
     * 分拨申请查询
     * @param waybill
     * @return
     */
    private boolean checkNmmsAllocate(String waybill){
        if (waybill.length() < 1) {
            return false;
        }
        if (gatherInfoHandle.debug){
            return true;
        }
        waybill = waybill.replace("-", "");
        //中文逗号替换
        waybill = waybill.replace(",", ",");
        String[] maifest = waybill.split(",");
        log.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 {
                    log.info("运单:{}分拨申请回执未查询到,或未进行分拨申请",awb);
                    return false;
                }
            }else{
                log.info("运单:{}分拨申请回执未查询到,或未进行分拨申请",awb);
                return false;
            }

        }
        return true;
    }
}