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.AppOrderRequest;
import com.heyu.api.common.annotation.AppLogin;
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.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.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;


@Slf4j
@RestController
@RequestMapping("/app/order")
@AppLogin
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;


    /***
     * https://api.1024api.com/api-interface/app/order/list
     *
     *
     * http://localhost:8888/app/order/list
     *
     * 列表
     * todo quyixiao
     */
    @Describe("订单列表")
    @RequestMapping("/list")
    public R list(@RequestBody AppOrderRequest vvOrderRequest) {
        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(),
                                OrderStatusEnums.delete.getStatus(),
                                vvOrderRequest.getMinCreateTimestamp(),
                                vvOrderRequest.getMaxCreateTimestamp(),
                                vvOrderRequest.getProductName(),
                                vvOrderRequest.getBuyerId(),
                                vvOrderRequest.getReverseStatus(),
                                vvOrderRequest.getCreateTimestampSort()
                        );
                    }
                });

        // 获取子单
        List<VvTradeOrderLineEntity> vvTradeOrderLineEntitiesGroupByTradeOrderId = pageUtils.getRows();
        // 获取订单
        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);

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


    /***
     *  订单添加
     *
     *  http://localhost:8888/app/order/detail
     */
    @Describe("订单详情")
    @RequestMapping("/detail")
    public R detail(@RequestBody AppTradeOrderDetailDTO vvOrderRequest) {
        List<VvTradeOrderLineEntity> vvTradeOrderLineEntities = vvTradeOrderLineDao.selectVvTradeOrderLineByIds(vvOrderRequest.getTradeOrderLineIdList());
        List<String> trackNumbers = SanUtils.field2Set2List(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);
        return R.ok().setData(appPackageDTOList);
    }

    /***
     *  订单添加
     *
     *  http://localhost:8888/app/order/add
     */
    @Describe("添加订单")
    @RequestMapping("/add")
    public R add(@RequestBody VvTradeOrderDTO vvOrderRequest) {
        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) {
                OrderSkuDTO orderSkuDTO = new OrderSkuDTO();
                orderSkuDTO.setSkuId(vvSkuEntity.getId());
                orderSkuDTO.setMessage("库存不足");
                return R.error().setData(orderSkuDTO);
            }
        }

        Map<Long, VvSkuEntity> skuEntityMap = SanUtils.groupByFiled2Map(vvSkuEntities, VvSkuEntity::getId);

        Map<Long, List<VvSkuPropertyValueEntity>> vvSkuPropertyValueMap = SanUtils.groupByFiled2MapList(vvSkuPropertyValueList, VvSkuPropertyValueEntity::getSkuId);

        List<Long> productIdList = SanUtils.field2Set2List(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;
        if (StringUtils.isNotEmpty(activityInfo)) {
            vvActivityDTO = JSONObject.parseObject(activityInfo, VvActivityDTO.class);
        }

        Integer batchNum = SanUtils.sum(vvOrderRequest.getVvTradeOrderLineDTOList(),VvTradeOrderLineDTO::getNum );

        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 (vvActivityDTO != null) {
                    vvTradeOrderLineEntity.setAwardAmount(vvActivityDTO.getAwardAmount());
                    vvTradeOrderLineEntity.setDiscountAmount(vvActivityDTO.getDiscountAmount());
                    payAmount = BigDecimalUtil.subtract(vvSkuEntity.getPromotionPrice(), vvActivityDTO.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);
        for (VvTradeOrderLineEntity tradeOrderLineEntity : vvTradeOrderLineEntityList) {
            tradeOrderLineEntity.setTradeOrderId(vvTradeOrderEntity.getId());
            vvTradeOrderLineDao.insertOrUpdateVvTradeOrderLine(tradeOrderLineEntity);
        }
        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());
        }

        DirectAPIv3JsapiPrepayResponse jsapiPrepayResponse = jsapiPrepay.prePay(vvTradeOrderEntity.getId(),
                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);
            }

            // 发送订单关单的消息
            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;
            });
        }


        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);
    }

    // /app/order/delete
    @Describe("删除订单")
    @RequestMapping("/delete")
    public R add(@RequestBody VvTradeOrderDeleteDTO vvOrderRequest) {
        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() + ""
                );
            }
        }
        return R.ok();
    }


    // /app/order/applyCancel
    @Describe("申请取消")
    @RequestMapping("/applyCancel")
    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.getReason()
            );
        }
        return R.ok();
    }


    // /app/order/shipped
    @Describe("买家签收")
    @RequestMapping("/shipped")
    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() + ""
            );
        }
        return R.ok();
    }


    /***
     * 订单 妥投   /app/order/delivered
     */
    @Describe("订单确认收货")
    @RequestMapping("/delivered")
    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() + ""
            );
        }
        return R.ok();
    }

    /***
     * 订单关闭   https://api.1024api.com/api-interface/app/order/close
     */
    @Describe("订单关闭")
    @RequestMapping("/close")
    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.getReason()
            );
        }
        jsApiPrepay.close(appCloseDTO.getTradeOrderId());
        return R.ok();
    }


}
