package com.heyu.api.controller.vv;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.heyu.api.alibaba.request.mm.order.AppCloseDTO;
import com.heyu.api.alibaba.request.mm.order.AppDeliveredDTO;
import com.heyu.api.alibaba.request.mm.order.VvActivityDTO;
import com.heyu.api.alibaba.request.mm.order.resp.*;
import com.heyu.api.alibaba.request.vv.AppCountRequest;
import com.heyu.api.alibaba.request.vv.AppOrderRequest;
import com.heyu.api.common.annotation.AppRealyLogin;
import com.heyu.api.common.annotation.Describe;
import com.heyu.api.data.constants.ApiConstants;
import com.heyu.api.data.dao.vv.*;
import com.heyu.api.data.dto.WeiXinPayDelayDTO;
import com.heyu.api.data.entity.vv.*;
import com.heyu.api.data.enums.*;
import com.heyu.api.data.kuaidi100.AppPackageDTO;
import com.heyu.api.data.kuaidi100.OrderCountDTO;
import com.heyu.api.data.kuaidi100.VVOrderListResp;
import com.heyu.api.data.service.impl.AbstractOrderAction;
import com.heyu.api.data.service.impl.AppliyReverseRequest;
import com.heyu.api.data.service.impl.ReverseOrderService;
import com.heyu.api.data.service.vv.VvPackageService;
import com.heyu.api.data.service.vv.VvTradeOrderConvertService;
import com.heyu.api.data.utils.*;
import com.heyu.api.jsapi.JsapiPrepay;
import com.heyu.api.jsapi.dto.pay.DirectAPIv3JsapiPrepayResponse;
import com.heyu.api.jsapi.dto.pay.WxPayVO;
import com.heyu.api.utils.ISelect;
import com.heyu.api.utils.PPageUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

/**
 * App订单控制器
 * 提供订单的创建、查询、支付、发货、确认收货、退款等完整的订单生命周期管理功能
 *
 * @author heyu
 */
@Slf4j
@RestController
@RequestMapping("/app/order")
public class AppOrderController {

    @Autowired
    private VvTradeOrderLineDao vvTradeOrderLineDao;

    @Autowired
    private VvTradeOrderDao vvTradeOrderDao;

    @Autowired
    private VvSkuDao vvSkuDao;


    @Autowired
    private VvProductDao vvProductDao;


    @Autowired
    private VvSkuPropertyValueDao vvSkuPropertyValueDao;


    @Autowired
    private VvBuyerDao vvBuyerDao;

    @Autowired
    private VvBuyerAddressDao vvBuyerAddressDao;

    @Autowired
    private JsapiPrepay jsapiPrepay;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    @Value("${eb.config.rabbitQueue.delayExchangeName}")
    private String delayExchangeName;

    @Value("${eb.config.weixin.pay.appid}")
    private String appid;

    @Value("${eb.config.weixin.pay.mchid}")
    private String mchid;


    @Value("${eb.config.weixin.pay.privateKeyFilePath}")
    private String privateKey;

    @Autowired
    private JsapiPrepay jsApiPrepay;

    @Autowired
    private VvTradeOrderConvertService vvTradeOrderConvertService;

    @Autowired
    private ReverseOrderService reverseOrderService;

    @Autowired
    private VvProductPropertyDao vvProductPropertyDao;

    @Autowired
    private VvPackageService vvPackageService;

    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private VvPromoterTradeOrderLineAwardDao vvPromoterTradeOrderLineAwardDao;

    @Autowired
    private VvPromoterBuyerDao vvPromoterBuyerDao;

    @Autowired
    private VvPromoterTradeOrderAwardDao vvPromoterTradeOrderAwardDao;


    @Autowired
    private VvOutTradeNoDao vvOutTradeNoDao;

    @Autowired
    private VvActivityDao vvActivityDao;


    /**
     * 订单列表查询
     * 支持按状态、时间、商品名称等多维度查询订单
     * 支持分页查询，返回订单包裹信息
     *
     * @param vvOrderRequest 订单查询请求参数
     * @return 订单列表，包含订单详情和物流信息
     */
    @Describe("订单列表")
    @RequestMapping("/list")
    @AppRealyLogin
    public R list(@RequestBody AppOrderRequest vvOrderRequest) {
        log.info("[订单列表查询] 开始查询, buyerId={}, status={}, pageNum={}, pageSize={}",
                vvOrderRequest.getBuyerId(), vvOrderRequest.getStatus(),
                vvOrderRequest.getPageNum(), vvOrderRequest.getPageSize());
        Integer commentStatus = null;
        if(ApiConstants.WAIT_COMMENT.equals(vvOrderRequest.getStatus())){
            commentStatus = 0;
            vvOrderRequest.setStatus(OrderStatusEnums.delivered.getStatus());
        }
        Integer newcommentStatus = commentStatus;

        PPageUtils pageUtils = PPageUtils.startPage(vvOrderRequest.getPageNum(), vvOrderRequest.getPageSize())
                .doSelect(new ISelect() {
                    @Override
                    public List doSelect(IPage page) {
                        return vvTradeOrderLineDao.selectByAppCondition(
                                page,
                                vvOrderRequest.getTradeOrderIds(),
                                vvOrderRequest.getStatus(),
                                newcommentStatus,
                                OrderStatusEnums.delete.getStatus(),
                                vvOrderRequest.getMinCreateTimestamp(),
                                vvOrderRequest.getMaxCreateTimestamp(),
                                vvOrderRequest.getProductName(),
                                vvOrderRequest.getBuyerId(),
                                vvOrderRequest.getReverseStatus(),
                                vvOrderRequest.getCreateTimestampSort()
                        );
                    }
                });

        // 获取子单
        List<VvTradeOrderLineEntity> vvTradeOrderLineEntitiesGroupByTradeOrderId = pageUtils.getRows();


        if(CollectionUtils.isEmpty(vvTradeOrderLineEntitiesGroupByTradeOrderId)){
            return R.ok().setData(new ArrayList<>());
        }
        // 获取订单
        List<Long> tradeOrderIds = SanUtils.list2listFilterNull(vvTradeOrderLineEntitiesGroupByTradeOrderId, VvTradeOrderLineEntity::getTradeOrderId);
        // 拿到订单的顺序
        List<VvTradeOrderEntity> tradeOrderEntities = vvTradeOrderDao.selectVvTradeOrderByTradeOrderIds(tradeOrderIds);
        // 拿到所有的子订单
        List<VvTradeOrderLineEntity> vvTradeOrderLineEntities = vvTradeOrderLineDao.selectAppTradeOrderByTradeOrderIds(tradeOrderIds);

        List<VVOrderListResp> vvOrderListResps = vvTradeOrderConvertService.convertTradeOrderLineResp(tradeOrderEntities, vvTradeOrderLineEntities, true);

        List<AppPackageDTO> appPackageDTOList = vvTradeOrderConvertService.buildAppPackageDTO(vvOrderListResps);

        log.info("[订单列表查询] 查询完成, buyerId={}, 订单数量={}, 包裹数量={}",
                vvOrderRequest.getBuyerId(), tradeOrderEntities.size(), appPackageDTOList.size());

        return R.ok().setData(appPackageDTOList);
    }


