package com.yami.shop.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.yami.shop.bean.dto.OrderRefundDto;
import com.yami.shop.bean.dto.hb.HBBaseReq;
import com.yami.shop.bean.dto.hb.OrderPaymentRequest;
import com.yami.shop.bean.dto.hb.ProductRequest;
import com.yami.shop.bean.dto.hb.ThirdPartyRefundRequest;
import com.yami.shop.bean.enums.*;
import com.yami.shop.bean.event.OrderRefundSuccessEvent;
import com.yami.shop.bean.event.ReceiptOrderEvent;
import com.yami.shop.bean.model.*;
import com.yami.shop.bean.param.*;
import com.yami.shop.bean.pay.RefundInfoDto;
import com.yami.shop.bean.vo.ExportContext;
import com.yami.shop.bean.vo.OrderRefundSkuVo;
import com.yami.shop.bean.vo.OrderRefundVo;
import com.yami.shop.common.bean.smqjh.Result;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.enums.PayType;
import com.yami.shop.common.enums.SMQJHResultCode;
import com.yami.shop.common.exception.GlobalException;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.Arith;
import com.yami.shop.common.util.HttpUtil;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.common.util.R;
import com.yami.shop.common.util.hb.HBR;
import com.yami.shop.dao.*;
import com.yami.shop.service.*;
import com.yami.shop.service.xsb.XSBPushRefundOrderService;
import com.yami.shop.utils.ExportUtils;
import com.yami.shop.utils.HBSignUtil;
import com.yami.shop.utils.SmqjhUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.rmi.server.ExportException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

import static com.yami.shop.common.util.HttpUtil.post;

@Slf4j
@Service
@AllArgsConstructor
public class OrderRefundServiceImpl extends ServiceImpl<OrderRefundMapper, OrderRefund> implements OrderRefundService {

    private final OrderRefundMapper orderRefundMapper;

    private final OrderRefundRecordMapper orderRefundRecordMapper;
    private final OrderRefundSkuMapper orderRefundskuMapper;
    private final OrderService orderService;
    private final ProductService productService;
    private final SkuService skuService;
    private final OrderItemService orderItemService;
    private final RefundOrderSettlementService refundOrderSettlementService;
    private final RefundDeliveryService refundDeliveryService;
    private final OrderSettlementService orderSettlementService;
    private final OrderSettlementMapper orderSettlementMapper;
    private final ShopDetailService shopDetailService;
    private final ShopWalletMapper shopWalletMapper;
    private final OrderMapper orderMapper;
    private final OrderItemMapper orderItemMapper;
    private final MapperFacade mapperFacade;
    private final ShopWalletLogService shopWalletLogService;
    private final ApplicationContext applicationContext;
    private final PayManagerService payManagerService;
    private final Snowflake snowflake;
    private final HBSignUtil hbSignUtil;
    private final OrderRefundSkuMapper orderRefundSkuMapper;

    @Autowired
    private ExportTaskService exportTaskService;

    @Autowired
    private XSBPushRefundOrderService xsbPushRefundOrderService;

    private final SmqjhUtil smqjhUtil;
    private final XsbMemberSupportService xsbMemberSupportService;

    //瀵煎嚭
    // 绾跨▼姹犻厤缃?
    private final ExecutorService exportExecutor = Executors.newFixedThreadPool(
            5,
            new ThreadFactoryBuilder()
                    .setNameFormat("refund-order-export-thread-%d")
                    .setDaemon(true)
                    .build()
    );

    /**
     * 鑾峰彇鍒嗛〉瀵硅薄
     */
    @Override
    public IPage<OrderRefundDto> getPage(Page page, OrderRefundDto orderRefundDto, String startTime, String endTime) {
        IPage<OrderRefundDto> orderRefundDtoIPage = orderRefundMapper.getPage(page, orderRefundDto, startTime, endTime);
        List<OrderRefundDto> records = orderRefundDtoIPage.getRecords();
        for (OrderRefundDto record : records) {
            getRefundTypeByOrderItem2(record);
        }
        return orderRefundDtoIPage;
    }

