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.DictEnum;
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.AddressTypeEnum;
import com.sckw.core.model.enums.CarWaybillV1Enum;
import com.sckw.core.model.enums.LogisticsOrderV1Enum;
import com.sckw.core.model.enums.UnitTypeEnum;
import com.sckw.core.utils.CollectionUtils;
import com.sckw.core.utils.DateUtils;
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.OrderDetailVo;
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.UserCacheResDto;
import com.sckw.transport.handler.*;
import com.sckw.transport.model.*;
import com.sckw.transport.model.param.*;
import com.sckw.transport.model.vo.OrderTotalTakeVo;
import com.sckw.transport.model.vo.StatisticsWaybillResp;
import com.sckw.transport.repository.*;
import com.sckw.transport.service.KwtWaybillOrderV1Service;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
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.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zk
 * @desc 司机app接单Service
 * @date 2023/7/19 0019
 */
@Slf4j
@Service
@SuppressWarnings("all")
@RequiredArgsConstructor
public class WaybillOrderService {

    private final KwtLogisticsOrderRepository logisticsOrderRepository;
    private final KwtLogisticsOrderCirculateRepository logisticsOrderCirculateRepository;
    private final KwtLogisticsOrderGoodsRepository logisticsOrderGoodsRepository;
    private final KwtLogisticsOrderAddressRepository logisticsOrderAddressRepository;
    private final KwtLogisticsOrderUnitRepository logisticsOrderUnitRepository;

    private final KwtWaybillOrderSubtaskRepository waybillOrderSubtaskRepository;
    private final KwtWaybillOrderRepository waybillOrderRepository;
    private final KwtWaybillOrderAddressRepository waybillOrderAddressRepository;
    private final KwtWaybillOrderTicketRepository waybillOrderTicketRepository;
    private final KwtWaybillOrderNodeRepository waybillOrderNodeRepository;
    private final KwtWaybillOrderWeighbridgeRepository waybillOrderWeighbridgeRepository;
    private final KwtLogisticsOrderContractRepository logisticsOrderContractRepository;

