
package com.tmerclub.cloud.delivery.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaOrderShippingService;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.impl.WxMaOrderShippingServiceImpl;
import cn.binarywang.wx.miniapp.bean.shop.request.shipping.*;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.tmerclub.cloud.api.delivery.dto.DeliveryOrderDTO;
import com.tmerclub.cloud.api.delivery.dto.DeliveryOrderItemDTO;
import com.tmerclub.cloud.api.delivery.vo.DeliveryInfoVO;
import com.tmerclub.cloud.api.delivery.vo.DeliveryOrderFeignVO;
import com.tmerclub.cloud.api.delivery.vo.DeliveryOrderItemFeignVO;
import com.tmerclub.cloud.api.order.feign.OrderFeignClient;
import com.tmerclub.cloud.api.payment.dto.PayInfoApiDto;
import com.tmerclub.cloud.api.payment.feign.PaymentFeignClient;
import com.tmerclub.cloud.api.user.feign.UserAddrFeignClient;
import com.tmerclub.cloud.config.WxConfig;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.constant.PayType;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.leaf.manager.SegmentManager;
import com.tmerclub.cloud.common.order.bo.EsOrderBO;
import com.tmerclub.cloud.common.order.constant.DeliveryType;
import com.tmerclub.cloud.common.order.constant.FlowSystemTypeEnum;
import com.tmerclub.cloud.common.order.vo.*;
import com.tmerclub.cloud.common.rocketmq.config.RocketMqConstant;
import com.tmerclub.cloud.common.security.AuthUserContext;
import com.tmerclub.cloud.common.util.Json;
import com.tmerclub.cloud.constant.DistributedIdKey;
import com.tmerclub.cloud.delivery.constant.DeliveryCompanyType;
import com.tmerclub.cloud.delivery.manager.DeliveryPrintManager;
import com.tmerclub.cloud.delivery.mapper.DeliveryOrderItemMapper;
import com.tmerclub.cloud.delivery.mapper.DeliveryOrderMapper;
import com.tmerclub.cloud.delivery.model.DeliveryOrder;
import com.tmerclub.cloud.delivery.model.DeliveryOrderItem;
import com.tmerclub.cloud.delivery.service.DeliveryCompanyService;
import com.tmerclub.cloud.delivery.service.DeliveryOrderService;
import com.tmerclub.cloud.delivery.vo.DeliveryCompanyVO;
import com.tmerclub.cloud.delivery.vo.DeliveryOrderVO;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单快递信息
 *
 * @author tmerclub
 * @date 2020-12-07 15:10:00
 */
@Service
public class DeliveryOrderServiceImpl implements DeliveryOrderService {

    private static final Logger logger = LoggerFactory.getLogger(DeliveryOrderServiceImpl.class);

    @Autowired
    private DeliveryOrderMapper deliveryOrderMapper;
    @Autowired
    private DeliveryOrderItemMapper deliveryOrderItemMapper;
    @Autowired
    private DeliveryCompanyService deliveryCompanyService;
    @Autowired
    private DeliveryPrintManager deliveryPrintManager;
    @Autowired
    private WxConfig wxConfig;
    @Autowired
    private SegmentManager segmentManager;
    @DubboReference
    private UserAddrFeignClient userAddrFeignClient;
    @DubboReference
    private PaymentFeignClient paymentFeignClient;
    @DubboReference
    private OrderFeignClient orderFeignClient;
    @Autowired
    private RocketMQTemplate sendNotifyToUserTemplate;


    @Override
    public DeliveryOrderVO getByDeliveryOrderId(Long deliveryOrderId) {
        return deliveryOrderMapper.getByDeliveryOrderId(deliveryOrderId);
    }