    /**
     * 订单数量统计
     * 统计用户各个状态的订单数量(待支付、待发货、配送中)
     *
     * @param appCountRequest 统计请求参数
     * @return 各状态订单数量统计
     */
    @Describe("订单数量")
    @RequestMapping("/count")
    @AppRealyLogin
    public R list(@RequestBody AppCountRequest appCountRequest) {
        log.info("[订单数量统计] 开始统计, buyerId={}", appCountRequest.getBuyerId());
        PPageUtils waitPayCount = PPageUtils.startPage(appCountRequest.getPageNum(), appCountRequest.getPageSize())
                .doSelect(new ISelect() {
                    @Override
                    public List doSelect(IPage page) {
                        return vvTradeOrderLineDao.selectByAppCount(page,
                                OrderStatusEnums.wait_pay.getStatus(),
                                appCountRequest.getBuyerId()
                        );
                    }
                });

        PPageUtils waitShippingCount = PPageUtils.startPage(appCountRequest.getPageNum(), appCountRequest.getPageSize())
                .doSelect(new ISelect() {
                    @Override
                    public List doSelect(IPage page) {
                        return vvTradeOrderLineDao.selectByAppCount(page,
                                OrderStatusEnums.wait_shipping.getStatus(),
                                appCountRequest.getBuyerId()
                        );
                    }
                });




        PPageUtils shippingCount = PPageUtils.startPage(appCountRequest.getPageNum(), appCountRequest.getPageSize())
                .doSelect(new ISelect() {
                    @Override
                    public List doSelect(IPage page) {
                        return vvTradeOrderLineDao.selectByAppCount(page,
                                OrderStatusEnums.shipping.getStatus(),
                                appCountRequest.getBuyerId()
                        );
                    }
                });

        OrderCountDTO orderCountDTO = new OrderCountDTO();

        orderCountDTO.setShippingCount(shippingCount.getTotal());
        orderCountDTO.setWaitPayCount(waitPayCount.getTotal());
        orderCountDTO.setWaitShippingCount(waitShippingCount.getTotal());

        log.info("[订单数量统计] 统计完成, buyerId={}, 待支付={}, 待发货={}, 配送中={}",
                appCountRequest.getBuyerId(), orderCountDTO.getWaitPayCount(),
                orderCountDTO.getWaitShippingCount(), orderCountDTO.getShippingCount());

        return R.ok().setData(orderCountDTO);

    }


    /**
     * 订单详情查询
     * 根据订单明细ID列表查询订单完整信息，包括物流信息
     *
     * @param vvOrderRequest 订单详情请求参数
     * @return 订单详细信息
     */
    @Describe("订单详情")
    @RequestMapping("/detail")
    @AppRealyLogin
    public R detail(@RequestBody AppTradeOrderDetailDTO vvOrderRequest) {
        log.info("[订单详情查询] 开始查询, tradeOrderLineIds={}", vvOrderRequest.getTradeOrderLineIdList());
        List<VvTradeOrderLineEntity> vvTradeOrderLineEntities = vvTradeOrderLineDao.selectVvTradeOrderLineByIds(vvOrderRequest.getTradeOrderLineIdList());
        List<String> trackNumbers = SanUtils.getDistinctFiledList(vvTradeOrderLineEntities, VvTradeOrderLineEntity::getTrackNumber);
        if (CollectionUtils.isNotEmpty(trackNumbers)) {
            for (String trackNumber : trackNumbers) {
                vvPackageService.selectVvKuaidiAndUpdateData(trackNumber, RoleEnums.user.getRole(), true);
            }
        }

        List<Long> tradeOrderIds = SanUtils.list2listFilterNull(vvTradeOrderLineEntities, VvTradeOrderLineEntity::getTradeOrderId);
        // 拿到订单的顺序
        List<VvTradeOrderEntity> tradeOrderEntities = vvTradeOrderDao.selectVvTradeOrderByTradeOrderIds(tradeOrderIds);
        List<VVOrderListResp> vvOrderListResps = vvTradeOrderConvertService.convertTradeOrderLineResp(tradeOrderEntities, vvTradeOrderLineEntities, true);
        List<AppPackageDTO> appPackageDTOList = vvTradeOrderConvertService.buildAppPackageDTO(vvOrderListResps);

        log.info("[订单详情查询] 查询完成, tradeOrderLineIds={}, 包裹数量={}",
                vvOrderRequest.getTradeOrderLineIdList(), appPackageDTOList.size());

        return R.ok().setData(appPackageDTOList);
    }

