package com.liquidnet.service.goblin.service.impl;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.type.TypeReference;
import com.liquidnet.commons.lang.util.*;
import com.liquidnet.service.adam.dto.vo.AdamAddressesVo;
import com.liquidnet.service.adam.dto.vo.AdamRscPolymer01Vo;
import com.liquidnet.service.base.*;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.goblin.constant.GoblinStatusConst;
import com.liquidnet.service.goblin.dto.manage.GoblinOrderParam;
import com.liquidnet.service.goblin.dto.manage.GoblinOrderSkuParam;
import com.liquidnet.service.goblin.dto.manage.GoblinOrderStoreParam;
import com.liquidnet.service.goblin.dto.vo.*;
import com.liquidnet.service.goblin.param.*;
import com.liquidnet.service.goblin.entity.GoblinOrderAttr;
import com.liquidnet.service.goblin.entity.GoblinOrderSku;
import com.liquidnet.service.goblin.entity.GoblinStoreOrder;
import com.liquidnet.service.goblin.service.GoblinCouponService;
import com.liquidnet.service.goblin.service.IGoblinOrderService;
import com.liquidnet.service.goblin.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

import static com.liquidnet.commons.lang.util.DateUtil.DTF_YMD_HMS;
import static com.liquidnet.commons.lang.util.DateUtil.getNowTime;

@Service
@Slf4j
public class GoblinOrderServiceImpl implements IGoblinOrderService {

    @Autowired
    GoblinRedisUtils redisUtils;
    @Autowired
    GoblinMongoUtils mongoUtils;
    @Autowired
    QueueUtils queueUtils;
    @Autowired
    GoblinOrderUtils orderUtils;
    @Autowired
    GoblinCouponService goblinCouponService;

    @Value("${liquidnet.service.order.url-pay.pay}")
    private String payUrl;
    @Value("${liquidnet.service.order.url-pay.check}")
    private String checkUrl;
    @Value("${liquidnet.service.order.url-pay.goblinUrl}")
    private String synUrl;

    @Override
    public ResponseDto<GoblinPayInnerResultVo> checkOrder(GoblinOrderParam param, String uid) {
        List<String> skuAndPreListAndNumber = CollectionUtil.arrayListString();
        List<String> platformCodeList = CollectionUtil.arrayListString();
        List<String> storeCodeList = CollectionUtil.arrayListString();

        List<GoblinOrderSqlParam> orderSqlParams = ObjectUtil.getGoblinOrderSqlParamArrayListList();

        String orderMasterCode = IDGenerator.storeMasterCode();//总订单id
        GoblinOrderPreParam preParam = GoblinOrderPreParam.getNew();
        preParam.setAuthCode(param.getAuthCode());
        preParam.setPayType(param.getPayType());
        preParam.setDeviceFrom(param.getDeviceFrom());
        preParam.setOpenId(param.getOpenId());
        preParam.setReturnUrl(param.getReturnUrl());
        preParam.setShowUrl(param.getShowUrl());
        preParam.setOrderMasterCode(orderMasterCode);
        preParam.setExpireTime(5);
        preParam.setPriceActual(BigDecimal.ZERO);
        preParam.setStoreName("");
        preParam.setSkuName("");
        preParam.setOrderIdList("");
        try {
            List<GoblinOrderStoreParam> goblinOrderStoreParamList = param.getGoblinOrderStoreParamList();//分订单
            //获取用户相关
            String addressId;
            if (param.getAddressIds() == null || param.getAddressIds().size() == 0) {
                addressId = "";
            } else {
                addressId = StringUtils.join(param.getAddressIds(), ",");
            }
            AdamRscPolymer01Vo userVo = null;
            if (noZhengzaiOrder(uid)) {
                userVo = orderUtils.adamAddressEnterMember(uid, null, addressId);
            }
            AdamAddressesVo addressesVo;
            boolean isMember;
            if (userVo == null) {
                isMember = false;
                addressesVo = null;
            } else {
                addressesVo = userVo.getAddressesVo();
                switch (userVo.getMembership()) {
                    case 10:
                    case 11:
                        isMember = true;
                        break;
                    default:
                        isMember = false;
                        break;
                }
            }
            for (GoblinOrderStoreParam storeParam : goblinOrderStoreParamList) {//商铺维度循环
                String orderId = IDGenerator.nextSnowId();
                String orderCode = IDGenerator.storeCode(orderId);
                for (GoblinOrderSkuParam skuParam : storeParam.getGoblinOrderSkuParamArrayList()) {//商品维度循环
                    String skuId = skuParam.getSkuId();
                    int number = skuParam.getNumber();
                    GoblinGoodsSkuInfoVo skuVo = redisUtils.getGoodsSkuInfoVo(skuId);
                    if (!(skuVo.getStatus().equals("3") && skuVo.getShelvesStatus().equals("3")) || skuVo.getDelFlg().equals("1")) {
                        throw new Exception("不可购买");
                    }
                    // 判断库存
                    String pre = GoblinStatusConst.MarketPreStatus.getPre(skuId);
                    int limitCount = skuVo.getBuyLimit() == 0 ? Integer.MAX_VALUE : skuVo.getBuyLimit();
                    //判断限购
                    if (noZhengzaiOrder(uid)) {
                        String res1 = orderUtils.judgeOrderLimit(uid, skuId, number, limitCount);
                        if (!res1.equals("")) {
                            throw new Exception("已超出限购数量");
                        }
                        //权限限购
                        Boolean res2 = orderUtils.judgeOrderRose(isMember, skuId, StringUtils.defaultString(((String) CurrentUtil.getTokenClaims().get("mobile")), ""), Integer.parseInt(skuVo.getBuyFactor()));
                        if (!res2) {
                            throw new Exception("无权购买");
                        }
                    }
                    int surplusGeneral = redisUtils.decrSkuStock(pre, skuId, number);

                    skuAndPreListAndNumber.add(skuId + "," + pre + "," + number);
                    //库存回滚
                    if (surplusGeneral < 0) {
                        throw new Exception("库存不足");
                    }
                }//GoblinOrderSkuParam
                //下单
                GoblinOrderPreParam pre = order(param, storeParam, uid, isMember, addressesVo, orderMasterCode, orderId, orderCode, platformCodeList, storeCodeList);
                preParam.setPriceActual(preParam.getPriceActual().add(pre.getPriceActual()));
                preParam.setStoreName(preParam.getStoreName() + "," + pre.getStoreName());
                preParam.setSkuName(preParam.getSkuName() + "," + pre.getSkuName());
                preParam.setOrderIdList(preParam.getOrderIdList() + "," + pre.getOrderIdList());

                GoblinOrderSqlParam sqlParam = GoblinOrderSqlParam.getNew();
                sqlParam.setStoreOrder(pre.getStoreOrder());
                sqlParam.setOrderAttr(pre.getOrderAttr());
                sqlParam.setOrderSkuList(pre.getOrderSkuList());
                orderSqlParams.add(sqlParam);
            }//GoblinOrderStoreParam
            if (preParam.getOrderIdList().equals("")) {
                throw new Exception("参数异常");
            }
            return payOrder(preParam, orderSqlParams, uid);
        } catch (Exception e) {
            log.error("Kylin Order Pay Error = {}", e);
            //回顾限购 回滚库存
            for (String item : skuAndPreListAndNumber) {
                String[] array = item.split(",");
                String skuId = array[0];
                String pre = array[1];
                int number = Integer.parseInt(array[2]);
                redisUtils.incrSkuStock(pre, skuId, number);
                if (noZhengzaiOrder(uid)) {
                    redisUtils.decrSkuCountByUid(uid, skuId, number);
                }
                log.error("回滚库存 skuId:{}", skuId);
            }
            //回退平台券
            for (String platformCode : platformCodeList) {
                orderUtils.backCoupon(platformCode, uid);
            }
            //回退店铺券
            List<BackCouponParam> params = ObjectUtil.getBackCouponParam();
            for (String storeCode : storeCodeList) {
                BackCouponParam backCouponParam = BackCouponParam.getNew();
                backCouponParam.setuCouponIds(storeCode);
                backCouponParam.setUid(uid);
                params.add(backCouponParam);
            }
            if (params.size() > 0) {
                goblinCouponService.backCoupon(params);
            }

            if (e.getMessage() == null) {
                return ResponseDto.failure(ErrorMapping.get("20018"));//乱七八糟异常
            } else if (e.getMessage().equals("无权购买")) {
                return ResponseDto.failure(e.getMessage());
            } else if (e.getMessage().equals("平台券不可用")) {
                return ResponseDto.failure(e.getMessage());
            } else if (e.getMessage().equals("店铺券不可用")) {
                return ResponseDto.failure(e.getMessage());
            } else if (e.getMessage().equals("不可购买")) {
                return ResponseDto.failure(e.getMessage());
            } else if (e.getMessage().equals("参数异常")) {
                return ResponseDto.failure(e.getMessage());
            } else if (e.getMessage().equals("库存不足")) {
                return ResponseDto.failure(e.getMessage());
            } else if (e.getMessage().equals("已超出限购数量")) {
                return ResponseDto.failure(e.getMessage());
            } else {
                return ResponseDto.failure(ErrorMapping.get("20018"));//乱七八糟异常
            }
        }
    }

