package com.liquidnet.service.order.service.impl;

import com.liquidnet.common.third.sqb.biz.SqbBiz;
import com.liquidnet.common.third.sqb.param.callback.CouponCallbackContent;
import com.liquidnet.common.third.sqb.param.callback.OrderCallbackContent;
import com.liquidnet.common.third.sqb.param.callback.RefundCallbackContent;
import com.liquidnet.common.third.sqb.param.request.CashierQueryRequest;
import com.liquidnet.common.third.sqb.param.request.CommonRequest;
import com.liquidnet.common.third.sqb.param.request.CreateWechatPrepayOrderRequest;
import com.liquidnet.common.third.sqb.param.request.SettlementCreateRequest;
import com.liquidnet.common.third.sqb.param.response.data.CashierQueryData;
import com.liquidnet.common.third.sqb.param.response.data.CreateWechatPrepayOrderData;
import com.liquidnet.common.third.sqb.param.response.data.OrderCreateData;
import com.liquidnet.common.third.sqb.param.response.data.SettlementCreateData;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.commons.lang.util.StringUtil;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.goblin.constant.GoblinStatusConst;
import com.liquidnet.service.goblin.dto.manage.GoblinSqbOrderParam;
import com.liquidnet.service.goblin.dto.vo.*;
import com.liquidnet.service.goblin.entity.GoblinSqbPerformanceGoods;
import com.liquidnet.service.goblin.service.IGoblinSqbOrderService;
import com.liquidnet.service.order.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

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

@Service
@Slf4j
public class GoblinSqbOrderServiceImpl implements IGoblinSqbOrderService {


    @Autowired
    private GoblinRedisUtils goblinRedisUtils;

    @Autowired
    private GoblinSqbRedisUtils goblinSqbRedisUtils;

    @Autowired
    private GoblinMongoUtils goblinMongoUtils;

    @Autowired
    private QueueUtils queueUtils;

    @Autowired
    private SqbBiz sqbBiz;

    @Autowired
    private DataUtils dataUtils;

    private static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /** 收钱吧结算明细：1=自定义商品，按传入单价(分)结算，避免 type=0 走商城原价 */
    private static final byte SQB_CHECKOUT_ITEM_TYPE_CUSTOM = 1;


    // ================================ 创建订单 ================================