    /**
     * 添加订单
     * 创建订单并发起微信支付，支持活动优惠和推广奖励
     * 主要流程:
     * 1. 校验库存
     * 2. 创建订单和订单明细
     * 3. 处理活动优惠和推广奖励
     * 4. 调用微信支付预下单
     * 5. 发送延迟关单消息
     *
     * @param vvOrderRequest 订单创建请求参数
     * @return 微信支付参数
     */
    @Describe("添加订单")
    @RequestMapping("/add")
    @AppRealyLogin
    public R add(@RequestBody VvTradeOrderDTO vvOrderRequest) {
        log.info("[添加订单] 开始创建订单, buyerId={}, skuIds={}, buyerAddressId={}",
                vvOrderRequest.getBuyerId(),
                SanUtils.getFieldList(vvOrderRequest.getVvTradeOrderLineDTOList(), VvTradeOrderLineDTO::getSkuId),
                vvOrderRequest.getBuyerAddressId());
        List<VvTradeOrderLineEntity> vvTradeOrderLineEntityList = new ArrayList<>();
        List<Long> skuIds = SanUtils.getFieldList(vvOrderRequest.getVvTradeOrderLineDTOList(), VvTradeOrderLineDTO::getSkuId);
        List<VvSkuPropertyValueEntity> vvSkuPropertyValueList = vvSkuPropertyValueDao.selectVvSkuPropertyValueBySkuIds(skuIds);
        Map<Long, VvTradeOrderLineDTO> vvTradeOrderLineMap = SanUtils.groupByFiled2Map(vvOrderRequest.getVvTradeOrderLineDTOList(), VvTradeOrderLineDTO::getSkuId);

        List<VvSkuEntity> vvSkuEntities = vvSkuDao.selectVvSkuBySkuIds(skuIds);
        // 校验库存
        for (VvSkuEntity vvSkuEntity : vvSkuEntities) {
            VvTradeOrderLineDTO vvTradeOrderLineDTO = vvTradeOrderLineMap.get(vvSkuEntity.getId());
            // 如果库存少于 0 ，则显示库存不足
            if (vvSkuEntity.getStock() - vvTradeOrderLineDTO.getNum() < 0) {
                log.warn("[添加订单] 库存不足, skuId={}, 当前库存={}, 购买数量={}",
                        vvSkuEntity.getId(), vvSkuEntity.getStock(), vvTradeOrderLineDTO.getNum());
                OrderSkuDTO orderSkuDTO = new OrderSkuDTO();
                orderSkuDTO.setSkuId(vvSkuEntity.getId());
                orderSkuDTO.setMessage("库存不足");
                return R.error().setData(orderSkuDTO);
            }
        }
        log.info("[添加订单] 库存校验通过, skuIds={}", skuIds);


        Map<Long, VvSkuEntity> skuEntityMap = SanUtils.groupByFiled2Map(vvSkuEntities, VvSkuEntity::getId);
        Map<Long, List<VvSkuPropertyValueEntity>> vvSkuPropertyValueMap = SanUtils.groupByFiled2MapList(vvSkuPropertyValueList, VvSkuPropertyValueEntity::getSkuId);
        List<Long> productIdList = SanUtils.getDistinctFiledList(vvSkuEntities, VvSkuEntity::getProductId);
        List<VvProductEntity> vvProductList = vvProductDao.selectVvProductByProductIds(productIdList);

        Map<Long, VvProductEntity> vvProductMap = SanUtils.groupByFiled2Map(vvProductList, VvProductEntity::getId);
        VvBuyerAddressEntity vvBuyerAddress = vvBuyerAddressDao.selectVvBuyerAddressById(vvOrderRequest.getBuyerAddressId());

        List<VvProductPropertyEntity> vvProductPropertyEntities = vvProductPropertyDao.selectVvProductPropertyByProductIdList(productIdList);
        Map<Long, List<VvProductPropertyEntity>> vvProductPropertyMap = SanUtils.groupByFiled2MapList(vvProductPropertyEntities, VvProductPropertyEntity::getProductId);
        String activityInfo = redisUtils.get(ApiConstants.token_activity + vvOrderRequest.getToken());

        VvActivityDTO vvActivityDTO = null;
        VvActivityEntity vvActivityEntity = null;
        if (StringUtils.isNotEmpty(activityInfo)) {
            vvActivityDTO = JSONObject.parseObject(activityInfo, VvActivityDTO.class);
            vvActivityEntity = vvActivityDao.selectVvActivityById(vvActivityDTO.getActivityId());
            log.info("[添加订单] 检测到活动信息, activityId={}, discountAmount={}, awardAmount={}",
                    vvActivityDTO.getActivityId(), vvActivityEntity.getDiscountAmount(), vvActivityEntity.getAwardAmount());
        }

        Integer batchNum = SanUtils.sum(vvOrderRequest.getVvTradeOrderLineDTOList(), VvTradeOrderLineDTO::getNum);
        log.info("[添加订单] 订单总数量={}", batchNum);

        for (VvTradeOrderLineDTO vvTradeOrderLineDTO : vvOrderRequest.getVvTradeOrderLineDTOList()) {
            VvSkuEntity vvSkuEntity = skuEntityMap.get(vvTradeOrderLineDTO.getSkuId());
            List<VvSkuPropertyValueEntity> vvSkuPropertyValueEntities = vvSkuPropertyValueMap.get(vvTradeOrderLineDTO.getSkuId());
            VvProductEntity vvProduct = vvProductMap.get(vvSkuEntity.getProductId());
            List<PropertyNameValue> propertyNameValues = new ArrayList<>();
            Map<String, VvSkuPropertyValueEntity> vvSkuPropertyValueItemMap = SanUtils.groupByFiled2Map(vvSkuPropertyValueEntities, VvSkuPropertyValueEntity::getProductPropertyName);
            // 对商品属性进行排序
            List<VvProductPropertyEntity> vvProductPropertyList = vvProductPropertyMap.get(vvSkuEntity.getProductId());
            for (VvProductPropertyEntity vvProductPropertyEntity : vvProductPropertyList) {
                VvSkuPropertyValueEntity vvSkuPropertyValueEntity = vvSkuPropertyValueItemMap.get(vvProductPropertyEntity.getProductPropertyName());
                PropertyNameValue propertyNameValue = new PropertyNameValue();
                propertyNameValue.setPropertyName(vvSkuPropertyValueEntity.getProductPropertyName());
                propertyNameValue.setPropertyValue(vvSkuPropertyValueEntity.getProductPropertyValue());
                propertyNameValues.add(propertyNameValue);
            }

            for (int i = 0; i < vvTradeOrderLineDTO.getNum(); i++) {
                VvTradeOrderLineEntity vvTradeOrderLineEntity = new VvTradeOrderLineEntity();
                vvTradeOrderLineEntity.setSkuId(vvTradeOrderLineDTO.getSkuId());
                vvTradeOrderLineEntity.setNum(1);                   // 拆成最细粒度的单
                vvTradeOrderLineEntity.setCreateTime(new Date());
                vvTradeOrderLineEntity.setModifyTime(new Date());
                vvTradeOrderLineEntity.setSalePrice(vvSkuEntity.getSalePrice());
                vvTradeOrderLineEntity.setSkuImageUrl(vvSkuEntity.getImageUrl());
                vvTradeOrderLineEntity.setOriginPrice(vvSkuEntity.getOriginPrice());
                vvTradeOrderLineEntity.setPromotionPrice(vvSkuEntity.getPromotionPrice());
                vvTradeOrderLineEntity.setSalePrice(vvSkuEntity.getSalePrice());
                vvTradeOrderLineEntity.setProductId(vvSkuEntity.getProductId());
                vvTradeOrderLineEntity.setProductName(vvProduct.getTitle());
                vvTradeOrderLineEntity.setPromotionPrice(vvSkuEntity.getPromotionPrice());
                vvTradeOrderLineEntity.setProductMainImageUrl(vvProduct.getMainImageUrl());
                vvTradeOrderLineEntity.setSkuInfo(JSON.toJSONString(propertyNameValues));
                vvTradeOrderLineEntity.setCreateTimestamp(System.currentTimeMillis());
                vvTradeOrderLineEntity.setModifyTimestamp(System.currentTimeMillis());
                vvTradeOrderLineEntity.setContry(vvBuyerAddress.getContry());
                vvTradeOrderLineEntity.setProvince(vvBuyerAddress.getProvince());
                vvTradeOrderLineEntity.setCity(vvBuyerAddress.getCity());
                vvTradeOrderLineEntity.setDistrict(vvBuyerAddress.getDistrict());
                vvTradeOrderLineEntity.setBuyerDetailAddress(vvBuyerAddress.getDetail());
                vvTradeOrderLineEntity.setStatus(OrderStatusEnums.create.getStatus());
                vvTradeOrderLineEntity.setBuyerId(vvOrderRequest.getBuyerId());
                vvTradeOrderLineEntity.setBuyerAddressId(vvOrderRequest.getBuyerAddressId());
                vvTradeOrderLineEntity.setBatchNum(batchNum);           // sku 对应的笔数
                // 支付金额默认是促销价格
                BigDecimal payAmount = vvSkuEntity.getPromotionPrice();
                if (vvActivityEntity != null) {
                    vvTradeOrderLineEntity.setAwardAmount(vvActivityEntity.getAwardAmount());
                    vvTradeOrderLineEntity.setDiscountAmount(vvActivityEntity.getDiscountAmount());
                    vvTradeOrderLineEntity.setPromoterId(vvActivityDTO.getBuyerId());
                    payAmount = BigDecimalUtil.subtract(vvSkuEntity.getPromotionPrice(), vvActivityEntity.getDiscountAmount());

                }
                vvTradeOrderLineEntity.setPayAmount(payAmount);
                vvTradeOrderLineEntity.setActivityInfo(activityInfo);
                vvTradeOrderLineEntityList.add(vvTradeOrderLineEntity);
            }
        }

        VvTradeOrderEntity vvTradeOrderEntity = new VvTradeOrderEntity();
        VvBuyerEntity vvBuyerEntity = vvBuyerDao.selectVvBuyerById(vvOrderRequest.getBuyerId());

        //创建时间
        vvTradeOrderEntity.setCreateTime(new Date());
        vvTradeOrderEntity.setModifyTime(new Date());
        vvTradeOrderEntity.setNum(vvTradeOrderLineEntityList.size());
        vvTradeOrderEntity.setBuyerPhone(vvBuyerEntity.getBuyerPhone());
        vvTradeOrderEntity.setBuyerName(vvBuyerEntity.getBuyerName());
        vvTradeOrderEntity.setBuyerWeixin(vvBuyerEntity.getBuyerWeixin());
        vvTradeOrderEntity.setGmtDownOrder(new Date());

        vvTradeOrderEntity.setContry(vvBuyerAddress.getContry());
        vvTradeOrderEntity.setProvince(vvBuyerAddress.getProvince());
        vvTradeOrderEntity.setCity(vvBuyerAddress.getCity());
        vvTradeOrderEntity.setDistrict(vvBuyerAddress.getDistrict());
        vvTradeOrderEntity.setBuyerDetailAddress(vvBuyerAddress.getDetail());

        BigDecimal tradeOrderPromotionPrice = SanUtils.sum(vvTradeOrderLineEntityList, VvTradeOrderLineEntity::getPromotionPrice);
        vvTradeOrderEntity.setPromotionPrice(tradeOrderPromotionPrice);

        vvTradeOrderEntity.setBuyerId(vvOrderRequest.getBuyerId());
        vvTradeOrderEntity.setCreateTimestamp(System.currentTimeMillis());
        vvTradeOrderEntity.setModifyTimestamp(System.currentTimeMillis());
        vvTradeOrderEntity.setBuyerAddressId(vvOrderRequest.getBuyerAddressId());

        BigDecimal tradePayAmount = SanUtils.sum(vvTradeOrderLineEntityList, VvTradeOrderLineEntity::getPayAmount);
        vvTradeOrderEntity.setPayAmount(tradePayAmount);
        vvTradeOrderDao.insertVvTradeOrder(vvTradeOrderEntity);

        log.info("[添加订单] 创建主订单成功, tradeOrderId={}, 订单金额={}, 明细数量={}",
                vvTradeOrderEntity.getId(), tradePayAmount, vvTradeOrderLineEntityList.size());

        List<VvPromoterTradeOrderLineAwardEntity> vvPromoterTradeOrderLineAwardEntityList = new ArrayList<>();

        for (VvTradeOrderLineEntity tradeOrderLineEntity : vvTradeOrderLineEntityList) {
            tradeOrderLineEntity.setTradeOrderId(vvTradeOrderEntity.getId());
            // 如果在奖励金额
            if (tradeOrderLineEntity.getAwardAmount() != null
                    && tradeOrderLineEntity.getAwardAmount().compareTo(BigDecimal.ZERO) > 0) {
                VvPromoterTradeOrderLineAwardEntity vvPromoterTradeOrderLineAwardEntity = new VvPromoterTradeOrderLineAwardEntity();
                vvPromoterTradeOrderLineAwardEntity.setPromoterId(tradeOrderLineEntity.getPromoterId());


                vvPromoterTradeOrderLineAwardEntity.setAwardAmount(vvActivityEntity.getAwardAmount());



                vvPromoterTradeOrderLineAwardEntity.setTradeOrderId(vvTradeOrderEntity.getId());
                vvPromoterTradeOrderLineAwardEntity.setTradeOrderLineId(tradeOrderLineEntity.getId());
                vvPromoterTradeOrderLineAwardEntity.setWasBuyerId(tradeOrderLineEntity.getBuyerId());
                vvPromoterTradeOrderLineAwardEntity.setWasBuyerName(tradeOrderLineEntity.getBuyerName());
                vvPromoterTradeOrderLineAwardEntity.setWasBuyerPhone(tradeOrderLineEntity.getBuyerPhone());
                vvPromoterTradeOrderLineAwardEntity.setWasBuyerWeixin(tradeOrderLineEntity.getBuyerWeixin());
                vvPromoterTradeOrderLineAwardEntity.setStatus(AwardStatusEnums.create.getStatus());
                vvPromoterTradeOrderLineAwardEntity.setGmtCreate(new Date());
                vvPromoterTradeOrderLineAwardEntityList.add(vvPromoterTradeOrderLineAwardEntity);
            }

            vvTradeOrderLineDao.insertOrUpdateVvTradeOrderLine(tradeOrderLineEntity);
        }

        List<VvPromoterBuyerEntity> vvPromoterBuyerList = null;
        if (vvActivityEntity != null) {
            vvPromoterBuyerList = vvPromoterBuyerDao.selectVvPromoterBuyerByPromoterId(vvActivityDTO.getBuyerId());
        }

        if (CollectionUtils.isNotEmpty(vvPromoterBuyerList)
                && CollectionUtils.isNotEmpty(vvPromoterTradeOrderLineAwardEntityList)) {
            Map<Long,List<VvPromoterTradeOrderLineAwardEntity>> vvPromoterTradeOrderLineAwardMap = new HashMap<>();
            for (VvPromoterTradeOrderLineAwardEntity vvPromoterTradeOrderLineAwardEntity : vvPromoterTradeOrderLineAwardEntityList) {
                BigDecimal awardAmount = vvPromoterTradeOrderLineAwardEntity.getAwardAmount();
                BigDecimal awardAmountSingle = BigDecimalUtil.divide(awardAmount, new BigDecimal(vvPromoterBuyerList.size()));
                VvPromoterTradeOrderLineAwardEntity promoterTradeOrderLineAwardNew = new VvPromoterTradeOrderLineAwardEntity();
                BeanUtils.copyProperties(vvPromoterTradeOrderLineAwardEntity, promoterTradeOrderLineAwardNew);
                BigDecimal sum = BigDecimal.ZERO;

                for (int i = 0; i < vvPromoterBuyerList.size(); i++) {
                    VvPromoterBuyerEntity vvPromoterBuyer = vvPromoterBuyerList.get(i);
                    if (i == vvPromoterBuyerList.size() - 1) {
                        promoterTradeOrderLineAwardNew.setAwardAmount(awardAmount.subtract(sum));
                    } else {
                        sum = sum.add(awardAmountSingle);
                        promoterTradeOrderLineAwardNew.setAwardAmount(awardAmountSingle);
                    }
                    promoterTradeOrderLineAwardNew.setPromoterBuyerId(vvPromoterBuyer.getPromoterBuyerId());
                    promoterTradeOrderLineAwardNew.setPromoterBuyerName(vvPromoterBuyer.getPromoterBuyerName());
                    promoterTradeOrderLineAwardNew.setPromoterBuyerPhone(vvPromoterBuyer.getPromoterBuyerPhone());
                    promoterTradeOrderLineAwardNew.setPromoterBuyerWeixin(vvPromoterBuyer.getPromoterBuyerWeixin());
                    vvPromoterTradeOrderLineAwardDao.insertVvPromoterTradeOrderLineAward(promoterTradeOrderLineAwardNew);

                    List<VvPromoterTradeOrderLineAwardEntity> list = vvPromoterTradeOrderLineAwardMap.get(vvPromoterBuyer.getPromoterBuyerId());
                    if (list == null) {
                        list = new ArrayList<>();
                    }
                    list.add(promoterTradeOrderLineAwardNew);
                    vvPromoterTradeOrderLineAwardMap.put(vvPromoterBuyer.getPromoterBuyerId(), list);
                }
            }



            for (Map.Entry<Long, List<VvPromoterTradeOrderLineAwardEntity>> entry : vvPromoterTradeOrderLineAwardMap.entrySet()) {
                VvPromoterTradeOrderAwardEntity vvPromoterTradeOrderAwardEntity = new VvPromoterTradeOrderAwardEntity();
                VvPromoterTradeOrderLineAwardEntity vvPromoterTradeOrderLineAwardIndex_0 = vvPromoterTradeOrderLineAwardEntityList.get(0);
                BeanUtils.copyProperties(vvPromoterTradeOrderLineAwardIndex_0, vvPromoterTradeOrderAwardEntity);

                List<VvPromoterTradeOrderLineAwardEntity> vvPromoterTradeOrderLineAwardEntities = entry.getValue();
                BigDecimal tradeOrderAward = SanUtils.sum(vvPromoterTradeOrderLineAwardEntities, VvPromoterTradeOrderLineAwardEntity::getAwardAmount);
                vvPromoterTradeOrderAwardEntity.setAwardAmount(tradeOrderAward);
                vvPromoterTradeOrderAwardDao.insertVvPromoterTradeOrderAward(vvPromoterTradeOrderAwardEntity);

                vvBuyerDao.updateVvBuyerByIdPromoterSumAmountPromoterNotArriveAmount(
                        vvPromoterTradeOrderAwardEntity.getAwardAmount(),
                        vvPromoterTradeOrderAwardEntity.getAwardAmount(),
                        vvPromoterTradeOrderAwardEntity.getId());


                for (VvPromoterTradeOrderLineAwardEntity vvPromoterTradeOrderLineAwardEntity : vvPromoterTradeOrderLineAwardEntities) {
                    vvPromoterTradeOrderLineAwardEntity.setPromoterTradeOrderAwardId(vvPromoterTradeOrderAwardEntity.getId());
                    vvPromoterTradeOrderLineAwardDao.updateVvPromoterTradeOrderLineAwardById(vvPromoterTradeOrderLineAwardEntity);
                }
            }
        }

        for (VvTradeOrderLineDTO vvTradeOrderLineDTO : vvOrderRequest.getVvTradeOrderLineDTOList()) {
            vvSkuDao.updateVvSkuStockSaleCountById(vvTradeOrderLineDTO.getNum(), vvTradeOrderLineDTO.getNum(), vvTradeOrderLineDTO.getNum(), vvTradeOrderLineDTO.getSkuId());
        }

        Map<Long, Integer> productNumMap = SanUtils.groupAndSum(VvTradeOrderLineEntity::getProductId, vvTradeOrderLineEntityList, VvTradeOrderLineEntity::getNum);
        for (Map.Entry<Long, Integer> map : productNumMap.entrySet()) {
            vvProductDao.updateShowSaleCountAndSaleCount(map.getValue(), map.getValue(), map.getKey());
        }

        VvOutTradeNoEntity vvOutTradeNo = new  VvOutTradeNoEntity();
        vvOutTradeNoDao.insertOrUpdateVvOutTradeNo(vvOutTradeNo);
        vvTradeOrderEntity.setOutTradeNo(vvOutTradeNo.getId()+"");
        vvTradeOrderDao.updateVvTradeOrderById(vvTradeOrderEntity);

        DirectAPIv3JsapiPrepayResponse jsapiPrepayResponse = jsapiPrepay.prePay(vvTradeOrderEntity.getOutTradeNo(),
                BigDecimalUtil.multiply(vvTradeOrderEntity.getPayAmount(), new BigDecimal(100)).longValue(),
                vvBuyerEntity.getOpenid()
        );

        log.info("[添加订单] 微信预下单成功, tradeOrderId={}, outTradeNo={}, prepayId={}",
                vvTradeOrderEntity.getId(), vvTradeOrderEntity.getOutTradeNo(), jsapiPrepayResponse.getPrepayId());

        String prepay_id = jsapiPrepayResponse.getPrepayId();

        if (jsapiPrepayResponse != null && jsapiPrepayResponse.getPrepayId() != null) {
            List<VvTradeOrderLineEntity> vvTradeOrderLineEntities = vvTradeOrderLineDao.selectVvTradeOrderLineByTradeOrderId(vvTradeOrderEntity.getId());
            for (VvTradeOrderLineEntity vvTradeOrderLineEntity : vvTradeOrderLineEntities) {
                vvTradeOrderLineEntity.setPayType(PayTypeEnums.weixin.getType());
                vvTradeOrderLineEntity.setStatus(OrderStatusEnums.wait_pay.getStatus());
                vvTradeOrderLineEntity.setPrepayId(jsapiPrepayResponse.getPrepayId());
                vvTradeOrderLineEntity.setGmtPrePay(new Date());
                vvTradeOrderLineDao.updateVvTradeOrderLineById(vvTradeOrderLineEntity);
            }

            // 发送订单关单的消息
            Date currentTime = new Date();
            Date after30 = DateUtils.addMinutes(currentTime, 30);
            Integer second = DateUtils.betweenSecond(currentTime, after30);
            WeiXinPayDelayDTO weiXinPayDelayDTO = new WeiXinPayDelayDTO();
            weiXinPayDelayDTO.setSendTime(DateUtils.formatDate(currentTime, com.heyu.api.data.utils.DateUtils.YYYY_MM_DD_HH_MM_SS));
            weiXinPayDelayDTO.setDelayTime(DateUtils.formatDate(after30, com.heyu.api.data.utils.DateUtils.YYYY_MM_DD_HH_MM_SS));
            weiXinPayDelayDTO.setType(DelayTypeEnums.weixinPayClose.getType());
            weiXinPayDelayDTO.setRole(RoleEnums.user.getRole());
            weiXinPayDelayDTO.setTradeOrderId(vvTradeOrderEntity.getId());

            rabbitTemplate.convertAndSend(delayExchangeName, "", JSON.toJSONString(weiXinPayDelayDTO), message -> {
                message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                message.getMessageProperties().setDelay((second) * 1000);   // 毫秒为单位，指定此消息的延时时长 ,+ 1 尽量保证机器人跑完了，再发送消息
                return message;
            });

            log.info("[添加订单] 发送延迟关单消息成功, tradeOrderId={}, delayTime={}秒",
                    vvTradeOrderEntity.getId(), second);
        }

        WxPayVO vo = new WxPayVO();
        Long timeStamp = System.currentTimeMillis() / 1000;
        String nonceStr = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
        String signatureStr = Stream.of(appid, String.valueOf(timeStamp), nonceStr, "prepay_id=" + prepay_id)
                .collect(Collectors.joining("\n", "", "\n"));
        //  "timeStamp": "1414561699",
        //    "nonceStr": "5K8264ILTKCH16CQ2502SI8ZNMTM67VS",
        //    "package": "prepay_id=wx201410272009395522657a690389285100",
        //    "signType": "RSA",
        //    "paySign": "oR9d",

        String sign = JsapiPrepay.getSign(signatureStr, privateKey);
        vo.setNonceStr(nonceStr);
        vo.setTimeStamp(timeStamp);
        vo.setMchid(mchid);
        vo.setPaySign(sign);
        vo.setPrepayId("prepay_id=" + prepay_id);

        log.info("[添加订单] 订单创建完成, tradeOrderId={}, outTradeNo={}, payAmount={}",
                vvTradeOrderEntity.getId(), vvTradeOrderEntity.getOutTradeNo(), vvTradeOrderEntity.getPayAmount());

        return R.ok().setData(vo);
    }