    private GoblinOrderPreParam order(GoblinOrderParam param, GoblinOrderStoreParam storeParam, String uid, boolean isMember, AdamAddressesVo addressesVo, String orderMasterCode, String orderId, String orderCode, List<String> platformCodeList, List<String> storeCodeList) throws Exception {
        String platVoucherCode = storeParam.getPlatVoucherCode();
        String storeVoucherCode = storeParam.getStoreVoucherCode();
        String storeId = storeParam.getStoreId();
        Map token = CurrentUtil.getTokenClaims();
        String headerCliSource = CurrentUtil.getHeaderCliSource(), headerCliVersion = CurrentUtil.getHeaderCliVersion();
        String source = headerCliSource == null ? "" : headerCliSource;
        String version = headerCliVersion == null ? "" : headerCliVersion;
        LocalDateTime now = LocalDateTime.now();
        String skuName = "";
        BigDecimal price;//sku应付价格
        BigDecimal priceBase;//sku原价
        BigDecimal storeTotalPrice = BigDecimal.ZERO;//订单总金额
        BigDecimal voucherMarket = BigDecimal.ZERO;//活动优惠金额
        String writeOffCode = ""; //取货码
        List<GoblinOrderSku> goblinOrderSkuList = ObjectUtil.getGoblinOrderSkuArrayList();
        String marketId = "";
        String marketType = "";
        for (GoblinOrderSkuParam skuParam : storeParam.getGoblinOrderSkuParamArrayList()) {
            String pre = GoblinStatusConst.MarketPreStatus.getPre(skuParam.getSkuId());
            GoblinGoodsSkuInfoVo skuVo = redisUtils.getGoodsSkuInfoVo(skuParam.getSkuId());
            GoblinGoodsInfoVo spuVo = redisUtils.getGoodsInfoVo(skuParam.getSpuId());
            marketId = spuVo.getMarketId();
            marketType = pre;
            skuName = skuName.concat(skuVo.getName()).concat(",");
            if (pre != null && pre.equals(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue())) {
                writeOffCode = "EMPTY";
            }
            //获得 活动原价
            price = skuVo.getPrice();
            if (isMember) {
                price = skuVo.getPriceMember();
            }
            //活动价格
            if (pre != null) {
                GoblinGoodsSkuInfoVo skuMarketVo = redisUtils.getGoodsSkuInfoVo(skuParam.getSkuId().split(pre)[0]);
                priceBase = skuMarketVo.getPrice();
                if (isMember) {
                    priceBase = skuMarketVo.getPriceMember();
                }
            } else {
                priceBase = skuVo.getPrice();
                if (isMember) {
                    priceBase = skuVo.getPriceMember();
                }
            }
            //获得活动优惠价格
            priceBase = priceBase.multiply(BigDecimal.valueOf(skuParam.getNumber()));
            price = price.multiply(BigDecimal.valueOf(skuParam.getNumber()));
            voucherMarket = voucherMarket.add(priceBase.subtract(price));
            storeTotalPrice = storeTotalPrice.add(price);
            //订单sku
            GoblinOrderSku orderSku = GoblinOrderSku.getNew();
            orderSku.setOrderSkuId(IDGenerator.nextTimeId2());
            orderSku.setOrderId(orderId);
            orderSku.setStatus(GoblinStatusConst.Status.ORDER_STATUS_0.getValue());
            orderSku.setSpuId(skuParam.getSpuId());
            orderSku.setSpuName(spuVo.getName());
            orderSku.setSkuId(skuParam.getSkuId());
            orderSku.setNum(skuParam.getNumber());
            orderSku.setSkuPrice(priceBase);
            orderSku.setSkuPriceActual(price);
            orderSku.setSkuName(skuVo.getName());
            orderSku.setSkuNo(skuVo.getSkuNo());
            orderSku.setSkuImage(skuVo.getSkuPic());
            orderSku.setSkuSpecs(JSON.toJSONString(skuVo.getSkuSpecList()));
            orderSku.setPriceVoucher(priceBase.subtract(price));
            orderSku.setCreatedAt(now);
            orderSku.setSpuName(spuVo.getName());
            orderSku.setSpuPic(spuVo.getCoverPic());
            goblinOrderSkuList.add(orderSku);
        }
        //优惠券
        BigDecimal voucherPrice = BigDecimal.ZERO;
        if (platVoucherCode != null && !platVoucherCode.equals("")) {
            TempCouponVo tempCouponVo = redisUtils.getTempCoupon(platVoucherCode);
            String spuIds = "";
            for (GoblinOrderSkuParam item : storeParam.getGoblinOrderSkuParamArrayList()) {
                String pre = GoblinStatusConst.MarketPreStatus.getPre(item.getSpuId());
                if (pre != null) {
                    spuIds = spuIds.concat(item.getSpuId().split(pre)[0] + ",");
                } else {
                    spuIds = spuIds.concat(item.getSpuId() + ",");
                }
            }
            if (tempCouponVo != null) {
                for (String spuId : spuIds.split(",")) {
                    if (tempCouponVo.getSpuIdList().contains(spuId)) {
                        voucherPrice = tempCouponVo.getValue();
                        break;
                    }
                }
            } else {
                HashMap<String, Object> hashMap = orderUtils.useCoupon(platVoucherCode, "购买商品[" + orderCode + "]", storeTotalPrice, spuIds, uid);
                voucherPrice = (BigDecimal) hashMap.get("voucher");
                Integer typeVoucher = (Integer) hashMap.get("type");
                if (typeVoucher.equals(-1)) {
                    throw new Exception("平台券不可用");
                } else {
                    platformCodeList.add(platVoucherCode);
                }
            }
        }
        //商铺券
        BigDecimal storeVoucherPrice = BigDecimal.ZERO;
        if (storeVoucherCode != null && !storeVoucherCode.equals("")) {
            String spuIds = "";
            for (GoblinOrderSkuParam item : storeParam.getGoblinOrderSkuParamArrayList()) {
                String pre = GoblinStatusConst.MarketPreStatus.getPre(item.getSpuId());
                if (pre != null) {
                    spuIds = spuIds.concat(item.getSpuId().split(pre)[0] + ",");
                } else {
                    spuIds = spuIds.concat(item.getSpuId() + ",");
                }
            }
            GoblinUseResultVo storeCouponVo = goblinCouponService.useCoupon(storeVoucherCode, "购买商品[" + orderCode + "]", storeTotalPrice, spuIds, uid);
            storeVoucherPrice = storeCouponVo.getValue();
            String typeVoucher = storeCouponVo.getCouType();
            if (typeVoucher.equals("-1")) {
                throw new Exception("店铺券不可用");
            } else {
                storeCodeList.add(storeVoucherCode);
            }
        }

        GoblinStoreInfoVo storeInfoVo = redisUtils.getStoreInfoVo(storeId);
        //生成订单
        GoblinStoreOrder storeOrder = GoblinStoreOrder.getNew();
        storeOrder.setMasterOrderCode(orderMasterCode);
        storeOrder.setOrderId(orderId);
        storeOrder.setStoreId(storeId);
        storeOrder.setStoreName(storeInfoVo.getStoreName());
        storeOrder.setOrderCode(orderCode);
        storeOrder.setUserId(uid);
        storeOrder.setUserName(StringUtils.defaultString(((String) token.get("nickname")), ""));
        storeOrder.setUserMobile(StringUtils.defaultString(((String) token.get("mobile")), ""));
        if (addressesVo == null) {
            storeOrder.setPriceExpress(BigDecimal.ZERO);
        } else {
            storeOrder.setPriceExpress(BigDecimal.ZERO);
        }
        storeOrder.setPriceTotal(storeTotalPrice.add(storeOrder.getPriceExpress()));
        storeOrder.setPriceActual(storeOrder.getPriceTotal().subtract(voucherPrice).subtract(storeVoucherPrice));
        storeOrder.setPriceRefund(BigDecimal.ZERO);
        storeOrder.setPriceCoupon(voucherPrice);
        storeOrder.setStorePriceCoupon(storeVoucherPrice);
        storeOrder.setPriceVoucher(voucherPrice.add(storeVoucherPrice).add(voucherMarket));
        storeOrder.setStatus(0);
        storeOrder.setUcouponId(platVoucherCode);
        storeOrder.setStoreCouponId(storeVoucherCode);
        storeOrder.setPayType(param.getPayType());
        storeOrder.setDeviceFrom(param.getDeviceFrom());
        storeOrder.setSource(source);
        storeOrder.setVersion(version);
        storeOrder.setIsMember(isMember ? 1 : 0);
        storeOrder.setOrderType(0);
        storeOrder.setWriteOffCode(writeOffCode);
        if (marketType != null && marketType.equals(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue())) {
            storeOrder.setPayCountdownMinute(1);
        } else {
            storeOrder.setPayCountdownMinute(5);
        }
        storeOrder.setIpAddress(CurrentUtil.getCliIpAddr());
        storeOrder.setCreatedAt(now);
        storeOrder.setMarketId(marketId);
        storeOrder.setMarketType(marketType);

        //订单attr
        GoblinOrderAttr orderAttr = GoblinOrderAttr.getNew();
        orderAttr.setOrderAttrId(IDGenerator.nextTimeId2());
        orderAttr.setOrderId(orderId);
        if (!writeOffCode.equals("EMPTY")) {
            orderAttr.setExpressContacts(addressesVo.getName());
            orderAttr.setExpressAddress(addressesVo.getProvince() + "," + addressesVo.getCounty() + "," + addressesVo.getCity());
            orderAttr.setExpressAddressDetail(addressesVo.getAddress());
            orderAttr.setExpressPhone(addressesVo.getPhone());
            orderAttr.setExpressType(1);
            orderAttr.setCreatedAt(now);
        }
        //返回值
        GoblinOrderPreParam preParam = GoblinOrderPreParam.getNew();
        preParam.setPriceActual(storeOrder.getPriceActual());
        preParam.setStoreName(storeInfoVo.getStoreName());
        preParam.setSkuName(skuName);
        preParam.setOrderIdList(storeOrder.getOrderId());
        preParam.setStoreOrder(storeOrder);
        preParam.setOrderAttr(orderAttr);
        preParam.setOrderSkuList(goblinOrderSkuList);
        return preParam;
    }