    @Override
    public ResponseDto<GoblinSqbOrderCreateVo> createOrder(String userId, GoblinSqbOrderParam orderParam) {
        log.info("[收钱吧下单] 下单开始 userId={}, param: {}", userId, JsonUtils.toJson(orderParam));

        String skuId = orderParam.getSkuId();
        String spuId = orderParam.getSpuId();
        String performancesId = orderParam.getPerformancesId();
        Integer quantity = orderParam.getQuantity();
        String openId = orderParam.getOpenId();
        if (StringUtil.isBlank(performancesId)) {
            return ResponseDto.failure("关联演出ID不能为空");
        }
        if (openId == null || openId.trim().isEmpty()) {
            return ResponseDto.failure("微信 openId 不能为空");
        }

        // Step 1: 分布式锁防重
        boolean locked = goblinSqbRedisUtils.tryOrderLock(userId, skuId);
        if (!locked) {
            log.warn("[收钱吧下单] 获取防重锁失败，userId={}, skuId={}", userId, skuId);
            return ResponseDto.failure("请勿重复下单");
        }

        try {
            // Step 2: 校验演出-商品关联
            List<GoblinSqbPerformanceGoods> performanceGoodsListCache = goblinSqbRedisUtils.getSqbPerformanceGoodsListCache(performancesId);
            if (performanceGoodsListCache.isEmpty()) {
                log.error("[收钱吧下单] 演出关联商品列表为空，performancesId={}, skuId={}", performancesId, skuId);
                return ResponseDto.failure("商品与演出关联不存在");
            }

            GoblinSqbPerformanceGoods matchedPerfRel = null;
            for (GoblinSqbPerformanceGoods goblinSqbPerformanceGoods : performanceGoodsListCache) {
                if (skuId.equals(goblinSqbPerformanceGoods.getSkuId())) {
                    matchedPerfRel = goblinSqbPerformanceGoods;
                    break;
                }
            }

            if (matchedPerfRel == null) {
                log.error("[收钱吧下单] 演出-商品关联不存在或已禁用，performancesId={}, skuId={}", performancesId, skuId);
                return ResponseDto.failure("商品与演出关联不存在");
            }

            GoblinGoodsSkuInfoVo skuVo = goblinRedisUtils.getGoodsSkuInfoVo(skuId);
            if (skuVo == null) {
                log.error("[收钱吧下单] 未找到商品, skuId: {}, spuId: {}", skuId, spuId);
                return ResponseDto.failure("商品不存在");
            }
            if (!skuId.equals(skuVo.getSkuId())) {
                return ResponseDto.failure("下单失败");
            }
            if (!skuVo.getShelvesStatus().equals("3")) {
                log.info("[收钱吧下单] 商品已下架 skuId: {}, spuId: {}", skuId, spuId);
                return ResponseDto.failure("商品已下架");
            }

            // Step 3: 原子扣减库存
            int remaining = goblinRedisUtils.decrSkuStock(null, skuId, quantity);
            if (remaining < 0) {
                goblinRedisUtils.incrSkuStock(null, skuId, quantity);
                log.warn("[收钱吧下单] 库存不足，skuId={}, quantity={}", skuId, quantity);
                return ResponseDto.failure("库存不足");
            }
            log.info("[收钱吧下单] 扣减库存成功，skuId={}, 剩余库存={}", skuId, remaining);

            // 唯一计价入口（元）；后续入库、收钱吧参数均只使用该单价/总价，传给 SQB 时再 yuanToFen
            BigDecimal unitPriceYuan = resolveSqbUnitPriceYuan(userId, performancesId, skuVo, matchedPerfRel);
            BigDecimal priceTotalYuan = unitPriceYuan.multiply(new BigDecimal(quantity));
            Long payAmountFen = GoblinSqbConvertUtils.yuanToFen(priceTotalYuan);
            Long unitPriceFen = GoblinSqbConvertUtils.yuanToFen(unitPriceYuan);
            log.info("[收钱吧下单] 计价(元) unitPriceYuan={}, priceTotalYuan={}, 传SQB(分) unitPriceFen={}, payAmountFen={}, performancesId={}, skuId={}",
                    unitPriceYuan, priceTotalYuan, unitPriceFen, payAmountFen, performancesId, skuId);

            // 获取该商品对应的商城的编号和密码
            GoblinSqbGoodsExtVo sqbGoodsExt = goblinSqbRedisUtils.getSqbGoodsExt(spuId, skuId);
            if (sqbGoodsExt == null) {
                log.error("[收钱吧下单] 正在商品对应收钱吧参数为空, spuId: {}, skuId: {}", spuId, skuId);
                goblinRedisUtils.incrSkuStock(null, skuId, quantity);
                return ResponseDto.failure("下单失败");
            }

            // 商品结算(type=1)：只传 checkoutItems，不传 request.amount；图片须非空
            String checkoutImage = resolveSqbCheckoutImage(spuId, skuVo);
            if (StringUtil.isBlank(checkoutImage)) {
                goblinRedisUtils.incrSkuStock(null, skuId, quantity);
                log.warn("[收钱吧下单] 自定义商品结算缺少图片 spuId={}, skuId={}", spuId, skuId);
                return ResponseDto.failure("商品图片缺失，无法下单");
            }
            SettlementCreateData settlementData = sqbBiz.createSettlement(
                    sqbGoodsExt.getMallSn(),
                    sqbGoodsExt.getSignature(),
                    userId,
                    Collections.singletonList(buildSqbCheckOutItem(skuVo, quantity,
                            sqbGoodsExt.getSqbSkuId(), sqbGoodsExt.getSqbSpuId(), unitPriceFen, checkoutImage)));
            if (settlementData == null) {
                goblinRedisUtils.incrSkuStock(null, skuId, quantity);
                return ResponseDto.failure("创建结算明细失败");
            }
            final String checkoutItemsId = settlementData.getCheckoutItemsId();
            log.info("[收钱吧下单] 创建结算明细成功，checkoutItemsId={}", checkoutItemsId);

            // Step 4.2: createOrder → 得 sqbOrderSn + sqbOrderSignature + sqbAcquiringSn
            String goodsName = skuVo.getName();
            OrderCreateData orderData = sqbBiz.createOrder(
                    sqbGoodsExt.getMallSn(),
                    sqbGoodsExt.getSignature(),
                    checkoutItemsId,
                    userId,
                    buildRequestId(IDGenerator.nextSnowId()),
                    buildTitle(goodsName)
            );
            if (orderData == null) {
                goblinRedisUtils.incrSkuStock(null, skuId, quantity);
                return ResponseDto.failure("创建收钱吧订单失败");
            }
            String sqbOrderSn = orderData.getOrderSn(); // 订单编号
            String sqbOrderSignature = orderData.getOrderSignature(); // 订单密钥
            String sqbAcquiringSn = orderData.getAcquiring() != null ? orderData.getAcquiring().getAcquiringSn() : null; // 收单号
            String sqbAcquiringSign = orderData.getAcquiring() != null ? orderData.getAcquiring().getSignature() : null; // 收单密钥
            log.info("[收钱吧下单] 创建订单成功，订单编号={}, 收单号={}", sqbOrderSn, sqbAcquiringSn);

            // Step 4.3: 创建微信预支付凭据
            CreateWechatPrepayOrderData.PaymentVoucher pv = createPrepayVoucher(
                    sqbAcquiringSn, sqbAcquiringSign, userId, openId, String.valueOf(payAmountFen),
                    "[收钱吧下单]");
            if (pv == null) {
                goblinRedisUtils.incrSkuStock(null, skuId, quantity);
                return ResponseDto.failure("创建微信预支付失败");
            }
            log.info("[收钱吧下单] 创建微信预支付订单成功，timeStamp={}", pv.getTimeStamp());

            final String orderId = IDGenerator.nextSnowId();
            String masterOrderCode = IDGenerator.nextTimeId();
            String orderCode = IDGenerator.nextTimeId();
            LocalDateTime orderCreatedAt = LocalDateTime.now();
            String now = orderCreatedAt.format(DTF);

            // 获取商品和 SKU 信息，供后续订单基础信息拼接使用
            GoblinGoodsInfoVo goodsInfo = goblinMongoUtils.getGoodsInfoVo(spuId);
            GoblinGoodsSkuInfoVo skuInfo = goblinMongoUtils.getGoodsSkuInfoVo(skuId);

            // 1) 构建基础商城订单 VO (GoblinStoreOrderVo)
            GoblinStoreOrderVo storeOrderVo = new GoblinStoreOrderVo();
            storeOrderVo.setMasterOrderCode(masterOrderCode);
            storeOrderVo.setOrderId(orderId);
            storeOrderVo.setStoreId(goodsInfo != null ? goodsInfo.getStoreId() : "SQB_STORE");
            storeOrderVo.setStoreName(goodsInfo != null ? goodsInfo.getStoreName() : "收钱吧商品聚合门店");
            storeOrderVo.setOrderCode(orderCode);
            storeOrderVo.setUserId(userId);
            // 姓名手机号为了兼容留空或占位即可
            storeOrderVo.setUserName("");
            storeOrderVo.setUserMobile("");

            storeOrderVo.setPriceTotal(priceTotalYuan);
            storeOrderVo.setPriceActual(priceTotalYuan);
            storeOrderVo.setPriceRefund(BigDecimal.ZERO);
            storeOrderVo.setPriceExpress(BigDecimal.ZERO);
            storeOrderVo.setPriceCoupon(BigDecimal.ZERO);
            storeOrderVo.setStorePriceCoupon(BigDecimal.ZERO);
            storeOrderVo.setPriceVoucher(BigDecimal.ZERO);
            // 待支付
            storeOrderVo.setStatus(0);
            storeOrderVo.setPayType("SQB_PAY"); // 标识为收钱吧支付类型
            storeOrderVo.setDeviceFrom("shouqianba");
            storeOrderVo.setOrderType(0);
            storeOrderVo.setWriteOffCode("EMPTY");
            storeOrderVo.setPayCountdownMinute(5);
            storeOrderVo.setCreatedAt(now);

            // 2) 构建基础商城 SKU VO (GoblinOrderSkuVo)
            String orderSkuId = IDGenerator.nextSnowId();
            GoblinOrderSkuVo orderSkuVo = new GoblinOrderSkuVo();
            orderSkuVo.setOrderSkuId(orderSkuId);
            orderSkuVo.setOrderId(orderId);
            orderSkuVo.setSpuId(spuId);
            orderSkuVo.setSpuName(goodsInfo != null ? goodsInfo.getName() : "收钱吧未知商品");
            orderSkuVo.setSkuId(skuId);
            orderSkuVo.setNum(quantity);
            orderSkuVo.setSkuPrice(unitPriceYuan);
            orderSkuVo.setSkuPriceActual(priceTotalYuan);
            orderSkuVo.setSkuName(skuInfo != null ? skuInfo.getName() : "收钱吧未匹配SKU");
            String skuImg = "";
            if (skuInfo != null && StringUtil.isNotBlank(skuInfo.getSkuPic())) {
                skuImg = skuInfo.getSkuPic();
            } else if (goodsInfo != null && StringUtil.isNotBlank(goodsInfo.getCoverPic())) {
                skuImg = goodsInfo.getCoverPic();
            }
            orderSkuVo.setSkuImage(skuImg);
            orderSkuVo.setSkuSpecs("[]");
            orderSkuVo.setPriceVoucher(BigDecimal.ZERO);
            orderSkuVo.setPriceRefund(BigDecimal.ZERO);
            orderSkuVo.setCreatedAt(now);
            // 待支付；特殊标识类型：33
            orderSkuVo.setStatus(GoblinStatusConst.Status.ORDER_STATUS_0.getValue());
            orderSkuVo.setSkuType(33);

            // 存入 Redis 并绑定关系
            List<String> orderSkuVoIds = new ArrayList<>();
            orderSkuVoIds.add(orderSkuId);
            storeOrderVo.setOrderSkuVoIds(orderSkuVoIds);
            goblinRedisUtils.setGoblinOrderSku(orderSkuId, orderSkuVo);
            goblinRedisUtils.setGoblinOrder(orderId, storeOrderVo);
            goblinRedisUtils.setMasterCode(masterOrderCode, orderId);

            // 3) 构建收钱吧专属特有字段 (GoblinSqbOrderVo)
            GoblinSqbOrderVo orderVo = new GoblinSqbOrderVo();
            orderVo.setOrderId(orderId);
            orderVo.setUserId(userId);
            orderVo.setPerformancesId(performancesId);
            orderVo.setOpenId(openId);
            orderVo.setSpuId(spuId);
            orderVo.setSkuId(skuId);
            orderVo.setQuantity(quantity);
            orderVo.setAmount(payAmountFen);
            orderVo.setSqbOrderSn(sqbOrderSn);
            orderVo.setSqbOrderSignature(sqbOrderSignature);
            orderVo.setSqbAcquiringSn(sqbAcquiringSn);
            orderVo.setSqbAcquiringSign(sqbAcquiringSign);
            orderVo.setSqbCheckoutItemsId(checkoutItemsId);
            orderVo.setRefundReason("");
            orderVo.setCouponUsedStatus(0);
            orderVo.setCreatedAt(now);
            orderVo.setUpdatedAt(now);

            goblinSqbRedisUtils.setSqbOrder(orderId, orderVo);
            goblinSqbRedisUtils.addSqbOrderList(userId, orderId);
            goblinSqbRedisUtils.setOrderIdBySqbOrderSn(sqbOrderSn, orderId);
            log.info("[收钱吧下单] 订单写入 Redis 成功，orderId={}", orderId);

            // Step 6: 写 MongoDB + 发送复用的 SQL MQ
            // 写入 Mongo
            goblinMongoUtils.insertGoblinOrderSkuVo(orderSkuVo);
            goblinMongoUtils.insertGoblinStoreOrderVo(storeOrderVo);
            // 收钱吧扩展暂无需单独写 MongoDB 除非专门需要查询

            // 拼接 SQL 数据并丢队列
            LinkedList<String> sqls = new LinkedList<>();
            sqls.add(com.liquidnet.service.base.SqlMapping.get("goblin.order.create.sku_insert"));
            sqls.add(com.liquidnet.service.base.SqlMapping.get("goblin.order.create.order_insert"));
            sqls.add(com.liquidnet.service.base.SqlMapping.get("goblin_sqb_order.insert"));

            LinkedList<Object[]> sqlDataSku = new LinkedList<>();
            sqlDataSku.add(new Object[]{
                    orderSkuVo.getOrderSkuId(), orderSkuVo.getOrderId(), orderSkuVo.getSpuId(), orderSkuVo.getSpuName(), (goodsInfo != null ? goodsInfo.getCoverPic() : ""),
                    orderSkuVo.getSkuId(), orderSkuVo.getNum(), orderSkuVo.getSkuPrice(), orderSkuVo.getSkuPriceActual(), orderSkuVo.getSkuName(),
                    "", orderSkuVo.getSkuImage(), orderSkuVo.getSkuSpecs(), orderSkuVo.getPriceVoucher(),
                    "", "", "", "", 0, // ERP 等非必要参数直接置空
                    orderSkuVo.getCreatedAt()
            });

            LinkedList<Object[]> sqlDataOrder = new LinkedList<>();
            sqlDataOrder.add(new Object[]{
                    storeOrderVo.getMasterOrderCode(), storeOrderVo.getOrderId(), storeOrderVo.getStoreId(), storeOrderVo.getStoreName(), storeOrderVo.getOrderCode(),
                    storeOrderVo.getUserId(), storeOrderVo.getUserName(), storeOrderVo.getUserMobile(), storeOrderVo.getPriceTotal(), storeOrderVo.getPayCode(),
                    storeOrderVo.getPriceActual(), storeOrderVo.getPriceRefund(), storeOrderVo.getPriceExpress(), storeOrderVo.getPriceCoupon(), storeOrderVo.getStorePriceCoupon(),
                    storeOrderVo.getPriceVoucher(), storeOrderVo.getStatus(), storeOrderVo.getUcouponId(), storeOrderVo.getStoreCouponId(), storeOrderVo.getPayType(), storeOrderVo.getDeviceFrom(),
                    storeOrderVo.getSource(), "", "", storeOrderVo.getVersion(), storeOrderVo.getIsMember(), storeOrderVo.getOrderType(), storeOrderVo.getWriteOffCode(), storeOrderVo.getPayCountdownMinute(),
                    storeOrderVo.getIpAddress(), storeOrderVo.getMarketId(), storeOrderVo.getMarketType(), storeOrderVo.getCreatedAt(), "", ""
            });

            // 收钱吧订单扩展表写库数据（coupon_used_status 默认 0）
            LinkedList<Object[]> sqlDataSqbOrder = new LinkedList<>();
            sqlDataSqbOrder.add(new Object[]{
                    orderId, userId, performancesId, spuId, skuId, quantity,
                    payAmountFen,
                    sqbOrderSn, sqbOrderSignature, sqbAcquiringSn, sqbAcquiringSign, checkoutItemsId,
                    0, now, now
            });

            // 借用 Base 模块中 ConsumerGoblinOrderCPRdsReceiver 这个队列消费类进行写库
            if (queueUtils != null) {
                queueUtils.sendMsgByRedis(com.liquidnet.service.base.constant.MQConst.GoblinQueue.GOBLIN_ORDER_CREATE_PAY.getKey(),
                        com.liquidnet.service.base.SqlMapping.gets(sqls, sqlDataSku, sqlDataOrder, sqlDataSqbOrder));
                queueUtils.sendMsgByRedisGoblinStock(masterOrderCode, orderCreatedAt, "GOBLIN", 5);
            }
            log.info("[收钱吧下单] 完成 MongoDB 及 MQ 落库，orderId={}, masterCode={}", orderId, masterOrderCode);

            // Step 7: 释放分布式锁，构建返回
            goblinSqbRedisUtils.releaseOrderLock(userId, skuId);

            GoblinSqbOrderCreateVo createVo = new GoblinSqbOrderCreateVo();
            createVo.setOrderId(orderId);
            createVo.setAcquiringSn(sqbAcquiringSn);
            createVo.setTimeStamp(pv.getTimeStamp());
            createVo.setPackageStr(pv.getPackageStr());
            createVo.setPaySign(pv.getPaySign());
            createVo.setAppId(pv.getAppId());
            createVo.setSignType(pv.getSignType());
            createVo.setNonceStr(pv.getNonceStr());

            log.info("[收钱吧下单] 下单成功，orderId={}", orderId);
            return ResponseDto.success(createVo);

        } catch (Exception e) {
            log.error("[收钱吧下单] 下单异常，userId={}, skuId={}", userId, skuId, e);
            goblinRedisUtils.incrSkuStock(null, skuId, quantity);
            return ResponseDto.failure("下单失败");
        } finally {
            goblinSqbRedisUtils.releaseOrderLock(userId, skuId);
        }
    }