    /**
     * 订单再次支付
     * 当订单支付失败或超时后，用户可以再次发起支付
     *
     * @param vvOrderRequest 支付请求参数
     * @return 微信支付参数
     */
    @Describe("订单再次支付")
    @RequestMapping("/to/pay")
    @AppRealyLogin
    public R toPay(@RequestBody VvTradeOrderToPayDTO vvOrderRequest) {
        log.info("[订单再次支付] 开始处理, tradeOrderId={}, buyerId={}",
                vvOrderRequest.getTradeOrderId(), vvOrderRequest.getBuyerId());
        VvTradeOrderEntity vvTradeOrderEntity = vvTradeOrderDao.selectVvTradeOrderById(vvOrderRequest.getTradeOrderId());

        VvBuyerEntity vvBuyerEntity = vvBuyerDao.selectVvBuyerById(vvOrderRequest.getBuyerId());
        VvOutTradeNoEntity vvOutTradeNo = new  VvOutTradeNoEntity();
        vvOutTradeNoDao.insertOrUpdateVvOutTradeNo(vvOutTradeNo);

        vvTradeOrderEntity.setOutTradeNo(vvOutTradeNo.getId()+"");
        vvTradeOrderDao.updateVvTradeOrderById(vvTradeOrderEntity);

        DirectAPIv3JsapiPrepayResponse jsapiPrepayResponse = jsapiPrepay.prePay(vvTradeOrderEntity.getOutTradeNo(),
                BigDecimalUtil.multiply(vvTradeOrderEntity.getPayAmount(), new BigDecimal(100)).longValue(),
                vvBuyerEntity.getOpenid()
        );

        String prepay_id = jsapiPrepayResponse.getPrepayId();

        if (jsapiPrepayResponse != null && jsapiPrepayResponse.getPrepayId() != null) {
            List<VvTradeOrderLineEntity> vvTradeOrderLineEntities = vvTradeOrderLineDao.selectVvTradeOrderLineByTradeOrderId(vvTradeOrderEntity.getId());
            for (VvTradeOrderLineEntity vvTradeOrderLineEntity : vvTradeOrderLineEntities) {
                vvTradeOrderLineEntity.setPayType(PayTypeEnums.weixin.getType());
                vvTradeOrderLineEntity.setStatus(OrderStatusEnums.wait_pay.getStatus());
                vvTradeOrderLineEntity.setPrepayId(jsapiPrepayResponse.getPrepayId());
                vvTradeOrderLineEntity.setGmtPrePay(new Date());
                vvTradeOrderLineDao.updateVvTradeOrderLineById(vvTradeOrderLineEntity);
            }
        }

        WxPayVO vo = new WxPayVO();
        Long timeStamp = System.currentTimeMillis() / 1000;
        String nonceStr = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
        String signatureStr = Stream.of(appid, String.valueOf(timeStamp), nonceStr, "prepay_id=" + prepay_id)
                .collect(Collectors.joining("\n", "", "\n"));

        //  "timeStamp": "1414561699",
        //    "nonceStr": "5K8264ILTKCH16CQ2502SI8ZNMTM67VS",
        //    "package": "prepay_id=wx201410272009395522657a690389285100",
        //    "signType": "RSA",
        //    "paySign": "oR9d",

        String sign = JsapiPrepay.getSign(signatureStr, privateKey);
        vo.setNonceStr(nonceStr);
        vo.setTimeStamp(timeStamp);
        vo.setMchid(mchid);
        vo.setPaySign(sign);
        vo.setPrepayId("prepay_id=" + prepay_id);

        return R.ok().setData(vo);
    }