    private ResponseDto<GoblinPayInnerResultVo> payOrder(GoblinOrderPreParam preParam, List<GoblinOrderSqlParam> sqlParams, String uid) {
        //是否免费
        boolean isFree = false;
        GoblinPayInnerResultVo payInnerResultVo;
        String payCode;
        if (preParam.getPriceActual().compareTo(BigDecimal.valueOf(0)) > 0 && !preParam.getPayType().equals("huifu")) {
            // 调用支付
            LinkedMultiValueMap<String, String> httpData = CollectionUtil.linkedMultiValueMapStringString();
            httpData.add("type", "PRODUCT");
            httpData.add("price", preParam.getPriceActual().toString());
//            httpData.add("price","0.01");
            httpData.add("name", preParam.getStoreName());
            httpData.add("detail", preParam.getSkuName());
            httpData.add("orderCode", preParam.getOrderMasterCode());
            httpData.add("orderId", preParam.getOrderIdList().substring(1));
            httpData.add("clientIp", CurrentUtil.getCliIpAddr());
            httpData.add("notifyUrl", synUrl);
            httpData.add("createDate", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            httpData.add("expireTime", preParam.getExpireTime() + "");
            httpData.add("payType", preParam.getPayType());
            httpData.add("deviceFrom", preParam.getDeviceFrom());

            if (preParam.getDeviceFrom().equals("micropay")) {
                httpData.add("authCode", preParam.getAuthCode());
            }
            if (preParam.getDeviceFrom().equals("js") || preParam.getDeviceFrom().equals("applet")) {
                httpData.add("openId", preParam.getOpenId());
            }
            if (preParam.getPayType().equals("alipay") && preParam.getDeviceFrom().equals("wap")) {
                httpData.add("showUrl", preParam.getShowUrl() + preParam.getOrderMasterCode());
                httpData.add("returnUrl", preParam.getReturnUrl() + preParam.getOrderMasterCode());
            }
            if (preParam.getPayType().equals("douyinpay")) {
                httpData.add("showUrl", preParam.getShowUrl() + preParam.getOrderMasterCode());
                httpData.add("returnUrl", preParam.getReturnUrl() + preParam.getOrderMasterCode());
            }
            if (preParam.getPayType().equals("unionpay")) {
                httpData.add("returnUrl", preParam.getReturnUrl() + preParam.getOrderMasterCode());
            }
            LinkedMultiValueMap<String, String> header = CollectionUtil.linkedMultiValueMapStringString();
            header.add("Accept", "application/json;charset=UTF-8");
            String returnData = HttpUtil.post(payUrl, httpData, header);
            log.info("调用 DRAGON 结果 = " + returnData);
            ResponseDto<GoblinPayInnerResultVo> dto = JsonUtils.fromJson(returnData, new TypeReference<ResponseDto<GoblinPayInnerResultVo>>() {
            });
            payInnerResultVo = GoblinPayInnerResultVo.getNew();
            payInnerResultVo.setCode(dto.getData().getCode());
            payInnerResultVo.setOrderCode(dto.getData().getOrderCode());
            payInnerResultVo.setPayData(dto.getData().getPayData());
            payInnerResultVo.setPayType(preParam.getPayType());
            payInnerResultVo.setPrice(preParam.getPriceActual());
            payCode = payInnerResultVo.getCode();
            payInnerResultVo.setShowUrl(preParam.getShowUrl());
            payInnerResultVo.setReturnUrl(preParam.getReturnUrl());
        } else if (preParam.getPayType().equals("huifu")) {
            isFree = true;
            preParam.setPayType("huifu");
            payCode = "HUIFU_PAY_CODE";
            payInnerResultVo = GoblinPayInnerResultVo.getNew();
            payInnerResultVo.setPrice(preParam.getPriceActual());
            payInnerResultVo.setPayType(preParam.getPayType());
        } else {
            isFree = true;
            preParam.setPayType("FREE");
            payCode = "FREE_PAY_CODE";
            payInnerResultVo = GoblinPayInnerResultVo.getNew();
            payInnerResultVo.setPrice(BigDecimal.valueOf(0));
            payInnerResultVo.setPayType(preParam.getPayType());
        }

        payInnerResultVo.setOrderMasterCode(preParam.getOrderMasterCode());

        LinkedList<String> sqls = CollectionUtil.linkedListString();
        sqls.add(SqlMapping.get("goblin.order.create.sku_insert"));
        sqls.add(SqlMapping.get("goblin.order.create.order_insert"));
        sqls.add(SqlMapping.get("goblin.order.create.attr_insert"));
        for (GoblinOrderSqlParam item : sqlParams) {
            List<String> goblinOrderSkuIdList = CollectionUtil.linkedListString();
            LinkedList<Object[]> sqlDataSku = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> sqlDataOrder = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> sqlDataAttr = CollectionUtil.linkedListObjectArr();
            for (GoblinOrderSku orderSku : item.getOrderSkuList()) {
                sqlDataSku.add(new Object[]{
                        orderSku.getOrderSkuId(), orderSku.getOrderId(), orderSku.getSpuId(), orderSku.getSpuName(), orderSku.getSpuPic(), orderSku.getSkuId(), orderSku.getNum(), orderSku.getSkuPrice(), orderSku.getSkuPriceActual(), orderSku.getSkuName(),
                        orderSku.getSkuNo(), orderSku.getSkuImage(), orderSku.getSkuSpecs(), orderSku.getPriceVoucher(), orderSku.getCreatedAt()
                });
                //订单 orderSku Vo
                GoblinOrderSkuVo orderSkuVo = GoblinOrderSkuVo.getNew();
                BeanUtils.copyProperties(orderSku, orderSkuVo);
                redisUtils.setGoblinOrderSku(orderSkuVo.getOrderSkuId(), orderSkuVo);
                mongoUtils.insertGoblinOrderSkuVo(orderSkuVo);
                goblinOrderSkuIdList.add(orderSkuVo.getOrderSkuId());
            }
            GoblinStoreOrder storeOrder = item.getStoreOrder();
            storeOrder.setPayCode(payCode);
            sqlDataOrder.add(new Object[]{
                    storeOrder.getMasterOrderCode(), storeOrder.getOrderId(), storeOrder.getStoreId(), storeOrder.getStoreName(), storeOrder.getOrderCode(), storeOrder.getUserId(), storeOrder.getUserName(), storeOrder.getUserMobile(), storeOrder.getPriceTotal(), storeOrder.getPayCode(),
                    storeOrder.getPriceActual(), storeOrder.getPriceRefund(), storeOrder.getPriceExpress(), storeOrder.getPriceCoupon(), storeOrder.getStorePriceCoupon(), storeOrder.getPriceVoucher(), storeOrder.getStatus(), storeOrder.getUcouponId(), storeOrder.getStoreCouponId(), storeOrder.getPayType(), storeOrder.getDeviceFrom(),
                    storeOrder.getSource(), storeOrder.getVersion(), storeOrder.getIsMember(), storeOrder.getOrderType(), storeOrder.getWriteOffCode(), storeOrder.getPayCountdownMinute(), storeOrder.getIpAddress(), storeOrder.getMarketId(), storeOrder.getMarketType(), storeOrder.getCreatedAt()
            });
            GoblinOrderAttr orderAttr = item.getOrderAttr();
            sqlDataAttr.add(new Object[]{
                    orderAttr.getOrderAttrId(), orderAttr.getOrderId(), orderAttr.getExpressContacts(), orderAttr.getExpressAddress(), orderAttr.getExpressAddressDetail(), orderAttr.getExpressPhone(), orderAttr.getExpressType(), orderAttr.getCreatedAt()
            });

            //订单vo
            GoblinStoreOrderVo orderVo = GoblinStoreOrderVo.getNew();
            BeanUtils.copyProperties(storeOrder, orderVo);
            //订单attr vo
            GoblinOrderAttrVo orderAttrVo = GoblinOrderAttrVo.getNew();
            BeanUtils.copyProperties(orderAttr, orderAttrVo);
            //redis 添加未支付列表
            int randomKey = redisUtils.addUnPayOrder(orderVo.getOrderId());
            //redis 赋值
            orderVo.setRandomKey(randomKey);
            orderVo.setOrderAttrVo(orderAttrVo);
            orderVo.setOrderSkuVoIds(goblinOrderSkuIdList);
            orderVo.setCreatedAt(getNowTime());
            redisUtils.setGoblinOrder(orderVo.getOrderId(), orderVo);
            redisUtils.setMasterCode(preParam.getOrderMasterCode(), preParam.getOrderIdList().substring(1));
            mongoUtils.insertGoblinStoreOrderVo(orderVo);
            //redis 订单列表
            if (noZhengzaiOrder(uid)) {
                if (orderVo.getMarketType() == null) {
                    redisUtils.addOrderList(uid, orderVo.getOrderId());
                } else if (orderVo.getMarketType().equals(GoblinStatusConst.MarketPreStatus.MARKET_PRE_ZHENGZAI.getValue())) {
                    redisUtils.addZhengzaiOrderList(uid, orderVo.getOrderId());
                }
            }
            //mysql  执行sql
            String sqlData = SqlMapping.gets(sqls, sqlDataSku, sqlDataOrder, sqlDataAttr);
            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_ORDER_CREATE_PAY.getKey(), sqlData);
        }
        log.info(UserPathDto.setData("下单(唤起支付)", preParam, payInnerResultVo));
        if (isFree && preParam.getPayType().equals("huifu")) {
            return ResponseDto.success(payInnerResultVo);
        } else if (isFree) {
            SyncOrderParam syncOrderParam = SyncOrderParam.getNew();
            syncOrderParam.setOrderCode(preParam.getOrderMasterCode());
            syncOrderParam.setPaymentAt(DateUtil.format(LocalDateTime.now(), DateUtil.Formatter.yyyyMMddHHmmss));
            syncOrderParam.setCode(payCode);
            syncOrderParam.setPrice(preParam.getPriceActual());
            syncOrderParam.setPaymentId("FREE_PAYMENT_ID");
            syncOrderParam.setPaymentType(null);
            syncOrderParam.setStatus(1);
            syncOrder(syncOrderParam);
            return ResponseDto.success(payInnerResultVo);
        } else {
            return ResponseDto.success(payInnerResultVo);
        }
    }

