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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.tmerclub.cloud.api.auth.constant.SysTypeEnum;
import com.tmerclub.cloud.api.delivery.dto.DeliveryOrderDTO;
import com.tmerclub.cloud.api.delivery.dto.DeliveryOrderItemDTO;
import com.tmerclub.cloud.api.delivery.vo.StationVO;
import com.tmerclub.cloud.api.feign.SearchOrderFeignClient;
import com.tmerclub.cloud.api.feign.SearchSpuFeignClient;
import com.tmerclub.cloud.api.multishop.feign.ShopDetailFeignClient;
import com.tmerclub.cloud.api.multishop.vo.ShopDetailVO;
import com.tmerclub.cloud.api.order.bo.DistributionAmountWithOrderIdBO;
import com.tmerclub.cloud.api.order.constant.OrderStatus;
import com.tmerclub.cloud.api.order.constant.PreSalePayStatus;
import com.tmerclub.cloud.api.order.constant.PurchaseOrderWaitStatus;
import com.tmerclub.cloud.api.order.vo.OrderAmountVO;
import com.tmerclub.cloud.api.order.vo.ShopAmountVO;
import com.tmerclub.cloud.api.payment.dto.OrderPayInfoDTO;
import com.tmerclub.cloud.api.payment.feign.PaymentFeignClient;
import com.tmerclub.cloud.api.product.bo.PlatformCommissionItemBO;
import com.tmerclub.cloud.api.product.bo.PlatformCommissionOrderItemBO;
import com.tmerclub.cloud.api.product.feign.CategoryShopFeignClient;
import com.tmerclub.cloud.api.product.feign.SpuFeignClient;
import com.tmerclub.cloud.api.seckill.feign.SeckillFeignClient;
import com.tmerclub.cloud.api.supplier.feign.SupplierDetailFeignClient;
import com.tmerclub.cloud.api.supplier.vo.SupplierApiDetailVO;
import com.tmerclub.cloud.api.user.bo.UserScoreBO;
import com.tmerclub.cloud.api.user.dto.UserTypeDTO;
import com.tmerclub.cloud.api.user.feign.UserLevelAndScoreOrderFeignClient;
import com.tmerclub.cloud.api.user.feign.UserLevelLogFeignClient;
import com.tmerclub.cloud.api.user.vo.UserApiVO;
import com.tmerclub.cloud.api.vo.EsPageVO;
import com.tmerclub.cloud.common.cache.constant.LockCacheNames;
import com.tmerclub.cloud.common.constant.*;
import com.tmerclub.cloud.common.database.dto.PageDTO;
import com.tmerclub.cloud.common.database.util.PageAdapter;
import com.tmerclub.cloud.common.database.util.PageUtil;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.i18n.I18nMessage;
import com.tmerclub.cloud.common.i18n.LanguageEnum;
import com.tmerclub.cloud.common.leaf.manager.SegmentManager;
import com.tmerclub.cloud.common.mongodb.bo.order.MongoOrderBO;
import com.tmerclub.cloud.common.order.bo.EsOrderBO;
import com.tmerclub.cloud.common.order.bo.EsOrderItemBO;
import com.tmerclub.cloud.common.order.bo.OrderStatusBO;
import com.tmerclub.cloud.common.order.bo.PayNotifyBO;
import com.tmerclub.cloud.common.order.constant.*;
import com.tmerclub.cloud.common.order.dto.*;
import com.tmerclub.cloud.common.order.util.OrderLangUtil;
import com.tmerclub.cloud.common.order.vo.*;
import com.tmerclub.cloud.common.product.constant.PreSaleType;
import com.tmerclub.cloud.common.product.constant.SpuMold;
import com.tmerclub.cloud.common.product.constant.SupplierDeliveryType;
import com.tmerclub.cloud.common.product.dto.ProductSearchDTO;
import com.tmerclub.cloud.common.product.vo.SpuVO;
import com.tmerclub.cloud.common.product.vo.search.SpuAdminVO;
import com.tmerclub.cloud.common.response.ResponseEnum;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.rocketmq.config.RocketMqConstant;
import com.tmerclub.cloud.common.security.AuthUserContext;
import com.tmerclub.cloud.common.util.*;
import com.tmerclub.cloud.constant.DistributedIdKey;
import com.tmerclub.cloud.delivery.constant.DeliveryCompanyType;
import com.tmerclub.cloud.delivery.manager.DeliveryManager;
import com.tmerclub.cloud.delivery.mapper.DeliveryCompanyMapper;
import com.tmerclub.cloud.delivery.service.StationService;
import com.tmerclub.cloud.delivery.vo.DeliveryCompanyVO;
import com.tmerclub.cloud.order.bo.SubmitOrderPayAmountInfoBO;
import com.tmerclub.cloud.order.constant.PlatformInterventionStatus;
import com.tmerclub.cloud.order.constant.RefundType;
import com.tmerclub.cloud.order.dto.multishop.OrderAdminDTO;
import com.tmerclub.cloud.order.dto.multishop.OrderItemDTO;
import com.tmerclub.cloud.order.dto.multishop.OrderRefundDTO;
import com.tmerclub.cloud.order.manager.MongoOrderRefundManager;
import com.tmerclub.cloud.order.mapper.OrderMapper;
import com.tmerclub.cloud.order.mapper.OrderRefundMapper;
import com.tmerclub.cloud.order.mapper.OrderSettlementMapper;
import com.tmerclub.cloud.order.model.*;
import com.tmerclub.cloud.order.service.*;
import com.tmerclub.cloud.order.model.*;
import com.tmerclub.cloud.order.service.*;
import com.tmerclub.cloud.order.vo.OrderAndPreSaleVO;
import com.tmerclub.cloud.order.vo.OrderRefundVO;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
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.util.*;
import java.util.stream.Collectors;

/**
 * 订单信息
 *
 * @author tmerclub
 * @date 2020-12-05 14:13:50
 */
@Service
public class OrderServiceImpl implements OrderService {
    private static final Logger log = LoggerFactory.getLogger(OrderServiceImpl.class);
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private RocketMQTemplate orderPurchaseNotifyShopTemplate;
    @Autowired
    private OrderSettlementMapper orderSettlementMapper;
    @Autowired
    private OrderItemService orderItemService;
    @Autowired
    private DeliveryCompanyMapper deliveryCompanyMapper;
    @Autowired
    private OrderItemLangService orderItemLangService;
    @Autowired
    private OrderPreSaleInfoService orderPreSaleInfoService;
    @Autowired
    private OrderRefundMapper orderRefundMapper;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private DeliveryManager deliveryManager;
    @Autowired
    private OrderAddrService orderAddrService;
    @Autowired
    private OrderSettlementService orderSettlementService;
    @Autowired
    private RocketMQTemplate stockMqTemplate;
    @Autowired
    private RocketMQTemplate couponMqTemplate;
    @Autowired
    private RocketMQTemplate sendNotifyToUserTemplate;
    @Autowired
    private RocketMQTemplate groupOrderCancelMqTemplate;
    @Autowired
    private RocketMQTemplate seckillOrderCancelMqTemplate;
    @Autowired
    private RocketMQTemplate userScoreTemplate;
    @Autowired
    private RocketMQTemplate sendNotifyToShopTemplate;
    @Autowired
    private OrderSelfStationService orderSelfStationService;
    @Autowired
    private OrderInvoiceService orderInvoiceService;
    @Autowired
    private OrderVirtualInfoService orderVirtualInfoService;
    @Autowired
    private RocketMQTemplate orderSubmitShopCartTemplate;
    @Autowired
    private SegmentManager segmentManager;
    @Autowired
    private MongoOrderRefundManager mongoOrderRefundManager;
    @Autowired
    private StationService stationService;
    @DubboReference
    private CategoryShopFeignClient categoryShopFeignClient;
    @DubboReference
    private SearchOrderFeignClient searchOrderFeignClient;
    @DubboReference
    private SearchSpuFeignClient searchSpuFeignClient;
    @DubboReference
    private PaymentFeignClient paymentFeignClient;
    @DubboReference
    private SpuFeignClient spuFeignClient;
    @DubboReference
    private UserLevelLogFeignClient userLevelLogFeignClient;
    @DubboReference
    private UserLevelAndScoreOrderFeignClient userLevelAndScoreOrderFeignClient;
    @DubboReference
    private ShopDetailFeignClient shopDetailFeignClient;
    @DubboReference
    private SupplierDetailFeignClient supplierDetailFeignClient;
    @DubboReference
    private SeckillFeignClient seckillFeignClient;

    @Override
    public Order getByOrderId(Long orderId) {
        return orderMapper.getByOrderId(orderId);
    }

    @Override
    public void update(Order order) {
        orderMapper.update(order);
    }