    /**
     * 删除订单
     * 将订单状态更新为已删除，仅在特定状态下允许删除
     *
     * @param vvOrderRequest 删除请求参数
     * @return 删除结果
     */
    @Describe("删除订单")
    @RequestMapping("/delete")
    @AppRealyLogin
    public R delete(@RequestBody VvTradeOrderDeleteDTO vvOrderRequest) {
        log.info("[删除订单] 开始处理, tradeOrderId={}, trackNumber={}, buyerId={}",
                vvOrderRequest.getTradeOrderId(), vvOrderRequest.getTrackNumber(), vvOrderRequest.getBuyerId());
        List<VvTradeOrderLineEntity> vvTradeOrderLineEntityList = null;
        if (StringUtils.isNotEmpty(vvOrderRequest.getTrackNumber())) {
            vvTradeOrderLineEntityList = vvTradeOrderLineDao.selectVvTradeOrderLineByTrackNumberBuyerId(vvOrderRequest.getTrackNumber(), vvOrderRequest.getBuyerId());
        }
        if (vvOrderRequest.getTradeOrderId() != null) {
            vvTradeOrderLineEntityList = vvTradeOrderLineDao.selectVvTradeOrderLineByTradeOrderIdBuyerId(vvOrderRequest.getTradeOrderId(), vvOrderRequest.getBuyerId());
        }
        if (CollectionUtils.isNotEmpty(vvTradeOrderLineEntityList)) {
            for (VvTradeOrderLineEntity vvTradeOrderLineEntity : vvTradeOrderLineEntityList) {
                if (AbstractOrderAction.checkFailed(vvTradeOrderLineEntity, true, ActionEnums.App_Delete)) {
                    return R.error("包裹状态 ：" + vvTradeOrderLineEntity.getStatus() + "，不符合状态。");
                }
            }
            for (VvTradeOrderLineEntity vvTradeOrderLineEntity : vvTradeOrderLineEntityList) {
                vvTradeOrderLineDao.updateByBuerIdAndIds(OrderStatusEnums.delete.getStatus(), vvOrderRequest.getBuyerId(), vvTradeOrderLineEntity.getId());
                vvTradeOrderConvertService.addOrderLineStatusLog(
                        vvTradeOrderLineEntity.getId(),
                        OrderStatusEnums.delete,
                        vvOrderRequest.getBuyerId(),
                        vvOrderRequest.getBuyerName()
                );
            }
        }
        return R.ok();
    }


