package com.sckw.transport.service.app;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.sckw.contract.api.RemoteContractService;
import com.sckw.contract.api.model.vo.KwcContractLogisticsDto;
import com.sckw.core.common.enums.enums.DictTypeEnum;
import com.sckw.core.common.enums.enums.ErrorCodeEnum;
import com.sckw.core.exception.BusinessPlatfromException;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.enums.CarWaybillV1Enum;
import com.sckw.core.model.enums.ForkliftStatusEnum;
import com.sckw.core.model.enums.GatekeeperStatusEnum;
import com.sckw.core.model.enums.GatekeeperTypeEnum;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.utils.DateUtils;
import com.sckw.core.utils.StringUtils;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.core.web.response.result.PageDataResult;
import com.sckw.fleet.api.RemoteFleetService;
import com.sckw.fleet.api.model.vo.RTruckVo;
import com.sckw.order.api.dubbo.TradeOrderInfoService;
import com.sckw.order.api.model.OrderUnitInfoDetailVO;
import com.sckw.product.api.dubbo.GoodsInfoService;
import com.sckw.product.api.model.KwpGoods;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.model.dto.res.KwsUserResDto;
import com.sckw.transport.model.*;
import com.sckw.transport.model.enuma.WeighbridgeTypeEnum;
import com.sckw.transport.model.param.forklift.reponse.GatekeeperOrderResp;
import com.sckw.transport.model.param.forklift.request.GatekeeperOrderIsPassParam;
import com.sckw.transport.model.param.forklift.request.GatekeeperOrderPassParam;
import com.sckw.transport.model.param.forklift.request.GatekeeperOrderPassReasonParam;
import com.sckw.transport.model.param.forklift.request.GatekeeperOrderQueryParam;
import com.sckw.transport.model.vo.StatisticsWaybillResp;
import com.sckw.transport.repository.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Author: donglang
 * Time: 2026-01-05
 * Des: 铲车司机Service
 * Version: 1.0
 */

@Slf4j
@Service
@RequiredArgsConstructor
public class GatekeeperOrderService {


    private final KwtGatekeeperWaybillOrderRepository gatekeeperWaybillOrderRepository;
    private final KwtForkliftWaybillOrderRepository forkliftWaybillOrderRepository;
    private final KwtWaybillOrderRepository waybillOrderRepository;
    private final KwtWaybillOrderSubtaskRepository waybillOrderSubtaskRepository;
    private final KwtWaybillOrderTicketRepository waybillOrderTicketRepository;
    private final KwtLogisticsOrderRepository logisticsOrderRepository;
    private final KwtLogisticsOrderGoodsRepository logisticsOrderGoodsRepository;
    private final KwtLogisticsOrderContractRepository logisticsOrderContractRepository;
    private final KwtWaybillOrderNodeRepository waybillOrderNodeRepository;
    private final KwtWaybillOrderWeighbridgeRepository waybillOrderWeighbridgeRepository;
    @Autowired
    protected KwtLogisticsOrderUnitRepository logisticsOrderUnitRepository;

    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteContractService remoteContractService;