    /**
     * 演出入口下单：后台配置了换购价且用户已购买本场演出门票时用换购价（元），否则用 SKU 销售价；换购价高于售价时按售价避免多收。
     */
    private BigDecimal resolveSqbUnitPriceYuan(String userId, String performancesId,
                                             GoblinGoodsSkuInfoVo skuVo, GoblinSqbPerformanceGoods perfRel) {
        if (skuVo == null) {
            return BigDecimal.ZERO;
        }
        BigDecimal base = skuVo.getSellPrice() != null ? skuVo.getSellPrice() : skuVo.getPrice();
        if (base == null) {
            base = BigDecimal.ZERO;
        }
        if (perfRel == null || perfRel.getSettlementPrice() == null) {
            return base;
        }
        BigDecimal sp = perfRel.getSettlementPrice();
        if (sp.compareTo(BigDecimal.ZERO) <= 0) {
            return base;
        }
        if (sp.compareTo(base) > 0) {
            return base;
        }
        int performanceBuyCount = dataUtils.getUserPBuyCount(userId, performancesId);
        if (performanceBuyCount <= 0) {
            log.info("[收钱吧下单] 用户未购买本场演出门票，不适用换购价 userId={}, performancesId={}, settlementPrice={}",
                    userId, performancesId, sp);
            return base;
        }
        return sp;
    }