    // /app/order/applyCancel
    @Describe("申请取消")
    @RequestMapping("/applyCancel")
    @AppRealyLogin
    public R applyCancel(@RequestBody VvTradeOrderCancelDTO request) {
        List<VvTradeOrderLineEntity> vvTradeOrderLineEntityList = vvTradeOrderLineDao.selectVvTradeOrderLineByTradeOrderId(request.getTradeOrderId());
        for (VvTradeOrderLineEntity vvTradeOrderLineEntity : vvTradeOrderLineEntityList) {
            if (AbstractOrderAction.checkFailed(vvTradeOrderLineEntity, true, ActionEnums.App_Apply_Cancel)) {
                return R.error("订单状态不是wait_shipping，不能取消订单");
            }
        }
        AppliyReverseRequest appliyReverseRequest = new AppliyReverseRequest();
        appliyReverseRequest.setRefundType(RefundTypeEnums.only_refund.getCode());
        appliyReverseRequest.setRefundReason("买家申请订单取消:" + request.getReason());
        appliyReverseRequest.setStatus(ReverseStatusEnums.buyer_apply_cancel.getStatus());
        reverseOrderService.createReverseOrder(vvTradeOrderLineEntityList, appliyReverseRequest);

        for (VvTradeOrderLineEntity vvTradeOrderLineEntity : vvTradeOrderLineEntityList) {
            vvTradeOrderConvertService.addOrderLineStatusLog(vvTradeOrderLineEntity.getId(),
                    ReverseStatusEnums.buyer_apply_cancel,
                    request.getBuyerId(),
                    request.getBuyerName()
                    , request.getReason()
            );
        }
        return R.ok();
    }