    @Override
    public List<DeliveryOrderFeignVO> getByDeliveryByOrderId(Long orderId) {
        List<DeliveryOrderFeignVO> deliveryOrderList = deliveryOrderMapper.getByDeliveryByOrderId(orderId, null);
        if (CollUtil.isEmpty(deliveryOrderList)) {
            return deliveryOrderList;
        }
        // 只需要查询第一个包裹的物流，其他包裹等用户点击后再查询
        DeliveryOrderFeignVO deliveryOrderFeignVO = deliveryOrderList.get(0);
        // 没有物流信息就不用查询
        if (Objects.isNull(deliveryOrderFeignVO.getDeliveryCompanyId()) || StrUtil.isBlank(deliveryOrderFeignVO.getDeliveryNo())) {
            return deliveryOrderList;
        }
        DeliveryCompanyVO deliveryCompanyVO = new DeliveryCompanyVO();
        if (Objects.equals(deliveryOrderFeignVO.getDeliveryType(), DeliveryType.DELIVERY.value())) {
            deliveryCompanyVO = deliveryCompanyService.getByDeliveryCompanyId(deliveryOrderFeignVO.getDeliveryCompanyId());
        } else if (Objects.equals(deliveryOrderFeignVO.getDeliveryType(), DeliveryType.ONLINE.value())) {
            deliveryCompanyVO = DeliveryCompanyType.getByDeliveryCompanyType(deliveryOrderFeignVO.getDeliveryCompanyId());
        }
        // 获取物流信息
        DeliveryInfoVO deliveryInfoVO;
        if (deliveryCompanyVO == null) {
            deliveryInfoVO = new DeliveryInfoVO();
            logger.error("物流公司信息查询失败，deliveryCompanyId:{}", deliveryOrderFeignVO.getDeliveryCompanyId());
        } else {
            deliveryOrderFeignVO.setDeliveryName(deliveryCompanyVO.getName());
            deliveryInfoVO = deliveryCompanyService.query(deliveryCompanyVO, deliveryOrderFeignVO.getDeliveryNo(), deliveryOrderFeignVO.getConsigneeMobile());
            logger.info("订单物流信息查询完毕： {}", deliveryInfoVO);
        }
        deliveryOrderFeignVO.setDelivery(deliveryInfoVO);
        return deliveryOrderList;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveDeliveryInfo(DeliveryOrderDTO deliveryOrderParam, Integer isPurchase, Integer unDeliveryNum) {
        List<DeliveryOrderFeignVO> deliveryList = getByDeliveryByOrderId(deliveryOrderParam.getOrderId());
        if (deliveryList.size() >= 9 && unDeliveryNum != 0) {
            throw new LuckException("一个订单最多只能拆分成10个包裹，请全选发货");
        }
        List<DeliveryOrderItemDTO> selectOrderItems = deliveryOrderParam.getSelectOrderItems();
        // 快递发货/无需物流/线上发货
        if (Objects.equals(DeliveryType.DELIVERY.value(), deliveryOrderParam.getDeliveryType())
                || Objects.equals(DeliveryType.NOT_DELIVERY.value(), deliveryOrderParam.getDeliveryType())
                || Objects.equals(DeliveryType.ONLINE.value(), deliveryOrderParam.getDeliveryType())) {
            //校验数量及获取发货的总数
            int prodNumSum = getAllProdNum(selectOrderItems);
            loadOrderDateId(deliveryOrderParam);
            DeliveryOrder deliveryOrder = new DeliveryOrder();
            deliveryOrder.setDeliveryOrderId(deliveryOrderParam.getDeliveryOrderId());
            deliveryOrder.setUserId(deliveryOrderParam.getUserId());
            deliveryOrder.setOrderId(deliveryOrderParam.getOrderId());
            if (Objects.equals(DeliveryType.DELIVERY.value(), deliveryOrderParam.getDeliveryType())) {
                //只有快递配送才有物流公司和单号
                logger.info("快递配送，物流公司：{}，单号：{}", deliveryOrderParam.getDeliveryCompanyId(), deliveryOrderParam.getDeliveryNo());
                deliveryOrder.setDeliveryCompanyId(deliveryOrderParam.getDeliveryCompanyId());
                deliveryOrder.setDeliveryNo(deliveryOrderParam.getDeliveryNo());
            } else if (Objects.equals(DeliveryType.ONLINE.value(), deliveryOrderParam.getDeliveryType())){
                // 线上发货DeliveryCompanyId为DeliveryCompanyType中的type
                DeliveryCompanyType deliveryCompanyType = DeliveryCompanyType.instance(deliveryOrderParam.getDeliveryCompanyType());
                logger.info("线上发货，物流公司:{}", deliveryCompanyType.getName());
                deliveryOrder.setDeliveryCompanyId(Long.valueOf(deliveryOrderParam.getDeliveryCompanyType()));
            }
            deliveryOrder.setCreateTime(new Date());
            deliveryOrder.setStatus(1);
            deliveryOrder.setAllCount(prodNumSum);
            // 保存收件人信息
            deliveryOrder.setConsigneeMobile(deliveryOrderParam.getMobile());
            deliveryOrder.setConsigneeName(deliveryOrderParam.getConsignee());
            deliveryOrder.setDeliveryType(deliveryOrderParam.getDeliveryType());
            //保存订单物流信息
            deliveryOrderMapper.save(deliveryOrder);
            //保存需要添加的关联信息
            if (CollectionUtil.isNotEmpty(deliveryOrderParam.getSelectOrderItems())) {
                logger.info("保存订单物流信息，deliveryOrderId：{}", deliveryOrder.getDeliveryOrderId());
                List<DeliveryOrderItem> deliveryOrderItems = new ArrayList<>(Constant.INITIAL_CAPACITY);
                for (DeliveryOrderItemDTO selectOrderItem : deliveryOrderParam.getSelectOrderItems()) {
                    DeliveryOrderItem deliveryOrderItem = new DeliveryOrderItem();
                    deliveryOrderItem.setDeliveryOrderItemId(selectOrderItem.getOrderItemId());
                    deliveryOrderItem.setDeliveryOrderId(deliveryOrder.getDeliveryOrderId());
                    deliveryOrderItem.setCount(selectOrderItem.getChangeNum());
                    deliveryOrderItem.setSpuName(selectOrderItem.getSpuName());
                    deliveryOrderItem.setSupplierImgUrl(selectOrderItem.getSupplierPic());
                    deliveryOrderItem.setSupplierSpuName(selectOrderItem.getSupplierSpuName());
                    deliveryOrderItem.setImgUrl(selectOrderItem.getPic());
                    deliveryOrderItems.add(deliveryOrderItem);
                }
                deliveryOrderItemMapper.saveBatch(deliveryOrderItems);
            }
        }
        if (Objects.equals(DeliveryType.ONLINE.value(), deliveryOrderParam.getDeliveryType())) {
            // 线上发货
            String deliveryNo = deliveryPrintManager.deliveryPrint(deliveryOrderParam, AuthUserContext.get().getSysType(), isPurchase);
            // 更新单号
            DeliveryOrder deliveryOrder = new DeliveryOrder();
            deliveryOrder.setDeliveryOrderId(deliveryOrderParam.getDeliveryOrderId());
            deliveryOrder.setDeliveryNo(deliveryNo);
            deliveryOrderMapper.update(deliveryOrder);
            deliveryOrderParam.setDeliveryNo(deliveryNo);
            SendNotifyBO sendNotifyBO = deliveryOrderParam.getSendNotifyBO();
            if (Objects.nonNull(sendNotifyBO)) {
                sendNotifyBO.setDvyFlowId(deliveryNo);
                List<SendNotifyBO> sendNotifyList = Collections.singletonList(sendNotifyBO);
                sendNotifyToUserTemplate.syncSend(RocketMqConstant.SEND_NOTIFY_TO_USER_TOPIC, new GenericMessage<>(sendNotifyList)).getSendStatus();
            }
        }
        // 小程序发货消息处理
        checkWechatPayDelivery(deliveryOrderParam, unDeliveryNum);
    }

    private void loadOrderDateId(DeliveryOrderDTO deliveryOrderParam) {
        Long deliveryOrderId = segmentManager.getSegmentIdWithDateTime(DistributedIdKey.tmerclub_DELIVERY_ORDER, deliveryOrderParam.getUserId());
        deliveryOrderParam.setDeliveryOrderId(deliveryOrderId);
        for (DeliveryOrderItemDTO selectOrderItem : deliveryOrderParam.getSelectOrderItems()) {
            Long orderItemId = segmentManager.getSegmentIdWithDateTime(DistributedIdKey.tmerclub_DELIVERY_ORDER_ITEM, deliveryOrderParam.getUserId());
            selectOrderItem.setOrderItemId(orderItemId);
        }
    }

    @Override
    public List<DeliveryOrderVO> listDetailDelivery(Long orderId) {
        return deliveryOrderItemMapper.listDetailDelivery(orderId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderDeliveries(List<DeliveryOrderDTO> list) {
        for (DeliveryOrderDTO deliveryOrderDTO : list) {
            if (Objects.equals(deliveryOrderDTO.getDeliveryType(), DeliveryType.ONLINE.value())) {
                throw new LuckException("线上发货不支持修改物流");
            }
            DeliveryOrder deliveryOrder = new DeliveryOrder();
            deliveryOrder.setDeliveryOrderId(deliveryOrderDTO.getDeliveryOrderId());
            deliveryOrder.setDeliveryCompanyId(deliveryOrderDTO.getDeliveryCompanyId());
            deliveryOrder.setDeliveryNo(deliveryOrderDTO.getDeliveryNo());
            deliveryOrder.setUpdateTime(new Date());
            deliveryOrderMapper.update(deliveryOrder);
        }
        updateWechatPayDelivery(list);
//        deliveryOrderMapper.updateBatch(list);
    }

    @Override
    public DeliveryOrderFeignVO deliveryOrderItemInfo(Long deliveryOrderId) {
        List<DeliveryOrderFeignVO> deliveryOrderList = deliveryOrderMapper.getByDeliveryByOrderId(null, deliveryOrderId);
        if (CollUtil.isEmpty(deliveryOrderList)) {
            throw new LuckException("包裹信息不存在，请刷新后重试");
        }
        // 只需要查询第一个包裹的物流，其他包裹等用户点击后再查询
        DeliveryOrderFeignVO deliveryOrderFeignVO = deliveryOrderList.get(0);
        if (Objects.nonNull(deliveryOrderFeignVO) && Objects.nonNull(deliveryOrderFeignVO.getDeliveryNo())) {
            // 查询交易单
            DeliveryCompanyVO deliveryCompanyVO = new DeliveryCompanyVO();
            if (Objects.equals(deliveryOrderFeignVO.getDeliveryType(), DeliveryType.DELIVERY.value())) {
                deliveryCompanyVO = deliveryCompanyService.getByDeliveryCompanyId(deliveryOrderFeignVO.getDeliveryCompanyId());
            } else if (Objects.equals(deliveryOrderFeignVO.getDeliveryType(), DeliveryType.ONLINE.value())) {
                deliveryCompanyVO = DeliveryCompanyType.getByDeliveryCompanyType(deliveryOrderFeignVO.getDeliveryCompanyId());
            }

            // 获取物流信息
            deliveryOrderFeignVO.setDeliveryName(deliveryCompanyVO.getName());
            DeliveryInfoVO deliveryInfoVO = deliveryCompanyService.query(deliveryCompanyVO, deliveryOrderFeignVO.getDeliveryNo(), deliveryOrderFeignVO.getConsigneeMobile());
            deliveryOrderFeignVO.setDelivery(deliveryInfoVO);
        }
        return deliveryOrderFeignVO;
    }

    @Override
    public List<DeliveryOrderFeignVO> listDeliveryCountByOrderId(List<Long> orderIds) {
        if (CollUtil.isEmpty(orderIds)) {
            return new ArrayList<>(0);
        }
        return deliveryOrderMapper.listDeliveryCountByOrderId(orderIds);
    }

    private int getAllProdNum(List<DeliveryOrderItemDTO> selectOrderItems) {
        //获取发货总数
        int prodNumSum = 0;
        for (DeliveryOrderItemDTO selectOrderItem : selectOrderItems) {
            prodNumSum += selectOrderItem.getChangeNum();
        }
        return prodNumSum;
    }

    @Override
    public void save(DeliveryOrder deliveryOrder) {
        deliveryOrderMapper.save(deliveryOrder);
    }

    @Override
    public void update(DeliveryOrder deliveryOrder) {
        deliveryOrderMapper.update(deliveryOrder);
    }

    @Override
    public void deleteById(Long deliveryOrderId) {
        deliveryOrderMapper.deleteById(deliveryOrderId);
    }

    @Override
    public Boolean checkAddr(TransportVO transportVO, Long userId, Long addrId) {
        UserAddrVO userAddrVO;
        if (addrId != null && addrId != 0) {
            userAddrVO = userAddrFeignClient.getUserAddrByAddrId(addrId).getData();
        } else {
            userAddrVO = userAddrFeignClient.getUserAddrByUserId(userId).getData();
        }
        if (transportVO.getIsFreeFee() == 1 || userAddrVO == null) {
            return true;
        } else {
            List<AreaVO> areaList = new ArrayList<>(Constant.INITIAL_CAPACITY);
            List<TransfeeVO> transFees = transportVO.getTransFees();
            if (!transFees.isEmpty()) {
                for (TransfeeVO transFee : transFees) {
                    areaList.addAll(transFee.getCityList());
                }
            }
            Map<Long, List<AreaVO>> areaMap = areaList.stream().collect(Collectors.groupingBy(AreaVO::getAreaId));
            return areaMap.containsKey(userAddrVO.getAreaId());
        }
    }


    /**
     * 小程序发货处理,录入发货信息
     * @param deliveryOrderParam
     * @param unDeliveryNum
     */
    private void checkWechatPayDelivery(DeliveryOrderDTO deliveryOrderParam, int unDeliveryNum) {
        List<PayInfoApiDto> payInfoApiDtos = paymentFeignClient.getPayInfoByUserIdAndOrderId(deliveryOrderParam.getUserId(), deliveryOrderParam.getOrderId()).getData();
        Boolean payFlag = false;
        PayInfoApiDto payInfoApiDto = new PayInfoApiDto();
        if (CollectionUtil.isNotEmpty(payInfoApiDtos)) {
            for (PayInfoApiDto payInfo : payInfoApiDtos) {
                // 判断是否是小程序购买
                if (Objects.equals(payInfo.getPayType(), PayType.WECHATPAY.value()) &&  Objects.equals(payInfo.getSystemModel(), FlowSystemTypeEnum.APPLETS.value())) {
                    payInfoApiDto = payInfo;
                    payFlag = true;
                    break;
                }
            }
        }
        if (payFlag) {
            // 查询小程序是否已开通发货信息管理服务
            Boolean managed = wxConfig.getTradeManaged();
            if (!managed) {
                return;
            }
            List<DeliveryOrderFeignVO> deliveryList = getByDeliveryByOrderId(deliveryOrderParam.getOrderId());
            deliveryList = deliveryList.stream().filter(deliveryOrderFeignVO -> !deliveryOrderFeignVO.getDeliveryOrderId().equals(deliveryOrderParam.getDeliveryOrderId())).collect(Collectors.toList());
            if (unDeliveryNum == 0 && CollectionUtil.isEmpty(deliveryList)) {
                // 统一发货
                upload(deliveryOrderParam, payInfoApiDto);
            }
            if (unDeliveryNum == 0 && CollectionUtil.isNotEmpty(deliveryList)){
                // 多包裹发货
                combinedUpload(deliveryOrderParam, deliveryList, payInfoApiDto);
            }
        }
    }

    /**
     * 修改小程序发货，只能修改一次
     * @param deliveryOrders
     */
    private void updateWechatPayDelivery(List<DeliveryOrderDTO> deliveryOrders) {
        EsOrderBO orderBO = orderFeignClient.getEsOrder(deliveryOrders.get(0).getOrderId()).getData();
        List<PayInfoApiDto> payInfoApiDtos = paymentFeignClient.getPayInfoByUserIdAndOrderId(deliveryOrders.get(0).getUserId(), deliveryOrders.get(0).getOrderId()).getData();
        Boolean payFlag = false;
        PayInfoApiDto payInfoApiDto = new PayInfoApiDto();
        if (CollectionUtil.isNotEmpty(payInfoApiDtos)) {
            for (PayInfoApiDto payInfo : payInfoApiDtos) {
                // 判断是否是小程序购买
                if (Objects.equals(payInfo.getPayType(), PayType.WECHATPAY.value()) &&  Objects.equals(payInfo.getSystemModel(), FlowSystemTypeEnum.APPLETS.value())) {
                    payInfoApiDto = payInfo;
                    payFlag = true;
                    break;
                }
            }
        }
        if (payFlag) {
            // 查询小程序是否已开通发货信息管理服务
            Boolean managed = wxConfig.getTradeManaged();
            if (!managed) {
                return;
            }
            WxMaOrderCombinedShippingInfoUploadRequest request = new WxMaOrderCombinedShippingInfoUploadRequest();
            OrderKeyBean orderKey = new OrderKeyBean();
            orderKey.setOrderNumberType(2);
            orderKey.setTransactionId(payInfoApiDto.getBizPayNo());
            request.setOrderKey(orderKey);
            WxMaOrderCombinedShippingInfoUploadRequest.SubOrderBean subOrderBean = new WxMaOrderCombinedShippingInfoUploadRequest.SubOrderBean();
            subOrderBean.setOrderKey(orderKey);
            subOrderBean.setDeliveryMode(2);
            subOrderBean.setLogisticsType(deliveryOrders.get(0).getDeliveryType() == 0 ? 1 : deliveryOrders.get(0).getDeliveryType());
            subOrderBean.setIsAllDelivered(true);
            List<ShippingListBean> shippingListBeanList = new ArrayList<>();
            for (DeliveryOrderDTO deliveryOrder : deliveryOrders) {
                if (deliveryOrder.getCreateTime().getTime() != deliveryOrder.getUpdateTime().getTime()) {
                    // 已经修改过一次了，不能再次修改小程序发货信息
                    break;
                }
                ShippingListBean shippingListBean = new ShippingListBean();
                shippingListBean.setTrackingNo(deliveryOrder.getDeliveryNo());
                DeliveryCompanyVO delivery = deliveryCompanyService.getByDeliveryCompanyId(deliveryOrder.getDeliveryCompanyId());
                if (Objects.nonNull(delivery)) {
                    shippingListBean.setExpressCompany(delivery.getBirdNo() == null ? delivery.getHundredNo() : delivery.getBirdNo());
                } else {
                    DeliveryCompanyType deliveryCompanyType = DeliveryCompanyType.instance(deliveryOrder.getDeliveryCompanyType());
                    shippingListBean.setExpressCompany(deliveryCompanyType.getKuaidicom());
                }
                String itemDesc = "";

                for (DeliveryOrderItem orderItem : deliveryOrderItemMapper.listItemDelivery(deliveryOrder.getDeliveryOrderId())) {
                    itemDesc += orderItem.getSpuName() + "*" + orderItem.getCount() + "    ";
                }
                shippingListBean.setItemDesc(itemDesc);
                ContactBean contactBean = new ContactBean();
                String mobile = getByDeliveryOrderId(deliveryOrder.getDeliveryOrderId()).getConsigneeMobile();
                contactBean.setReceiverContact(mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2"));
                shippingListBean.setContact(contactBean);
                shippingListBeanList.add(shippingListBean);
            }
            if(shippingListBeanList.size() == 0){
                return;
            }
            subOrderBean.setShippingList(shippingListBeanList);
            request.setSubOrders(Collections.singletonList(subOrderBean));
            DateFormat dft = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
            request.setUploadTime(dft.format(new Date()));
            PayerBean payerBean = new PayerBean();
            payerBean.setOpenid(payInfoApiDto.getBizUserId());
            request.setPayer(payerBean);
            try {
                WxMaService wxMaService = wxConfig.getWxMaService();
                WxMaOrderShippingService wxMaOrderShippingService = new WxMaOrderShippingServiceImpl(wxMaService);
                logger.info("修改发货录入的参数" + Json.toJsonString(request));
                wxMaOrderShippingService.upload(request);
            } catch (WxErrorException wxErrorException) {
                wxErrorException.printStackTrace();
                throw new LuckException(wxErrorException.getError().getErrorMsg());
            }
        }
    }

    /**
     * 发货信息录入接口,统一发货（一次性全部发货）
     * @param deliveryOrderParam
     */
    private void upload(DeliveryOrderDTO deliveryOrderParam, PayInfoApiDto payInfoApiDto) {
        // 统一发货
        WxMaOrderShippingInfoUploadRequest request = new WxMaOrderShippingInfoUploadRequest();
        OrderKeyBean orderKey = new OrderKeyBean();
        orderKey.setOrderNumberType(2);
        orderKey.setTransactionId(payInfoApiDto.getBizPayNo());
        request.setOrderKey(orderKey);
        request.setDeliveryMode(1);
        request.setLogisticsType(deliveryOrderParam.getDeliveryType() == 0 ? 1 : deliveryOrderParam.getDeliveryType());
        request.setShippingList(Collections.singletonList(createShippingBean(deliveryOrderParam)));
        DateFormat dft = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
        request.setUploadTime(dft.format(new Date()));
        PayerBean payerBean = new PayerBean();
        payerBean.setOpenid(payInfoApiDto.getBizUserId());
        request.setPayer(payerBean);
        try {
            WxMaService wxMaService = wxConfig.getWxMaService();
            WxMaOrderShippingService wxMaOrderShippingService = new WxMaOrderShippingServiceImpl(wxMaService);
            logger.info("一次发货录入的参数" + Json.toJsonString(request));
            wxMaOrderShippingService.upload(request);
        } catch (WxErrorException wxErrorException) {
            wxErrorException.printStackTrace();
            throw new LuckException(wxErrorException.getError().getErrorMsg());
        }
    }

    /**
     * 发货信息合单录入接口,多包裹发货（多次发货）
     * @param deliveryOrderParam
     * @param deliveryList
     * @param payInfoApiDto
     */
    private void combinedUpload(DeliveryOrderDTO deliveryOrderParam, List<DeliveryOrderFeignVO> deliveryList, PayInfoApiDto payInfoApiDto) {
        // 分批发货
        WxMaOrderCombinedShippingInfoUploadRequest request = new WxMaOrderCombinedShippingInfoUploadRequest();
        OrderKeyBean orderKey = new OrderKeyBean();
        orderKey.setOrderNumberType(2);
        orderKey.setTransactionId(payInfoApiDto.getBizPayNo());
        request.setOrderKey(orderKey);
        WxMaOrderCombinedShippingInfoUploadRequest.SubOrderBean subOrderBean = new WxMaOrderCombinedShippingInfoUploadRequest.SubOrderBean();
        subOrderBean.setOrderKey(orderKey);
        subOrderBean.setDeliveryMode(2);
        subOrderBean.setLogisticsType(deliveryOrderParam.getDeliveryType() == 0 ? 1 : deliveryOrderParam.getDeliveryType());
        subOrderBean.setIsAllDelivered(true);
        List<ShippingListBean> shippingListBeanList = new ArrayList<>();
        shippingListBeanList.add(createShippingBean(deliveryOrderParam));
        for (DeliveryOrderFeignVO orderFeignVO : deliveryList) {
            ShippingListBean shippingListBean = new ShippingListBean();
            if ( !orderFeignVO.getDeliveryType().equals(DeliveryType.NOT_DELIVERY.value())) {
                shippingListBean.setTrackingNo(orderFeignVO.getDeliveryNo());
                DeliveryCompanyVO delivery = deliveryCompanyService.getByDeliveryCompanyId(orderFeignVO.getDeliveryCompanyId());
                if (Objects.nonNull(delivery)) {
                    shippingListBean.setExpressCompany(delivery.getBirdNo() == null ? delivery.getHundredNo() : delivery.getBirdNo());
                } else {
                    DeliveryCompanyType deliveryCompanyType = DeliveryCompanyType.instance(deliveryOrderParam.getDeliveryCompanyType());
                    shippingListBean.setExpressCompany(deliveryCompanyType.getKuaidicom());
                }
                ContactBean contactBean = new ContactBean();
                contactBean.setReceiverContact(orderFeignVO.getConsigneeMobile().replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2"));
                shippingListBean.setContact(contactBean);
            }
            String itemDesc = "";
            for (DeliveryOrderItemFeignVO orderItem : orderFeignVO.getOrderItems()) {
                itemDesc += orderItem.getSpuName() + "*" + orderItem.getCount() + "    ";
            }
            shippingListBean.setItemDesc(itemDesc);
            shippingListBeanList.add(shippingListBean);
        }
        subOrderBean.setShippingList(shippingListBeanList);
        request.setSubOrders(Collections.singletonList(subOrderBean));
        DateFormat dft = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
        request.setUploadTime(dft.format(new Date()));
        PayerBean payerBean = new PayerBean();
        payerBean.setOpenid(payInfoApiDto.getBizUserId());
        request.setPayer(payerBean);
        try {
            WxMaService wxMaService = wxConfig.getWxMaService();
            WxMaOrderShippingService wxMaOrderShippingService = new WxMaOrderShippingServiceImpl(wxMaService);
            logger.info("多包裹合单录入的参数" + Json.toJsonString(request));
            wxMaOrderShippingService.upload(request);
        } catch (WxErrorException wxErrorException) {
            wxErrorException.printStackTrace();
            throw new LuckException(wxErrorException.getError().getErrorMsg());
        }
    }

    /**
     * 创建小程序发货的包裹信息
     * @param deliveryOrderParam
     * @return
     */
    private ShippingListBean createShippingBean(DeliveryOrderDTO deliveryOrderParam) {
        ShippingListBean shippingListBean = new ShippingListBean();
        if (!deliveryOrderParam.getDeliveryType().equals(DeliveryType.NOT_DELIVERY.value())) {
            shippingListBean.setTrackingNo(deliveryOrderParam.getDeliveryNo());
            shippingListBean.setExpressCompany(null);
            if (Objects.nonNull(deliveryOrderParam.getDeliveryCompanyId())){
                DeliveryCompanyVO delivery = deliveryCompanyService.getByDeliveryCompanyId(deliveryOrderParam.getDeliveryCompanyId());
                shippingListBean.setExpressCompany(delivery.getBirdNo() == null ? delivery.getHundredNo() : delivery.getBirdNo());
            } else {
                DeliveryCompanyType deliveryCompanyType = DeliveryCompanyType.instance(deliveryOrderParam.getDeliveryCompanyType());
                shippingListBean.setExpressCompany(deliveryCompanyType.getKuaidicom());
            }
            ContactBean contactBean = new ContactBean();
            contactBean.setReceiverContact(deliveryOrderParam.getMobile().replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2"));
            shippingListBean.setContact(contactBean);
        }
        String itemDesc = "";
        for (DeliveryOrderItemDTO orderItem : deliveryOrderParam.getSelectOrderItems()) {
            itemDesc += orderItem.getSpuName() + "*" + orderItem.getChangeNum() + "    ";
        }
        shippingListBean.setItemDesc(itemDesc);
        return shippingListBean;
    }

}