    /** 自定义商品结算要求 image 非空：优先 SKU 图，否则 SPU 封面 */
    private String resolveSqbCheckoutImage(String spuId, GoblinGoodsSkuInfoVo skuVo) {
        if (skuVo != null && StringUtil.isNotBlank(skuVo.getSkuPic())) {
            return skuVo.getSkuPic().trim();
        }
        GoblinGoodsInfoVo goodsInfo = goblinMongoUtils.getGoodsInfoVo(spuId);
        if (goodsInfo != null && StringUtil.isNotBlank(goodsInfo.getCoverPic())) {
            return goodsInfo.getCoverPic().trim();
        }
        return null;
    }

    private SettlementCreateRequest.CheckoutItem buildSqbCheckOutItem(GoblinGoodsSkuInfoVo skuVo,
                                                                      Integer quantity,
                                                                      String sqbSkuId,
                                                                      String sqbSpuId,
                                                                      Long unitPriceFen,
                                                                      String imageUrl) {
        SettlementCreateRequest.CheckoutItem checkoutItem = new SettlementCreateRequest.CheckoutItem();
        checkoutItem.setSpuId(sqbSpuId);
        checkoutItem.setSkuId(sqbSkuId);
        checkoutItem.setPrice(unitPriceFen);
        checkoutItem.setQuantity(String.valueOf(quantity));
        checkoutItem.setType(SQB_CHECKOUT_ITEM_TYPE_CUSTOM);
        checkoutItem.setTitle(skuVo.getName());
        checkoutItem.setImage(imageUrl);
        return checkoutItem;
    }

    // ================================ 查询支付状态 ================================

    @Override
    public ResponseDto<Integer> queryPayStatus(String userId, String orderId) {
        log.info("[收钱吧支付状态] 开始查询 userId={}, orderId={}", userId, orderId);

        GoblinStoreOrderVo storeOrderVo = goblinRedisUtils.getGoblinOrder(orderId);
        if (storeOrderVo == null) {
            return ResponseDto.failure("订单不存在");
        }
        if (!userId.equals(storeOrderVo.getUserId())) {
            return ResponseDto.failure("无权限访问该订单");
        }
        GoblinSqbOrderVo orderVo = goblinSqbRedisUtils.getSqbOrder(orderId);
        if (orderVo != null && orderVo.getUserId() != null && !userId.equals(orderVo.getUserId())) {
            return ResponseDto.failure("无权限访问该订单");
        }
        return ResponseDto.success(resolveSqbFlowStatusCode(storeOrderVo));
    }


    // ================================ 回调处理 ================================