    @Override
    public ResponseDto<GoblinPayInnerResultVo> payAgain(PayAgainParam param) {
        String uid = CurrentUtil.getCurrentUid();
        LocalDateTime now = LocalDateTime.now();
        //检查订单时间 是否关闭
        GoblinStoreOrderVo storeOrderVo = redisUtils.getGoblinOrder(param.getOrderId());
        if (!storeOrderVo.getUserId().equals(uid)) {
            return ResponseDto.failure(ErrorMapping.get("20003"));
        }
        if (storeOrderVo == null) {
            return ResponseDto.failure("订单不存在");
        }

        if (storeOrderVo.getStatus() != GoblinStatusConst.Status.ORDER_STATUS_0.getValue()) {
            return ResponseDto.failure("订单无法支付");//订单
        }
        MultiValueMap<String, String> header = CollectionUtil.linkedMultiValueMapStringString();
        header.add("Accept", "application/json;charset=UTF-8");
        String returnCheckData = HttpUtil.get(checkUrl + "?code=" + storeOrderVo.getPayCode(), null, header);
        ResponseDto<GoblinPayInnerResultVo> checkVo = JsonUtils.fromJson(returnCheckData, new TypeReference<ResponseDto<GoblinPayInnerResultVo>>() {
        });
        if (checkVo.getData().getStatus() == 1) {
            return ResponseDto.failure("订单已支付");
        }
        GoblinPayInnerResultVo payInnerResultVo = GoblinPayInnerResultVo.getNew();
//        if (!storeOrderVo.getPayType().equals("FREE") && storeOrderVo.getPayType().equals(param.getPayType()) && storeOrderVo.getDeviceFrom().equals(param.getDeviceFrom())) {
//            payInnerResultVo.setCode(checkVo.getData().getCode());
//            payInnerResultVo.setOrderCode(checkVo.getData().getOrderCode());
//            payInnerResultVo.setPayData(checkVo.getData().getPayData());
//            payInnerResultVo.setOrderId(param.getOrderId());
//            payInnerResultVo.setPayType(param.getPayType());
//            payInnerResultVo.setPrice(storeOrderVo.getPriceActual());
//            storeOrderVo.setPayCode(payInnerResultVo.getCode());
//            payInnerResultVo.setShowUrl(param.getShowUrl() + storeOrderVo.getOrderId());
//            payInnerResultVo.setReturnUrl(param.getReturnUrl() + storeOrderVo.getOrderId());
//            log.info(UserPathDto.setData("再次支付[原支付方式]", param, payInnerResultVo));
//        } else
        if (!storeOrderVo.getPayType().equals("FREE")) {
            // 调用支付
            LinkedMultiValueMap<String, String> httpData = CollectionUtil.linkedMultiValueMapStringString();
            httpData.add("type", "PRODUCT");
            httpData.add("price", storeOrderVo.getPriceActual().toString());
            httpData.add("name", redisUtils.getStoreInfoVo(storeOrderVo.getStoreId()).getStoreName());
            httpData.add("detail", "查找最初订单");
            httpData.add("orderCode", storeOrderVo.getMasterOrderCode());
//            httpData.add("orderId", storeOrderVo.getOrderId());
            httpData.add("clientIp", storeOrderVo.getIpAddress());
            httpData.add("notifyUrl", synUrl);
            httpData.add("createDate", storeOrderVo.getCreatedAt());
            httpData.add("expireTime", storeOrderVo.getPayCountdownMinute().toString());
            httpData.add("payType", storeOrderVo.getPayType());
            httpData.add("deviceFrom", param.getDeviceFrom());
            if (param.getDeviceFrom().equals("js") || param.getDeviceFrom().equals("applet")) {
                httpData.add("openId", param.getOpenId());
            }
            if (param.getPayType().equals("alipay") && param.getDeviceFrom().equals("wap")) {
                httpData.add("showUrl", param.getShowUrl() + storeOrderVo.getOrderId());
                httpData.add("returnUrl", param.getReturnUrl() + storeOrderVo.getOrderId());
            }
            if (param.getPayType().equals("douyinpay")) {
                httpData.add("showUrl", param.getShowUrl() + storeOrderVo.getOrderId());
                httpData.add("returnUrl", param.getReturnUrl() + storeOrderVo.getOrderId());
            }
            if (param.getPayType().equals("unionpay")) {
                httpData.add("returnUrl", param.getReturnUrl() + storeOrderVo.getOrderId());
            }
            String returnData = HttpUtil.post(payUrl, httpData);
            log.info("调用 DRAGON 结果 = " + returnData);
            ResponseDto<GoblinPayInnerResultVo> dto = JsonUtils.fromJson(returnData, new TypeReference<ResponseDto<GoblinPayInnerResultVo>>() {
            });
            payInnerResultVo.setCode(dto.getData().getCode());
            payInnerResultVo.setOrderCode(dto.getData().getOrderCode());
            payInnerResultVo.setPayData(dto.getData().getPayData());
            payInnerResultVo.setOrderId(storeOrderVo.getOrderId());
            payInnerResultVo.setPayType(storeOrderVo.getPayType());
            payInnerResultVo.setPrice(storeOrderVo.getPriceActual());
            storeOrderVo.setPayCode(payInnerResultVo.getCode());
            payInnerResultVo.setShowUrl(param.getShowUrl() + storeOrderVo.getOrderId());
            payInnerResultVo.setReturnUrl(param.getReturnUrl() + storeOrderVo.getOrderId());
            //mysql
            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_ORDER_AGAIN.getKey(),
                    SqlMapping.get("goblin_order.pay.again", param.getPayType(), param.getDeviceFrom(), payInnerResultVo.getCode(), param.getOrderId(), now, now));
            log.info(UserPathDto.setData("再次支付[新支付方式]", param, payInnerResultVo));
        }
        return ResponseDto.success(payInnerResultVo);
    }

    @Override
    public String syncOrder(SyncOrderParam syncOrderParam) {
        log.debug("SYNC PARAM = " + syncOrderParam.toString());
        //支付时间
        LocalDateTime now = LocalDateTime.now();
        String[] array = redisUtils.getMasterCode(syncOrderParam.getOrderCode());
        String uid = "0";
        BigDecimal priceActual = BigDecimal.ZERO;
        for (String orderId : array) {
            GoblinStoreOrderVo orderVo = redisUtils.getGoblinOrder(orderId);
            priceActual = priceActual.add(orderVo.getPriceActual());
            uid = orderVo.getUserId();
            if (orderVo == null) {
                log.error("订单号：" + syncOrderParam.getOrderCode() + " 订单不存在");
                return "fail";//订单不存在
            }
            if (orderVo.getStatus() != GoblinStatusConst.Status.ORDER_STATUS_0.getValue()) {
                if (orderVo.getPayCode().equals(syncOrderParam.getCode())) {
                    log.error("订单号：" + syncOrderParam.getOrderCode() + " 重复支付");
                    return "fail";//重复支付
                }
            }
//            if (orderVo.getPriceActual().compareTo(syncOrderParam.getPrice()) != 0) {
//                log.error("订单号：" + syncOrderParam.getOrderCode() + " 价格不符");
//                return "fail";//价格不符
//            }
            LinkedList<String> sqls = CollectionUtil.linkedListString();
            LinkedList<Object[]> sqlDataOrder = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> sqlDataSku = CollectionUtil.linkedListObjectArr();
            GoblinStoreOrder storeOrder = GoblinStoreOrder.getNew();
            if (orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_5.getValue() && syncOrderParam.getStatus().equals(1)) {
                log.error("订单号为 {} 的订单超时支付", syncOrderParam.getOrderCode());
                // todo hujiachen 操作超时支付
//                orderVo.setStatus(GoblinStatusConst.OrderStatus.ORDER_STATUS_61.getValue());
//                redisUtils.setGoblinOrder(orderVo.getOrderId(),orderVo);
            } else if ((orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_6.getValue() || orderVo.getStatus() == GoblinStatusConst.Status.ORDER_STATUS_7.getValue()) && syncOrderParam.getStatus().equals(1)) {
                log.error("订单号为 {} 的订单正在退款 或者已退款", syncOrderParam.getOrderCode());
            } else if (syncOrderParam.getStatus().equals(1)) {
                log.error("订单号为 {} 的订单正常流程", syncOrderParam.getOrderCode());
                storeOrder.setPaymentType(syncOrderParam.getPaymentType());
                storeOrder.setPaymentId(syncOrderParam.getPaymentId());
                storeOrder.setPayCode(syncOrderParam.getCode());
                LocalDateTime payTime = LocalDateTime.parse(syncOrderParam.getPaymentAt(), DTF_YMD_HMS);
                storeOrder.setPayTime(payTime);
                if (orderVo.getWriteOffCode().equals("EMPTY")) {
                    storeOrder.setWriteOffCode(IDGenerator.getWriteOffCode());
                } else {
                    storeOrder.setWriteOffCode("");
                }
                storeOrder.setStatus(GoblinStatusConst.Status.ORDER_STATUS_2.getValue());
                storeOrder.setUpdatedAt(now);
                sqls.add(SqlMapping.get("goblin_order.pay.order"));
                sqlDataOrder.add(new Object[]{
                        storeOrder.getPaymentType(), storeOrder.getPaymentId(), storeOrder.getPayCode(), storeOrder.getPayTime(), storeOrder.getWriteOffCode(), storeOrder.getStatus(), storeOrder.getUpdatedAt(),
                        orderId, now, now
                });
                sqls.add(SqlMapping.get("goblin_order.pay.sku"));
                List<String> skuList = orderVo.getOrderSkuVoIds();
                for (String orderSkuVoIds : skuList) {
                    GoblinOrderSkuVo orderSkuVo = redisUtils.getGoblinOrderSkuVo(orderSkuVoIds);
                    //增加销量
                    redisUtils.incrSkuSaleCount(orderSkuVo.getSpuId(), orderSkuVo.getSkuId(), orderSkuVo.getNum());
                    orderSkuVo.setStatus(GoblinStatusConst.Status.ORDER_STATUS_2.getValue());
                    //redis
                    redisUtils.setGoblinOrderSku(orderSkuVo.getOrderSkuId(), orderSkuVo);
                    //mongo
                    mongoUtils.updateGoblinOrderSkuVo(orderSkuVo.getOrderSkuId(), orderSkuVo);
                    //mongo 添加操作日志
                    GoblinOrderLogVo logVo = GoblinOrderLogVo.getNew();
                    logVo.setOrderId(orderVo.getOrderId());
                    logVo.setOrderCode(orderVo.getOrderCode());
                    logVo.setPayCode(orderVo.getPayCode());
                    logVo.setStoreId(orderVo.getStoreId());
                    if (orderSkuVo.getSkuId().indexOf(GoblinStatusConst.MarketPreStatus.MARKET_PRE_PURCHASE.getValue()) > 0) {
                        logVo.setOrderType("zhengzai");
                    } else {
                        logVo.setOrderType("order");
                    }
                    logVo.setSpuId(orderSkuVo.getSpuId());
                    logVo.setSkuId(orderSkuVo.getSkuId());
                    logVo.setSkuPriceActual(orderSkuVo.getSkuPriceActual().multiply(new BigDecimal(100)).longValue());
                    logVo.setStatus(GoblinStatusConst.Status.ORDER_LOG_STATUS_11.getValue());
                    logVo.setRemark(GoblinStatusConst.Status.ORDER_LOG_STATUS_11.getDesc());
                    logVo.setOperationId(uid);
                    logVo.setOperationName(orderVo.getUserName());
                    logVo.setOperationType(GoblinStatusConst.Type.OPERATION_TYPE_1.getValue());
                    logVo.setCreatedAt(LocalDateTime.now());
                    mongoUtils.insertGoblinOrderLogVo(logVo);
                    //mysql
                    sqlDataSku.add(new Object[]{
                            GoblinStatusConst.Status.ORDER_STATUS_2.getValue(), now,
                            orderSkuVo.getOrderSkuId(), now, now
                    });
                }
                //redis
                orderVo.setPayCode(storeOrder.getPayCode());
                orderVo.setPayTime(syncOrderParam.getPaymentAt());
                orderVo.setWriteOffCode(storeOrder.getWriteOffCode());
                orderVo.setStatus(storeOrder.getStatus());
                orderVo.setPaymentId(syncOrderParam.getPaymentId());
                orderVo.setPaymentType(syncOrderParam.getPaymentType());
                orderVo.setOrderSkuVoIds(skuList);
                redisUtils.setGoblinOrder(orderId, orderVo);
                redisUtils.setOffCode(orderVo.getWriteOffCode(), orderVo.getMasterOrderCode());
                //删除未支付订单
                redisUtils.removeGoblinOrder(orderVo.getRandomKey()+"", orderId);
                //mongo
                mongoUtils.updateGoblinStoreOrderVo(orderId, orderVo);
                //mysql
                queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_ORDER_CREATE_PAY.getKey(),
                        SqlMapping.gets(sqls, sqlDataOrder, sqlDataSku));
            }
            //发短信
//            SmsEnum.ADTemplate adTemplate = null;
//            if (orderTicketData.getGetTicketType().equals("express")) {
//                adTemplate = SmsEnum.ADTemplate.SMS_225995308;
//            } else if (orderTicketData.getGetTicketType().equals("electronic")) {
//                adTemplate = ticketData.getIsShowCode() == 1 ? SmsEnum.ADTemplate.SMS_225995308 : SmsEnum.ADTemplate.SMS_225995308;
//            }
//
//            if (null != adTemplate) {
//                queueUtils.sendMsgByRedis(MQConst.KylinQueue.SMS_NOTICE.getKey(),
//                        SmsMessage.builder().setPhone(orderTicketData.getUserMobile())
//                                .setSignName(SmsEnum.ADSignName.M02.getVal())
//                                .setTemplateCode(adTemplate.name())
//                                .setTemplateParam("name", orderTicketData.getPerformanceTitle())
//                                .setTemplateParam("time", time1 + " " + time2).toJson()
//                );
//            }
            //加分
            if (noZhengzaiOrder(uid)) {
                orderUtils.doTask(uid, priceActual);
            }
        }
        return "success";
    }

    @Override
    public ResponseDto<Integer> checkOrderResult(String orderId) {
        String uid = CurrentUtil.getCurrentUid();
        GoblinStoreOrderVo storeOrderVo = redisUtils.getGoblinOrder(orderId);
        if (storeOrderVo == null) {
            return ResponseDto.failure("订单不存在");
        } else {
            if (!storeOrderVo.getUserId().equals(uid)) {
                return null;
            }
            String returnCheckData = HttpUtil.get(checkUrl + "?code=" + storeOrderVo.getPayCode(), null);
            ResponseDto<SyncOrderParam> syncOrderDtoParam = JsonUtils.fromJson(returnCheckData, new TypeReference<ResponseDto<SyncOrderParam>>() {
            });
            if (syncOrderDtoParam.getData().getStatus() == 1) {
                //处理订单
                syncOrder(syncOrderDtoParam.getData());
                return ResponseDto.success(1);
            } else {
                return ResponseDto.success(0);
            }
        }
    }

    @Override
    public ResponseDto<Integer> checkOrderResultMaterCode(String masterCode) {
        String[] orderIds = redisUtils.getMasterCode(masterCode);
        if (orderIds == null) {
            return ResponseDto.failure("订单不存在");
        } else {
            for (String orderId : orderIds) {
                GoblinStoreOrderVo storeOrderVo = redisUtils.getGoblinOrder(orderId);
                String returnCheckData = HttpUtil.get(checkUrl + "?code=" + storeOrderVo.getPayCode(), null);
                ResponseDto<SyncOrderParam> syncOrderDtoParam = JsonUtils.fromJson(returnCheckData, new TypeReference<ResponseDto<SyncOrderParam>>() {
                });
                if (syncOrderDtoParam.getData().getStatus() == 1) {
                    //处理订单
                    syncOrder(syncOrderDtoParam.getData());
                } else {
                    return ResponseDto.success(0);
                }
            }
            return ResponseDto.success(1);
        }
    }

    @Override
    public String refundSyncOrder(RefundCallbackParam refundCallbackParam) {
        LocalDateTime now = LocalDateTime.now();
        String nowStr = DateUtil.getNowTime();
        log.info("refundCallback订单退款回调参数: [RefundCallbackParam={}]", refundCallbackParam);
        GoblinBackOrderVo backOrderVo = mongoUtils.getGoblinBackOrderVoByBackCode(refundCallbackParam.getOrderRefundCode());
        if (backOrderVo == null) {
            log.info("refundCallback: 退款订单查询失败，编号{}", refundCallbackParam.getOrderRefundCode());
            return "fail";
        }
        if (backOrderVo.getStatus() == GoblinStatusConst.Status.ORDER_LOG_STATUS_20.getValue() || backOrderVo.getStatus() == GoblinStatusConst.Status.ORDER_LOG_STATUS_201.getValue()) {
            log.info("refundCallback: 退款订单已取消，编号{}", refundCallbackParam.getOrderRefundCode());
            return "fail";
        }
        if (backOrderVo.getStatus() == GoblinStatusConst.Status.ORDER_LOG_STATUS_22.getValue()) {
            log.info("refundCallback: 退款订单已完成，编号{}", refundCallbackParam.getOrderRefundCode());
            return "success";
        }
        Integer status = refundCallbackParam.getStatus();
        if (1 == status && (backOrderVo.getStatus() == 0 || backOrderVo.getStatus() == 10)) { // 退款成功
            LinkedList<String> sqls = CollectionUtil.linkedListString();
            LinkedList<Object[]> sqlsOrder = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> sqlsOrderSku = CollectionUtil.linkedListObjectArr();
            LinkedList<Object[]> sqlsBackOrder = CollectionUtil.linkedListObjectArr();
            sqls.add(SqlMapping.get("goblin_order.store.refundPrice"));
            sqls.add(SqlMapping.get("goblin_order.store.refundSkuPrice"));
            sqls.add(SqlMapping.get("goblin_order.store.refundBackOrder"));
            String orderId = backOrderVo.getOrderId();
            List<GoblinBackOrderSkuVo> backOrderSkuVos = backOrderVo.getBackOrderSkuVos();
            BigDecimal price = refundCallbackParam.getRefundPrice();
            GoblinStoreOrderVo orderVo = redisUtils.getGoblinOrder(orderId);
            orderVo.setPriceRefund(orderVo.getPriceRefund().add(price));
            if (orderVo.getPriceRefund().compareTo(orderVo.getPriceActual()) >= 0) {
                //整单退款 退券
                orderVo.setStatus(GoblinStatusConst.Status.ORDER_STATUS_6.getValue());
                if (!(orderVo.getUcouponId() == null || orderVo.getUcouponId().equals(""))) {
                    orderUtils.backCoupon(orderVo.getUcouponId(), orderVo.getUserId());
                }

                if (!(orderVo.getStoreCouponId() == null || orderVo.getStoreCouponId().equals(""))) {
                    List<BackCouponParam> params = ObjectUtil.getBackCouponParam();
                    BackCouponParam backCouponParam = BackCouponParam.getNew();
                    backCouponParam.setuCouponIds(orderVo.getStoreCouponId());
                    backCouponParam.setUid(orderVo.getUserId());
                    params.add(backCouponParam);
                    goblinCouponService.backCoupon(params);
                }
            }
            backOrderVo.setStatus(GoblinStatusConst.Status.ORDER_BACK_STATUS_2.getValue());
            backOrderVo.setRefundAt(nowStr);
            for (GoblinBackOrderSkuVo backOrderSkuVo : backOrderSkuVos) {
                GoblinOrderSkuVo orderSkuVo = redisUtils.getGoblinOrderSkuVo(backOrderSkuVo.getOrderSkuId());
                orderSkuVo.setPriceRefund(orderSkuVo.getPriceRefund() == null ? price : orderSkuVo.getPriceRefund().add(price));
                if (orderSkuVo.getPriceRefund().compareTo(orderSkuVo.getSkuPriceActual()) >= 0) {
                    orderSkuVo.setStatus(GoblinStatusConst.Status.ORDER_STATUS_6.getValue());
                    String pre = GoblinStatusConst.MarketPreStatus.getPre(orderSkuVo.getSkuId());
                    String skuId = orderSkuVo.getSkuId();
                    redisUtils.incrSkuStock(pre, skuId, orderSkuVo.getNum());
                    redisUtils.decrSkuCountByUid(orderVo.getUserId(), skuId, orderSkuVo.getNum());
                }
                redisUtils.setGoblinOrderSku(backOrderSkuVo.getOrderSkuId(), orderSkuVo);
                mongoUtils.updateGoblinOrderSkuVo(backOrderSkuVo.getOrderSkuId(), orderSkuVo);
                sqlsOrderSku.add(new Object[]{
                        orderSkuVo.getPriceRefund(), orderSkuVo.getStatus(), now,
                        backOrderSkuVo.getOrderSkuId(), now, now
                });
                GoblinOrderLogVo logVo = GoblinOrderLogVo.getNew();
                logVo.setOrderId(orderVo.getOrderId());
                logVo.setOrderCode(orderVo.getOrderCode());
                logVo.setPayCode(orderVo.getPayCode());
                if (orderSkuVo.getSkuId().indexOf(GoblinStatusConst.MarketPreStatus.MARKET_PRE_PURCHASE.getValue()) > 0) {
                    logVo.setOrderType("zhengzai");
                } else {
                    logVo.setOrderType("order");
                }
                logVo.setStoreId(orderVo.getStoreId());
                logVo.setSpuId(orderSkuVo.getSpuId());
                logVo.setSpuName(backOrderSkuVo.getSpuName());
                logVo.setSkuId(backOrderSkuVo.getSkuId());
                logVo.setSkuPriceActual(price.multiply(BigDecimal.valueOf(100)).negate().longValue());
                logVo.setStatus(GoblinStatusConst.Status.ORDER_LOG_STATUS_22.getValue());
                logVo.setOperationId(backOrderVo.getUserId());
                logVo.setOperationType(GoblinStatusConst.Type.OPERATION_TYPE_2.getValue());
                logVo.setCreatedAt(now);
                mongoUtils.insertGoblinOrderLogVo(logVo);
            }
            //redis
            redisUtils.setGoblinOrder(orderId, orderVo);
            redisUtils.setBackOrderVo(backOrderVo.getBackOrderId(), backOrderVo);
            //mongo
            mongoUtils.updateGoblinStoreOrderVo(orderId, orderVo);
            mongoUtils.updateGoblinBackOrderVo(backOrderVo.getBackOrderId(), backOrderVo);
            //mysql
            sqlsOrder.add(new Object[]{
                    orderVo.getPriceRefund(), orderVo.getStatus(), now,
                    orderId, now, now
            });
            sqlsBackOrder.add(new Object[]{
                    backOrderVo.getStatus(), now, now, backOrderVo.getBackOrderId(), now, now
            });
            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_STORE_ORDER_OPERA.getKey(),
                    SqlMapping.gets(sqls, sqlsOrder, sqlsOrderSku, sqlsBackOrder));
        } else if (0 == status) {

    }
        return"success";
}

    @Override
    public ResponseDto<List<GoblinMailVo>> getMail(String orderId, String mailId) {
        List<GoblinMailVo> voList = redisUtils.getGoblinMail(orderId);
        for (GoblinMailVo vo : voList) {
            if (mailId.equals(vo.getMailId())) {
                List<GoblinOrderSkuVo> orderSkuVos = ObjectUtil.getGoblinOrderSkuVoArrayList();
                for (String orderSkuId : vo.getOrderSkuVoIds()) {
                    GoblinOrderSkuVo orderSkuVo = redisUtils.getGoblinOrderSkuVo(orderSkuId);
                    orderSkuVos.add(orderSkuVo);
                }
                vo.setOrderSkuVos(orderSkuVos);
            }
        }
        return ResponseDto.success(voList);
    }

    private boolean noZhengzaiOrder(String uid) {
        return !uid.equals("zhengzai");
    }
}