    @Override
    public void deleteById(Long orderId) {
        orderMapper.deleteById(orderId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submit(ShopCartOrderMergerVO mergerOrder) {
        Long userId = mergerOrder.getUserId();
        // 订单商品参数
        List<ShopCartOrderVO> shopCartOrders = mergerOrder.getShopCartOrders();

        List<OrderSettlement> orderSettlements = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<Order> orders = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<OrderItem> orderItems = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<OrderItem> giveawayOrderItems = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<OrderPreSaleInfo> orderPreSaleInfos = new ArrayList<>(Constant.INITIAL_CAPACITY);
        Set<Long> shopCartItemIds = new HashSet<>(Constant.INITIAL_CAPACITY);
        OrderAddr orderAddr = BeanUtil.map(mergerOrder.getUserAddr(), OrderAddr.class);
        if (Objects.nonNull(mergerOrder.getUserAddr())) {
            Long addrId = segmentManager.getSegmentIdWithDateTime(DistributedIdKey.tmerclub_ORDER_ADDR, userId);
            orderAddr.setOrderAddrId(addrId);
        }

        Map<Long, List<VirtualRemarkVO>> virtualRemarkMap = new HashMap<>(8);
        List<OrderVirtualInfo> orderVirtualInfos = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<OrderSelfStation> orderSelfStations = new ArrayList<>(Constant.INITIAL_CAPACITY);
        // 虚拟商品备注信息列表
        if (CollUtil.isNotEmpty(mergerOrder.getVirtualRemarkList())) {
            virtualRemarkMap = mergerOrder.getVirtualRemarkList().stream().collect(Collectors.groupingBy(VirtualRemarkVO::getSpuId));
        }
        // 只会有一个
        StationVO station = null;
        Map<Long, Integer> dvyTypeMap = mergerOrder.getDvyTypes().stream().collect(Collectors.toMap(DvyTypeDTO::getShopId, DvyTypeDTO::getDvyType));
        // 每个店铺生成一个订单
        for (ShopCartOrderVO shopCartOrderDto : shopCartOrders) {
            Order order = this.getOrder(userId, dvyTypeMap.get(shopCartOrderDto.getShopId()), mergerOrder.getSpuMold(), shopCartOrderDto);
            // 获取订单id
            order.setOrderId(shopCartOrderDto.getOrderId());
            this.saveOrderInvoice(mergerOrder, order);
            this.addOrderSettlement(mergerOrder, userId, orderSettlements, shopCartOrderDto, order);

            List<ShopCartItemDiscountVO> shopCartItemDiscounts = shopCartOrderDto.getShopCartItemDiscounts();
            for (ShopCartItemDiscountVO shopCartItemDiscount : shopCartItemDiscounts) {
                List<ShopCartItemVO> shopCartItems = shopCartItemDiscount.getShopCartItems();
                for (ShopCartItemVO shopCartItem : shopCartItems) {
                    if (!Objects.equals(shopCartItem.getCartItemId(), 0L)) {
                        shopCartItemIds.add(shopCartItem.getCartItemId());
                    }
                    if (order.getOrderItems() == null) {
                        order.setOrderItems(new ArrayList<>(0));
                    }
                    OrderItem orderItem = getOrderItem(mergerOrder, order, shopCartItem, virtualRemarkMap, shopCartOrderDto);
                    orderItem.setOrderItemId(segmentManager.getSegmentIdWithDateTime(DistributedIdKey.tmerclub_ORDER_ITEM, userId));
                    shopCartItem.setOrderItemId(orderItem.getOrderItemId());
                    orderItems.add(orderItem);
                    order.getOrderItems().add(orderItem);
                    handleGiveawayAndCombo(giveawayOrderItems, order, shopCartItem, orderItem);
                    handlePreSaleInfo(orderPreSaleInfos, order, shopCartItem);
                }
            }
            setOrderAddrId(orderAddr, order);
            orders.add(order);
            // 处理自提和同城配送的订单
            int dvyType = dvyTypeMap.get(shopCartOrderDto.getShopId());
            this.deliverySubmitOrderListener(mergerOrder, order, dvyType, station);
            // 处理下虚拟商品订单
            handlerVirtualProdOder(orderVirtualInfos, mergerOrder, shopCartOrderDto, order);
        }

        // 添加赠品订单项
        if (CollUtil.isNotEmpty(giveawayOrderItems)) {
            orderItems.addAll(giveawayOrderItems);
        }

        saveInfo(orderSettlements, orders, orderItems, orderPreSaleInfos, orderVirtualInfos, orderSelfStations, orderAddr);

        // 购物车下单的订单，提交成功后要删掉购物车中的商品信息
        if (CollUtil.isNotEmpty(shopCartItemIds)) {
            SendStatus sendStatus = orderSubmitShopCartTemplate.syncSend(RocketMqConstant.ORDER_SUBMIT_SHOP_CART,
                    new GenericMessage<>(new OrderSubmitShopCartItemDTO(userId, new ArrayList<>(shopCartItemIds)))).getSendStatus();
            if (!Objects.equals(sendStatus, SendStatus.SEND_OK)) {
                throw new LuckException(ResponseEnum.EXCEPTION);
            }
        }
    }

    private void saveInfo(List<OrderSettlement> orderSettlements, List<Order> orders, List<OrderItem> orderItems,
                          List<OrderPreSaleInfo> orderPreSaleInfos, List<OrderVirtualInfo> orderVirtualInfos,
                          List<OrderSelfStation> orderSelfStations, OrderAddr orderAddr) {
        Date createTime = new Date();
        orders.forEach(order -> order.setCreateTime(createTime));
        orderItems.forEach(item -> item.setCreateTime(createTime));
        orderSettlements.forEach(item -> item.setCreateTime(createTime));
        orderMapper.saveBatch(orders);
        orderItemService.saveBatch(orderItems);
        orderItemLangService.saveOrderItemLang(orderItems);

        // 保存收货地址
        if (Objects.nonNull(orderAddr)) {
            orderAddr.setCreateTime(createTime);
            // 保存收货地址
            orderAddrService.save(orderAddr);
        }
        // 保存订单结算信息
        orderSettlementMapper.saveBatch(orderSettlements);
        // 保存预售信息
        if (CollectionUtil.isNotEmpty(orderPreSaleInfos)) {
            orderPreSaleInfoService.saveBatch(orderPreSaleInfos,createTime);
        }
        // 保存虚拟订单核销信息
        if (CollUtil.isNotEmpty(orderVirtualInfos)) {
            orderVirtualInfoService.saveBatch(orderVirtualInfos);
        }
        // 保存自提订单信息
        if (CollUtil.isNotEmpty(orderSelfStations)) {
            orderSelfStationService.saveBatch(orderSelfStations);
        }
    }

    private void handleGiveawayAndCombo(List<OrderItem> giveawayOrderItems, Order order, ShopCartItemVO shopCartItem, OrderItem orderItem) {

        // 赠品
        List<OrderItem> orderItemList = giveawayOrderItems(order, shopCartItem);
        if (CollectionUtil.isNotEmpty(orderItemList)) {
            orderItem.setMainGiveaway(1);
            giveawayOrderItems.addAll(orderItemList);
        }else{
            orderItemList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        }
        // 组合商品
        if (CollUtil.isEmpty(shopCartItem.getComboShopCartItems())) {
            return;
        }
//        int allCount = order.getAllCount();
        List<OrderItem> comboOrderItemList = new ArrayList<>(shopCartItem.getComboShopCartItems().size());
        for (ShopCartItemVO shopCartItemVO : shopCartItem.getComboShopCartItems()) {
            OrderItem comboOrderItem = BeanUtil.map(shopCartItemVO, OrderItem.class);
            comboOrderItem.setOrderItemId(segmentManager.getSegmentIdWithDateTime(DistributedIdKey.tmerclub_ORDER_ITEM, order.getUserId()));
            comboOrderItem.setShopId(order.getShopId());
            comboOrderItem.setOrderItemLangList(getOrderItemLangList(shopCartItemVO, comboOrderItem));
            comboOrderItem.setOrderId(order.getOrderId());
            comboOrderItem.setPic(shopCartItemVO.getImgUrl());
            comboOrderItem.setSpuMold(shopCartItemVO.getMold());
            // 保存中英文名称
            comboOrderItem.setCount(shopCartItemVO.getCount());
            //代发货数量
            comboOrderItem.setBeDeliveredNum(shopCartItemVO.getCount());
            comboOrderItem.setPrice(shopCartItemVO.getSkuPriceFee());
            comboOrderItem.setSpuTotalAmount(shopCartItemVO.getTotalAmount());
            comboOrderItem.setUserId(orderItem.getUserId());
            comboOrderItem.setIsComm(0);
            setAmount(shopCartItem, comboOrderItem);
            comboOrderItem.setGiveawayAmount(Constant.ZERO_LONG);
            comboOrderItem.setActivityId(shopCartItem.getOrderItemId());
            // 库存区域id
            comboOrderItem.setStockPointId(shopCartItemVO.getStockPointId());
            comboOrderItem.setActivityType(OrderActivityType.COMBO_PROD.value());

            // 供应商相关信息保存
            comboOrderItem.setPartyCode(shopCartItem.getPartyCode());
            comboOrderItem.setSupplierSpuId(shopCartItem.getSupplierSpuId());
            comboOrderItem.setSupplierSkuId(shopCartItem.getSupplierSkuId());
//            comboOrderItem.setItemPurchaseAmount(shopCartItem.getTotalPurchaseAmount() != null ? shopCartItem.getTotalPurchaseAmount() : 0L);
//            comboOrderItem.setSupplierId(shopCartItem.getSupplierId());
//            comboOrderItem.setSpuCode(shopCartItem.getSpuCode());
//            comboOrderItem.setComboAmount(shopCartItem.getComboAmount());
            //供应商订单字段数据
            if (Objects.nonNull(comboOrderItem.getSupplierSpuId())) {
                comboOrderItem.setSupplierPic(shopCartItem.getSupplierUrl());
            }

            orderItemList.add(comboOrderItem);
        }

        if (CollectionUtil.isNotEmpty(orderItemList)) {
            giveawayOrderItems.addAll(orderItemList);
        }
    }

    private void handlePreSaleInfo(List<OrderPreSaleInfo> orderPreSaleInfos, Order order, ShopCartItemVO shopCartItem) {
        // 如果是预售商品保存下下预售信息
        if (Objects.nonNull(shopCartItem.getPreSaleType()) && !Objects.equals(shopCartItem.getPreSaleType(), PreSaleType.DISABLE.value())) {
            order.setPreSaleType(shopCartItem.getPreSaleType());
            OrderPreSaleInfo orderPreSaleInfo = getOrderPresaleInfo(order, shopCartItem);
            orderPreSaleInfo.setUserId(order.getUserId());
            orderPreSaleInfos.add(orderPreSaleInfo);
        }
    }

    private static void setOrderAddrId(OrderAddr orderAddr, Order order) {
        if (Objects.nonNull(orderAddr)) {
            order.setOrderAddrId(orderAddr.getOrderAddrId());
        } else {
            order.setOrderAddrId(0L);
        }
    }

    private void addOrderSettlement(ShopCartOrderMergerVO mergerOrder, Long userId, List<OrderSettlement> orderSettlements, ShopCartOrderVO shopCartOrderDto, Order order) {
        // 插入订单结算表
        OrderSettlement orderSettlement = new OrderSettlement();
        Long settlementId = segmentManager.getSegmentIdWithDateTime(DistributedIdKey.tmerclub_ORDER_SETTLEMENT, userId);
        orderSettlement.setSettlementId(settlementId);
        orderSettlement.setUserId(userId);
        orderSettlement.setIsClearing(0);
        orderSettlement.setOrderId(order.getOrderId());
        orderSettlement.setPayAmount(order.getActualTotal());
        orderSettlement.setVersion(0);
        //如果用使用积分，结算表将积分价格插入
        if (mergerOrder.getIsScorePay() != null && mergerOrder.getIsScorePay() == 1) {
            orderSettlement.setPayScore(shopCartOrderDto.getUseScore());
        } else {
            orderSettlement.setPayScore(0L);
        }
        orderSettlements.add(orderSettlement);
    }

    private void saveOrderInvoice(ShopCartOrderMergerVO mergerOrder, Order order) {
        //保存发票信息，每个店铺一个
        if (CollectionUtil.isNotEmpty(mergerOrder.getOrderInvoiceList())) {
            for (OrderInvoiceDTO orderInvoiceDTO : mergerOrder.getOrderInvoiceList()) {
                if (Objects.equals(order.getShopId(), orderInvoiceDTO.getShopId())) {
                    OrderInvoice orderInvoice = BeanUtil.map(orderInvoiceDTO, OrderInvoice.class);
                    orderInvoice.setInvoiceState(1);
                    orderInvoice.setInvoiceType(1);
                    orderInvoice.setInvoiceContext(1);
                    orderInvoice.setApplicationTime(new Date());
                    orderInvoice.setOrderId(order.getOrderId());
                    orderInvoice.setShopId(order.getShopId());
                    orderInvoiceService.save(order.getUserId(), orderInvoice);
                }
            }
        }
    }


    /**
     * 计算分摊金额
     */
    private void calculatePlatformCommission(List<Order> orders, List<OrderItem> orderItems) {
        List<PlatformCommissionOrderItemBO> platformCommissionOrderItems = new ArrayList<>(Constant.INITIAL_CAPACITY);
        for (OrderItem orderItem : orderItems) {
            PlatformCommissionOrderItemBO platformCommissionOrderItemBO = getPlatformCommissionOrderItemBO(orderItem);
            platformCommissionOrderItems.add(platformCommissionOrderItemBO);
        }


        ServerResponseEntity<List<PlatformCommissionOrderItemBO>> listServerResponseEntity = categoryShopFeignClient.calculatePlatformCommission(platformCommissionOrderItems);
        if (!listServerResponseEntity.isSuccess()) {
            throw new LuckException(listServerResponseEntity);
        }


        List<PlatformCommissionOrderItemBO> data = listServerResponseEntity.getData();
        for (OrderItem orderItem : orderItems) {
            for (PlatformCommissionOrderItemBO platformCommissionOrderItemBO : data) {
                // 积分订单属于平台的订单不需要计算平台佣金
                if (Objects.equals(orders.get(0).getOrderType(), OrderType.SCORE.value())) {
                    // 分摊比例
                    orderItem.setRate(0.0);
                    // 平台佣金
                    orderItem.setPlatformCommission(0L);
                    orderItem.setSupplierRate(0.0);
                    orderItem.setPurchasePlatformCommission(0L);
                    continue;
                }
                //赠品和子组合订单不需要计算佣金
                if (Objects.equals(orderItem.getActivityType(), OrderActivityType.GIVEAWAY.value()) || Objects.equals(orderItem.getActivityType(), OrderActivityType.COMBO_PROD.value())) {
                    // 分摊比例
                    orderItem.setRate(0.0);
                    // 平台佣金
                    orderItem.setPlatformCommission(0L);
                    orderItem.setSupplierRate(0.0);
                    orderItem.setPurchasePlatformCommission(0L);
                    break;
                }
                // 通过商品确定订单项
                if (Objects.equals(orderItem.getSkuId(), platformCommissionOrderItemBO.getSkuId())) {
                    // 分摊比例
                    orderItem.setRate(platformCommissionOrderItemBO.getRate());
                    // 平台佣金,如果是商家代销，供应商采购价的佣金也需要计算
                    // 平台对商家的差价抽佣 = （商家定的销售价格 - 供应商价格）-（商家定的销售价格 - 供应商价格）* 平台抽佣百分比
                    // 平台对商家的差价抽佣 = （用户实付金额 + 平台优惠金额 - 供应商金额） * 比例
                    long shopAmount = orderItem.getActualTotal() + orderItem.getPlatformShareReduce() - orderItem.getItemPurchaseAmount();
                    shopAmount = Math.max(shopAmount, 0L);
                    orderItem.setPlatformCommission(PriceUtil.divideByBankerRounding((long) ((shopAmount) * platformCommissionOrderItemBO.getRate()), 100));
                    orderItem.setSupplierRate(0.0);
                    orderItem.setPurchasePlatformCommission(0L);
                    if (!Objects.equals(orderItem.getSupplierId(), 0L)) {
                        // 供应商没有平台优惠，此时不用加上平台优惠进行计算
                        // 平台对供应商的抽佣 = 供应商定价 * 平台抽佣百分比
                        orderItem.setPurchasePlatformCommission(PriceUtil.divideByBankerRounding((long) (orderItem.getItemPurchaseAmount() * platformCommissionOrderItemBO.getSupplierRate()), 100));
                        orderItem.setSupplierRate(platformCommissionOrderItemBO.getSupplierRate());
                    }
                }
            }
        }
        Map<Long, List<OrderItem>> orderIdMap = orderItems.stream().collect(Collectors.groupingBy(OrderItem::getOrderId));
        for (Order order : orders) {
            Long totalPlatformCommission = 0L;
            List<OrderItem> orderItemList = orderIdMap.get(order.getOrderId());
            for (OrderItem orderItem : orderItemList) {
                totalPlatformCommission += orderItem.getPlatformCommission();
            }
            order.setPlatformCommission(totalPlatformCommission);
        }

    }

    private static PlatformCommissionOrderItemBO getPlatformCommissionOrderItemBO(OrderItem orderItem) {
        PlatformCommissionOrderItemBO platformCommissionOrderItemBO = new PlatformCommissionOrderItemBO();
        PlatformCommissionItemBO platformCommissionShop = new PlatformCommissionItemBO();
        platformCommissionShop.setShopId(orderItem.getShopId());
        platformCommissionShop.setSysType(SysTypeEnum.MULTISHOP.value());
        platformCommissionOrderItemBO.setShopItem(platformCommissionShop);
        // 如果有供应商也放进去
        if (!Objects.equals(orderItem.getSupplierId(), 0L)) {
            PlatformCommissionItemBO platformCommissionSupplierItem = new PlatformCommissionItemBO();
            platformCommissionSupplierItem.setShopId(orderItem.getSupplierId());
            platformCommissionSupplierItem.setSysType(SysTypeEnum.SUPPLIER.value());
            platformCommissionOrderItemBO.setSupplierItem(platformCommissionSupplierItem);
        }
        platformCommissionOrderItemBO.setCategoryId(orderItem.getCategoryId());
        platformCommissionOrderItemBO.setSkuId(orderItem.getSkuId());
        return platformCommissionOrderItemBO;
    }

    @Override
    public List<OrderStatusBO> getOrdersStatus(List<Long> orderIds) {
        if (CollUtil.isEmpty(orderIds)) {
            return new ArrayList<>(0);
        }
        List<OrderStatusBO> orderStatusList = orderMapper.getOrdersStatus(orderIds);
        if (CollUtil.isEmpty(orderStatusList)) {
            return new ArrayList<>(0);
        }
        for (Long orderId : orderIds) {
            boolean hasOrderId = false;
            for (OrderStatusBO orderStatusBO : orderStatusList) {
                if (Objects.equals(orderStatusBO.getOrderId(), orderId)) {
                    hasOrderId = true;
                    break;
                }
            }
            if (!hasOrderId) {
                OrderStatusBO orderStatusBO = new OrderStatusBO();
                orderStatusBO.setOrderId(orderId);
                orderStatusList.add(orderStatusBO);
            }
        }
        return orderStatusList;
    }

    @Override
    public OrderAmountVO getOrdersActualAmount(List<Long> orderIds) {
        if (CollUtil.isEmpty(orderIds)) {
            return null;
        }
        List<OrderAndPreSaleVO> orderAmountList = orderMapper.listOrderActualAmount(orderIds);
        OrderAmountVO orderAmountVO = new OrderAmountVO();
        orderAmountVO.setPayAmount(0L);
        Map<Long, ShopAmountVO> shopAmountMap = new HashMap<>(16);
        for (OrderAndPreSaleVO orderVO : orderAmountList) {
            orderAmountVO.setPayScore(orderVO.getOrderScore());
            // 定金预售判断
            boolean flag = Objects.equals(orderVO.getPreSaleType(), PreSaleType.DEPOSIT.value());
            long payAmount = 0L;
            if (flag) {
                // 未付定金
                if (Objects.equals(orderVO.getStatus(), OrderStatus.UNPAY.value())) {
                    payAmount = orderVO.getDepositAmount();
                }
                // 未付尾款
                long balanceAmount = orderVO.getBalanceAmount() + orderVO.getFreightAmount() - orderVO.getPlatformFreeFreightAmount();
                if (Objects.equals(orderVO.getStatus(), OrderStatus.WAIT_BALANCE.value()) && balanceAmount <= 0L) {
                    throw new LuckException("尾款为0，无需进行支付尾款");
                }
                if (Objects.equals(orderVO.getStatus(), OrderStatus.WAIT_BALANCE.value())) {
                    // 如果是支付尾款还需要加上运费
                    payAmount = balanceAmount;
                }
            } else {
                // 普通订单
                payAmount = orderVO.getActualTotal();
            }
            orderAmountVO.setPayAmount(orderAmountVO.getPayAmount() + payAmount);
            // 添加下收款人和金额
            if (!shopAmountMap.containsKey(orderVO.getShopId())) {
                ShopAmountVO shopAmountVO = new ShopAmountVO();
                shopAmountVO.setBizUserId(orderVO.getShopId().toString());
                shopAmountVO.setAmount(payAmount);
                shopAmountMap.put(orderVO.getShopId(), shopAmountVO);
            } else {
                ShopAmountVO shopAmount = shopAmountMap.get(orderVO.getShopId());
                shopAmount.setAmount(shopAmount.getAmount() + payAmount);
                shopAmountMap.put(orderVO.getShopId(), shopAmount);
            }
        }
        List<ShopAmountVO> shopAmountList = new ArrayList<>(shopAmountMap.values());
        orderAmountVO.setShopAmountList(shopAmountList);
        return orderAmountVO;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<OrderStatusBO> updateByToPaySuccess(PayNotifyBO message, List<OrderStatusBO> ordersStatus, List<Long> orderIds) {

        if (CollectionUtil.isEmpty(ordersStatus) && Objects.isNull(message.getShopCartOrderMergerVO())) {
            log.error("无法找到订单信息，message: + {}", Json.toJsonString(message));
            return null;
        }
        // 如果数据库没有，但是messag有则直接保存到数据库
        if(Objects.nonNull(message.getShopCartOrderMergerVO()) && CollectionUtil.isEmpty(ordersStatus)){
            ShopCartOrderMergerVO shopCartOrderMergerVO = message.getShopCartOrderMergerVO();
            RLock lock = redissonClient.getLock(LockCacheNames.LOCK_SECKILL_ORDER_PAY_SUCCESS_PERFIX + shopCartOrderMergerVO.getUserId());
            lock.lock();
            try {
//                // 再查询一遍确定没有数据
//                List<OrderStatusBO> ordersStatusResponse = getOrdersStatus(orderIdList);
                // 从redis中查询到了数据，存入到数据库，此处用到了分布式锁，防止多个线程同时操作数据库
                submit(message.getShopCartOrderMergerVO());
            } finally {
                lock.unlock();
            }
            ordersStatus = getOrdersStatus(orderIds);
        }
        // 还有可能是取消订单再支付的，这里加上已取消的订单
        ordersStatus = ordersStatus.stream()
                .filter(orderStatusBO -> Objects.equals(orderStatusBO.getStatus(), OrderStatus.UNPAY.value())
                        || Objects.equals(orderStatusBO.getStatus(), OrderStatus.CLOSE.value())
                        || Objects.equals(orderStatusBO.getStatus(), OrderStatus.WAIT_BALANCE.value()))
                .collect(Collectors.toList());
        if (CollectionUtil.isEmpty(ordersStatus)) {
            return ordersStatus;
        }
        List<Long> needUpdateOrderIds = ordersStatus.stream().map(OrderStatusBO::getOrderId).collect(Collectors.toList());
        Integer orderType = ordersStatus.get(0).getOrderType();
        Long actualTotal;
        StringBuilder payIds = new StringBuilder(Constant.INITIAL_CAPACITY);
        // 团购订单
        if (Objects.equals(orderType, OrderType.GROUP.value())) {
            // 待成团
            orderMapper.updateByToGroupPaySuccess(needUpdateOrderIds, message.getPayType(), message.getPaySysType());
        } else {
            for (OrderStatusBO esOrderVO : ordersStatus) {
                // 待发货 或待收货
                orderMapper.updateByToPaySuccess(esOrderVO, message.getPayType(), message.getPaySysType());
            }
        }
        for (OrderStatusBO esOrderVO : ordersStatus) {
            if (Objects.equals(esOrderVO.getOrderMold(), 1)) {
                // 如果是虚拟订单，发货时间为当前支付成功时间
                log.info("虚拟订单发货，订单id:{}", esOrderVO.getOrderId());
                Order order = new Order();
                order.setOrderId(esOrderVO.getOrderId());
                order.setDeliveryTime(new Date());
                orderMapper.update(order);
            }
        }
        // 预售信息处理,并且获取当前已经支付的金额
        actualTotal = handleOrderPreSale(needUpdateOrderIds, ordersStatus, message, payIds);
        orderSettlementMapper.updateToPaySuccess(needUpdateOrderIds, message.getPayId(), message.getPayType(), payIds.toString(), actualTotal);
        return ordersStatus;
    }

    private Long handleOrderPreSale(List<Long> needUpdateOrderIds, List<OrderStatusBO> ordersStatusList, PayNotifyBO payNotifyBO, StringBuilder payIds) {
        Integer statusDb = ordersStatusList.get(0).getStatus();
        OrderStatusBO order = ordersStatusList.get(0);
        long payAmount = 0L;
        List<OrderPreSaleInfo> orderPreSaleInfoList = orderPreSaleInfoService.listByOrderIds(needUpdateOrderIds);
        // 如果为空则不需要处理预售信息，且不需要修改金额
        if (CollectionUtil.isEmpty(orderPreSaleInfoList)) {
            return 0L;
        }
        OrderPreSaleInfo dbOrderPreSaleInfo = orderPreSaleInfoList.get(0);
        // 如果是定金预售，还需要修改下订单支付后的状态
        if (Objects.equals(dbOrderPreSaleInfo.getPreSaleType(), PreSaleType.DEPOSIT.value())) {
            // 当前如果尾款为0且(邮费减去平台包邮金额也为0)，并且尾款支付时间已开始，设置订单为待发货状态
            boolean flag = order.getFreightAmount() - order.getPlatformFreeFreightAmount() == 0L && dbOrderPreSaleInfo.getBalanceAmount() == 0L;
            if (dbOrderPreSaleInfo.getBalanceStartTime().getTime() < System.currentTimeMillis() && flag) {
                statusDb = OrderStatus.WAIT_BALANCE.value();
                ordersStatusList.get(0).setStatus(statusDb);
            }
            // 定金预售订单，1.待付尾款 2.待发货
            orderMapper.updateByToPreSaleSuccess(needUpdateOrderIds, statusDb);
        }
        // 处理下预售的发货时间
        for (OrderPreSaleInfo orderPreSaleInfo : orderPreSaleInfoList) {
            if (Objects.equals(orderPreSaleInfo.getPreSaleType(), PreSaleType.DEPOSIT.value())) {
                orderPreSaleInfo.setPayStatus(Objects.equals(statusDb, OrderStatus.UNPAY.value()) ? PreSalePayStatus.PAYED_DEPOSIT.value() : PreSalePayStatus.PAYED_BALANCE.value());
                //尾款支付时间
                orderPreSaleInfo.setBalancePayTime(Objects.equals(statusDb, OrderStatus.UNPAY.value()) ? null : new Date());
                // 定金预售,待支付时支付后的实付金额为定金
                payAmount = Objects.equals(statusDb, OrderStatus.UNPAY.value()) ? orderPreSaleInfo.getDepositAmount() : ordersStatusList.get(0).getActualTotal();
                // 如果发货时间不是固定时间，且为支付尾款设置下发货时间
                if (!Objects.equals(orderPreSaleInfo.getPreSaleDeliveryType(), -1) && Objects.equals(statusDb, OrderStatus.WAIT_BALANCE.value())) {
                    orderPreSaleInfo.setPreSaleDeliveryTime(DateUtil.offsetDay(new DateTime(), orderPreSaleInfo.getPreSaleDeliveryType()));
                }
            } else if (!Objects.equals(orderPreSaleInfo.getPreSaleDeliveryType(), -1)) {
                // 如果全款预售发货时间不是固定时间，设置下发货时间
                orderPreSaleInfo.setPreSaleDeliveryTime(DateUtil.offsetDay(new DateTime(), orderPreSaleInfo.getPreSaleDeliveryType()));
            }
        }
        if (CollectionUtil.isNotEmpty(orderPreSaleInfoList)) {
            orderPreSaleInfoService.updateBatch(orderPreSaleInfoList);
        }
        if (Objects.equals(statusDb, OrderStatus.WAIT_BALANCE.value())) {
            OrderSettlement orderSettlement = orderSettlementMapper.getByOrderId(needUpdateOrderIds.get(0));
            if (Objects.nonNull(payNotifyBO.getPayId())) {
                if (Objects.nonNull(orderSettlement.getPayId())) {
                    payIds.append(orderSettlement.getPayId()).append(StrUtil.COMMA).append(payNotifyBO.getPayId());
                } else {
                    payIds.append(payNotifyBO.getPayId());
                }
            }else{
                payIds.append(orderSettlement.getPayId());
            }
        }
        return payAmount;
    }

    @Override
    public List<OrderSimpleAmountInfoBO> getOrdersSimpleAmountInfo(List<Long> orderIds) {


        List<OrderSimpleAmountInfoBO> ordersSimpleAmountInfos = orderMapper.getOrdersSimpleAmountInfo(orderIds);
        Map<Long, List<OrderRefundVO>> refundMap;
        if (CollUtil.isNotEmpty(orderIds)) {
            List<OrderRefundVO> refunds = orderRefundMapper.getProcessOrderRefundByOrderIds(orderIds);
            List<Long> itemIds = refunds.stream().map(OrderRefundVO::getOrderItemId).filter(itemId -> !Objects.equals(itemId, 0L)).collect(Collectors.toList());
            if(CollectionUtil.isNotEmpty(itemIds)) {
                List<OrderItem> orderItems = orderItemService.listByIds(itemIds);
                Map<Long, OrderItem> orderItemMap = orderItems.stream().collect(Collectors.toMap(OrderItem::getOrderItemId, orderItem -> orderItem));
                for (OrderRefundVO refund : refunds) {
                    if (orderItemMap.containsKey(refund.getOrderItemId())) {
                        OrderItem orderItem = orderItemMap.get(refund.getOrderItemId());
                        refund.setItemPurchaseAmount(orderItem.getItemPurchaseAmount());
                        refund.setActualTotal(orderItem.getActualTotal());
                        refund.setPurPlatformRefundCommission(orderItem.getPurchasePlatformCommission());
                    }
                }
            }
            refundMap = refunds.stream().collect(Collectors.groupingBy(OrderRefundVO::getOrderId));
        } else {
            refundMap = new HashMap<>(0);
        }
        List<DistributionAmountWithOrderIdBO> distributionAmountWithOrderIds = orderItemService.sumTotalDistributionAmountByOrderIds(orderIds);

        for (OrderSimpleAmountInfoBO ordersSimpleAmountInfo : ordersSimpleAmountInfos) {
            long purchaseAmount = 0L;
            long actualTotal = 0L;
            long purchasePlatformCommission = 0L;
            if (refundMap.containsKey(ordersSimpleAmountInfo.getOrderId()) && !Objects.equals(ordersSimpleAmountInfo.getSupplierId(), 0L)) {
                // 减去退款的实付金额，采购金额，采购佣金
                List<OrderRefundVO> orderRefunds = refundMap.get(ordersSimpleAmountInfo.getOrderId());
                for (OrderRefundVO orderRefund : orderRefunds) {
                    if (orderRefund.getItemPurchaseAmount() == null) {
                        continue;
                    }
                    purchaseAmount += orderRefund.getItemPurchaseAmount();
                    actualTotal += orderRefund.getActualTotal();
                    purchasePlatformCommission += orderRefund.getPurPlatformRefundCommission();
                }
                ordersSimpleAmountInfo.setPurchaseAmount(ordersSimpleAmountInfo.getPurchaseAmount() - purchaseAmount);
                ordersSimpleAmountInfo.setActualTotal(ordersSimpleAmountInfo.getActualTotal() - actualTotal);
                ordersSimpleAmountInfo.setPurchasePlatformCommission(ordersSimpleAmountInfo.getPurchasePlatformCommission() - purchasePlatformCommission);
            }

            ordersSimpleAmountInfo.setShopAmount(ordersSimpleAmountInfo.getReduceAmount() - ordersSimpleAmountInfo.getPlatformAmount());
            Long orderId = ordersSimpleAmountInfo.getOrderId();
            ordersSimpleAmountInfo.setDistributionAmount(0L);
            // 订单总分销金额
            for (DistributionAmountWithOrderIdBO distributionAmountWithOrderId : distributionAmountWithOrderIds) {
                if (Objects.equals(distributionAmountWithOrderId.getOrderId(), orderId)) {
                    ordersSimpleAmountInfo.setDistributionAmount(distributionAmountWithOrderId.getDistributionAmount() + distributionAmountWithOrderId.getDistributionParentAmount());
                }
            }
        }

        return ordersSimpleAmountInfos;
    }

    /**
     * 取消订单和mq日志要同时落地
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelOrderAndGetCancelOrderIds(ShopCartOrderMergerVO mergerOrder, List<Long> orderIds) {
        List<OrderStatusBO> ordersStatus = this.getOrdersStatus(orderIds);
        List<Long> cancelOrderIds = new ArrayList<>(Constant.INITIAL_CAPACITY);
        Integer orderType = null;
        Long userId = null;
        // 未支付的订单才插入数据
        for (OrderStatusBO orderStatusBO : ordersStatus) {
            // 状态为空或者
            if (!OrderStatus.unPay(orderStatusBO.getStatus())) {
                continue;
            }
            cancelOrderIds.add(orderStatusBO.getOrderId());
            orderType = orderStatusBO.getOrderType();
            userId = orderStatusBO.getUserId();
        }
        if(Objects.nonNull(mergerOrder) && OrderStatus.unPay(mergerOrder.getStatus())){
            cancelOrderIds.add(orderIds.get(0));
            userId = mergerOrder.getUserId();
            orderType = mergerOrder.getOrderType().value();
        }

        if (CollUtil.isEmpty(cancelOrderIds)) {
            log.info("订单已支付成功，不能取消，订单id：{}", orderIds);
            return;
        }

        // 取消订单之前，先查询下是否已支付成功
        List<Long> paySuccessList = paymentFeignClient.queryAndHandleOrderPaySuccess(new OrderPayInfoDTO(cancelOrderIds, userId));


        // 移除已支付成功的订单id
        if (CollUtil.isNotEmpty(paySuccessList)) {
            cancelOrderIds.removeAll(paySuccessList);
        }
        if (CollectionUtil.isEmpty(cancelOrderIds)) {
            log.info("订单已支付成功，不能取消，订单id：{}", orderIds);
            return;
        }
        // 如果是支付宝支付，或者微信 二维码支付直接使二维码失效
        ServerResponseEntity<?> cancelOrderQrCodeResponseEntity = paymentFeignClient.cancelOrderQrCode(new OrderPayInfoDTO(cancelOrderIds, userId));
        if (!cancelOrderQrCodeResponseEntity.isSuccess()) {
            log.error("失效订单支付宝、微信支付二维码失败，订单id：{}，错误信息：{}", cancelOrderIds, cancelOrderQrCodeResponseEntity.getMsg());
            throw new LuckException(cancelOrderQrCodeResponseEntity.getMsg());
        }
        // 如果是redis中拿的订单且数据库没有这个订单，创建订单
        if(Objects.nonNull(mergerOrder) && CollectionUtil.isEmpty(ordersStatus)) {
            RLock lock = redissonClient.getLock(LockCacheNames.LOCK_SECKILL_ORDER_PAY_SUCCESS_PERFIX + mergerOrder.getUserId());
            lock.lock();
            try {
//                // 再查询一遍确定没有数据
//                List<OrderStatusBO> ordersStatusResponse = getOrdersStatus(orderIdList);
                // 从redis中查询到了数据，存入到数据库，此处用到了分布式锁，防止多个线程同时操作数据库
                submit(mergerOrder);
            } finally {
                lock.unlock();
            }
        }
        // 取消订单
        int updateStatus = orderMapper.cancelOrders(cancelOrderIds);
        // 订单已经支付就不能取消了
        if (updateStatus == 0) {
            throw new LuckException("订单状态已发生改变，请刷新后再试");
        }

        sendOrderMsg(mergerOrder,orderIds, ordersStatus, orderType);
    }

    private void sendOrderMsg(ShopCartOrderMergerVO mergerOrder, List<Long> orderIds, List<OrderStatusBO> ordersStatus, Integer orderType) {
        // 团购订单
        if (Objects.equals(orderType, OrderType.GROUP.value())) {
            SendStatus groupSendStatus = groupOrderCancelMqTemplate.syncSend(RocketMqConstant.GROUP_ORDER_CANCEL_TOPIC, new GenericMessage<>(orderIds)).getSendStatus();
            if (!Objects.equals(groupSendStatus, SendStatus.SEND_OK)) {
                // 消息发不出去就抛异常，发的出去无所谓
                log.error("团购订单取消失败，订单id：{}, 错误信息：{}", orderIds, groupSendStatus);
                throw new LuckException(ResponseEnum.EXCEPTION);
            }
        }

        // 秒杀有自己的库存
        if (Objects.equals(orderType, OrderType.SECKILL.value())) {
            SendStatus groupSendStatus = seckillOrderCancelMqTemplate.syncSend(RocketMqConstant.SECKILL_ORDER_CANCEL_TOPIC, new GenericMessage<>(mergerOrder)).getSendStatus();
            if (!Objects.equals(groupSendStatus, SendStatus.SEND_OK)) {
                // 消息发不出去就抛异常，发的出去无所谓
                log.error("秒杀订单取消失败，订单id：{}, 错误信息：{}", orderIds, groupSendStatus);
                throw new LuckException(ResponseEnum.EXCEPTION);
            }
        } else {
            // 解锁库存状态
            log.info("解锁库存，订单id：{}", orderIds);
            SendStatus stockSendStatus = stockMqTemplate.syncSend(RocketMqConstant.STOCK_UNLOCK_TOPIC_BY_ORDER_ID, new GenericMessage<>(orderIds)).getSendStatus();
            if (!Objects.equals(stockSendStatus, SendStatus.SEND_OK)) {
                // 消息发不出去就抛异常，发的出去无所谓
                log.error("库存解锁失败，订单id：{}, 错误信息：{}", orderIds, stockSendStatus);
                throw new LuckException(ResponseEnum.EXCEPTION);
            }
        }

        if (Objects.equals(orderType, OrderType.ORDINARY.value())) {
            // 解锁优惠券状态
            log.info("解锁优惠券，订单id：{}", orderIds);
            SendStatus couponSendStatus = couponMqTemplate.syncSend(RocketMqConstant.COUPON_UNLOCK_TOPIC, new GenericMessage<>(orderIds)).getSendStatus();
            // 为什么不用批量消息，因为rocketmq不支持topic不一样发批量消息
            if (!Objects.equals(couponSendStatus, SendStatus.SEND_OK)) {
                // 消息发不出去就抛异常，发的出去无所谓
                log.error("优惠券解锁失败，订单id：{}, 错误信息：{}", orderIds, couponSendStatus);
                throw new LuckException(ResponseEnum.EXCEPTION);
            }
        }
        if (Objects.equals(orderType, OrderType.ORDINARY.value()) || Objects.equals(orderType, OrderType.SCORE.value())) {
            // 解锁用户积分状态
            log.info("解锁用户积分，订单id：{}", orderIds);
            UserScoreBO userScoreBo = new UserScoreBO();
            userScoreBo.setUserId(ordersStatus.get(0).getUserId());
            userScoreBo.setOrderIds(orderIds);
            userScoreBo.setFlag(true);
            SendStatus userScoreSendStatus = userScoreTemplate.syncSend(RocketMqConstant.SCORE_UNLOCK_TOPIC, new GenericMessage<>(userScoreBo)).getSendStatus();
            if (!Objects.equals(userScoreSendStatus, SendStatus.SEND_OK)) {
                // 消息发不出去就抛异常，发的出去无所谓
                log.error("用户积分解锁失败，订单id：{}, 用户id：{}", orderIds, ordersStatus.get(0).getUserId());
                throw new LuckException(ResponseEnum.EXCEPTION);
            }
        }
        if(Objects.nonNull(mergerOrder)) {
            // 直接删除redis中该订单
            ServerResponseEntity<Void> responseEntity = seckillFeignClient.deleteRedisOrderByUserIdAndOrderId(mergerOrder.getUserId(), orderIds.get(0));
            if (!responseEntity.isSuccess()) {
                throw new LuckException(ResponseEnum.EXCEPTION);
            }
        }
        // todo 如果涉及到用户积分成长值之类的，要考虑下要不要分布式，取消的订单，除了支付成功，不然都不会改变订单状态
    }

    @Override
    public Order getOrderByOrderIdAndUserId(Long orderId, Long userId) {
        Order order = orderMapper.getOrderByOrderIdAndUserId(orderId, userId);
        if (order == null) {
            // 订单不存在
            log.error("订单不存在，订单id：{}", orderId);
            throw new LuckException(ResponseEnum.ORDER_NOT_EXIST);
        }
        return order;
    }

    @Override
    public Order getOrderByOrderIdAndStationId(Long orderId, Long stationId) {
        Order order = orderMapper.getOrderByOrderIdAndStationId(orderId, stationId);
        if (order == null) {
            // 订单不存在
            log.error("订单不存在，订单id：{}", orderId);
            throw new LuckException(ResponseEnum.ORDER_NOT_EXIST);
        }
        return order;
    }

    @Override
    public OrderVO getOrderByOrderId(Long orderId) {
        Order order = orderMapper.getOrderByOrderIdAndShopId(orderId, AuthUserContext.get().getTenantId());
        if (order == null) {
            // 订单不存在
            log.error("订单不存在，订单id：{}", orderId);
            throw new LuckException(ResponseEnum.ORDER_NOT_EXIST);
        }
        return BeanUtil.map(order, OrderVO.class);
    }

    @Override
    public int receiptOrder(Long orderId) {
        return orderMapper.receiptOrder(orderId);
    }

    @Override
    public void deleteOrder(Long orderId) {
        orderMapper.deleteOrder(orderId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delivery(DeliveryOrderDTO deliveryOrderParam) {
        List<OrderRefundVO> orderRefunds = orderRefundMapper.getProcessingOrderRefundByOrderId(deliveryOrderParam.getOrderId());
        // 移除退款成功的退款记录
        orderRefunds.removeIf(orderRefund -> Objects.equals(orderRefund.getReturnMoneySts(), ReturnProcessStatusEnum.SUCCESS.value()) || Objects.equals(orderRefund.getPlatformInterventionStatus(), PlatformInterventionStatus.SUCCESS.value()));
        if (CollectionUtil.isNotEmpty(orderRefunds)) {
            throw new LuckException("该订单有退款信息正在处理当中，请处理完毕之后再进行发货的操作!");
        }
        // 设置好收货人信息
        OrderAddr orderAddr = orderAddrService.getById(deliveryOrderParam.getOrderAddrId());
        OrderAddrVO orderAddrVO = BeanUtil.map(orderAddr, OrderAddrVO.class);
        if (Objects.nonNull(orderAddrVO)) {
            deliveryOrderParam.setConsignee(orderAddrVO.getConsignee());
            deliveryOrderParam.setMobile(orderAddrVO.getMobile());
        }
        deliveryOrderParam.setUserId(orderAddr.getUserId());

        Order orderDb = orderMapper.getDeliveryInfoByOrderId(deliveryOrderParam.getOrderId());
        // 订单不是待发货状态或者订单正在申请退款中，此时不能对订单进行发货操作
        if (!Objects.equals(orderDb.getStatus(), OrderStatus.PAYED.value()) || Objects.equals(orderDb.getRefundStatus(), RefundStatusEnum.APPLY.value())) {
            log.error("订单不是待发货状态或者订单正在申请退款中，此时不能对订单进行发货操作，订单id：{}", deliveryOrderParam.getOrderId());
            throw new LuckException(ResponseEnum.DATA_ERROR);
        }
        orderItemService.updateByDeliveries(deliveryOrderParam.getSelectOrderItems(), deliveryOrderParam.getDeliveryType(),deliveryOrderParam.getOrderId());
        // 算下未发货商品数量
        int unDeliveryNum = orderItemService.countUnDeliveryNumByOrderId(deliveryOrderParam.getOrderId());
        if (Objects.equals(deliveryOrderParam.getDeliveryType(), DeliveryType.DELIVERY.value())
                || Objects.equals(deliveryOrderParam.getDeliveryType(), DeliveryType.ONLINE.value())) {
            log.info("发货操作，推送给用户发货提醒，订单号为：{}，未发货商品数量为：{}", deliveryOrderParam.getOrderId(), unDeliveryNum);
            String companyName = getCompanyName(deliveryOrderParam);
            StringBuilder sb = new StringBuilder(Constant.INITIAL_CAPACITY);
            for (DeliveryOrderItemDTO selectOrderItem : deliveryOrderParam.getSelectOrderItems()) {
                sb.append(selectOrderItem.getSpuName()).append(StrUtil.COMMA);
            }
            sb.deleteCharAt(sb.length() - 1);
            // 获取订单发货信息, 发送消息给用户
            SendNotifyBO sendNotifyBO = new SendNotifyBO();
            sendNotifyBO.setUserId(orderDb.getUserId());
            sendNotifyBO.setBizId(orderDb.getOrderId());
            sendNotifyBO.setSpuName(sb.toString());
            sendNotifyBO.setShopId(orderDb.getShopId());
            sendNotifyBO.setMobile(orderDb.getMobile());
            sendNotifyBO.setDvyName(companyName);
            sendNotifyBO.setSendType(SendTypeEnum.DELIVERY.getValue());
            sendNotifyBO.setDvyFlowId(deliveryOrderParam.getDeliveryNo());
            if (Objects.equals(deliveryOrderParam.getDeliveryType(), DeliveryType.ONLINE.value())) {
                deliveryOrderParam.setSendNotifyBO(sendNotifyBO);
            } else {
                List<SendNotifyBO> sendNotifyList = Collections.singletonList(sendNotifyBO);
                SendStatus sendStockStatus = sendNotifyToUserTemplate.syncSend(RocketMqConstant.SEND_NOTIFY_TO_USER_TOPIC, new GenericMessage<>(sendNotifyList)).getSendStatus();
            }
        }
        //修改为发货状态
        if (Objects.equals(unDeliveryNum, 0)) {
            log.info("订单已全部发货，订单号为：{}", deliveryOrderParam.getOrderId());
            Date date = new Date();
            Order order = new Order();
            order.setOrderId(deliveryOrderParam.getOrderId());
            order.setStatus(OrderStatus.CONSIGNMENT.value());
            order.setUpdateTime(date);
            order.setDeliveryTime(date);
            //判断是无需物流还是快递发货,如果是无需快递，则判断该订单是否包含有物流的项，若有物流则配送类型为快递配送，没有物流则不变
            if (orderItemService.getDevTypeByOrderId(deliveryOrderParam.getOrderId())) {
                order.setDeliveryType(DeliveryType.DELIVERY.value());
            } else {
                order.setDeliveryType(deliveryOrderParam.getDeliveryType());
            }
            orderMapper.update(order);
        }
        // 确定订单发货后，保存订单包裹数据
        deliveryManager.saveDeliveryInfo(deliveryOrderParam, 0, unDeliveryNum);
    }

    private String getCompanyName(DeliveryOrderDTO deliveryOrderParam) {
        String companyName;
        if (Objects.equals(deliveryOrderParam.getDeliveryType(), DeliveryType.DELIVERY.value())) {
            DeliveryCompanyVO deliveryCompanyVO = deliveryCompanyMapper.getByDeliveryCompanyId(deliveryOrderParam.getDeliveryCompanyId());
            companyName = deliveryCompanyVO.getName();
        } else {
            DeliveryCompanyType deliveryCompanyType = DeliveryCompanyType.instance(deliveryOrderParam.getDeliveryCompanyType());
            if (Objects.isNull(deliveryCompanyType)) {
                throw new LuckException("网点关联快递公司配置为空");
            }
            companyName = deliveryCompanyType.getName();
        }
        return companyName;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeAmount(OrderAdminDTO orderAdminDTO, Order dbOrder) {
        if (!Objects.equals(dbOrder.getShopId(), AuthUserContext.get().getTenantId())) {
            throw new LuckException(ResponseEnum.UNAUTHORIZED);
        }
        if (!Objects.equals(dbOrder.getStatus(), OrderStatus.UNPAY.value())) {
            throw new LuckException("订单状态已发生改变，无法更改订单金额");
        }
        //减少金额
        Long amount = 0L;
        //平台优惠金额
        Long platformAmount = 0L;
        Map<Long, OrderItemDTO> collect = orderAdminDTO.getOrderItems().stream().collect(Collectors.toMap(OrderItemDTO::getOrderItemId, orderItem -> orderItem));
        for (OrderItem orderItemDb : dbOrder.getOrderItems()) {
            orderItemDb.setSupplierId(dbOrder.getSupplierId());
            //判断是否是赠品或者子组合订单项
            if (Objects.equals(orderItemDb.getActivityType(), OrderActivityType.GIVEAWAY.value()) || Objects.equals(orderItemDb.getActivityType(), OrderActivityType.COMBO_PROD.value())) {
                continue;
            }
            OrderItemDTO orderItem = collect.get(orderItemDb.getOrderItemId());
            boolean notChange = Objects.isNull(orderItem.getChangeAmount()) ||
                    Objects.equals(orderItem.getChangeAmount(), orderItemDb.getActualTotal()) ||
                    orderItemDb.getShopChangeFreeAmount() > 0;
            if (notChange) {
                continue;
            }
            if (orderItem.getChangeAmount() < Constant.MIN_ORDER_AMOUNT) {
                throw new LuckException("订单金额必须大于0");
            }
            Long changeAmount;
            // 改变金额大于订单金额-仅修改店铺改价优惠金额
            if (orderItem.getChangeAmount() > orderItemDb.getActualTotal()) {
                changeAmount = orderItem.getChangeAmount() - orderItemDb.getActualTotal();
                orderItemDb.setShopChangeFreeAmount(orderItemDb.getShopChangeFreeAmount() + changeAmount);
                //实际金额 = 原实际金额 - 变化金额
                orderItemDb.setActualTotal(orderItem.getChangeAmount());
                amount = amount + changeAmount;
                continue;
            }
            changeAmount = orderItemDb.getActualTotal() - orderItem.getChangeAmount();
            //修改平台优惠金额
            Long playformItemAmount = 0L;
            // 如果改变后金额小于当前金额，则进行修改平台优惠金额
            if (orderItem.getChangeAmount() < orderItemDb.getActualTotal() && orderItemDb.getPlatformShareReduce() > 0) {
                //金额减少比例 = 减少金额  % 总金额
                double proportion = Arith.div(changeAmount, orderItemDb.getSpuTotalAmount(), 6);
                //平台优惠金额减少金额 = 减少比例 * 原平台优惠金额
                playformItemAmount = Double.valueOf(Arith.round(Arith.mul(proportion, orderItemDb.getPlatformShareReduce()), 0)).longValue();
                //平台优惠金额 = 原平台优惠金额 - 平台优惠金额减少金额
                orderItemDb.setPlatformShareReduce(orderItemDb.getPlatformShareReduce() - playformItemAmount);
            }
            //实际金额 = 原实际金额 - 变化金额
            orderItemDb.setActualTotal(orderItemDb.getActualTotal() - changeAmount);
            //总优惠金额 = 变化金额 + 原总优惠金额
            orderItemDb.setShareReduce(changeAmount + orderItemDb.getShareReduce());
            // 店铺改价金额为订单项减少的金额
            orderItemDb.setShopChangeFreeAmount(orderItemDb.getShopChangeFreeAmount() - changeAmount);
            amount = amount - changeAmount;
            platformAmount = platformAmount + playformItemAmount;
            // 优惠总额
            dbOrder.setReduceAmount(dbOrder.getReduceAmount() + changeAmount);
        }
        // 重新计算佣金
        calculatePlatformCommission(Collections.singletonList(dbOrder), dbOrder.getOrderItems());
        orderItemService.updateBatch(dbOrder.getOrderItems());
        OrderSettlement orderSettlement = orderSettlementService.getByOrderId(dbOrder.getOrderId());
        // 修改订单信息
        dbOrder.setActualTotal(dbOrder.getActualTotal() + amount);
        dbOrder.setPlatformAmount(dbOrder.getPlatformAmount() - platformAmount);
        // 计算运费变化金额
        calculTransFee(orderAdminDTO, dbOrder, amount);
        orderSettlement.setPayAmount(dbOrder.getActualTotal());
        orderSettlementService.update(orderSettlement);
        // 修改运费信息
        orderMapper.update(dbOrder);
    }

    private void calculTransFee(OrderAdminDTO orderAdminDTO, Order dbOrder, Long amount) {
        Long changeFreightAmount;
        Long freightAmount = orderAdminDTO.getFreightAmount() + dbOrder.getPlatformFreeFreightAmount();
        if (!Objects.equals(dbOrder.getFreightAmount(), freightAmount)) {
            ServerResponseEntity<Boolean> serverResponse = userLevelAndScoreOrderFeignClient.getHaveFreeFeeRight(dbOrder.getUserId(), dbOrder.getShopId());
            if (!serverResponse.isSuccess()) {
                throw new LuckException(serverResponse.getMsg());
            }
            if (BooleanUtil.isTrue(serverResponse.getData())) {
                throw new LuckException("平台会员包邮不能修改运费");
            }
            if (orderAdminDTO.getFreightAmount() < 0L) {
                throw new LuckException("运费金额不能小于0");
            }
            changeFreightAmount = freightAmount - dbOrder.getFreightAmount();
            if (Objects.equals(dbOrder.getFreightAmount(), 0L) && dbOrder.getFreeFreightAmount() < 0L) {
                // 商家运费模板包邮，改价的运费由商家承担
                dbOrder.setFreeFreightAmount(-changeFreightAmount);
            } else if (dbOrder.getFreeFreightAmount() < 0L) {
                // 商家有商品运费模板包邮，改价的运费由不包邮商品承担
                dbOrder.setFreightAmount(freightAmount);
                if (changeFreightAmount < 0L) {
                    dbOrder.setFreeFreightAmount(dbOrder.getFreeFreightAmount() + changeFreightAmount);
                }
                dbOrder.setActualTotal(dbOrder.getActualTotal() + changeFreightAmount);
            } else {
                dbOrder.setFreightAmount(freightAmount);
                dbOrder.setActualTotal(dbOrder.getActualTotal() + changeFreightAmount);
            }
        }
        dbOrder.setShopChangeFreeAmount(dbOrder.getShopChangeFreeAmount() + amount);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeAmountByPreSale(OrderAdminDTO orderAdminDTO, Order dbOrder) {
        if (!Objects.equals(dbOrder.getShopId(), AuthUserContext.get().getTenantId())) {
            throw new LuckException(ResponseEnum.UNAUTHORIZED);
        }
        if (!Objects.equals(dbOrder.getStatus(), OrderStatus.UNPAY.value())) {
            throw new LuckException("订单状态已发生改变，无法更改订单金额");
        }
        OrderPreSaleInfoVO orderPreSaleInfoVO = orderPreSaleInfoService.getByOrderId(dbOrder.getOrderId());
        //减少金额
        Long amount = 0L;
        //平台优惠金额
        Long platformAmount = 0L;
        Map<Long, OrderItemDTO> collect = orderAdminDTO.getOrderItems().stream().collect(Collectors.toMap(OrderItemDTO::getOrderItemId, orderItem -> orderItem));
        OrderItem orderItemDb = dbOrder.getOrderItems().get(0);
        // 如果大于1则表示有赠品，筛选一下
        if (dbOrder.getOrderItems().size() > 1) {
            List<OrderItem> mainItemList = dbOrder.getOrderItems().stream().filter(orderItem -> Objects.equals(orderItem.getMainGiveaway(), 1)).toList();
            orderItemDb = mainItemList.get(0);
        }
        orderItemDb.setSupplierId(dbOrder.getSupplierId());
        OrderItemDTO orderItem = collect.get(orderItemDb.getOrderItemId());
        boolean notChange = Objects.isNull(orderItem.getChangeAmount()) ||
                Objects.equals(orderItem.getChangeAmount(), orderPreSaleInfoVO.getBalanceAmount()) ||
                orderItemDb.getShopChangeFreeAmount() > 0;
        if (!notChange) {
            if (orderItem.getChangeAmount() < Constant.MIN_ORDER_AMOUNT && Objects.isNull(orderPreSaleInfoVO)) {
                throw new LuckException("订单金额必须大于0");
            }
            // 改变金额大于尾款金额-仅修改店铺改价优惠金额
            if (orderItem.getChangeAmount() > orderPreSaleInfoVO.getBalanceAmount()) {
                long changeBalanceAmount = orderItem.getChangeAmount() - orderPreSaleInfoVO.getBalanceAmount();
                orderItemDb.setShopChangeFreeAmount(orderItemDb.getShopChangeFreeAmount() + changeBalanceAmount);
                //实际金额 = 原实际金额 - 变化金额
                orderItemDb.setActualTotal(orderItemDb.getActualTotal() + changeBalanceAmount);
                amount = amount + changeBalanceAmount;
            } else {
                long changeBalanceAmount = orderPreSaleInfoVO.getBalanceAmount() - orderItem.getChangeAmount();
                //修改平台优惠金额
                Long playformItemAmount = 0L;
                // 如果改变后金额小于当前金额，则进行修改平台优惠金额
                if (orderItemDb.getPlatformShareReduce() > 0) {
                    //金额减少比例 = 减少金额  % 总金额
                    double proportion = Arith.div(changeBalanceAmount, orderItemDb.getSpuTotalAmount(), 6);
                    //平台优惠金额减少金额 = 减少比例 * 原平台优惠金额
                    playformItemAmount = Double.valueOf(Arith.round(Arith.mul(proportion, orderItemDb.getPlatformShareReduce()), 0)).longValue();
                    //平台优惠金额 = 原平台优惠金额 - 平台优惠金额减少金额
                    orderItemDb.setPlatformShareReduce(orderItemDb.getPlatformShareReduce() - playformItemAmount);
                }
                //实际金额 = 原实际金额 - 变化金额
                orderItemDb.setActualTotal(orderItemDb.getActualTotal() - changeBalanceAmount);
                //总优惠金额 = 变化金额 + 原总优惠金额
                orderItemDb.setShareReduce(changeBalanceAmount + orderItemDb.getShareReduce());
                // 店铺改价金额为订单项减少的金额
                orderItemDb.setShopChangeFreeAmount(orderItemDb.getShopChangeFreeAmount() - changeBalanceAmount);
                amount = amount - changeBalanceAmount;
                platformAmount = platformAmount + playformItemAmount;
                // 优惠总额
                dbOrder.setReduceAmount(dbOrder.getReduceAmount() + changeBalanceAmount);
            }
            // 修改预售信息
            orderPreSaleInfoVO.setBalanceAmount(orderItem.getChangeAmount());
            OrderPreSaleInfo orderPreSaleInfo = BeanUtil.map(orderPreSaleInfoVO, OrderPreSaleInfo.class);
            orderPreSaleInfoService.updateBatch(Collections.singletonList(orderPreSaleInfo));
            //---------for------
            // 重新计算佣金
            calculatePlatformCommission(Collections.singletonList(dbOrder), dbOrder.getOrderItems());
            orderItemService.updateBatch(dbOrder.getOrderItems());
            // 修改订单信息
            dbOrder.setActualTotal(dbOrder.getActualTotal() + amount);
            dbOrder.setPlatformAmount(dbOrder.getPlatformAmount() - platformAmount);
        }
        OrderSettlement orderSettlement = orderSettlementService.getByOrderId(dbOrder.getOrderId());
        // 计算运费变化金额
        calculTransFee(orderAdminDTO, dbOrder, amount);
        orderSettlement.setPayAmount(dbOrder.getActualTotal());
        orderSettlementService.update(orderSettlement);
        // 修改运费信息
        orderMapper.update(dbOrder);
    }

    @Override
    public SubmitOrderPayAmountInfoBO getSubmitOrderPayAmountInfo(long[] orderIdList) {
        if (ArrayUtil.isEmpty(orderIdList)) {
            return null;
        }
        return orderMapper.getSubmitOrderPayAmountInfo(orderIdList);
    }

    @Override
    public EsOrderBO getEsOrder(Long orderId) {
        return orderMapper.getEsOrder(orderId);
    }

    private OrderItem getOrderItem(ShopCartOrderMergerVO mergerOrder, Order order, ShopCartItemVO shopCartItem, Map<Long, List<VirtualRemarkVO>> virtualRemarkMap, ShopCartOrderVO shopCartOrderVO) {
        OrderItem orderItem = new OrderItem();
        orderItem.setOrderId(order.getOrderId());
        orderItem.setShopId(shopCartItem.getShopId());
        orderItem.setSkuId(shopCartItem.getSkuId());
        orderItem.setSpuId(shopCartItem.getSpuId());
        orderItem.setCategoryId(shopCartItem.getCategoryId());
        // TODO 国际化
        orderItem.setOrderItemLangList(getOrderItemLangList(shopCartItem,orderItem));
        // 库存区域id
        orderItem.setStockPointId(Objects.equals(shopCartItem.getMold(),SpuMold.COMBO.value()) ? 0L : shopCartItem.getStockPointId());
        orderItem.setCount(shopCartItem.getCount());
        // 待发货数量
        orderItem.setBeDeliveredNum(shopCartItem.getCount());
        orderItem.setPic(shopCartItem.getImgUrl());
        orderItem.setPrice(shopCartItem.getSkuPriceFee());
        orderItem.setUserId(order.getUserId());
        orderItem.setSpuTotalAmount(shopCartItem.getTotalAmount());
        orderItem.setIsComm(0);
        orderItem.setShopCartTime(shopCartItem.getCreateTime());
        // 分销金额
        orderItem.setDistributionAmount(0L);
        orderItem.setDistributionParentAmount(0L);
        //平台的补贴优惠金额
        orderItem.setPlatformShareReduce(shopCartItem.getPlatformShareReduce());
        // 实际订单项支付金额
        orderItem.setActualTotal(shopCartItem.getActualTotal());
        // 分摊优惠金额
        orderItem.setShareReduce(shopCartItem.getShareReduce());
        //推广员卡号
        orderItem.setDistributionUserId(shopCartItem.getDistributionUserId());
        // 积分价格（单价）
        orderItem.setScoreFee(shopCartItem.getScoreFee());
        //使用积分价格
        orderItem.setUseScore(shopCartItem.getScorePrice() != null ? shopCartItem.getScorePrice() : 0L);
        orderItem.setScoreAmount(shopCartItem.getScoreReduce() != null ? shopCartItem.getScoreReduce() : 0L);
        orderItem.setMemberAmount(shopCartItem.getLevelReduce() != null ? shopCartItem.getLevelReduce() : 0L);

        orderItem.setPlatformCouponAmount(shopCartItem.getPlatformCouponAmount() != null ? shopCartItem.getPlatformCouponAmount() : 0L);
        orderItem.setShopCouponAmount(shopCartItem.getShopCouponAmount() != null ? shopCartItem.getShopCouponAmount() : 0L);
        orderItem.setDiscountAmount(shopCartItem.getDiscountAmount() != null ? shopCartItem.getDiscountAmount() : 0L);
        orderItem.setPlatformFreeFreightAmount(shopCartItem.getPlatformFreeFreightAmount() != null ? shopCartItem.getPlatformFreeFreightAmount() : 0L);
        // 平台佣金
        orderItem.setRate(shopCartItem.getRate() != null ? shopCartItem.getRate() : 0.0);
        orderItem.setPlatformCommission(shopCartItem.getPlatformCommission() != null ? shopCartItem.getPlatformCommission() : 0L);
        orderItem.setSupplierRate(Objects.nonNull(shopCartItem.getSupplierRate()) ? shopCartItem.getSupplierRate() : 0.0);
        orderItem.setPurchasePlatformCommission(Objects.nonNull(shopCartItem.getPurchasePlatformCommission()) ? shopCartItem.getPurchasePlatformCommission() : 0L);

        // 获取积分，确认收货之后才会获取积分
        orderItem.setGainScore(0L);
        // 生成订单之后才会进行订单改价
        orderItem.setShopChangeFreeAmount(0L);
        // 改价之后才会商家免运费，注意：要是改变了规则，这里也要改
        orderItem.setFreeFreightAmount(0L);
        orderItem.setSpuMold(shopCartItem.getMold());
        // 如果是虚拟商品，则修改为无需快递的发货方式
        handleVirtual(shopCartItem, virtualRemarkMap, shopCartOrderVO, orderItem);
        // 供应商相关信息保存
        orderItem.setItemPurchaseAmount(shopCartItem.getTotalPurchaseAmount() != null ? shopCartItem.getTotalPurchaseAmount() : 0L);
        orderItem.setSupplierId(shopCartItem.getSupplierId());
        orderItem.setSpuCode(shopCartItem.getSpuCode());
        orderItem.setPartyCode(shopCartItem.getPartyCode());
        orderItem.setSupplierSkuId(shopCartItem.getSupplierSkuId());
        orderItem.setSupplierSpuId(shopCartItem.getSupplierSpuId());
        orderItem.setComboAmount(shopCartItem.getComboAmount());
        orderItem.setGiveawayAmount(0L);
        //供应商订单字段数据
        if (Objects.nonNull(orderItem.getSupplierSpuId())) {
            orderItem.setSupplierPic(shopCartItem.getSupplierUrl());
        }

        setActivityInfo(mergerOrder, shopCartItem, orderItem);
        return orderItem;
    }

    private static void setActivityInfo(ShopCartOrderMergerVO mergerOrder, ShopCartItemVO shopCartItem, OrderItem orderItem) {
        if (Objects.nonNull(shopCartItem.getComboId())) {
            orderItem.setActivityId(shopCartItem.getComboId());
            orderItem.setActivityType(OrderActivityType.COMBO.value());
        }

        if (Objects.equals(mergerOrder.getActivityType(), OrderActivityType.GROUP.value()) ||
                Objects.equals(mergerOrder.getActivityType(), OrderActivityType.SECKILL.value())) {
            orderItem.setActivityId(mergerOrder.getActivityId());
            orderItem.setActivityType(mergerOrder.getActivityType());
        }
    }

    private void handleVirtual(ShopCartItemVO shopCartItem, Map<Long, List<VirtualRemarkVO>> virtualRemarkMap, ShopCartOrderVO shopCartOrderVO, OrderItem orderItem) {
        if (Objects.equals(shopCartItem.getMold(), 1)) {
            // 存入留言
            String virtualRemarkStr = Json.toJsonString(virtualRemarkMap.get(shopCartItem.getSpuId()));
            orderItem.setVirtualRemark(virtualRemarkStr);
            orderItem.setSpuMold(SpuMold.VIRTUAL.value());
            orderItem.setIsRefund(shopCartItem.getIsRefund());
            orderItem.setDeliveryType(DeliveryType.NOT_DELIVERY.value());
            SpuVO spuVO = spuFeignClient.getDetailById(shopCartItem.getSpuId()).getData();
            if (Objects.nonNull(spuVO)) {
                shopCartOrderVO.setWriteOffNum(spuVO.getWriteOffNum());
                shopCartOrderVO.setIsRefund(spuVO.getIsRefund());
                orderItem.setWriteOffNum(spuVO.getWriteOffNum());
                // 如果是虚拟商品且需要核销，放进去
                if (!Objects.equals(spuVO.getWriteOffNum(), 0) && !Objects.equals(spuVO.getWriteOffNum(), null)) {
                    Date startTime = new Date();
                    Date endTime;
                    // 判断有效期
                    switch (spuVO.getWriteOffTime()) {
                        case -1:
                            endTime = null;
                            break;
                        case 0:
                            startTime = spuVO.getWriteOffStart();
                            endTime = spuVO.getWriteOffEnd();
                            break;
                        case 1:
                            endTime = DateUtil.endOfDay(startTime);
                            break;
                        default:
                            endTime = DateUtil.offsetDay(startTime, spuVO.getWriteOffTime());
                            break;
                    }
                    shopCartOrderVO.setWriteOffStart(startTime);
                    shopCartOrderVO.setWriteOffEnd(endTime);
                    if (Objects.equals(spuVO.getWriteOffNum(), -1)) {
                        shopCartOrderVO.setWriteOffMultipleCount(spuVO.getWriteOffMultipleCount());
                        orderItem.setWriteOffMultipleCount(spuVO.getWriteOffMultipleCount());
                    }
                    orderItem.setWriteOffStart(startTime);
                    orderItem.setWriteOffEnd(endTime);
                }
            }
        }
    }

    private List<OrderItem> giveawayOrderItems(Order order, ShopCartItemVO shopCartItem) {
        int allCount = order.getAllCount();
        if (CollUtil.isEmpty(shopCartItem.getGiveawayShopCartItemList())) {
            return Collections.emptyList();
        }
        List<OrderItem> orderItemList = new ArrayList<>(shopCartItem.getGiveawayShopCartItemList().size());
        for (ShopCartItemVO shopCartItemVO : shopCartItem.getGiveawayShopCartItemList()) {
            OrderItem orderItem = BeanUtil.map(shopCartItemVO, OrderItem.class);
            orderItem.setOrderItemId(segmentManager.getSegmentIdWithDateTime(DistributedIdKey.tmerclub_ORDER_ITEM, order.getUserId()));
            orderItem.setShopId(order.getShopId());
            orderItem.setOrderItemLangList(getOrderItemLangList(shopCartItemVO, orderItem));
            orderItem.setOrderId(order.getOrderId());
            orderItem.setPic(shopCartItemVO.getImgUrl());
            orderItem.setSpuMold(shopCartItemVO.getMold());
            // 保存中英文名称
            orderItem.setCount(orderItem.getCount());
            //代发货数量
            orderItem.setBeDeliveredNum(orderItem.getCount());
            orderItem.setPrice(shopCartItemVO.getSkuPriceFee());
            orderItem.setSpuTotalAmount(shopCartItemVO.getTotalAmount());
            orderItem.setIsComm(0);
            setAmount(shopCartItem, orderItem);

            orderItem.setGiveawayAmount((long) Arith.mul(shopCartItemVO.getGiveawayRefundPrice(), shopCartItemVO.getCount()));
            orderItem.setMainGiveaway(0);
            orderItem.setActivityId(shopCartItem.getOrderItemId());
            // 库存区域id
            orderItem.setStockPointId(shopCartItem.getStockPointId());
            orderItem.setActivityType(OrderActivityType.GIVEAWAY.value());
            orderItemList.add(orderItem);
            allCount += shopCartItemVO.getCount();
        }
        order.setAllCount(allCount);

        return orderItemList;
    }

    private static void setAmount(ShopCartItemVO shopCartItem, OrderItem orderItem) {
        //平台的补贴优惠金额
        orderItem.setPlatformShareReduce(Constant.ZERO_LONG);
        // 实际订单项支付金额
        orderItem.setActualTotal(Constant.ZERO_LONG);
        // 分摊优惠金额
        orderItem.setShareReduce(Constant.ZERO_LONG);
        orderItem.setMemberAmount(Constant.ZERO_LONG);
        orderItem.setScoreAmount(Constant.ZERO_LONG);
        orderItem.setDistributionAmount(Constant.ZERO_LONG);
        orderItem.setDistributionParentAmount(Constant.ZERO_LONG);
        orderItem.setPlatformCouponAmount(Constant.ZERO_LONG);
        orderItem.setShopCouponAmount(Constant.ZERO_LONG);
        orderItem.setDiscountAmount(Constant.ZERO_LONG);
        orderItem.setPlatformFreeFreightAmount(Constant.ZERO_LONG);
        // 平台佣金
        orderItem.setRate(shopCartItem.getRate() != null ? shopCartItem.getRate() : 0.0);
        orderItem.setPlatformCommission(Constant.ZERO_LONG);
        orderItem.setSupplierRate(Objects.nonNull(shopCartItem.getSupplierRate()) ? shopCartItem.getSupplierRate() : 0.0);
        orderItem.setPurchasePlatformCommission(Constant.ZERO_LONG);
        //使用积分价格
        orderItem.setUseScore(Constant.ZERO_LONG);
        // 改价之后才会商家免运费，注意：要是改变了规则，这里也要改
        orderItem.setFreeFreightAmount(Constant.ZERO_LONG);
        // 获取积分，确认收货之后才会获取积分
        orderItem.setGainScore(Constant.ZERO_LONG);
        // 生成订单之后才会进行订单改价
        orderItem.setShopChangeFreeAmount(Constant.ZERO_LONG);
        // 供应商相关信息保存
        orderItem.setItemPurchaseAmount(Constant.ZERO_LONG);
    }



    private OrderPreSaleInfo getOrderPresaleInfo(Order order, ShopCartItemVO shopCartItem) {
        OrderPreSaleInfo orderPreSaleInfo = new OrderPreSaleInfo();
        orderPreSaleInfo.setOrderId(order.getOrderId());
        orderPreSaleInfo.setPreSaleType(shopCartItem.getPreSaleType());
        // 如果是定金预售，保存下定金信息，否则只保存发货信息
        if (Objects.equals(shopCartItem.getPreSaleType(), PreSaleType.DEPOSIT.value())) {
            orderPreSaleInfo.setDepositAmount(shopCartItem.getActualDepositAmount());
            orderPreSaleInfo.setDepositExpansionAmount(shopCartItem.getDepositExpansionAmount());
            orderPreSaleInfo.setDepositReduceAmount(shopCartItem.getDepositReduceAmount());
            orderPreSaleInfo.setBalanceAmount(shopCartItem.getActualBalanceAmount());
            orderPreSaleInfo.setBalanceStartTime(shopCartItem.getBalanceStartTime());
            orderPreSaleInfo.setBalanceEndTime(shopCartItem.getBalanceEndTime());
            orderPreSaleInfo.setUserId(order.getUserId());
        }
        orderPreSaleInfo.setPreSaleDeliveryTime(shopCartItem.getPreSaleDeliveryTime());
        orderPreSaleInfo.setPreSaleDeliveryType(shopCartItem.getPreSaleDeliveryType());
        // 供应商相关信息保存
        return orderPreSaleInfo;
    }

    /**
     * 获取订单项的国际化信息
     *
     * @param shopCartItem 购物车项
     * @param orderItem
     * @return 订单项的国际化信息列表
     */
    private List<OrderItemLang> getOrderItemLangList(ShopCartItemVO shopCartItem, OrderItem orderItem) {
        List<OrderItemLang> orderItemLangList = new ArrayList<>(2);
        Map<Integer, String> spuNameMap = shopCartItem.getSpuLangList().stream()
                .filter(orderSpuLangVO -> CharSequenceUtil.isNotBlank(orderSpuLangVO.getSpuName()))
                .collect(Collectors.toMap(OrderSpuLangVO::getLang, OrderSpuLangVO::getSpuName));
        Map<Integer, String> skuNameMap = new HashMap<>(Constant.INITIAL_CAPACITY);
        Map<Integer, String> comboSkuNameMap = new HashMap<>(Constant.INITIAL_CAPACITY);
        if(CollectionUtil.isNotEmpty(shopCartItem.getSkuLangList())) {
            skuNameMap = shopCartItem.getSkuLangList().stream()
                    .filter(orderSkuLangVO -> CharSequenceUtil.isNotBlank(orderSkuLangVO.getSkuName()))
                    .collect(Collectors.toMap(OrderSkuLangVO::getLang, OrderSkuLangVO::getSkuName));
            comboSkuNameMap = shopCartItem.getSkuLangList().stream()
                    .filter(orderSkuLangVO -> CharSequenceUtil.isNotBlank(orderSkuLangVO.getComboSkuName()))
                    .collect(Collectors.toMap(OrderSkuLangVO::getLang, OrderSkuLangVO::getComboSkuName));
        }
        Map<Integer, String> supplierspuNameMap = null == shopCartItem.getSupplierSpuLangList() ?
                new HashMap<>(2) : shopCartItem.getSupplierSpuLangList().stream()
                .filter(orderSpuLangVO -> CharSequenceUtil.isNotBlank(orderSpuLangVO.getSpuName()))
                .collect(Collectors.toMap(OrderSpuLangVO::getLang, OrderSpuLangVO::getSpuName));
        Map<Integer, String> supplierskuNameMap = null == shopCartItem.getSupplierSkuLangList() ?
                new HashMap<>(2) : shopCartItem.getSupplierSkuLangList().stream()
                .filter(orderSkuLangVO -> CharSequenceUtil.isNotBlank(orderSkuLangVO.getSkuName()))
                .collect(Collectors.toMap(OrderSkuLangVO::getLang, OrderSkuLangVO::getSkuName));
//        for (LanguageEnum value : LanguageEnum.values()) {
        Integer lang = LanguageEnum.LANGUAGE_ZH_CN.getLang();
//        if (!spuNameMap.containsKey(lang) && !skuNameMap.containsKey(lang)) {
//            continue;
//        }
        OrderItemLang orderItemLang = new OrderItemLang();
        orderItemLang.setLang(lang);
        orderItemLang.setSkuName(LangUtil.getLangValue(skuNameMap, lang));
        orderItemLang.setSpuName(LangUtil.getLangValue(spuNameMap, lang));
//        orderItemLang.setComboSpuName(LangUtil.getLangValue(comboSpuNameMap, lang));
//        orderItemLang.setComboSkuName(LangUtil.getLangValue(comboSkuNameMap, lang));
        orderItem.setSpuName(orderItemLang.getSpuName());
        orderItem.setSkuName(orderItemLang.getSkuName());
        orderItemLangList.add(orderItemLang);
        if (supplierspuNameMap.containsKey(lang) || supplierskuNameMap.containsKey(lang)) {
            log.info("判断是否有供应商国际化信息");
            orderItemLang.setSupplierSpuName(LangUtil.getLangValue(supplierspuNameMap, lang));
            orderItemLang.setSupplierSkuName(LangUtil.getLangValue(supplierskuNameMap, lang));
        }
//        }
        return orderItemLangList;
    }

    private Order getOrder(Long userId, Integer dvyType, Integer spuMold, ShopCartOrderVO shopCartOrderVO) {
        if (Objects.nonNull(shopCartOrderVO.getHasComboOrder()) && shopCartOrderVO.getHasComboOrder()) {
            spuMold = shopCartOrderVO.getSpuMold();
        }else {
            spuMold = Objects.isNull(shopCartOrderVO.getSpuMold()) ? spuMold : shopCartOrderVO.getSpuMold();
        }
        dvyType = Objects.equals(spuMold, 1) ? DeliveryType.NOT_DELIVERY.value() : dvyType;
        // 订单信息
        Order order = new Order();
        order.setOrderId(shopCartOrderVO.getOrderId());

        order.setShopId(shopCartOrderVO.getShopId());
        order.setShopName(shopCartOrderVO.getShopName());
        // 用户id
        order.setUserId(userId);
        // 商品总额
        order.setTotal(shopCartOrderVO.getTotal());
        // 实际总额
        order.setActualTotal(shopCartOrderVO.getActualTotal());
        order.setStatus(OrderStatus.UNPAY.value());
        order.setIsPayed(0);
        order.setDeleteStatus(0);
        order.setAllCount(shopCartOrderVO.getTotalCount());
        order.setReduceAmount(shopCartOrderVO.getShopReduce());
        order.setFreightAmount(shopCartOrderVO.getTransfee());
        order.setRemarks(shopCartOrderVO.getRemarks());
        order.setDeliveryType(dvyType);
        order.setOrderScore(shopCartOrderVO.getUseScore());
        order.setOrderType(shopCartOrderVO.getOrderType() != null ? shopCartOrderVO.getOrderType() : OrderType.ORDINARY.value());
        order.setPlatformAmount(shopCartOrderVO.getPlatformAmount() != null ? shopCartOrderVO.getPlatformAmount() : 0L);
        order.setScoreAmount(shopCartOrderVO.getScoreReduce() != null ? shopCartOrderVO.getScoreReduce() : 0L);
        order.setMemberAmount(shopCartOrderVO.getLevelReduce() != null ? shopCartOrderVO.getLevelReduce() : 0L);
        order.setPlatformCouponAmount(shopCartOrderVO.getPlatformCouponReduce() != null ? shopCartOrderVO.getPlatformCouponReduce() : 0L);
        order.setShopCouponAmount(shopCartOrderVO.getCouponReduce() != null ? shopCartOrderVO.getCouponReduce() : 0L);
        order.setDiscountAmount(shopCartOrderVO.getDiscountReduce() != null ? shopCartOrderVO.getDiscountReduce() : 0L);
        order.setPlatformAmount(shopCartOrderVO.getPlatformAmount() != null ? shopCartOrderVO.getPlatformAmount() : 0L);
        order.setReduceAmount(shopCartOrderVO.getShopReduce() != null ? shopCartOrderVO.getShopReduce() : 0L);
        order.setFreeFreightAmount(shopCartOrderVO.getFreeTransfee() != null ? shopCartOrderVO.getFreeTransfee() : 0L);
        order.setPlatformFreeFreightAmount(shopCartOrderVO.getLevelFreeTransfee() != null ? shopCartOrderVO.getLevelFreeTransfee() : 0L);
        order.setPlatformCommission(shopCartOrderVO.getPlatformCommission() != null ? shopCartOrderVO.getPlatformCommission() : 0L);
        order.setDistributionAmount(0L);
        order.setShopChangeFreeAmount(0L);
        order.setIsSettled(0);
        order.setSupplierId(0L);
        order.setSupplierDeliveryType(0);
        order.setWaitPurchase(0);
        order.setPurchaseSpreadAmount(0L);
        order.setPreSaleType(shopCartOrderVO.getPreSaleType());
        order.setOrderMold(spuMold);
        order.setShopComboAmount(calculateShopComboAmount(shopCartOrderVO));
        if (Objects.isNull(shopCartOrderVO.getMainOrderId())) {
            shopCartOrderVO.setMainOrderId(Constant.ZERO_LONG);
        }
        order.setMainOrderId(shopCartOrderVO.getMainOrderId());
        // 供应商相关
        // 判断下是否为供应商商品,如果是商家代销供应商商品且为供应商发货设置供应商信息
        if (Objects.nonNull(shopCartOrderVO.getSupplierId()) && !Objects.equals(shopCartOrderVO.getSupplierId(), 0L)) {
            order.setSupplierId(shopCartOrderVO.getSupplierId());
            if (Objects.equals(shopCartOrderVO.getSupplierDeliveryType(), SupplierDeliveryType.SUPPLIER_DELIVERY.value())) {
                order.setSupplierDeliveryType(SupplierDeliveryType.SUPPLIER_DELIVERY.value());
            } else {
                order.setSupplierDeliveryType(SupplierDeliveryType.SHOP_DELIVERY.value());
            }
        }

        return order;
    }

    /**
     * 计算订单套餐商品优惠金额
     *
     * @param shopCartOrderVO
     * @return
     */
    private Long calculateShopComboAmount(ShopCartOrderVO shopCartOrderVO) {
        List<ShopCartItemDiscountVO> shopCartItemDiscounts = shopCartOrderVO.getShopCartItemDiscounts();
        Long shopComboAmount = 0L;
        for (ShopCartItemDiscountVO shopCartItemDiscount : shopCartItemDiscounts) {
            List<ShopCartItemVO> shopCartItems = shopCartItemDiscount.getShopCartItems();
            for (ShopCartItemVO shopCartItem : shopCartItems) {
                if (Objects.nonNull(shopCartItem.getComboId()) && shopCartItem.getComboId() > 0) {
                    shopComboAmount += shopCartItem.getComboAmount();
                }
            }
        }
        return shopComboAmount;
    }

    @Override
    public Long sumTotalDistributionAmountByOrderItem(List<OrderItem> orderItems) {
        // 订单总分销金额
        long totalDistributionAmount = 0L;
        if (CollectionUtil.isNotEmpty(orderItems)) {
            for (OrderItem orderItem : orderItems) {
                if (Objects.isNull(orderItem.getDistributionUserId())) {
                    continue;
                }
                // 如果改订单项已经退款了的话，分销员的佣金就已经回退了，不需要继续算钱
                if (Objects.equals(orderItem.getRefundStatus(), RefundStatusEnum.SUCCEED.value())) {
                    continue;
                }
                // 分销佣金
                if (orderItem.getDistributionAmount() != null && orderItem.getDistributionAmount() > 0) {
                    totalDistributionAmount = totalDistributionAmount + orderItem.getDistributionAmount();
                }
                // 上级分销佣金
                if (orderItem.getDistributionParentAmount() != null && orderItem.getDistributionParentAmount() > 0) {
                    totalDistributionAmount = totalDistributionAmount + orderItem.getDistributionParentAmount();
                }
            }
        }
        return totalDistributionAmount;
    }

    @Override
    public Order getOrderAndOrderItemData(Long orderId, Long shopId) {
        Order order = orderMapper.getOrderAndOrderItemData(orderId, shopId);
        orderLangHandle(order);
        return order;
    }

    @Override
    public OrderCountVO countNumberOfStatus(Long userId) {
        OrderCountVO orderCountVO = orderMapper.countNumberOfStatus(userId);
        // 补充退款订单数据
        OrderRefundDTO orderRefundDTO = new OrderRefundDTO();
        orderRefundDTO.setUserId(userId);
        orderRefundDTO.setNotInStatuses(Arrays.asList(ReturnProcessStatusEnum.SUCCESS.value(), ReturnProcessStatusEnum.FAIL.value()));
        Long refundCount = mongoOrderRefundManager.countRefundOrder(orderRefundDTO);
        orderCountVO.setRefund(refundCount.intValue());
        return orderCountVO;
    }


    @Override
    public EsPageVO<EsOrderVO> myOrderPage(OrderSearchDTO orderSearchDTO) {
        EsPageVO<EsOrderVO> page = new EsPageVO<>();
        int pageSize = orderSearchDTO.getPageSize();
        int begin = 0;
        int size = orderSearchDTO.getPageSize();
        int redisOrderTotal = 0;
        List<EsOrderVO> orderList = new ArrayList<>();
        boolean getRedisOrder = Objects.isNull(orderSearchDTO.getStatus())
                || Objects.equals(orderSearchDTO.getStatus(), OrderStatus.UNPAY.value())
                || Objects.equals(orderSearchDTO.getStatus(), OrderStatus.PAYED.value());
        if(getRedisOrder) {
            // 获取redis是否存在订单，并返回符合条件的redis订单总数
            redisOrderTotal = getRedisOrderAndTotal(orderSearchDTO, redisOrderTotal, orderList);
        }
        // 计算一下当前页，数据库的订单还需要补充多少条数据
        // 比如redis中有5条数据，数据库 30条，总计35条，一页 10条
        PageAdapter pageAdapter = new PageAdapter(orderSearchDTO.getPageNum(), orderSearchDTO.getPageSize());
        // 如果redis有值，判断一下
        // 比如redis有23条，一页10条
        // 如果是第一页，redis这一页有10条，redisTotal > begin + size ,则数据库的size只需要拿0条
        // 如果是第二页，redisTotal > begin + size ,则数据库的size只需要拿0条
        // 如果是第三页，begin < redisTotal < begin + size ,20 < 23 < 20 + 10,则数据库的begin = 0, size只需要拿begin + size - redisTotal = 7条
        // 如果是第四页，redisTotal < begin,20 < 30,则数据库的begin = begin - redisTotal = 30 - 23 = 7, size = 10条
        if(redisOrderTotal > pageAdapter.getBegin() && redisOrderTotal < pageAdapter.getBegin() + pageAdapter.getSize()){
            size = pageAdapter.getBegin() + pageAdapter.getSize() - redisOrderTotal;
        }else if(redisOrderTotal <= pageAdapter.getBegin()){
            begin = pageAdapter.getBegin() - redisOrderTotal;
        }
        pageAdapter.setSize(size);
        // begin最小从0开始，如果是负数，begin = 0
        pageAdapter.setBegin(begin);
        orderSearchDTO.setBegin(begin);
        orderSearchDTO.setPageSize(size);
        if (StrUtil.isNotBlank(orderSearchDTO.getSpuName())) {
            EsPageVO<EsOrderVO> esOrderVOEsPageVO = orderPage(orderSearchDTO);
            orderList.addAll(esOrderVOEsPageVO.getList());
            page.setTotal(esOrderVOEsPageVO.getTotal() + redisOrderTotal);
            page.setPages(PageUtil.getPages(page.getTotal(), pageSize));
            page.setList(orderList);
            return page;
        }

        Long orderTotal = orderMapper.countPageOrderIds(orderSearchDTO);

        page.setTotal(orderTotal + redisOrderTotal);
        page.setPages(PageUtil.getPages(page.getTotal(), pageSize));
        // 如果缓存中的订单已经超过当前页的总数，直接return
        if(CollectionUtil.isNotEmpty(orderList) && orderList.size() >= pageSize){
            page.setList(orderList);
            return page;
        }
        List<Long> orderIds = orderMapper.pageOrderIds(orderSearchDTO,pageAdapter);
        if (CollUtil.isNotEmpty(orderIds)) {
            List<EsOrderVO> orderListDb = orderMapper.userOrderList(orderIds, I18nMessage.getLang());
            OrderLangUtil.esOrderLang(orderListDb);
            orderList.addAll(orderListDb);
            page.setList(orderList);
        } else {
            page.setList(orderList);
        }
        // 判断一下，如果redisTotal的行数小于10条，则和数据库/es查询出来的一起排序
        // 如果redisTotal的行数大于10条，则不需要排序,默认redis的订单排在前面
        if(redisOrderTotal < pageSize){
            orderList.sort(Comparator.comparing(EsOrderVO::getCreateTime).reversed());
        }
        return page;
    }

    private int getRedisOrderAndTotal(OrderSearchDTO orderSearchDTO, int redisOrderTotal, List<EsOrderVO> orderList) {
        // 获取当前用户缓存中的秒杀订单
        ServerResponseEntity<Map<Object, Object>> mapServerResponseEntity = seckillFeignClient.mapSeckillOrderByUserIdAndRedis(orderSearchDTO.getUserId());
        if (!mapServerResponseEntity.isSuccess()) {
            throw new LuckException(mapServerResponseEntity.getMsg());
        }
        Map<Object, Object> entries = mapServerResponseEntity.getData();
        if(CollectionUtil.isEmpty(entries)){
            return 0;
        }
        // 分页查询
        Integer pageSize = orderSearchDTO.getPageSize();
        List<Long> orderIds = new ArrayList<>();
        // 因为要分页，所以需要排序，而且由于这里是单个用户的redis订单列表,直接按照时间排序就好
        for (Object orderIdKey : entries.keySet()) {
            String orderKey = orderIdKey.toString();
            if(orderKey.startsWith(SeckillOrderCacheConstant.STATUS)) {
                continue;
            }
            String orderIdStr = orderKey.replace(SeckillOrderCacheConstant.ORDER_INFO,"");
            orderIds.add(Long.valueOf(orderIdStr));
        }
        // 获取当前页数
        PageAdapter pageAdapter = new PageAdapter(orderSearchDTO.getPageNum(), orderSearchDTO.getPageSize());
        // 第二页起始就是，（2-1） * 10 = 10
        // 10 + 10 < 15 ? 20 : 15
        int begin = pageAdapter.getBegin();
        orderIds = orderIds.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
        // 目前map有存订单和订单状态信息，需要拆分一下
        for (Long orderId : orderIds) {
            // 获取订单信息转成order
            Object orderInfoObj = entries.get(SeckillOrderCacheConstant.ORDER_INFO + orderId);
            ShopCartOrderMergerVO shopCartOrderMergerVO = JSONObject.parseObject((String) orderInfoObj, ShopCartOrderMergerVO.class);
            Order order = getOrderInfoByShopCartOrderMerger(shopCartOrderMergerVO);

            // 获取订单状态
            Object statusObj = entries.get(SeckillOrderCacheConstant.STATUS + order.getOrderId());
            order.setStatus(Integer.valueOf(statusObj.toString()));
            if(Objects.nonNull(orderSearchDTO.getStatus()) && !Objects.equals(orderSearchDTO.getStatus(),order.getStatus())){
                continue;
            }
            EsOrderVO esOrderVO = BeanUtil.map(order, EsOrderVO.class);
            // 在用户商品名称搜索时，由于缓存存的是秒杀订单，所以只有一个订单项，直接模糊搜索
            OrderLangUtil.esOrderList(esOrderVO.getOrderItems());
            EsOrderItemVO esOrderItemVO = esOrderVO.getOrderItems().get(0);
            esOrderVO.setOrderItems(BeanUtil.mapAsList(order.getOrderItems(), EsOrderItemVO.class));
            // 处理一下预售
            if(Objects.nonNull(esOrderVO.getPreSaleType())){
                ShopCartItemVO shopCartItem = shopCartOrderMergerVO.getShopCartOrders().get(0).getShopCartItemDiscounts().get(0).getShopCartItems().get(0);
                esOrderVO.setPreSaleDeliveryTime(shopCartItem.getPreSaleDeliveryTime());
                esOrderVO.setPreSaleDeliveryType(shopCartItem.getPreSaleDeliveryType());
            }
            boolean orderIdCheck = Objects.isNull(orderSearchDTO.getOrderId()) || Objects.equals(esOrderVO.getOrderId(),orderSearchDTO.getOrderId());
            boolean nameCheck = StrUtil.isBlank(orderSearchDTO.getSpuName()) || esOrderItemVO.getSpuName().contains(orderSearchDTO.getSpuName());
            if(orderIdCheck && nameCheck) {
                // redis符合条件的条数
                redisOrderTotal++;
                // 判断一下,每次进来起始数都减去1，如果小于0就可以放入了
                begin--;
                if(begin >= 0){
                    continue;
                }
                if(pageSize > 0) {
                    orderList.add(esOrderVO);
                }
                // 开始一页数据扣减
                pageSize--;
            }
        }
        return redisOrderTotal;
    }


    @Override
    public EsPageVO<EsOrderVO> orderPage(OrderSearchDTO orderSearchDTO) {

        // 处理下payType
        List<Integer> payTypeList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        if (Objects.equals(orderSearchDTO.getPayType(), SearchPayType.WECHATPAY.value())) {
            payTypeList.addAll(Arrays.asList(PayType.WE_CHAT_PAY_ARRAY));
        } else if (Objects.equals(orderSearchDTO.getPayType(), SearchPayType.ALIPAY.value())) {
            payTypeList.addAll(Arrays.asList(PayType.ALI_PAY_ARRAY));
        } else if (Objects.equals(orderSearchDTO.getPayType(), SearchPayType.BALANCE.value())) {
            payTypeList.add(PayType.BALANCE.value());
        } else if (Objects.equals(orderSearchDTO.getPayType(), SearchPayType.SCOREPAY.value())) {
            payTypeList.add(PayType.SCOREPAY.value());
        }
        orderSearchDTO.setPayTypeList(payTypeList);
        ServerResponseEntity<EsPageVO<EsOrderVO>> orderResponse = searchOrderFeignClient.pageOrder(orderSearchDTO);
        return orderResponse.getData();
    }

    @Override
    public int countByOrderId(Long orderId) {
        return orderMapper.countByOrderId(orderId);
    }


    @Override
    public EsPageVO<EsOrderVO> pageByUserId(PageDTO pageDTO, String userId) {
        OrderSearchDTO orderSearchDTO = new OrderSearchDTO();
        orderSearchDTO.setUserId(Long.valueOf(userId));
        orderSearchDTO.setPageNum(pageDTO.getPageNum());
        orderSearchDTO.setPageSize(pageDTO.getPageSize());
        orderSearchDTO.setShopId(AuthUserContext.get().getTenantId());
        ServerResponseEntity<EsPageVO<EsOrderVO>> orderResponseEntity = searchOrderFeignClient.pageOrder(orderSearchDTO);
        if (!orderResponseEntity.isSuccess()) {
            log.info("查询订单列表失败，失败原因：{}", orderResponseEntity.getMsg());
            throw new LuckException(orderResponseEntity.getMsg());
        }
        return orderResponseEntity.getData();
    }


    @Override
    public int settledOrder(List<Long> orderIds) {
        return orderMapper.settledOrder(orderIds);
    }

    @Override
    public EsOrderBO getEsOrderInfo(Long orderId) {
        EsOrderBO order = orderMapper.getEsOrderInfo(orderId);
        if (Objects.isNull(order)) {
            return null;
        }
        this.loadMongoOrderBo(order);
        EsOrderBO esOrderBO = BeanUtil.map(order, EsOrderBO.class);
        if (Objects.nonNull(order.getAddr())) {
            esOrderBO.setReceivingAddr(order.getProvince() + order.getCity() + order.getArea() + order.getAddr());
        }
        return esOrderBO;
    }

    private void loadMongoOrderBo(EsOrderBO orderBO) {
        // 拼接字符串
        StringBuilder spuCodes = new StringBuilder(500);
        StringBuilder partyCodes = new StringBuilder(500);
        List<Long> spuIds = new ArrayList<>(10);
        for (EsOrderItemBO orderItem : orderBO.getOrderItems()) {
            spuIds.add(orderItem.getSpuId());
            for (OrderItemLangVO orderItemLang : orderItem.getOrderItemLangList()) {
                if (Objects.equals(orderItemLang.getLang(), LanguageEnum.LANGUAGE_ZH_CN.getLang())) {
                    orderItem.setSpuNameZh(orderItemLang.getSpuName());
                    orderItem.setSkuNameZh(orderItemLang.getSkuName());
                    orderItem.setSupplierSpuNameZh(orderItemLang.getSupplierSpuName());
                    orderItem.setSupplierSkuNameZh(orderItemLang.getSupplierSkuName());
                } else if (Objects.equals(orderItemLang.getLang(), LanguageEnum.LANGUAGE_EN.getLang())) {
                    orderItem.setSpuNameEn(orderItemLang.getSpuName());
                    orderItem.setSkuNameEn(orderItemLang.getSkuName());
                    orderItem.setSupplierSpuNameEn(orderItemLang.getSupplierSpuName());
                    orderItem.setSupplierSkuNameEn(orderItemLang.getSupplierSkuName());
                }
            }
            orderItem.setOrderItemLangList(null);
            if (StrUtil.isNotBlank(orderItem.getSpuCode())) {
                spuCodes.append(orderItem.getSpuCode()).append(StrUtil.COMMA);
            }
            if (StrUtil.isNotBlank(orderItem.getPartyCode())) {
                partyCodes.append(orderItem.getPartyCode()).append(StrUtil.COMMA);
            }
        }
        this.setPrimaryCategoryId(orderBO, spuIds);
        // 判断是否为新成交用户
        MongoOrderBO firstOrderData = orderMapper.getUserFirstUserOrder(orderBO.getUserId(), orderBO.getSupplierId(), orderBO.getOrderId());
        orderBO.setFirstOrder(firstOrderData.getFirstOrder());
        orderBO.setFirstSupplierOrder(firstOrderData.getFirstSupplierOrder());

        // 插入会员类型
        UserApiVO user = userLevelLogFeignClient.getUserTypeAndUserNameAtTime(new UserTypeDTO(orderBO.getUserId(), orderBO.getCreateTime()));
        orderBO.setUserType(user.getLevelType());
        if (spuCodes.length() > 1 && spuCodes.lastIndexOf(StrUtil.COMMA) == spuCodes.length() - 1) {
            spuCodes.deleteCharAt(spuCodes.length() - 1);
        }

        if (partyCodes.length() > 1 && partyCodes.lastIndexOf(StrUtil.COMMA) == partyCodes.length() - 1) {
            partyCodes.deleteCharAt(partyCodes.length() - 1);
        }
        orderBO.setSpuCodes(spuCodes.toString());
        orderBO.setPartyCodes(partyCodes.toString());
        // 如果是自提订单，查询自提点信息
        if (Objects.equals(orderBO.getDeliveryType(), DeliveryType.STATION.value())) {
            OrderSelfStationVO orderSelfStationVO = orderSelfStationService.getStationByOrderId(null, orderBO.getOrderId());
            orderBO.setConsignee(orderSelfStationVO.getStationUserName());
            orderBO.setMobile(orderSelfStationVO.getStationUserMobile());
            orderBO.setAddr(null);
        }
        // 虚拟订单的收货人姓名就是用于昵称，用于收货人姓名的筛选
        if (Objects.equals(orderBO.getOrderMold(), 1)) {
            orderBO.setConsignee(user.getNickName());
        }
    }

    private void setPrimaryCategoryId(EsOrderBO orderBO, List<Long> spuIds) {
        ProductSearchDTO productSearchDTO = new ProductSearchDTO();
        productSearchDTO.setPageSize(PageDTO.MAX_PAGE_SIZE);
        productSearchDTO.setPageNum(PageDTO.DEFAULT_PAGE_NUM);
        productSearchDTO.setSpuIds(spuIds);
        ServerResponseEntity<EsPageVO<SpuAdminVO>> searchResponse = searchSpuFeignClient.adminPage(productSearchDTO);
        if (!searchResponse.isSuccess()) {
            throw new LuckException(searchResponse.getMsg());
        }
        List<SpuAdminVO> spuList = searchResponse.getData().getList();
        if (CollUtil.isNotEmpty(spuList)) {
            Map<Long, Long> categoryMap = spuList.stream().collect(Collectors.toMap(SpuAdminVO::getSpuId, SpuAdminVO::getPrimaryCategoryId));
            for (EsOrderItemBO orderItem : orderBO.getOrderItems()) {
                Long categoryId = categoryMap.get(orderItem.getSpuId());
                orderItem.setPrimaryCategoryId(categoryId);
            }
        }
    }

    private EsOrderBO loadEsOrderBo(Order order) {
        EsOrderBO esOrderBO = BeanUtil.map(order, EsOrderBO.class);
        esOrderBO.setOrderItems(new ArrayList<>(Constant.INITIAL_CAPACITY));
        // 拼接字符串
        StringBuilder spuCodes = new StringBuilder(500);
        StringBuilder partyCodes = new StringBuilder(500);
        for (OrderItem orderItem : order.getOrderItems()) {
            EsOrderItemBO orderItemVO = BeanUtil.map(orderItem, EsOrderItemBO.class);
            esOrderBO.getOrderItems().add(orderItemVO);
            for (OrderItemLang orderItemLang : orderItem.getOrderItemLangList()) {
                if (Objects.equals(orderItemLang.getLang(), LanguageEnum.LANGUAGE_ZH_CN.getLang())) {
                    orderItemVO.setSpuNameZh(orderItemLang.getSpuName());
                    orderItemVO.setSkuNameZh(orderItemLang.getSkuName());
                } else if (Objects.equals(orderItemLang.getLang(), LanguageEnum.LANGUAGE_EN.getLang())) {
                    orderItemVO.setSpuNameEn(orderItemLang.getSpuName());
                    orderItemVO.setSkuNameEn(orderItemLang.getSkuName());
                }
            }
            if (StrUtil.isNotBlank(orderItem.getSpuCode())) {
                spuCodes.append(orderItem.getSpuCode()).append(StrUtil.COMMA);
            }
            if (StrUtil.isNotBlank(orderItem.getPartyCode())) {
                partyCodes.append(orderItem.getPartyCode()).append(StrUtil.COMMA);
            }
        }
        if (spuCodes.length() > 1 && spuCodes.lastIndexOf(StrUtil.COMMA) == spuCodes.length() - 1) {
            spuCodes.deleteCharAt(spuCodes.length() - 1);
        }

        if (partyCodes.length() > 1 && partyCodes.lastIndexOf(StrUtil.COMMA) == partyCodes.length() - 1) {
            partyCodes.deleteCharAt(partyCodes.length() - 1);
        }
        esOrderBO.setSpuCodes(spuCodes.toString());
        esOrderBO.setPartyCodes(partyCodes.toString());
        return esOrderBO;
    }

    @Override
    public SendNotifyBO getOrderInfoByOrderId(Long orderId) {
        // 获取订单信息
        EsOrderBO order = orderMapper.getEsOrder(orderId);
        List<com.tmerclub.cloud.common.order.vo.OrderItemVO> orderItems = orderItemService.listOrderItemAndLangByOrderId(orderId);
        StringBuilder sb = new StringBuilder(Constant.INITIAL_CAPACITY);
        for (com.tmerclub.cloud.common.order.vo.OrderItemVO selectOrderItem : orderItems) {
            String skuName = Objects.isNull(selectOrderItem.getSkuName()) ? "" : selectOrderItem.getSkuName();
            sb.append(selectOrderItem.getSpuName()).append(skuName).append(StrUtil.COMMA);
        }
        sb.deleteCharAt(sb.length() - 1);

        SendNotifyBO sendNotifyBO = new SendNotifyBO();
        sendNotifyBO.setUserId(order.getUserId());
        sendNotifyBO.setBizId(order.getOrderId());
        sendNotifyBO.setMobile(order.getMobile());
        sendNotifyBO.setSpuName(sb.toString());
        sendNotifyBO.setPrice(PriceUtil.toDecimalPrice(order.getActualTotal()).toString());
        sendNotifyBO.setShopId(order.getShopId());
        return sendNotifyBO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateWaitPurchaseBatchById(List<Order> orders) {
        if (CollUtil.isEmpty(orders)) {
            return;
        }
        for (Order order : orders) {
            orderMapper.updateWaitPurchase(order);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sourcingOrder(Order order) {
        Order orderDb = getByOrderId(order.getOrderId());
        if (Objects.equals(orderDb.getWaitPurchase(), PurchaseOrderWaitStatus.PURCHASED.value())) {
            log.info("订单已经采购，不需要再次采购");
            return;
        }
        order.setWaitPurchase(PurchaseOrderWaitStatus.PURCHASED.value());
        orderMapper.update(order);
        // 发送消息，订单支付成功 通知商家分账
        PayNotifyBO payNotifyBO = new PayNotifyBO();
        payNotifyBO.setOrderIds(Collections.singletonList(order.getOrderId()));
        payNotifyBO.setAgreePurchase(1);
        // 生成店铺钱包日志id列表
        List<Long> shopWalletIds = segmentManager.listSegmentId(DistributedIdKey.tmerclub_SHOP_WALLET_LOG, payNotifyBO.getOrderIds().size() * 3);
        payNotifyBO.setShopWalletIds(shopWalletIds);
        SendStatus sendShopStatus = orderPurchaseNotifyShopTemplate.syncSend(RocketMqConstant.ORDER_PURCHASE_NOTIFY_SHOP_TOPIC, new GenericMessage<>(payNotifyBO)).getSendStatus();
        if (!Objects.equals(sendShopStatus, SendStatus.SEND_OK)) {
            // 消息发不出去就抛异常，因为订单回调会有多次，几乎不可能每次都无法发送出去，发的出去无所谓因为接口是幂等的
            log.info("订单采购后，通知商家分账失败");
            throw new LuckException(ResponseEnum.EXCEPTION);
        }

        //商家采购后，给对应供应商发送待发货提醒
        List<SendNotifyBO> notifyList = this.listSimpleSendNotifyBO(Collections.singletonList(order.getOrderId()));
        for (SendNotifyBO sendNotifyBO : notifyList) {
            sendNotifyBO.setPrice(PriceUtil.toDecimalPrice(sendNotifyBO.getActualTotal()).toString());
            sendNotifyBO.setSendType(SendTypeEnum.USER_PAY_SUCCESS_TO_SUPPLIER.getValue());
            sendNotifyBO.setShopId(null);
        }
        SendStatus sendShopMsgStatus = sendNotifyToShopTemplate.syncSend(RocketMqConstant.SEND_NOTIFY_TO_SHOP_TOPIC, new GenericMessage<>(notifyList.get(0))).getSendStatus();
        if (!Objects.equals(sendShopMsgStatus, SendStatus.SEND_OK)) {
            log.info("订单采购后，通知供应商发货失败");
            throw new LuckException(ResponseEnum.EXCEPTION);
        }
    }


    @Override
    public List<SendNotifyBO> listSimpleSendNotifyBO(List<Long> orderIds) {
        List<OrderItemVO> orderItemList = orderItemService.listOrderItemAndLangByOrderIds(orderIds);
        Map<Long, List<OrderItemVO>> orderItemMap = orderItemList.stream().collect(Collectors.groupingBy(OrderItemVO::getOrderId));

        List<SendNotifyBO> sendNotifyList = new ArrayList<>(orderIds.size());
        for (List<OrderItemVO> orderItems : orderItemMap.values()) {
            OrderItemVO orderItemVO = orderItems.get(0);
            SendNotifyBO sendNotifyBO = new SendNotifyBO();
            sendNotifyBO.setBizId(orderItemVO.getOrderId());
            sendNotifyBO.setSpuName(orderItemVO.getSpuName());
            sendNotifyList.add(sendNotifyBO);
        }
        return sendNotifyList;
    }

    @Override
    public List<SendNotifyBO> listSendNotifyByOrderIds(List<Long> orderIds) {
        List<OrderVO> orderList = orderMapper.listOrderAndLangByOrderIds(orderIds);
        // 获取自提订单的订单id
        List<Long> stationOrderIds = orderList.stream().filter(orderVO -> Objects.equals(orderVO.getDeliveryType(), DeliveryType.STATION.value())).map(OrderVO::getOrderId).collect(Collectors.toList());
        List<OrderSelfStationVO> orderSelfStationVOS = orderSelfStationService.listSelfStationByOrderIds(stationOrderIds);
        Map<Long, OrderSelfStationVO> orderStationMap = orderSelfStationVOS.stream().collect(Collectors.toMap(OrderSelfStationVO::getOrderId, orderSelfStationVO -> orderSelfStationVO));
        List<SendNotifyBO> sendNotifyList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        for (OrderVO orderVO : orderList) {
            SendNotifyBO sendNotifyBO = new SendNotifyBO();
            sendNotifyBO.setShopId(orderVO.getShopId());
            sendNotifyBO.setSupplierId(orderVO.getSupplierId());
            sendNotifyBO.setBizId(orderVO.getOrderId());
            sendNotifyBO.setUserId(orderVO.getUserId());
            sendNotifyBO.setSupplierDeliveryType(orderVO.getSupplierDeliveryType());
            sendNotifyBO.setActualTotal(orderVO.getActualTotal());
            sendNotifyBO.setMobile(Objects.equals(orderVO.getDeliveryType(), DeliveryType.STATION.value()) ? orderStationMap.get(orderVO.getOrderId()).getStationUserMobile() : orderVO.getMobile());
            sendNotifyBO.setShopChangeFreeAmount(orderVO.getShopChangeFreeAmount());
            OrderLangUtil.orderItemVOList(orderVO.getOrderItems());
            StringBuilder stringBuilder = new StringBuilder(Constant.INITIAL_CAPACITY);
            for (com.tmerclub.cloud.common.order.vo.OrderItemVO orderItem : orderVO.getOrderItems()) {
                stringBuilder.append(orderItem.getSpuName()).append(" ");
                if (StrUtil.isNotBlank(orderItem.getSkuName())) {
                    stringBuilder.append(orderItem.getSkuName());
                }
                stringBuilder.append(",");
            }
            if (stringBuilder.length() > 0) {
                stringBuilder.deleteCharAt(stringBuilder.length() - 1);
                sendNotifyBO.setSpuName(stringBuilder.toString());
            }
            sendNotifyList.add(sendNotifyBO);
        }
        return sendNotifyList;
    }

    /**
     * 订单语言信息处理
     *
     * @param order 订单
     */
    private void orderLangHandle(Order order) {
        Integer lang = I18nMessage.getLang();
        for (OrderItem orderItem : order.getOrderItems()) {
            if (CollUtil.isEmpty(orderItem.getOrderItemLangList())) {
                continue;
            }
            Map<Integer, OrderItemLang> langMap = orderItem.getOrderItemLangList().stream().collect(Collectors.toMap(OrderItemLang::getLang, s -> s));
            OrderItemLang orderItemLang;
            if (langMap.containsKey(lang)) {
                orderItemLang = langMap.get(lang);
            } else {
                orderItemLang = langMap.get(Constant.DEFAULT_LANG);
            }
            if (Objects.isNull(orderItemLang)) {
                continue;
            }
            orderItem.setSpuName(orderItemLang.getSpuName());
            orderItem.setSkuName(orderItemLang.getSkuName());
            orderItem.setSupplierSpuName(orderItemLang.getSupplierSpuName());
            orderItem.setSupplierSkuName(orderItemLang.getSupplierSkuName());
        }
    }

    @Override
    public void getReturnOrderStatus(OrderVO orderVO) {
        List<OrderRefund> returnOrderList = orderRefundMapper.getProcessOrderRefundByOrderId(orderVO.getOrderId());
        if (CollUtil.isEmpty(returnOrderList)) {
            return;
        }
        Map<Long, com.tmerclub.cloud.common.order.vo.OrderItemVO> itemMap = orderVO.getOrderItems().stream().collect(Collectors.toMap(com.tmerclub.cloud.common.order.vo.OrderItemVO::getOrderItemId, s -> s));
        for (OrderRefund orderRefund : returnOrderList) {
            if (Objects.equals(orderRefund.getRefundType(), RefundType.ALL.value())) {
                orderVO.getOrderItems().forEach(item -> item.setReturnMoneySts(orderRefund.getReturnMoneySts()));
                break;
            } else {
                itemMap.get(orderRefund.getOrderItemId()).setReturnMoneySts(orderRefund.getReturnMoneySts());
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderStationByOrderId(List<Long> orderIdList, Long userId, Long stationId) {
        if (CollUtil.isEmpty(orderIdList)) {
            // 请选择最少一个需要自提的订单
            throw new LuckException("请选择最少一个需要自提的订单");
        }
        List<OrderVO> orderList = orderMapper.getStationOrderByOrderIds(orderIdList, userId, null);
        OrderVO orderParam = new OrderVO();
        if (CollectionUtils.isEmpty(orderList)) {
            // 订单不存在
            throw new LuckException("订单不存在");
        }
        for (OrderVO order : orderList) {
            if (Objects.isNull(order)) {
                // 订单不存在
                throw new LuckException("订单不存在");
            }
            orderParam = order;
            if (Objects.equals(order.getOrderMold(), 1)) {
                orderVirtualInfoService.orderWriteOffByOrderId(null, BeanUtil.map(order, Order.class), stationId);
                continue;
            }
            // 如果不是自提订单且不是核销订单就直接报错，如果是扫商家码进来的就不需要自提点id
            if (!Objects.equals(order.getDeliveryType(), DeliveryType.STATION.value()) && !Objects.equals(stationId, null)) {
                // 订单不存在
                throw new LuckException("订单不存在");
            }
            boolean isRefund = Objects.equals(order.getRefundStatus(), RefundStatusEnum.APPLY.value())
                    || Objects.equals(order.getRefundStatus(), RefundStatusEnum.SUCCEED.value());
            if (Objects.nonNull(order.getRefundStatus()) && isRefund) {
                // 订单退款中，无法自提
                throw new LuckException(order.getOrderId() + "订单退款中，无法自提");
            }
            List<OrderRefundVO> processOrderRefunds = orderRefundMapper.getProcessingRefundByOrderId(order.getOrderId());
            if (CollectionUtil.isNotEmpty(processOrderRefunds)) {
                // 订单退款中，无法自提
                throw new LuckException(order.getOrderId() + "订单退款中，无法自提");
            }
            if (!Objects.equals(order.getStatus(), OrderStatus.PAYED.value())) {
                // 订单已提货
                throw new LuckException(order.getOrderId() + "订单已提货");
            }
            order.setStatus(OrderStatus.CONSIGNMENT.value());
            order.setDeliveryTime(new Date());
            order.setUpdateTime(new Date());
        }
        if (Objects.isNull(stationId)) {
            stationId = orderParam.getStationId();
        }
        StationVO stationVO = deliveryManager.getStation(stationId);
        List<SendNotifyBO> sendNotifyList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<Long> updateList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        for (OrderVO orderVO : orderList) {
            if (orderVO.getOrderMold() == null || orderVO.getOrderMold() != 1) {
                updateList.add(orderVO.getOrderId());
            }
            Integer lang = I18nMessage.getLang();
            String spuNames = orderVO.getOrderItems().stream().map(x -> {
                for (OrderItemLangVO itemLang : x.getOrderItemLangList()) {
                    if (Objects.equals(itemLang.getLang(), lang)) {
                        return itemLang.getSpuName();
                    }
                }
                return "";
            }).collect(Collectors.joining(" "));
            // 添加消息通知
            addSendNotify(sendNotifyList, orderVO, spuNames);
            sendNotifyList.forEach(item -> {
                item.setStationName(stationVO.getStationName());
            });
        }
        if (updateList.size() != 0) {
            orderMapper.updateByToStatinoSuccess(updateList);
        }
        SendStatus sendStockStatus = sendNotifyToUserTemplate.syncSend(RocketMqConstant.SEND_NOTIFY_TO_USER_TOPIC, new GenericMessage<>(sendNotifyList)).getSendStatus();
        if (!Objects.equals(sendStockStatus, SendStatus.SEND_OK)) {
            log.info("自提订单提货后，推送用户消息发送失败");
            throw new LuckException(ResponseEnum.EXCEPTION);
        }
    }

    private static void addSendNotify(List<SendNotifyBO> sendNotifyList, OrderVO orderVO, String spuNames) {
        // TODO 消息推送-发货提醒,通知其他服务
        SendNotifyBO sendNotifyBO = new SendNotifyBO();
        sendNotifyBO.setUserId(orderVO.getUserId());
        sendNotifyBO.setBizId(orderVO.getOrderId());
        sendNotifyBO.setSpuName(spuNames);
        sendNotifyBO.setShopId(orderVO.getShopId());
        sendNotifyBO.setMobile(orderVO.getMobile());
        sendNotifyBO.setPrice(String.valueOf((orderVO.getActualTotal() / 100)));
        sendNotifyBO.setProdNum(orderVO.getAllCount());
        sendNotifyBO.setDvyName(null);
        sendNotifyBO.setSendType(SendTypeEnum.WRITE_OFF.getValue());
        sendNotifyBO.setDvyFlowId(null);
        sendNotifyList.add(sendNotifyBO);
    }

    @Override
    public List<OrderVO> listStationOrder(OrderDTO orderDTO) {
        return orderMapper.listStationOrder(orderDTO);
    }

    @Override
    public Map<Long, String> checkShopName(OrderSearchDTO orderSearchDTO) {
        Map<Long, String> shopNameMap = new HashMap<>(Constant.INITIAL_CAPACITY);
        if (null != orderSearchDTO.getShopName() && !Objects.equals(orderSearchDTO.getShopName(), "")) {
            log.info("根据店铺名称查询店铺信息，防止店铺被改名导致的订单数据不准确");
            List<ShopDetailVO> shopList = shopDetailFeignClient.getShopDetailByShopIdAndShopName(orderSearchDTO.getShopName()).getData();
            orderSearchDTO.setShopName(null);
            if (CollUtil.isNotEmpty(shopList)) {
                log.info("将数据库查询的店铺id放入查询条件中");
                shopNameMap.putAll(shopList.stream().collect(Collectors.toMap(ShopDetailVO::getShopId, ShopDetailVO::getShopName)));
                orderSearchDTO.setShopIds(shopList.stream().map(ShopDetailVO::getShopId).collect(Collectors.toList()));
            } else {
                orderSearchDTO.setShopId(Constant.DEFAULT_SHOP_ID);
            }
        }
        return shopNameMap;
    }

    @Override
    public Map<Long, String> checkSupplierName(OrderSearchDTO orderSearchDTO) {
        Map<Long, String> supplierNameMap = new HashMap<>(Constant.INITIAL_CAPACITY);
        if (null != orderSearchDTO.getSupplierName() && !Objects.equals(orderSearchDTO.getSupplierName(), "")) {
            log.info("根据供应商名称查询供应商信息，防止供应商被改名导致的订单数据不准确");
            List<SupplierApiDetailVO> supplierList = supplierDetailFeignClient.getSupplierDetailBySupplierName(orderSearchDTO.getSupplierName()).getData();
            orderSearchDTO.setSupplierName(null);
            if (CollUtil.isNotEmpty(supplierList)) {
                log.info("将数据库查询的店铺id放入查询条件中");
                supplierNameMap.putAll(supplierList.stream().collect(Collectors.toMap(SupplierApiDetailVO::getSupplierId, SupplierApiDetailVO::getSupplierName)));
                orderSearchDTO.setSupplierIds(supplierList.stream().map(SupplierApiDetailVO::getSupplierId).collect(Collectors.toList()));
            } else {
                orderSearchDTO.setSupplierId(Constant.DEFAULT_SUPPLIER_ID);
            }
        }
        return supplierNameMap;
    }

    /**
     * 处理自提订单操作
     *
     * @param mergerOrder         聚合订单信息
     * @param order               订单
     * @param dvyType             配送方式
     * @param station             自提点信息
     */
    private void deliverySubmitOrderListener(ShopCartOrderMergerVO mergerOrder, Order order,
                                             Integer dvyType, StationVO station) {
        //判断是否是自提订单
        if (!Objects.equals(dvyType, DeliveryType.STATION.value())) {
            return;
        }
        Date now = new Date();
        //自提订单的地址信息
        OrderSelfStation orderSelfStation = BeanUtil.map(mergerOrder.getOrderSelfStation(), OrderSelfStation.class);
        if (orderSelfStation == null) {
            // 请填写自提信息
            throw new LuckException("请填写自提信息");
        }
        if (order.getOrderItems().get(0).getSpuMold().equals(SpuMold.VIRTUAL.value())) {
            // 虚拟商品不支持自提
            log.info("虚拟商品不需要设置自提信息");
            return;
        }
        if (Objects.isNull(station)) {
            log.info("获取自提点信息：{}", orderSelfStation.getStationId());
            station = stationService.getByStationId(orderSelfStation.getStationId());
        }
        Long userId = mergerOrder.getUserId();
        if (Objects.isNull(station)) {
            // 自提点信息不存在，请重新选择自提点
            throw new LuckException("自提点信息不存在，请重新选择自提点");
        }
        orderSelfStation.setOrderSelfStationId(segmentManager.getSegmentIdWithDateTime(DistributedIdKey.tmerclub_ORDER_SELF_STATION, userId));
        orderSelfStation.setUserId(userId);
        String addr = station.getProvince() + station.getCity() + station.getArea() + station.getAddr();
        //获取最新的随机码
        String code = Constant.PICKUP_CODE_PREFIX + segmentManager.getSegmentCode(DistributedIdKey.tmerclub_ORDER_STATION_CODE, 8);
        orderSelfStation.setStationCode(code);
        orderSelfStation.setOrderId(order.getOrderId());
        orderSelfStation.setShopId(order.getShopId());
        orderSelfStation.setStationAddress(addr);
        //若是固定电话，则拼接上区号
        String mobilePrefix = StrUtil.isNotBlank(station.getMobilePrefix()) ? station.getMobilePrefix() : "";
        orderSelfStation.setStationPhone(mobilePrefix + station.getMobile());
        orderSelfStation.setCreateTime(now);
        orderSelfStation.setUpdateTime(now);
        orderSelfStationService.save(orderSelfStation);
    }

    /**
     * 处理虚拟商品操作
     *
     * @param orderVirtualInfos 虚拟订单核销信息列表
     * @param mergerOrder       聚合订单信息
     * @param shopCartOrderDto  店铺订单信息
     * @param order             订单信息
     */
    private void handlerVirtualProdOder(List<OrderVirtualInfo> orderVirtualInfos, ShopCartOrderMergerVO mergerOrder, ShopCartOrderVO shopCartOrderDto, Order order) {
        Long userId = mergerOrder.getUserId();
        order.setOrderMold(order.getOrderItems().get(0).getSpuMold());
        for (OrderItem orderItem : order.getOrderItems()) {
            if(!Objects.equals(orderItem.getSpuMold(),SpuMold.VIRTUAL.value())){
                continue;
            }
            orderItem.setIsRefund(shopCartOrderDto.getIsRefund());
            Map<Long, List<VirtualRemarkVO>> map = new HashMap<>(8);
            ShopCartItemVO shopCartItemVO = shopCartOrderDto.getShopCartItemDiscounts().get(0).getShopCartItems().get(0);
            Long prodId = shopCartItemVO.getSpuId();
            // 虚拟商品备注信息列表
            if (CollUtil.isNotEmpty(mergerOrder.getVirtualRemarkList())) {
                for (VirtualRemarkVO virtualRemarkVO : mergerOrder.getVirtualRemarkList()) {
                    if (Objects.isNull(virtualRemarkVO.getSpuId())) {
                        virtualRemarkVO.setSpuId(prodId);
                    }
                }
                map = mergerOrder.getVirtualRemarkList().stream().collect(Collectors.groupingBy(VirtualRemarkVO::getSpuId));
            }
            // 存入留言
            String virtualRemarkStr = Json.toJsonString(map.get(prodId));
            orderItem.setVirtualRemark(virtualRemarkStr);
            // 虚拟商品默认无需快递
            order.setDeliveryType(DeliveryType.NOT_DELIVERY.value());
            // 存入核销信息
            order.setWriteOffStart(shopCartOrderDto.getWriteOffStart());
            order.setWriteOffEnd(shopCartOrderDto.getWriteOffEnd());
            if (Objects.nonNull(shopCartOrderDto.getWriteOffEnd()) && DateUtil.compare(shopCartOrderDto.getWriteOffEnd(), new Date()) < 0) {
                throw new LuckException("卡券已过期！");
            }
            order.setWriteOffNum(shopCartOrderDto.getWriteOffNum());
            order.setWriteOffMultipleCount(shopCartOrderDto.getWriteOffMultipleCount());
            order.setWriteOffStatus(0);
            order.setWriteOffCount(0);
            if (Objects.equals(order.getWriteOffNum(), 0)) {
                continue;
            }

            for (int i = 0; i < order.getAllCount(); i++) {
                OrderVirtualInfo orderVirtualInfo = new OrderVirtualInfo();
                orderVirtualInfo.setOrderVirtualInfoId(segmentManager.getSegmentIdWithDateTime(DistributedIdKey.tmerclub_ORDER_VIRTUAL_INFO, userId));
                orderVirtualInfo.setOrderId(order.getOrderId());
                orderVirtualInfo.setOrderItemId(orderItem.getOrderItemId());
                orderVirtualInfo.setShopId(order.getShopId());
                orderVirtualInfo.setIsWriteOff(0);
                orderVirtualInfo.setWriteOffMultipleCount(order.getWriteOffMultipleCount());
                //获取最新的随机码
                String code = Constant.VIRTUAL_CODE_PREFIX + segmentManager.getSegmentCode(DistributedIdKey.tmerclub_ORDER_VIRTUAL_CODE, 8);
                orderVirtualInfo.setWriteOffCode(code);
                orderVirtualInfo.setCreateTime(new Date());
                orderVirtualInfos.add(orderVirtualInfo);
            }
        }
    }

    @Override
    public Order getOrderInfoByShopCartOrderMerger(ShopCartOrderMergerVO mergerOrder) {
        Long userId = mergerOrder.getUserId();
        ShopCartOrderVO shopCartOrderDto = mergerOrder.getShopCartOrders().get(0);
        ShopCartItemVO shopCartItem = mergerOrder.getShopCartOrders().get(0).getShopCartItemDiscounts().get(0).getShopCartItems().get(0);
        OrderAddr orderAddr = BeanUtil.map(mergerOrder.getUserAddr(), OrderAddr.class);
        if (Objects.nonNull(mergerOrder.getUserAddr())) {
            orderAddr.setOrderAddrId(mergerOrder.getUserAddr().getAddrId());
        }
        Map<Long, Integer> dvyTypeMap = mergerOrder.getDvyTypes().stream().collect(Collectors.toMap(DvyTypeDTO::getShopId, DvyTypeDTO::getDvyType));
        Order order = getOrder(userId, dvyTypeMap.get(shopCartOrderDto.getShopId()), mergerOrder.getSpuMold(), shopCartOrderDto);
        Map<Long, List<VirtualRemarkVO>> virtualRemarkMap = new HashMap<>(8);
        // 虚拟商品备注信息列表
        if (CollUtil.isNotEmpty(mergerOrder.getVirtualRemarkList())) {
            virtualRemarkMap = mergerOrder.getVirtualRemarkList().stream().collect(Collectors.groupingBy(VirtualRemarkVO::getSpuId));
        }
        OrderItem orderItem = getOrderItem(mergerOrder, order, shopCartItem, virtualRemarkMap, shopCartOrderDto);
        order.setOrderItems(Collections.singletonList(orderItem));
        order.setOrderAddr(orderAddr);
        order.setStatus(mergerOrder.getStatus());
        order.setCreateTime(mergerOrder.getCreateTime());

        // 处理一下预售
        order.setPreSaleType(shopCartItem.getPreSaleType());
        OrderPreSaleInfo orderPreSaleInfo = new OrderPreSaleInfo();
        orderPreSaleInfo.setPreSaleDeliveryTime(shopCartItem.getPreSaleDeliveryTime());
        orderPreSaleInfo.setPreSaleType(shopCartItem.getPreSaleType());
        orderPreSaleInfo.setPreSaleDeliveryType(shopCartItem.getPreSaleDeliveryType());
        order.setOrderPreSaleInfo(orderPreSaleInfo);
        // 秒杀不能定金预售
//        OrderPreSaleInfo orderPresaleInfo = getOrderPresaleInfo(shopCartOrderDto.getOrderId(), userId, shopCartItem);
        return order;
    }


}
