package com.sckw.transport.service;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.sckw.contract.api.RemoteContractService;
import com.sckw.contract.api.model.dto.res.ContractCommonInfoResDto;
import com.sckw.core.common.enums.NumberConstant;
import com.sckw.core.common.enums.enums.DictEnum;
import com.sckw.core.common.enums.enums.DictTypeEnum;
import com.sckw.core.exception.BusinessException;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.enums.LogisticsOrderEnum;
import com.sckw.core.model.page.PageResult;
import com.sckw.core.utils.*;
import com.sckw.core.web.constant.HttpStatus;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.core.web.response.HttpResult;
import com.sckw.mongo.enums.BusinessTypeEnum;
import com.sckw.mongo.model.SckwLogisticsOrder;
import com.sckw.order.api.dubbo.TradeOrderInfoService;
import com.sckw.order.api.model.*;
import com.sckw.stream.enums.MessageEnum;
import com.sckw.stream.model.SckwBusSum;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.model.dto.res.EntCacheResDto;
import com.sckw.system.api.model.dto.res.SysDictResDto;
import com.sckw.system.api.model.dto.res.UserCacheResDto;
import com.sckw.transport.api.model.vo.LogisticsOrderVO;
import com.sckw.transport.common.config.MessageUrlConfig;
import com.sckw.transport.dao.*;
import com.sckw.transport.model.*;
import com.sckw.transport.model.dto.CancelOrderDTO;
import com.sckw.transport.model.dto.DocumentParamDTO;
import com.sckw.transport.model.param.ContractParam;
import com.sckw.transport.model.param.LogisticsOrderParam;
import com.sckw.transport.model.vo.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.function.StreamBridge;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lfdc
 * @description 运输服务公共service接口
 * @date 2023-06-29 15:06:45
 */
@Slf4j
@Service
public class TransportCommonService {

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

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

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

    @Autowired
    MessageUrlConfig messageUrlConfig;

    @Autowired
    public CommonService commonService;

    @Autowired
    public KwtWaybillOrderService waybillOrderService;

    @Autowired
    public KwtLogisticsOrderGoodsMapper logisticsOrderGoodsMapper;

    @Autowired
    public KwtLogisticsOrderContractMapper logisticsOrderContractMapper;

    @Autowired
    public KwtLogisticsOrderMapper logisticsOrderMapper;

    @Autowired
    public KwtLogisticsOrderAddressMapper logisticsOrderAddressMapper;

    @Autowired
    public KwtLogisticsOrderTrackMapper logisticsOrderTrackMapper;

    @Autowired
    public KwtLogisticsOrderUnitMapper logisticsOrderUnitMapper;

    @Autowired
    public KwtWaybillOrderMapper waybillOrderMapper;

    @Resource
    private StreamBridge streamBridge;

    /**
     * 查看订单详情
     *
     * @param dto
     * @return
     */
    public HttpResult getOrderDetail(DocumentParamDTO dto) {
        HttpResult httpResult = new HttpResult();
        httpResult.setCode(HttpStatus.SUCCESS_CODE);
        if (String.valueOf(NumberConstant.THREE).equals(dto.getDocumentType())) {
            //托运订单
            OrderDetailVO orderDetailVO = getOrderData(dto);
            httpResult.setData(orderDetailVO);
        } else if (String.valueOf(NumberConstant.TWO).equals(dto.getDocumentType())) {
            //承运订单
            OrderDetailVO orderDetailVO = getOrderData(dto);
            httpResult.setData(orderDetailVO);
        } else if (String.valueOf(NumberConstant.ZERO).equals(dto.getDocumentType())) {
            //销售订单
            OrderDetailVO orderDetailVO = getOrderData(dto);
            httpResult.setData(orderDetailVO);
        } else if (String.valueOf(NumberConstant.ONE).equals(dto.getDocumentType())) {
            //采购订单
            OrderDetailVO orderDetailVO = getOrderData(dto);
            httpResult.setData(orderDetailVO);
        } else {
            httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
            httpResult.setMsg("单据类型错误");
        }
        return httpResult;
    }