    // /app/order/shipped
    @Describe("买家签收")
    @RequestMapping("/shipped")
    @AppRealyLogin
    public R shipped(@RequestBody VvTradeOrderShippedDTO request) {
        List<VvTradeOrderLineEntity> vvTradeOrderLineEntityList = vvTradeOrderLineDao.selectVvTradeOrderLineByTrackNumber(request.getTrackNumber());
        for (VvTradeOrderLineEntity tradeOrderLineEntity : vvTradeOrderLineEntityList) {
            if (AbstractOrderAction.checkFailed(tradeOrderLineEntity, true, ActionEnums.App_Shipped)) {
                return R.error("订单状态不对");
            }
        }
        for (VvTradeOrderLineEntity tradeOrderLineEntity : vvTradeOrderLineEntityList) {
            tradeOrderLineEntity.setStatus(OrderStatusEnums.shipped.getStatus());
            tradeOrderLineEntity.setGmtDelivered(new Date());
            tradeOrderLineEntity.setDeliveredUser(request.getBuyerId() + "");
            vvTradeOrderLineDao.updateVvTradeOrderLineById(tradeOrderLineEntity);

            vvTradeOrderConvertService.addOrderLineStatusLog(tradeOrderLineEntity.getId(),
                    OrderStatusEnums.shipped,
                    request.getBuyerId(),
                    request.getBuyerName() + ""
            );
        }
        return R.ok();
    }