    @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 80000)
    TradeOrderInfoService tradeOrderInfoService;

    @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
   RemoteSystemService remoteSystemService;

    @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
    GoodsInfoService goodsInfoService;

    @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
    protected RemoteFleetService remoteFleetService;


    @Autowired
    WaybillOrderService waybillOrderService;

    /**
     * 分页查询门卫订单
     * @param param
     * @return
     */
    public PageDataResult<GatekeeperOrderResp> pageQueryGatekeeperOrder(GatekeeperOrderQueryParam param) {
        log.info("查询门卫订单：{}", JSON.toJSONString(param));
        if (param.getStatus() == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "状态不能为空！");
        }

        //构建查询条件
        LambdaQueryWrapper<KwtGatekeeperWaybillOrder> wrapper = buildAndExecuteQuery(param);
        sort(param, wrapper);

        //查询门卫订单
        Page<KwtGatekeeperWaybillOrder> pageByStatus = gatekeeperWaybillOrderRepository.page(new Page<>(param.getPageNum(), param.getPageSize()), wrapper);
        List<KwtGatekeeperWaybillOrder> records = pageByStatus.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            log.info("当前无运单订单信息");
            return PageDataResult.empty(param.getPageNum(), param.getPageSize());
        }
        List<GatekeeperOrderResp> gatekeeperOrderPageResult = getGatekeeperOrderPageResult(records);
        //处理异常车辆数据
        gatekeeperOrderPageResult = filterGatekeeperOrderResp(param, gatekeeperOrderPageResult);
        //过滤山上/山下门卫数据
        List<GatekeeperOrderResp> filterResult = filter(gatekeeperOrderPageResult);

        return PageDataResult.success(param.getPageNum(), param.getPageSize(), pageByStatus.getTotal(), filterResult);
    }

    /**
     * 内存排序 + 内存分页
     */
    private PageDataResult<GatekeeperOrderResp> pageQueryWithMemorySort(GatekeeperOrderQueryParam param) {
        //构建查询条件
        LambdaQueryWrapper<KwtGatekeeperWaybillOrder> wrapper = buildAndExecuteQuery(param);

        //查询门卫订单
        List<KwtGatekeeperWaybillOrder> records = gatekeeperWaybillOrderRepository.list(wrapper);
        if (CollectionUtils.isEmpty(records)) {
            log.info("当前无运单订单信息");
            return PageDataResult.empty(param.getPageNum(), param.getPageSize());
        }
        List<GatekeeperOrderResp> gatekeeperOrderPageResult = getGatekeeperOrderPageResult(records);

        //处理异常车辆数据
        gatekeeperOrderPageResult = filterGatekeeperOrderResp(param, gatekeeperOrderPageResult);

        //过滤山上/山下门卫数据
        List<GatekeeperOrderResp> filterResult = filter(gatekeeperOrderPageResult);

        //排序
        sort2(param, filterResult);

        List<List<GatekeeperOrderResp>> pageList = Lists.partition(gatekeeperOrderPageResult, param.getPageSize());
        List<GatekeeperOrderResp> walletPageList = pageList.size() >= param.getPageNum() ?
                pageList.get(param.getPageNum() - 1) : Collections.emptyList();

        return PageDataResult.success(param.getPageNum(), param.getPageSize(), (long) walletPageList.size(), gatekeeperOrderPageResult);
    }


    /**
     * 构建查询条件并执行分页查询
     */
    private LambdaQueryWrapper<KwtGatekeeperWaybillOrder> buildAndExecuteQuery(GatekeeperOrderQueryParam param) {
        //基础查询条件
        LambdaQueryWrapper<KwtGatekeeperWaybillOrder> queryWrapper = buildBaseQueryWrapper(param);

        //模糊查询条件
        handleSearchKeyword(param, queryWrapper);
        return queryWrapper;

    }

    /**
     * 构建基础查询条件
     * @param param
     * @return
     */
    private  LambdaQueryWrapper<KwtGatekeeperWaybillOrder> buildBaseQueryWrapper(GatekeeperOrderQueryParam param) {
        LambdaQueryWrapper<KwtGatekeeperWaybillOrder> wrapper = Wrappers.<KwtGatekeeperWaybillOrder>lambdaQuery()
                .eq(KwtGatekeeperWaybillOrder::getEntId, param.getEntId());

        //待进场
        if (param.getStatus() == 1) {
            wrapper.eq(KwtGatekeeperWaybillOrder::getStatus, GatekeeperStatusEnum.PENDING_ENTRY.getCode());
            //待离场
        } else if (param.getStatus() == 2) {
            wrapper.in(KwtGatekeeperWaybillOrder::getStatus,
                    GatekeeperStatusEnum.PENDING_RELEASE.getCode(),
                    GatekeeperStatusEnum.READY_RELEASE.getCode());
            //场内车辆，状态为4是：处理场内异常车辆逻辑
        } else if (param.getStatus() == 3 || param.getStatus() == 4) {
            wrapper.in(KwtGatekeeperWaybillOrder::getStatus,
                    GatekeeperStatusEnum.IN_YARD.getCode(),
                    GatekeeperStatusEnum.PENDING_RELEASE.getCode(),
                    GatekeeperStatusEnum.READY_RELEASE.getCode());
            //出入记录
        } else if (param.getStatus() == 5) {
            wrapper.in(KwtGatekeeperWaybillOrder::getStatus,
                    GatekeeperStatusEnum.EXITED.getCode(),
                    GatekeeperStatusEnum.EMPTY_EXITED.getCode());
        }
        return wrapper;
    }

    /**
     * 关键词模糊查询
     */
    private void handleSearchKeyword(GatekeeperOrderQueryParam param, LambdaQueryWrapper<KwtGatekeeperWaybillOrder> wrapper) {
        if (StringUtils.isBlank(param.getKeyWords())) {
            return;
        }
        Set<Long> matchedWaybillOrderIds = findMatchedGatekeeperOrderIds(param);
        if (CollectionUtils.isEmpty(matchedWaybillOrderIds)) {
            log.info("模糊查询无匹配结果，关键词：{}", param.getKeyWords());
            // 设置一个不可能的条件，确保返回空结果
            wrapper.eq(KwtGatekeeperWaybillOrder::getId, Global.MINUS_ONE);
        } else {
            wrapper.in(KwtGatekeeperWaybillOrder::getId, matchedWaybillOrderIds);
        }
    }

    /**
     * 查询匹配的运单ID（以铲车ID为主键）
     */
    private Set<Long> findMatchedGatekeeperOrderIds(GatekeeperOrderQueryParam param) {
        Set<Long> gatekeeperOrderIds = ConcurrentHashMap.newKeySet();;
        List<Runnable> searchTasks = Arrays.asList(
                //1. 运单编号查询（主表字段，直接匹配）
                () -> addMatchedIds(gatekeeperOrderIds, param),

                //2. 车牌号、司机姓名查询
                () -> addMatchedIdsFromWaybillNo(gatekeeperOrderIds, param),

                // 3. 客户名称查询
                () -> addMatchedIdsFromLogisticsOrderNo(gatekeeperOrderIds, param)
        );
        // 使用并行流执行查询任务
        searchTasks.parallelStream().forEach(Runnable::run);
        return gatekeeperOrderIds;
    }

    /**
     * 运单编号查询
     * @param gatekeeperOrderIds
     * @param param
     */
    private void addMatchedIds(Set<Long> gatekeeperOrderIds, GatekeeperOrderQueryParam param) {
        // 1. 运单编号查询（主表字段，直接匹配）
        List<KwtGatekeeperWaybillOrder> gatekeeperWaybillOrder = gatekeeperWaybillOrderRepository.list(
                Wrappers.<KwtGatekeeperWaybillOrder>lambdaQuery()
                        .like(KwtGatekeeperWaybillOrder::getWOrderNo, param.getKeyWords())
        );
        gatekeeperOrderIds.addAll(gatekeeperWaybillOrder.stream()
                .map(KwtGatekeeperWaybillOrder::getId)
                .collect(Collectors.toSet()));
    }

    /**
     * 车牌号、司机姓名查询
     * @param gatekeeperOrderIds
     * @param param
     */
    private void addMatchedIdsFromWaybillNo(Set<Long> gatekeeperOrderIds, GatekeeperOrderQueryParam param) {
        List<KwtWaybillOrder> waybillOrders = waybillOrderRepository.list(
                Wrappers.<KwtWaybillOrder>lambdaQuery()
                        .like(KwtWaybillOrder::getTruckNo, param.getKeyWords())
                        .or()
                        .like(KwtWaybillOrder::getDriverName, param.getKeyWords())
                        .eq(KwtWaybillOrder::getDelFlag, 0)
        );
        if (CollectionUtils.isNotEmpty(waybillOrders)) {
            List<Long> matchedWaybillOrderIds = waybillOrders.stream()
                    .map(KwtWaybillOrder::getId)
                    .collect(Collectors.toList());

            // 查询这些物流运单对应的铲车订单
            List<KwtGatekeeperWaybillOrder> gatekeeperOrderList = gatekeeperWaybillOrderRepository
                    .queryGatekeeperWaybillOrderByWOrderIds(matchedWaybillOrderIds);

            gatekeeperOrderIds.addAll(gatekeeperOrderList.stream()
                    .map(KwtGatekeeperWaybillOrder::getId)
                    .collect(Collectors.toSet()));
        }
    }


    /**
     * 从企业名称查询贸易订单关联的铲车订单
     */
    private void addMatchedIdsFromLogisticsOrderNo(Set<Long> gatekeeperOrderIds, GatekeeperOrderQueryParam param) {
        // 从企业名称查询贸易订单
        List<OrderUnitInfoDetailVO> orderUnitInfoDetailVOS = tradeOrderInfoService.queryOrderUnitInfByEntName(param.getKeyWords());

        if (CollectionUtils.isEmpty(orderUnitInfoDetailVOS)) {
            return;
        }
        Set<Long> tOrderIds = orderUnitInfoDetailVOS.stream()
                .map(OrderUnitInfoDetailVO::getTOrderId)
                .collect(Collectors.toSet());

        // 通过贸易订单查询关联的物流订单
        List<KwtLogisticsOrder> logisticsOrders = logisticsOrderRepository.queryByTradeOrderIds(tOrderIds);
        if (CollectionUtils.isNotEmpty(logisticsOrders)) {
            List<Long> logOrderIds = logisticsOrders.stream()
                    .map(KwtLogisticsOrder::getId)
                    .collect(Collectors.toList());

            // 查询这些物流订单对应的铲车订单
            List<KwtGatekeeperWaybillOrder> gatekeeperOrderList = gatekeeperWaybillOrderRepository
                    .queryGatekeeperWaybillOrderByLogOrderIds(logOrderIds);

            gatekeeperOrderIds.addAll(gatekeeperOrderList.stream()
                    .map(KwtGatekeeperWaybillOrder::getId)
                    .collect(Collectors.toSet()));
        }

    }

    /**
     * 获取门卫订单数据
     * @param records
     * @return
     */
    private List<GatekeeperOrderResp> getGatekeeperOrderPageResult(List<KwtGatekeeperWaybillOrder> records) {
        log.info("开始门卫订单查询，param:{}", JSON.toJSONString(records));
        Set<Long> wOrderIds = records.stream().map(KwtGatekeeperWaybillOrder::getWOrderId)
                .filter(Objects::nonNull).collect(Collectors.toSet());
        //查询运单
        List<KwtWaybillOrder> waybillOrders = waybillOrderRepository.queryByBillOrderIds(wOrderIds);
        if (CollectionUtils.isEmpty(waybillOrders)) {
            log.info("【门卫】无物流运单信息，运单id:{}", JSON.toJSONString(wOrderIds));
            return Collections.emptyList();
        }
        Map<Long, KwtWaybillOrder> waybillOrderMap = waybillOrders.stream()
                .collect(Collectors.toMap(KwtWaybillOrder::getId, Function.identity(), (x, y) -> x));

        Set<Long> lOrderIds = waybillOrders.stream().map(KwtWaybillOrder::getLOrderId)
                .filter(Objects::nonNull).collect(Collectors.toSet());

        //查询运单装卸货
        List<KwtWaybillOrderTicket> waybillOrderTickets = waybillOrderTicketRepository.queryByWOrderIds(new ArrayList<>(wOrderIds));
        if (CollectionUtils.isEmpty(waybillOrderTickets)) {
            log.info("【门卫】无运单装卸货信息，运单id:{}", JSON.toJSONString(wOrderIds));
            return Collections.emptyList();
        }
        Map<String, KwtWaybillOrderTicket> waybillOrderTicketMap = waybillOrderTickets.stream()
                .collect(Collectors.toMap(ticket -> ticket.getWOrderId() + "-" + ticket.getType(), Function.identity(), (x, y) -> x));

        //查询物流订单
        List<KwtLogisticsOrder> logisticsOrder = logisticsOrderRepository.queryByLogOrderIds(lOrderIds);
        if (CollectionUtils.isEmpty(logisticsOrder)) {
            log.info("【门卫】无物流订单信息，物流订单id:{}", JSON.toJSONString(lOrderIds));
            return Collections.emptyList();
        }

        // 按照order_type区分“正常订单”和“原矿运输订单”
        Map<Boolean, List<KwtLogisticsOrder>> partitionedMap = logisticsOrder.stream()
                .collect(Collectors.partitioningBy(order -> Integer.valueOf(1).equals(order.getOrderType())));

        List<KwtLogisticsOrder> typeNullList = partitionedMap.get(false);
        List<KwtLogisticsOrder> typeOneList = partitionedMap.get(true);
        log.info("正常流程订单信息: {}，数量:{}, 原矿运输订单信息: {}，数量:{}",  JSON.toJSONString(typeNullList), typeNullList.size(),
                JSON.toJSONString(typeOneList), typeOneList.size());

        List<GatekeeperOrderResp> resultList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(typeNullList)) {
            Set<Long> tOrderIds = typeNullList.stream().map(KwtLogisticsOrder::getTOrderId).collect(Collectors.toSet());
            List<OrderUnitInfoDetailVO> orderUnitVOS = tradeOrderInfoService.queryOrderUnitInfByTOrderId(tOrderIds);
            if (CollectionUtils.isEmpty(orderUnitVOS)) {
                log.info("【门卫】无贸易订单企业信息，贸易订单id:{}", JSON.toJSONString(tOrderIds));
                return Collections.emptyList();
            }
            //查询贸易订单企业信息
            Map<String, OrderUnitInfoDetailVO> tradeOrderAndUnit = orderUnitVOS.stream().collect(Collectors
                    .toMap(unit -> unit.getTOrderId() + "-" + unit.getUnitType(),
                            Function.identity(), (x, y) -> x));

            //组装正常流程门卫订单数据
            Set<Long> lOrderId = typeNullList.stream().map(KwtLogisticsOrder::getId).collect(Collectors.toSet());
            List<GatekeeperOrderResp> gatekeeperOrderResp = records.stream()
                    .filter(x -> lOrderId.contains(x.getLOrderId()))
                    .map(gatekeeperWaybillOrder -> buildGatekeeperOrderResp(gatekeeperWaybillOrder,
                            waybillOrderMap, waybillOrderTicketMap, typeNullList, tradeOrderAndUnit, Boolean.FALSE))
                    .collect(Collectors.toList());
            resultList.addAll(gatekeeperOrderResp);
        }

        if (CollectionUtils.isNotEmpty(typeOneList)) {
            //组装原矿运输门卫订单数据
            Set<Long> lOrderId = typeOneList.stream().map(KwtLogisticsOrder::getId).collect(Collectors.toSet());
            List<GatekeeperOrderResp> rawOreGatekeeperOrderResp = records.stream()
                    .filter(x -> lOrderId.contains(x.getLOrderId()))
                    .map(gatekeeperWaybillOrder -> buildGatekeeperOrderResp(gatekeeperWaybillOrder,
                            waybillOrderMap, waybillOrderTicketMap, typeOneList, Collections.emptyMap(), Boolean.TRUE))
                    .collect(Collectors.toList());
            resultList.addAll(rawOreGatekeeperOrderResp);
        }

        log.info("门卫订单查询结束，result:{}", JSON.toJSONString(resultList));
        return resultList;

    }

    /**
     * 组装门卫订单信息
     * @param gatekeeperWaybillOrder
     * @param waybillOrderMap

     * @return
     */
    private GatekeeperOrderResp buildGatekeeperOrderResp(KwtGatekeeperWaybillOrder gatekeeperWaybillOrder,
                                                         Map<Long, KwtWaybillOrder> waybillOrderMap,
                                                         Map<String, KwtWaybillOrderTicket> waybillOrderTicketMap,
                                                         List<KwtLogisticsOrder> logisticsOrder,
                                                         Map<String, OrderUnitInfoDetailVO> tradeOrderAndUnit,
                                                         boolean isRawOre) {
        log.info("开始{}门卫订单查询，param:{}", isRawOre ? "原矿运输" : "正常流程", JSON.toJSONString(gatekeeperWaybillOrder));
        GatekeeperOrderResp gatekeeper = new GatekeeperOrderResp();
        gatekeeper.setId(gatekeeperWaybillOrder.getId());
        gatekeeper.setEntId(gatekeeperWaybillOrder.getEntId());
        gatekeeper.setWaybillOrderNo(gatekeeperWaybillOrder.getWOrderNo());
        gatekeeper.setWaybillOrderId(gatekeeperWaybillOrder.getWOrderId());
        gatekeeper.setLogisticsOrderId(gatekeeperWaybillOrder.getLOrderId());
        gatekeeper.setStatus(gatekeeperWaybillOrder.getStatus());
        gatekeeper.setType(gatekeeperWaybillOrder.getType());
        gatekeeper.setTypeDesc(GatekeeperTypeEnum.getDesc(gatekeeperWaybillOrder.getType()));
        String statusDesc = Objects.equals(gatekeeperWaybillOrder.getType(), GatekeeperTypeEnum.LOADING.getCode())
                ? GatekeeperStatusEnum.getDesc(gatekeeperWaybillOrder.getStatus())
                : GatekeeperStatusEnum.getDescription(gatekeeperWaybillOrder.getStatus());
        gatekeeper.setStatusDesc(statusDesc);
        gatekeeper.setCarAxisName(gatekeeperWaybillOrder.getCarAxis());
        gatekeeper.setLegalLoad(gatekeeperWaybillOrder.getLegalLoad());
        gatekeeper.setTruckType(gatekeeperWaybillOrder.getTruckType());
        gatekeeper.setIntoTime(gatekeeperWaybillOrder.getIntoTime());
        gatekeeper.setLeaveTime(gatekeeperWaybillOrder.getLeaveTime());
        gatekeeper.setWaybillAcceptTime(gatekeeperWaybillOrder.getWaybillAcceptTime());
        gatekeeper.setEntrustAmount(gatekeeperWaybillOrder.getEntrustAmount());
        gatekeeper.setGoodsId(gatekeeperWaybillOrder.getGoodsId());
        gatekeeper.setGoodsName(gatekeeperWaybillOrder.getGoodsName());
        gatekeeper.setRemark(gatekeeperWaybillOrder.getRemark());
        gatekeeper.setWeighbridgeId(gatekeeperWaybillOrder.getWeighbridgeId());

        //运单数据
        KwtWaybillOrder waybillOrder = waybillOrderMap.getOrDefault(gatekeeperWaybillOrder.getWOrderId(), new KwtWaybillOrder());
        gatekeeper.setTruckId(waybillOrder.getTruckId());
        gatekeeper.setTruckNo(waybillOrder.getTruckNo());
        gatekeeper.setName(waybillOrder.getDriverName());
        gatekeeper.setPhone(waybillOrder.getDriverPhone());
        gatekeeper.setIdCard(waybillOrder.getDriverIdcard());

        //装卸货信息
        KwtWaybillOrderTicket ticket = waybillOrderTicketMap.getOrDefault(gatekeeperWaybillOrder.getWOrderId() + "-" + 1, new KwtWaybillOrderTicket());
        gatekeeper.setTareAmount(ticket.getTareAmount());
        gatekeeper.setGrossAmount(ticket.getGrossAmount());

        //获取当前物流订单
        KwtLogisticsOrder logOrder = logisticsOrder.stream()
                .filter(log -> Objects.equals(log.getId(), gatekeeperWaybillOrder.getLOrderId()))
                .findFirst().orElse(new KwtLogisticsOrder());
        // 正常流程
        if (!isRawOre) {
            //采购企业信息
            OrderUnitInfoDetailVO orderUnit = tradeOrderAndUnit.getOrDefault(logOrder.getTOrderId() + "-" + 1, new OrderUnitInfoDetailVO());
            gatekeeper.setPrEntId(orderUnit.getEntId());
            gatekeeper.setPrEntName(orderUnit.getFirmName());
        }

        // 原矿运输
        if (isRawOre && Objects.equals(gatekeeperWaybillOrder.getType(),2)) {
            //装货净重
            BigDecimal loadAmount = ticket.getAmount();
            //卸货净重
            KwtWaybillOrderTicket unloadTicket = waybillOrderTicketMap.getOrDefault(gatekeeperWaybillOrder.getWOrderId() + "-" + 2, new KwtWaybillOrderTicket());
            BigDecimal unloadAmount = unloadTicket.getAmount();
            gatekeeper.setUnloadAmount(unloadAmount);
            gatekeeper.setUnloadingTareAmount(unloadTicket.getTareAmount());
            gatekeeper.setUnloadingGrossAmount(unloadTicket.getGrossAmount());

            //计算货损率
            BigDecimal lossRate = calculateLossRate(loadAmount, unloadAmount);
            gatekeeper.setLossRate(lossRate);
            gatekeeper.setIsPassReason(isLossRateExceeded(logOrder, lossRate));
        }

        gatekeeper.setOrderType(logOrder.getOrderType());
        gatekeeper.setOrderTypeDesc(Objects.equals(logOrder.getOrderType(), 1) ? "原矿运输" : "产品销售");

        log.info("{}门卫订单查询结束，param:{}", isRawOre ? "原矿运输" : "正常流程", JSON.toJSONString(gatekeeperWaybillOrder));
        return gatekeeper;
    }

    /**
     * 计算货损率
     */
    private static BigDecimal calculateLossRate(BigDecimal loadAmount, BigDecimal unloadAmount) {
        log.info("[门卫]开始计算货损率，装货净重:{}，卸货净重：{}", JSON.toJSONString(loadAmount), JSON.toJSONString(loadAmount));
        BigDecimal lossRate = BigDecimal.ZERO;
        if (loadAmount != null && unloadAmount != null && loadAmount.compareTo(BigDecimal.ZERO) > 0) {
             lossRate = loadAmount.subtract(unloadAmount)
                    .divide(loadAmount, 4, RoundingMode.HALF_UP)
                    .setScale(2, RoundingMode.HALF_UP);
            return lossRate;
        }
        log.info("[门卫]计算货损率完成，货损率:{}", JSON.toJSONString(lossRate));
        return lossRate;

    }

    /**
     * 校验货损率是否超过千分之三
     */
    private boolean isLossRateExceeded(KwtLogisticsOrder logOrder, BigDecimal lossRate) {
        log.info("[门卫]开始计算货损率是否超过配置值，物流订单:{}，货损率：{}", JSON.toJSONString(logOrder), JSON.toJSONString(lossRate));
        KwtLogisticsOrderContract orderContract = logisticsOrderContractRepository.queryByLogOrderId(logOrder.getId());
        if (orderContract == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_CONTRACT_NOT_FOUND, "物流订单无合同数据！");
        }
        KwcContractLogisticsDto contractLogisticsDto = remoteContractService.queryContractByContractId(orderContract.getContractId());
        if (contractLogisticsDto == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.DATA_NOT_EXIST, "物流合同不存在！");
        }
        if (contractLogisticsDto.getAllowedError() == null || contractLogisticsDto.getAllowedError().compareTo(BigDecimal.ZERO) <= 0) {
            return false;
        }
        // 查询出来的货损率为5，表示千分之5，需除以1000
        BigDecimal allowedError = contractLogisticsDto.getAllowedError().divide(new BigDecimal("1000"), 6, RoundingMode.HALF_UP);

        log.info("[门卫]计算货损率是否超过配置值完成，配置的货损率：{}", JSON.toJSONString(allowedError));
        return lossRate.compareTo(allowedError) > 0;
    }

    /**
     * 处理异常车辆数据
     * @param param
     * @param gatekeeperOrderPageResult
     * @return
     */
    private static List<GatekeeperOrderResp> filterGatekeeperOrderResp(GatekeeperOrderQueryParam param, List<GatekeeperOrderResp> gatekeeperOrderPageResult) {
        double configHours = 3;
        //处理异常车辆数据
        if (param.getStatus() != 4) {
            return gatekeeperOrderPageResult;
        }
        return gatekeeperOrderPageResult.stream().filter(order -> {
            if (order.getIntoTime() == null) {
                return false;
            }
            // 计算已停留小时数
            double stayHours = DateUtils.hoursBetween(order.getIntoTime(), new Date());
            order.setDurationTime(stayHours);
            return stayHours > configHours;
        }).collect(Collectors.toList());
    }

    /**
     * 过滤山上/山下门卫数据：待放行时候区分
     * @param gatekeeperOrderPageResult
     */
    private List<GatekeeperOrderResp> filter(List<GatekeeperOrderResp> gatekeeperOrderPageResult) {
        Long userId = LoginUserHolder.getUserId();
        log.info("门卫用户id:{}", userId);
        KwsUserResDto kwsUserResDto = remoteSystemService.queryByUserId(userId);
        log.info("门卫用户信息:{}", JSON.toJSONString(kwsUserResDto));
        if (kwsUserResDto == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "用户数据不能为空！");
        }

        return gatekeeperOrderPageResult.stream()
                .filter(order -> {
                    // status不等于10的订单，不做地磅过滤
                    if (!Objects.equals(order.getStatus(), 10)) {
                        return true;
                    }
                    // 地磅为空的数据，山上山下都保留
                    Long weighbridgeId = order.getWeighbridgeId();
                    if (weighbridgeId == null) {
                        return true;
                    }
                    // 山下（邓总）：只保留 10100111L
                    if (Objects.equals(kwsUserResDto.getType(), 1)) {
                        return weighbridgeId == 10100111L;
                    }
                    // 山上：只保留 10100112L 或 10100113L
                    return weighbridgeId == 10100112L || weighbridgeId == 10100113L;
                })
                .collect(Collectors.toList());
    }

    /**
     * 排序
     * @param param
     * @param wrapper
     */
    private void sort(GatekeeperOrderQueryParam param, LambdaQueryWrapper<KwtGatekeeperWaybillOrder> wrapper) {
        log.info("门卫订单排序，param:{}", JSON.toJSONString(param), JSON.toJSONString(param));
        // 根据状态进行排序
        switch (param.getStatus()) {
            case 1:
                // 待进场: 运输司机接单时间升序
                wrapper.orderByAsc(KwtGatekeeperWaybillOrder::getWaybillAcceptTime);
                break;
            case 2:
                //待离场:未放行数据按照司机点击离场数据升序
                wrapper.orderByAsc(KwtGatekeeperWaybillOrder::getUpdateTime);
                break;
            case 3:
                // 场内车辆: 车辆进场时间升序
                wrapper.orderByAsc(KwtGatekeeperWaybillOrder::getIntoTime);
                break;
            case 4:
                // 异常车辆: 场内耗时倒序
                wrapper.orderByAsc(KwtGatekeeperWaybillOrder::getIntoTime);
                break;
            case 5:
                // 出入记录: 离场时间倒序
                wrapper.orderByDesc(KwtGatekeeperWaybillOrder::getLeaveTime);
                break;
            default:
                break;
        }
    }

    /**
     * 排序
     * @param param
     * @param gatekeeperOrderPageResult
     */
    private void sort2(GatekeeperOrderQueryParam param, List<GatekeeperOrderResp> gatekeeperOrderPageResult) {
        log.info("门卫订单内存排序，param:{}, order:{}", JSON.toJSONString(param), JSON.toJSONString(gatekeeperOrderPageResult));
        if (CollectionUtils.isEmpty(gatekeeperOrderPageResult)) {
            return;
        }
        // 根据状态进行排序
        switch (param.getStatus()) {
            case 4:
                // 异常车辆: 场内耗时倒序
                gatekeeperOrderPageResult.sort(Comparator.comparing(GatekeeperOrderResp::getDurationTime).reversed());
                break;
            default:
                break;
        }
    }

    /**
     * 铲车订单状态统计
     * @param param
     * @return
     */
    public StatisticsWaybillResp statisticsGatekeeperOrder(GatekeeperOrderQueryParam param) {
        log.info("门卫订单统计：{}", JSON.toJSONString(param));
        StatisticsWaybillResp resp = new StatisticsWaybillResp();

        LambdaQueryWrapper<KwtGatekeeperWaybillOrder> wrapper = Wrappers.<KwtGatekeeperWaybillOrder>lambdaQuery()
                .eq(KwtGatekeeperWaybillOrder::getEntId, param.getEntId())
                .orderByDesc(KwtGatekeeperWaybillOrder::getCreateTime);

        //查询门卫订单
        List<KwtGatekeeperWaybillOrder> orderList = gatekeeperWaybillOrderRepository.list(wrapper);
        log.info("查询门卫订单, size:{}", orderList.size());
        if (CollectionUtils.isEmpty(orderList)) {
            log.info("当前无门卫统计记录，统计结果为空");
            resp.setOrderStatusStatistics(buildDefaultStatusStatistics());
            return resp;
        }
        //过滤山上/山下门卫数据
        List<KwtGatekeeperWaybillOrder> filterResult = filterGatekeeper(orderList);
        resp.setOrderStatusStatistics(calculateStatusStatistics(filterResult));
        return resp;

    }

    /**
     * 构建默认的状态统计列表（三种状态，数量均为0）
     * @return 默认统计列表
     */
    private List<StatisticsWaybillResp.OrderBillStatusStatistics> buildDefaultStatusStatistics() {
        List<StatisticsWaybillResp.OrderBillStatusStatistics> defaultList = new ArrayList<>();
        // 待进场
        StatisticsWaybillResp.OrderBillStatusStatistics pendingEntry = new StatisticsWaybillResp.OrderBillStatusStatistics();
        pendingEntry.setOrderStatus("1");
        pendingEntry.setOrderStatusDesc("待进场");
        pendingEntry.setOrderNum("0");
        defaultList.add(pendingEntry);
        // 待离场
        StatisticsWaybillResp.OrderBillStatusStatistics pendingExit = new StatisticsWaybillResp.OrderBillStatusStatistics();
        pendingExit.setOrderStatus("2");
        pendingExit.setOrderStatusDesc("待离场");
        pendingExit.setOrderNum("0");
        defaultList.add(pendingExit);
        // 场内车辆
        StatisticsWaybillResp.OrderBillStatusStatistics inPark = new StatisticsWaybillResp.OrderBillStatusStatistics();
        inPark.setOrderStatus("3");
        inPark.setOrderStatusDesc("场内车辆");
        inPark.setOrderNum("0");
        defaultList.add(inPark);
        // 异常车辆
        StatisticsWaybillResp.OrderBillStatusStatistics isAbnormal = new StatisticsWaybillResp.OrderBillStatusStatistics();
        isAbnormal.setOrderStatus("4");
        isAbnormal.setOrderStatusDesc("异常车辆");
        isAbnormal.setOrderNum("0");
        defaultList.add(isAbnormal);

        return defaultList;
    }

    /**
     * 过滤山上/山下门卫数据：待放行时候区分
     * @param gatekeeperOrderPageResult
     */
    private List<KwtGatekeeperWaybillOrder> filterGatekeeper(List<KwtGatekeeperWaybillOrder> gatekeeperOrderPageResult) {
        Long userId = LoginUserHolder.getUserId();
        log.info("门卫用户id:{}", userId);
        KwsUserResDto kwsUserResDto = remoteSystemService.queryByUserId(userId);
        log.info("门卫用户信息:{}", JSON.toJSONString(kwsUserResDto));
        if (kwsUserResDto == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "用户数据不能为空！");
        }

        return gatekeeperOrderPageResult.stream()
                .filter(order -> {
                    // status不等于10的订单，不做地磅过滤
                    if (!Objects.equals(order.getStatus(), 10)) {
                        return true;
                    }
                    // 地磅为空的数据，山上山下都保留
                    Long weighbridgeId = order.getWeighbridgeId();
                    if (weighbridgeId == null) {
                        return true;
                    }
                    // 山下（邓总）：只保留 10100111L
                    if (Objects.equals(kwsUserResDto.getType(), 1)) {
                        return weighbridgeId == 10100111L;
                    }
                    // 山上：只保留 10100112L 或 10100113L
                    return weighbridgeId == 10100112L || weighbridgeId == 10100113L;
                })
                .collect(Collectors.toList());
    }

    /**
     * 计算运单状态统计
     * @param orderList
     * @return
     */
    private static List<StatisticsWaybillResp.OrderBillStatusStatistics> calculateStatusStatistics(List<KwtGatekeeperWaybillOrder> orderList) {
        log.info("开始统计计算,param：{}", orderList.size());
        //车辆停留超时配置
        double configHours = 2000;

        // 定义状态码聚合规则
        Map<String[], List<String>> aggregateRules = Map.of(
                new String[]{"1", "待进场"}, Arrays.asList("1"),
                new String[]{"2", "待离场"}, Arrays.asList("10", "15"),
                new String[]{"3", "场内车辆"}, Arrays.asList("5", "10", "15"),
                new String[]{"4", "异常车辆"}, Arrays.asList("5", "10", "15")
        );

        // 按原始状态统计数量
        Map<String, Long> statusCountMap = orderList.stream()
                .collect(Collectors.groupingBy(va ->String.valueOf(va.getStatus()), Collectors.counting()));
        log.info("按原始状态统计数量:{}", JSON.toJSONString(statusCountMap));

        // 进行状态聚合
        List<StatisticsWaybillResp.OrderBillStatusStatistics> aggregatedList = aggregateRules.entrySet().stream()
                .map(rule -> {
                    String[] aggregateInfo = rule.getKey();
                    List<String> originalStatuses = rule.getValue();
                    long totalNum = 0;

                    // 处理状态为4的异常车辆
                    if (Objects.equals(aggregateInfo[0],"4")) {
                        totalNum = orderList.stream().filter(order -> {
                            // 1. 必须包含在定义的异常状态源中 (5,10,15)
                            if (!originalStatuses.contains(String.valueOf(order.getStatus()))) {
                                return false;
                            }
                            // 2. 进场时间不为空
                            if (order.getIntoTime() == null) {
                                return false;
                            }
                            // 3. 计算停留时长
                            double stayHours = DateUtils.hoursBetween(order.getIntoTime(), new Date());
                            return stayHours > configHours;
                        }).count();
                    } else {
                        // 汇总对应状态的数量
                        totalNum = originalStatuses.stream()
                                .mapToLong(status -> statusCountMap.getOrDefault(status, 0L))
                                .sum();
                        log.info("{}状态统计，num：{}", JSON.toJSONString(aggregateInfo[1]), totalNum);
                    }

                    // 构建聚合结果对象
                    StatisticsWaybillResp.OrderBillStatusStatistics aggregateStat = new StatisticsWaybillResp.OrderBillStatusStatistics();
                    aggregateStat.setOrderStatus(aggregateInfo[0]); // 聚合状态编码
                    aggregateStat.setOrderStatusDesc(aggregateInfo[1]); // 聚合状态描述
                    aggregateStat.setOrderNum(String.valueOf(totalNum)); // 汇总数量
                    return aggregateStat;
                })
                .sorted(Comparator.comparing(StatisticsWaybillResp.OrderBillStatusStatistics::getOrderStatus))
                .collect(Collectors.toList());
        log.info("统计计算完成，result：{}", JSON.toJSONString(aggregatedList));
        return aggregatedList;
    }



    /**
     * 门卫放行
     * @param param
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void pass(GatekeeperOrderPassParam param) {
        log.info("门卫放行：{}", JSON.toJSONString(param));
        KwtGatekeeperWaybillOrder gatekeeper = gatekeeperWaybillOrderRepository.getById(param.getId());
        if (gatekeeper == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.FORKLIFT_ORDER_NOT_FOUND, "当前门卫订单不存在！");
        }
        //放行后 mock抬杆流程
//        mockPass(param, gatekeeper);

        //放行后直接抬杆离场
        driverPass(param, gatekeeper);
    }

    /**
     * 放行后 mock抬杆流程
     * @param param
     * @param gatekeeper
     */
    private void mockPass(GatekeeperOrderPassParam param, KwtGatekeeperWaybillOrder gatekeeper) {
        //1. 更改门卫状态为：已放行
        updateGatekeeperOrderStatus(gatekeeper, param);

        //2. 更改司机状态为：已放行未离场
        updateWaybillOrderStatus(gatekeeper, param);
    }

    /**
     * 更改门卫状态为：已放行
     * @param gatekeeper
     */
    private void updateGatekeeperOrderStatus(KwtGatekeeperWaybillOrder gatekeeper, GatekeeperOrderPassParam param) {
        if (!GatekeeperStatusEnum.PENDING_RELEASE.getCode().equals(gatekeeper.getStatus())) {
            throw new BusinessPlatfromException(ErrorCodeEnum.FORKLIFT_ORDER_STATUS_ERROR, "当前门卫订单状态异常，不能放行！");
        }
        //门卫放行后状态更改为：已放行
        gatekeeper.setStatus(GatekeeperStatusEnum.READY_RELEASE.getCode());
        gatekeeper.setLeaveTime(new Date());
        gatekeeper.setGatekeeperUserId(param.getGatekeeperUserId());
        gatekeeper.setGatekeeperName(param.getGatekeeperName());
        gatekeeper.setUpdateUser(param.getGatekeeperUserId());
        gatekeeperWaybillOrderRepository.updateById(gatekeeper);
    }

    /**
      * 更改司机状态为：已放行未离场
     * @param gatekeeper
     */
    private void updateWaybillOrderStatus(KwtGatekeeperWaybillOrder gatekeeper, GatekeeperOrderPassParam param) {
        // 1. 修改运单状态：已放行未离场
        updateWaybillStatus(gatekeeper);

        // 2. 修改子运单状态：已放行未离场
        updateWaybillSubtaskStatus(gatekeeper);

        // 3.创建运单轨迹日日志
        creatWaybillOrderNode(gatekeeper, param);
    }

    /**
     * 修改运单状态
     * @param gatekeeper
     */
    private void updateWaybillStatus(KwtGatekeeperWaybillOrder gatekeeper) {
        KwtWaybillOrder waybillOrder = waybillOrderRepository.getById(gatekeeper.getWOrderId());
        if (waybillOrder == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.FORKLIFT_ORDER_NOT_FOUND, "当前运单数据不存在！");
        }

        //装货单
        if (Objects.equals(gatekeeper.getType(), GatekeeperTypeEnum.LOADING.getCode())) {
            if (!CarWaybillV1Enum.WAIT_RELEASE.getCode().equals(waybillOrder.getStatus())) {
                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前运单状态异常，不能推进为已放行待离场！");
            }
            waybillOrder.setStatus(CarWaybillV1Enum.RELEASED_NOT_EXITED.getCode());
        } else {
            //卸货单校验
            if (!CarWaybillV1Enum.UNLOADING_WAIT_RELEASE.getCode().equals(waybillOrder.getStatus())) {
                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前运单状态异常，不能推进为已完成！");
            }
            waybillOrder.setStatus(CarWaybillV1Enum.COMPLETED.getCode());
        }
        waybillOrderRepository.updateById(waybillOrder);
    }

    /**
     * 修改子运单状态
     * @param gatekeeper
     */
    private void updateWaybillSubtaskStatus(KwtGatekeeperWaybillOrder gatekeeper) {
        KwtWaybillOrderSubtask waybillSubtask = waybillOrderSubtaskRepository.queryByWOrderId(gatekeeper.getWOrderId());
        if (waybillSubtask == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到关联的子运单！");
        }
        //装货单
        if (Objects.equals(gatekeeper.getType(), GatekeeperTypeEnum.LOADING.getCode())) {
            if (!CarWaybillV1Enum.WAIT_RELEASE.getCode().equals(waybillSubtask.getStatus())) {
                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前子运单状态异常，不能推进为已放行待离场！");
            }
            waybillSubtask.setStatus(CarWaybillV1Enum.RELEASED_NOT_EXITED.getCode());
        } else {
            //卸货单校验
            if (!CarWaybillV1Enum.UNLOADING_WAIT_RELEASE.getCode().equals(waybillSubtask.getStatus())) {
                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前子运单状态异常，不能推进为已完成！");
            }
            waybillSubtask.setStatus(CarWaybillV1Enum.COMPLETED.getCode());
        }
        waybillOrderSubtaskRepository.updateById(waybillSubtask);
    }

    /**
     * 创建日子轨迹记录
     * @param gatekeeper
     * @return
     */
    public void creatWaybillOrderNode(KwtGatekeeperWaybillOrder gatekeeper, GatekeeperOrderPassParam param) {
        log.info("[门卫放行]创建车辆运单-节点轨迹入参参数：{}", JSON.toJSONString(gatekeeper));
        // 查询运单
        KwtWaybillOrder waybillOrder = waybillOrderRepository.getById(gatekeeper.getWOrderId());
        if (waybillOrder == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到关联的运单！");
        }
        // 查询子运单
        KwtWaybillOrderSubtask subtask = waybillOrderSubtaskRepository.queryByWOrderId(gatekeeper.getWOrderId());
        if (subtask == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到关联的子运单！");
        }
        //校验是否有卸货过磅记录
        List<KwtWaybillOrderWeighbridge> weighbridges = waybillOrderWeighbridgeRepository
                .queryWaybillOrderWeighbridgeByWOrderId(gatekeeper.getWOrderId(), WeighbridgeTypeEnum.UNLOADING.getCode());
        if (CollectionUtils.isEmpty(weighbridges)) {
            // 创建门卫放行记录
            String remark = "门卫[" + param.getGatekeeperName() + "]已放行";
            creatPassLogo(subtask, waybillOrder, remark);
        } else {
            // 1.创建门卫放行记录
            String remark1 = "门卫[" + param.getGatekeeperName() + "]已放行";
            creatPassLogo(subtask, waybillOrder, remark1);

            // 2.创建车辆离场放行记录
            String remark2 = "车辆[" + waybillOrder.getTruckNo() + "]已离场";
            creatPassLogo(subtask, waybillOrder, remark2);

            // 3.创建运单完成放行记录
            String remark3 = "运单[" + waybillOrder.getWOrderNo() + "]已完成";
            creatPassLogo(subtask, waybillOrder, remark3);

        }
        log.info("[门卫放行]创建车辆运单-节点轨迹完成!");
    }

    /**
     * 记录门卫放行记录
     * @param subtask
     * @param waybillOrder
     */
    private void creatPassLogo(KwtWaybillOrderSubtask subtask, KwtWaybillOrder waybillOrder,String remark) {
        KwtWaybillOrderNode node = new KwtWaybillOrderNode();
        node.setWOrderId(waybillOrder.getId());
        node.setWSubtaskId(subtask.getId());
        node.setOrderStatus(subtask.getStatus());
        node.setTruckId(waybillOrder.getTruckId());
        node.setDriverId(waybillOrder.getDriverId());
        node.setDriverName(waybillOrder.getDriverName());
        node.setRemark(remark);
        waybillOrderNodeRepository.save(node);
        log.info("[门卫放行]记录节点轨迹成功，节点ID：{}", node.getId());
    }


    /**
     * 放行后直接离场
     * @param param
     * @param gatekeeper
     */
    private void driverPass(GatekeeperOrderPassParam param, KwtGatekeeperWaybillOrder gatekeeper) {
        // 查询运单
        KwtWaybillOrder waybillOrder = waybillOrderRepository.getById(gatekeeper.getWOrderId());
        if (waybillOrder == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.FORKLIFT_ORDER_NOT_FOUND, "[门卫放行]当前运单数据不存在！");
        }

        //1. 计算是否空载离场
        Boolean isEmptyLoadLeave = calculateEmptyLoad(waybillOrder);

        //2. 更改门卫状态为：已离场
        updateGatekeeperOrderStatus2(gatekeeper, param, isEmptyLoadLeave);

        //3. 更改司机状态为：已离场
        updateWaybillOrderStatus2(gatekeeper, param, waybillOrder, isEmptyLoadLeave);

        //4. 创建门卫卸货订单