    /**
     * 获取订单详情
     *
     * @param dto
     * @return
     */
    private OrderDetailVO getOrderData(DocumentParamDTO dto) {
        KwtLogisticsOrder logisticsOrder = logisticsOrderMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrder>()
                        .eq(KwtLogisticsOrder::getId, dto.getId())
                        .eq(StringUtils.isNotBlank(dto.getDocumentNo()), KwtLogisticsOrder::getLOrderNo, dto.getDocumentNo())
                /**.eq(KwtLogisticsOrder::getEntId, LoginUserHolder.getEntId())*/);
        if (logisticsOrder == null) {
            log.info("查无单据:{}", JSONObject.toJSONString(dto));
            throw new RuntimeException("查无单据");

        }
        KwtLogisticsOrderContract contract = logisticsOrderContractMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderContract>()
                .eq(StringUtils.isNotBlank(dto.getId()), KwtLogisticsOrderContract::getLOrderId, dto.getId()));
        KwtLogisticsOrderUnit unitOne = logisticsOrderUnitMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderUnit>()
                .eq(StringUtils.isNotBlank(dto.getId()), KwtLogisticsOrderUnit::getLOrderId, dto.getId())
                .eq(KwtLogisticsOrderUnit::getUnitType, NumberConstant.ONE));
        KwtLogisticsOrderUnit unitTwo = logisticsOrderUnitMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderUnit>()
                .eq(StringUtils.isNotBlank(dto.getId()), KwtLogisticsOrderUnit::getLOrderId, dto.getId())
                .eq(KwtLogisticsOrderUnit::getUnitType, NumberConstant.TWO));
        KwtLogisticsOrderAddress loadOrderAddress = logisticsOrderAddressMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderAddress>()
                .eq(StringUtils.isNotBlank(dto.getId()), KwtLogisticsOrderAddress::getLOrderId, dto.getId())
                .eq(KwtLogisticsOrderAddress::getAddressType, NumberConstant.ONE));
        KwtLogisticsOrderAddress unloadOrderAddress = logisticsOrderAddressMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderAddress>()
                .eq(StringUtils.isNotBlank(dto.getId()), KwtLogisticsOrderAddress::getLOrderId, dto.getId())
                .eq(KwtLogisticsOrderAddress::getAddressType, NumberConstant.TWO));
        KwtLogisticsOrderGoods orderGoods = logisticsOrderGoodsMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderGoods>()
                .eq(StringUtils.isNotBlank(logisticsOrder.getId()), KwtLogisticsOrderGoods::getLOrderId, logisticsOrder.getId()));
        OrderDetailVO orderDetailVO = new OrderDetailVO();
        orderDetailVO.setId(String.valueOf(logisticsOrder.getId()));
        if (contract != null) {
            orderDetailVO.setContractId(contract.getContractId() == null ? null : String.valueOf(contract.getContractId()));
            //todo 接口调用合同服务查询合同信息
            List<Long> list = new ArrayList<>(NumberConstant.SIXTEEN);
            list.add(contract.getContractId());
            Map<Long, ContractCommonInfoResDto> contractBaseInfo = remoteContractService.queryContractBaseInfo(list);
            if (CollectionUtils.isNotEmpty(contractBaseInfo) && !ObjectUtils.isEmpty(contractBaseInfo.get(contract.getContractId()))) {
                orderDetailVO.setContractName(contractBaseInfo.get(contract.getContractId()).getContactName());
                orderDetailVO.setContractNo(contractBaseInfo.get(contract.getContractId()).getContractCode());
                orderDetailVO.setSigningWay(contractBaseInfo.get(contract.getContractId()).getSigningWay());
            }
        }
        if (unitOne != null) {
            orderDetailVO.setConsignCompanyId(unitOne.getEntId());
            orderDetailVO.setConsignCompany(unitOne.getFirmName());
            orderDetailVO.setConsignContacts(unitOne.getContacts());
            orderDetailVO.setConsignPhone(unitOne.getPhone());
            orderDetailVO.setCollectionCompany(unitOne.getFirmName());
        }
        if (unitTwo != null) {
            orderDetailVO.setCarrierCompanyId(unitTwo.getEntId());
            orderDetailVO.setCarrierCompany(unitTwo.getFirmName());
            orderDetailVO.setCarrierContacts(unitTwo.getContacts());
            orderDetailVO.setCarrierPhone(unitTwo.getPhone());
        }
        orderDetailVO.setTaxRate(logisticsOrder.getTaxRate());
        orderDetailVO.setTaxRateLabel(logisticsOrder.getTaxRate() + "%");
        orderDetailVO.setStatus(logisticsOrder.getStatus());
        orderDetailVO.setStatusLabel(LogisticsOrderEnum.getName(logisticsOrder.getStatus()));
        orderDetailVO.setGoodsId(String.valueOf(orderGoods == null ? null : orderGoods.getGoodsId()));
        orderDetailVO.setGoodsName(orderGoods == null ? null : orderGoods.getGoodsName());
        orderDetailVO.setNumber(logisticsOrder.getAmount() == null ? null : logisticsOrder.getAmount());
        orderDetailVO.setPrice(logisticsOrder.getPrice() == null ? null : logisticsOrder.getPrice());
        orderDetailVO.setLoss(logisticsOrder.getLoss() == null ? null : logisticsOrder.getLoss());
        orderDetailVO.setDeduct(logisticsOrder.getGoodsPrice() == null ? null : logisticsOrder.getGoodsPrice());
        orderDetailVO.setLoadName(loadOrderAddress.getName());
        orderDetailVO.setLoadAddress(loadOrderAddress.getCityName());
        orderDetailVO.setLoadContacts(loadOrderAddress.getContacts());
        orderDetailVO.setLoadPhone(loadOrderAddress.getPhone());
        orderDetailVO.setLoadAddressDetail(loadOrderAddress.getDetailAddress());
        orderDetailVO.setUnloadName(unloadOrderAddress.getName());
        orderDetailVO.setUnloadAddress(unloadOrderAddress.getCityName());
        orderDetailVO.setUnloadContacts(unloadOrderAddress.getContacts());
        orderDetailVO.setUnloadPhone(unloadOrderAddress.getPhone());
        orderDetailVO.setUnloadAddressDetail(unloadOrderAddress.getDetailAddress());
        orderDetailVO.setSettlementCycle(logisticsOrder.getSettlementCycle() == null ? null : String.valueOf(logisticsOrder.getSettlementCycle()));
        if (logisticsOrder.getSettlementCycle() != null) {
            Map<String, SysDictResDto> dtoMap = remoteSystemService.queryDictMapByType(DictTypeEnum.SETTLEMENT_CYCLE.getType());
            orderDetailVO.setSettlementCycleLabel(dtoMap.isEmpty() ? null :
                    (dtoMap.get(String.valueOf(logisticsOrder.getSettlementCycle())) == null ? null : dtoMap.get(String.valueOf(logisticsOrder.getSettlementCycle())).getLabel()));
        }
        orderDetailVO.setBillingMode(logisticsOrder.getBillingMode());
        if (logisticsOrder.getBillingMode() != null) {
            Map<String, SysDictResDto> dictResDtoMap = remoteSystemService.queryDictMapByType(DictTypeEnum.CHARGING_TYPE.getType());
            orderDetailVO.setBillingModeLabel(dictResDtoMap.isEmpty() ? null :
                    (dictResDtoMap.get(logisticsOrder.getBillingMode()) == null ? null : dictResDtoMap.get(logisticsOrder.getBillingMode()).getLabel()));
        }
        orderDetailVO.setScheduleStartTime(logisticsOrder.getStartTime() == null ? null : logisticsOrder.getStartTime());
        orderDetailVO.setScheduleEndTime(logisticsOrder.getEndTime() == null ? null : logisticsOrder.getEndTime());
        if (logisticsOrder.getBillingMode().equals(String.valueOf(NumberConstant.ONE))) {
            orderDetailVO.setPerformanceAmount(logisticsOrder.getTotalLoadAmount() == null ? null : logisticsOrder.getTotalLoadAmount());
        } else if (logisticsOrder.getBillingMode().equals(String.valueOf(NumberConstant.TWO))) {
            orderDetailVO.setPerformanceAmount(logisticsOrder.getUnloadAmount() == null ? null : logisticsOrder.getUnloadAmount());
        }