    /**
     * 支付成功回调(orderStateCode=35)。
     * 更新主单 status→2(已支付) + 子单 status→2，三方(Redis/Mongo/MySQL)同步。
     * 已支付/已完成/已退款等终态幂等跳过。
     */
    @Override
    public ResponseDto<String> handlePayCallback(OrderCallbackContent orderCallbackContent) {
        log.info("[收钱吧支付回调] 收到回调参数: {}", orderCallbackContent);
        String sqbOrderSn = orderCallbackContent.getOrderSn();
        if (StringUtil.isBlank(sqbOrderSn)) return ResponseDto.failure("缺少订单标识");

        if (!Integer.valueOf(35).equals(orderCallbackContent.getOrderStateCode())) {
            log.info("[收钱吧支付回调] orderStateCode={} 不作任何数据更新", orderCallbackContent.getOrderStateCode());
            return ResponseDto.success("success");
        }

        final String orderId = goblinSqbRedisUtils.getOrderIdBySqbOrderSn(sqbOrderSn);
        if (StringUtil.isBlank(orderId)) return ResponseDto.failure("订单不存在");

        GoblinSqbOrderVo orderVo = goblinSqbRedisUtils.getSqbOrder(orderId);
        if (orderVo == null) return ResponseDto.failure("订单不存在");

        GoblinStoreOrderVo storeOrderVo = goblinRedisUtils.getGoblinOrder(orderId);
        if (storeOrderVo == null) {
            return ResponseDto.failure("订单不存在");
        }
        if (storeOrderVo.getStatus() != null) {
            int st = storeOrderVo.getStatus();
            if (st == GoblinStatusConst.Status.ORDER_STATUS_2.getValue()
                    || st == GoblinStatusConst.Status.ORDER_STATUS_4.getValue()
                    || st == GoblinStatusConst.Status.ORDER_STATUS_6.getValue()
                    || st == GoblinStatusConst.Status.ORDER_STATUS_61.getValue()) {
                return ResponseDto.success("success");
            }
        }

        String now = LocalDateTime.now().format(DTF);
        LocalDateTime nowLdt = LocalDateTime.now();
        orderVo.setUpdatedAt(now);
        goblinSqbRedisUtils.setSqbOrder(orderId, orderVo);
        syncOrderStatus(orderId, 1);

        // 子单同步 status → 2
        if (!CollectionUtils.isEmpty(storeOrderVo.getOrderSkuVoIds())) {
            LinkedList<String> sqls = new LinkedList<>();
            sqls.add(SqlMapping.get("goblin_order.pay.sku"));
            LinkedList<Object[]> skuArgs = new LinkedList<>();
            for (String skuVoId : storeOrderVo.getOrderSkuVoIds()) {
                GoblinOrderSkuVo skuVo = goblinRedisUtils.getGoblinOrderSkuVo(skuVoId);
                if (skuVo == null) continue;
                if (Integer.valueOf(GoblinStatusConst.Status.ORDER_STATUS_2.getValue()).equals(skuVo.getStatus())) continue;
                skuVo.setStatus(GoblinStatusConst.Status.ORDER_STATUS_2.getValue());
                goblinRedisUtils.setGoblinOrderSku(skuVo.getOrderSkuId(), skuVo);
                goblinMongoUtils.updateGoblinOrderSkuVo(skuVo.getOrderSkuId(), skuVo);
                skuArgs.add(new Object[]{skuVo.getStatus(), nowLdt, "", skuVo.getOrderSkuId(), nowLdt, nowLdt});
            }
            if (!skuArgs.isEmpty() && queueUtils != null) {
                queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_ORDER_CREATE_PAY.getKey(),
                        SqlMapping.gets(sqls, skuArgs));
            }
        }