//        creatGatekeeperUnLoadingOrder(gatekeeper, waybillOrder);
    }

    /**
     * 计算是否空载离场
     * @param waybillOrder
     * @return
     */
    private Boolean calculateEmptyLoad(KwtWaybillOrder waybillOrder) {
        log.info("[门卫放行]计算是否空载离场：{}", JSON.toJSONString(waybillOrder));
        //查询运单装卸货信息
        KwtWaybillOrderTicket orderTicket = waybillOrderTicketRepository.queryByWOrderIdByIdAndType(waybillOrder.getId(), 1);
        if (orderTicket == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_TICKET_NOT_FOUND, "当前物流运单装卸货信息不存在，无法记录皮重！");
        }
        BigDecimal loadAmount = orderTicket.getAmount();

        //空载离场,净重<=0.5
        boolean result = loadAmount != null && loadAmount.compareTo(BigDecimal.valueOf(0.5)) <= 0;
        log.info("[门卫放行]计算是否空载离场完成：{}", JSON.toJSONString(result));
        return result;
    }


    /**
     * 更改门卫状态为：已放行
     * @param gatekeeper
     */
    private void updateGatekeeperOrderStatus2(KwtGatekeeperWaybillOrder gatekeeper, GatekeeperOrderPassParam param, Boolean isEmptyLoadLeave) {
        log.info("[门卫放行]更改门卫状态为已放行：{}", JSON.toJSONString(gatekeeper));
        if (!GatekeeperStatusEnum.PENDING_RELEASE.getCode().equals(gatekeeper.getStatus())) {
            throw new BusinessPlatfromException(ErrorCodeEnum.FORKLIFT_ORDER_STATUS_ERROR, "当前门卫订单状态异常，不能放行！");
        }
        //门卫放行后状态更改为：已离场/空载离场
        GatekeeperStatusEnum targetStatus = isEmptyLoadLeave ? GatekeeperStatusEnum.EMPTY_EXITED : GatekeeperStatusEnum.EXITED;
        gatekeeper.setStatus(targetStatus.getCode());
        gatekeeper.setLeaveTime(new Date());
        gatekeeper.setGatekeeperUserId(param.getGatekeeperUserId());
        gatekeeper.setGatekeeperName(param.getGatekeeperName());
        gatekeeper.setUpdateUser(param.getGatekeeperUserId());
        gatekeeperWaybillOrderRepository.updateById(gatekeeper);
        log.info("[门卫放行]更改门卫状态已放行完成!");
    }

    /**
     * 更改司机状态为：已离场
     * @param gatekeeper
     */
    private void updateWaybillOrderStatus2(KwtGatekeeperWaybillOrder gatekeeper, GatekeeperOrderPassParam param,
                                           KwtWaybillOrder waybillOrder, Boolean isEmptyLoadLeave) {
        // 1. 修改运单状态：已离场
        updateWaybillStatus2(gatekeeper, waybillOrder, isEmptyLoadLeave);

        // 2. 修改子运单状态：已离场
        updateWaybillSubtaskStatus2(gatekeeper, isEmptyLoadLeave);

        // 3.创建运单轨迹日日志
        creatWaybillOrderNode(gatekeeper, param);
    }

    /**
     * 修改运单状态
     * @param gatekeeper
     */
    private void updateWaybillStatus2(KwtGatekeeperWaybillOrder gatekeeper, KwtWaybillOrder waybillOrder,Boolean isEmptyLoadLeave) {
        log.info("[门卫放行]更改运单状态为已离场/空载离场：{}", JSON.toJSONString(gatekeeper));
        //装货单
        if (Objects.equals(gatekeeper.getType(), GatekeeperTypeEnum.LOADING.getCode())) {
            if (!CarWaybillV1Enum.WAIT_RELEASE.getCode().equals(waybillOrder.getStatus())) {
                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前运单状态异常，不能推进为已离场！");
            }
            // 校验状态：若是空载离场，运单状态为已完成
            CarWaybillV1Enum status = isEmptyLoadLeave ? CarWaybillV1Enum.COMPLETED : CarWaybillV1Enum.WAIT_LOADING;
            if (isEmptyLoadLeave) {
                waybillOrder.setRemark("空载离场");
            }
            waybillOrder.setStatus(status.getCode());
        } else {
            //卸货单校验
            if (!CarWaybillV1Enum.UNLOADING_WAIT_RELEASE.getCode().equals(waybillOrder.getStatus())) {
                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前运单状态异常，不能推进为已完成！");
            }
            waybillOrder.setStatus(CarWaybillV1Enum.COMPLETED.getCode());
        }
        waybillOrderRepository.updateById(waybillOrder);
        log.info("[门卫放行]更改运单状态为已离场/空载离场完成!");
    }

    /**
     * 修改子运单状态
     * @param gatekeeper
     */
    private void updateWaybillSubtaskStatus2(KwtGatekeeperWaybillOrder gatekeeper, Boolean isEmptyLoadLeave) {
        log.info("[门卫放行]更改子运单状态为已离场/空载离场：{}", JSON.toJSONString(gatekeeper));
        KwtWaybillOrderSubtask waybillSubtask = waybillOrderSubtaskRepository.queryByWOrderId(gatekeeper.getWOrderId());
        if (waybillSubtask == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到关联的子运单！");
        }
        //装货单
        if (Objects.equals(gatekeeper.getType(), GatekeeperTypeEnum.LOADING.getCode())) {
            if (!CarWaybillV1Enum.WAIT_RELEASE.getCode().equals(waybillSubtask.getStatus())) {
                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前子运单状态异常，不能推进为已离场！");
            }
            // 校验状态：若是空载离场，运单状态为已完成
            CarWaybillV1Enum status = isEmptyLoadLeave ? CarWaybillV1Enum.COMPLETED : CarWaybillV1Enum.WAIT_LOADING;
            waybillSubtask.setStatus(status.getCode());
        } else {
            //卸货单校验
            if (!CarWaybillV1Enum.UNLOADING_WAIT_RELEASE.getCode().equals(waybillSubtask.getStatus())) {
                throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前子运单状态异常，不能推进为已完成！");
            }
            waybillSubtask.setStatus(CarWaybillV1Enum.COMPLETED.getCode());
        }
        waybillOrderSubtaskRepository.updateById(waybillSubtask);
        log.info("[门卫放行]更改子运单状态为已离场/空载离场完成!");
    }


    /**
     * 创建卸货门卫订单
     *
     * @param waybillOrder
     */
    private void creatGatekeeperUnLoadingOrder(KwtGatekeeperWaybillOrder gatekeeperOrder, KwtWaybillOrder waybillOrder) {
        log.info("[门卫放行]开始创建卸货门卫订单：{}", JSON.toJSONString(waybillOrder));
        // 原矿卸货放行不需要创建门卫订单
        if (Objects.equals(gatekeeperOrder.getType(), GatekeeperTypeEnum.UNLOADING.getCode())) {
            log.info("[门卫放行]当前是卸货流程放行，不需要再次创建门卫订单：{}", JSON.toJSONString(gatekeeperOrder));
            return;
        }

        // 只有原矿运输的才会新增卸货门卫订单
        KwtLogisticsOrder logisticsOrder = getLogisticsOrder(waybillOrder.getLOrderId());
        if (!Objects.equals(1, logisticsOrder.getOrderType())) {
            log.info("[门卫放行]不需要创建卸货门卫订单：{}", JSON.toJSONString(logisticsOrder));
            return;
        }

        RTruckVo truck = remoteFleetService.findTruckByTruckNo(waybillOrder.getTruckNo());
        if (truck == null || !Objects.equals(truck.getStatus(), 0)) {
            throw new BusinessPlatfromException(ErrorCodeEnum.TRUCK_STATUS_ERROR, "当前车辆非正常状态，不能接单！");
        }
        //查询子运单
        KwtWaybillOrderSubtask waybillSubtask = getWaybillSubtask(waybillOrder.getId());

        try {
            KwtGatekeeperWaybillOrder gatekeeper = new KwtGatekeeperWaybillOrder();
            gatekeeper.setEntId(getEntId(logisticsOrder));
            gatekeeper.setWOrderId(waybillOrder.getId());
            gatekeeper.setWOrderNo(waybillOrder.getWOrderNo());
            gatekeeper.setLOrderId(waybillOrder.getLOrderId());

            //查询字典
            Map<String, Map<String, String>> dictValueAndDictResDtoMap = remoteSystemService.queryDictByType(
                    Arrays.asList(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), DictTypeEnum.GOODS_SPEC.getType()));
            Map<String, String> goodsTypeMap= dictValueAndDictResDtoMap.getOrDefault(DictTypeEnum.PRODUCT_NAME_TYPE.getType(), new HashMap<>());
            Map<String, String> goodsSpecMap= dictValueAndDictResDtoMap.getOrDefault(DictTypeEnum.GOODS_SPEC.getType(), new HashMap<>());

            // 查询商品信息
            KwtLogisticsOrderGoods orderGoods = logisticsOrderGoodsRepository.queryByLogOrderId(waybillOrder.getLOrderId());
            KwpGoods goods = goodsInfoService.getGoodsById(orderGoods.getGoodsId());
            if (goods != null) {
                gatekeeper.setGoodsId(goods.getId());
                gatekeeper.setGoodsName(goods.getName()+"/"+goodsTypeMap.getOrDefault(goods.getGoodsType(),"")+"/"+goodsSpecMap.getOrDefault(goods.getSpec(), ""));
            }

            gatekeeper.setWaybillAcceptTime(waybillOrder.getCreateTime());
            gatekeeper.setType(GatekeeperTypeEnum.UNLOADING.getCode());
            gatekeeper.setStatus(GatekeeperStatusEnum.PENDING_ENTRY.getCode());
            gatekeeper.setWaybillAcceptTime(waybillOrder.getCreateTime());
            gatekeeper.setTruckType(truck.getTruckType());
            gatekeeper.setEntrustAmount(waybillSubtask.getEntrustAmount());
            gatekeeper.setCarAxis(truck.getCarAxis());
            gatekeeper.setLegalLoad(truck.getLegalLoad());
            gatekeeper.setCreateTime(new Date());
            gatekeeper.setCreateUser(waybillOrder.getDriverId());
            gatekeeper.setUpdateUser(waybillOrder.getDriverId());

            gatekeeperWaybillOrderRepository.save(gatekeeper);
            log.debug("卸货门卫订单数据保存成功");
        } catch (Exception e) {
            log.error("保存卸货门卫订单数据失败！运单ID: {}, 异常信息:", waybillOrder.getId(), e);
        }
    }

    /**
     * 查询物流订单
     */
    protected KwtLogisticsOrder getLogisticsOrder(Long logOrderId) {
        KwtLogisticsOrder logisticsOrder = logisticsOrderRepository.queryByLogisticsOrderId(logOrderId);
        if (logisticsOrder == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_FOUND, "物流订单数据不存在！");
        }
        return logisticsOrder;
    }

    /**
     * 查询子运单
     */
    protected KwtWaybillOrderSubtask getWaybillSubtask(Long waybillOrderId) {
        KwtWaybillOrderSubtask subtask = waybillOrderSubtaskRepository.queryByWOrderId(waybillOrderId);
        if (subtask == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到关联的子运单！");
        }
        return subtask;
    }

    /**
     * 获取企业id
     * @param logOrder
     * @return
     */
    private Long getEntId(KwtLogisticsOrder logOrder) {
        log.info("[创建卸货门卫]开始查询企业id，入参参数：{}", JSON.toJSONString(logOrder));
        Long entId = -1L;
        KwtLogisticsOrderUnit kwtLogisticsOrderUnit = logisticsOrderUnitRepository.queryByLOrderIdAndUnitType(logOrder.getId(), 1);
        if (kwtLogisticsOrderUnit == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_FOUND, "[接单]物流企业信息数据不存在");
        }
        // 原矿运输山上、上下门卫企业id
        List<Long> mockEntIds = Arrays.asList(538039617157337089L, 538040297439891457L);
        if (Objects.equals(1, logOrder.getOrderType()) && mockEntIds.contains(kwtLogisticsOrderUnit.getEntId())) {
            entId = mockEntIds.get(1);
        }
        log.info("[创建卸货门卫]查询企业id完成，入参参数：{}", JSON.toJSONString(entId));
        return entId;
    }

    /**
     * 校验是否可放行
     * @param gatekeeper
     */
    public void savePassReason(GatekeeperOrderPassReasonParam gatekeeper) {
        // 1.保存放行原因
        saveGatePassReason(gatekeeper);

        // 2.门卫放行
        GatekeeperOrderPassParam passParam = new GatekeeperOrderPassParam();
        passParam.setId(gatekeeper.getId());
        passParam.setGatekeeperUserId(gatekeeper.getGatekeeperUserId());
        passParam.setGatekeeperName(gatekeeper.getGatekeeperName());
        pass(passParam);
    }

    /**
     * 保存放行原因
     * @param gatekeeper
     */
    private void saveGatePassReason(GatekeeperOrderPassReasonParam gatekeeper) {
        log.info("[门卫放行原因]保存放行原因, param:{}", JSON.toJSONString(gatekeeper));
        KwtGatekeeperWaybillOrder gatekeeperWaybillOrder = gatekeeperWaybillOrderRepository.getById(gatekeeper.getId());
        if (gatekeeperWaybillOrder == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.GATEKEEPER_ORDER_NOT_FOUND, "[门卫放行原因]门卫订单不存在！");
        }
        KwtWaybillOrder waybillOrder = waybillOrderRepository.getById(gatekeeperWaybillOrder.getWOrderId());
        if (waybillOrder == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_FOUND, "[门卫放行原因]运单不存在！");
        }
        waybillOrder.setPassReason(gatekeeper.getPassReason());
        waybillOrder.setPassUrl(gatekeeper.getPassUrl());
        waybillOrderRepository.updateById(waybillOrder);
        log.info("[门卫放行原因]保存放行原因完成!");
    }

    /**
     * 校验是否可放行
     * @param gatekeeper
     */
    public Boolean checkIsPass(GatekeeperOrderIsPassParam gatekeeper) {
        log.info("校验是否可放行：{}", JSON.toJSONString(gatekeeper));
        List<KwtWaybillOrder> wbOrderByTruckNo = waybillOrderRepository.findWbOrderByTruckNo(gatekeeper.getTruckNo());
        if (CollectionUtils.isEmpty(wbOrderByTruckNo)) {
            log.info("未找到运单数据，校验抬杆结果：{}, 运单：{}", Boolean.FALSE, JSON.toJSONString(wbOrderByTruckNo));
            return Boolean.FALSE;
        }
        // 获取最新的一条数据
        KwtWaybillOrder waybillOrder = wbOrderByTruckNo.get(0);
        List<KwtWaybillOrderWeighbridge> weighbridges = checkIsFirst(waybillOrder);
        if (CollectionUtils.isEmpty(weighbridges)) {
            // 进场第一次抬杆
            Boolean result = Objects.equals(waybillOrder.getStatus(), CarWaybillV1Enum.PENDING_VEHICLE.getCode()) ? Boolean.TRUE : Boolean.FALSE;
            log.info("第一次过磅校校验抬杆结果：{}, 运单：{}", JSON.toJSONString(result), JSON.toJSONString(waybillOrder));
            return result;
        } else if (weighbridges.size() == 1) {
            //第二次抬杆

            //第三次抬杆：铲车司机已接单未完成装载情况
            KwtForkliftWaybillOrder forklift = forkliftWaybillOrderRepository.queryForkliftWaybillOrderByWOrderId(waybillOrder.getId());
            if (Objects.equals(forklift.getStatus(), ForkliftStatusEnum.ORDER_TAKING.getCode())) {
                log.info("[出场上榜]铲车司机已接单未完成，抬杆结果：{}, 运单：{}", Boolean.FALSE, JSON.toJSONString(waybillOrder));
                return Boolean.FALSE;
            }
            if (Objects.equals(forklift.getStatus(), ForkliftStatusEnum.COMPLETED.getCode())) {
                Boolean result = Objects.equals(waybillOrder.getStatus(), CarWaybillV1Enum.EXIT_COMPLETED.getCode()) ? Boolean.TRUE : Boolean.FALSE;
                log.info("[出场上榜]铲车司机完成装载，抬杆结果：{}, 运单：{}", result, JSON.toJSONString(waybillOrder));
                return result;
            }

            Boolean result = Objects.equals(waybillOrder.getStatus(), CarWaybillV1Enum.REFUSE_TRAFFIC.getCode()) ? Boolean.TRUE : Boolean.FALSE;
            log.info("[进场下榜/出场上榜]抬杆,校验出场结果：{}, 运单：{}", result, JSON.toJSONString(waybillOrder));
            return result;
        } else {
            KwtForkliftWaybillOrder forklift = forkliftWaybillOrderRepository.queryForkliftWaybillOrderByWOrderId(waybillOrder.getId());
            if (Objects.equals(forklift.getStatus(), ForkliftStatusEnum.COMPLETED.getCode())) {
                if (Objects.equals(waybillOrder.getStatus(), CarWaybillV1Enum.EXIT_COMPLETED.getCode())) {
                    log.info("[出场上榜]运输司机回退，铲车司机完成装载，抬杆结果：{}, 运单：{}", Boolean.TRUE, JSON.toJSONString(waybillOrder));
                    return Boolean.TRUE;
                }
            }

            if (Objects.equals(waybillOrder.getStatus(), CarWaybillV1Enum.WAIT_LOADING.getCode())) {
                log.info("[出场下榜]抬杆,校验出场结果：{}, 运单：{}", Boolean.TRUE, JSON.toJSONString(waybillOrder));
                // 填充抬杆完成标签
                updateWaybillOrderOpened(waybillOrder);
                return Boolean.TRUE;
            }

            if (Objects.equals(waybillOrder.getStatus(), CarWaybillV1Enum.COMPLETED.getCode())) {
                if (Objects.equals(forklift.getStatus(), ForkliftStatusEnum.COMPLETED.getCode())) {
                    log.info("[出场下榜]铲车司机完成装载，空载离场过磅,校验出场结果：{}, 运单：{}", Boolean.TRUE, JSON.toJSONString(waybillOrder));
                    // 填充抬杆完成标签
                    updateWaybillOrderOpened(waybillOrder);
                    return Boolean.TRUE;
                } else {
                    log.info("[出场下榜]铲车司机未接单，空载离场过磅,校验出场结果：{}, 运单：{}", Boolean.TRUE, JSON.toJSONString(waybillOrder));
                    // 填充抬杆完成标签
                    updateWaybillOrderOpened(waybillOrder);
                    return Boolean.TRUE;
                }
            }
            if (Objects.equals(waybillOrder.getStatus(), CarWaybillV1Enum.REFUSE_TRAFFIC.getCode())) {
                log.info("[出场下榜]铲车未接单，有重量过磅,校验出场结果：{}, 运单：{}", Boolean.FALSE, JSON.toJSONString(waybillOrder));
                return Boolean.FALSE;
            }
        }
        log.info("抬杆未知情况，校验出场结果：{}, 运单：{}", Boolean.FALSE, JSON.toJSONString(waybillOrder));
        return Boolean.FALSE;
    }

    /**
     * 填充抬杆完成标签
     * @param waybillOrder
     */
    private void updateWaybillOrderOpened(KwtWaybillOrder waybillOrder) {
        waybillOrder.setOpened(1);
        waybillOrderRepository.updateById(waybillOrder);
        log.info("已完成全部过磅流程，运单：{}", JSON.toJSONString(waybillOrder));
    }

    /**
     * 校验是否可放行
     * @param gatekeeper
     */
    public Boolean checkIsPassV2(GatekeeperOrderIsPassParam gatekeeper) {
        log.info("校验是否可放行：{}", JSON.toJSONString(gatekeeper));
        List<KwtWaybillOrder> wbOrderByTruckNo = waybillOrderRepository.findWbOrderByTruckNo(gatekeeper.getTruckNo());
        if (CollectionUtils.isEmpty(wbOrderByTruckNo)) {
            return Boolean.FALSE;
        }
        // 获取最新的一条数据
        KwtWaybillOrder waybillOrder = wbOrderByTruckNo.get(0);
        List<KwtWaybillOrderWeighbridge> weighbridges = checkIsFirst(waybillOrder);
        if (CollectionUtils.isEmpty(weighbridges)) {
            // 第一次抬杆
            Boolean result = Objects.equals(waybillOrder.getStatus(), CarWaybillV1Enum.PENDING_VEHICLE.getCode()) ? Boolean.TRUE : Boolean.FALSE;
            log.info("第一次过磅校验出场是否可放行完成，抬杆结果：{}, 运单：{}", JSON.toJSONString(result), JSON.toJSONString(waybillOrder));
            return result;
        } else if (weighbridges.size() == 1){
            // 第二、三次过磅
            List<KwtGatekeeperWaybillOrder> gatekeeperWaybillOrders = getGatekeeperWaybillOrders(waybillOrder);
            if (CollectionUtils.isEmpty(gatekeeperWaybillOrders)) {
                return Boolean.FALSE;
            }
            KwtGatekeeperWaybillOrder gatekeeperWaybillOrder = gatekeeperWaybillOrders.get(0);

            //不考虑司机还在榜上未抬杆，铲车司机就接单情况
            KwtForkliftWaybillOrder forklift = forkliftWaybillOrderRepository.queryForkliftWaybillOrderByWOrderId(waybillOrder.getId());
            if (Objects.equals(forklift.getStatus(), ForkliftStatusEnum.ORDER_TAKING.getCode())) {
                return Boolean.FALSE;
            }

            Boolean result = Objects.equals(gatekeeperWaybillOrder.getStatus(), GatekeeperStatusEnum.IN_YARD.getCode()) ? Boolean.TRUE : Boolean.FALSE;
            log.info("后续过磅,校验出场是否可放行完成，抬杆结果：{}, 运单：{}", JSON.toJSONString(result), JSON.toJSONString(waybillOrder));
            return result;
        } else {
            // 第四次过磅
            List<KwtGatekeeperWaybillOrder> gatekeeperWaybillOrders = getGatekeeperWaybillOrders(waybillOrder);
            if (CollectionUtils.isEmpty(gatekeeperWaybillOrders)) {
                return Boolean.FALSE;
            }
            KwtGatekeeperWaybillOrder gatekeeperWaybillOrder = gatekeeperWaybillOrders.get(0);

            // 定义运单可以可放行的状态集合
            List<Integer> PASS_STATUSES = Arrays.asList(
                    GatekeeperStatusEnum.IN_YARD.getCode(),
                    GatekeeperStatusEnum.EXITED.getCode(),
                    GatekeeperStatusEnum.EMPTY_EXITED.getCode()
            );
            Boolean result = PASS_STATUSES.contains(gatekeeperWaybillOrder.getStatus()) ? Boolean.TRUE : Boolean.FALSE;
            if(result) {
                updateWaybillOrderOpened(waybillOrder);
            }
            log.info("最后过磅,校验出场是否可放行完成，抬杆结果：{}, 运单：{}", JSON.toJSONString(result), JSON.toJSONString(waybillOrder));
            return result;
        }
    }

    /**
     * 校验是否第一次过磅
     * @param waybillOrder
     * @return
     */
    private List<KwtWaybillOrderWeighbridge> checkIsFirst(KwtWaybillOrder waybillOrder) {
        return waybillOrderWeighbridgeRepository
                .queryWaybillOrderWeighbridgeByWOrderId(waybillOrder.getId(), WeighbridgeTypeEnum.LOADING.getCode());
    }

    /**
     * 查询门卫
     * @param waybillOrder
     * @return
     */
    private List<KwtGatekeeperWaybillOrder> getGatekeeperWaybillOrders(KwtWaybillOrder waybillOrder) {
        return gatekeeperWaybillOrderRepository
                .queryGatekeeperWaybillOrderByWOrderIds(Lists.newArrayList(waybillOrder.getId()));
    }


}