//        orderDetailVO.setPerformanceAmount(logisticsOrder.getLoadAmount() == null ? null : logisticsOrder.getLoadAmount());
        orderDetailVO.setTotalLoadAmount(logisticsOrder.getTotalLoadAmount() == null ? new BigDecimal("0.00") : logisticsOrder.getTotalLoadAmount());
        orderDetailVO.setTotalUnloadAmount(logisticsOrder.getTotalUnloadAmount() == null ? new BigDecimal("0.00") : logisticsOrder.getTotalUnloadAmount());
        orderDetailVO.setCreateTime(logisticsOrder.getCreateTime());
        orderDetailVO.setPayment(logisticsOrder.getPayment());
        if (logisticsOrder.getPayment() != null) {
            Map<String, SysDictResDto> dictResDtoMap = remoteSystemService.queryDictMapByType(DictTypeEnum.TRADE_TYPE.getType());
            if (dictResDtoMap.isEmpty()) {
                orderDetailVO.setPaymentLabel(null);
            } else {
                if (dictResDtoMap.get(logisticsOrder.getPayment().toString()) != null) {
                    orderDetailVO.setPaymentLabel(dictResDtoMap.get(logisticsOrder.getPayment().toString()).getLabel());
                }
            }
        }
        if (orderDetailVO.getSigningWay() != null) {
            Map<String, SysDictResDto> dictResDtoMap = remoteSystemService.queryDictMapByType(DictTypeEnum.SIGNING_TYPE.getType());
            if (dictResDtoMap.isEmpty()) {
                orderDetailVO.setPaymentLabel(null);
            } else {
                if (dictResDtoMap.get(String.valueOf(orderDetailVO.getSigningWay())) != null) {
                    orderDetailVO.setSigningWayLabel(dictResDtoMap.get(orderDetailVO.getSigningWay().toString()).getLabel());
                }
            }
        }
        if (logisticsOrder.getGoodsPriceUnit() != null) {
            SysDictResDto sysDictResDto = remoteSystemService.queryDictByTypeAndValue(DictTypeEnum.PRICE_TYPE.getType(), logisticsOrder.getGoodsPriceUnit());
            orderDetailVO.setDeductLabel(sysDictResDto == null ? null : sysDictResDto.getLabel());
        }
        if (logisticsOrder.getLossUnit() != null) {
            SysDictResDto sysDictResDto = remoteSystemService.queryDictByTypeAndValue(DictTypeEnum.TAX_RATE_TYPE.getType(), logisticsOrder.getLossUnit());
            orderDetailVO.setLossLabel(sysDictResDto == null ? null : sysDictResDto.getLabel());
        }
        if (logisticsOrder.getUnit() != null) {
            SysDictResDto sysDictResDto = remoteSystemService.queryDictByTypeAndValue(DictTypeEnum.UNIT_TYPE.getType(), logisticsOrder.getUnit());
            orderDetailVO.setNumberLabel(sysDictResDto == null ? null : sysDictResDto.getLabel());
        }
        if (logisticsOrder.getPriceType() != null) {
            SysDictResDto sysDictResDto = remoteSystemService.queryDictByTypeAndValue(DictTypeEnum.PRICE_TYPE.getType(), String.valueOf(logisticsOrder.getPriceType()));
            orderDetailVO.setPriceLabel(sysDictResDto == null ? null : sysDictResDto.getLabel());
        }
        orderDetailVO.setRemark(logisticsOrder.getRemark());
        orderDetailVO.setWaitDistributionAmount(logisticsOrder.getAmount()
                .subtract(logisticsOrder.getSubcontractAmount() == null ? new BigDecimal("0.00") : logisticsOrder.getSubcontractAmount())
                .subtract(logisticsOrder.getEntrustAmount() == null ? new BigDecimal("0.00") : logisticsOrder.getEntrustAmount()));
        /**亏吨量/吨->装货量-卸货量
         * 合理损耗值=装货量*合理损耗
         扣亏量/吨->亏吨量-合理损耗值
         罚款值 扣亏量/吨*扣亏货值
         总运价:
         按照装货量 运输运价*装货量
         按照卸货量 卸货量*运输单价-罚款值
         按照趟次=运输运价
         */
        //合理损耗
        BigDecimal loss = logisticsOrder.getLoss() == null ? new BigDecimal("0.00") : logisticsOrder.getLoss();

        Integer status = logisticsOrder.getStatus();
        List<Integer> orderStatusFinish = new ArrayList<>();
        orderStatusFinish.add(LogisticsOrderEnum.HAVE_FINISHED.getCode());
        orderStatusFinish.add(LogisticsOrderEnum.HAVE_RECONCILED.getCode());
        orderStatusFinish.add(LogisticsOrderEnum.HAVE_ALREADY_SETTLED.getCode());
        /**根据当前单据状态进行订单金额计算*/
        if (orderStatusFinish.contains(status)) {
            /**亏吨量/吨->装货量-卸货量
             扣亏量/吨->亏吨量-合理损耗值
             扣亏量/吨->亏吨量-合理损耗值(装货量*合理损耗)*/
            BigDecimal loadAmount = logisticsOrder.getLoadAmount() == null ? new BigDecimal("0.00") : logisticsOrder.getLoadAmount();
            BigDecimal unloadAmount = logisticsOrder.getUnloadAmount() == null ? new BigDecimal("0.00") : logisticsOrder.getUnloadAmount();
            //运价
            BigDecimal price = logisticsOrder.getPrice() == null ? new BigDecimal("0.00") : logisticsOrder.getPrice();
            //亏吨量
            BigDecimal defectiveWeighNumber = loadAmount.subtract(unloadAmount);
            //合理损耗值
            BigDecimal lossAmount = loadAmount.multiply(loss);
            //扣亏量/吨
            BigDecimal deductWeighNumber = defectiveWeighNumber.subtract(lossAmount);
            if (deductWeighNumber.compareTo(new BigDecimal("0")) < 0) {
                deductWeighNumber = new BigDecimal("0.00");
            }
            //罚款值
            BigDecimal fineValue = (logisticsOrder.getGoodsPrice() == null ? new BigDecimal("0.00") : logisticsOrder.getGoodsPrice()).multiply(deductWeighNumber);
            if (DictEnum.CHARGING_TYPE_1.getValue().equals(logisticsOrder.getBillingMode())) {
                orderDetailVO.setOrderAmount(price.multiply(loadAmount));
            } else if (DictEnum.CHARGING_TYPE_2.getValue().equals(logisticsOrder.getBillingMode())) {
                orderDetailVO.setOrderAmount(unloadAmount.multiply(price).subtract(fineValue));
            } else if (DictEnum.CHARGING_TYPE_3.getValue().equals(logisticsOrder.getBillingMode())) {
                orderDetailVO.setOrderAmount(price);
            }
        } else {
            orderDetailVO.setOrderAmount(logisticsOrder.getAmount().multiply(logisticsOrder.getPrice()));
        }
        return orderDetailVO;
    }

    /**
     * 撤销托运
     *
     * @param orderDto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public HttpResult cancelConsign(CancelOrderDTO orderDto) {
        log.info("订单-撤销托运请求参数:{}", JSONObject.toJSONString(orderDto));
        HttpResult result = new HttpResult();
        KwtLogisticsOrder logisticsOrder = logisticsOrderMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrder>()
                        .eq(KwtLogisticsOrder::getId, orderDto.getId())
                /* .eq(KwtLogisticsOrder::getLOrderNo, orderDto.getOrderNo())*/
                /**.eq(KwtLogisticsOrder::getEntId, LoginUserHolder.getEntId())*/);
        if (logisticsOrder == null) {
            result.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
            result.setMsg("单据不存在");
            return result;
        }
        if (!LogisticsOrderEnum.PENDING_ORDER.getStatus().equals(String.valueOf(logisticsOrder.getStatus()))) {
            result.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
            result.setMsg("待接单才允许撤销托运");
            return result;
        }
        /**以此字段判别是否存在分包操作*/
        if (ObjectUtils.isEmpty(logisticsOrder.getPid()) && "1".equals(logisticsOrder.getType())) {
            /**并不存在分包，撤销数据回归到贸易订单，[待接单状态]下才能撤销托运*/
            /**调用dubbo 修改数值*/
            Long tOrderId = logisticsOrder.getTOrderId();
            CreateOrCancelLogisticsOrderParam param = new CreateOrCancelLogisticsOrderParam();
            param.setEntrustAmount(logisticsOrder.getAmount().negate());
            param.setUpdateBy(LoginUserHolder.getUserId());
            param.setUpdateByName(LoginUserHolder.getUserName());
            param.setTOrderId(tOrderId);
            HttpResult httpResult = tradeOrderInfoService.createOrCancelLogisticsOrder(param);
            if (HttpStatus.SUCCESS_CODE != httpResult.getCode()) {
                log.info("撤销托运错误:,请求参数:{},响应信息:{}", JSONObject.toJSONString(param), JSONObject.toJSONString(httpResult));
            }
            logisticsOrderMapper.update(null, new LambdaUpdateWrapper<KwtLogisticsOrder>()
                    .eq(KwtLogisticsOrder::getId, logisticsOrder.getId())
                    .set(KwtLogisticsOrder::getStatus, LogisticsOrderEnum.CANCEL_ORDER.getCode())
                    .set(KwtLogisticsOrder::getUpdateBy, LoginUserHolder.getUserId())
                    .set(KwtLogisticsOrder::getUpdateTime, new Date()));
            updateOrderTrack(logisticsOrder.getId(), orderDto.getRemark(), LogisticsOrderEnum.CANCEL_ORDER);
            //mongodb更新
            SckwLogisticsOrder order = new SckwLogisticsOrder();
            order.set_id(logisticsOrder.getId());
            order.setLOrderId(logisticsOrder.getId());
            order.setStatus(LogisticsOrderEnum.CANCEL_ORDER.getStatus());
            order.setUpdateTime(new Date());
            order.setUpdateByName(LoginUserHolder.getUserName());
            order.setUpdateBy(LoginUserHolder.getUserId());
            SckwBusSum busSum = new SckwBusSum();
            //业务汇总类型
            busSum.setBusSumType(BusinessTypeEnum.LOGISTICS_ORDER_TYPE.getName());
            //操作对象（1新增/2修改）
            busSum.setMethod(NumberConstant.TWO);
            //业务汇总数据对象
            busSum.setObject(order);
            streamBridge.send("sckw-busSum", JSON.toJSONString(busSum));
        } else {
            /**即代表存在分包,当次是属于被分包.需要将数据回归到上游数据。*/
            Long pid = logisticsOrder.getPid();
            /**指的是上游单据进行回归*/
            KwtLogisticsOrder order = logisticsOrderMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrder>()
                    .eq(KwtLogisticsOrder::getId, pid));
            //上游分配量
            BigDecimal amount = logisticsOrder.getAmount();
            //已经完成的量
            BigDecimal loadAmount = logisticsOrder.getLoadAmount();
            //未完成的量
            BigDecimal subtract = amount.subtract(loadAmount);
            //.setScale(2,BigDecimal.ROUND_HALF_DOWN)
            BigDecimal add = order.getSubcontractAmount().subtract(amount);
            logisticsOrderMapper.update(null, new LambdaUpdateWrapper<KwtLogisticsOrder>()
                    .eq(KwtLogisticsOrder::getId, order.getId())
                    .set(KwtLogisticsOrder::getDelFlag, NumberConstant.ZERO)
                    .set(KwtLogisticsOrder::getSubcontractAmount, add)
                    .set(KwtLogisticsOrder::getUpdateBy, LoginUserHolder.getUserId())
                    .set(KwtLogisticsOrder::getUpdateTime, new Date()));