    @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
    RemoteSystemService remoteSystemService;
    @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 80000)
    TradeOrderInfoService tradeOrderInfoService;
    @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
    RemoteFleetService remoteFleetService;
    @DubboReference(version = "1.0.0", group = "design", check = false, timeout = 6000)
    GoodsInfoService goodsInfoService;
    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteContractService remoteContractService;

    private final TakingOrderHandler takingOrderHandler;
    private final CancelHandler cancelHandler;
    private final ComeIntoHandler comeIntoHandler;
    private final LoadingHandler loadingHandler;
    private final LeaveMockHandler leaveMockHandler;
    private final LeaveHandler leaveHandler;
    private final EmptyLoadLeaveHandler emptyLoadLeaveHandler;
    private final ReplenishHandler replenishHandler;
    private final LiftRodReleaseHandler liftRodReleaseHandler;

    private final UnloadingHandler unloadingHandler;
    private final UnloadingLeavedHandler unloadingLeavedHandler;
    private final UnloadingWeighHandler unloadingWeighHandler;

    private final KwtWaybillOrderV1Service waybillOrderV1Service;

    // 注入RedisTemplate用于分布式锁
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    // 分布式锁相关常量
    private static final String TAKING_ORDER_LOCK_PREFIX = "transport:taking_order:lock:";
    // 锁超时时间30秒
    private static final long LOCK_EXPIRE_SECONDS = 30;
    // 锁等待时间500毫秒
    private static final long LOCK_WAIT_MILLIS = 500;
    // 锁重试间隔100毫秒
    private static final long LOCK_RETRY_INTERVAL = 100;

    //载重任务量浮动吨数
    private static final BigDecimal TWO_TONS = new BigDecimal("2");
    //载重任务量计算比例
    private static final BigDecimal EIGHTY_PERCENT = new BigDecimal("0.8");

    // 定义进行中的状态集合
    private static final List<Integer> UNDER_WAY = Arrays.asList(
            CarWaybillV1Enum.PENDING_VEHICLE.getCode(),
            CarWaybillV1Enum.REFUSE_TRAFFIC.getCode(),
            CarWaybillV1Enum.EXIT_COMPLETED.getCode(),
            CarWaybillV1Enum.EMPTY_WAIT_LEAVE.getCode(),
            CarWaybillV1Enum.WAIT_LEAVE.getCode(),
            CarWaybillV1Enum.UNLOADING.getCode(),
            CarWaybillV1Enum.WAIT_RELEASE.getCode(),
            CarWaybillV1Enum.REPLENISHING.getCode(),
            CarWaybillV1Enum.REPLENISH_FINISH.getCode(),
            CarWaybillV1Enum.RELEASED_NOT_EXITED.getCode(),
            CarWaybillV1Enum.WAIT_LOADING.getCode(),
            CarWaybillV1Enum.UNLOADING_POINT.getCode(),
            CarWaybillV1Enum.UNLOADING_WAIT_LEAVE.getCode(),
            CarWaybillV1Enum.UNLOADING_WAIT_RELEASE.getCode());

    // 定义审核的状态集合
    private static final List<Integer> REVIEW = Arrays.asList(
            CarWaybillV1Enum.COMPLETION_LOADING.getCode(),
            CarWaybillV1Enum.REVIEW_REJECTION.getCode());

    // 定义已完成的状态集合
    private static final List<Integer> COMPLETED = Arrays.asList(
            CarWaybillV1Enum.COMPLETED.getCode(),
            CarWaybillV1Enum.CANCELLED.getCode());




    /**
     * 查询司机关联完成运单和累计运输量
     * @param param
     * @return
     */
    public OrderTotalTakeVo queryTotalTake(OrderCirculateTotalTakeParam param) {
        log.info("查询司机关联完成运单和累计运输量：{}", JSON.toJSONString(param));
        LambdaQueryWrapper<KwtWaybillOrder> queryWrapper = Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getEntId, param.getEntId())
                .eq(KwtWaybillOrder::getDriverId, param.getDriverId())
                .eq(KwtWaybillOrder::getDelFlag,0)
                .eq(KwtWaybillOrder::getStatus,CarWaybillV1Enum.COMPLETED.getCode())
                .orderByDesc(KwtWaybillOrder::getCreateTime)
                .orderByDesc(KwtWaybillOrder::getId);
        //1. 查询司机的完成运单
        List<KwtWaybillOrder> waybillOrders = waybillOrderRepository.list(queryWrapper);
        if (CollectionUtils.isEmpty(waybillOrders)) {
            log.info("当前司机的无运单,driverId: {}", JSON.toJSONString(param));
            return new OrderTotalTakeVo();
        }
        //2. 批量查询子运单
        List<Long> waybillOrderIds = waybillOrders.stream().map(KwtWaybillOrder::getId).distinct().collect(Collectors.toList());
        List<KwtWaybillOrderSubtask> kwtWaybillOrderSubtasks = waybillOrderSubtaskRepository.queryByWOrderIds(waybillOrderIds);
        if (CollectionUtils.isEmpty(kwtWaybillOrderSubtasks)) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "物流子运单不存在");
        }

        // 总运输量 = 累计装货量 + 卸货量
        BigDecimal toalEntrustAmount = kwtWaybillOrderSubtasks
                .stream()
                .map(sub -> {
                    //卸货量为空，说明次运单按照装货方式计费
                    if (sub.getUnloadAmount() == null) {
                        return sub.getLoadAmount() == null || sub.getLoadAmount().compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : sub.getLoadAmount();
                    } else {
                        return sub.getUnloadAmount().compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : sub.getUnloadAmount();
                    }
                })
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        OrderTotalTakeVo totalTakeVo = new OrderTotalTakeVo();
        totalTakeVo.setTotalTake(waybillOrders.size());
        totalTakeVo.setEntrustAmount(toalEntrustAmount);
        log.info("查询司机关联完成运单和累计运输量成功，结果：{}", JSON.toJSONString(totalTakeVo));

        return totalTakeVo;

    }

    /**
     * 查询司机关联车辆的物流订单
     * @param param
     * @return
     */
    public PageDataResult<LogisticsOrderResp> queryTruckLogisticsOrder(OrderCirculateQueryParam param) {
        log.info("查询司机关联车辆的物流订单：{}", JSON.toJSONString(param));
        if (StringUtils.isBlank(param.getTruckNo())) {
            return PageDataResult.empty(param.getPageNum(), param.getPageSize());
        }
        //查询车辆信息
        RTruckVo rTruckVo = getTruck(param.getTruckNo());

        List<KwtLogisticsOrderCirculate> circulateList = logisticsOrderCirculateRepository.queryOrderCirculateByEntId(param.getEntId(), param.getTruckNo());
        if (CollectionUtils.isEmpty(circulateList)) {
            log.info("当前车辆无派单订单，truckNo:{}", param.getTruckNo());
            return PageDataResult.empty(param.getPageNum(), param.getPageSize());
        }
        //物流派车订单
        Map<Long, KwtLogisticsOrderCirculate> logOrderIdAndCirculateMap = circulateList.stream().collect(Collectors.toMap(KwtLogisticsOrderCirculate::getLOrderId,
                Function.identity(), (x, y) -> x));
        //物流订单id
        List<Long> logOrderIdList = circulateList.stream().map(KwtLogisticsOrderCirculate::getLOrderId).filter(Objects::nonNull).collect(Collectors.toList());

        //物流订单
        List<KwtLogisticsOrder> logOrderList = logisticsOrderRepository.queryByLogOrderIds(logOrderIdList);
        if (CollectionUtils.isEmpty(logOrderList)) {
            log.info("当前车辆无物流订单，truckNo:{}", param.getTruckNo());
            throw new BusinessPlatfromException(ErrorCodeEnum.DRIVER_STATUS_ERROR, "当前车辆无物流订单");
        }

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

        // 获取order_type=null的订单集合
        List<KwtLogisticsOrder> typeNullList = partitionedMap.get(false);
        log.info("正常流程的订单信息: {}，数量:{}",  JSON.toJSONString(typeNullList), typeNullList.size());

        // 获取order_type=1的订单集合
        List<KwtLogisticsOrder> typeOneList = partitionedMap.get(true);
        log.info("原矿运输的订单信息: {}，数量:{}", JSON.toJSONString(typeOneList), typeOneList.size());

        List<LogisticsOrderResp> orderList = new ArrayList<>();

        // 正常流程
        //1.查询正常流程物流运运单
        if (CollectionUtils.isNotEmpty(typeNullList)) {
            List<LogisticsOrderResp> normalOrderList = getLogisticsOrderResps(param, typeNullList, logOrderIdAndCirculateMap, rTruckVo);
            orderList.addAll(normalOrderList);
        }
        if (CollectionUtils.isNotEmpty(typeOneList)) {
            // 原矿运输
            List<LogisticsOrderResp> rawOreOrdderList = getRawOreLogisticsOrderResps(param, typeOneList, logOrderIdAndCirculateMap, rTruckVo);
            orderList.addAll(rawOreOrdderList);
        }

        //内存分页
        List<List<LogisticsOrderResp>> pageList = Lists.partition(orderList, param.getPageSize());
        List<LogisticsOrderResp> walletPageList = pageList.size() >= param.getPageNum() ?
                pageList.get(param.getPageNum() - 1) : Collections.emptyList();

        PageDataResult<LogisticsOrderResp> walletPageResponse = PageDataResult.success(param.getPageNum(), param.getPageSize(), (long) walletPageList.size(), walletPageList);
        log.info("查询司机关联车辆的物流订单成功,resouce:{}", JSON.toJSONString(walletPageResponse));
        return walletPageResponse;

    }

    /**
     * 正常流程查询物流订单
     * @param param
     * @param logOrderList
     * @param logOrderIdList
     * @param logOrderIdAndCirculateMap
     * @param rTruckVo
     * @return
     */
    private List<LogisticsOrderResp> getLogisticsOrderResps(OrderCirculateQueryParam param, List<KwtLogisticsOrder> logOrderList,
                                                            Map<Long, KwtLogisticsOrderCirculate> logOrderIdAndCirculateMap,
                                                            RTruckVo rTruckVo) {
        log.info("开始查询正常流程物流订单，param:{}", JSON.toJSONString(param));
        List<Long> logOrderIdList = logOrderList.stream().map(KwtLogisticsOrder::getId).filter(Objects::nonNull).collect(Collectors.toList());

        Map<Long, List<KwtLogisticsOrder>> tradeIdAndLogOrderList = logOrderList.stream().collect(Collectors.groupingBy(KwtLogisticsOrder::getTOrderId));

        //物流id映射物流商品
        List<KwtLogisticsOrderGoods> logOrderGoods = logisticsOrderGoodsRepository.queryByLogOrderIds(logOrderIdList);
        if (CollectionUtils.isEmpty(logOrderGoods)) {
            log.info("当前车辆的物流订单无商品信息，truckNo:{}", param.getTruckNo());
            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_GOODS, "当前车辆的物流订单无商品信息");
        }
        Map<Long, KwtLogisticsOrderGoods> logOrderIdAndGoodsMap = logOrderGoods.stream().collect(Collectors.toMap(KwtLogisticsOrderGoods::getLOrderId,
                Function.identity(), (x, y) -> x));

        //交易商品信息
        List<Long> goodsIds = logOrderGoods.stream().map(KwtLogisticsOrderGoods::getGoodsId).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(goodsIds)) {
            log.info("物流订单无关联商品信息，logOrderId:{}", JSON.toJSONString(logOrderIdList));
            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_GOODS, "物流订单无关联商品信息");
        }
        Map<Long, KwpGoods> goodsIdAndGoodsMap = goodsInfoService.getGoodsByIds(goodsIds);

        //承运托运企业
        List<KwtLogisticsOrderUnit> logOrderUnits = logisticsOrderUnitRepository.queryByLogOrderIds(logOrderIdList);
        if (CollectionUtils.isEmpty(logOrderUnits)) {
            log.info("物流订单无关联承运托运企业，logOrderId:{}", JSON.toJSONString(logOrderIdList));
            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_ENT, "物流订单无关联承运托运企业");
        }
        Map<String, KwtLogisticsOrderUnit> logOrderIdAndUnitMap = logOrderUnits.stream().collect(Collectors.toMap(
                unit -> unit.getLOrderId() + "-" + unit.getUnitType(), Function.identity(), (x, y) -> x));

        //贸易订单id
        Set<Long> tradeOrderIds = logOrderList.stream().map(KwtLogisticsOrder::getTOrderId).collect(Collectors.toSet());

        //供应企业
        List<OrderUnitInfoDetailVO> orderUnitDetailVOS = tradeOrderInfoService.queryOrderUnitInfByTOrderId(tradeOrderIds);
        if (CollectionUtils.isEmpty(orderUnitDetailVOS)) {
            log.info("交易订单无关联采取/销售企业，tradeOrderIds:{}", JSON.toJSONString(tradeOrderIds));
            throw new BusinessPlatfromException(ErrorCodeEnum.TRADE_ORDER_NOT_ENT, "交易订单无关联采取/销售企业");
        }
        Map<String, OrderUnitInfoDetailVO> tOrderIdAndUnitMap = orderUnitDetailVOS.stream().collect(Collectors.toMap(
                unit -> unit.getTOrderId() + "-" + unit.getUnitType(), Function.identity(), (x, y) -> x));

        //地址
        Map<String, KwtLogisticsOrderAddress> logOrderIdAndAddressMap = getKwtLogisticsOrderAddressMap(logOrderIdList);

        //子运单
        List<KwtWaybillOrderSubtask> orderSubtaskList = waybillOrderSubtaskRepository.queryByLogIds(logOrderIdList);
        if(CollectionUtils.isEmpty(orderSubtaskList)) {
            orderSubtaskList = new ArrayList<>();
        }
        Map<Long, List<KwtWaybillOrderSubtask>> logOrderIdAndSubtaskMap = orderSubtaskList.stream()
                .collect(Collectors.groupingBy(KwtWaybillOrderSubtask::getLOrderId));

        //获取贸易订单
        List<OrderDetailVo> orderDetailVos = tradeOrderInfoService.queryByTradeOrderIds(tradeOrderIds);
        if (CollectionUtils.isEmpty(orderDetailVos)) {
            log.info("当前车辆贸易订单不存在，truckNo:{}", param.getTruckNo());
            throw new BusinessPlatfromException(ErrorCodeEnum.TRADE_ORDER_NOT_FOUND, "当前车辆贸易订单不存在");
        }
        Map<Long, OrderDetailVo> tradeIdAndOrderDetailVoMap = orderDetailVos.stream()
                .collect(Collectors.toMap(OrderDetailVo::getId, Function.identity(), (x, y) -> x));

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

        //组装数据
        List<LogisticsOrderResp> ordderList = logOrderList.stream()
                .map(order -> {
                    return getLogisticsOrderResp(order, logOrderIdAndGoodsMap, goodsIdAndGoodsMap, logOrderIdAndUnitMap,
                            tOrderIdAndUnitMap, logOrderIdAndAddressMap, logOrderIdAndCirculateMap, tradeIdAndOrderDetailVoMap,
                            tradeIdAndLogOrderList, logOrderIdAndSubtaskMap, dictValueAndDictResDtoMap);
                })
                .filter(logisticsOrderResp -> {
                    // 校验是否满足车辆任务量，满足才保留
                    return checkCurTruckLoadVolume(rTruckVo, logisticsOrderResp.getRemainingAmount());
                })
                .collect(Collectors.toList());
        log.info("查询正常流程物流订单结束，resouse:{}", JSON.toJSONString(ordderList));
        return ordderList;
    }

    /**
     * 原矿运输
     * @param param
     * @param logOrderList
     * @param logOrderIdList
     * @param logOrderIdAndCirculateMap
     * @param rTruckVo
     * @return
     */
    private List<LogisticsOrderResp> getRawOreLogisticsOrderResps(OrderCirculateQueryParam param, List<KwtLogisticsOrder> logOrderList,
                                                                  Map<Long, KwtLogisticsOrderCirculate> logOrderIdAndCirculateMap,
                                                                  RTruckVo rTruckVo) {
        log.info("开始查询原矿运输流程物流订单，param:{}", JSON.toJSONString(param));
        List<Long> logOrderIdList = logOrderList.stream().map(KwtLogisticsOrder::getId).filter(Objects::nonNull).collect(Collectors.toList());

        Map<Long, List<KwtLogisticsOrder>> tradeIdAndLogOrderList = logOrderList.stream()
                .collect(Collectors.groupingBy(KwtLogisticsOrder::getTOrderId));

        //物流id映射物流商品
        List<KwtLogisticsOrderGoods> logOrderGoods = logisticsOrderGoodsRepository.queryByLogOrderIds(logOrderIdList);
        if (CollectionUtils.isEmpty(logOrderGoods)) {
            log.info("当前车辆的物流订单无商品信息，truckNo:{}", param.getTruckNo());
            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_GOODS, "当前车辆的物流订单无商品信息");
        }
        Map<Long, KwtLogisticsOrderGoods> logOrderIdAndGoodsMap = logOrderGoods.stream().collect(Collectors.toMap(KwtLogisticsOrderGoods::getLOrderId,
                Function.identity(), (x, y) -> x));

        //交易商品信息
        List<Long> goodsIds = logOrderGoods.stream().map(KwtLogisticsOrderGoods::getGoodsId).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(goodsIds)) {
            log.info("物流订单无关联商品信息，logOrderId:{}", JSON.toJSONString(logOrderIdList));
            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_GOODS, "物流订单无关联商品信息");
        }
        Map<Long, KwpGoods> goodsIdAndGoodsMap = goodsInfoService.getGoodsByIds(goodsIds);

        //承运托运企业
        List<KwtLogisticsOrderUnit> logOrderUnits = logisticsOrderUnitRepository.queryByLogOrderIds(logOrderIdList);
        if (CollectionUtils.isEmpty(logOrderUnits)) {
            log.info("物流订单无关联承运托运企业，logOrderId:{}", JSON.toJSONString(logOrderIdList));
            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_ENT, "物流订单无关联承运托运企业");
        }
        Map<String, KwtLogisticsOrderUnit> logOrderIdAndUnitMap = logOrderUnits.stream().collect(Collectors.toMap(
                unit -> unit.getLOrderId() + "-" + unit.getUnitType(), Function.identity(), (x, y) -> x));

        //地址
        Map<String, KwtLogisticsOrderAddress> logOrderIdAndAddressMap = getKwtLogisticsOrderAddressMap(logOrderIdList);

        //子运单
        List<KwtWaybillOrderSubtask> orderSubtaskList = waybillOrderSubtaskRepository.queryByLogIds(logOrderIdList);
        if(CollectionUtils.isEmpty(orderSubtaskList)) {
            orderSubtaskList = new ArrayList<>();
        }
        Map<Long, List<KwtWaybillOrderSubtask>> logOrderIdAndSubtaskMap = orderSubtaskList.stream()
                .collect(Collectors.groupingBy(KwtWaybillOrderSubtask::getLOrderId));

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

        //组装数据
        List<LogisticsOrderResp> ordderList = logOrderList.stream()
                .map(order -> {
                    return getRawOreLogisticsOrderResp(order, logOrderIdAndGoodsMap, goodsIdAndGoodsMap, logOrderIdAndUnitMap,
                            logOrderIdAndAddressMap, logOrderIdAndCirculateMap,
                            tradeIdAndLogOrderList, logOrderIdAndSubtaskMap, dictValueAndDictResDtoMap);
                })
                .filter(logisticsOrderResp -> {
                    // 校验是否满足车辆任务量，满足才保留
                    return checkCurTruckLoadVolume(rTruckVo, logisticsOrderResp.getRemainingAmount());
                })
                .collect(Collectors.toList());
        log.info("查询原矿运输流程物流订单结束，resouse:{}", JSON.toJSONString(ordderList));
        return ordderList;
    }

    /**
     * 校验车辆状态
     * @param param
     * @return
     */
    private RTruckVo getTruck(String truckNo) {
        RTruckVo truckVO = remoteFleetService.findTruckByTruckNo(truckNo);
        if (truckVO == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.TRUCK_NOT_FOUND, "当前车辆不存在");
        }
        //核定载重
        if (truckVO.getLegalLoad() == null || BigDecimal.ZERO.compareTo(truckVO.getLegalLoad()) == 0) {
            throw new BusinessPlatfromException(ErrorCodeEnum.RESOURCE_NOT_FOUND, "车辆核定载重不能为空！");
        }

        return truckVO;
    }

    /**
     * 校验当前车辆任务量：
     * 若有皮重：任务量 = 核定载重 - 皮重
     * 若无皮重：任务量 = 核定载重 × 80%
     * <p>
     * 1.当订单余量>=车辆的（法定载重-首次皮重）且<（法定载重-首次皮重 + 2）时，接取的任务量为车辆的（法定载重-首次皮重）；
     * 2.订单余量<车辆的（法定载重-首次皮重）时，该车辆无法接单；
     * 3.当订单余量>= (法定载重-首次皮重 + 2)时，接取的任务量为 (法定载重-首次皮重 + 2)
     *
     * @param truckNo
     */
    private Boolean checkCurTruckLoadVolume(RTruckVo truckNo, BigDecimal remainingAmount) {
        log.info("开始校验当前车辆任务量！param:{}, 订单余量：{}", JSON.toJSONString(truckNo), JSON.toJSONString(remainingAmount));
        //核定载重
        BigDecimal actualWeight = truckNo.getLegalLoad();
        //首次皮重
        BigDecimal tareWeight = truckNo.getTareWeight();
        //任务量
        BigDecimal loadVolume;
        if (tareWeight != null) {
            // 有皮重：任务量 = 核定载重 - 皮重
            loadVolume = actualWeight.subtract(tareWeight);
            log.info("车辆有皮重，皮重：{}， 任务量:{}", tareWeight, loadVolume);

        } else {
            // 无皮重：任务量 = 核定载重 × 80%
            loadVolume = actualWeight.multiply(EIGHTY_PERCENT);
            log.info("车辆无皮重，按80%核定载重计算，车辆任务量：{}", loadVolume);
        }

        if (remainingAmount.compareTo(loadVolume) < 0) {
            // 规则2：订单余量 < 任务量 → 无法接单
            return false;
        }

        return true;
    }


    /**
     * 装卸货地址
     * @param logOrderIdList
     * @return
     */
    private Map<String, KwtLogisticsOrderAddress> getKwtLogisticsOrderAddressMap(List<Long> logOrderIdList) {
        List<KwtLogisticsOrderAddress> logOrderAddressList = logisticsOrderAddressRepository.queryByLogOrderIds(logOrderIdList);
        if (CollectionUtils.isEmpty(logOrderAddressList)) {
            log.info("物流订单无装卸货地址信息，logOrderIdList:{}", JSON.toJSONString(logOrderIdList));
            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_ADDRESS, "物流订单无装卸货地址信息");
        }
        return logOrderAddressList.stream().collect(Collectors
                .toMap(address -> address.getLOrderId() + "-" + address.getAddressType(),
                        Function.identity(), (x, y) -> x));
    }

    /**
     * 组装正常流程订单列表信息
     * @param order
     * @param logOrderIdAndGoodsMap
     * @param goodsIdAndGoodsMap
     * @param logOrderIdAndUnitMap
     * @param tOrderIdAndUnitMap
     * @param logOrderIdAndAddressMap
     * @param logOrderIdAndCirculateMap
     * @return
     */
    private LogisticsOrderResp getLogisticsOrderResp(KwtLogisticsOrder order, Map<Long, KwtLogisticsOrderGoods> logOrderIdAndGoodsMap,
                                                     Map<Long, KwpGoods> goodsIdAndGoodsMap,
                                                     Map<String, KwtLogisticsOrderUnit> logOrderIdAndUnitMap,
                                                     Map<String, OrderUnitInfoDetailVO> tOrderIdAndUnitMap,
                                                     Map<String, KwtLogisticsOrderAddress> logOrderIdAndAddressMap,
                                                     Map<Long, KwtLogisticsOrderCirculate> logOrderIdAndCirculateMap,
                                                     Map<Long, OrderDetailVo> tradeIdAndOrderDetailVoMap,
                                                     Map<Long, List<KwtLogisticsOrder>> tradeIdAndLogOrderList ,
                                                     Map<Long, List<KwtWaybillOrderSubtask>> logisticsOrderIdAndSubtaskList,
                                                     Map<String, Map<String, String>> dictValueAndDictResDtoMap) {
        LogisticsOrderResp orderResp = new LogisticsOrderResp();
        orderResp.setLogisticsOrderId(Optional.ofNullable(order.getId()).map(String::valueOf).orElse(null));
        orderResp.setLogisticsOrderNo(order.getLOrderNo());
        //商品
        KwtLogisticsOrderGoods orderGoods = logOrderIdAndGoodsMap.getOrDefault(order.getId(), new KwtLogisticsOrderGoods());
        KwpGoods goods = goodsIdAndGoodsMap.getOrDefault(orderGoods.getGoodsId(), new KwpGoods());
        if (Objects.nonNull(goods)){
            orderResp.setGoodsId(Optional.ofNullable(goods.getId()).map(String::valueOf).orElse(null));
            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<>());
            orderResp.setGoodsName(goods.getName()+"/"+goodsTypeMap.getOrDefault(goods.getGoodsType(),"")+"/"+goodsSpecMap.getOrDefault(goods.getSpec(), ""));
        }

        //托运企业
        KwtLogisticsOrderUnit consignEnt = logOrderIdAndUnitMap.getOrDefault(order.getId() + "-" + UnitTypeEnum.CONSIGN.getCode(), new KwtLogisticsOrderUnit());
        orderResp.setConsignCompanyId(Optional.ofNullable(consignEnt.getEntId()).map(String::valueOf).orElse(null));
        orderResp.setConsignCompanyName(consignEnt.getFirmName());
        //承运企业
        KwtLogisticsOrderUnit carriageEnt = logOrderIdAndUnitMap.getOrDefault(order.getId() + "-" + UnitTypeEnum.CARRIAGE.getCode(), new KwtLogisticsOrderUnit());
        orderResp.setCarriageCompanyId(Optional.ofNullable(carriageEnt.getEntId()).map(String::valueOf).orElse(null));
        orderResp.setCarriageCompanyName(carriageEnt.getFirmName());
        //供应企业
        OrderUnitInfoDetailVO supplierEnt = tOrderIdAndUnitMap.getOrDefault(order.getTOrderId() + "-" + "2", new OrderUnitInfoDetailVO());
        orderResp.setSupplierCompanyId(Optional.ofNullable(supplierEnt.getEntId()).map(String::valueOf).orElse(null));
        orderResp.setSupplierCompanyName(supplierEnt.getFirmName());
        //采购单位
        OrderUnitInfoDetailVO proEnt = tOrderIdAndUnitMap.getOrDefault(order.getTOrderId() + "-" + "1", new OrderUnitInfoDetailVO());
        orderResp.setPrEntId(proEnt.getEntId());
        orderResp.setPrEntName(proEnt.getFirmName());

        //装货地址
        KwtLogisticsOrderAddress shipmentAddress = logOrderIdAndAddressMap.getOrDefault(order.getId() + "-" + AddressTypeEnum.SHIPMENT.getCode(), new KwtLogisticsOrderAddress());
        orderResp.setLoadAddress(shipmentAddress.getCityName()+shipmentAddress.getDetailAddress());
        //卸货地址
        KwtLogisticsOrderAddress takeAddress = logOrderIdAndAddressMap.getOrDefault(order.getId() + "-" + AddressTypeEnum.TAKE.getCode(), new KwtLogisticsOrderAddress());
        orderResp.setUnloadAddress(takeAddress.getCityName()+takeAddress.getDetailAddress());
        //装卸地之间距离
        orderResp.setDistanceKm(order.getDistance());

        //时间
        orderResp.setStartTime(DateUtils.format(order.getStartTime(), DateUtils.DATE_PATTERN));
        orderResp.setEndTime(DateUtils.format(order.getEndTime(), DateUtils.DATE_PATTERN));
        KwtLogisticsOrderCirculate orderCirculate = logOrderIdAndCirculateMap.getOrDefault(order.getId(), new KwtLogisticsOrderCirculate());
        orderResp.setSendTime(DateUtils.format(orderCirculate.getCreateTime(), DateUtils.DATE_TIME_PATTERN));

        //派单人信息
        UserCacheResDto userCacheResDto = remoteSystemService.queryUserCacheById(orderCirculate.getCreateBy());
        orderResp.setSendOperator(Optional.ofNullable(userCacheResDto).map(UserCacheResDto::getName).orElse(null));
        orderResp.setSendPhone(Optional.ofNullable(userCacheResDto).map(UserCacheResDto::getPhone).orElse(null));
        orderResp.setStatus(Optional.ofNullable(order.getStatus()).map(String::valueOf).orElse(null));
        orderResp.setStatusDesc(LogisticsOrderV1Enum.IN_TRANSIT.getCode().equals(order.getStatus()) ? "待接单" : "未知状态");
        //设置余量
        BigDecimal orderSurplus = getSupAmount(order.getTOrderId(), tradeIdAndOrderDetailVoMap, tradeIdAndLogOrderList,
                logisticsOrderIdAndSubtaskList);
        orderResp.setOrderSurplus(orderSurplus.toPlainString());
        orderResp.setRemainingAmount(orderSurplus);

        return orderResp;
    }

    /**
     * 组装原矿运输订单列表信息
     * @param order
     * @param logOrderIdAndGoodsMap
     * @param goodsIdAndGoodsMap
     * @param logOrderIdAndUnitMap
     * @param tOrderIdAndUnitMap
     * @param logOrderIdAndAddressMap
     * @param logOrderIdAndCirculateMap
     * @return
     */
    private LogisticsOrderResp getRawOreLogisticsOrderResp(KwtLogisticsOrder order, Map<Long, KwtLogisticsOrderGoods> logOrderIdAndGoodsMap,
                                                     Map<Long, KwpGoods> goodsIdAndGoodsMap,
                                                     Map<String, KwtLogisticsOrderUnit> logOrderIdAndUnitMap,
                                                     Map<String, KwtLogisticsOrderAddress> logOrderIdAndAddressMap,
                                                     Map<Long, KwtLogisticsOrderCirculate> logOrderIdAndCirculateMap,
                                                     Map<Long, List<KwtLogisticsOrder>> tradeIdAndLogOrderList ,
                                                     Map<Long, List<KwtWaybillOrderSubtask>> logisticsOrderIdAndSubtaskList,
                                                     Map<String, Map<String, String>> dictValueAndDictResDtoMap) {
        LogisticsOrderResp orderResp = new LogisticsOrderResp();
        orderResp.setOrderType(order.getOrderType());
        orderResp.setLogisticsOrderId(Optional.ofNullable(order.getId()).map(String::valueOf).orElse(null));
        orderResp.setLogisticsOrderNo(order.getLOrderNo());
        //商品
        KwtLogisticsOrderGoods orderGoods = logOrderIdAndGoodsMap.getOrDefault(order.getId(), new KwtLogisticsOrderGoods());
        KwpGoods goods = goodsIdAndGoodsMap.getOrDefault(orderGoods.getGoodsId(), new KwpGoods());
        if (Objects.nonNull(goods)){
            orderResp.setGoodsId(Optional.ofNullable(goods.getId()).map(String::valueOf).orElse(null));
            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<>());
            orderResp.setGoodsName(goods.getName()+"/"+goodsTypeMap.getOrDefault(goods.getGoodsType(),"")+"/"+goodsSpecMap.getOrDefault(goods.getSpec(), ""));
        }

        //供应企业
        KwtLogisticsOrderUnit supplierEnt = logOrderIdAndUnitMap.getOrDefault(order.getId() + "-" + 1, new KwtLogisticsOrderUnit());
        orderResp.setSupplierCompanyId(Optional.ofNullable(supplierEnt.getEntId()).map(String::valueOf).orElse(null));
        orderResp.setSupplierCompanyName(supplierEnt.getFirmName());
        //承运企业
        KwtLogisticsOrderUnit carriageEnt = logOrderIdAndUnitMap.getOrDefault(order.getId() + "-" + 2, new KwtLogisticsOrderUnit());
        orderResp.setCarriageCompanyId(Optional.ofNullable(carriageEnt.getEntId()).map(String::valueOf).orElse(null));
        orderResp.setCarriageCompanyName(carriageEnt.getFirmName());

        //装货地址
        KwtLogisticsOrderAddress shipmentAddress = logOrderIdAndAddressMap.getOrDefault(order.getId() + "-" + AddressTypeEnum.SHIPMENT.getCode(), new KwtLogisticsOrderAddress());
        orderResp.setLoadAddress(shipmentAddress.getCityName()+shipmentAddress.getDetailAddress());
        //卸货地址
        KwtLogisticsOrderAddress takeAddress = logOrderIdAndAddressMap.getOrDefault(order.getId() + "-" + AddressTypeEnum.TAKE.getCode(), new KwtLogisticsOrderAddress());
        orderResp.setUnloadAddress(takeAddress.getCityName()+takeAddress.getDetailAddress());
        //装卸地之间距离
        orderResp.setDistanceKm(order.getDistance());

        //时间
        orderResp.setStartTime(DateUtils.format(order.getStartTime(), DateUtils.DATE_PATTERN));
        orderResp.setEndTime(DateUtils.format(order.getEndTime(), DateUtils.DATE_PATTERN));
        KwtLogisticsOrderCirculate orderCirculate = logOrderIdAndCirculateMap.getOrDefault(order.getId(), new KwtLogisticsOrderCirculate());
        orderResp.setSendTime(DateUtils.format(orderCirculate.getCreateTime(), DateUtils.DATE_TIME_PATTERN));

        //派单人信息
        UserCacheResDto userCacheResDto = remoteSystemService.queryUserCacheById(orderCirculate.getCreateBy());
        orderResp.setSendOperator(Optional.ofNullable(userCacheResDto).map(UserCacheResDto::getName).orElse(null));
        orderResp.setSendPhone(Optional.ofNullable(userCacheResDto).map(UserCacheResDto::getPhone).orElse(null));
        orderResp.setStatus(Optional.ofNullable(order.getStatus()).map(String::valueOf).orElse(null));
        orderResp.setStatusDesc(LogisticsOrderV1Enum.IN_TRANSIT.getCode().equals(order.getStatus()) ? "待接单" : "未知状态");
        //设置余量
        BigDecimal orderSurplus = getRawOreSupAmount(order, logisticsOrderIdAndSubtaskList);
        orderResp.setOrderSurplus(orderSurplus.toPlainString());
        orderResp.setRemainingAmount(orderSurplus);

        return orderResp;
    }


    /**
     * 查询司机关联车辆的物流运单
     * @param param
     * @return
     */
    public PageDataResult<WaybillOrderStatusResp> queryWaybillOrder(WaybillOrderQueryParam param) {
        log.info("查询司机的物流运单：{}", JSON.toJSONString(param));
        if (StringUtils.isBlank(param.getTruckNo())) {
            return PageDataResult.empty(param.getPageNum(), param.getPageSize());
        }
        //构建查询条件
        LambdaQueryWrapper<KwtWaybillOrder> queryWrapper = buildAndExecuteQuery(param);

        //分页查询运单主数据
        Page<KwtWaybillOrder> waybillOrderList = waybillOrderRepository.page(new Page<>(param.getPageNum(), param.getPageSize()), queryWrapper);
        List<KwtWaybillOrder> records = waybillOrderList.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            log.info("当前车辆辆的无物流运单，truckNo:{}", param.getTruckNo());
            return PageDataResult.empty(param.getPageNum(), param.getPageSize());
        }

        //获取运单关联数据并返回结果
        List<WaybillOrderStatusResp> ordderList = getWaybillOrderRelevantData(param, records);
        sort(param, ordderList);
        log.info("查询司机的物流运单成功！");
        return PageDataResult.success(param.getPageNum(), param.getPageSize(), waybillOrderList.getTotal() , ordderList);
    }

    /**
     * 构建查询条件并执行分页查询
     */
    private LambdaQueryWrapper<KwtWaybillOrder> buildAndExecuteQuery(WaybillOrderQueryParam param) {
        //基础查询条件
        LambdaQueryWrapper<KwtWaybillOrder> queryWrapper = buildBaseQueryWrapper(param);
        //模糊查询条件
        handleSearchKeyword(queryWrapper, param.getSearchKeyword(), param);
        return queryWrapper;
    }

    /**
     * 构建基础查询条件
     * @param param
     * @return
     */
    private static LambdaQueryWrapper<KwtWaybillOrder> buildBaseQueryWrapper(WaybillOrderQueryParam param) {
        LambdaQueryWrapper<KwtWaybillOrder> queryWrapper = Wrappers.<KwtWaybillOrder>lambdaQuery()
                .eq(KwtWaybillOrder::getEntId, param.getEntId())
                .eq(KwtWaybillOrder::getDelFlag, 0)
                .orderByDesc(KwtWaybillOrder::getCreateTime)
                .orderByDesc(KwtWaybillOrder::getId);
        //进行中
        if (Objects.equals(param.getStatus(), Global.NUMERICAL_ONE)) {
            queryWrapper.in(KwtWaybillOrder::getStatus, UNDER_WAY);
            queryWrapper.eq(KwtWaybillOrder::getTruckNo, param.getTruckNo());
        } else if (Objects.equals(param.getStatus(), Global.NUMERICAL_TWO)) {
            //单证审核
            queryWrapper.in(KwtWaybillOrder::getStatus, REVIEW);
            queryWrapper.eq(KwtWaybillOrder::getDriverId, param.getDriverId());
        } else if (Objects.equals(param.getStatus(), Global.NUMERICAL_THREE)) {
            //已完成
            queryWrapper.in(KwtWaybillOrder::getStatus, COMPLETED);
            queryWrapper.eq(KwtWaybillOrder::getDriverId, param.getDriverId());
        }
        return queryWrapper;
    }

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

    /**
     * 查询匹配的运单ID（以运单ID为主键）
     */
    private Set<Long> findMatchedWaybillOrderIds(String keyword, WaybillOrderQueryParam param) {
        Set<Long> waybillOrderIds = ConcurrentHashMap.newKeySet();;
        List<Runnable> searchTasks = Arrays.asList(
                //1. 运单编号查询（主表字段，直接匹配）
                () -> addMatchedIdsFromWaybillNo(keyword, param, waybillOrderIds),

                // 2. 通过物流订单编号查询关联的运单
                () -> addMatchedIdsFromLogisticsOrderNo(waybillOrderIds, keyword, param),

                // 3. 通过托运单位查询关联的运单
                () -> addMatchedIdsFromShipper(waybillOrderIds, keyword, param),

                // 4. 通过货物名称查询关联的运单
                () -> addMatchedIdsFromGoodsName(waybillOrderIds, keyword, param)
        );
        // 使用并行流执行查询任务
        searchTasks.parallelStream().forEach(Runnable::run);
        return waybillOrderIds;
    }

    /**
     * 从运单编号查询匹配运单ID
     * @param keyword
     * @param param
     * @param waybillOrderIds
     */
    private void addMatchedIdsFromWaybillNo(String keyword, WaybillOrderQueryParam param, Set<Long> waybillOrderIds) {
        // 1. 运单编号查询（主表字段，直接匹配）
        LambdaQueryWrapper<KwtWaybillOrder> wrapper = Wrappers.<KwtWaybillOrder>lambdaQuery()
                .like(KwtWaybillOrder::getWOrderNo, keyword)
                .eq(KwtWaybillOrder::getEntId, param.getEntId())
                .eq(KwtWaybillOrder::getDelFlag, 0);

        if (Objects.equals(param.getStatus(), Global.NUMERICAL_ONE)) {
            //进行中
            wrapper.eq(KwtWaybillOrder::getTruckNo, param.getTruckNo());
        } else if (Objects.equals(param.getStatus(), Global.NUMERICAL_TWO) || Objects.equals(param.getStatus(), Global.NUMERICAL_THREE)) {
            //单证审核、已完成
            wrapper.eq(KwtWaybillOrder::getDriverId, param.getDriverId());
        }

        List<KwtWaybillOrder> waybillOrders = waybillOrderRepository.list(wrapper);
        waybillOrderIds.addAll(waybillOrders.stream()
                .map(KwtWaybillOrder::getId)
                .collect(Collectors.toList()));
    }

    /**
     * 从物流订单编号查询运单ID
     */
    private void addMatchedIdsFromLogisticsOrderNo(Set<Long> waybillOrderIds, String keyword, WaybillOrderQueryParam param) {
        // 2. 通过物流订单编号查询关联的运单
        List<KwtLogisticsOrder> logisticsOrders = logisticsOrderRepository.list(
                Wrappers.<KwtLogisticsOrder>lambdaQuery()
                        .like(KwtLogisticsOrder::getLOrderNo, keyword)
                        .eq(KwtLogisticsOrder::getDelFlag, 0)
        );
        if (CollectionUtils.isNotEmpty(logisticsOrders)) {
            List<Long> matchedLogOrderIds = logisticsOrders.stream()
                    .map(KwtLogisticsOrder::getId)
                    .collect(Collectors.toList());

            LambdaQueryWrapper<KwtWaybillOrder> wrapper = Wrappers.<KwtWaybillOrder>lambdaQuery()
                    .in(KwtWaybillOrder::getLOrderId, matchedLogOrderIds)
                    .eq(KwtWaybillOrder::getEntId, param.getEntId())
                    .eq(KwtWaybillOrder::getDelFlag, 0);
            if (Objects.equals(param.getStatus(), Global.NUMERICAL_ONE)) {
                //进行中
                wrapper.eq(KwtWaybillOrder::getTruckNo, param.getTruckNo());
            } else if (Objects.equals(param.getStatus(), Global.NUMERICAL_TWO) || Objects.equals(param.getStatus(), Global.NUMERICAL_THREE)) {
                //单证审核、已完成
                wrapper.eq(KwtWaybillOrder::getDriverId, param.getDriverId());
            }

            // 查询这些物流订单对应的运单
            List<KwtWaybillOrder> waybillsByLogOrder = waybillOrderRepository.list(wrapper);

            waybillOrderIds.addAll(waybillsByLogOrder.stream()
                    .map(KwtWaybillOrder::getId)
                    .collect(Collectors.toList()));
        }
    }

    /**
     * 从托运单位查询匹配运单ID
     */
    private void addMatchedIdsFromShipper(Set<Long> waybillOrderIds, String keyword, WaybillOrderQueryParam param) {
        List<KwtLogisticsOrderUnit> orderUnits = logisticsOrderUnitRepository.list(
                Wrappers.<KwtLogisticsOrderUnit>lambdaQuery()
                        .eq(KwtLogisticsOrderUnit::getUnitType, UnitTypeEnum.CONSIGN.getCode())
                        .like(KwtLogisticsOrderUnit::getFirmName, keyword)
                        .eq(KwtLogisticsOrderUnit::getDelFlag, 0)
        );
        if (CollectionUtils.isNotEmpty(orderUnits)) {
            List<Long> matchedLogOrderIds = orderUnits.stream()
                    .map(KwtLogisticsOrderUnit::getLOrderId)
                    .collect(Collectors.toList());

            LambdaQueryWrapper<KwtWaybillOrder> wrapper = Wrappers.<KwtWaybillOrder>lambdaQuery()
                    .in(KwtWaybillOrder::getLOrderId, matchedLogOrderIds)
                    .eq(KwtWaybillOrder::getEntId, param.getEntId())
                    .eq(KwtWaybillOrder::getDelFlag, 0);
            if (Objects.equals(param.getStatus(), Global.NUMERICAL_ONE)) {
                //进行中
                wrapper.eq(KwtWaybillOrder::getTruckNo, param.getTruckNo());
            } else if (Objects.equals(param.getStatus(), Global.NUMERICAL_TWO) || Objects.equals(param.getStatus(), Global.NUMERICAL_THREE)) {
                //单证审核、已完成
                wrapper.eq(KwtWaybillOrder::getDriverId, param.getDriverId());
            }

            // 查询这些物流订单对应的运单
            List<KwtWaybillOrder> waybillsByUnits =  waybillOrderRepository.list(wrapper);

            waybillOrderIds.addAll(waybillsByUnits.stream()
                    .map(KwtWaybillOrder::getId)
                    .collect(Collectors.toList()));
        }
    }

    /**
     * 从货物名称查询匹配运单ID
     */
    private void addMatchedIdsFromGoodsName(Set<Long> waybillOrderIds, String keyword, WaybillOrderQueryParam param) {
        List<KwtLogisticsOrderGoods> orderGoods = logisticsOrderGoodsRepository.list(
                Wrappers.<KwtLogisticsOrderGoods>lambdaQuery()
                        .like(KwtLogisticsOrderGoods::getGoodsName, keyword)
                        .eq(KwtLogisticsOrderGoods::getDelFlag, 0)
        );
        if (CollectionUtils.isNotEmpty(orderGoods)) {
            List<Long> matchedLogOrderIds = orderGoods.stream()
                    .map(KwtLogisticsOrderGoods::getLOrderId)
                    .collect(Collectors.toList());

            LambdaQueryWrapper<KwtWaybillOrder> wrapper = Wrappers.<KwtWaybillOrder>lambdaQuery()
                    .in(KwtWaybillOrder::getLOrderId, matchedLogOrderIds)
                    .eq(KwtWaybillOrder::getEntId, param.getEntId())
                    .eq(KwtWaybillOrder::getDelFlag, 0);
            if (Objects.equals(param.getStatus(), Global.NUMERICAL_ONE)) {
                //进行中
                wrapper.eq(KwtWaybillOrder::getTruckNo, param.getTruckNo());
            } else if (Objects.equals(param.getStatus(), Global.NUMERICAL_TWO) || Objects.equals(param.getStatus(), Global.NUMERICAL_THREE)) {
                //单证审核、已完成
                wrapper.eq(KwtWaybillOrder::getDriverId, param.getDriverId());
            }

            // 查询这些物流订单对应的运单
            List<KwtWaybillOrder> waybillsByGoods = waybillOrderRepository.list(wrapper);

            waybillOrderIds.addAll(waybillsByGoods.stream()
                    .map(KwtWaybillOrder::getId)
                    .collect(Collectors.toList()));
        }
    }

    /**
     * 获取运单关联数据
     * @param param
     * @param records
     * @return
     */
    private List<WaybillOrderStatusResp> getWaybillOrderRelevantData(WaybillOrderQueryParam param, List<KwtWaybillOrder> records) {
        //物流运单id
        List<Long>  wbOrderIdList = records.stream().map(KwtWaybillOrder::getId)
                .filter(Objects::nonNull).distinct().collect(Collectors.toList());
        //物流订单id
        List<Long> logOrderIdList = records.stream().map(KwtWaybillOrder::getLOrderId)
                .filter(Objects::nonNull).distinct().collect(Collectors.toList());

        //子运单
        List<KwtWaybillOrderSubtask> orderSubtaskList = waybillOrderSubtaskRepository.queryByWOrderIds(wbOrderIdList);
        if (CollectionUtils.isEmpty(orderSubtaskList)) {
            log.info("当前车辆辆的无物流子运单，truckNo:{}", param.getTruckNo());
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "当前物流子运单不存在");
        }
        Map<Long, KwtWaybillOrderSubtask> subtaskMap = orderSubtaskList.stream().collect(Collectors.toMap(subtask -> subtask.getWOrderId(),
                Function.identity(), (x, y) -> x));

        //派单信息
        List<KwtLogisticsOrderCirculate> logOrderCirculateList = logisticsOrderCirculateRepository.queryByLogOrderIdsAndTruckNo(logOrderIdList, param.getTruckNo());
        if (CollectionUtils.isEmpty(logOrderCirculateList)) {
            log.info("当前车辆无派单订单，truckNo:{}", param.getTruckNo());
            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_FOUND, "当前车辆无派单订单");
        }
        //车牌关联物流订单
        Map<Long, KwtLogisticsOrderCirculate> logOrderIdAndCirculateMap = logOrderCirculateList.stream().collect(
                Collectors.toMap(KwtLogisticsOrderCirculate::getLOrderId, Function.identity(), (x, y) -> x));

        //物流订单
        List<KwtLogisticsOrder> logOrderList = logisticsOrderRepository.queryByLogisticsOrderIds(logOrderIdList);
        if (CollectionUtils.isEmpty(logOrderList)) {
            log.info("当前车辆无物流订单，truckNo:{}", param.getTruckNo());
            throw new BusinessPlatfromException(ErrorCodeEnum.DRIVER_STATUS_ERROR, "当前车辆无物流订单");
        }

        // 按照order_type区分“正常订单”和“原矿运输订单”
        Map<Boolean, List<KwtLogisticsOrder>> partitionedMap = logOrderList.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<WaybillOrderStatusResp> ordderList = new ArrayList<>();
        //1.查询正常流程物流运运单
        if (CollectionUtils.isNotEmpty(typeNullList)) {
            List<WaybillOrderStatusResp> normalOrdderList = getWaybillOrderStatusResps(param, records, typeNullList,
                    orderSubtaskList, wbOrderIdList, subtaskMap, logOrderIdAndCirculateMap, Boolean.FALSE);
            ordderList.addAll(normalOrdderList);
        }

        //2.查询原矿运输物流运运单
        if (CollectionUtils.isNotEmpty(typeOneList)) {
            List<WaybillOrderStatusResp> rawOreOrdderList = getWaybillOrderStatusResps(param, records, typeOneList,
                    orderSubtaskList,wbOrderIdList, subtaskMap, logOrderIdAndCirculateMap, Boolean.TRUE);
            ordderList.addAll(rawOreOrdderList);
        }

        return ordderList;
    }

    /**
     * 查询正常流程物流运单
     * @param param
     * @return
     */
    private List<WaybillOrderStatusResp> getWaybillOrderStatusResps(WaybillOrderQueryParam param, List<KwtWaybillOrder> records,
                                                                    List<KwtLogisticsOrder> logOrderList,
                                                                    List<KwtWaybillOrderSubtask> orderSubtaskList,
                                                                    List<Long> wbOrderIdList,
                                                                    Map<Long, KwtWaybillOrderSubtask> subtaskMap,
                                                                    Map<Long, KwtLogisticsOrderCirculate> logOrderIdAndCirculateMap,
                                                                    boolean isRawOre) {
        log.info("开始{}物流运单查询，param:{}", isRawOre ? "原矿运输" : "正常流程", JSON.toJSONString(param));
        List<Long> logOrderIdList = logOrderList.stream().map(KwtLogisticsOrder::getId).filter(Objects::nonNull).collect(Collectors.toList());
        // 物流订单映射
        Map<Long, KwtLogisticsOrder> logOrderMap = logOrderList.stream().collect(Collectors.toMap(KwtLogisticsOrder::getId,
                Function.identity(), (x, y) -> x));

        // 贸易订单相关（仅非原矿运输查询）
        Map<Long, OrderDetailVo> tradeIdAndOrderDetailVoMap;
        Map<Long, List<KwtLogisticsOrder>> tradeIdAndLogOrderList;
        Map<String, OrderUnitInfoDetailVO> tOrderIdAndUnitMap;
        if (!isRawOre) {
            Set<Long> tradeIds = logOrderList.stream().map(KwtLogisticsOrder::getTOrderId).collect(Collectors.toSet());
            //获取贸易订单
            List<OrderDetailVo> orderDetailVos = tradeOrderInfoService.queryByTradeOrderIds(tradeIds);
            if (CollectionUtils.isEmpty(orderDetailVos)) {
                log.info("当前车辆的贸易订单无数据，truckNo:{}", param.getTruckNo());
                throw new BusinessPlatfromException(ErrorCodeEnum.TRADE_ORDER_NOT_FOUND, "当前车辆的贸易订单数据不存在");
            }
            tradeIdAndOrderDetailVoMap = orderDetailVos.stream().collect(Collectors.toMap(OrderDetailVo::getId,
                    Function.identity(), (x, y) -> x));

            tradeIdAndLogOrderList = logOrderList.stream().collect(Collectors.groupingBy(KwtLogisticsOrder::getTOrderId));

            //贸易企业
            List<OrderUnitInfoDetailVO> orderUnitDetailVOS = tradeOrderInfoService.queryOrderUnitInfByTOrderId(tradeIds);
            if (CollectionUtils.isEmpty(orderUnitDetailVOS)) {
                log.info("交易订单无关联采取/销售企业，tradeOrderIds:{}", JSON.toJSONString(tradeIds));
                throw new BusinessPlatfromException(ErrorCodeEnum.TRADE_ORDER_NOT_ENT, "交易订单无关联采取/销售企业");
            }
            tOrderIdAndUnitMap = orderUnitDetailVOS.stream().collect(Collectors.toMap(
                    unit -> unit.getTOrderId() + "-" + unit.getUnitType(), Function.identity(), (x, y) -> x));

        } else {
            tradeIdAndOrderDetailVoMap = new HashMap<>();
            tradeIdAndLogOrderList = new HashMap<>();
            tOrderIdAndUnitMap = new HashMap<>();
        }

        // 子任务分组
        Map<Long, List<KwtWaybillOrderSubtask>> logisticsOrderIdAndSubtaskList = orderSubtaskList.stream()
                .collect(Collectors.groupingBy(KwtWaybillOrderSubtask::getLOrderId));

        //物流订单商品
        List<KwtLogisticsOrderGoods> logOrderGoods = logisticsOrderGoodsRepository.queryByLogOrderIds(logOrderIdList);
        if (CollectionUtils.isEmpty(logOrderGoods)) {
            log.info("当前车辆的物流订单无商品信息，truckNo:{}", param.getTruckNo());
            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_GOODS, "当前车辆的物流订单无商品信息");
        }
        //物流id映射商品
        Map<Long, KwtLogisticsOrderGoods> logOrderIdAndGoodsMap = logOrderGoods.stream().collect(
                Collectors.toMap(KwtLogisticsOrderGoods::getLOrderId, Function.identity(), (x, y) -> x));

        //交易商品信息
        List<Long> goodsIds = logOrderGoods.stream().map(KwtLogisticsOrderGoods::getGoodsId).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(goodsIds)) {
            log.info("物流订单无关联商品信息，logOrderId:{}", JSON.toJSONString(logOrderIdList));
            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_GOODS, "物流订单无关联商品信息");
        }
        Map<Long, KwpGoods> goodsIdAndGoodsMap = goodsInfoService.getGoodsByIds(goodsIds);

        //承运托运企业
        List<KwtLogisticsOrderUnit> logOrderUnits = logisticsOrderUnitRepository.queryByLogOrderIds(logOrderIdList);
        if (CollectionUtils.isEmpty(logOrderUnits)) {
            log.info("物流订单无关联承运托运企业，logOrderId:{}", JSON.toJSONString(logOrderIdList));
            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_ENT, "物流订单无关联承运托运企业");
        }
        Map<String, KwtLogisticsOrderUnit> logOrderIdAndUnitMap = logOrderUnits.stream().collect(
                Collectors.toMap(unit -> unit.getLOrderId() + "-" + unit.getUnitType(),
                        Function.identity(), (x, y) -> x));
        //地址
        Map<String, KwtLogisticsOrderAddress> logOrderIdAndAddressMap = getKwtLogisticsOrderAddressMap(logOrderIdList);

        //装卸货信息
        List<KwtWaybillOrderTicket> orderTicketList = waybillOrderTicketRepository.queryByWOrderIds(wbOrderIdList);
        if (CollectionUtils.isEmpty(orderTicketList)) {
            log.info("当前车辆无物流运单装卸货信息，truckNo:{}", param.getTruckNo());
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_TICKET, "当前车辆无物流运单装卸货信息");
        }
        Map<String, KwtWaybillOrderTicket> ticketMap = orderTicketList.stream()
                .collect(Collectors.toMap(ticket -> ticket.getWOrderId() + "-" + ticket.getType(),
                        Function.identity(), (x, y) -> x));

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

        List<WaybillOrderStatusResp> orderList = records.stream()
                .filter(record -> record.getLOrderId() != null && logOrderIdList.contains(record.getLOrderId()))
                .map(billOrder -> {
                    return getWaybillOrderResp(billOrder, subtaskMap, logOrderMap, logOrderIdAndCirculateMap,
                            logOrderIdAndGoodsMap, logOrderIdAndUnitMap, logOrderIdAndAddressMap, ticketMap,
                            tradeIdAndOrderDetailVoMap,tradeIdAndLogOrderList,logisticsOrderIdAndSubtaskList,
                            dictValueAndDictResDtoMap, goodsIdAndGoodsMap, tOrderIdAndUnitMap);
                }).collect(Collectors.toList());
        log.info("{}物流运单查询结束，result:{}", isRawOre ? "原矿运输" : "正常流程", JSON.toJSONString(orderList));
        return orderList;
    }


    /**
     * 组装运单列表信息
     * @param order
     * @param logOrderIdAndGoodsMap
     * @param logOrderIdAndUnitMap
     * @param logOrderIdAndAddressMap
     * @return
     */
    private WaybillOrderStatusResp getWaybillOrderResp(KwtWaybillOrder wbOrder,  Map<Long, KwtWaybillOrderSubtask> subtaskMap,
                                                       Map<Long, KwtLogisticsOrder> logOrderMap,
                                                       Map<Long, KwtLogisticsOrderCirculate> logOrderIdAndCirculateMap,
                                                       Map<Long, KwtLogisticsOrderGoods> logOrderIdAndGoodsMap,
                                                       Map<String, KwtLogisticsOrderUnit> logOrderIdAndUnitMap,
                                                       Map<String, KwtLogisticsOrderAddress> logOrderIdAndAddressMap,
                                                       Map<String, KwtWaybillOrderTicket> ticketMap,
                                                       Map<Long, OrderDetailVo> tradeIdAndOrderDetailVoMap,
                                                       Map<Long, List<KwtLogisticsOrder>> tradeIdAndLogOrderList ,
                                                       Map<Long, List<KwtWaybillOrderSubtask>> logisticsOrderIdAndSubtaskList,
                                                       Map<String, Map<String, String>> dictValueAndDictResDtoMap,
                                                       Map<Long, KwpGoods> goodsIdAndGoodsMap,
                                                       Map<String, OrderUnitInfoDetailVO> tOrderIdAndUnitMap) {
        WaybillOrderStatusResp wbOrderResp = new WaybillOrderStatusResp();
        wbOrderResp.setId(wbOrder.getId());
        wbOrderResp.setLogisticsOrderId(Optional.ofNullable(wbOrder.getLOrderId()).map(String::valueOf).orElse(null));
        wbOrderResp.setWaybillNo(wbOrder.getWOrderNo());
        wbOrderResp.setRemark(wbOrder.getRemark());
        wbOrderResp.setLabel(wbOrder.getLabel());
        wbOrderResp.setUpdateTime(wbOrder.getUpdateTime());
        wbOrderResp.setPassReason(wbOrder.getPassReason());
        wbOrderResp.setPassUrl(wbOrder.getPassUrl());
        //装货、卸货净重、任务量
        KwtWaybillOrderSubtask subtask = subtaskMap.getOrDefault(wbOrder.getId(), new KwtWaybillOrderSubtask());
        wbOrderResp.setLoadingNetWeight(subtask.getLoadAmount());
        wbOrderResp.setUnloadingNetWeight(subtask.getUnloadAmount());
        wbOrderResp.setTaskNum(subtask.getEntrustAmount());

        //物流订单信息
        KwtLogisticsOrder logOrder = logOrderMap.getOrDefault(wbOrder.getLOrderId(), new KwtLogisticsOrder());
        wbOrderResp.setLogisticsOrderNo(logOrder.getLOrderNo());
        wbOrderResp.setChargeType(logOrder.getBillingMode());
        wbOrderResp.setChargeTypeDesc(DictEnum.getLabel(DictTypeEnum.CHARGING_TYPE.getType(), logOrder.getBillingMode()));
        wbOrderResp.setOrderType(logOrder.getOrderType());

        //设置余量
        BigDecimal supAmount = Objects.equals(1, logOrder.getOrderType()) ? getRawOreSupAmount(logOrder, logisticsOrderIdAndSubtaskList)
                : getSupAmount(logOrder.getTOrderId(), tradeIdAndOrderDetailVoMap, tradeIdAndLogOrderList, logisticsOrderIdAndSubtaskList);
        wbOrderResp.setOrderSurplus(supAmount);

        //托运企业
        KwtLogisticsOrderUnit consignEnt = logOrderIdAndUnitMap.getOrDefault(wbOrder.getLOrderId() + "-" + UnitTypeEnum.CONSIGN.getCode(), new KwtLogisticsOrderUnit());
        wbOrderResp.setConsignCompanyId(Optional.ofNullable(consignEnt.getEntId()).map(String::valueOf).orElse(null));
        wbOrderResp.setConsignCompanyName(consignEnt.getFirmName());

        //采购单位
        OrderUnitInfoDetailVO proEnt = tOrderIdAndUnitMap.getOrDefault(logOrder.getTOrderId() + "-" + "1", new OrderUnitInfoDetailVO());
        wbOrderResp.setPrEntId(proEnt.getEntId());
        wbOrderResp.setPrEntName(proEnt.getFirmName());

        //商品信息
        KwtLogisticsOrderGoods orderGoods = logOrderIdAndGoodsMap.getOrDefault(wbOrder.getLOrderId(), new KwtLogisticsOrderGoods());
        KwpGoods goods = goodsIdAndGoodsMap.getOrDefault(orderGoods.getGoodsId(), new KwpGoods());
        if (Objects.nonNull(goods)){
            wbOrderResp.setGoodsId(Optional.ofNullable(goods.getId()).map(String::valueOf).orElse(null));
            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<>());
            wbOrderResp.setGoodsName(goods.getName()+"/"+goodsTypeMap.getOrDefault(goods.getGoodsType(),"")+"/"+goodsSpecMap.getOrDefault(goods.getSpec(), ""));
        }

        //装货地址
        KwtLogisticsOrderAddress shipmentAddress = logOrderIdAndAddressMap.getOrDefault(wbOrder.getLOrderId() + "-" + AddressTypeEnum.SHIPMENT.getCode(), new KwtLogisticsOrderAddress());
        wbOrderResp.setLoadAddress(shipmentAddress.getCityName()+shipmentAddress.getDetailAddress());
        wbOrderResp.setLoadLng(shipmentAddress.getLng());
        wbOrderResp.setLoadLat(shipmentAddress.getLat());
        //卸货地址
        KwtLogisticsOrderAddress takeAddress = logOrderIdAndAddressMap.getOrDefault(wbOrder.getLOrderId() + "-" + AddressTypeEnum.TAKE.getCode(), new KwtLogisticsOrderAddress());
        wbOrderResp.setUnloadAddress(takeAddress.getCityName()+takeAddress.getDetailAddress());
        wbOrderResp.setUnloadLng(takeAddress.getLng());
        wbOrderResp.setUnloadLat(takeAddress.getLat());
        //装卸地之间距离
        wbOrderResp.setDistanceKm(logOrder.getDistance());

        //皮重、毛重
        KwtWaybillOrderTicket tareAmountTicket = ticketMap.getOrDefault(wbOrder.getId() + "-" + AddressTypeEnum.SHIPMENT.getCode(), new KwtWaybillOrderTicket());
        wbOrderResp.setTareAmount(tareAmountTicket.getTareAmount());
        wbOrderResp.setGrossAmount(tareAmountTicket.getGrossAmount());

        //司机信息
        wbOrderResp.setDriverId(wbOrder.getDriverId());
        wbOrderResp.setDriverName(wbOrder.getDriverName());
        wbOrderResp.setDriverPhone(wbOrder.getDriverPhone());

        //派车信息
        KwtLogisticsOrderCirculate orderCirculate = logOrderIdAndCirculateMap.getOrDefault(wbOrder.getLOrderId(), new KwtLogisticsOrderCirculate());
        wbOrderResp.setSendTime(DateUtils.format(orderCirculate.getCreateTime(), DateUtils.DATE_TIME_PATTERN));
        //法定载重
        RTruckVo truckByTruckNo = remoteFleetService.findTruckByTruckNo(orderCirculate.getTruckNo());
        if (truckByTruckNo != null) {
            wbOrderResp.setLegalLoad(truckByTruckNo.getLegalLoad());
        }

        //派单人信息
        UserCacheResDto userCacheResDto = remoteSystemService.queryUserCacheById(orderCirculate.getCreateBy());
        wbOrderResp.setSendOperator(Optional.ofNullable(userCacheResDto).map(UserCacheResDto::getName).orElse(null));
        wbOrderResp.setSendPhone(Optional.ofNullable(userCacheResDto).map(UserCacheResDto::getPhone).orElse(null));

        //状态
        wbOrderResp.setStatus(wbOrder.getStatus());
        // 使用已定义的常量集合来判断状态
        if (UNDER_WAY.contains(wbOrder.getStatus())) {
            wbOrderResp.setStatusDesc("进行中");
        } else if (Objects.equals(wbOrder.getStatus(), CarWaybillV1Enum.COMPLETION_LOADING.getCode())) {
            wbOrderResp.setStatusDesc("待审核");
        } else if (Objects.equals(wbOrder.getStatus(), CarWaybillV1Enum.COMPLETED.getCode())) {
            if (Objects.equals(subtask.getRemark(), "空载离场")) {
                wbOrderResp.setStatusDesc("空载完成");
            } else {
                wbOrderResp.setStatusDesc("已完成");
            }
        } else if (Objects.equals(wbOrder.getStatus(), CarWaybillV1Enum.REVIEW_REJECTION.getCode())) {
            wbOrderResp.setStatusDesc("待修改");
        } else if (Objects.equals(wbOrder.getStatus(), CarWaybillV1Enum.CANCELLED.getCode())) {
            wbOrderResp.setStatusDesc("已取消");
        } else {
            wbOrderResp.setStatusDesc("未知状态");
        }

        // 原矿运输订单计算是否超过货损率
        if (Objects.equals(logOrder.getOrderType(), 1)) {
            //装货净重
            BigDecimal loadAmount = tareAmountTicket.getAmount();
            //卸货净重
            KwtWaybillOrderTicket unloadTicket = ticketMap.getOrDefault(wbOrder.getId() + "-" + 2, new KwtWaybillOrderTicket());
            BigDecimal unloadAmount = unloadTicket.getAmount();

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

        return wbOrderResp;

    }

    /**
     * 计算货损率
     */
    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("[门卫]开始计算货损率是否超过配置值，物流订单:{}，货损率：{}", com.alibaba.fastjson2.JSON.toJSONString(logOrder), com.alibaba.fastjson2.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("[门卫]计算货损率是否超过配置值完成，配置的货损率：{}", com.alibaba.fastjson.JSON.toJSONString(allowedError));
        return lossRate.compareTo(allowedError) > 0;
    }

    /**
     * 计算贸易订单余量
     * 逻辑：贸易订单总量 - (所有关联物流订单下，非取消/完成状态的子运单委托量 + 对应计费模式的磅单量)
     *
     * @param tradeOrderId                贸易订单ID
     * @param tradeIdAndOrderDetailVoMap  贸易订单详情映射
     * @param tradeIdAndLogOrderList      贸易订单关联的物流订单列表映射
     * @param logisticsOrderIdAndSubtaskList 物流订单关联的子运单列表映射
     * @param waybillOrderIdAndTicketList    运单ID关联的磅单列表映射
     * @return 订单余量，保留两位小数
     */
    private BigDecimal getSupAmount(Long tradeOrderId,
                                    Map<Long, OrderDetailVo> tradeIdAndOrderDetailVoMap,
                                    Map<Long, List<KwtLogisticsOrder>> tradeIdAndLogOrderList,
                                    Map<Long, List<KwtWaybillOrderSubtask>> logisticsOrderIdAndSubtaskList) {
        log.debug("开始计算贸易订单余量，tradeOrderId: {}", tradeOrderId);

        // 1. 获取贸易订单总货物量
        OrderDetailVo detailVo = tradeIdAndOrderDetailVoMap.getOrDefault(tradeOrderId, new OrderDetailVo());
        BigDecimal tradeAmount = Optional.ofNullable(detailVo).map(OrderDetailVo::getAmount).orElse(BigDecimal.ZERO);
        log.debug("贸易订单[{}]总货物量: {}", tradeOrderId, tradeAmount);

        // 2. 获取该贸易订单下的所有物流订单
        List<KwtLogisticsOrder> kwtLogisticsOrders = tradeIdAndLogOrderList.get(tradeOrderId);
        
        // 已占用总量初始化
        BigDecimal usedAmount = BigDecimal.ZERO;

        if (CollectionUtils.isNotEmpty(kwtLogisticsOrders)) {
            log.debug("贸易订单[{}]关联物流订单数量: {}", tradeOrderId, kwtLogisticsOrders.size());
            
            for (KwtLogisticsOrder kwtLogisticsOrder : kwtLogisticsOrders) {
                Long logOrderId = kwtLogisticsOrder.getId();
                // 获取当前物流订单下的所有子运单
                List<KwtWaybillOrderSubtask> waybillOrderSubtasks = logisticsOrderIdAndSubtaskList.getOrDefault(logOrderId, Collections.emptyList());
                
                if (CollectionUtils.isEmpty(waybillOrderSubtasks)) {
                    log.debug("物流订单[{}]无子运单，跳过", logOrderId);
                    continue;
                }

                // 定义需要剔除的状态：已取消、已完成、空载（这些状态下的运单不再占用当前可接单的余量，或者其量已结算）
                // 注意：具体业务逻辑中，通常“进行中”的运单会占用余量。这里根据原代码逻辑，剔除CANCELLED和COMPLETED。
                //      空载待离场，实际装货量接近0,所以也要剔除
                List<Integer> excludeStatusList = Arrays.asList(CarWaybillV1Enum.CANCELLED.getCode(), CarWaybillV1Enum.COMPLETED.getCode()
                        , CarWaybillV1Enum.EMPTY_WAIT_LEAVE.getCode());

                // 4. 计算子运单委托量合计（仅统计未取消/未完成/空载的有效子运单）
                BigDecimal entrustAmount = waybillOrderSubtasks.stream()
                        .filter(Objects::nonNull)
                        .filter(subtask -> !excludeStatusList.contains(subtask.getStatus()))
                        .map(KwtWaybillOrderSubtask::getEntrustAmount)
                        .filter(Objects::nonNull)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                
                log.debug("物流订单[{}]子运单委托量合计: {}", logOrderId, entrustAmount);

                // 5. 计算运单已完成的合计量
                BigDecimal totalLoadAmount = kwtLogisticsOrders.stream().filter(Objects::nonNull)
                        .map(KwtLogisticsOrder::getTotalLoadAmount)
                        .filter(Objects::nonNull)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);

                log.debug("物流订单[{}]有完成的运单实际装货量合计: {}", logOrderId, totalLoadAmount);

                // 累加到总占用量
                usedAmount = usedAmount.add(entrustAmount).add(totalLoadAmount);
            }
        }

        log.debug("贸易订单[{}]总占用量: {}", tradeOrderId, usedAmount);

        // 6. 计算余量：贸易订单总量 - 已占用量
        // 如果计算结果小于等于0，则余量为0，避免负数
        BigDecimal surplus = tradeAmount.subtract(usedAmount);
        BigDecimal finalSurplus = surplus.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : surplus;
        
        // 保留两位小数，四舍五入
        BigDecimal result = finalSurplus.setScale(2, RoundingMode.HALF_UP);
        log.debug("贸易订单[{}]最终余量: {}", tradeOrderId, result);
        
        return result;
    }


    /**
     * 计算贸易订单余量
     * 逻辑：贸易订单总量 - (所有关联物流订单下，非取消/完成状态的子运单委托量 + 对应计费模式的磅单量)
     *
     * @param tradeOrderId                贸易订单ID
     * @param tradeIdAndOrderDetailVoMap  贸易订单详情映射
     * @param tradeIdAndLogOrderList      贸易订单关联的物流订单列表映射
     * @param logisticsOrderIdAndSubtaskList 物流订单关联的子运单列表映射
     * @param waybillOrderIdAndTicketList    运单ID关联的磅单列表映射
     * @return 订单余量，保留两位小数
     */
    private BigDecimal getRawOreSupAmount(KwtLogisticsOrder order,
                                          Map<Long, List<KwtWaybillOrderSubtask>> logisticsOrderIdAndSubtaskList) {
        log.debug("开始计算物流订单余量，param: {}", JSON.toJSONString(order));

        // 1. 获取贸易订单总货物量
        BigDecimal tradeAmount = order.getAmount();
        log.debug("物流订单[{}]总货物量: {}", order.getId(), tradeAmount);

        Long logOrderId = order.getId();
        // 获取当前物流订单下的所有子运单
        List<KwtWaybillOrderSubtask> waybillOrderSubtasks = logisticsOrderIdAndSubtaskList.getOrDefault(logOrderId, Collections.emptyList());

        if (CollectionUtils.isEmpty(waybillOrderSubtasks)) {
            BigDecimal tradeTotalAmount = tradeAmount.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : tradeAmount;
            BigDecimal bigDecimal = tradeTotalAmount.setScale(2, RoundingMode.HALF_UP);
            log.debug("物流订单[{}]无子运单，跳过, 最终余量: {}",logOrderId, bigDecimal);
            return bigDecimal;
        }

        // 定义需要剔除的状态：已取消、已完成、空载（这些状态下的运单不再占用当前可接单的余量，或者其量已结算）
        // 注意：具体业务逻辑中，通常“进行中”的运单会占用余量。这里根据原代码逻辑，剔除CANCELLED和COMPLETED。
        //      空载待离场，实际装货量接近0,所以也要剔除
        List<Integer> excludeStatusList = Arrays.asList(CarWaybillV1Enum.CANCELLED.getCode(), CarWaybillV1Enum.COMPLETED.getCode()
                , CarWaybillV1Enum.EMPTY_WAIT_LEAVE.getCode());

        // 4. 计算子运单委托量合计（仅统计未取消/未完成/空载的有效子运单）
        BigDecimal entrustAmount = waybillOrderSubtasks.stream()
                .filter(Objects::nonNull)
                .filter(subtask -> !excludeStatusList.contains(subtask.getStatus()))
                .map(KwtWaybillOrderSubtask::getEntrustAmount)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        log.debug("物流订单[{}]子运单委托量合计: {}", logOrderId, entrustAmount);

        // 5. 计算运单已完成的合计量
        BigDecimal totalLoadAmount = order.getTotalLoadAmount();
        totalLoadAmount = totalLoadAmount == null || totalLoadAmount.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : totalLoadAmount;
        log.debug("物流订单[{}]有完成的运单实际装货量合计: {}", logOrderId, totalLoadAmount);

        // 累加到总占用量
        BigDecimal usedAmount = entrustAmount.add(totalLoadAmount);

        log.debug("物流订单[{}]总占用量: {}", logOrderId, usedAmount);

        // 6. 计算余量：贸易订单总量 - 已占用量
        // 如果计算结果小于等于0，则余量为0，避免负数
        BigDecimal surplus = tradeAmount.subtract(usedAmount);
        BigDecimal finalSurplus = surplus.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : surplus;

        // 保留两位小数，四舍五入
        BigDecimal result = finalSurplus.setScale(2, RoundingMode.HALF_UP);
        log.debug("物流订单[{}]最终余量: {}", logOrderId, result);

        return result;
    }

    /**
     * 批量构建运单ID与磅单信息映射，供订单余量计算复用。
     */
    private Map<Long, List<KwtWaybillOrderTicket>> getWaybillOrderIdAndTicketList(List<KwtWaybillOrderSubtask> orderSubtaskList) {
        if (CollectionUtils.isEmpty(orderSubtaskList)) {
            return Collections.emptyMap();
        }
        List<Long> waybillOrderIds = orderSubtaskList.stream()
                .filter(Objects::nonNull)
                .map(KwtWaybillOrderSubtask::getWOrderId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(waybillOrderIds)) {
            return Collections.emptyMap();
        }
        List<KwtWaybillOrderTicket> ticketList = waybillOrderTicketRepository.queryByWOrderIds(waybillOrderIds);
        if (CollectionUtils.isEmpty(ticketList)) {
            return Collections.emptyMap();
        }
        return ticketList.stream()
                .filter(Objects::nonNull)
                .collect(Collectors.groupingBy(KwtWaybillOrderTicket::getWOrderId));
    }

    /**
     * 排序
     * @param param
     * @param gatekeeperOrderPageResult
     */
    private void sort(WaybillOrderQueryParam param, List<WaybillOrderStatusResp> ordderList) {
        log.info("运单分页列表排序，param:{}, order:{}", JSON.toJSONString(param), JSON.toJSONString(ordderList));
        if (CollectionUtils.isEmpty(ordderList)) {
            return;
        }
        // 完成运单，根据时间倒叙排列
        if (Objects.equals(3, param.getStatus())) {
            ordderList.sort(Comparator.comparing(WaybillOrderStatusResp::getUpdateTime).reversed());
        }
    }

    /**
     * 运单统计
     * @param param
     * @return
     */
    public StatisticsWaybillResp statisticsWaybillOrder(WaybillOrderQueryParam param) {
        log.info("运单状态统计，参数：{}", JSON.toJSONString(param));
        StatisticsWaybillResp waybillResp = new StatisticsWaybillResp();
        if (StringUtils.isBlank(param.getTruckNo())) {
            // 车牌号为空时，返回默认的三种状态
            waybillResp.setOrderStatusStatistics(buildDefaultStatusStatistics());
            return waybillResp;
        }
        //构建查询条件并获取运单数据
        LambdaQueryWrapper<KwtWaybillOrder> queryWrapper = buildAndExecuteQuery(param);
        List<KwtWaybillOrder> records = waybillOrderRepository.list(queryWrapper);
        if (CollectionUtils.isEmpty(records)) {
            log.info("当前车辆辆的无物流运单，统计结果为空， truckNo:{}", param.getTruckNo());
            waybillResp.setOrderStatusStatistics(buildDefaultStatusStatistics());
            return waybillResp;
        }

        //查询运单关联数据
//        List<WaybillOrderStatusResp> waybillOrdertDatas = getWaybillOrderRelevantData(param, records);
        waybillResp.setOrderStatusStatistics(calculateStatusStatistics(param, records));
        return waybillResp;
    }


    /**
     * 构建默认的状态统计列表（三种状态，数量均为0）
     * @return 默认统计列表
     */
    private List<StatisticsWaybillResp.OrderBillStatusStatistics> buildDefaultStatusStatistics() {
        List<StatisticsWaybillResp.OrderBillStatusStatistics> defaultList = new ArrayList<>();
        // 进行中
        StatisticsWaybillResp.OrderBillStatusStatistics underWay = new StatisticsWaybillResp.OrderBillStatusStatistics();
        underWay.setOrderStatus("1");
        underWay.setOrderStatusDesc("进行中");
        underWay.setOrderNum("0");
        defaultList.add(underWay);
        // 单证审核
        StatisticsWaybillResp.OrderBillStatusStatistics review = new StatisticsWaybillResp.OrderBillStatusStatistics();
        review.setOrderStatus("2");
        review.setOrderStatusDesc("单证审核");
        review.setOrderNum("0");
        defaultList.add(review);
        // 已完成
        StatisticsWaybillResp.OrderBillStatusStatistics completed = new StatisticsWaybillResp.OrderBillStatusStatistics();
        completed.setOrderStatus("3");
        completed.setOrderStatusDesc("已完成");
        completed.setOrderNum("0");
        defaultList.add(completed);
        return defaultList;
    }

    /**
     * 计算运单状态统计
     * @param records
     * @return
     */
    private static List<StatisticsWaybillResp.OrderBillStatusStatistics> calculateStatusStatistics(WaybillOrderQueryParam param, List<KwtWaybillOrder> records) {
        // 定义状态码聚合规则
        Map<List<String>, String[]> aggregateRules = Map.of(
                Arrays.asList("1", "5", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21"), new String[]{"1", "进行中"},
                Arrays.asList("23", "30"), new String[]{"2", "单证审核"},
                Arrays.asList("25", "99"), new String[]{"3", "已完成"}
        );

        // 按原始状态统计数量
        Map<String, Long> statusCountMap = records.stream()
                .collect(Collectors.groupingBy(va ->String.valueOf(va.getStatus()), Collectors.counting()));

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

                    // 汇总对应状态的数量
                    long totalNum;
                    // ===================== 你要的过滤逻辑 =====================
                    if ("1".equals(aggStatus)) {
                        // 状态1：按truckNo过滤
                        totalNum = records.stream()
                                .filter(va -> originalStatuses.contains(String.valueOf(va.getStatus())))
                                .filter(va -> Objects.equals(va.getTruckNo(), param.getTruckNo()))
                                .count();
                    } else {
                        // 状态2、3：按driverId过滤
                        totalNum = records.stream()
                                .filter(va -> originalStatuses.contains(String.valueOf(va.getStatus())))
                                .filter(va -> Objects.equals(va.getDriverId(), param.getDriverId()))
                                .count();
                    }
                    // 构建聚合结果对象
                    StatisticsWaybillResp.OrderBillStatusStatistics aggregateStat = new StatisticsWaybillResp.OrderBillStatusStatistics();
                    aggregateStat.setOrderStatus(aggStatus); // 聚合状态编码
                    aggregateStat.setOrderStatusDesc(aggDesc); // 聚合状态描述
                    aggregateStat.setOrderNum(String.valueOf(totalNum)); // 汇总数量
                    return aggregateStat;
                })
                .sorted(Comparator.comparing(StatisticsWaybillResp.OrderBillStatusStatistics::getOrderStatus))
                .collect(Collectors.toList());
        return aggregatedList;
    }

    /**
     * 物流订单接单
     * @param param
     */
    @Transactional(rollbackFor = Exception.class)
    public OrderTakingResp orderTaking(OrderCirculateTakingQueryParam param) {
        // 1. 幂等性校验
        checkIdempotent(param);

        // 2. 构建分布式锁Key（物流订单ID+车牌号 唯一标识）
        String lockKey = TAKING_ORDER_LOCK_PREFIX + param.getLogOrderId() + "_" + param.getTruckNo();
        String requestId = UUID.randomUUID().toString();
        boolean lockAcquired = false;

        try {
            // 3. 获取分布式锁（带重试机制）
            lockAcquired = acquireLock(lockKey, requestId, LOCK_EXPIRE_SECONDS, LOCK_WAIT_MILLIS);
            if (!lockAcquired) {
                log.warn("接单请求获取分布式锁失败，可能存在重复提交，param:{}", JSON.toJSONString(param));
                throw new BusinessPlatfromException(ErrorCodeEnum.REPEAT_SUBMIT, "当前接单请求正在处理中，请稍后再试");
            }

            // 4. 再次幂等性校验（防止锁等待期间已经创建运单）
            checkIdempotent(param);

            // 5. 执行接单
            return takingOrderHandler.handler(param);

        } finally {
            // 6. 释放分布式锁
            if (lockAcquired) {
                releaseLock(lockKey, requestId);
                log.info("释放接单分布式锁成功，lockKey:{}, requestId:{}", lockKey, requestId);
            }
        }
    }

    /**
     * 幂等性校验：检查是否已经存在该车辆针对该物流订单的有效运单
     * @param param 接单参数
     */
    private void checkIdempotent(OrderCirculateTakingQueryParam param) {
        // 查询该物流订单+车牌号+企业下是否已有接单状态运单
        KwtWaybillOrder existingOrder = waybillOrderRepository.findOneByTruckNo(param.getLogOrderId(), param.getTruckNo(), param.getEntId());

        if (existingOrder != null) {
            log.warn("重复接单校验失败，已存在有效运单，logOrderId:{}, truckNo:{}, waybillOrderId:{}",
                    param.getLogOrderId(), param.getTruckNo(), existingOrder.getId());
            throw new BusinessPlatfromException(ErrorCodeEnum.REPEAT_SUBMIT,
                    String.format("该车辆[%s]已针对该物流订单接单，运单ID：%s", param.getTruckNo(), existingOrder.getId()));
        }
    }

    /**
     * 获取分布式锁（带重试机制）
     * @param lockKey       锁Key
     * @param requestId     请求ID（保证只有自己能释放锁）
     * @param expireSeconds 锁过期时间（秒）
     * @param waitMillis    最大等待时间（毫秒）
     * @return 是否获取成功
     */
    private boolean acquireLock(String lockKey, String requestId, long expireSeconds, long waitMillis) {
        long startTime = System.currentTimeMillis();
        while (System.currentTimeMillis() - startTime < waitMillis) {
            // 使用SET NX EX命令获取锁
            Boolean success = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, expireSeconds, TimeUnit.SECONDS);
            if (Boolean.TRUE.equals(success)) {
                log.info("获取接单分布式锁成功，lockKey:{}, requestId:{}", lockKey, requestId);
                return true;
            }

            // 未获取到锁，短暂休眠后重试
            try {
                Thread.sleep(LOCK_RETRY_INTERVAL);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.error("获取锁时线程中断", e);
                return false;
            }
        }

        log.warn("获取接单分布式锁超时，lockKey:{}, waitMillis:{}", lockKey, waitMillis);
        return false;
    }

    /**
     * 释放分布式锁（使用Lua脚本保证原子性）
     * @param lockKey   锁Key
     * @param requestId 请求ID
     */
    private void releaseLock(String lockKey, String requestId) {
        String luaScript = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
        redisScript.setScriptText(luaScript);
        redisScript.setResultType(Long.class);

        Long result = redisTemplate.execute(redisScript, Collections.singletonList(lockKey), requestId);
        if (result == null || result == 0) {
            log.warn("释放接单分布式锁失败，可能锁已过期或被其他请求释放，lockKey:{}, requestId:{}", lockKey, requestId);
        }
    }

    /**
     * 取消订单接单
     * @param param
     */
    @Transactional(rollbackFor = Exception.class)
    public void cancelWaybillOrder(WaybillOrderCancelParam param) {
        cancelHandler.handler(param);
    }

    /**
     * 到达装货地点-手动推推送数据
     * @param param
     */
    @Transactional(rollbackFor = Exception.class)
    public void comeInto(WaybillOrderCmeIntoWeighParam param) {
        log.info("[过磅]开始过磅，入参参数：{}", JSON.toJSONString(param));
        if (StringUtils.isBlank(param.getTruckNo())){
            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "车牌号不能为空！");
        }
        if (param.getWeighAmount() == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "称重重量不能为空！");
        }
        if (param.getWeighbridgeId() == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "地磅id不能为空！");
        }
        // 定义运单可以过磅的状态集合
        List<Integer> FORBIDDEN_STATUSES = Arrays.asList(
                CarWaybillV1Enum.PENDING_VEHICLE.getCode(),
                CarWaybillV1Enum.REFUSE_TRAFFIC.getCode(),
                CarWaybillV1Enum.EXIT_COMPLETED.getCode(),
                CarWaybillV1Enum.EMPTY_WAIT_LEAVE.getCode(),
                CarWaybillV1Enum.WAIT_LEAVE.getCode(),
                CarWaybillV1Enum.UNLOADING.getCode(),
                CarWaybillV1Enum.REPLENISHING.getCode(),
                CarWaybillV1Enum.REPLENISH_FINISH.getCode()
        );
        List<KwtWaybillOrder> waybillOrders = waybillOrderRepository.findWbOrderByTruckNoAndStatus(param.getTruckNo(), FORBIDDEN_STATUSES);
        // 称重过磅
        if (CollectionUtils.isEmpty(waybillOrders)) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_FOUND, "[山上称重过磅]当前车辆没有称重过磅状态的运单!");
        }
        commonComeInto(param, waybillOrders, FORBIDDEN_STATUSES);
        log.info("[过磅]过磅结束！");
    }

    /**
     * 655称重过磅
     * @param param
     * @param waybillOrders
     * @param FORBIDDEN_STATUSES
     */
    private void commonComeInto(WaybillOrderCmeIntoWeighParam param, List<KwtWaybillOrder> waybillOrders, List<Integer> FORBIDDEN_STATUSES) {
        if (waybillOrders.size() > 1) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_FOUND, "[称重过磅]当前车辆过磅称重运单数据存在多条!");
        }
        KwtWaybillOrder waybillOrder = waybillOrders.get(0);
        param.setWaybillOrderId(waybillOrder.getId());
        comeIntoHandler.handler(param);
    }

    /**
     * 获取企业id
     * @param logOrder
     * @return
     */
    private Long getEntId(KwtLogisticsOrder logOrder) {
        log.info("[创建装货门卫]开始查询企业id，入参参数：{}", JSON.toJSONString(logOrder));
        Long entId;
        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(0);
        } else {
            List<OrderUnitInfoDetailVO> unitInfoDetailVOS = tradeOrderInfoService.queryOrderUnitByTradeOrderId(logOrder.getTOrderId());
            OrderUnitInfoDetailVO unitInfoDetailVO = unitInfoDetailVOS.stream()
                    .filter(unit -> Objects.equals(unit.getUnitType(), "2"))
                    .findFirst().orElse(new OrderUnitInfoDetailVO());
            entId = unitInfoDetailVO.getEntId();
        }
        log.info("[创建装货门卫]查询企业id完成，入参参数：{}", JSON.toJSONString(entId));
        return entId;
    }

    /**
     * 装货过磅
     * @param param
     */
    private void comeIntoHandler(WaybillOrderCmeIntoWeighParam param, KwtWaybillOrder waybillOrder) {
        log.info("[装货过磅]开始装货过磅，参数：{}", JSON.toJSONString(param));
        // 定义运单可以过磅的状态集合
        List<Integer> FORBIDDEN_STATUSES = Arrays.asList(
                CarWaybillV1Enum.PENDING_VEHICLE.getCode(),
                CarWaybillV1Enum.REFUSE_TRAFFIC.getCode(),
                CarWaybillV1Enum.EXIT_COMPLETED.getCode(),
                CarWaybillV1Enum.EMPTY_WAIT_LEAVE.getCode(),
                CarWaybillV1Enum.WAIT_LEAVE.getCode(),
                CarWaybillV1Enum.UNLOADING.getCode(),
                CarWaybillV1Enum.REPLENISHING.getCode(),
                CarWaybillV1Enum.REPLENISH_FINISH.getCode()
        );
        if (!FORBIDDEN_STATUSES.contains(waybillOrder.getStatus())) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "[装货过磅]当前车辆没有称重过磅状态的运单");
        }
        param.setWaybillOrderId(waybillOrder.getId());
        comeIntoHandler.handler(param);
        log.info("[装货过磅]装货过磅结束！");
    }

    /**
     * 卸货过磅
     * @param param
     */
    private void unloadingWeighHnadler(WaybillOrderCmeIntoWeighParam param, KwtWaybillOrder waybillOrder) {
        log.info("[卸货过磅]开始装货过磅，参数：{}", JSON.toJSONString(param));
        WaybillOrderUnloadingWeighParam unloadingWeighParam = new WaybillOrderUnloadingWeighParam();
        unloadingWeighParam.setTruckNo(param.getTruckNo());
        unloadingWeighParam.setWeighAmount(param.getWeighAmount());
        unloadingWeighParam.setWeighbridgeId(param.getWeighbridgeId());
        unloadingWeighParam.setWeighbridgeName(param.getWeighbridgeName());
        unloadingWeighParam.setWeighUrl(param.getWeighUrl());

        // 定义运单可以卸货过磅的状态集合
        List<Integer> FORBIDDEN_STATUSES = Arrays.asList(
                CarWaybillV1Enum.WAIT_LOADING.getCode(),
                CarWaybillV1Enum.UNLOADING_POINT.getCode()
        );
        if (!FORBIDDEN_STATUSES.contains(waybillOrder.getStatus())) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "[卸货过磅]当前车辆没有称重过磅状态的运单");
        }
        unloadingWeighParam.setWaybillOrderId(waybillOrder.getId());
        unloadingWeighHandler.handler(unloadingWeighParam);
        log.info("[卸货过磅]卸货过磅结束！");
    }


    /**
     * 已装货 -手动推推送数据
     * @param param
     */
    @Transactional(rollbackFor = Exception.class)
    public void loading(WaybillOrderLoadingParam param) {
        loadingHandler.handler(param);
    }

    /**
     * 离场过磅（计算毛重和净重）-手动推推送数据
     * @param param
     */
    @Transactional(rollbackFor = Exception.class)
    public void leave(WaybillOrderLeaveMockParam param) {
        leaveMockHandler.handler(param);
    }

    /**
     * 空载离场
     * @param param
     */
    public void emptyLoadLeave(WaybillOrderEmptyLoadLeaveParam param) {
        emptyLoadLeaveHandler.handler(param);
    }

    /**
     * 补货
     * @param param
     */
    public void replenish(WaybillOrderReplenishParam param) {
        replenishHandler.handler(param);
    }

    /**
     * 离场
     * @param param
     */
    @Transactional(rollbackFor = Exception.class)
    public void leavedWaybillOrder(WaybillOrderLeaveParam param) {
        leaveHandler.handler(param);
    }

    /**
     * 抬杆放行 mock
     * @param param
     */
    public void liftRodRelease(WaybillOrderLiftRodReleaseParam param){
        liftRodReleaseHandler.handler(param);
    }


    /**
     * 打印榜单
     * @param param
     */
    public void printList(WaybillOrderLiftRodReleaseParam param){
        log.info("运单状态统计，参数：{}", JSON.toJSONString(param));
    }

    /**
     * 卸货过磅
     * @param param
     */
    @Transactional(rollbackFor = Exception.class)
    public void unloadingWeigh(WaybillOrderUnloadingWeighParam param) {
        if (StringUtils.isBlank(param.getTruckNo())){
            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "车牌号不能为空！");
        }
        if (param.getWeighAmount() == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "卸货过磅称重重量不能为空！");
        }
        // 定义运单可以卸货过磅的状态集合
        List<Integer> FORBIDDEN_STATUSES = Arrays.asList(
                CarWaybillV1Enum.WAIT_LOADING.getCode(),
                CarWaybillV1Enum.UNLOADING_POINT.getCode()
        );
        List<KwtWaybillOrder> wbOrderByTruckNo = waybillOrderRepository.findWbOrderByTruckNoAndStatus(param.getTruckNo(), FORBIDDEN_STATUSES);
        if (CollectionUtils.isEmpty(wbOrderByTruckNo) || wbOrderByTruckNo.size() > 1) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_FOUND, "当前车辆没有可以卸货过磅称重状态的运单");
        }
        param.setWaybillOrderId(wbOrderByTruckNo.get(0).getId());
        unloadingWeighHandler.handler(param);
    }


    /**
     * 卸货离场
     * @param param
     */
    @Transactional(rollbackFor = Exception.class)
    public void unloadingLeaved(WaybillOrderUnLoadingLeaveParam param) {
        unloadingLeavedHandler.handler(param);
    }
    
    /**
     * 卸货
     * @param param
     */
    @Transactional(rollbackFor = Exception.class)
    public void unloadingWaybillOrder(WaybillOrderUnloadParam param) {
        unloadingHandler.handler(param);
    }

    /**
     * 过磅推送图片
     * @param param
     */
    public void weighImage(WaybillOrderWeighImageParam param) {
        log.info("[过磅]开始保存图片，入参参数：{}", JSON.toJSONString(param));
        if (StringUtils.isBlank(param.getTruckNo())){
            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "车牌号不能为空！");
        }
        // 定义运单可以过磅的状态集合(无论山上山下地磅)
        List<Integer> FORBIDDEN_STATUSES = Arrays.asList(
                CarWaybillV1Enum.PENDING_VEHICLE.getCode(),
                CarWaybillV1Enum.REFUSE_TRAFFIC.getCode(),
                CarWaybillV1Enum.EXIT_COMPLETED.getCode(),
                CarWaybillV1Enum.EMPTY_WAIT_LEAVE.getCode(),
                CarWaybillV1Enum.WAIT_LEAVE.getCode(),
                CarWaybillV1Enum.UNLOADING.getCode(),
                CarWaybillV1Enum.REPLENISHING.getCode(),
                CarWaybillV1Enum.REPLENISH_FINISH.getCode(),
                CarWaybillV1Enum.WAIT_LOADING.getCode(),
                CarWaybillV1Enum.UNLOADING_POINT.getCode()
        );
        List<KwtWaybillOrder> wbOrderByTruckNo = waybillOrderRepository.findWbOrderByTruckNoAndStatus(param.getTruckNo(), FORBIDDEN_STATUSES);
        if (CollectionUtils.isEmpty(wbOrderByTruckNo)) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_FOUND, "[过磅推送图片]当前车辆没有可以过磅称重状态的运单");
        }
        if (wbOrderByTruckNo.size() > 1) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_FOUND, "[过磅推送图片]当前车辆过磅称重状态存在多条运单");
        }
        KwtWaybillOrder waybillOrder = wbOrderByTruckNo.get(0);
        KwtWaybillOrderNode waybillOrderNode = waybillOrderNodeRepository.queryNodesByOrderId(waybillOrder.getId(), waybillOrder.getStatus());
        if (waybillOrderNode == null) {
            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_FOUND, "[过磅推送图片]未查询运单节点数据");
        }
        waybillOrderNode.setWeighUrl(String.join(",", param.getWeighImageList()));
        waybillOrderNodeRepository.updateById(waybillOrderNode);
        log.info("[过磅]保存图片结束，result：{}", JSON.toJSONString(waybillOrderNode));
    }