    /**
     * 鏍规嵁缂栫爜鏌ヨ閫€娆惧崟淇℃伅
     *
     * @param refundSn 閫€娆惧崟缂栫爜
     * @return 閫€娆惧寘瑁呭璞?
     */
    @Override
    public OrderRefundDto getOrderRefundByRefundSn(String refundSn) {
        OrderRefundDto orderRefundDto = orderRefundMapper.getOrderRefundByRefundSn(refundSn);
        if (orderRefundDto == null) {
            return null;
        }
        //鑾峰彇鎬绘暟锛屽鏋滀负0鍒欎负鍏ㄩ儴
        if (orderRefundDto.getGoodsNum() == 0) {
            Order order = orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNumber, orderRefundDto.getOrderNumber()));
            orderRefundDto.setGoodsNum(order.getProductNums());
        }
        // 鍒ゆ柇閫€娆惧崟绫诲瀷锛?:鏁村崟閫€娆?2:鍗曚釜鐗╁搧閫€娆撅級
        getRefundTypeByOrderItem2(orderRefundDto);
        orderRefundDto.setIsCancel(true);
        // 濡傛灉鏄崟椤归€€娆?涓旇鍗曠姸鎬佷负寰呭彂璐э紝鍒欏垽鏂€€娆炬搷浣滄槸鍚﹀彲浠ュ彇娑?
        if (orderRefundDto.getRefundType().equals(RefundType.SINGLE.value()) && orderRefundDto.getStatus().equals(OrderStatus.PADYED.value())) {
            Integer orderRefundNums = orderRefundMapper.getOrderRefundCountByRefundSn(orderRefundDto.getRefundSn());
            int orderItemNums = orderItemService.count(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderNumber, orderRefundDto.getOrderNumber()));
            //璁㈠崟閫€娆鹃」绛変簬璁㈠崟椤?澶氫釜璁㈠崟椤? -> 璇ヨ鍗曞凡鍏ㄩ儴杩涜閫€娆剧敵璇?-> 涓嶈兘杩涜鍙栨秷閫€娆炬搷浣?
            if (orderItemNums > 1 && orderRefundNums.equals(orderItemNums)) {
                orderRefundDto.setIsCancel(false);
            }
        }
        orderRefundDto.setRecords(orderRefundRecordMapper.selectList(new LambdaQueryWrapper<OrderRefundRecord>()
                .eq(OrderRefundRecord::getOrderRefundId, orderRefundDto.getRefundId())
                .orderByDesc(OrderRefundRecord::getSort)));
        applyMemberDiscountGuard(orderRefundDto);
        return orderRefundDto;
    }

    /**
     * 鏍规嵁閫€娆綢D鑾峰彇閫€娆惧崟淇℃伅
     *
     * @param refundId 閫€娆惧崟ID
     * @return
     */
    @Override
    public OrderRefundDto getOrderRefundById(Long refundId, Long shopId) {
        OrderRefundDto orderRefundDto = orderRefundMapper.getById(refundId, shopId);
        if (orderRefundDto == null) {
            throw new GlobalException("无法获取退款订单信息");
        }
        // 鍒ゆ柇閫€娆惧崟绫诲瀷锛?:鏁村崟閫€娆?2:鍗曚釜鐗╁搧閫€娆撅級
        getRefundTypeByOrderItem(orderRefundDto);

        //鏀惰揣鍦板潃瀵硅薄
        orderRefundDto.setRefundDelivery(refundDeliveryService.getOne(
                new LambdaQueryWrapper<RefundDelivery>().eq(RefundDelivery::getRefundSn, orderRefundDto.getRefundSn())));
        applyMemberDiscountGuard(orderRefundDto);
        return orderRefundDto;
    }

    /**
     * 鐢熸垚閫€娆句俊鎭拰姣旂巼淇℃伅
     *
     * @param shopId 鍟嗗id
     */
    @Override
    public StatisticsRefundParam getOrderRefundByShopId(Long shopId, Date startTime, Date endTime) {
        StatisticsRefundParam refundParam = orderRefundMapper.getRefundByShopId(shopId, startTime, endTime);
        OrderPayParam oderParam = orderService.getPayUserCountByshopId(shopId, startTime, endTime);
        StatisticsRefundParam yesterdayRefundParam = orderRefundMapper.getRefundByShopId(shopId, DateUtil.beginOfDay(DateUtil.yesterday()),
                DateUtil.endOfDay(DateUtil.yesterday()));
        OrderPayParam yesterdayOderParam = orderService.getPayUserCountByshopId(shopId, DateUtil.beginOfDay(DateUtil.yesterday()),
                DateUtil.endOfDay(DateUtil.yesterday()));
        StatisticsRefundParam lastWeekRefundParam = orderRefundMapper.getRefundByShopId(shopId, DateUtil.beginOfDay(DateUtil.lastWeek()),
                DateUtil.endOfDay(DateUtil.lastWeek()));
        OrderPayParam lastWeekOderParam = orderService.getPayUserCountByshopId(shopId, DateUtil.beginOfDay(DateUtil.lastWeek()),
                DateUtil.endOfDay(DateUtil.lastWeek()));
        double yesterdayRate = 0.00;
        double lastWeekRate = 0.00;
        double refundRate = 0.00;
        double yesterdayRefundRate = 0.00;
        double lastweekRefundRate = 0.00;
        //閲戦姣旂巼
        if (yesterdayRefundParam.getPayActualTotal() != 0) {
            yesterdayRate = Arith.div(Arith.mul(refundParam.getPayActualTotal(), 100), yesterdayRefundParam.getPayActualTotal(), 2);
        }
        if (lastWeekRefundParam.getPayActualTotal() != 0) {
            lastWeekRate = Arith.div(Arith.mul(refundParam.getPayActualTotal(), 100), lastWeekRefundParam.getPayActualTotal(), 2);
        }
        //閫€娆炬瘮鐜?
        if (oderParam.getPayOrderCount() != 0) {
            refundRate = Arith.div(Arith.mul(refundParam.getRefundCount(), 100), oderParam.getPayOrderCount(), 2);
        }
        if (yesterdayOderParam.getPayOrderCount() != 0) {
            yesterdayRefundRate = Arith.div(Arith.mul(refundParam.getRefundCount(), 100), yesterdayOderParam.getPayOrderCount(), 2);
        }
        if (lastWeekOderParam.getPayOrderCount() != 0) {
            lastweekRefundRate = Arith.div(Arith.mul(lastWeekRefundParam.getRefundCount(), 100), lastWeekOderParam.getPayOrderCount(), 2);
        }
        yesterdayRefundRate = Arith.sub(refundRate, yesterdayRefundRate);
        lastweekRefundRate = Arith.sub(refundRate, lastweekRefundRate);
        refundParam.setYesterdayAmountRate(yesterdayRate);
        refundParam.setSevenDayAmountRate(lastWeekRate);
        refundParam.setRefundRate(refundRate);
        refundParam.setYesterdayRefundRate(yesterdayRefundRate);
        refundParam.setSevenDayRefundRate(lastweekRefundRate);
        return refundParam;
    }


    /**
     * 鐢熸垚閫€娆句俊鎭拰鍒嗘姣旂巼淇℃伅
     *
     * @param shopId 鍟嗗id
     */
    @Override
    public List<StatisticsRefundParam> getOrderRefundByShopIdAndDay(Long shopId, Date startTime, Date endTime) {
        List<StatisticsRefundParam> refundList = orderRefundMapper.getRefundByShopIdAndDay(shopId, startTime, endTime);
        List<OrderPayParam> orderList = orderMapper.getPayOrderByTime(shopId, startTime, endTime);
        List<StatisticsRefundParam> refundNewList = new ArrayList<>();
        for (int i = 0; i < refundList.size(); i++) {
            StatisticsRefundParam refundParam = refundList.get(i);
            if (i + 1 > orderList.size()) {
                break;
            }
            OrderPayParam orderParam = orderList.get(i);
            Double rate = 0.00;
            if (orderParam.getPayOrderCount() != 0) {
                rate = Arith.div(Arith.mul(refundParam.getRefundCount(), 100), orderParam.getPayOrderCount(), 2);

            } else if (refundParam.getRefundCount() != 0) {
                rate = 100.00;
            }

            refundParam.setRefundRate(rate);
            refundList.set(i, refundParam);
            if (i % 7 == 0) {
                refundParam.setRefundDateToString(DateUtil.formatDate(refundParam.getRefundDate()));
                refundNewList.add(refundParam);
            }
        }
        return refundNewList;
    }

    /**
     * 鏍规嵁鍟嗗搧鍚嶇敓鎴愰€€娆炬帓琛?
     *
     * @param shopId 鍟嗗id
     */
    @Override
    public List<StatisticsRefundParam> getRefundRankingByProd(Long shopId, Date beginTime, Date endTime) {
        List<StatisticsRefundParam> ranking = orderRefundMapper.getRefundRankingByProd(shopId, beginTime, endTime);
        return ranking;
    }

    /**
     * 鏍规嵁閫€娆惧師鍥犵敓鎴愰€€娆炬帓琛?
     *
     * @param shopId 鍟嗗id
     */
    @Override
    public List<StatisticsRefundParam> getRefundRankingByReason(Long shopId, Date beginTime, Date endTime) {
        List<StatisticsRefundParam> ranking = orderRefundMapper.getRefundRankingByReason(shopId, beginTime, endTime);
        List<StatisticsRefundParam> rank = new ArrayList<>();
        double sum = 0.00;
        for (StatisticsRefundParam refundParam : ranking) {
            sum = Arith.add(sum, refundParam.getPayActualTotal());
        }
        for (StatisticsRefundParam refundParam : ranking) {
            refundParam.setRefundRate(Arith.div(Arith.mul(refundParam.getPayActualTotal(), 100), sum, 2));
            rank.add(refundParam);
        }
        return rank;
    }

    /**
     * 鐢熸垚閫€娆惧崟
     *
     * @param orderRefund 閫€娆惧璞?
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderRefund applyRefund(OrderRefund orderRefund) {
        // 鐢熸垚閫€娆惧崟
        save(orderRefund);
        // 鏇存柊璁㈠崟鐘舵€?
        Order order = orderService.getById(orderRefund.getOrderId());
        Integer refundType = orderRefund.getRefundType();
        if (Objects.equals(refundType, RefundType.ALL.value())) {
            order.setRefundStatus(RefundStatusEnum.APPLY.value());
        } else {
            order.setRefundStatus(RefundStatusEnum.APPLY.value());
        }
        orderService.updateById(order);
        return orderRefund;
    }

    /**
     * 鍒ゆ柇閫€娆惧崟绫诲瀷锛?:鏁村崟閫€娆?2:鍗曚釜鐗╁搧閫€娆撅級
     */
    private void getRefundTypeByOrderItem(OrderRefundDto orderRefundDto) {
        if (Objects.equals(orderRefundDto.getRefundType(), RefundType.ALL.value())) {
            List<OrderItem> items = orderItemService.getOrderItemsByOrderNumber(orderRefundDto.getOrderNumber());
            orderRefundDto.setOrderItems(items);
            orderRefundDto.setRefundScore(items.stream().mapToInt(OrderItem::getUseScore).sum());
        } else {
            OrderItem item = orderItemService.getById(orderRefundDto.getOrderItemId());
            orderRefundDto.getOrderItems().add(item);
            orderRefundDto.setRefundScore(item.getUseScore());
        }
    }

    private void getRefundTypeByOrderItem2(OrderRefundDto orderRefundDto) {
        int oldSum = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
                        .eq(OrderItem::getOrderNumber, orderRefundDto.getOrderNumber())).stream().mapToInt(OrderItem::getProdCount)
                .sum();
        List<OrderItem> item = orderItemService.getRefundTypeByOrderItem2(orderRefundDto.getRefundId());
        int newSum = item.stream().mapToInt(OrderItem::getProductCount).sum();
        if (!item.isEmpty()) {
            orderRefundDto.setGoodsTotal(item.stream().map(OrderItem::getGoodsTotal).reduce(0.0, Double::sum));
            if (oldSum == newSum) {
                //浠ｈ〃鍏ㄩ儴閫€锛屾墍浠ラ渶瑕佸鍔犺繍璐规樉绀?
                double goodsTotal = Arith.add(BigDecimal.valueOf(orderRefundDto.getGoodsTotal()), BigDecimal.valueOf(orderRefundDto.getFreightAmount()));
                orderRefundDto.setGoodsTotal(goodsTotal);
            }
            item.forEach(c -> c.setRefundCount(orderItemService.refundCount(c.getOrderItemId())));
        }
        orderRefundDto.setOrderItems(item);
    }

    private void applyMemberDiscountGuard(OrderRefundDto orderRefundDto) {
        if (orderRefundDto == null) {
            return;
        }
        List<OrderItem> orderItems = orderRefundDto.getOrderItems();
        if (!isXsbOrder(orderItems)) {
            orderRefundDto.setMemberDiscountAmount(0.0);
            orderRefundDto.setMemberDiscountDesc(null);
            if (CollectionUtils.isNotEmpty(orderItems)) {
                orderItems.forEach(item -> item.setMemberDiscountShareAmount(0.0));
            }
            return;
        }
        if (orderRefundDto.getMemberDiscountAmount() == null) {
            orderRefundDto.setMemberDiscountAmount(0.0);
        }
    }

    private boolean isXsbOrder(List<OrderItem> orderItems) {
        if (CollectionUtils.isEmpty(orderItems)) {
            return false;
        }
        return xsbMemberSupportService.hasXsbBusinessType(orderItems.stream()
                .map(OrderItem::getSkuId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList()));
    }


    /**
     * 鍗栧澶勭悊锛堥€€娆?杩斿洖閫€璐у湴鍧€锛?
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderRefundDto processRefundOrder(OrderRefundParam orderRefundParam, Long shopId) {
        OrderRefundDto orderRefundDto = getOrderRefundById(orderRefundParam.getRefundId(), shopId);
        if (Objects.equals(-1, orderRefundDto.getReturnMoneySts())) {
            throw new GlobalException("买家已取消申请");
        }
        Date now = new Date();


        // 鏄惁鍚屾剰閫€娆?
        if (Objects.equals(orderRefundParam.getRefundSts(), RefundStsType.DISAGREE.value())) {
            // 涓嶅悓鎰忛€€娆?
            disagreeRefund(orderRefundParam, orderRefundDto, 1);
        } else {
            // 姝ｅ湪澶勭悊閫€娆剧殑鐘舵€?
            orderRefundDto.setReturnMoneySts(ReturnMoneyStsType.PROCESSING.value());

            // 鍒ゆ柇鏄€€娆鹃€€璐?浠呴€€娆?1:浠呴€€娆?2:閫€娆鹃€€璐?
            if (Objects.equals(orderRefundDto.getApplyType(), 1)) {
                // 鍚屾剰閫€娆?
                agreeRefund(orderRefundDto);
                // 鍑忓皯鍟嗗缁撶畻閲戦
                subShopSettlementAmount(orderRefundDto);
            } else {
                // 鍚屾剰閫€娆鹃€€璐ф搷浣?
                // 璁剧疆閫€璐х墿娴佷俊鎭?
//                RefundAddr refundAddr = refundAddrService.getById(orderRefundParam.getRefundAddrId());
//                if (refundAddr == null) {
//                    throw new GlobalException("璇疯缃€€璐х墿娴佷俊鎭?);
//                }
                ShopDetail shopDetailByShopId = shopDetailService.getShopDetailByShopId(orderRefundDto.getShopId());
                RefundDelivery refundDelivery = new RefundDelivery();
                refundDelivery.setShopId(orderRefundDto.getShopId());
                refundDelivery.setRefundSn(orderRefundDto.getRefundSn());
                refundDelivery.setUserId(orderRefundDto.getUserId());
                refundDelivery.setReceiverName(shopDetailByShopId.getShopName());
                refundDelivery.setReceiverMobile(shopDetailByShopId.getMobile());
//                refundDelivery.setReceiverTelephone(refundAddr.getReceiverTelephone());
//                refundDelivery.setReceiverPostCode(refundAddr.getPostCode());
                String addr = shopDetailByShopId.getProvince() + shopDetailByShopId.getCity() + shopDetailByShopId.getArea() + shopDetailByShopId.getShopAddress();
                refundDelivery.setReceiverAddr(addr);
                refundDelivery.setCreateTime(new Date());
                refundDelivery.setPayer(orderRefundParam.getPayer());
                refundDeliveryService.save(refundDelivery);
            }
        }

        // 璁剧疆鍗栧澶囨敞
        orderRefundDto.setSellerMsg(orderRefundParam.getSellerMsg());
        // 鍙楃悊鏃堕棿
        orderRefundDto.setHandelTime(now);
        // 鏇存柊鏃堕棿
        orderRefundDto.setUpdateTime(now);

        // 鏇存柊鏁版嵁
        updateById(orderRefundDto);
        return orderRefundDto;
    }

    /**
     * 鏀跺埌璐у悓鎰忛€€娆?
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderRefundDto returnMoney(OrderRefundParam orderRefundParam, Long shopId) {
        // 鑾峰彇閫€娆惧崟淇℃伅
        OrderRefundDto orderRefundDto = getOrderRefundById(orderRefundParam.getRefundId(), shopId);

        if (!Objects.equals(ReturnMoneyStsType.CONSIGNMENT.value(), orderRefundDto.getReturnMoneySts())) {
            throw new GlobalException("璁㈠崟鐘舵€佸凡缁忓彂鐢熸敼鍙橈紝璇峰嬁閲嶅鎿嶄綔");
        }
        if (Objects.equals(-1, orderRefundDto.getReturnMoneySts())) {
            throw new GlobalException("买家已取消申请");
        }
        Date now = new Date();

        // 鏄惁鍚屾剰閫€娆?
        if (Objects.equals(orderRefundParam.getRefundSts(), RefundStsType.AGREE.value())) {
            // 鍑忓皯鍟嗗缁撶畻閲戦
            subShopSettlementAmount(orderRefundDto);

            // 鍚屾剰鎿嶄綔
            orderRefundDto.setReturnMoneySts(ReturnMoneyStsType.RECEIVE.value());
            // 鍚屾剰閫€娆?
            agreeRefund(orderRefundDto);

        } else {
            disagreeRefund(orderRefundParam, orderRefundDto, 2);
        }

        // 鏄惁鏀跺埌璐?
        orderRefundDto.setIsReceiver(orderRefundParam.getIsReceiver());
        // 鏀惰揣鏃堕棿
        orderRefundDto.setReceiveTime(now);
        // 鏇存柊鏃堕棿
        orderRefundDto.setUpdateTime(now);

        // 鏇存柊鏁版嵁
        updateById(orderRefundDto);

        return orderRefundDto;
    }

    /**
     * 鍑忓皯鍟嗗缁撶畻閲戦/鏈粨绠楅噾棰?
     */
    private void subShopSettlementAmount(OrderRefundDto orderRefundDto) {
        Long shopId = orderRefundDto.getShopId();
        // 鍚屾剰閫€娆撅紝鍒ゆ柇鍟嗗鏄惁杩樻湁閲戦杩涜閫€娆?
        Order order = orderService.getOrderByOrderNumber(orderRefundDto.getOrderNumber());
        if (order == null) {
            throw new GlobalException("鏈壘鍒拌璁㈠崟淇℃伅");
        }
        double shopRealRefundAmount = orderRefundDto.getRefundAmount();

        // 璁㈠崟鍙戣捣閫€娆炬椂锛屾墸闄ゅ晢瀹堕噾棰濆簲璇ュ姞涓婂钩鍙伴儴鍒?
        // 濡傛灉璁㈠崟100鍏冿紝骞冲彴鍑?0鍏冪粰鍟嗗锛堝骞冲彴10鍏冧紭鎯犲埜锛屼細鍛樻姌鎵?鎶橈級锛岀敤鎴锋敮浠?0鍏冿紝姝ゆ椂鍟嗗缁撶畻鏃讹紝瑕佹嬁鍒?00鍏冿紝銆?
        // 褰撶敤鎴疯繘琛岄€€娆撅紝鏈変竴閮ㄥ垎閽辨槸骞冲彴鍑虹殑锛屽钩鍙板嚭鐨勮繖閮ㄥ垎閽憋紝瑕佸皢骞冲彴鍑虹殑杩欓儴鍒嗛挶鎸夋暟鎹簱瀛樼殑骞冲彴浼樻儬閲戦浠庡晢瀹堕偅閲屾墸闄わ紝濡傜敤鎴烽€€90鍧楋紝鍟嗗缁撶畻鍑忓皯100鍧椼€?
        if (Objects.nonNull(order.getPlatformAmount()) && order.getPlatformAmount() > 0) {
            if (Objects.equals(orderRefundDto.getRefundType(), RefundType.ALL.value())) {
                shopRealRefundAmount = Arith.add(shopRealRefundAmount, order.getPlatformAmount());
            } else {
                OrderItem item = orderItemService.getById(orderRefundDto.getOrderItemId());
                shopRealRefundAmount = Arith.add(shopRealRefundAmount, item.getPlatformShareReduce());
            }
        }

        // 搴楅摵鐪熸閫€娆剧殑閲戦鏄笉鐢ㄩ€€鍒嗛攢鍛樼殑閭ｉ儴鍒嗙殑
        // 濡傛灉璁㈠崟100鍏冿紝鍒嗛攢10鍏冿紝10鍏冪殑鍒嗛攢璐圭敤鐢卞晢瀹跺嚭锛屾鏃跺晢瀹剁粨绠楁椂锛屾嬁鍒?0鍏冦€?
        // 褰撶敤鎴疯繘琛岄€€娆撅紝閫€1鍧楃殑鏃跺€欙紝鍒嗛攢浼氭棤鏁堬紝姝ゆ椂鍟嗗鎷垮洖缁欏嚭鍘荤殑10鍏冨垎閿€璐圭敤锛屽苟灏?鍏冪粰鍒伴€€娆剧敤鎴凤紝姝ゆ椂鍟嗗鍥犱负閫€娆捐禋9鍏冦€?shopRealRefundAmount = -9
        // 褰撶敤鎴疯繘琛岄€€娆撅紝閫€11鍧楃殑鏃跺€欙紝鍒嗛攢浼氭棤鏁堬紝姝ゆ椂鍟嗗鎷垮洖缁欏嚭鍘荤殑10鍏冨垎閿€璐圭敤锛屽苟灏?1鍏冪粰鍒伴€€娆剧敤鎴凤紝姝ゆ椂鍟嗗鍥犱负閫€娆句簭1鍏冦€俿hopRealRefundAmount = 1
        if (orderRefundDto.getDistributionTotalAmount() != null) {
            shopRealRefundAmount = Arith.sub(shopRealRefundAmount, orderRefundDto.getDistributionTotalAmount());
        }

        ShopWallet shopWallet = shopWalletMapper.selectOne(new LambdaQueryWrapper<ShopWallet>().eq(ShopWallet::getShopId, shopId));
        ShopWallet newShopWallet = mapperFacade.map(shopWallet, ShopWallet.class);

        // 宸茬‘璁ゆ敹璐х殑璁㈠崟鎵ｉ櫎宸茬粨绠楃殑閲戦
        if (Objects.equals(order.getHbOrderStatus(), OrderStatus.SUCCESS.value())) {
            // 骞冲彴鎶婇€€娆鹃噾棰濆綊杩樺晢瀹讹紝鍟嗗閫€杩橀噾棰濆埌鐢ㄦ埛
            if (shopWallet.getSettledAmount() < shopRealRefundAmount) {
                throw new GlobalException("您的可提现金额不足，无法进行退款");
            }
            newShopWallet.setSettledAmount(Arith.sub(shopWallet.getSettledAmount(), shopRealRefundAmount));
            newShopWallet.setTotalSettledAmount(Arith.sub(shopWallet.getTotalSettledAmount(), shopRealRefundAmount));
        }
        // 1. 璁㈠崟鏈‘璁ゆ敹璐у垯鎵ｆ湭缁撶畻閲戦
        // 2. 鍟嗗鎾ら攢鎷煎洟娲诲姩鏃跺け鏁堟嫾鍥㈡椂锛屽皢寰呮垚鍥㈢殑闃熶紞杩涜閫€娆?
        if (Objects.equals(order.getHbOrderStatus(), OrderStatus.PADYED.value()) || Objects.equals(order.getHbOrderStatus(), OrderStatus.CONSIGNMENT.value()) || Objects.equals(order.getHbOrderStatus(), OrderStatus.WAIT_GROUP.value())) {

            if (shopWallet.getUnsettledAmount() < shopRealRefundAmount) {
                throw new GlobalException("您的待结算金额不足，无法进行退款");
            }
            newShopWallet.setUnsettledAmount(Arith.sub(shopWallet.getUnsettledAmount(), shopRealRefundAmount));
        }
        newShopWallet.setUpdateTime(new Date());
        // 娣诲姞閽卞寘鏃ュ織璁板綍
        shopWalletLogService.saveShopWalletLog(shopWallet, newShopWallet, ShopWalletChangeReason.ORDER_REFUND, orderRefundDto.getOrderNumber());

        // 鏇存柊鍟嗗閽卞寘淇℃伅
        if (shopWalletMapper.updateById(newShopWallet) != 1) {
            throw new GlobalException("更新店铺钱包信息失败");
        }
    }

    /**
     * 涓嶅悓鎰忛€€娆?
     *
     * @param orderRefundParam
     * @param orderRefundDto
     * @param type             1 鐢ㄦ埛鍙戣捣鏄嫆缁? 2 鍟嗗鏀惰揣鍚庢嫆缁?
     */
    private void disagreeRefund(OrderRefundParam orderRefundParam, OrderRefundDto orderRefundDto, Integer type) {
        // 涓嶅悓鎰忛€€娆?
        orderRefundDto.setReturnMoneySts(ReturnMoneyStsType.REJECT.value());
        orderRefundDto.setReturnMoneySts(ReturnMoneyStsType.FAIL.value());
        // 鎷掔粷鍘熷洜
        orderRefundDto.setRejectMessage(orderRefundParam.getRejectMessage());
        orderRefundDto.setRejectTime(new Date());

        // 鏇存柊璁㈠崟
        Order order = orderService.getById(orderRefundDto.getOrderId());
        Integer orderRefundSuccessCount = orderRefundMapper.selectCount(new LambdaQueryWrapper<OrderRefund>()
                .eq(OrderRefund::getOrderId, orderRefundDto.getOrderId())
                .eq(OrderRefund::getReturnMoneySts, ReturnMoneyStsType.SUCCESS.value()));
        // 濡傛灉鏈夎鍗曢」閫€娆炬垚鍔燂紝鍒欒鍗曠姸鎬佷负閮ㄥ垎閫€娆炬垚鍔燂紝鍚﹀垯涓洪€€娆惧け璐?
        if (orderRefundSuccessCount > 0) {
            order.setRefundStatus(RefundStatusEnum.PARTIAL_SUCCESS.value());
        } else {
            order.setRefundStatus(RefundStatusEnum.DISAGREE.value());
        }
        if (type == 2) {
            order.setHbOrderStatus(OrderStatus.CLOSE.value());
        }
        orderService.updateById(order);
    }

    /**
     * 涔板鎻愪氦鐗╂祦淇℃伅
     *
     * @param orderRefund    閫€娆惧崟瀵硅薄
     * @param refundDelivery 閫€娆剧墿娴佸崟瀵硅薄
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitExpress(OrderRefund orderRefund, RefundDelivery refundDelivery) {
        refundDeliveryService.updateById(refundDelivery);
        updateById(orderRefund);
    }

    /**
     * 绯荤粺鑷姩閫€娆炬搷浣滐紙鎵归噺锛?
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void systemAutoRefundBatch(List<OrderRefundDto> orderRefundDtoList) {
        for (OrderRefundDto orderRefundDto : orderRefundDtoList) {
            agreeRefund(orderRefundDto);
            update(orderRefundDto, new LambdaQueryWrapper<OrderRefund>()
                    .eq(OrderRefund::getRefundSn, orderRefundDto.getRefundSn()));
            // 鍑忓皯鍟嗗鏈粨绠楅噾棰?
            subShopSettlementAmount(orderRefundDto);

            try {
                submitWxRefund(orderRefundDto);
            } catch (YamiShopBindException e) {
                WxPayException wxPayException = (WxPayException) e.getObject();
                if (Objects.equals("订单已全额退款", wxPayException.getErrCodeDes())) {
                    continue;
                }
                throw e;
            }
        }
    }

    /**
     * 绯荤粺楠岃瘉閫€娆剧粨鏋?
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void verifyRefund(OrderRefundDto orderRefundDto, String payRefundId) {
        // 鏌ヨ閫€娆剧粨绠楄褰?
        RefundOrderSettlement refundOrderSettlement = refundOrderSettlementService.getOne(
                new LambdaQueryWrapper<RefundOrderSettlement>().eq(RefundOrderSettlement::getRefundSn, orderRefundDto.getRefundSn()));

        // 鍒ゆ柇閫€娆剧粨绠楄褰曟槸鍚︿负鐢宠鐘舵€?
        if (refundOrderSettlement == null || refundOrderSettlement.getRefundStatus() != 1) {
            throw new GlobalException("退款已处理，无需重复处理");
        }

        // 鏇存柊閫€娆剧粨绠楄褰?
        refundOrderSettlement.setPayRefundId(payRefundId);
        refundOrderSettlement.setRefundStatus(2);
        if (!refundOrderSettlementService.updateById(refundOrderSettlement)) {
            throw new GlobalException("服务器繁忙，请稍后再试");
        }
        // 鏇存柊璁㈠崟
        Order order = orderService.getOrderByOrderNumber(orderRefundDto.getOrderNumber());
        int oldOrderStatus = order.getHbOrderStatus();

        // 閫€娆炬垚鍔燂紙淇濆瓨閫€娆剧粨绠楄褰曘€佹洿鏂拌鍗曘€佽繕鍘熷簱瀛橈級
        refundSuccess(order, orderRefundDto);

        // 鎺ㄩ€侀€€娆炬垚鍔熶簨浠?
        applicationContext.publishEvent(new OrderRefundSuccessEvent(orderRefundDto));

        // 闈炴暣鍗曢€€娆?&& 浠ュ墠璁㈠崟娌℃湁缁撶畻锛堢‘璁ゆ敹璐э級&& 鐜板湪璁㈠崟鍏抽棴浜?&& 鍥犱负閫€娆惧鑷磋鍗曞叧闂?
        // 濡傛灉璁㈠崟鍥犱负閫€娆惧叧闂紝瑕佽繘琛岀粨绠楃粰鍟嗗鐨勬搷浣滐紝杩欎釜缁撶畻鐨勮绠楁槸閫€娆惧畬鎴愬悗缁撶畻鐨勶紝鎵€浠ヤ笉瑕侀殢渚挎敼鍙橀『搴?
        if (!Objects.equals(orderRefundDto.getRefundType(), RefundType.ALL.value())
                && !Objects.equals(oldOrderStatus, OrderStatus.SUCCESS.value())
                && Objects.equals(order.getHbOrderStatus(), OrderStatus.CLOSE.value())
                && Objects.equals(order.getCloseType(), OrderCloseType.REFUND.value())) {
            applicationContext.publishEvent(new ReceiptOrderEvent(order));
        }
    }

    /**
     * 鍚屾剰閫€娆炬搷浣滐紙鐢熸垚缁撶畻璁板綍锛?
     */
    private void agreeRefund(OrderRefundDto orderRefundDto) {
        Date nowDate = new Date();
        // 鏌ヨ鏀粯璁板綍
        OrderSettlement orderSettlement = orderSettlementService.getById(orderRefundDto.getSettlementId());
        if (orderSettlement == null) {
            throw new GlobalException("没有查询到支付记录，无法申请退款");
        }
        if (refundOrderSettlementService.count(new LambdaQueryWrapper<RefundOrderSettlement>().eq(RefundOrderSettlement::getRefundSn, orderRefundDto.getRefundSn())) > 0) {
            throw new GlobalException("璁㈠崟姝ｅ湪杩涜閫€娆剧粨绠楋紝璇峰嬁閲嶅鎿嶄綔");
        }

        // 鐢熸垚閫€娆剧粨绠楄褰?
        RefundOrderSettlement refundOrderSettlement = new RefundOrderSettlement();
        refundOrderSettlement.setOrderNumber(orderRefundDto.getOrderNumber());
        refundOrderSettlement.setOrderPayNo(orderRefundDto.getOrderPayNo());
        refundOrderSettlement.setRefundSn(orderRefundDto.getRefundSn());
        refundOrderSettlement.setPayType(orderSettlement.getPayType());
        refundOrderSettlement.setPayTypeName(orderSettlement.getPayTypeName());
        refundOrderSettlement.setRefundAmount(orderRefundDto.getRefundAmount());
        refundOrderSettlement.setOrderTotalAmount(orderRefundDto.getOrderAmount());
        refundOrderSettlement.setUserId(orderRefundDto.getUserId());
        refundOrderSettlement.setRefundStatus(1);
        refundOrderSettlement.setCreateTime(nowDate);
        refundOrderSettlement.setUpdateTime(nowDate);
        refundOrderSettlementService.save(refundOrderSettlement);

        // 鏇存柊閫€娆惧崟淇℃伅
        orderRefundDto.setDecisionTime(nowDate);
        orderRefundDto.setUpdateTime(nowDate);
    }

    /**
     * 鎻愪氦閫€娆捐姹傦紙鍚戝井淇″彂璧烽€€娆捐姹傦級
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void submitWxRefund(OrderRefundDto orderRefundDto) {
        // 鍒ゆ柇鏄惁宸插悓鎰忛€€娆?
        if (orderRefundDto.getDecisionTime() == null) {
            return;
        }
        // 鏌ヨ鏀粯璁板綍
        OrderSettlement orderSettlement = orderSettlementService.getById(orderRefundDto.getSettlementId());
        RefundInfoDto refundInfo = new RefundInfoDto();
        refundInfo.setPayType(PayType.instance(orderSettlement.getPayType()));
        refundInfo.setPayNo(orderSettlement.getPayNo());
        refundInfo.setRefundSn(orderRefundDto.getRefundSn());
        refundInfo.setRefundAmount(orderRefundDto.getRefundAmount());
        refundInfo.setNotifyUrl("/order/refund/result/" + orderSettlement.getPayType());

        // 鑾峰彇鏀粯鐨勬椂鍊欑殑鏀粯閲戦
        double payAmountWhenPay = orderSettlementMapper.getPayAmountWhenPay(orderSettlement.getPayNo());
        refundInfo.setPayAmount(payAmountWhenPay);

        boolean refundSuccess = payManagerService.doRefund(refundInfo);
        if (refundSuccess) {
            verifyRefund(orderRefundDto, "");
        }
    }

    @Override
    public double sumRefundSuccessAmountByOrderId(Long orderId) {
        return orderRefundMapper.sumRefundSuccessAmountByOrderId(orderId);
    }

    @Override
    public List<OrderRefund> getProcessingOrderRefundByOrderId(Long orderId) {
        return orderRefundMapper.getProcessingOrderRefundByOrderId(orderId);
    }

    /**
     * 閫€娆炬垚鍔燂紙鏇存柊閫€娆剧粨绠楄褰曘€佹洿鏂拌鍗曘€佽繕鍘熷簱瀛橈級
     */
    private void refundSuccess(Order order, OrderRefundDto orderRefundDto) {
        if (Objects.equals(orderRefundDto.getRefundType(), RefundType.ALL.value())) {
            order.setHbOrderStatus(OrderStatus.CLOSE.value());
            order.setCancelTime(new Date());
            order.setUpdateTime(new Date());
            order.setCloseType(OrderCloseType.REFUND.value());
            order.setRefundStatus(RefundStatusEnum.SUCCEED.value());
        } else {
            // 鏌ョ湅鏄惁宸茬粡杈惧埌浜嗘墍鏈夌殑璁㈠崟鏁伴噺锛屽鏄垯璁㈠崟鍏抽棴
            int totalRefundNum = 0;
            // 宸查€€娆惧崟
            List<OrderRefund> orderRefundList = orderRefundMapper.selectList(new LambdaQueryWrapper<OrderRefund>()
                    .eq(OrderRefund::getOrderId, orderRefundDto.getOrderId())
                    .eq(OrderRefund::getReturnMoneySts, ReturnMoneyStsType.SUCCESS.value())
            );
            if (CollectionUtils.isNotEmpty(orderRefundList)) {
                totalRefundNum += orderRefundList.stream().mapToInt(OrderRefund::getGoodsNum).sum();
            }

            // 鏁翠釜璁㈠崟瀹屾垚閫€娆剧殑鏃跺€?
            if (totalRefundNum + orderRefundDto.getGoodsNum() >= order.getProductNums()) {
                order.setHbOrderStatus(OrderStatus.CLOSE.value());
                order.setCancelTime(new Date());
                order.setUpdateTime(new Date());
                order.setCloseType(OrderCloseType.REFUND.value());
                order.setRefundStatus(RefundStatusEnum.SUCCEED.value());
            } else {
                order.setRefundStatus(RefundStatusEnum.PARTIAL_SUCCESS.value());
            }

            // 閫€娆炬垚鍔熷悗锛岃鍗曟病鏈夊叧闂紝涓斿彂璐ц鍗曢」 + 閫€娆炬垚鍔熻鍗曢」 = 璁㈠崟椤规€绘暟閲?锛岃鍗曠姸鎬佹敼涓哄緟鏀惰揣
            if (!Objects.equals(order.getHbOrderStatus(), OrderStatus.CLOSE.value()) && Objects.equals(order.getHbOrderStatus(), OrderStatus.PADYED.value())) {
                List<OrderItem> list = orderItemService.list(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderNumber, order.getOrderNumber()));
                Integer count = 0;
                for (OrderItem orderItem : list) {
                    if (Objects.equals(orderItem.getStatus(), 0)) {
                        count++;
                    }
                }
                if (orderRefundList.size() + count + orderRefundDto.getOrderItems().size() >= list.size()) {
                    order.setHbOrderStatus(OrderStatus.CONSIGNMENT.value());
                    order.setDvyTime(new Date());
                }
            }
        }
        orderService.updateById(order);

        // 杩樺師搴撳瓨
        OrderRefundDto orderRefund = getOrderRefundByRefundSn(orderRefundDto.getRefundSn());
        List<OrderItem> orderItems = orderRefund.getOrderItems();
        for (OrderItem orderItem : orderItems) {
            Product product = productService.getById(orderItem.getProdId());
            Sku productSuk = skuService.getSkuBySkuId(orderItem.getSkuId());

            int totalStocks = product.getTotalStocks();
            int skuStocks = productSuk.getStocks();
            if (Objects.equals(orderRefundDto.getRefundType(), RefundType.ALL.value())) {
                // 鍏ㄩ儴閫€娆撅紝杩樺師鍏ㄩ儴鏁伴噺
                totalStocks += orderItem.getProdCount();
                skuStocks += orderItem.getProdCount();
            } else {
                // 閮ㄥ垎閫€娆撅紝杩樺師閫€娆炬暟閲?
                totalStocks += orderRefund.getGoodsNum();
                skuStocks += orderRefund.getGoodsNum();
            }
            product.setTotalStocks(totalStocks);
            productSuk.setStocks(skuStocks);
            productService.updateById(product);
            skuService.updateById(productSuk);
            skuService.removeSkuCacheBySkuId(productSuk.getSkuId(), product.getProdId());
        }

        // 閫€娆炬垚鍔?
        orderRefundDto.setReturnMoneySts(ReturnMoneyStsType.SUCCESS.value());
        orderRefundDto.setRefundTime(new Date());
        updateById(orderRefundDto);
        // 閫€娆炬椂鍒嗛攢闇€瑕佽绠?orderItems
        order.setOrderItems(orderItems);

    }

    /**
     * 鍙栨秷鐢宠瓒呮椂鐨勮鍗曪紝鏃犺璇ヨ秴鏃惰鍗曞浜庝换浣曠姸鎬?
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelWhenTimeOut(List<OrderRefund> orderRefundList) {
        if (CollectionUtils.isEmpty(orderRefundList)) {
            return;
        }
        Date now = new Date();
        for (OrderRefund orderRefund : orderRefundList) {
            orderRefund.setReturnMoneySts(ReturnMoneyStsType.FAIL.value());
            Order order = orderService.getById(orderRefund.getOrderId());
            if (ObjectUtil.isNotEmpty(order)) {
                order.setRefundStatus(4);
                orderService.updateById(order);
            }
            orderRefund.setSellerMsg("退款超时已自动关闭");
            orderRefund.setShipTime(now);
            orderRefund.setUpdateTime(now);

        }
        updateBatchById(orderRefundList);
    }

    @Override
    public boolean checkRefundDate(Order order) {
        // 鍒ゆ柇鏄惁瓒呰繃鏀寔鐨勯€€娆惧ぉ鏁?
        if (Objects.equals(order.getHbOrderStatus(), OrderStatus.SUCCESS.value())) {
            long finallyTime = order.getFinallyTime().getTime();
            long currentTime = System.currentTimeMillis();
            int miniTime = Constant.MAX_FINALLY_REFUND_TIME * 24 * 60 * 60 * 1000;
            if (currentTime - finallyTime > miniTime) {
                return false;
            }
        }
        return true;
    }

    @Override
    public double sumRefundSuccessPlatformAmountByOrderId(Long orderId) {
        return orderRefundMapper.sumRefundSuccessPlatformAmountByOrderId(orderId);
    }

    @Override
    public void overTimeRefundOrder(com.yami.shop.bean.app.param.OrderRefundParam orderRefundParam) {
        // 鑾峰彇璁㈠崟淇℃伅
        Order order = orderService.getOrderByOrderNumber(orderRefundParam.getOrderNumber());
        if (ObjectUtil.isEmpty(order)) {
            throw new GlobalException("此订单不存在，无法退货退款");
        }
        if (!Objects.equals(order.getIsPayed(), 1)) {
            throw new GlobalException("当前订单还未付款，无法申请");
        }

        if (Objects.equals(order.getHbOrderStatus(), OrderStatus.CLOSE.value())) {
            throw new GlobalException("当前订单已失败，不允许退款");
        }

        if (Objects.equals(order.getHbOrderStatus(), OrderStatus.WAIT_GROUP.value())) {
            throw new GlobalException("当前订单正在等待成团，需成团后才能继续操作");
        }

        if (orderRefundParam.getRefundAmount() > order.getActualTotal()) {
            throw new GlobalException("退款金额已超出订单金额，无法申请");
        }

        //寰呮敹璐?-> 鏁村崟閫€娆?-> 閫€娆鹃噾棰?< 璁㈠崟閲戦 - 杩愯垂閲戦
        if (Objects.equals(order.getHbOrderStatus(), OrderStatus.CONSIGNMENT.value()) && orderRefundParam.getRefundType().equals(RefundType.ALL.value())) {
            Double refundAmount = Arith.sub(order.getActualTotal(), order.getFreightAmount());
            if (orderRefundParam.getRefundAmount() > refundAmount) {
                throw new GlobalException("退款金额已超出订单金额，无法申请");
            }
        }

        if (Objects.equals(order.getOrderType(), Constant.ORDER_TYPE_SCORE)) {
            throw new GlobalException("积分商品，无法退款");
        }
        if (Objects.equals(orderRefundParam.getRefundType(), RefundType.ALL.value()) && (!Objects.isNull(order.getRefundStatus()) && !Objects.equals(order.getRefundStatus(), RefundStatusEnum.DISAGREE.value()))) {
            throw new GlobalException("积分商品，无法退款");
        }

        // 鐢熸垚閫€娆惧崟淇℃伅
        OrderRefund newOrderRefund = new OrderRefund();

        // 鑾峰彇鎵€鏈夋鍦ㄨ繘琛屼腑鐨勯€€娆捐鍗?
        List<OrderRefund> orderRefunds = baseMapper.getProcessingOrderRefundByOrderId(order.getOrderId());

        for (OrderRefund orderRefund : orderRefunds) {
            if (Objects.equals(RefundType.ALL.value(), orderRefund.getRefundType())) {
                throw new GlobalException("该订单正在进行整单退款，无法进行新的退款操作");
            }
            if (Objects.equals(orderRefund.getOrderItemId(), orderRefundParam.getOrderItemId())) {
                throw new GlobalException("该商品正在进行退款中，无法进行新的退款操作");
            }
        }

        // 濡傛灉瀛樺湪鍒嗛攢璁㈠崟锛屽垯璁＄畻鍒嗛攢鎬婚噾棰?
        List<OrderItem> orderItemList = orderItemService.getOrderItemsByOrderNumber(order.getOrderNumber());
        // 鍒ゆ柇閫€娆惧崟绫诲瀷锛?:鏁村崟閫€娆?2:鍗曚釜鐗╁搧閫€娆撅級
        if (orderRefundParam.getRefundType().equals(RefundType.ALL.value())) {
            // 鍏ㄩ儴鐗╁搧閫€娆?
            // 璁＄畻璇ヨ鍗曢」鐨勫垎閿€閲戦
            newOrderRefund.setDistributionTotalAmount(orderService.sumTotalDistributionAmountByOrderItem(orderItemList));
            // 璁＄畻骞冲彴閫€娆鹃噾棰濓紙閫€娆炬椂灏嗚繖閮ㄥ垎閽遍€€鍥炵粰骞冲彴锛屾墍浠ュ晢瀹惰鎵ｉ櫎浠庡钩鍙拌繖閲岃幏鍙栫殑閲戦锛?
            newOrderRefund.setPlatformRefundAmount(order.getPlatformAmount());
        } else {
            // 閮ㄥ垎鐗╁搧閫€娆?
            OrderItem orderItem = orderItemService.getOne(new LambdaQueryWrapper<OrderItem>()
                    .eq(OrderItem::getOrderItemId, orderRefundParam.getOrderItemId())
                    .eq(OrderItem::getOrderNumber, orderRefundParam.getOrderNumber()));
            if (orderItem == null) {
                throw new GlobalException("该商品在订单中不存在");
            }
            boolean isCanRefund = false;
            //  鏌ョ湅鏄惁鏈夋敮浠橀噾棰濆拰绉垎閮戒负绌虹殑璁㈠崟锛屾湁鍒欐姏鍑哄紓甯?
            for (OrderItem item : orderItemList) {
                if (item.getActualTotal() <= 0.0 && item.getUseScore() <= 0.0) {
                    isCanRefund = true;
                    break;
                }
            }
            if (isCanRefund) {
                throw new GlobalException("璇ヨ鍗曢儴鍒嗚鍗曢」鏀粯閲戦鍜岀Н鍒嗕负0锛屾棤娉曚娇鐢ㄩ儴鍒嗛€€娆撅紒");
            }

            if (order.getPlatformAmount() > 0 && !Arith.isEquals(orderRefundParam.getRefundAmount(), orderItem.getActualTotal())) {
                throw new GlobalException("该订单使用了平台优惠，无法进行部分退款");
            }
            // 璁＄畻璇ヨ鍗曢」鐨勫垎閿€閲戦
            newOrderRefund.setDistributionTotalAmount(orderService.sumTotalDistributionAmountByOrderItem(Collections.singletonList(orderItem)));

            // 璁＄畻骞冲彴閫€娆鹃噾棰濓紙閫€娆炬椂灏嗚繖閮ㄥ垎閽遍€€鍥炵粰骞冲彴锛屾墍浠ュ晢瀹惰鎵ｉ櫎浠庡钩鍙拌繖閲岃幏鍙栫殑閲戦锛?
            //姝ゅ璁剧疆瀹為檯骞冲彴鎶电幇閲戦
            newOrderRefund.setPlatformRefundAmount(orderItem.getPlatformShareReduce());

            // 閫€娆剧墿鍝佹暟閲忎负null鎴栬€?鏃讹紝鍒欎负閫€娆惧叏閮ㄦ暟閲?
            if (orderRefundParam.getGoodsNum() <= 0) {
                orderRefundParam.setGoodsNum(orderItem.getProdCount());
            }

            // 鍒ゆ柇閫€娆炬暟閲忔槸鍚︽孩鍑?
            if (orderRefundParam.getGoodsNum() > orderItem.getProdCount()) {
                throw new GlobalException("閫€娆剧墿鍝佹暟閲忓凡瓒呭嚭璁㈠崟涓殑鏁伴噺锛屼笉鍏佽鐢宠");
            }

            // 鍒ゆ柇閫€娆鹃噾棰濇槸鍚﹁秴鍑鸿鍗曢噾棰?
            double refundSingleAmount = Arith.div(orderRefundParam.getRefundAmount(), orderRefundParam.getGoodsNum(), 3);
            double singleAmount = Arith.div(orderItem.getActualTotal(), orderItem.getProdCount(), 3);
            if (refundSingleAmount > orderItem.getProductTotalAmount() || refundSingleAmount > singleAmount) {
                throw new GlobalException("退款金额已超出订单金额，无法申请");
            }

            // 涓€涓鍗曢」鍙兘鐢宠涓€娆￠€€娆?
            for (OrderRefund orderRefund : orderRefunds) {
                if (Objects.equals(orderRefund.getOrderId(), orderItem.getOrderItemId())) {
                    throw new GlobalException("閫€娆捐鍗曢」宸插鐞嗭紝璇峰嬁閲嶅鐢宠");
                }
            }
        }

        newOrderRefund.setShopId(order.getShopId());
        newOrderRefund.setUserId(order.getUserId());
        newOrderRefund.setOrderId(order.getOrderId());
        newOrderRefund.setRefundSn(String.valueOf(snowflake.nextId()));
        newOrderRefund.setRefundType(orderRefundParam.getRefundType());

        newOrderRefund.setRefundAmount(orderRefundParam.getRefundAmount());
        if (Objects.equals(RefundType.ALL.value(), orderRefundParam.getRefundType())) {
            newOrderRefund.setOrderItemId(0L);
        } else {
            newOrderRefund.setOrderItemId(orderRefundParam.getOrderItemId());
            // 寰呭彂璐х姸鎬?鏈€鍚庝竴浠跺晢鍝佽繘琛岄€€娆撅紝閫€娆鹃噾棰?=  鍟嗗搧閲戦 + 璁㈠崟杩愯垂閲戦
            if (Objects.equals(order.getHbOrderStatus(), OrderStatus.PADYED.value()) && order.getFreightAmount() > 0) {
                int orderItenCount = orderItemService.count(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getOrderNumber, order.getOrderNumber()));
                if (Objects.equals(orderRefunds.size(), orderItenCount - 1)) {
                    newOrderRefund.setRefundAmount(Arith.add(newOrderRefund.getRefundAmount(), order.getFreightAmount()));
                }
            }
        }

        newOrderRefund.setGoodsNum(orderRefundParam.getGoodsNum());
        newOrderRefund.setApplyType(orderRefundParam.getApplyType());
        if (Objects.equals(orderRefundParam.getApplyType(), 2)) {
            newOrderRefund.setIsReceiver(true);
        } else {
            newOrderRefund.setIsReceiver(orderRefundParam.getIsReceiver());
        }
        newOrderRefund.setBuyerReason(orderRefundParam.getBuyerReason());
        newOrderRefund.setBuyerDesc(orderRefundParam.getBuyerDesc());
        newOrderRefund.setBuyerMobile(orderRefundParam.getBuyerMobile());
        newOrderRefund.setPhotoFiles(orderRefundParam.getPhotoFiles());
        newOrderRefund.setReturnMoneySts(ReturnMoneyStsType.APPLY.value());
        newOrderRefund.setApplyTime(new Date());
        newOrderRefund.setUpdateTime(new Date());
        this.applyRefund(newOrderRefund);
    }


    //*************************** 鍞悗鎺ュ彛 ***************************
    @Override
    public String createRefundOrder(String channelOrderId, String afterSaleOrder) {
        log.info("createRefundOrder 閫€娆惧崟鎺ㄩ€佸崟鍙峰紑濮媍hannelOrderId锛歿},afterSaleOrder:{}", channelOrderId, afterSaleOrder);
        HBBaseReq<Object> build = HBBaseReq.create();
        build.setAppId(hbSignUtil.getAppId());

        // 3. 鏋勫缓澶栧眰璇锋眰浣?
        JSONObject requestBody = new JSONObject();
        requestBody.put("channelOrderId", channelOrderId);
        requestBody.put("afterSaleOrder", afterSaleOrder);
        // 4. 灏嗘暣涓狫SON瀵硅薄搴忓垪鍖栦负瀛楃涓插苟璁剧疆
        build.setBody(JSON.toJSONString(requestBody));

        build.setSign(hbSignUtil.signMd5(build));
        log.info("post 閫€娆惧崟鎺ㄩ€佸崟鍙峰弬鏁帮細{}", JSON.toJSONString(build));
        String post = post(hbSignUtil.getHBHost() + "/api/refund/asyncSave", build);
        log.info("post 閫€娆惧崟鎺ㄩ€佺粨鏋滐細{}", post);
        return post;
    }

    @Override
    public String changeStatus(String afterSaleOrder, Integer refundStatus) {
        HBBaseReq<Object> build = HBBaseReq.create();
        build.setAppId(hbSignUtil.getAppId());
        OrderRefund orderRefund = orderRefundMapper.selectOne(new LambdaQueryWrapper<OrderRefund>().eq(OrderRefund::getRefundSn, afterSaleOrder));
        // 3. 鏋勫缓澶栧眰璇锋眰浣?
        JSONObject requestBody = new JSONObject();
        requestBody.put("afterSaleOrder", afterSaleOrder);
//        閫€娆惧崟鐘舵€?10:寰呭鏍?20:澶勭悊涓?30:椹冲洖閫€娆?40:鎾ら攢閫€娆?60:寰呴€€璐э紙涓€瀹″悓鎰忥級 65:寰呯‘璁ゆ敹璐э紙浜屽寰呭鏍革級 70:閫€娆惧畬鎴?
        requestBody.put("refundStatus", refundStatus);
        requestBody.put("timestamp", orderRefund.getApplyTime().getTime());

//        deliveryMan 閫€璐х殑閰嶉€佸憳鍚嶇О
//        deliveryMobile 閫€璐х殑閰嶉€佸憳鐢佃瘽
//        deliveryManNo 閫€璐х殑閰嶉€佸憳缂栧彿

        // 4. 灏嗘暣涓狫SON瀵硅薄搴忓垪鍖栦负瀛楃涓插苟璁剧疆
        build.setBody(JSON.toJSONString(requestBody));
        build.setSign(hbSignUtil.signMd5(build));
        log.info("post 閫€娆惧崟鎺ㄩ€佸崟鍙峰弬鏁帮細{}", JSON.toJSONString(build));
        String post = post(hbSignUtil.getHBHost() + "/api/refund/changeStatus", build);
        log.info("post 閫€娆惧崟鎺ㄩ€佺粨鏋滐細{}", post);

        return post;
    }

    @Override
    public HBR details(JSONObject hBRequest) {
        ThirdPartyRefundRequest thirdPartyRefundRequest = new ThirdPartyRefundRequest();
        try {
            JSONObject bodyStr = hBRequest.getJSONObject("body");
            log.info("閫€娆捐鍗曚俊鎭紝body锛歿}", bodyStr);
            String channelOrderId = bodyStr.getString("channelOrderId");
            String afterSaleOrder = bodyStr.getString("afterSaleOrder");
            Order order = orderMapper.getOrderByOrderNumber(channelOrderId);
            if (order == null) {
                log.error("娴峰崥閫€娆捐鎯咃細璁㈠崟涓嶅瓨鍦紝channelOrderId={}", channelOrderId);
                return HBR.error("订单不存在：" + channelOrderId);
            }
            OrderRefund orderRefund = orderRefundMapper.selectOne(new LambdaQueryWrapper<OrderRefund>().eq(OrderRefund::getRefundSn, afterSaleOrder));
            if (orderRefund == null) {
                log.error("娴峰崥閫€娆捐鎯咃細閫€娆惧崟涓嶅瓨鍦紝afterSaleOrder={}", afterSaleOrder);
                return HBR.error("退款单不存在：" + afterSaleOrder);
            }
            ShopDetail shopDetailByShopId = shopDetailService.getShopDetailByShopId(orderRefund.getShopId());
            if (shopDetailByShopId == null) {
                log.error("娴峰崥閫€娆捐鎯咃細闂ㄥ簵涓嶅瓨鍦紝shopId={}", orderRefund.getShopId());
                return HBR.error("门店不存在：" + orderRefund.getShopId());
            }

            thirdPartyRefundRequest.setChannelOrderId(channelOrderId);
            thirdPartyRefundRequest.setOutStationNo(shopDetailByShopId.getHbStationNo());
            thirdPartyRefundRequest.setAfterSaleOrder(orderRefund.getRefundSn());
            thirdPartyRefundRequest.setSaleType(1);//鍞墠鍞悗鏍?1:鍞墠 2:鍞悗
            if (Objects.equals(order.getHbOrderStatus(), OrderStatus.SUCCESS.value())) {
                thirdPartyRefundRequest.setSaleType(2);
            }
            thirdPartyRefundRequest.setReason(orderRefund.getBuyerReason());
            thirdPartyRefundRequest.setProblemDescription(orderRefund.getBuyerDesc());

            thirdPartyRefundRequest.setRefundStatus(orderRefund.getReturnMoneySts());
            Integer applyType = orderRefund.getApplyType();
            if (Objects.equals(applyType, 1)) {
                thirdPartyRefundRequest.setApplyDeal(10);
            } else if (Objects.equals(applyType, 2)) {
                thirdPartyRefundRequest.setApplyDeal(40);
            } else {
                thirdPartyRefundRequest.setApplyDeal(50);
            }

            thirdPartyRefundRequest.setPickAddress(orderRefund.getBuyerMobile());
            thirdPartyRefundRequest.setRefundType(orderRefund.getRefundType());
            thirdPartyRefundRequest.setMoney((long) (orderRefund.getRefundAmount() == null ? 0 : orderRefund.getRefundAmount() * 100));
            thirdPartyRefundRequest.setTimestamp(orderRefund.getApplyTime() != null ? orderRefund.getApplyTime().getTime() : System.currentTimeMillis());
            thirdPartyRefundRequest.setRefundSource(1);

            List<ProductRequest> productRequests = new ArrayList<>();
            orderRefundSkuMapper.selectList(new LambdaQueryWrapper<OrderRefundSku>().eq(OrderRefundSku::getOrderRefundId, orderRefund.getRefundId())).forEach(orderRefundSku -> {
                Sku sku = skuService.getById(orderRefundSku.getSkuId());
                if (sku == null) {
                    log.error("娴峰崥閫€娆捐鎯咃細SKU涓嶅瓨鍦紝skuId={}, orderRefundId={}", orderRefundSku.getSkuId(), orderRefund.getRefundId());
                    return; // skip this sku
                }
                ProductRequest productRequest = new ProductRequest();
                productRequest.setSkuName(sku.getSkuName());
                productRequest.setSkuId(orderRefundSku.getSkuId());
                productRequest.setChannelSkuId(sku.getHbSkuId());
                productRequest.setRefundCount(orderRefundSku.getProductCount());
                productRequest.setRefundMoney((long) (orderRefundSku.getSkuPrice() == null ? 0 : orderRefundSku.getProductCount() * orderRefundSku.getSkuPrice() * 100));
                productRequest.setTransId(sku.getSkuId().toString());
                productRequests.add(productRequest);

            });
            thirdPartyRefundRequest.setProducts(productRequests);

            List<OrderPaymentRequest> orderPaymentRequests = new ArrayList<>();
            OrderPaymentRequest orderPaymentRequest = new OrderPaymentRequest();
            orderPaymentRequest.setPaymentType(1002);
            orderPaymentRequest.setPaymentAmount((long) (orderRefund.getRefundAmount() == null ? 0 : orderRefund.getRefundAmount() * 100));
            orderPaymentRequest.setPaymentNum(1);
            orderPaymentRequests.add(orderPaymentRequest);
            thirdPartyRefundRequest.setOrderPayments(orderPaymentRequests);
            log.info("閫€娆捐鍗曚俊鎭紝鍙傛暟锛歿}", thirdPartyRefundRequest);
            // 杩斿洖閫€娆惧崟淇℃伅
            log.info("閫€娆捐鍗曠姸鎬侊細{}", orderRefund.getReturnMoneySts());
            //TODO 閫€娆惧崟瀹屾垚澶勭悊绉垎
            if (Objects.equals(orderRefund.getReturnMoneySts(), 70)) {
                //鎺ㄩ€佸晢瀹跺鏍哥姸鎬佸悗 鍚屾閫€娆惧崟鐘舵€?
                changeStatus(orderRefund.getRefundSn(), orderRefund.getReturnMoneySts());
                if (ChannelType.SMQJH.value().equals(orderRefund.getChannelType())) {
                    //褰撳睘浜庡競姘戣闆嗗悎鐨勮鍗曠殑鏃跺€欙紝鐩存帴鍥炴帹甯傛皯璇烽泦鍚堣繘琛岄€€娆鹃€昏緫澶勭悊;
                    log.info("銆愯鎯呫€戞帹閫佸競姘戣闆嗗悎绉垎澶勭悊锛?{}", orderRefund.getRefundSn());
                    try {
                        orderService.returnRefundCheck(orderRefund.getRefundSn());
                        String s = HttpUtil.get(smqjhUtil.getOmsBaseUrl() + SmqjhUtil.omsSmqjhRefundPointsHandleUrl + orderRefund.getRefundSn());
                        log.info("銆愯鎯呫€戞帹閫佸競姘戣闆嗗悎绉垎澶勭悊杩斿洖锛?{}", s);
                        if (StringUtils.isNotEmpty(s)) {
                            Result result = JSONObject.parseObject(s, Result.class);
                            if (result == null) {
                                log.error("【详情】推送市民请集合积分处理返回失败：返回结果为空");
                            }
                            if (result != null && !SMQJHResultCode.SUCCESS.getCode().equals(result.getCode())) {
                                log.error("【详情】推送市民请集合积分处理返回失败：{}", result.getMsg());
                            }
                        }
                    } catch (Exception e) {
                        log.error("【详情】推送市民请集合积分处理报错：{}", e.getMessage(), e);
                    }
                } else {
                    orderService.returnRefund(orderRefund.getOrderNumber());
                }
            }
        } catch (Exception e) {
            log.error("海博退款订单查询异常，请求参数：{}，异常信息：", hBRequest, e);
            return HBR.error("鏈煡寮傚父");
        }

        log.info("閫€娆捐鍗曚俊鎭紝杩斿洖锛歿}", thirdPartyRefundRequest);
        return HBR.success(thirdPartyRefundRequest);
    }

    @Override
    public HBR audit(JSONObject hBRequest) {
        try {
            JSONObject bodyStr = hBRequest.getJSONObject("body");
            log.info("鍞悗瀹℃牳鎺ュ彛-鍥炶皟鎺ュ彛锛宐ody锛歿}", bodyStr);
            String afterSaleOrder = bodyStr.getString("afterSaleOrder");
            String channelOrderId = bodyStr.getString("channelOrderId");
            Integer auditType = bodyStr.getInteger("auditType");
            Integer applyDeal = bodyStr.getInteger("applyDeal");

            if (ObjectUtil.isNotEmpty(applyDeal)) {
                if (applyDeal == 40) {
                    //40:閫€璐ч€€娆?
                    applyDeal = 2;
                } else {
                    applyDeal = 1;
                }
            }
            OrderRefund orderRefund = orderRefundMapper.selectOne(new LambdaQueryWrapper<OrderRefund>().eq(OrderRefund::getRefundSn, afterSaleOrder));
            if (auditType == 3) {
                //3锛氶┏鍥?
                String reason = bodyStr.getString("reason");
                orderRefund.setReturnMoneySts(ReturnMoneyStsType.REJECT.value());
                orderRefund.setRejectMessage(reason);
                orderRefundMapper.updateById(orderRefund);

                Order orderByOrderNumber = orderService.getOrderByOrderNumber(channelOrderId);
                orderByOrderNumber.setRefundStatus(4);
                orderService.updateById(orderByOrderNumber);

                //鐢熸垚閫€娆鹃┏鍥炶褰?
                addOrderRefundRecord(orderRefund.getRefundId(), 20, 3, reason);
            } else {
                //瀹℃牳閫氳繃
                orderRefund.setApplyType(applyDeal);
                if (applyDeal == 1) {
                    orderRefund.setReturnMoneySts(ReturnMoneyStsType.SUCCESS.value());
                } else {
                    //閫€璐ч€€娆鹃渶瑕佸鐞嗕簩瀹?
                    orderRefund.setReturnMoneySts(ReturnMoneyStsType.CONSIGNMENT.value());
                }
                orderRefundMapper.updateById(orderRefund);

                //鐢熸垚寰呭晢瀹跺鏍歌褰?
                if (applyDeal == 1) {
                    addOrderRefundRecord(orderRefund.getRefundId(), 5, 3, "您的申请已通过，退款处理中");
                } else {
                    addOrderRefundRecord(orderRefund.getRefundId(), 6, 3, "申请已通过，请及时填写退货物流信息");
                }
            }

            if (applyDeal == 1) {
                if (!ChannelType.SMQJH.value().equals(orderRefund.getChannelType())) {
                    //璁㈠崟閫€娆鹃噾棰濇垨鑰呯Н鍒嗗鐞?
                    orderService.returnRefund(orderRefund.getOrderNumber());
                }
            }

            //鎺ㄩ€佸晢瀹跺鏍哥姸鎬佸悗 鍚屾閫€娆惧崟鐘舵€?
            changeStatus(orderRefund.getRefundSn(), orderRefund.getReturnMoneySts());
            try {
                if (ChannelType.SMQJH.value().equals(orderRefund.getChannelType())) {
                    orderService.returnRefundCheck(orderRefund.getRefundSn());
                    R<String> stringR = xsbPushRefundOrderService.pushRefundStatus(orderRefund);
                    if (!stringR.isSuccess()) {
                        log.error("鎺ㄩ€佸競姘戣闆嗗悎瀹℃牳鐘舵€佸け璐?{},{}", stringR.getMsg(), JSONObject.toJSON(stringR));
                    } else {
                        log.info("推送市民请集合退款状态成功");
                    }
                }

            } catch (Exception e) {
                log.error("鎺ㄩ€佸競姘戣闆嗗悎瀹℃牳鐘舵€佹姤閿?{}", e);
            }
        } catch (Exception e) {
            log.error("娴峰崥閫€娆捐鍗曟煡璇㈠紓甯革細{}", e);
            return HBR.error("鏈煡寮傚父");
        }

        return HBR.success();
    }

    @Override
    public HBR confirmOrder(JSONObject hBRequest) {
        try {
            JSONObject bodyStr = hBRequest.getJSONObject("body");
            log.info("鍞悗纭鎺ュ彛-鍥炶皟鎺ュ彛锛宐ody锛歿}", bodyStr);
            String afterSaleOrder = bodyStr.getString("afterSaleOrder");
            String channelOrderId = bodyStr.getString("channelOrderId");
            Integer auditType = bodyStr.getInteger("auditType");

            OrderRefund orderRefund = orderRefundMapper.selectOne(new LambdaQueryWrapper<OrderRefund>().eq(OrderRefund::getRefundSn, afterSaleOrder));
            if (auditType == 3) {
                //3锛氶┏鍥?
                Order orderByOrderNumber = orderService.getOrderByOrderNumber(channelOrderId);
                orderByOrderNumber.setRefundStatus(4);
                orderService.updateById(orderByOrderNumber);

                orderRefund.setReturnMoneySts(ReturnMoneyStsType.REJECT.value());
                orderRefund.setRejectMessage(bodyStr.getString("reason"));
            } else {
                orderRefund.setIsReceiver(true);
                orderRefund.setReceiveTime(new Date());
                orderRefund.setReturnMoneySts(ReturnMoneyStsType.SUCCESS.value());
            }
            orderRefundMapper.updateById(orderRefund);
            if (ChannelType.SMQJH.value().equals(orderRefund.getChannelType())) {
                try {
                    orderService.returnRefundCheck(orderRefund.getRefundSn());
                    //褰撳睘浜庡競姘戣闆嗗悎鐨勮鍗曠殑鏃跺€欙紝鐩存帴鍥炴帹甯傛皯璇烽泦鍚堣繘琛岄€€娆鹃€昏緫澶勭悊;
                    R<String> stringR = xsbPushRefundOrderService.pushRefundStatus(orderRefund);
                    if (!stringR.isSuccess()) {
                        log.error("鎺ㄩ€佸競姘戣闆嗗悎鏀惰揣鐘舵€佸け璐?{},{}", stringR.getMsg(), JSONObject.toJSON(stringR));
                    }
                    log.info("推送市民请集合退款审核状态成功");

                } catch (Exception e) {
                    log.error("鎺ㄩ€佸競姘戣闆嗗悎鏀惰揣鐘舵€佹姤閿?{}", e);
                }

            }else {
                //璁㈠崟閫€娆鹃噾棰濇垨鑰呯Н鍒嗗鐞?
                orderService.returnRefund(orderRefund.getOrderNumber());
            }
            //鎺ㄩ€佸晢瀹跺鏍哥姸鎬佸悗 鍚屾閫€娆惧崟鐘舵€?
            changeStatus(orderRefund.getRefundSn(), orderRefund.getReturnMoneySts());
        } catch (Exception e) {
            log.error("娴峰崥閫€娆捐鍗曟煡璇㈠紓甯革細{}", e);
            return HBR.error("鏈煡寮傚父");
        }

        return HBR.success();
    }

    @Override
    public void addOrderRefundRecord(Long refundId, Integer auditStatus, Integer sort, String instructions) {
        OrderRefundRecord orderRefundRecord = new OrderRefundRecord();
        orderRefundRecord.setOrderRefundId(refundId);
        orderRefundRecord.setInstructions(instructions);
        Date date = new Date();
        orderRefundRecord.setCreateTime(date);
        orderRefundRecord.setUpdateTime(date);
        orderRefundRecord.setAuditStatus(auditStatus);
        orderRefundRecord.setSort(sort);
        orderRefundRecordMapper.insert(orderRefundRecord);
    }

    @Override
    public HBR partRefund(JSONObject hBRequest) {
        try {
            JSONObject bodyStr = hBRequest.getJSONObject("body");
            log.info("閮ㄥ垎閫€娆炬帴鍙?鍥炶皟鎺ュ彛锛宐ody锛歿}", bodyStr);
            String channelOrderId = bodyStr.getString("channelOrderId");
            Integer applyDeal = bodyStr.getInteger("applyDeal");

            OrderRefundParam orderRefundParam = new OrderRefundParam();
            Order order = orderMapper.getOrderAndOrderItemByOrderNumber(channelOrderId);
            orderRefundParam.setOrderNumber(channelOrderId);
            orderRefundParam.setRefundType(RefundType.SINGLE.value());
            orderRefundParam.setApplyType(1);
            orderRefundParam.setRefundType(2);
            orderRefundParam.setIsReceiver(false);
            orderRefundParam.setBuyerReason("17");
            orderRefundParam.setBuyerDesc(bodyStr.getString("reason"));
            orderRefundParam.setBuyerMobile(order.getUserMobile());
            orderRefundParam.setRefundAmount(order.getActualTotal());

            OrderRefund orderRefund = new OrderRefund();
            if (ObjectUtil.isNotEmpty(applyDeal)) {
                if (applyDeal == 10) {
                    orderRefund.setApplyType(1);
                } else {
                    orderRefund.setApplyType(5);
                }
            }
            JSONArray products = bodyStr.getJSONArray("products");
            log.info("閮ㄥ垎閫€娆炬帴鍙?鍥炶皟鎺ュ彛锛宲roducts锛歿}", products);

            List<OrderRefundSku> orderRefundSkuList = new ArrayList<>();
            int goodsNum = 0;
            for (Object product : products) {
                JSONObject productJson = JSON.parseObject(product.toString());
                long channelSkuId = Long.parseLong(productJson.getString("channelSkuId"));
                OrderRefundSku orderRefundSku = new OrderRefundSku();
//                String skuId = productJson.getString("skuId");
                skuService.getOne(new LambdaQueryWrapper<Sku>().eq(Sku::getHbSkuId, channelSkuId));
                OrderItem orderItem = orderItemService.getOne(new LambdaQueryWrapper<OrderItem>().eq(OrderItem::getSkuId, channelSkuId)
                        .eq(OrderItem::getOrderNumber, channelOrderId));

                orderRefundSku.setSkuId(orderItem.getSkuId());
                orderRefundSku.setOrderItemId(orderItem.getOrderItemId());
                orderRefundSku.setSkuPrice(orderItem.getPrice());
                int count = Integer.parseInt(productJson.getString("productCount"));
                goodsNum += count;
                orderRefundSku.setProductCount(count);
                orderRefundSkuList.add(orderRefundSku);
            }
            orderRefund.setGoodsNum(goodsNum);
            orderRefundParam.setOrderRefundSkuList(orderRefundSkuList);

            OrderRefund orderRefund1 = orderService.applyAgain(orderRefundParam, ReturnMoneyStsType.SUCCESS.value());
            //鎺ㄩ€佹捣鍗氬垱寤鸿鍗?
            createRefundOrder(order.getOrderNumber(), orderRefund1.getRefundSn());
        } catch (Exception e) {
            log.error("娴峰崥閫€娆捐鍗曟煡璇㈠紓甯革細{}", e);
            return HBR.error("鏈煡寮傚父");
        }

        return HBR.success();
    }

    @Override
    public HBR createResult(JSONObject hBRequest) {
//        try {
//            JSONObject bodyStr = hBRequest.getJSONObject("body");
//            log.info("鍒涘缓閫€娆剧粨鏋滄帴鍙?鍥炶皟鎺ュ彛锛宐ody锛歿}", bodyStr);
//            String afterSaleO
//            OrderRefund orderRefund = orderRefundMapper.selectOne(new LambdaQueryWrapper<OrderRefund>().eq(OrderRefund::getRefundSn, afterSaleOrder));
//            orderRefund.setReturnMoneySts(ReturnMoneyStsType.SUCCESS.value());
//            orderRefundMapper.updateById(orderRefund);
//            Order orderByOrderNumber = orderService.getById(orderRefund.getOrderId());
//            orderByOrderNumber.setRefundStatus(2);
//            orderService.updateById(orderByOrderNumber);
//        } catch (Exception e) {
//            log.error("娴峰崥閫€娆捐鍗曟煡璇㈠紓甯革細{}", e);
//            HBR.error("鏈煡寮傚父");
//        }

        return HBR.success();
    }

    @Override
    public OrderRefundCountParam orderRefundCount(OrderRefundStaisticsParam orderRefund) {
        return orderRefundMapper.orderRefundCount(orderRefund);
    }

    @Override
    public IPage<OrderRefundVo> orderRefundPage(PageParam<OrderRefund> page, OrderRefundStaisticsParam orderRefund) {
        return orderRefundMapper.orderRefundPage(page, orderRefund);
    }

    @Override
    public OrderRefundVo selectInfoById(Long refundId) {
        return orderRefundMapper.selectInfoById(refundId);
    }

    /**
     * 瀵煎嚭鍞悗璁㈠崟
     *
     * @param orderRefund
     * @param userId
     */
    @Override
    public R<String> export(OrderRefundStaisticsParam orderRefund, Long userId) {

        List<OrderRefundVo> orderRefundList = orderRefundMapper.findOrderRefund(orderRefund);
        for (OrderRefundVo record : orderRefundList) {
            record.setOrderRefundSkuList(orderRefundskuMapper.selectByRefundId(record.getRefundId()));
        }
        if (orderRefundList.isEmpty()) {
            throw new GlobalException("本次导出未查询到数据，不允许导出");
        }
        String taskId = UUID.randomUUID().toString();
        ExportTask exportTask = new ExportTask();
        exportTask.setUserId(userId);
        exportTask.setExportStatus(0);//瀵煎嚭鐘舵€佽繘琛屼腑
        exportTask.setTaskId(taskId);
        exportTask.setExportType(2);//瀵煎嚭绫诲瀷
        exportTask.setTaskName("售后订单导出");
        exportTask.setExportMsg("导出中");
        exportTask.setCreateTime(new Date());
        exportTask.setUpdateTime(new Date());
        exportTaskService.save(exportTask);
        // 寮傛鎵ц瀵煎嚭
        CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
            Thread currentThread = Thread.currentThread();
            ExportContext context = new ExportContext(null, currentThread, false, 0);
            exportTaskService.putTaskId(taskId, context);
            try {
                // 璁板綍浠诲姟寮€濮?
                log.info("寮€濮嬫墽琛屽鍑轰换鍔★紝鐢ㄦ埛ID: {}", userId);
                exportNormalOrders(orderRefundList, exportTask, "refundOrder", context);
                // 璁板綍浠诲姟瀹屾垚
                log.info("瀵煎嚭浠诲姟瀹屾垚锛岀敤鎴稩D: {}", userId);
            } catch (Exception e) {
                log.error("瀵煎嚭浠诲姟寮傚父锛岀敤鎴稩D: {}", userId, e);
                exportTask.setExportStatus(2);
                exportTask.setExportMsg("瀵煎嚭澶辫触," + e.getMessage());
                exportTaskService.updateById(exportTask);
            } finally {
                exportTaskService.removeTaskId(taskId);
            }
        }, exportExecutor);
        // 瀛樺偍浠诲姟涓婁笅鏂?
        exportTaskService.putTaskId(taskId, new ExportContext(future, null, false, 0));
        return R.SUCCESS("成功");
    }

    /**
     * 瀵煎嚭姝ｅ父璁㈠崟鏁版嵁鍒癊xcel锛堢洿鎺ヨ緭鍑哄埌HttpServletResponse锛?
     */
    public void exportNormalOrders(List<OrderRefundVo> orderList,
                                   ExportTask exportTask,
                                   String fileName, ExportContext context) {
        // 2. 鐢熸垚瀹夊叏鐨勬枃浠跺悕
        String safeFileName = ExportUtils.generateSafeFileName(fileName);
        // 3. 鍑嗗鏂囦欢璺緞
        try {
            ExportUtils.prepareExportFile(safeFileName, exportTask);
        } catch (ExportException e) {
            exportTask.setExportStatus(2);//澶勭悊澶辫触
            exportTask.setExportMsg(e.getMessage());
            exportTaskService.updateById(exportTask);
            return;
        }
        File file = new File(exportTask.getFileUrl());
        try (Workbook workbook = new SXSSFWorkbook(100)) {
            // 鍒涘缓Sheet
            Sheet sheet = workbook.createSheet("鍞悗璁㈠崟");

            // 璁剧疆鍒楀
            setupColumnWidth(sheet);

            // 鍒涘缓琛ㄥご鏍峰紡
            CellStyle headerStyle = ExportUtils.createHeaderStyle(workbook);

            // 鍒涘缓鏁版嵁鏍峰紡
            CellStyle dataStyle = ExportUtils.createDataStyle(workbook);
            CellStyle numberStyle = ExportUtils.createNumberStyle(workbook);
            CellStyle dateStyle = ExportUtils.createDateStyle(workbook);


            String[] headers = {
                    "序号", "订单编号", "退款编号", "申请时间", "申请方式", "售后状态",
                    "订单类型", "退款商品名称", "规格", "购买单价(元)", "退款数量", "小计(元)",
                    "退款商品总数量", "退款总金额(元)", "退款现金(元)", "退款积分(元)", "退款过期积分(分)",
                    "所属企业", "买家姓名", "买家手机号"
            };
            // 鍒涘缓鍚堝苟鍗曞厓鏍肩殑琛ㄥご
            ExportUtils.createMergedHeader(sheet, headerStyle, "鍞悗璁㈠崟", 19);

            // 鍒涘缓鍒楁爣棰樿
            ExportUtils.createColumnHeaders(sheet, headerStyle, headers);

            // 濉厖鏁版嵁
            fillOrderData(sheet, orderList, dataStyle, numberStyle, dateStyle, context);
            // 鍐欏叆鏂囦欢
            try (FileOutputStream fos = new FileOutputStream(file);
                 BufferedOutputStream bos = new BufferedOutputStream(fos)) {
                workbook.write(bos);
            }
            // 妫€鏌ユ槸鍚﹁涓柇
            if (context.isCancelled() || Thread.currentThread().isInterrupted()) {
                log.info("导出任务 {} 已取消，已处理行数：{}", exportTask.getTaskId(), context.getProcessedRows());
                exportTask.setExportStatus(1); // 3-宸插彇娑?
                exportTask.setExportMsg("导出任务已取消，已处理行数：" + context.getProcessedRows());
                exportTaskService.updateById(exportTask);
                return;
            }
            log.info("璁㈠崟瀵煎嚭鎴愬姛锛屾枃浠讹細{}锛岃褰曟暟锛歿}", fileName, orderList.size());
            exportTask.setExportStatus(1);
            exportTask.setExportMsg("瀵煎嚭鎴愬姛");
            exportTask.setUpdateTime(new Date());
            exportTaskService.updateById(exportTask);
        } catch (InterruptedException e) {
            log.error("导出任务 {} 被中断", exportTask.getTaskId());
            Thread.currentThread().interrupt(); // 閲嶆柊璁剧疆涓柇鐘舵€?
            exportTask.setExportStatus(4);
            exportTask.setExportMsg("导出任务已取消");
            exportTaskService.updateById(exportTask);
        } catch (Exception e) {
            log.error("璁㈠崟瀵煎嚭澶辫触", e);
            exportTask.setExportStatus(2);
            exportTask.setExportMsg("导出失败：" + e.getMessage());
            exportTaskService.updateById(exportTask);
        }
    }

    /**
     * 璁剧疆鍒楀
     */
    private void setupColumnWidth(Sheet sheet) {
        // 鏍规嵁妯℃澘璁剧疆鍒楀锛堝崟浣嶏細1/256瀛楃瀹藉害锛?
        sheet.setColumnWidth(0, 12 * 256);   // 搴忓彿
        sheet.setColumnWidth(1, 12 * 256);   // 璁㈠崟缂栧彿
        sheet.setColumnWidth(2, 18 * 256);   // 閫€娆剧紪鍙?
        sheet.setColumnWidth(3, 18 * 256);   // 鐢宠鏃堕棿
        sheet.setColumnWidth(4, 10 * 256);   // 鐢宠鏂瑰紡
        sheet.setColumnWidth(5, 8 * 256);    // 鍞悗鐘舵€?
        sheet.setColumnWidth(6, 25 * 256);   // 璁㈠崟绫诲瀷
        sheet.setColumnWidth(7, 20 * 256);   // 閫€娆惧晢鍝佸悕绉?
        sheet.setColumnWidth(8, 10 * 256);   // 瑙勬牸
        sheet.setColumnWidth(9, 8 * 256);    // 璐拱鍗曚环(鍏?
        sheet.setColumnWidth(10, 10 * 256);   // 閫€娆炬暟閲?
        sheet.setColumnWidth(11, 12 * 256);  // 灏忚(鍏?
        sheet.setColumnWidth(12, 12 * 256);  // 閫€娆惧晢鍝佹€绘暟閲?
        sheet.setColumnWidth(13, 8 * 256);   // 閫€娆炬€婚噾棰?鍏?
        sheet.setColumnWidth(14, 12 * 256);  // 閫€杩樼幇閲?鍏?
        sheet.setColumnWidth(15, 10 * 256);  // 閫€杩樼Н鍒?鍏?
        sheet.setColumnWidth(16, 15 * 256);  // 閫€杩樼Н鍒嗕腑杩囨湡绉垎(鍒?
        sheet.setColumnWidth(17, 15 * 256);  // 鎵€灞炰紒涓?
        sheet.setColumnWidth(18, 10 * 256);  // 涔板濮撳悕
        sheet.setColumnWidth(19, 15 * 256);  // 涔板鐢佃瘽
    }

    /**
     * 濉厖璁㈠崟鏁版嵁
     */
    private void fillOrderData(Sheet sheet, List<OrderRefundVo> orderList,
                               CellStyle dataStyle, CellStyle numberStyle, CellStyle dateStyle, ExportContext context) throws InterruptedException {
        int batchSize = 100; // 姣忔壒澶勭悊1000鏉?
        int totalRows = orderList.size();
        int rowNum = 2; // 浠庣3琛屽紑濮嬶紙0-based绱㈠紩锛?
        int indexNum = 1; //搴忓彿

        for (int i = 0; i < totalRows; i += batchSize) {
            int end = Math.min(i + batchSize, totalRows);
            List<OrderRefundVo> batch = orderList.subList(i, end);

            for (OrderRefundVo orderRefundVo : orderList) {
                // 瀹氭湡妫€鏌ヤ腑鏂爣蹇?
                if (context.isCancelled() || Thread.currentThread().isInterrupted()) {
                    context.setProcessedRows(indexNum);
                    break;
                }
                Row row = sheet.createRow(rowNum++);
                row.setHeightInPoints(18);
                // 搴忓彿
                ExportUtils.createCell(sheet, row, 0, orderRefundVo.getOrderRefundSkuList().size(), rowNum, indexNum, dataStyle);
                fillOrderRowData(sheet, rowNum, row, orderRefundVo, dataStyle, numberStyle, dateStyle);
                rowNum += orderRefundVo.getOrderRefundSkuList().size() - 1;
                indexNum++;
            }

            // 瀹氭湡鍒锋柊鍒扮鐩?
            if (rowNum % 100 == 0) {
                try {
                    ((SXSSFSheet) sheet).flushRows(100);
                } catch (IOException e) {
                    log.warn("刷新行数据失败", e);
                }
            }
        }

    }

    /**
     * 濉厖鍗曡璁㈠崟鏁版嵁
     */
    private void fillOrderRowData(Sheet sheet, int rowNum, Row row, OrderRefundVo orderRefundVo,
                                  CellStyle dataStyle, CellStyle numberStyle, CellStyle dateStyle) {

        // 璁㈠崟缂栧彿
        ExportUtils.createCell(sheet, row, 1, orderRefundVo.getOrderRefundSkuList().size(), rowNum, orderRefundVo.getOrderNumber(), dataStyle);

        // 閫€娆剧紪鍙?
        ExportUtils.createCell(sheet, row, 2, orderRefundVo.getOrderRefundSkuList().size(), rowNum, orderRefundVo.getRefundSn(), dateStyle);

        // 鐢宠鏃堕棿
        ExportUtils.createCell(sheet, row, 3, orderRefundVo.getOrderRefundSkuList().size(), rowNum, ExportUtils.formatDate(orderRefundVo.getApplyTime()), dateStyle);

        // 鐢宠鏂瑰紡
        ExportUtils.createCell(sheet, row, 4, orderRefundVo.getOrderRefundSkuList().size(), rowNum, getApplyType(orderRefundVo.getApplyType()), dataStyle);

        // 鍞悗鐘舵€?
        ExportUtils.createCell(sheet, row, 5, orderRefundVo.getOrderRefundSkuList().size(), rowNum, getReturnMoneySts(orderRefundVo.getReturnMoneySts()), dataStyle);
        // 璁㈠崟绫诲瀷
        ExportUtils.createCell(sheet, row, 6, orderRefundVo.getOrderRefundSkuList().size(), rowNum, getDvyType(orderRefundVo.getDvyType()), dataStyle);
        // 鍟嗗搧鏄庣粏琛岋紙姣忎釜璁㈠崟椤逛竴琛岋級
        fillOrderItems(sheet, rowNum, row, orderRefundVo, dataStyle, numberStyle);

        // 閫€娆惧晢鍝佹€绘暟閲?
        ExportUtils.createCell(sheet, row, 12, orderRefundVo.getOrderRefundSkuList().size(), rowNum, orderRefundVo.getGoodsNum(), numberStyle);

        // 閫€娆炬€婚噾棰?鍏?
        ExportUtils.createCell(sheet, row, 13, orderRefundVo.getOrderRefundSkuList().size(), rowNum, orderRefundVo.getRefundTotalMoney(), numberStyle);

        // 閫€杩樼幇閲?鍏?
        ExportUtils.createCell(sheet, row, 14, orderRefundVo.getOrderRefundSkuList().size(), rowNum, orderRefundVo.getRefundAmount(), numberStyle);

        // 閫€杩樼Н鍒?鍏?
        ExportUtils.createCell(sheet, row, 15, orderRefundVo.getOrderRefundSkuList().size(), rowNum, "-" + (orderRefundVo.getOffsetPoints() == null ? 0 : Arith.div(Double.valueOf(orderRefundVo.getOffsetPoints()), 100)), numberStyle);

        // 閫€杩樼Н鍒嗕腑杩囨湡绉垎(鍒?
        ExportUtils.createCell(sheet, row, 16, orderRefundVo.getOrderRefundSkuList().size(), rowNum, (orderRefundVo.getRefundExpiredScore() == null ? 0 : orderRefundVo.getRefundExpiredScore()), numberStyle);

        // 鎵€灞炰紒涓?
        ExportUtils.createCell(sheet, row, 17, orderRefundVo.getOrderRefundSkuList().size(), rowNum, orderRefundVo.getChannelName(), dataStyle);

        // 涔板濮撳悕
        ExportUtils.createCell(sheet, row, 18, orderRefundVo.getOrderRefundSkuList().size(), rowNum, orderRefundVo.getReceiver(), dataStyle);

        // 涔板鐢佃瘽
        ExportUtils.createCell(sheet, row, 19, orderRefundVo.getOrderRefundSkuList().size(), rowNum, orderRefundVo.getBuyerMobile(), dataStyle);
    }

    /**
     * 濉厖璁㈠崟椤规槑缁?
     */
    private void fillOrderItems(Sheet sheet, int rowNum, Row row, OrderRefundVo orderRefundVo,
                                CellStyle dataStyle, CellStyle numberStyle) {
        int itemSize = orderRefundVo.getOrderRefundSkuList().size();

        for (int i = 0; i < itemSize; i++) {
            Row currentRow = (i < 1) ? row : sheet.createRow(rowNum + (i - 1));
            OrderRefundSkuVo orderRefundSkuVo = orderRefundVo.getOrderRefundSkuList().get(i);
            // 閫€娆惧晢鍝佸悕绉?
            ExportUtils.createCell(sheet, currentRow, 7, 0, rowNum, orderRefundSkuVo.getProdName(), dataStyle);

            // 瑙勬牸
            ExportUtils.createCell(sheet, currentRow, 8, 0, rowNum, orderRefundSkuVo.getSpec(), dataStyle);

            // 璐拱鍗曚环(鍏?
            ExportUtils.createCell(sheet, currentRow, 9, 0, rowNum, orderRefundSkuVo.getSkuPrice(), numberStyle);

            // 閫€娆炬暟閲?
            ExportUtils.createCell(sheet, currentRow, 10, 0, rowNum, orderRefundSkuVo.getProductCount(), dataStyle);

            // 灏忚(鍏?
            ExportUtils.createCell(sheet, currentRow, 11, 0, rowNum, (Arith.multiply(orderRefundSkuVo.getProductCount(), orderRefundSkuVo.getSkuPrice(), 2)), numberStyle);

        }
    }

    /**
     * 娴峰崥璁㈠崟鐘舵€?
     *
     * @param status
     * @return
     */
    private String getReturnMoneySts(Integer status) {
        switch (status) {
            case 10:
                return "待审核";
            case 20:
                return "处理中";
            case 30:
                return "驳回退款";
            case 40:
                return "撤销退款";
            case 60:
                return "待退货（一审同意）";
            case 65:
                return "待确认收货（二审待审核）";
            case 70:
                return "退款完成";
            default:
                return "未知状态";
        }
    }

    /**
     * 璁㈠崟绫诲瀷
     *
     * @param dvyType
     * @return
     */
    private String getDvyType(Integer dvyType) {
        switch (dvyType) {
            case 1:
                return "快递";
            case 2:
                return "自提";
            case 3:
                return "及时配送";
            default:
                return "未知类型";
        }
    }

    /**
     * 璁㈠崟绫诲瀷
     *
     * @param applyType
     * @return
     */
    private String getApplyType(Integer applyType) {
        switch (applyType) {
            case 1:
                return "仅退款";
            case 2:
                return "退货退款";
            case 5:
                return "差价退款";
            default:
                return "未知类型";
        }
    }

    @Override
    public Integer queryRemainGoodsNumber(String orderNumber) {
        return orderRefundMapper.queryRemainGoodsNumber(orderNumber);
    }

    /**
     * 鏍规嵁璁㈠崟鍙锋煡璇㈤€€娆剧被鍨嬬殑閲戦
     *
     * @param orderId
     * @param value
     * @return
     */
    @Override
    public BigDecimal countRefundMoney(Long orderId, Integer value) {
        return orderRefundMapper.countRefundMoney(orderId, value);
    }


}