//            updateOrderTrack(logisticsOrder.getId(),orderDto.getRemark(),LogisticsOrderEnum.CANCEL_ORDER);
            /**下游订单进行状态改变*/
            logisticsOrderMapper.update(null, new LambdaUpdateWrapper<KwtLogisticsOrder>()
                    .eq(KwtLogisticsOrder::getId, logisticsOrder.getId())
                    .set(KwtLogisticsOrder::getStatus, LogisticsOrderEnum.CANCEL_ORDER.getCode())
                    .set(KwtLogisticsOrder::getUpdateBy, LoginUserHolder.getUserId())
                    .set(KwtLogisticsOrder::getUpdateTime, new Date()));
            updateOrderTrack(logisticsOrder.getId(), orderDto.getRemark(), LogisticsOrderEnum.CANCEL_ORDER);
            /**mongodb更新*/
            //父级
            SckwLogisticsOrder sckwLogisticsOrder = new SckwLogisticsOrder();
            sckwLogisticsOrder.set_id(order.getId());
            sckwLogisticsOrder.setLOrderId(order.getId());
            sckwLogisticsOrder.setSubcontractAmount(add);
            sckwLogisticsOrder.setUpdateTime(new Date());
            sckwLogisticsOrder.setUpdateByName(LoginUserHolder.getUserName());
            sckwLogisticsOrder.setUpdateBy(LoginUserHolder.getUserId());
            SckwBusSum busSum = new SckwBusSum();
            //业务汇总类型
            busSum.setBusSumType(BusinessTypeEnum.LOGISTICS_ORDER_TYPE.getName());
            //操作对象（1新增/2修改）
            busSum.setMethod(NumberConstant.TWO);
            //业务汇总数据对象
            busSum.setObject(sckwLogisticsOrder);
            //当前级
            streamBridge.send("sckw-busSum", JSON.toJSONString(busSum));
            SckwLogisticsOrder logisticsOrder1 = new SckwLogisticsOrder();
            logisticsOrder1.set_id(logisticsOrder.getId());
            logisticsOrder1.setLOrderId(logisticsOrder.getId());
            logisticsOrder1.setStatus(LogisticsOrderEnum.CANCEL_ORDER.getStatus());
            logisticsOrder1.setUpdateTime(new Date());
            logisticsOrder1.setUpdateByName(LoginUserHolder.getUserName());
            logisticsOrder1.setUpdateBy(LoginUserHolder.getUserId());
            SckwBusSum busSum1 = new SckwBusSum();
            //业务汇总类型
            busSum1.setBusSumType(BusinessTypeEnum.LOGISTICS_ORDER_TYPE.getName());
            //操作对象（1新增/2修改）
            busSum1.setMethod(NumberConstant.TWO);
            //业务汇总数据对象
            busSum1.setObject(logisticsOrder1);
            streamBridge.send("sckw-busSum", JSON.toJSONString(busSum1));
        }
//        String type = orderDto.getType();
//        if ("1".equals(type)) {
//            commonService.cancelLogisticsConsignment(logisticsOrder.getLOrderNo(), logisticsOrder.getCreateBy(), logisticsOrder.getEntId(), MessageEnum.CANCELLATION_LOGISTICS,newLogisticsOrderUrl);
//        } else if ("2".equals(type)) {
//            commonService.cancelLogisticsConsignment(logisticsOrder.getLOrderNo(), logisticsOrder.getCreateBy(), logisticsOrder.getEntId(), MessageEnum.CARRIAGE_CANCELLATION_LOGISTICS,newLogisticsOrderUrl);
//        }

        Long id = logisticsOrder.getId();
        //托运
        KwtLogisticsOrderUnit consignUnit = logisticsOrderUnitMapper.selectOne(
                new LambdaQueryWrapper<KwtLogisticsOrderUnit>()
                        .eq(KwtLogisticsOrderUnit::getLOrderId, id)
                        .eq(KwtLogisticsOrderUnit::getUnitType, NumberConstant.ONE));
        //承运
        KwtLogisticsOrderUnit carriageUnit = logisticsOrderUnitMapper.selectOne(
                new LambdaQueryWrapper<KwtLogisticsOrderUnit>()
                        .eq(KwtLogisticsOrderUnit::getLOrderId, id)
                        .eq(KwtLogisticsOrderUnit::getUnitType, NumberConstant.TWO));