    /***
     * 订单 妥投   /app/order/delivered
     */
    @Describe("订单确认收货")
    @RequestMapping("/delivered")
    @AppRealyLogin
    public R delivered(@RequestBody AppDeliveredDTO vvDeliveredDTO) {
        List<VvTradeOrderLineEntity> vvTradeOrderLineEntityList = vvTradeOrderLineDao.selectVvTradeOrderLineByTrackNumberBuyerId(
                vvDeliveredDTO.getTrackNumber(),
                vvDeliveredDTO.getBuyerId()
        );

        for (VvTradeOrderLineEntity tradeOrderLineEntity : vvTradeOrderLineEntityList) {
            if (AbstractOrderAction.checkFailed(tradeOrderLineEntity, true, ActionEnums.App_Delivered)) {
                return R.error("订单状态不对,status:" + tradeOrderLineEntity.getStatus());
            }
        }

        for (VvTradeOrderLineEntity tradeOrderLineEntity : vvTradeOrderLineEntityList) {
            tradeOrderLineEntity.setStatus(OrderStatusEnums.delivered.getStatus());
            tradeOrderLineEntity.setGmtDelivered(new Date());
            tradeOrderLineEntity.setDeliveredUser(vvDeliveredDTO.getBuyerId() + "");
            vvTradeOrderLineDao.updateVvTradeOrderLineById(tradeOrderLineEntity);

            vvTradeOrderConvertService.addOrderLineStatusLog(
                    tradeOrderLineEntity.getId(),
                    OrderStatusEnums.delivered,
                    vvDeliveredDTO.getBuyerId(),
                    vvDeliveredDTO.getBuyerName()
            );
        }
        return R.ok();
    }

    /***
     * 订单关闭   https://api.1024api.com/api-interface/app/order/close
     */
    @Describe("订单关闭")
    @RequestMapping("/close")
    @AppRealyLogin
    public R close(@RequestBody AppCloseDTO appCloseDTO) {
        List<VvTradeOrderLineEntity> vvTradeOrderLineEntityList = vvTradeOrderLineDao.selectVvTradeOrderLineByTradeOrderId(appCloseDTO.getTradeOrderId());
        for (VvTradeOrderLineEntity tradeOrderLineEntity : vvTradeOrderLineEntityList) {
            if (AbstractOrderAction.checkFailed(tradeOrderLineEntity, true, ActionEnums.App_Close)) {
                return R.error("订单状态不对,当前状态：" + tradeOrderLineEntity.getStatus());
            }
        }
        for (VvTradeOrderLineEntity tradeOrderLineEntity : vvTradeOrderLineEntityList) {
            tradeOrderLineEntity.setStatus(OrderStatusEnums.close.getStatus());
            tradeOrderLineEntity.setGmtClose(new Date());
            tradeOrderLineEntity.setCloseUser(appCloseDTO.getTradeOrderId() + "");
            tradeOrderLineEntity.setCloseReason(appCloseDTO.getReason());
            vvTradeOrderLineDao.updateVvTradeOrderLineById(tradeOrderLineEntity);

            vvTradeOrderConvertService.addOrderLineStatusLog(
                    tradeOrderLineEntity.getId(),
                    OrderStatusEnums.close,
                    appCloseDTO.getBuyerId(),
                    appCloseDTO.getBuyerName(),
                    appCloseDTO.getReason()
            );
        }
        jsApiPrepay.close(appCloseDTO.getTradeOrderId());
        return R.ok();
    }


}