//    /**
//     * 物流订单接单
//     * @param param
//     * @return
//     */
//    @Transactional(rollbackFor = Exception.class)
//    public void orderTaking(OrderCirculateTakingQueryParam param){
//        log.info("物流订单接单入参参数：{}", JSON.toJSONString(param));
//
//        //1.校验物流订单
//        KwtLogisticsOrder logOrder = checkLogOrder(param);
//        //2.校验交易订单
//        OrderDetailVo orderDetail = checkTradeOrder(param, logOrder);
//        //3.校验司机
//        RDriverVo driver = checkDriver(param);
//        //4.校验车辆
//        RTruckVo truckNo = checkTruck(param);
//        //5.校验车辆是否已有未完成运单
//        checkTruckUnfinished(param);
//
//        //计算任务量（含接单校验）
//        BigDecimal turckLoadVolume = queryCurTruckLoadVolume(truckNo, orderDetail);
//
//
//        //创建运单及关联数据
//
//        //1、生成物流运单
//        KwtWaybillOrder waybillOrder = createWaybillOrder(param, driver, truckNo);
//
//        //2、生成物流子运单
//        KwtWaybillOrderSubtask waybillOrderSubtask = createWaybillOrderSubtask(param, waybillOrder, turckLoadVolume);
//
//        //3、生成物流运单地址
//        List<KwtWaybillOrderAddress> waybillOrderAdderessList = createWaybillOrderAddress(param, waybillOrder, waybillOrderSubtask);
//
//        //4、生成车辆运单-装卸货信息
//        createWaybillOrderTicket(logOrder, waybillOrder, waybillOrderSubtask, waybillOrderAdderessList, truckNo);
//
//        //5.生成车运单接单节点轨迹
//        createWaybillOrderNode(param, waybillOrder, waybillOrderSubtask);
//
//        //6、更新上游订单：回写贸易订单
//        updateTradeOrder(orderDetail, turckLoadVolume);
//
//        //7、更新上游订单：回写物流订单
//        updateLogOrder(logOrder, turckLoadVolume);
//
//        log.info("物流订单接单完成，运单ID：{}", waybillOrder.getId());
//
//    }
//
//
//
//    /**
//     * 校验物流订单是否是可接单状态
//     * @param param
//     * @return
//     */
//    private KwtLogisticsOrder checkLogOrder(OrderCirculateTakingQueryParam param) {
//        KwtLogisticsOrder logOrder = logisticsOrderRepository.queryByLogOrderIdAndStatus(param.getLogOrderId(), LogisticsOrderV1Enum.IN_TRANSIT.getCode());
//        if (logOrder == null) {
//            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_STATUS_ERROR, "物流订单非可接单状态");
//        }
//        return logOrder;
//    }
//
//    /**
//     * 校验交易订单状态
//     * @param param
//     * @param logOrder
//     * @return
//     */
//    private OrderDetailVo checkTradeOrder(OrderCirculateTakingQueryParam param, KwtLogisticsOrder logOrder) {
//        OrderDetailVo orderDetail = tradeOrderInfoService.queryByTradeOrderId(logOrder.getTOrderId());
//        if (orderDetail == null || orderDetail.getStatus() == Global.NUMERICAL_ONE) {
//            throw new BusinessPlatfromException(ErrorCodeEnum.TRADE_ORDER_STATUS_ERROR, "当前物流订单的交易订单已锁定");
//        }
//        return orderDetail;
//    }
//
//    /**
//     * 校验司机状态
//     * @param param
//     * @return
//     */
//    private RDriverVo checkDriver(OrderCirculateTakingQueryParam param) {
//        RDriverVo driver = remoteFleetService.findDriver(param.getDriverId());
//        if (driver == null || driver.getStatus() == Global.NUMERICAL_ONE) {
//            throw new BusinessPlatfromException(ErrorCodeEnum.DRIVER_STATUS_ERROR, "当前司机已锁定");
//        }
//        return driver;
//    }
//
//    /**
//     * 校验车辆状态
//     * @param param
//     * @return
//     */
//    private RTruckVo checkTruck(OrderCirculateTakingQueryParam param) {
//        RTruckVo truckNo = remoteFleetService.findTruckByTruckNo(param.getTruckNo());
//        if (truckNo == null || truckNo.getStatus() == Global.NUMERICAL_ONE) {
//            throw new BusinessPlatfromException(ErrorCodeEnum.TRUCK_STATUS_ERROR, "当前车辆已锁定");
//        }
//        //核定载重
//        if (truckNo.getActualWeight() == null) {
//            throw new BusinessPlatfromException(ErrorCodeEnum.RESOURCE_NOT_FOUND, "车辆核定载重不能为空！");
//        }
//        return truckNo;
//    }
//
//    /**
//     * 校验车辆是否已有未完成运单(不可继续接单状态：已接单、已入场、已装货、已离场、审核驳回)
//     * @param param
//     */
//    private void checkTruckUnfinished(OrderCirculateTakingQueryParam param) {
//        List<KwtWaybillOrder> wbOrderByTruckNo = waybillOrderRepository.findWbOrderByTruckNoAndStatus(param.getTruckNo(), FORBIDDEN_STATUSES);
//        boolean hasForbidden  = wbOrderByTruckNo.stream()
//                .anyMatch(order -> order != null && FORBIDDEN_STATUSES.contains(order.getStatus()));
//        if (hasForbidden) {
//            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_UNFINISHED, "当前车辆有未完成的状态，不可继续接单");
//        }
//    }
//
//
//    /**
//     * 计算当前车辆任务量：
//     * 若有皮重：任务量 = 核定载重 - 皮重
//     * 若无皮重：任务量 = 核定载重 × 80%
//     * <p>
//     * 1.当订单余量>=车辆的（法定载重-首次皮重）且<（法定载重-首次皮重 + 2）时，接取的任务量为车辆的（法定载重-首次皮重）；
//     * 2.订单余量<车辆的（法定载重-首次皮重）时，该车辆无法接单；
//     * 3.当订单余量>= (法定载重-首次皮重 + 2)时，接取的任务量为 (法定载重-首次皮重 + 2)
//     *
//     * @param param
//     */
//    private BigDecimal queryCurTruckLoadVolume(RTruckVo truckNo, OrderDetailVo tradeOrder) {
//        //核定载重
//        BigDecimal actualWeight = truckNo.getActualWeight();
//        log.info("车辆核定载重：{}", actualWeight);
//        //首次皮重
//        BigDecimal tareWeight = truckNo.getTareWeight();
//        //任务量
//        BigDecimal loadVolume;
//        if (tareWeight != null) {
//            // 有皮重：任务量 = 核定载重 - 皮重
//            loadVolume = actualWeight.subtract(tareWeight);
//            log.info("车辆有皮重，皮重：{}， 任务量:{}", tareWeight, loadVolume);
//
//        } else {
//            // 无皮重：任务量 = 核定载重 × 80%
//            loadVolume = actualWeight.multiply(EIGHTY_PERCENT);
//            log.info("车辆无皮重，按80%核定载重计算，车辆任务量：{}", loadVolume);
//        }
//
//        //订单分配总量
//        BigDecimal entrustAmount = tradeOrder.getEntrustAmount();
//        //订单实际交付量
//        BigDecimal actualAmount = tradeOrder.getActualAmount();
//        if (entrustAmount == null || actualAmount == null) {
//            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, "订单分配总量或订单实际交付量不能为空！");
//        }
//        //订单余量 = 分配总量 - 实际交付量
//        BigDecimal remainingAmount = entrustAmount.subtract(actualAmount);
//        log.info("订单余量 = 分配总量:{} - 实际交付量:{} = 车辆任务量:{}", entrustAmount, actualAmount, remainingAmount);
//
//        // 最终接取的任务量
//        BigDecimal taskAmount;
//        BigDecimal loadVolumePlus2 = loadVolume.add(TWO_TONS);
//        if (remainingAmount.compareTo(loadVolume) < 0) {
//            // 规则2：订单余量 < 任务量 → 无法接单
//            throw new BusinessPlatfromException(ErrorCodeEnum.PARAM_ERROR, String.format("订单余量不足，无法接单, 订单余量:%s, 车辆任务量:%s", remainingAmount, loadVolume));
//        } else if (remainingAmount.compareTo(loadVolumePlus2) >= 0) {
//            // 规则3：订单余量 >= 任务量+2 → 接取任务量+2
//            taskAmount = loadVolumePlus2;
//            log.info("订单余量充足，按(任务量+2吨)接单,最终任务量: {}", taskAmount);
//        } else {
//            // 规则1：订单余量 >= 任务量 且 < 任务量+2 → 接取任务量
//            taskAmount = loadVolume;
//            log.info("订单余量适中，按基础任务量接单，最终任务量: {}", taskAmount);
//        }
//        log.info("最终任务量：{}", taskAmount);
//        return taskAmount;
//    }
//
//    /**
//     * 创建物流运单
//     *
//     * @param param
//     */
//    private KwtWaybillOrder createWaybillOrder(OrderCirculateTakingQueryParam param, RDriverVo driver, RTruckVo truckNo) {
//        log.info("创建物流运单入参参数：{}", JSON.toJSONString(param));
//        KwtWaybillOrder waybillOrder = new KwtWaybillOrder();
//
//        waybillOrder.setEntId(param.getEntId());
//        waybillOrder.setWOrderNo(null);
//        waybillOrder.setType(1);
//        waybillOrder.setTruckId(truckNo.getId());
//        waybillOrder.setTruckNo(param.getTruckNo());
//        waybillOrder.setDriverId(param.getDriverId());
//        waybillOrder.setDriverName(driver.getName());
//        waybillOrder.setDriverPhone(driver.getPhone());
//        waybillOrder.setDriverIdcard(driver.getIdcard());
//        waybillOrder.setStatus(CarWaybillV1Enum.PENDING_VEHICLE.getCode());
//        waybillOrder.setTaskStartTime(new Date());
//        waybillOrderRepository.save(waybillOrder);
//        log.info("创建物流运单成功，运单ID：{}", waybillOrder.getId());
//
//        return waybillOrder;
//
//    }
//
//    /**
//     * 创建物流子运单
//     *
//     * @param param
//     */
//    private KwtWaybillOrderSubtask createWaybillOrderSubtask(OrderCirculateTakingQueryParam param, KwtWaybillOrder waybillOrder,
//                                                             BigDecimal turckLoadVolume) {
//        log.info("创建物流子运单入参参数：{}", JSON.toJSONString(param));
//        KwtWaybillOrderSubtask subtask = new KwtWaybillOrderSubtask();
//
//        subtask.setEntId(param.getEntId());
//        subtask.setLOrderId(param.getLogOrderId());
//        subtask.setWOrderId(waybillOrder.getId());
//        subtask.setWOrderNo(waybillOrder.getWOrderNo());
//        subtask.setUnit(null);
//
//        subtask.setEntrustAmount(turckLoadVolume);
//        subtask.setLoadTime(waybillOrder.getTaskStartTime());
//        subtask.setUnloadTime(waybillOrder.getEndTime());
//        subtask.setStatus(CarWaybillV1Enum.PENDING_VEHICLE.getCode());
//        waybillOrderSubtaskRepository.save(subtask);
//        log.info("创建物流子运单成功，子运单ID：{}", subtask.getId());
//
//        return subtask;
//
//    }
//
//    /**
//     * 创建物流运单地址
//     *
//     * @param param
//     */
//    private List<KwtWaybillOrderAddress> createWaybillOrderAddress(OrderCirculateTakingQueryParam param, KwtWaybillOrder waybillOrder,
//                                                                    KwtWaybillOrderSubtask waybillOrderSubtask) {
//        log.info("创建物流运单地址入参参数，logOrderId：{}", param.getLogOrderId());
//        //地址
//        Map<String, KwtLogisticsOrderAddress> logOrderIdAndAddressMap = getKwtLogisticsOrderAddressMap(Lists.newArrayList(param.getLogOrderId()));
//        List<KwtWaybillOrderAddress> createdAddresses = new ArrayList<>();
//
//        //装货地址
//        KwtLogisticsOrderAddress shipmentSource = logOrderIdAndAddressMap.getOrDefault(
//                param.getLogOrderId() + "-" + AddressTypeEnum.SHIPMENT.getCode(), new KwtLogisticsOrderAddress());
//        KwtWaybillOrderAddress shipmentAddress = createAddress(waybillOrder, waybillOrderSubtask, shipmentSource, AddressTypeEnum.SHIPMENT);
//        createdAddresses.add(shipmentAddress);
//        log.info("创建物流运单装货地址成功，运单地址ID：{}", shipmentAddress.getId());
//
//        //卸货地址
//        KwtLogisticsOrderAddress takeSource = logOrderIdAndAddressMap.getOrDefault(
//                param.getLogOrderId() + "-" + AddressTypeEnum.TAKE.getCode(), new KwtLogisticsOrderAddress());
//        KwtWaybillOrderAddress takeAddress = createAddress(waybillOrder, waybillOrderSubtask, takeSource, AddressTypeEnum.TAKE);
//        createdAddresses.add(takeAddress);
//        log.info("创建物流运单卸货地址成功，运单地址ID：{}", takeAddress.getId());
//
//        log.info("成功创建{}个运单地址", createdAddresses.size());
//        return createdAddresses;
//    }
//
//    /**
//     * 装卸货地址
//     * @param logOrderIdList
//     * @return
//     */
//    private Map<String, KwtLogisticsOrderAddress> getKwtLogisticsOrderAddressMap(List<Long> logOrderIdList) {
//        List<KwtLogisticsOrderAddress> logOrderAddressList = logisticsOrderAddressRepository.queryByLogOrderIds(logOrderIdList);
//        if (CollectionUtils.isEmpty(logOrderAddressList)) {
//            log.info("物流订单无装卸货地址信息，logOrderIdList:{}", JSON.toJSONString(logOrderIdList));
//            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_NOT_ADDRESS, "物流订单无装卸货地址信息");
//        }
//        return logOrderAddressList.stream().collect(Collectors
//                .toMap(address -> address.getLOrderId() + "-" + address.getType(),
//                        Function.identity(), (x, y) -> x));
//    }
//
//    /**
//     * 保存运单物流地址
//     * @param waybillOrder
//     * @param waybillOrderSubtask
//     * @param shipmentAddress
//     */
//    private KwtWaybillOrderAddress createAddress(KwtWaybillOrder waybillOrder, KwtWaybillOrderSubtask subtask,
//                                                 KwtLogisticsOrderAddress orderAddress, AddressTypeEnum typeEnum) {
//        KwtWaybillOrderAddress address = new KwtWaybillOrderAddress();
//        address.setWOrderId(waybillOrder.getId());
//        address.setWSubtaskId(subtask.getId());
//        address.setLAddressId(orderAddress.getId());
//        address.setAddressType(typeEnum.getCode());
//        address.setName(orderAddress.getName());
//        address.setType(orderAddress.getType());
//        address.setContacts(orderAddress.getContacts());
//        address.setPhone(orderAddress.getPhone());
//        address.setCityCode(orderAddress.getCityCode());
//        address.setCityName(orderAddress.getCityName());
//        address.setDetailAddress(orderAddress.getDetailAddress());
//        address.setLat(orderAddress.getLat());
//        address.setLng(orderAddress.getLng());
//        address.setFence(orderAddress.getFence());
//        address.setEntryType(orderAddress.getEntryType());
//        address.setPlanTime(waybillOrder.getTaskStartTime());
//        address.setSort(Global.NUMERICAL_ONE);
//        address.setEntrustAmount(subtask.getEntrustAmount());
//
//        waybillOrderAddressRepository.save(address);
//        return address;
//
//    }
//
//    /**
//     * 生成车辆运单-装卸货信息
//     *
//     * @param param
//     * @param waybillOrder
//     */
//    private void createWaybillOrderTicket(KwtLogisticsOrder logOrder,
//                                          KwtWaybillOrder waybillOrder, KwtWaybillOrderSubtask waybillOrderSubtask,
//                                          List<KwtWaybillOrderAddress> waybillOrderAddresses, RTruckVo truckNo) {
//        log.info("创建车辆运单-装卸货信息入参参数， 运单ID{}",logOrder.getLOrderNo());
//
//        //装货地址
//        KwtWaybillOrderAddress shipmentAddress = getWaybillOrderAddress(waybillOrderAddresses, AddressTypeEnum.SHIPMENT);
//        createTicket(waybillOrder, waybillOrderSubtask, shipmentAddress, logOrder, truckNo);
//        log.info("创建车辆运单-装卸货信息成功！");
//
//        //卸货地址
//        KwtWaybillOrderAddress takeAddress = getWaybillOrderAddress(waybillOrderAddresses, AddressTypeEnum.TAKE);
//        createTicket(waybillOrder, waybillOrderSubtask, takeAddress, logOrder, truckNo);
//        log.info("创建车辆运单-装卸货信息成功！");
//
//    }
//
//
//    /**
//     * 运单地址(装货、卸货地址)
//     *
//     * @param waybillOrderAddresses
//     * @param typeEnum
//     * @return
//     */
//    private KwtWaybillOrderAddress getWaybillOrderAddress(List<KwtWaybillOrderAddress> waybillOrderAddresses, AddressTypeEnum typeEnum) {
//        return waybillOrderAddresses.stream()
//                .filter(address -> address != null && typeEnum.getCode() == address.getType())
//                .findFirst()
//                .orElseThrow(() -> new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_ADDRESS_NOT_FOUND, "未找到装货地址数据！"));
//    }
//
//    /**
//     * 保存车辆运单-装卸货信息
//     *
//     * @param waybillOrder
//     * @param waybillOrderSubtask
//     * @param shipmentAddress
//     */
//    private void createTicket(KwtWaybillOrder waybillOrder, KwtWaybillOrderSubtask waybillOrderSubtask,
//                              KwtWaybillOrderAddress shipmentAddress, KwtLogisticsOrder logOrder, RTruckVo truckNo) {
//        KwtWaybillOrderTicket ticket = new KwtWaybillOrderTicket();
//        ticket.setWOrderId(waybillOrder.getId());
//        ticket.setWSubtaskId(waybillOrderSubtask.getId());
//        ticket.setWAddressId(shipmentAddress.getId());
//        ticket.setType(shipmentAddress.getAddressType());
//        ticket.setUnit(logOrder.getUnit());
//        ticket.setAmount(BigDecimal.ZERO);
//        ticket.setGrossAmount(truckNo.getGrossWeight());
//        ticket.setTareAmount(truckNo.getTareWeight());
//        waybillOrderTicketRepository.save(ticket);
//    }
//
//
//    /**
//     * 生成车辆运单-节点轨迹
//     *
//     * @param param
//     * @param waybillOrder
//     */
//    private void createWaybillOrderNode(OrderCirculateTakingQueryParam param, KwtWaybillOrder waybillOrder, KwtWaybillOrderSubtask waybillOrderSubtask) {
//        log.info("创建车辆运单-节点轨迹入参参数：{}", JSON.toJSONString(param));
//        KwtWaybillOrderNode orderNode = new KwtWaybillOrderNode();
//        orderNode.setWOrderId(waybillOrder.getId());
//        orderNode.setWSubtaskId(waybillOrderSubtask.getWOrderId());
//        orderNode.setOrderStatus(waybillOrder.getStatus());
//        orderNode.setTruckId(waybillOrder.getTruckId());
//        orderNode.setTruckNo(waybillOrder.getTruckNo());
//        orderNode.setDriverId(waybillOrder.getDriverId());
//        orderNode.setDriverName(waybillOrder.getDriverName());
//        orderNode.setLng(param.getLng());
//        orderNode.setLat(param.getLat());
//        waybillOrderNodeRepository.save(orderNode);
//        log.info("创建车辆运单-节点轨迹成功，节点轨迹ID：{}", orderNode.getId());
//    }
//
//    /**
//     * 回写贸易订单数据
//     * @param param
//     */
//    private void updateTradeOrder(OrderDetailVo orderDetail, BigDecimal truckLoadVolume) {
//        log.info("更新上游贸易订单运输量数据，tradeOrderId：{}", orderDetail.getId());
//        // 计算当前车辆运输量
//        BigDecimal totalLoadVolume = Optional.ofNullable(orderDetail.getActualAmount())
//                .map(entrust -> entrust.add(truckLoadVolume))
//                .orElse(truckLoadVolume);
//
//        UpdateActualAmountParam tradeParam = new UpdateActualAmountParam();
//        tradeParam.setTOrderId(orderDetail.getId());
//        tradeParam.setActualLoadAmount(totalLoadVolume);
//        tradeOrderInfoService.updateOrderActualAmount(tradeParam);
//        log.info("更新上游贸易订单运输量成功, 贸易订单ID：{}", orderDetail.getId());
//    }
//
//
//    /**
//     * 回写物流订单数据
//     * @param param
//     */
//    private void updateLogOrder(KwtLogisticsOrder logOrder, BigDecimal truckLoadVolume) {
//        log.info("更新上游物流运输量数据，logOrderId：{}", logOrder);
//        // 计算当前车辆总运输量
//        BigDecimal totalLoadVolume = Optional.ofNullable(logOrder.getEntrustAmount())
//                .map(entrust -> entrust.add(truckLoadVolume))
//                .orElse(truckLoadVolume);
//
//        logOrder.setEntrustAmount(totalLoadVolume);
//        logisticsOrderRepository.updateById(logOrder);
//        log.info("更新上游物流运输量成功, 物流订单ID：{}", logOrder.getId());
//    }
//
//    /**
//     * 取消订单
//     *
//     * @param waybillOrderId
//     * @return
//     */
//    public void cancelWaybillOrder(WaybillOrderCancelParam param) {
//        log.info("取消订单接单入参参数：{}", JSON.toJSONString(param));
//        //1.取消物流运单
//        BigDecimal entrustAmount = updateWaybillOrder(param);
//
//        //2.更新上游订单：更新物流订单运输量
//        KwtLogisticsOrder logOrder = updateLogOrder(param, entrustAmount);
//
//        //3.更新上游订单：更新贸易订单运输量
//        updateTradeOrder(logOrder, entrustAmount);
//
//
//        log.info("取消接单成功！");
//    }
//
//    /**
//     * 更改物流运单状态
//     * @param param
//     * @return
//     */
//    private BigDecimal updateWaybillOrder(WaybillOrderCancelParam param) {
//        KwtWaybillOrder waybillOrder = waybillOrderRepository.queryByBillOrderId(param.getWaybillOrderId());
//        if (waybillOrder == null || CarWaybillV1Enum.PENDING_VEHICLE.getCode() != waybillOrder.getStatus()) {
//            log.info("当前物流运单状态不可取消， waybillOrderId：{}", param.getWaybillOrderId());
//            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前物流运单状态不可取消！");
//        }
//        waybillOrder.setStatus(CarWaybillV1Enum.APPROVAL_TREAT.getCode());
//        waybillOrderRepository.updateById(waybillOrder);
//        log.info("取消物流运单成功, 物流运单ID：{}", waybillOrder.getId());
//
//        //车辆本次运输量
//        KwtWaybillOrderSubtask orderSubtask = waybillOrderSubtaskRepository.queryByWOrderId(waybillOrder.getId());
//        BigDecimal entrustAmount = orderSubtask.getEntrustAmount();
//
//        //生成取消接单节点轨迹
//        createEnteredWaybillOrderNode(param.getLng(), param.getLat(), waybillOrder, CarWaybillV1Enum.APPROVAL_TREAT);
//
//        return entrustAmount;
//    }
//
//    /**
//     * 更新上游物流订单 - 减运输量
//     * @param param
//     * @param entrustAmoun
//     * @return
//     */
//    private KwtLogisticsOrder updateLogOrder(WaybillOrderCancelParam param, BigDecimal entrustAmount) {
//        KwtLogisticsOrder logOrder = logisticsOrderRepository.queryByLogisticsOrderId(param.getLogOrderId());
//        if (logOrder == null) {
//            log.info("当前物流运单无关联物流订单数据：{}", param.getLogOrderId());
//            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_LOG_ORDER, "当前物流运单无关联物流订单数据！");
//        }
//
//        //取消接单的物流订单的总运输量不能为空
//        if (logOrder.getEntrustAmount() == null || logOrder.getEntrustAmount().compareTo(BigDecimal.ZERO) <= 0) {
//            throw new BusinessPlatfromException(ErrorCodeEnum.LOGISTICS_ORDER_AMOUNT_ERROR, "已接单物订单的总运单量不能为空或0！");
//        }
//        logOrder.setEntrustAmount(logOrder.getEntrustAmount().subtract(entrustAmount));
//        logisticsOrderRepository.updateById(logOrder);
//        log.info("更新上游物流订单运输量成功, 物流订单ID：{}", logOrder.getId());
//        return logOrder;
//    }
//
//
//    /**
//     * 更新上游贸易订单 - 减运输量
//     * @param logOrder
//     * @param entrustAmount
//     */
//    private void updateTradeOrder(KwtLogisticsOrder logOrder, BigDecimal entrustAmount) {
//        OrderDetailVo tradeOrder = tradeOrderInfoService.queryByTradeOrderId(logOrder.getTOrderId());
//        //取消接单的物流订单的总运输量不能为空
//        if (tradeOrder.getActualAmount() == null || tradeOrder.getActualAmount().compareTo(BigDecimal.ZERO) <= 0) {
//            throw new BusinessPlatfromException(ErrorCodeEnum.TRADE_ORDER_AMOUNT_ERROR, "已接单交易订单的总运输量不能为空或0！");
//        }
//
//        UpdateActualAmountParam tradeParam = new UpdateActualAmountParam();
//        tradeParam.setTOrderId(tradeOrder.getId());
//        tradeParam.setActualLoadAmount(tradeOrder.getActualAmount().subtract(entrustAmount));
//        tradeOrderInfoService.updateOrderActualAmount(tradeParam);
//        log.info("更新上游贸易订单运输量成功, 贸易订单ID：{}", tradeOrder.getId());
//    }
//
//
//    /**
//     * 到达装货地点
//     * @param waybillOrderId
//     * @return
//     */
//    public void comeInto(WaybillOrderCmeIntoWeighParam param){
//        log.info("推送物流运单状态到到达装货地点：{}", JSON.toJSONString(param));
//        //1.修改物流运单状态-到达装货地点
//        KwtWaybillOrder waybillOrder = updateWaybillOrderStayus(param.getWaybillOrderId(), CarWaybillV1Enum.PENDING_VEHICLE, CarWaybillV1Enum.REFUSE_TRAFFIC);
//        waybillOrderRepository.updateById(waybillOrder);
//
//        //2.填充运单皮重
//        LambdaQueryWrapper<KwtWaybillOrderTicket>  queryWrapper = Wrappers.<KwtWaybillOrderTicket>lambdaQuery()
//                .eq(KwtWaybillOrderTicket::getWOrderId, param.getWaybillOrderId())
//                .eq(KwtWaybillOrderTicket::getType, AddressTypeEnum.SHIPMENT.getCode());
//        KwtWaybillOrderTicket orderTicket = waybillOrderTicketRepository.getOne(queryWrapper);
//        orderTicket.setTareAmount(param.getTareAmount());
//        waybillOrderTicketRepository.save(orderTicket);
//
//        //3.填充首次皮重
//        RTruckVo truck = remoteFleetService.findTruckByTruckNo(param.getTruckNo());
//        if (truck != null && truck.getTareWeight() == null) {
//            RTruckVo truckNo = new RTruckVo();
//            truckNo.setId(truck.getId());
//            truckNo.setTareWeight(param.getTareAmount());
//            remoteFleetService.updateTruckTareAmount(truckNo);
//        }
//        //4.生成到达装货地点节点轨迹
//        createEnteredWaybillOrderNode(param.getLng(), param.getLat(), waybillOrder, CarWaybillV1Enum.REFUSE_TRAFFIC);
//
//        log.info("物流运单到达装货地点成功！");
//    }
//
//    /**
//     * 已装货
//     * @param waybillOrderId
//     * @return
//     */
//    public void loading(WaybillOrderLoadingParam param){
//        log.info("推送物流运单状态到已装货：{}", JSON.toJSONString(param));
//        //1.修改物流运单状态-已装货
//        KwtWaybillOrder waybillOrder = updateWaybillOrderStayus(param.getWaybillOrderId(), CarWaybillV1Enum.REFUSE_TRAFFIC, CarWaybillV1Enum.EXIT_COMPLETED);
//        waybillOrderRepository.updateById(waybillOrder);
//
//        //2.生成已已装货节点轨迹
//        createEnteredWaybillOrderNode(param.getLng(), param.getLat(), waybillOrder, CarWaybillV1Enum.EXIT_COMPLETED);
//        log.info("物流运单装货成功！");
//    }
//
//    /**
//     * 离场过磅-计算毛重和装货净重
//     * @param waybillOrderId
//     * @return
//     */
//    public void leave(WaybillOrderLeaveMockParam param){
//        log.info("离场过磅-计算毛重和净重, 入参参数：{}", JSON.toJSONString(param));
//        //校验运单状态
//        KwtWaybillOrder waybillOrder = waybillOrderRepository.queryByBillOrderId(param.getWaybillOrderId());
//        if (waybillOrder == null) {
//            log.warn("物流运单不存在，waybillOrderId：{}", param.getWaybillOrderId());
//            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_FOUND, "物流运单不存在！");
//        }
//        if (CarWaybillV1Enum.EXIT_COMPLETED.getCode() != waybillOrder.getStatus()) {
//            log.warn("运单状态不符合离场过磅条件，当前状态: {}, 要求状态: 已装货, waybillOrderId: {}", waybillOrder.getStatus(), waybillOrder.getId());
//            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "运单状态不符合离场过磅条件，无法推进下一节点！");
//        }
//
//        //记录毛重和装货净重
//        paddingGrossAndLoadAmount(param, waybillOrder);
//    }
//
//    /**
//     * 记录毛重和装货净重
//     * @param param
//     * @param waybillOrder
//     */
//    private void paddingGrossAndLoadAmount(WaybillOrderLeaveMockParam param, KwtWaybillOrder waybillOrder) {
//        List<KwtWaybillOrderTicket> ticketList = waybillOrderTicketRepository.queryByWOrderId(param.getWaybillOrderId());
//        // 按 type 分组
//        Map<Integer, KwtWaybillOrderTicket> ticketMap = ticketList.stream()
//                .collect(Collectors.toMap(KwtWaybillOrderTicket::getType, Function.identity(), (a, b) -> a));
//        //1.填充毛重
//        updateGrossAmount(param, ticketMap);
//        //2.填充装货净重
//        updateLoadAmount(param, waybillOrder, ticketMap);
//    }
//
//    /**
//     * 填充毛重
//     * @param param
//     * @param ticketMap
//     */
//    private void updateGrossAmount(WaybillOrderLeaveMockParam param, Map<Integer, KwtWaybillOrderTicket> ticketMap) {
//        //查询卸货信息，用于记录毛重
//        KwtWaybillOrderTicket takeTicket = ticketMap.getOrDefault(AddressTypeEnum.TAKE.getCode(), new KwtWaybillOrderTicket());
//        if (takeTicket == null) {
//            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_TICKET_NOT_FOUND, "当前物流运单装卸货信息不存在，无法记录毛重！");
//        }
//        takeTicket.setGrossAmount(param.getGrossAmount());
//        waybillOrderTicketRepository.updateById(takeTicket);
//    }
//
//    /**
//     * 填充装货净重
//     * @param param
//     * @param waybillOrder
//     * @param ticketMap
//     */
//    private void updateLoadAmount(WaybillOrderLeaveMockParam param, KwtWaybillOrder waybillOrder, Map<Integer, KwtWaybillOrderTicket> ticketMap) {
//        //查询卸货信息，用于获取皮重
//        KwtWaybillOrderTicket shipmentTicket  = ticketMap.getOrDefault(AddressTypeEnum.SHIPMENT.getCode(), new KwtWaybillOrderTicket());
//        if (shipmentTicket == null) {
//            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_TICKET_NOT_FOUND, "当前物流运单装卸货信息不存在，无法获取皮重！");
//        }
//        //皮重
//        BigDecimal tareAmount = shipmentTicket.getTareAmount();
//
//        //更新子运单的装货净重
//        KwtWaybillOrderSubtask subtask = waybillOrderSubtaskRepository.queryByWOrderId(waybillOrder.getId());
//        if (subtask == null) {
//            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到关联的子运单！");
//        }
//        BigDecimal loadAmount = param.getGrossAmount().subtract(Optional.ofNullable(tareAmount).orElse(BigDecimal.ZERO));
//        subtask.setLoadAmount(loadAmount);
//        subtask.setLoadTime(new Date());
//        waybillOrderSubtaskRepository.updateById(subtask);
//        log.info("物流运单离场过磅成功！运单ID: {}, 毛重: {}, 皮重: {}, 装货净重: {}", param.getWaybillOrderId(), param.getGrossAmount(), tareAmount, loadAmount);
//    }
//
//
//    /**
//     * 离场
//     * @param waybillOrderId
//     * @return
//     */
//    public void leavedWaybillOrder(WaybillOrderLeaveParam param){
//        log.info("推送物流运单状态到已离场：{}", JSON.toJSONString(param));
//        //1.修改物流运单状态-离场
//        KwtWaybillOrder waybillOrder = updateWaybillOrderStayus(param.getWaybillOrderId(), CarWaybillV1Enum.EXIT_COMPLETED, CarWaybillV1Enum.WAIT_LOADING);
//        waybillOrderRepository.updateById(waybillOrder);
//
//        //2.生成已已装货节点轨迹
//        createEnteredWaybillOrderNode(param.getLng(), param.getLat(), waybillOrder, CarWaybillV1Enum.WAIT_LOADING);
//        log.info("物流运单离场成功！");
//    }
//
//    /**
//     * 卸货
//     * @param waybillOrderId
//     * @return
//     */
//    public void unloadingWaybillOrder(WaybillOrderUnloadParam param){
//        log.info("推送物流运单状态到已卸货：{}", JSON.toJSONString(param));
//        //1.修改物流运单状态-已卸货
//        KwtWaybillOrder waybillOrder = updateWaybillOrderStayus(param.getWaybillOrderId(), CarWaybillV1Enum.WAIT_LOADING, CarWaybillV1Enum.COMPLETION_LOADING);
//        waybillOrderRepository.updateById(waybillOrder);
//
//        //2.更新子运单卸货净重  TODO 审核通过后，贸易订单和物流订单的运输量需要已实际卸货净重为准
//        KwtWaybillOrderSubtask subtask = waybillOrderSubtaskRepository.queryByWOrderId(waybillOrder.getId());
//        if (subtask == null) {
//            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到关联的子运单！");
//        }
//        subtask.setUnloadAmount(param.getUnloadAmount());
//        subtask.setUnloadTime(new Date());
//        waybillOrderSubtaskRepository.updateById(subtask);
//
//        //3.生成已卸货节点轨迹
//        createEnteredWaybillOrderNode(param.getLng(), param.getLat(), waybillOrder, CarWaybillV1Enum.COMPLETION_LOADING);
//        log.info("物流运单卸货成功！");
//    }
//
//    /**
//     * 更改物流订单状态
//     * @param param
//     * @param startTypeEnum
//     * @param endTypeEnum
//     */
//    private KwtWaybillOrder updateWaybillOrderStayus(Long waybillOrderId, CarWaybillV1Enum startTypeEnum, CarWaybillV1Enum endTypeEnum) {
//        KwtWaybillOrder waybillOrder = waybillOrderRepository.queryByBillOrderId(waybillOrderId);
//        if (waybillOrder == null) {
//            log.error("物流运单不存在，waybillOrderId：{}", waybillOrderId);
//            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_NOT_FOUND, "物流运单不存在！");
//        }
//
//        if (startTypeEnum.getCode() != waybillOrder.getStatus()) {
//            log.info("当前物流运单状态不正确，无法推进下一节点， waybillOrderId：{}", waybillOrderId);
//            throw new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_STATUS_ERROR, "当前物流运单状态不正确，无法推进下一节点！");
//        }
//        //更改物流运单状态
//        waybillOrder.setStatus(endTypeEnum.getCode());
//        return waybillOrder;
//    }
//
//    /**
//     *  生成运单节点轨迹
//     * @param param
//     * @param waybillOrder
//     */
//    private void createEnteredWaybillOrderNode(String lng, String lat, KwtWaybillOrder waybillOrder, CarWaybillV1Enum carWaybillV1Enum) {
//        log.info("创建车辆运单节点轨迹入参参数, wOrderId: {}", waybillOrder.getWOrderId());
//        List<KwtWaybillOrderSubtask> waybillOrderSubtaskList = waybillOrderSubtaskRepository.queryByLogId(waybillOrder.getLOrderId());
//        KwtWaybillOrderSubtask waybillOrderSubtask = Optional.ofNullable(waybillOrderSubtaskList)
//                .stream()
//                .flatMap(List::stream)
//                .filter(Objects::nonNull)
//                .findFirst()
//                .orElseThrow(() -> new BusinessPlatfromException(ErrorCodeEnum.WAYBILL_ORDER_SUB_NOT_FOUND, "未找到有效的子运单"));
//
//        KwtWaybillOrderNode orderNode = new KwtWaybillOrderNode();
//        orderNode.setWOrderId(waybillOrder.getId());
//        orderNode.setWSubtaskId(waybillOrderSubtask.getWOrderId());
//        orderNode.setOrderStatus(carWaybillV1Enum.getCode());
//        orderNode.setTruckId(waybillOrder.getTruckId());
//        orderNode.setTruckNo(waybillOrder.getTruckNo());
//        orderNode.setDriverId(waybillOrder.getDriverId());
//        orderNode.setDriverName(waybillOrder.getDriverName());
//        orderNode.setLng(lng);
//        orderNode.setLat(lat);
//        waybillOrderNodeRepository.save(orderNode);
//        log.info("创建车辆运单节点轨迹，节点轨迹ID：{}", orderNode.getId());
//    }


}