//        commonService.cancelLogisticsConsignment(consignUnit, carriageUnit, logisticsOrder.getLOrderNo(), logisticsOrder.getCreateBy(),
//                logisticsOrder.getEntId(), MessageEnum.CANCELLATION_LOGISTICS, MessageEnum.CARRIAGE_CANCELLATION_LOGISTICS);
        commonService.newSendLogisticsOrderToMessage(consignUnit, carriageUnit, logisticsOrder.getLOrderNo(), logisticsOrder.getCreateBy(),
                logisticsOrder.getEntId(),
                messageUrlConfig.getPc().getConsignLogisticsAddOrderUrl(), messageUrlConfig.getApp().getConsignLogisticsAddOrderUrl(),
                messageUrlConfig.getPc().getCarriageLogisticsAddOrderUrl(), messageUrlConfig.getApp().getCarriageLogisticsAddOrderUrl(),
                MessageEnum.CANCELLATION_LOGISTICS, MessageEnum.CARRIAGE_CANCELLATION_LOGISTICS,
                "1");
        return result;
    }

    /**
     * 根据物流订单修改物流状态表
     *
     * @param id
     * @param remark
     * @param logisticsOrderEnum
     */
    private void updateOrderTrack(Long id, String remark, LogisticsOrderEnum logisticsOrderEnum) {
        KwtLogisticsOrderTrack orderTrack = logisticsOrderTrackMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderTrack>()
                .eq(KwtLogisticsOrderTrack::getLOrderId, id)
                .eq(KwtLogisticsOrderTrack::getStatus, logisticsOrderEnum.getCode())
        );
        if (orderTrack == null) {
            KwtLogisticsOrderTrack track = new KwtLogisticsOrderTrack();
            track.setId(new IdWorker(NumberConstant.ONE).nextId());
            track.setLOrderId(id);
            track.setRemark(remark);
            track.setStatus(LogisticsOrderEnum.CANCEL_ORDER.getCode());
            track.setCreateBy(LoginUserHolder.getUserId());
            track.setCreateTime(new Date());
            track.setUpdateBy(LoginUserHolder.getUserId());
            track.setUpdateTime(new Date());
            logisticsOrderTrackMapper.insert(track);
        } else {
            orderTrack.setRemark(remark);
            orderTrack.setStatus(LogisticsOrderEnum.CANCEL_ORDER.getCode());
            orderTrack.setUpdateBy(LoginUserHolder.getUserId());
            orderTrack.setUpdateTime(new Date());
            logisticsOrderTrackMapper.updateById(orderTrack);
        }
    }

    /**
     * 对账管理-运费收款对账界面查询接口
     *
     * @param logisticsOrderParam
     * @return
     */
    public HttpResult getAcceptCarriageOrder(LogisticsOrderParam logisticsOrderParam) {
        SysDictResDto sysDictResDto = remoteSystemService.queryDictByTypeAndValue(DictTypeEnum.TRADE_TYPE.getType(), logisticsOrderParam.getPayment());
        String dictValue = sysDictResDto == null ? null : sysDictResDto.getValue();
        if (StringUtils.isNotBlank(logisticsOrderParam.getStartTime())) {
            logisticsOrderParam.setStartTime(StringTimeUtil.fillStart(logisticsOrderParam.getStartTime()));
        }
        if (StringUtils.isNotBlank(logisticsOrderParam.getEndTime())) {
            logisticsOrderParam.setEndTime(StringTimeUtil.fillEnd(logisticsOrderParam.getEndTime()));
        }
        Integer page = logisticsOrderParam.getPage();
        Long entId = LoginUserHolder.getEntId();
        List<Long> ids = new ArrayList<>();
        ids.add(entId);
        EntCacheResDto entCacheResDto = remoteSystemService.queryEntTreeById(entId);
        if (entCacheResDto != null) {
            ids.add(entCacheResDto.getId());
        }
        List<Integer> orderStatusList = new ArrayList<>();
        orderStatusList.add(LogisticsOrderEnum.HAVE_FINISHED.getCode());
        ids = ids.stream().distinct().collect(Collectors.toList());
        logisticsOrderParam.setPage((logisticsOrderParam.getPage() - 1) * logisticsOrderParam.getPageSize());
        List<LogisticsOrderVO> list = logisticsOrderMapper.selectLogisticOrderData(logisticsOrderParam, dictValue, LoginUserHolder.getEntId(), ids, orderStatusList);
        Long count = logisticsOrderMapper.selectLogisticOrderCount(logisticsOrderParam, dictValue, LoginUserHolder.getEntId(), ids, orderStatusList);
        /**计量单位*/
        Map<String, String> unitTypeDictData = getDictData(DictTypeEnum.UNIT_TYPE.getType());
        /**运价方式*/
        Map<String, String> priceDictData = getDictData(DictTypeEnum.PRICE_TYPE.getType());
//        /**签约方式*/
//        Map<String, String> singDictData = getDictData(DictTypeEnum.SIGNING_TYPE.getType());
        /**计费方式*/
        Map<String, String> chargingDictData = getDictData(DictTypeEnum.CHARGING_TYPE.getType());
        /**结算周期*/
        Map<String, String> settlementDictData = getDictData(DictTypeEnum.SETTLEMENT_CYCLE.getType());
        /**合理损耗*/
        Map<String, String> taxRateTypeDictData = getDictData(DictTypeEnum.TAX_RATE_TYPE.getType());
        if (CollectionUtils.isNotEmpty(list)) {
            for (LogisticsOrderVO logisticsOrderDTO : list) {

                String tOrderId = logisticsOrderDTO.getTOrderId();
                if (StringUtils.isNotBlank(tOrderId)) {
                    try {
                        OrderDetailRes orderDetailById = tradeOrderInfoService.getOrderDetailById(Long.parseLong(tOrderId));
                        if (orderDetailById != null) {
                            List<UnitInfoDetailRes> unitInfo = orderDetailById.getUnitInfo();
                            if (CollectionUtils.isNotEmpty(unitInfo)) {
                                for (UnitInfoDetailRes detailRes : unitInfo) {
                                    if ("1".equals(detailRes.getUnitType())) {
                                        logisticsOrderDTO.setConsignee(detailRes.getFirmName());
                                    }
                                    if ("2".equals(detailRes.getUnitType())) {
                                        logisticsOrderDTO.setForwardingUnit(detailRes.getFirmName());
                                    }
                                }
                            }
                        }
                    } catch (NumberFormatException e) {
                        System.out.println("查询不到贸易订单数据,id" + tOrderId);
                    }
                }

                KwtLogisticsOrderUnit consignOrderUnit = logisticsOrderUnitMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderUnit>()
                        .eq(KwtLogisticsOrderUnit::getLOrderId, logisticsOrderDTO.getLOrderId())
                        .eq(KwtLogisticsOrderUnit::getUnitType, NumberConstant.ONE));
                KwtLogisticsOrderUnit carrierOrderUnit = logisticsOrderUnitMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderUnit>()
                        .eq(KwtLogisticsOrderUnit::getLOrderId, logisticsOrderDTO.getLOrderId())
                        .eq(KwtLogisticsOrderUnit::getUnitType, NumberConstant.TWO));
                KwtLogisticsOrderAddress loadOrderAddress = logisticsOrderAddressMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderAddress>()
                        .eq(KwtLogisticsOrderAddress::getLOrderId, logisticsOrderDTO.getLOrderId())
                        .eq(KwtLogisticsOrderAddress::getAddressType, NumberConstant.ONE)
                );
                KwtLogisticsOrderAddress unloadOrderAddress = logisticsOrderAddressMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderAddress>()
                        .eq(KwtLogisticsOrderAddress::getLOrderId, logisticsOrderDTO.getLOrderId())
                        .eq(KwtLogisticsOrderAddress::getAddressType, NumberConstant.TWO)
                );
                KwtLogisticsOrderContract contract = logisticsOrderContractMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderContract>()
                        .eq(KwtLogisticsOrderContract::getLOrderId, logisticsOrderDTO.getLOrderId())
                );

                KwtLogisticsOrderGoods orderGoods = logisticsOrderGoodsMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderGoods>()
                        .eq(KwtLogisticsOrderGoods::getLOrderId, logisticsOrderDTO.getLOrderId())
                );
                logisticsOrderDTO.setGoodsName(orderGoods == null ? null : orderGoods.getGoodsName());

                String billingMode = logisticsOrderDTO.getBillingMode();

                /**
                 * 一、罚款值计算：
                 * 1、合理损耗值=实装量*合理损耗（‰）
                 *  1.1 亏吨量= 实装量-实卸量
                 * 2、扣亏量=亏吨量-合理损耗值【要求大于0，如果小于0则扣亏货量取0】
                 * 3、罚款值=扣亏量 * 扣亏货值
                 *
                 * 二、运价计算：
                 * 1、按装货量：总运价=实装量*运价-罚款值
                 * 2、按卸货量：总运价=实卸量*运价-罚款值
                 * 3、按趟次：总运价=运价*趟次【后期加】
                 */
                //运价
                BigDecimal price = logisticsOrderDTO.getPrice() == null ? new BigDecimal("0.00") : logisticsOrderDTO.getPrice();


                /**亏吨量/吨->装货量-卸货量
                 扣亏量/吨->亏吨量-合理损耗值
                 扣亏量/吨->亏吨量-合理损耗值(装货量*合理损耗)*/
                BigDecimal loadAmount = logisticsOrderDTO.getTotalLoadAmount() == null ? new BigDecimal("0.00") : logisticsOrderDTO.getTotalLoadAmount();
                BigDecimal unloadAmount = logisticsOrderDTO.getTotalUnloadAmount() == null ? new BigDecimal("0.00") : logisticsOrderDTO.getTotalUnloadAmount();
                BigDecimal loss = logisticsOrderDTO.getLoss() == null ? new BigDecimal("0.00") : logisticsOrderDTO.getLoss();
                //亏吨量
                BigDecimal defectiveWeighNumber = loadAmount.subtract(unloadAmount);
                //合理损耗值
                BigDecimal lossAmount = loadAmount.multiply(logisticsOrderDTO.getLoss() == null ? new BigDecimal("0.00") : logisticsOrderDTO.getLoss());
                //扣亏量