        log.info("[收钱吧支付回调] orderStateCode=35 主单已支付，orderId={}", orderId);
        return ResponseDto.success("success");
    }

    /**
     * 退款完成回调(targetState=20)。
     * 主单 status→6(退款通过) + priceRefund→实付金额，子单 status→6 + priceRefund→实付金额，
     * 恢复库存（幂等），主单/子单/扩展单批量落库 MySQL。
     */
    @Override
    public ResponseDto<String> handleRefundCallback(RefundCallbackContent refundCallbackContent) {
        log.info("[收钱吧退款回调] 收到回调参数: {}", refundCallbackContent);

        String sqbOrderSn = refundCallbackContent.getOrderSn();
        if (StringUtil.isBlank(sqbOrderSn)) return ResponseDto.failure("缺少订单标识");

        if (!Integer.valueOf(20).equals(refundCallbackContent.getTargetState())) {
            log.info("[收钱吧退款回调] targetState={} 不作任何数据更新", refundCallbackContent.getTargetState());
            return ResponseDto.success("success");
        }

        final String orderId = goblinSqbRedisUtils.getOrderIdBySqbOrderSn(sqbOrderSn);
        if (StringUtil.isBlank(orderId)) return ResponseDto.failure("订单不存在");

        if (!tryAcquireRefundLock(orderId)) {
            log.warn("[收钱吧退款回调] 获取退款锁失败，稍后重试 orderId={}", orderId);
            return ResponseDto.failure("退款处理中");
        }

        try {
            GoblinSqbOrderVo orderVo = goblinSqbRedisUtils.getSqbOrder(orderId);
            if (orderVo == null) return ResponseDto.failure("订单不存在");
            GoblinStoreOrderVo storeOrderVo = goblinRedisUtils.getGoblinOrder(orderId);
            if (storeOrderVo == null) {
                return ResponseDto.failure("订单不存在");
            }
            if (Integer.valueOf(GoblinStatusConst.Status.ORDER_STATUS_6.getValue()).equals(storeOrderVo.getStatus())) {
                return ResponseDto.success("success");
            }

            String now = LocalDateTime.now().format(DTF);
            LocalDateTime nowLdt = LocalDateTime.now();
            orderVo.setUpdatedAt(now);
            goblinSqbRedisUtils.setSqbOrder(orderId, orderVo);

            // 更新主单退款金额与状态
            storeOrderVo.setStatus(GoblinStatusConst.Status.ORDER_STATUS_6.getValue());
            storeOrderVo.setPriceRefund(storeOrderVo.getPriceActual() != null ? storeOrderVo.getPriceActual() : BigDecimal.ZERO);

            // 更新子单退款金额与状态
            List<GoblinOrderSkuVo> orderSkuVos = new ArrayList<>();
            if (!CollectionUtils.isEmpty(storeOrderVo.getOrderSkuVoIds())) {
                for (String skuVoId : storeOrderVo.getOrderSkuVoIds()) {
                    GoblinOrderSkuVo skuVo = goblinRedisUtils.getGoblinOrderSkuVo(skuVoId);
                    if (skuVo != null) {
                        skuVo.setStatus(GoblinStatusConst.Status.ORDER_STATUS_6.getValue());
                        skuVo.setPriceRefund(skuVo.getSkuPriceActual() != null ? skuVo.getSkuPriceActual() : BigDecimal.ZERO);
                        goblinRedisUtils.setGoblinOrderSku(skuVo.getOrderSkuId(), skuVo);
                        goblinMongoUtils.updateGoblinOrderSkuVo(skuVo.getOrderSkuId(), skuVo);
                        orderSkuVos.add(skuVo);
                    }
                }
            }

            // 持久化 Redis / Mongo
            goblinRedisUtils.setGoblinOrder(orderId, storeOrderVo);
            goblinMongoUtils.updateGoblinStoreOrderVo(orderId, storeOrderVo);

            // 恢复库存（SETNX 幂等，防重复回调双还）
            if (goblinSqbRedisUtils.tryMarkRefundStockRestored(orderId)) {
                goblinRedisUtils.incrSkuStock(null, orderVo.getSkuId(), orderVo.getQuantity());
                log.info("[收钱吧退款回调] 库存已归还 orderId={}, skuId={}, qty={}",
                        orderId, orderVo.getSkuId(), orderVo.getQuantity());
            } else {
                log.info("[收钱吧退款回调] 库存已归还过，跳过 orderId={}", orderId);
            }

            // 批量落库 MySQL
            LinkedList<String> sqls = new LinkedList<>();
            sqls.add(SqlMapping.get("goblin_order.store.refundPrice"));
            sqls.add(SqlMapping.get("goblin_order.store.refundSkuPrice"));
            sqls.add(SqlMapping.get("goblin_sqb_order.update_refund"));

            LinkedList<Object[]> argsOrder = new LinkedList<>();
            argsOrder.add(new Object[]{storeOrderVo.getPriceRefund(), storeOrderVo.getStatus(), nowLdt, orderId, nowLdt, nowLdt});

            LinkedList<Object[]> argsSku = new LinkedList<>();
            for (GoblinOrderSkuVo skuVo : orderSkuVos) {
                argsSku.add(new Object[]{skuVo.getPriceRefund(), skuVo.getStatus(), nowLdt, skuVo.getOrderSkuId(), nowLdt, nowLdt});
            }

            LinkedList<Object[]> argsSqb = new LinkedList<>();
            argsSqb.add(new Object[]{
                    orderVo.getRefundSn() != null ? orderVo.getRefundSn() : "",
                    orderVo.getRefundSignature() != null ? orderVo.getRefundSignature() : "",
                    orderVo.getRefundReason() != null ? orderVo.getRefundReason() : "",
                    now, orderId, now, now
            });

            if (queueUtils != null) {
                queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_ORDER_CREATE_PAY.getKey(),
                        SqlMapping.gets(sqls, argsOrder, argsSku, argsSqb));
            }

            log.info("[收钱吧退款回调] targetState=20 更新退款状态成功，orderId={}", orderId);
            return ResponseDto.success("success");
        } finally {
            goblinSqbRedisUtils.releaseRefundLock(orderId);
        }
    }

    @Override
    public ResponseDto<String> handleCouponCallback(CouponCallbackContent callbackContent) {
        log.info("[收钱吧券状态回调] 收到回调参数: {}", callbackContent);

        String sqbOrderSn = callbackContent.getOrderSn();
        if (StringUtil.isBlank(sqbOrderSn)) return ResponseDto.failure("缺少订单标识");

        List<CouponCallbackContent.VoucherItem> voucherList = callbackContent.getOrderVoucherList();
        if (CollectionUtils.isEmpty(voucherList)) {
            log.info("[收钱吧券状态回调] orderVoucherList 为空，不作任何数据更新 orderSn={}", sqbOrderSn);
            return ResponseDto.success("success");
        }
        CouponCallbackContent.VoucherItem first = voucherList.get(0);
        if (first.getTargetState() == null || first.getTargetState() != 1) {
            log.info("[收钱吧券状态回调] targetState={} 不作任何数据更新 orderSn={}", first.getTargetState(), sqbOrderSn);
            return ResponseDto.success("success");
        }

        final String orderId = goblinSqbRedisUtils.getOrderIdBySqbOrderSn(sqbOrderSn);
        if (StringUtil.isBlank(orderId)) return ResponseDto.failure("订单不存在");

        GoblinSqbOrderVo orderVo = goblinSqbRedisUtils.getSqbOrder(orderId);
        if (orderVo == null) return ResponseDto.failure("订单不存在");
        GoblinStoreOrderVo storeOrderVo = goblinRedisUtils.getGoblinOrder(orderId);
        if (storeOrderVo != null && Integer.valueOf(GoblinStatusConst.Status.ORDER_STATUS_4.getValue()).equals(storeOrderVo.getStatus())) {
            return ResponseDto.success("success");
        }
        if (Integer.valueOf(1).equals(orderVo.getCouponUsedStatus())) {
            return ResponseDto.success("success");
        }

        String now = LocalDateTime.now().format(DTF);
        if (first.getVoucherNo() != null && !first.getVoucherNo().isEmpty()) {
            orderVo.setCouponSn(first.getVoucherNo());
        }
        if (first.getQrCodeUrl() != null && !first.getQrCodeUrl().isEmpty()) {
            orderVo.setCouponQrCode(first.getQrCodeUrl());
        }
        orderVo.setCouponUsedStatus(1);
        orderVo.setUpdatedAt(now);
        goblinSqbRedisUtils.setSqbOrder(orderId, orderVo);
        syncOrderStatus(orderId, 2);
        log.info("[收钱吧券状态回调] targetState=1 已核销，主单已完成，orderId={}", orderId);
        return ResponseDto.success("success");
    }

    // ================================ 再次付款 ================================

    @Override
    public ResponseDto<GoblinSqbOrderCreateVo> repay(String userId, String orderId) {
        log.info("[收钱吧再次付款] userId={}, orderId={}", userId, orderId);

        GoblinStoreOrderVo storeOrderVo = goblinRedisUtils.getGoblinOrder(orderId);
        if (storeOrderVo == null) {
            return ResponseDto.failure("订单不存在");
        }
        if (!userId.equals(storeOrderVo.getUserId())) {
            return ResponseDto.failure("无权限访问该订单");
        }
        if (!Integer.valueOf(GoblinStatusConst.Status.ORDER_STATUS_0.getValue()).equals(storeOrderVo.getStatus())) {
            return ResponseDto.failure("订单状态不支持再次付款（仅待支付状态可重新拉起）");
        }
        List<String> orderSkuVoIds = storeOrderVo.getOrderSkuVoIds();
        if (CollectionUtils.isEmpty(orderSkuVoIds)) {
            return ResponseDto.failure("订单数据异常");
        }
        GoblinOrderSkuVo firstSkuVo = goblinRedisUtils.getGoblinOrderSkuVo(orderSkuVoIds.get(0));
        if (firstSkuVo == null) {
            return ResponseDto.failure("订单数据异常");
        }
        if (!Integer.valueOf(33).equals(firstSkuVo.getSkuType())) {
            return ResponseDto.failure("该订单非收钱吧订单");
        }

        GoblinSqbOrderVo orderVo = goblinSqbRedisUtils.getSqbOrder(orderId);
        if (orderVo == null) {
            return ResponseDto.failure("收钱吧支付信息已失效，请取消订单后重新下单");
        }
        if (!userId.equals(orderVo.getUserId())) {
            return ResponseDto.failure("无权限访问该订单");
        }
        if (orderVo.getSqbAcquiringSn() == null) {
            return ResponseDto.failure("订单数据异常，缺少收单号");
        }

        if (orderVo.getOpenId() == null || orderVo.getOpenId().trim().isEmpty()) {
            return ResponseDto.failure("缺少微信 openId，无法拉起支付");
        }
        Long repayFen = orderVo.getAmount();
        if (repayFen == null) {
            return ResponseDto.failure("订单金额异常");
        }

        boolean locked = goblinSqbRedisUtils.tryOrderLock(userId, orderVo.getSkuId());
        if (!locked) {
            return ResponseDto.failure("请勿重复操作");
        }
        try {
            CreateWechatPrepayOrderData.PaymentVoucher pv = createPrepayVoucher(
                    orderVo.getSqbAcquiringSn(), orderVo.getSqbAcquiringSign(),
                    userId, orderVo.getOpenId(), String.valueOf(repayFen),
                    "[收钱吧再次付款]");
            if (pv == null) {
                return ResponseDto.failure("再次付款失败，请稍后重试");
            }

            GoblinSqbOrderCreateVo createVo = new GoblinSqbOrderCreateVo();
            createVo.setOrderId(orderId);
            createVo.setAcquiringSn(orderVo.getSqbAcquiringSn());
            createVo.setTimeStamp(pv.getTimeStamp());
            createVo.setPackageStr(pv.getPackageStr());
            createVo.setPaySign(pv.getPaySign());
            createVo.setAppId(pv.getAppId());
            createVo.setSignType(pv.getSignType());
            createVo.setNonceStr(pv.getNonceStr());

            log.info("[收钱吧再次付款] 成功，orderId={}", orderId);
            return ResponseDto.success(createVo);

        } catch (Exception e) {
            log.error("[收钱吧再次付款] 异常，orderId={}", orderId, e);
            return ResponseDto.failure("再次付款失败：" + e.getMessage());
        } finally {
            goblinSqbRedisUtils.releaseOrderLock(userId, orderVo.getSkuId());
        }
    }

    // ================================ 私有辅助方法 ================================

    private CommonRequest.Seller buildSeller() {
        CommonRequest.Seller seller = new CommonRequest.Seller();
        seller.setMerchantId(sqbBiz.getSqbConfig().getMerchantId());
        seller.setMerchantUserId(sqbBiz.getSqbConfig().getMerchantUserId());
        seller.setRole(sqbBiz.getSqbConfig().getRole());
        return seller;
    }

    private CashierQueryRequest buildCashierQueryRequest(CommonRequest.Seller seller,
                                                         String acquiringSn,
                                                         String acquiringSignature) {
        CashierQueryRequest req = new CashierQueryRequest();
        req.setAppid(sqbBiz.getSqbConfig().getAppId());
        req.setSeller(seller);
        req.setPaymentMode(4); // 4-微信小程序支付

        CashierQueryRequest.PaymentEnv paymentEnv = new CashierQueryRequest.PaymentEnv();
        paymentEnv.setClient("wechat");
        req.setPaymentEnv(paymentEnv);

        CommonRequest.Acquiring acquiring = new CommonRequest.Acquiring();
        acquiring.setAcquiringSn(acquiringSn);
        acquiring.setSignature(acquiringSignature);
        req.setAcquiringInfo(acquiring);
        return req;
    }

    private CreateWechatPrepayOrderRequest buildWechatPrepayRequest(CommonRequest.Seller seller,
                                                                    String acquiringSn,
                                                                    String acquiringSignature,
                                                                    String selectedSignature,
                                                                    String seq,
                                                                    CashierQueryData cashierData) {
        CreateWechatPrepayOrderRequest req = new CreateWechatPrepayOrderRequest();
        req.setAppid(sqbBiz.getSqbConfig().getAppId());
        req.setSeller(seller);
        req.setAcquiringSn(acquiringSn);
        req.setSignature(acquiringSignature);
        req.setSelectedSignature(selectedSignature);
        req.setSeq(seq);

        // 使用收银台返回的第一个可用支付工具
        if (cashierData != null && !CollectionUtils.isEmpty(cashierData.getPayTools())) {
            List<CreateWechatPrepayOrderRequest.UsingPayTool> usingPayTools = new ArrayList<>();
            cashierData.getPayTools().stream()
                    .filter(t -> Boolean.TRUE.equals(t.getSelectable()))
                    .findFirst()
                    .ifPresent(payTool -> {
                        CreateWechatPrepayOrderRequest.UsingPayTool usingTool = new CreateWechatPrepayOrderRequest.UsingPayTool();
                        usingTool.setId(payTool.getId());
                        usingTool.setPayTool(payTool.getType());
                        usingTool.setPayMode(4);
                        usingTool.setAmount(payTool.getShowAmount() != null ? String.valueOf(payTool.getShowAmount()) : "0");
                        usingTool.setIdentity(null);
                        usingTool.setRequestSn(IDGenerator.nextSnowId());
                        usingPayTools.add(usingTool);
                    });
            req.setUsingPayTools(usingPayTools);
        }
        return req;
    }


    /**
     * 构建收钱吧请求唯一ID，规则：AppCode（4位）+ id，总长不超过40位。
     *
     * @param id 业务唯一标识（如雪花ID）
     * @return 不超过40位的请求ID字符串
     */
    private String buildRequestId(String id) {
        String appCode = sqbBiz.getSqbConfig().getAppCode();
        if (appCode == null) appCode = "";
        String raw = appCode + id;
        return raw.length() > 40 ? raw.substring(0, 40) : raw;
    }

    /**
     * 构建收钱吧订单标题，不超过32位。
     *
     * @param name 商品名称
     * @return 不超过32位的标题字符串
     */
    private String buildTitle(String name) {
        if (name == null || name.isEmpty()) return "商品支付";
        return name.length() > 32 ? name.substring(0, 32) : name;
    }

    /**
     * 查询收银台 → 取微信支付工具 → 调 createWechatPrepayOrder，返回支付凭据。
     * 失败返回 null，调用方自行处理错误信息与资源（库存/锁）。
     */
    private CreateWechatPrepayOrderData.PaymentVoucher createPrepayVoucher(
            String acquiringSn, String acquiringSign, String userId,
            String openId, String amountFen, String logPrefix) {
        CashierQueryData cashierData = sqbBiz.queryCashier(acquiringSn, acquiringSign, userId);
        if (cashierData == null) {
            log.error("{} 查询收银台失败", logPrefix);
            return null;
        }
        List<CashierQueryData.PayTool> payTools = cashierData.getPayTools();
        if (payTools.isEmpty()) {
            log.error("{} 支付工具为空", logPrefix);
            return null;
        }
        CashierQueryData.PayTool payTool = payTools.stream()
                .filter(p -> p.getType().equals(0)).collect(Collectors.toList()).get(0);
        if (payTool == null) {
            log.error("{} 微信支付工具为空", logPrefix);
            return null;
        }

        Map<String, Object> channelExt = new HashMap<>();
        channelExt.put("sub_appid", "wx4732efeaa2b08086");

        CreateWechatPrepayOrderData prepayData = sqbBiz.createWechatPrepayOrder(
                acquiringSn, acquiringSign, userId, openId, amountFen,
                buildRequestId(IDGenerator.nextSnowId()), payTool, channelExt,
                cashierData.getSelectedSignature(), cashierData.getSeq());
        if (prepayData == null || prepayData.getPaymentVoucher() == null) {
            log.error("{} 创建微信预支付失败", logPrefix);
            return null;
        }
        return prepayData.getPaymentVoucher();
    }


    /**
     * 按主单 goblin_store_order.status 映射为支付轮询用整型（0待支付 1已付 2已完成 3退款 4退款中 5取消）
     */
    private int resolveSqbFlowStatusCode(GoblinStoreOrderVo store) {
        if (store == null || store.getStatus() == null) {
            return 0;
        }
        int s = store.getStatus();
        if (s == GoblinStatusConst.Status.ORDER_STATUS_0.getValue()) {
            return 0;
        }
        if (s == GoblinStatusConst.Status.ORDER_STATUS_61.getValue()) {
            return 4;
        }
        if (s == GoblinStatusConst.Status.ORDER_STATUS_6.getValue()) {
            return 3;
        }
        if (s == GoblinStatusConst.Status.ORDER_STATUS_4.getValue()) {
            return 2;
        }
        if (s == GoblinStatusConst.Status.ORDER_STATUS_2.getValue()) {
            return 1;
        }
        if (s == GoblinStatusConst.Status.ORDER_STATUS_5.getValue()) {
            return 5;
        }
        return 0;
    }

    /**
     * 退款回调抢锁：与发起退款共用 orderId 锁；短暂重试，避免发起侧刚释放前回调直接失败。
     */
    private boolean tryAcquireRefundLock(String orderId) {
        for (int i = 0; i < 5; i++) {
            if (goblinSqbRedisUtils.tryRefundLock(orderId)) {
                return true;
            }
            try {
                Thread.sleep(200L);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
        return false;
    }

    /**
     * 将收钱吧内部状态码映射为商城主单 status，同步 Redis / MongoDB / MySQL。
     */
    private void syncOrderStatus(String orderId, int status) {
        final int zhengzaiStatus = sqbOrderStatusConvert(status);

        GoblinStoreOrderVo storeOrderVo = goblinRedisUtils.getGoblinOrder(orderId);
        if (storeOrderVo == null) return;

        String now = LocalDateTime.now().format(DTF);
        storeOrderVo.setStatus(zhengzaiStatus);
        if (zhengzaiStatus == GoblinStatusConst.Status.ORDER_STATUS_2.getValue()) { // 支付成功
            storeOrderVo.setPayTime(now);
        }

        // 1. 同步 Redis
        goblinRedisUtils.setGoblinOrder(orderId, storeOrderVo);

        // 2. 同步 MongoDB
        goblinMongoUtils.updateGoblinStoreOrderVo(orderId, storeOrderVo);

        // 3. 同步 MySQL (复用下单 MQ 发送 Update 语句)
        String sql;
        Object[] data;
        LocalDateTime nowLdt = LocalDateTime.now();
        if (zhengzaiStatus == GoblinStatusConst.Status.ORDER_STATUS_2.getValue()) {
            sql = SqlMapping.get("goblin_sqb.syncStatusPay");
            data = new Object[]{zhengzaiStatus, storeOrderVo.getPayTime(), now, orderId, nowLdt, nowLdt};
        } else {
            sql = SqlMapping.get("goblin_sqb.syncStatus");
            data = new Object[]{zhengzaiStatus, now, orderId, nowLdt, nowLdt};
        }

        LinkedList<String> sqls = new LinkedList<>();
        sqls.add(sql);
        LinkedList<Object[]> sqlData = new LinkedList<>();
        sqlData.add(data);

        if (queueUtils != null) {
            queueUtils.sendMsgByRedis(MQConst.GoblinQueue.GOBLIN_ORDER_CREATE_PAY.getKey(),
                    SqlMapping.gets(sqls, sqlData));
        }
    }


    /**
     * 收钱吧业务事件码 → 商城主单 goblin_store_order.status（与扩展表无关）
     *
     * @param sqbOrderStatus 0待支付 1已支付 2已核销(主单完成) 3已退款 4退款中 5取消 9失败
     */
    private int sqbOrderStatusConvert(Integer sqbOrderStatus) {
        if (null == sqbOrderStatus) {
            return -1;
        }
        switch (sqbOrderStatus) {
            case 0:
                // 0-待支付 -> 对应枚举 ORDER_STATUS_0
                return GoblinStatusConst.Status.ORDER_STATUS_0.getValue();

            case 1:
                // 1-已支付 -> 对应枚举 ORDER_STATUS_2 (代发货)
                return GoblinStatusConst.Status.ORDER_STATUS_2.getValue();

            case 2:
                // 2-已核销 -> 对应枚举 ORDER_STATUS_4 (已完成)
                return GoblinStatusConst.Status.ORDER_STATUS_4.getValue();

            case 3:
                // 3-已退款 -> 对应枚举 ORDER_STATUS_6 (退款通过)
                return GoblinStatusConst.Status.ORDER_STATUS_6.getValue();

            case 4:
                // 4-退款中 -> 对应枚举 ORDER_STATUS_61 (发起-退款)
                return GoblinStatusConst.Status.ORDER_STATUS_61.getValue();

            case 5:
                // 5-已取消 -> 对应枚举 ORDER_STATUS_5
                return GoblinStatusConst.Status.ORDER_STATUS_5.getValue();

            case 9:
                // 9-失败 -> 这里归类为 ORDER_STATUS_5 (取消/终态)，如有特殊需求可调整
                return sqbOrderStatus;
            default:
                return sqbOrderStatus;
        }
    }
}