//                BigDecimal deductWeighNumber = defectiveWeighNumber.subtract(lossAmount);
//                if (deductWeighNumber.compareTo(new BigDecimal("0")) < 0) {
//                    deductWeighNumber = new BigDecimal("0.00");
//                }
                BigDecimal deductWeighNumber = commonService.deficitLossAmount(loadAmount, defectiveWeighNumber, loss, logisticsOrderDTO.getLossUnit());
                //罚款值
                BigDecimal fineValue = (logisticsOrderDTO.getGoodsPrice() == null ? new BigDecimal("0.00") : logisticsOrderDTO.getGoodsPrice()).multiply(deductWeighNumber);
                /**
                 *
                 * 二、运价计算：
                 * 1、按装货量：总运价=实装量*运价-罚款值
                 * 2、按卸货量：总运价=实卸量*运价-罚款值
                 * 3、按趟次：总运价=运价*趟次【后期加】
                 */
                //todo 2023-10-10 含税金额不减去罚款值 另指定罚款值进行返回数据
                BigDecimal actualAmount = new BigDecimal("0.00");
                if (DictEnum.CHARGING_TYPE_1.getValue().equals(billingMode)) {
//                    actualAmount = (logisticsOrderDTO.getTotalLoadAmount() == null ? new BigDecimal("0.00") : logisticsOrderDTO.getTotalLoadAmount()).multiply(price).subtract(fineValue);
                    actualAmount = (logisticsOrderDTO.getTotalLoadAmount() == null ? new BigDecimal("0.00") : logisticsOrderDTO.getTotalLoadAmount()).multiply(price);
                } else if (DictEnum.CHARGING_TYPE_2.getValue().equals(billingMode)) {
//                    actualAmount = (logisticsOrderDTO.getTotalUnloadAmount() == null ? new BigDecimal("0.00") : logisticsOrderDTO.getTotalUnloadAmount()).multiply(price).subtract(fineValue);
                    actualAmount = (logisticsOrderDTO.getTotalUnloadAmount() == null ? new BigDecimal("0.00") : logisticsOrderDTO.getTotalUnloadAmount()).multiply(price);
                }
                logisticsOrderDTO.setDeductPrice(fineValue);
                logisticsOrderDTO.setTaxMoney(actualAmount);
//                logisticsOrderDTO.setContractId();
                logisticsOrderDTO.setContractName(contract.getContractName());
                logisticsOrderDTO.setContractNo(contract.getContractNo());
                logisticsOrderDTO.setGoodsPriceLabel(priceDictData.get(logisticsOrderDTO.getPriceType()));
                logisticsOrderDTO.setCreateByName(remoteSystemService.queryUserCacheById(logisticsOrderDTO.getCreateBy()) == null ? null : remoteSystemService.queryUserCacheById(logisticsOrderDTO.getCreateBy()).getName());
                logisticsOrderDTO.setLoadAddress(loadOrderAddress.getDetailAddress());
                logisticsOrderDTO.setLoadName(loadOrderAddress.getName());
                logisticsOrderDTO.setLoadContacts(loadOrderAddress.getContacts());
                logisticsOrderDTO.setLoadPhone(loadOrderAddress.getPhone());
                logisticsOrderDTO.setUnloadAddress(unloadOrderAddress.getDetailAddress());
                logisticsOrderDTO.setUnloadName(unloadOrderAddress.getName());
                logisticsOrderDTO.setUnloadContacts(unloadOrderAddress.getContacts());
                logisticsOrderDTO.setUnloadPhone(unloadOrderAddress.getPhone());
                logisticsOrderDTO.setCarrierCompany(carrierOrderUnit == null ? null : carrierOrderUnit.getFirmName());
                logisticsOrderDTO.setCarrierPhone(carrierOrderUnit == null ? null : carrierOrderUnit.getPhone());
                logisticsOrderDTO.setCarrierContacts(carrierOrderUnit == null ? null : carrierOrderUnit.getContacts());
                logisticsOrderDTO.setConsignCompany(consignOrderUnit == null ? null : consignOrderUnit.getFirmName());
                logisticsOrderDTO.setConsignPhone(consignOrderUnit == null ? null : consignOrderUnit.getPhone());
                logisticsOrderDTO.setConsignContacts(consignOrderUnit == null ? null : consignOrderUnit.getContacts());
                logisticsOrderDTO.setSettlementCycleLabel(logisticsOrderDTO.getSettlementCycle() == null ? null : settlementDictData.get(logisticsOrderDTO.getSettlementCycle().toString()));
                logisticsOrderDTO.setBillingModeLabel(chargingDictData.get(logisticsOrderDTO.getBillingMode()));
                logisticsOrderDTO.setPriceLabel(priceDictData.get(logisticsOrderDTO.getPriceType()));
                logisticsOrderDTO.setLossUnitLabel(taxRateTypeDictData.get(logisticsOrderDTO.getLossUnit()));
                logisticsOrderDTO.setAmountLabel(unitTypeDictData.get(logisticsOrderDTO.getUnit()));
                logisticsOrderDTO.setIgnoreAmountLabel(unitTypeDictData.get(logisticsOrderDTO.getUnit()));
                logisticsOrderDTO.setLoadAmount(logisticsOrderDTO.getTotalLoadAmount());
                logisticsOrderDTO.setUnloadAmount(logisticsOrderDTO.getTotalUnloadAmount());
                if (logisticsOrderDTO.getTOrderId() != null) {
                    try {
                        OrderDetailRes orderDetailRes = tradeOrderInfoService.getOrderDetailById(Long.valueOf(logisticsOrderDTO.getTOrderId()));
                        if (orderDetailRes != null) {
                            List<UnitInfoDetailRes> unitInfo = orderDetailRes.getUnitInfo();
                            if (CollectionUtils.isNotEmpty(unitInfo)) {
                                for (UnitInfoDetailRes unitInfoDetailRes : unitInfo) {
                                    if (String.valueOf(NumberConstant.TWO).equals(unitInfoDetailRes.getUnitType())) {
                                        logisticsOrderDTO.setShipmentsUnitId(String.valueOf(unitInfoDetailRes.getEntId()));
                                        logisticsOrderDTO.setShipmentsUnit(unitInfoDetailRes.getFirmName());
                                    } else if (String.valueOf(NumberConstant.ONE).equals(unitInfoDetailRes.getUnitType())) {
                                        logisticsOrderDTO.setReceiveGoodsUnitId(String.valueOf(unitInfoDetailRes.getEntId()));
                                        logisticsOrderDTO.setReceiveGoodsUnit(unitInfoDetailRes.getFirmName());
                                    }
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.error("tradeOrderInfoService.getOrderDetailById error id:{},errorMessage:{}", logisticsOrderDTO.getTOrderId(), e.getMessage(), e);
                    }
                }
//                logisticsOrderDTO.setCount(waybillOrderMapper.selectCount(new LambdaQueryWrapper<KwtWaybillOrder>().eq(KwtWaybillOrder::getLOrderId, logisticsOrderDTO.getLOrderId())));
            }
        }
        PageResult build = PageResult.build(page, logisticsOrderParam.getPageSize(), count, list);
        return HttpResult.ok(build);
    }

    public Map<String, String> getDictData(String type) {
        Map<String, String> maps = new HashMap<>(NumberConstant.SIXTEEN);
        List<SysDictResDto> list = remoteSystemService.queryDictByType(type);
        if (CollectionUtils.isNotEmpty(list)) {
            maps = list.stream().collect(Collectors.toMap(SysDictResDto::getValue, SysDictResDto::getLabel, (key1, key2) -> key2));
        }
        return maps;
    }

    public HttpResult getLogisticsOrderByContractId(ContractParam contractParam) {
        List<Long> contractIds = StringUtils.splitStrToList(contractParam.getContractIds(), Long.class);
        Map<Long, EntCacheResDto> entMap = remoteSystemService.queryEntTreeByIds(Collections.singletonList(LoginUserHolder.getEntId()));
        List<SckwLogisticsOrderVO> list = logisticsOrderMapper.selectOrderListByContractId(contractParam.getContractType(), entMap.get(LoginUserHolder.getEntId()).getId(), contractIds);
        List<SckwLogisticsOrderVO> returnList = new ArrayList<>();
        /**计量单位*/
        Map<String, String> dictResDtoMap = getDictData(DictTypeEnum.UNIT_TYPE.getType());
        /**支付方式*/
        Map<String, String> tradeTypeDictData = getDictData(DictTypeEnum.TRADE_TYPE.getType());
        /**运价方式*/
//        Map<String, String> priceDictData = getDictData(DictTypeEnum.PRICE_TYPE.getType());
        /**计费方式*/
        Map<String, String> chargingDictData = getDictData(DictTypeEnum.CHARGING_TYPE.getType());
        /**结算周期*/
        Map<String, String> settlementDictData = getDictData(DictTypeEnum.SETTLEMENT_CYCLE.getType());
        /**签约方式*/
//        Map<String, String> signingWay = getDictData(DictTypeEnum.SIGNING_TYPE.getType());
        /**合理损耗*/
        Map<String, String> taxRateTypeDictData = getDictData(DictTypeEnum.TAX_RATE_TYPE.getType());
        if (CollectionUtils.isNotEmpty(list)) {
            for (SckwLogisticsOrderVO vo : list) {
                vo.setBillingModeLabel(chargingDictData == null ? null : chargingDictData.get(vo.getBillingMode()));
                vo.setPaymentLabel(vo.getPayment() == null ? null : tradeTypeDictData.get(vo.getPayment().toString()));
                vo.setStatusLabel(LogisticsOrderEnum.getDestination(vo.getStatus()));
                vo.setLossUnitLabel(vo.getLossUnit() == null ? null : taxRateTypeDictData.get(vo.getLossUnit()));
                vo.setUnitLabel(vo.getUnit() == null ? null : dictResDtoMap.get(vo.getUnit()));
                vo.setGoodsPriceUnitLabel(vo.getGoodsPriceUnit() == null ? null : dictResDtoMap.get(vo.getGoodsPriceUnit()));
                vo.setSettlementCycleLabel(vo.getSettlementCycle() == null ? null : settlementDictData.get(vo.getSettlementCycle().toString()));
                UserCacheResDto userCacheResDto = remoteSystemService.queryUserCacheById(vo.getCreateBy());
                vo.setCreateByName(userCacheResDto == null ? null : userCacheResDto.getName());
            }
            returnList = list.stream().skip((contractParam.getPage() - 1) * contractParam.getPageSize()).limit(contractParam.getPageSize()).collect(Collectors.toList());
        }
        PageResult build = PageResult.build(contractParam.getPage(), contractParam.getPageSize(), list.stream().count(), returnList);
        return HttpResult.ok(build);
    }

    /**
     * @param lOrderId 承运订单ID
     * @desc 完结物流订单数据处理
     * @author zk
     * @date 2023/9/18
     **/
    public void closeHandle(Long lOrderId) {
        /**1数据校验**/
        KwtLogisticsOrder logisticsOrder = logisticsOrderMapper.selectById(lOrderId);
        if (logisticsOrder == null) {
            return;
        }

        /**2物流订单树形数据结构**/
        //所有管理物流订单
        List<KwtLogisticsOrder> orders = logisticsOrderMapper.findLogisticsOrder(new HashMap<>(Global.NUMERICAL_SIXTEEN) {{
            put("plOrderIds", lOrderId);
            put("currentlOrderId", logisticsOrder.getPids());
            put("allOrderId", Global.NUMERICAL_ONE);
        }});
        //数据copy
        List<KwtLogisticsOrderTreeVo> logisticsOrders = new ArrayList<>();
        for (KwtLogisticsOrder order : orders) {
            KwtLogisticsOrderTreeVo logisticsOrderVo = new KwtLogisticsOrderTreeVo();
            BeanUtils.copyProperties(order, logisticsOrderVo);
            logisticsOrders.add(logisticsOrderVo);
        }
        List<KwtLogisticsOrderTreeVo> treeData = findTree(logisticsOrders);
        //数据去除已完结订单下级
        orderTreeHandle(treeData);

        /**3链路数据组装*/
        List<List<KwtLogisticsOrderTreeVo>> orderLinks = new ArrayList<>();
        for (KwtLogisticsOrderTreeVo order : treeData) {
            Stack<KwtLogisticsOrderTreeVo> pathStack = new Stack<>();
            iteratorNode(order, pathStack, orderLinks);
        }
        List<KwtLogisticsOrderTreeVo> orderLink = findLink(orderLinks, lOrderId);
        //倒序
        assert orderLink != null;
        Collections.reverse(orderLink);

        /**4数据处理**/
        for (KwtLogisticsOrderTreeVo order : orderLink) {
            //排除已完结订单
            if (Objects.equals(order.getStatus(), LogisticsOrderEnum.HAVE_FINISHED.getCode())) {
                //上级物流订单分包量技术-排除一级物流订单
                if (order.getPid() != null) {
                    //mysql数据更新
                    KwtLogisticsOrder currentOrder = logisticsOrderMapper.selectById(order.getPid());
                    //差值=上游委托量-实际总装货量
                    BigDecimal difference = order.getAmount().subtract(order.getTotalLoadAmount());
                    currentOrder.setSubcontractAmount(currentOrder.getSubcontractAmount().subtract(difference));
                    logisticsOrderMapper.updateById(currentOrder);

                    //Mongodb数据更新
                    SckwLogisticsOrder lOrder = new SckwLogisticsOrder();
                    lOrder.setSubcontractAmount(currentOrder.getSubcontractAmount());
                    waybillOrderService.editSckwLogisticsOrder(lOrder, currentOrder);
                }
                continue;
            }

            //车辆运单统计(运输中的物流订单+车辆运单审核通过)
            WaybillCountVo waybillCount = waybillOrderMapper.findWaybillOrderCount(new HashMap<>(Global.NUMERICAL_SIXTEEN) {{
                //put("ownOrderId", order.getId());
                put("upperlOrderId", order.getId());
                put("passStatus", Global.NUMERICAL_ONE);
                put("logisticsStatus", LogisticsOrderEnum.IN_TRANSIT.getCode());
            }});
            //物流订单统计(运输完成后的物流订单)
            LogisticsCountVo LogisticsCount = logisticsOrderMapper.findLogisticsOrderCount(new HashMap<>(Global.NUMERICAL_SIXTEEN) {{
                put("upperlOrderId", order.getId());
                put("finishedStatus", Global.NUMERICAL_ONE);
            }});

            //mysql数据更新
            KwtLogisticsOrder currentOrder = logisticsOrderMapper.selectById(order.getId());
            currentOrder.setTotalLoadAmount(waybillCount.getLoadAmount().add(LogisticsCount.getTotalLoadAmount()));
            currentOrder.setTotalUnloadAmount(waybillCount.getUnloadAmount().add(LogisticsCount.getTotalUnloadAmount()));
            logisticsOrderMapper.updateById(currentOrder);

            //Mongodb数据更新
            SckwLogisticsOrder lOrder = new SckwLogisticsOrder();
            lOrder.setTotalLoadAmount(currentOrder.getTotalLoadAmount());
            lOrder.setTotalUnloadAmount(currentOrder.getTotalUnloadAmount());
            waybillOrderService.editSckwLogisticsOrder(lOrder, currentOrder);

            //一级物流订单向贸易订单推送数据
            if (order.getPid() == null && Integer.parseInt(order.getType()) == Global.NUMERICAL_ONE) {
                //物流订单统计(运输完成后的物流订单)
                LogisticsCountVo tradeCount = logisticsOrderMapper.findLogisticsOrderCount(new HashMap<>() {{
                    put("tOrderId", order.getTOrderId());
                    put("level", Global.NUMERICAL_ONE);
                }});
                UpdateActualAmountParam tradeOrder = new UpdateActualAmountParam();
                tradeOrder.setTOrderId(logisticsOrder.getTOrderId());
                tradeOrder.setActualLoadAmount(tradeCount.getTotalLoadAmount());
                tradeOrder.setActualUnloadAmount(tradeCount.getTotalUnloadAmount());
                tradeOrder.setUpdateBy(LoginUserHolder.getUserId());
                tradeOrder.setUpdateByName(LoginUserHolder.getUserName());
                log.info("托运订单手动完结请求参数:{}", JSONObject.toJSONString(tradeOrder));
                HttpResult httpResult = tradeOrderInfoService.updateActualAmount(tradeOrder);
                if (httpResult.getCode() != HttpStatus.SUCCESS_CODE) {
                    log.info("贸易订单手动完结订单异常,传递信息:{},返回信息:{}", JSONObject.toJSONString(tradeOrder), JSONObject.toJSONString(httpResult));
                    throw new BusinessException("单据完结出现错误！" + httpResult.getMsg());
                }
            }
        }
    }

    /**
     * @param treeData 物流订单树形数据
     * @desc 数据去除已完结订单下级
     * @author zk
     * @date 2023/9/18
     **/
    public static void orderTreeHandle(List<KwtLogisticsOrderTreeVo> treeData) {
        if (CollectionUtil.isEmpty(treeData)) {
            return;
        }

        for (KwtLogisticsOrderTreeVo order : treeData) {
            orderTreeHandle(order.getChildren());
            if (order.getStatus() == 4) {
                order.setChildren(null);
            }
        }
    }

    /**
     * @param orders 物流订单
     * @desc 树形数据处理
     * @author zk
     * @date 2023/9/18
     **/
    public static List<KwtLogisticsOrderTreeVo> findTree(List<KwtLogisticsOrderTreeVo> orders) {
        //跟节点
        List<KwtLogisticsOrderTreeVo> rootList = new ArrayList();

        //获取根节点数据
        if (CollectionUtil.isNotEmpty(orders)) {
            for (KwtLogisticsOrderTreeVo order : orders) {
                if (order.getPid() == null) {
                    rootList.add(order);
                }
            }
        }

        //遍历，找到二级节点（根节点的id和所有节点中的pid比较）
        for (KwtLogisticsOrderTreeVo order : rootList) {
            List<KwtLogisticsOrderTreeVo> child = getChild(order.getId(), orders);
            order.setChildren(child);
        }

        return rootList;
    }

    /**
     * @param pid    上级物流订单ID
     * @param orders 物流订单
     * @desc 树形数据处理-递归
     * @author zk
     * @date 2023/9/18
     **/
    public static List<KwtLogisticsOrderTreeVo> getChild(Long pid, List<KwtLogisticsOrderTreeVo> orders) {
        List<KwtLogisticsOrderTreeVo> childList = new ArrayList();
        for (KwtLogisticsOrderTreeVo order : orders) {
            if (pid.equals(order.getPid())) {
                //获取当前节点id的所有子列表
                childList.add(order);
            }
        }
        for (KwtLogisticsOrderTreeVo order : childList) {
            //将该id的子节点进行遍历，通过递归调用，获取每一个子节点的子节点数据
            List<KwtLogisticsOrderTreeVo> child = getChild(order.getId(), orders);
            order.setChildren(child);
        }
        if (childList.size() == 0) {
            //子节点的长度为0,返回null,null不会被阿里的FastJson包解析
            return null;
        }
        return childList;
    }

    /**
     * @param: order 当前节点
     * @param: pathstack 栈
     * @param: orderLinks 设备链路信息
     * @desc 链路组装
     * @author zk
     * @date 2023/8/8
     **/
    public static void iteratorNode(KwtLogisticsOrderTreeVo order, Stack<KwtLogisticsOrderTreeVo> pathstack, List orderLinks) {
        //入栈
        pathstack.push(order);
        List childlist = order.getChildren();
        //没有子节点 说明是叶子结点
        if (childlist == null) {
            List list = new ArrayList();
            Iterator stackIt = pathstack.iterator();
            while (stackIt.hasNext()) {
                list.add(stackIt.next());
            }
            List<KwtLogisticsOrderTreeVo> orders = print(list);
            orderLinks.add(orders);
        } else {
            Iterator iterator = childlist.iterator();
            while (iterator.hasNext()) {
                KwtLogisticsOrderTreeVo child = (KwtLogisticsOrderTreeVo) iterator.next();
                //深度优先 进入递归
                iteratorNode(child, pathstack, orderLinks);
                //回溯时候出栈
                pathstack.pop();
            }
        }
    }

    /**
     * @param list 树形数据
     * @desc 链路组装
     * @author zk
     * @date 2023/8/8
     **/
    private static List<KwtLogisticsOrderTreeVo> print(List list) {
        List<KwtLogisticsOrderTreeVo> orders = new ArrayList();
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            KwtLogisticsOrderTreeVo order = (KwtLogisticsOrderTreeVo) iterator.next();
            order.setChildren(null);
            orders.add(order);
        }
        return orders;
    }

    /**
     * @param orderLinks 物流订单链路信息
     * @param lOrderId   物流订单id
     * @desc 获取当前物流订单垂直链路
     * @author zk
     * @date 2023/9/18
     **/
    public static List<KwtLogisticsOrderTreeVo> findLink(List<List<KwtLogisticsOrderTreeVo>> orderLinks, Long lOrderId) {
        for (List<KwtLogisticsOrderTreeVo> logisticsOrders : orderLinks) {
            for (KwtLogisticsOrderTreeVo order : logisticsOrders) {
                if (Objects.equals(lOrderId, order.getId())) {
                    return logisticsOrders;
                }
            }
        }
        return null;
    }

}
