package com.yiqi.order.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.yiqi.activity.domain.ActivityRechargeItem;
import com.yiqi.app.domain.AppUser;
import com.yiqi.app.service.IAppUserPointLogService;
import com.yiqi.app.service.IAppUserService;
import com.yiqi.app.service.impl.AppUserBillMstrServiceImpl;
import com.yiqi.app.service.impl.AppUserPointLogServiceImpl;
import com.yiqi.common.exception.ServiceException;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yiqi.activity.service.IActivityRechargeItemService;
import com.yiqi.activity.service.impl.ActivityInfoServiceImpl;
import com.yiqi.app.domain.AppCouponItem;
import com.yiqi.app.service.IAppCouponItemService;
import com.yiqi.common.core.domain.R;
import com.yiqi.common.utils.CurrencyUtil;
import com.yiqi.common.utils.pay.PayCodeUtils;
import com.yiqi.delay.DelayMessage;
import com.yiqi.delay.DelayQueueCache;
import com.yiqi.order.domain.vo.*;
import com.yiqi.order.service.IOrderRechargeCouponRelationService;
import com.yiqi.app.service.IAppUserBillMstrService;
import com.yiqi.common.core.domain.AuthHolder;
import com.yiqi.common.enums.*;
import com.yiqi.common.exception.GlobalException;
import com.yiqi.common.utils.DateUtils;
import com.yiqi.common.utils.OrderNoUtils;
import com.yiqi.common.utils.SecurityUtils;
import com.yiqi.order.domain.*;
import com.yiqi.order.domain.dto.*;
import com.yiqi.order.mapper.OrderRechargeMapper;
import com.yiqi.order.service.*;
import com.yiqi.order.domain.OrderRechargeRefund;
import com.yiqi.recharge.domain.RechargePasswordCard;
import com.yiqi.recharge.domain.RechargeType;
import com.yiqi.recharge.domain.dto.BillMstrOrderDTO;
import com.yiqi.recharge.domain.dto.ConsumeOrderDTO;
import com.yiqi.order.service.IOrderRechargeRefundService;
import com.yiqi.recharge.service.IRechargeCardBatchRecordService;
import com.yiqi.recharge.service.IRechargePasswordCardService;
import com.yiqi.recharge.service.IRechargeTypeService;
import com.yiqi.system.domain.SysStore;
import com.yiqi.system.service.ISysStoreService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 充值订单Service业务层处理
 *
 * @author ruoyi
 * @date 2023-09-27
 */
@Service
public class OrderRechargeServiceImpl extends ServiceImpl<OrderRechargeMapper, OrderRecharge> implements IOrderRechargeService {
    @Autowired
    private OrderNoUtils orderNoUtils;
    @Autowired
    IOrderRechargeInstalmentService orderRechargeInstalmentService;
    @Autowired
    IRechargePasswordCardService rechargePasswordCardService;
    @Autowired
    IRechargeCardBatchRecordService rechargeCardBatchRecordService;
    @Autowired
    IRechargeTypeService rechargeTypeService;
    @Autowired
    private IAppUserService appUserService;

    @Autowired
    private ISysStoreService sysStoreService;

    @Autowired
    private IAppUserBillMstrService appUserBillMstrService;
    @Autowired
    private IAppCouponItemService appCouponItemService;
    @Autowired
    private IPayService payService;
    @Autowired
    private DelayQueueCache delayQueueCache;
    @Autowired
    private IOrderPayInfoService orderPayInfoService;
    @Autowired
    private ActivityInfoServiceImpl activityInfoService;
    @Autowired
    private IActivityRechargeItemService activityRechargeItemService;
    @Autowired
    private IOrderRechargeCouponRelationService orderRechargeCouponRelationService;

    private static final Logger log = LoggerFactory.getLogger(OrderRechargeServiceImpl.class);
    @Autowired
    private IOrderRechargeRefundService orderRechargeRefundService;
    @Autowired
    private IAppUserBillMstrService billMstrOrderService;
    @Autowired
    private IAppUserPointLogService appUserPointLogService;

    /**
     * 查询充值订单
     *
     * @param id 充值订单主键
     * @return 充值订单
     */
    @Override
    public OrderRecharge selectOrderRechargeById(Long id) {
        OrderRecharge orderRecharge = baseMapper.selectOrderRechargeById(id);
        AppUser appUser = appUserService.selectAppUserById(orderRecharge.getAppUserId());
        if (appUser != null) {
            orderRecharge.setAppUserName(appUser.getNickName());
            orderRecharge.setAppUserPhone(appUser.getPhoneNumber());
        }
        SysStore sysStore = sysStoreService.getById(orderRecharge.getStoreId());
        if (sysStore != null) {
            orderRecharge.setStoreName(sysStore.getName());
        }
        if (!orderRecharge.getOrderStatus().equals("0")) {
            RechargePasswordCard rechargePasswordCard = rechargePasswordCardService.selectRechargePasswordCardByOrderNo(orderRecharge.getOrderNo());
            orderRecharge.setRechargePasswordCard(rechargePasswordCard);
        }
        List<OrderRechargeInstalment> orderRechargeInstalments = getPayDetailById(id, null);
        orderRecharge.setOrderRechargeInstalments(orderRechargeInstalments);
        return orderRecharge;
    }

    @Override
    public List<OrderRechargeRefundListVO> refundRechargeOrderList(OrderRechargeRefundQueryDTO orderRechargeRefundQueryDTO) {
        if (!SecurityUtils.getLoginUser().getSourceType().equals(SourceType.MANAGER.getCode())) {
            orderRechargeRefundQueryDTO.setSourceType(SecurityUtils.getLoginUser().getSourceType());
        }
        if (StrUtil.isEmpty(String.valueOf(orderRechargeRefundQueryDTO.getOrgId()))) {
            orderRechargeRefundQueryDTO.setOrgId(SecurityUtils.getLoginUser().getOrgId());
        } else {
            orderRechargeRefundQueryDTO.setOrgId(orderRechargeRefundQueryDTO.getOrgId());
        }
        return baseMapper.refundRechargeOrderList(orderRechargeRefundQueryDTO);
    }

    /**
     * 查询充值订单列表
     *
     * @param orderRechargeQueryDTO 充值订单
     * @return 充值订单
     */
    @Override
    public List<OrderRechargeListVO> selectOrderRechargeList(OrderRechargeQueryDTO orderRechargeQueryDTO) {
        if (StrUtil.isEmpty(String.valueOf(orderRechargeQueryDTO.getOrgId()))) {
            orderRechargeQueryDTO.setOrgId(SecurityUtils.getLoginUser().getOrgId());
        } else {
            orderRechargeQueryDTO.setOrgId(orderRechargeQueryDTO.getOrgId());
        }
        return baseMapper.selectOrderRechargeList(orderRechargeQueryDTO);
    }

    /**
     * 查询充值订单列表
     *
     * @param orderRechargeListVO 充值订单
     * @return 充值订单
     */
    @Override
    public List<OrderRechargeListVO> selectRefundList(OrderRechargeListVO orderRechargeListVO) {
        return baseMapper.selectRefundList(orderRechargeListVO);
    }

    /**
     * 修改充值订单
     *
     * @param orderRecharge 充值订单
     * @return 结果
     */
    @Override
    public int updateOrderRecharge(OrderRecharge orderRecharge) {
        orderRecharge.setUpdateTime(DateUtils.getNowDate());
        return baseMapper.updateById(orderRecharge);
    }

    /**
     * 拒绝退卡
     *
     * @param orderRechargeRefund 退卡
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int refundRechargeNo(OrderRechargeRefund orderRechargeRefund) {
        orderRechargeRefund.setRefundStatus(RechargeRefundStatusType.REFUND_REFUSE.getCode());

        OrderRecharge orderRecharge = this.getOne(new QueryWrapper<OrderRecharge>().lambda().eq(OrderRecharge::getOrderNo, orderRechargeRefund.getOrderNo()));
        if (orderRecharge == null) {
            throw new GlobalException("充值订单不存在");
        }
        RechargePasswordCard rechargePasswordCard = rechargePasswordCardService.getOne(new QueryWrapper<RechargePasswordCard>().lambda()
                .eq(RechargePasswordCard::getOrderNo, orderRecharge.getOrderNo())
                .eq(RechargePasswordCard::getDelFlag, DeleteStatus.OK.getCode()), Boolean.FALSE);
        if (rechargePasswordCard == null) {
            log.info("充值订单{}" + orderRechargeRefund.getOrderNo() + "操作退款，未找到该笔订单对应的充值卡记录");
            throw new GlobalException("未找到该笔订单对应的充值卡记录");
        }
        rechargePasswordCard.setRechargeStatus(RechargeStatusType.HAS_USE.getCode());
        rechargePasswordCard.buildUpdateData();
        rechargePasswordCardService.updateById(rechargePasswordCard);

        orderRecharge.setUpdateTime(DateUtils.getNowDate());

        orderRecharge.setRefundStatus(OrderRefundStatus.REFUND_REFUSE.getCode());
        orderRecharge.buildUpdateData();
        baseMapper.updateById(orderRecharge);

        orderRechargeRefundService.updateById(orderRechargeRefund);

        return 1;
    }


    /**
     * 同意退卡
     *
     * @param orderRechargeRefund 退卡
     * @return 结果
     */
    @Override
    public int refundRechargeYes(OrderRechargeRefund orderRechargeRefund) {

        OrderRecharge orderRecharge = this.getOne(new QueryWrapper<OrderRecharge>().lambda().eq(OrderRecharge::getOrderNo, orderRechargeRefund.getOrderNo()));
        if (orderRecharge == null) {
            throw new GlobalException("充值订单不存在");
        }
        RechargePasswordCard rechargePasswordCard = rechargePasswordCardService.getOne(new QueryWrapper<RechargePasswordCard>().lambda()
                .eq(RechargePasswordCard::getOrderNo, orderRecharge.getOrderNo())
                .eq(RechargePasswordCard::getDelFlag, DeleteStatus.OK.getCode()), Boolean.FALSE);
        if (rechargePasswordCard == null) {
            log.info("充值订单{}" + orderRechargeRefund.getOrderNo() + "操作退款，未找到该笔订单对应的充值卡记录");
            throw new GlobalException("未找到该笔订单对应的充值卡记录");
        }
        rechargePasswordCard.setRechargeStatus(RechargeStatusType.FROZEN.getCode());
        rechargePasswordCard.buildUpdateData();


        orderRecharge.setUpdateTime(DateUtils.getNowDate());
        orderRecharge.setRefundStatus(OrderRefundStatus.REFUNDING.getCode());
        orderRecharge.buildUpdateData();
        baseMapper.updateById(orderRecharge);
        orderRechargeRefund.setRefundStatus(RechargeRefundStatusType.REFUNDING.getCode());
        orderRechargeRefund.setUpdateTime(DateUtils.getNowDate());
        orderRechargeRefund.setRefundTime(DateUtils.getNowDate());
        //退款申请中
        if (orderRechargeRefund.getRefundType().equals(PayType.CASH.getCode())) {
            rechargePasswordCard.setRechargeStatus(RechargeStatusType.REFUND.getCode());
            orderRecharge.setRefundStatus(RechargeRefundStatusType.REFUND_AGREE.getCode());
            orderRechargeRefund.setRefundStatus(RechargeRefundStatusType.REFUND_AGREE.getCode());
        }
        rechargePasswordCardService.updateById(rechargePasswordCard);
        orderRechargeRefund.setRemark("退卡审核同意");
        orderRechargeRefundService.updateById(orderRechargeRefund);

        //执行退款逻辑
        PayRefundDTO payRefundDTO = null;
        if (orderRechargeRefund.getAliRefundAmount().compareTo(BigDecimal.ZERO) > 0) {
            payRefundDTO = new PayRefundDTO(PayType.ALIPAY.getCode(), orderRechargeRefund.getOrderNo()
                    , orderRechargeRefund.getAliRefundAmount(), orderRechargeRefund.getRefundNo(), orderRecharge.getOutTradeOrderNo()
                    , orderRechargeRefund.getRefundReason());
        }
        if (orderRechargeRefund.getWxRefundAmount().compareTo(BigDecimal.ZERO) > 0) {
            payRefundDTO = new PayRefundDTO(PayType.WECHAT.getCode(), orderRechargeRefund.getOrderNo()
                    , orderRechargeRefund.getWxRefundAmount(), orderRechargeRefund.getRefundNo(), orderRecharge.getOutTradeOrderNo()
                    , orderRechargeRefund.getRefundReason());
        }
        RefundResponseDTO refundResponse = payService.refundApply(payRefundDTO);
        if (refundResponse.getRefundResult().equals(PayResult.success.getCode())) {
            refundSuccess(orderRechargeRefund.getOrderNo());
        } else if (refundResponse.getRefundResult().equals(PayResult.fail.getCode())) {
            refundError(orderRechargeRefund.getOrderNo());
        } else {
            //增加到延迟支付查询队列
            DelayMessage delayMessage = new DelayMessage(payRefundDTO.getOutRequestNo(), DelayTagsEnum.ORDER_REUND_DELAY_QUEUE_TASK.getCode(), JSONUtil.toJsonStr(payRefundDTO));
            //暂不执行
            delayQueueCache.addDelayJob(delayMessage, RefundQueryTimesEnum.getDelayTime(delayMessage.getPollingNum()));
        }

//        appUserBillMstrService.refundRecord(ConsumeOrderDTO.buildOrderRechargeRefundData(orderRecharge), new RefundBaseDTO(orderNoUtils.getRefundOrderNo()));
        //查询分段支付记录
//        List<OrderRechargeInstalment> orderRechargeInstalments = getPayDetailById(orderRecharge.getId(), "2");
//        BigDecimal cashRefundAmount = orderRechargeRefund.getCashRefundAmount();
//        BigDecimal aliRefundAmount = orderRechargeRefund.getAliRefundAmount();
//        BigDecimal wxRefundAmount = orderRechargeRefund.getWxRefundAmount();
//        for (OrderRechargeInstalment orderRechargeInstalment : orderRechargeInstalments) {
//            if (orderRechargeInstalment.getPayType().equals(PayType.CASH.getCode())) {
//                if (cashRefundAmount.compareTo(BigDecimal.ZERO) == 0) {
//                    continue;
//                }
//                if (cashRefundAmount.compareTo(orderRechargeInstalment.getPayAmount()) > 0) {
//                    orderRechargeInstalmentService.refundRechargeNo(orderRechargeInstalment, orderRechargeInstalment.getPayAmount());
//                    cashRefundAmount = CurrencyUtil.sub(cashRefundAmount, orderRechargeInstalment.getPayAmount());
//                } else {
//                    orderRechargeInstalmentService.refundRechargeNo(orderRechargeInstalment, cashRefundAmount);
//                    cashRefundAmount = BigDecimal.ZERO;
//                }
//            } else if (orderRechargeInstalment.getPayType().equals(PayType.WECHAT.getCode())) {
//                if (wxRefundAmount.compareTo(BigDecimal.ZERO) == 0) {
//                    continue;
//                }
//                if (wxRefundAmount.compareTo(orderRechargeInstalment.getPayAmount()) > 0) {
//                    orderRechargeInstalmentService.refundRechargeNo(orderRechargeInstalment, orderRechargeInstalment.getPayAmount());
//                    wxRefundAmount = CurrencyUtil.sub(wxRefundAmount, orderRechargeInstalment.getPayAmount());
//                } else {
//                    orderRechargeInstalmentService.refundRechargeNo(orderRechargeInstalment, wxRefundAmount);
//                    wxRefundAmount = BigDecimal.ZERO;
//                }
//            } else if (orderRechargeInstalment.getPayType().equals(PayType.ALIPAY.getCode())) {
//                if (aliRefundAmount.compareTo(BigDecimal.ZERO) == 0) {
//                    continue;
//                }
//                if (aliRefundAmount.compareTo(orderRechargeInstalment.getPayAmount()) > 0) {
//                    orderRechargeInstalmentService.refundRechargeNo(orderRechargeInstalment, orderRechargeInstalment.getPayAmount());
//                    aliRefundAmount = CurrencyUtil.sub(aliRefundAmount, orderRechargeInstalment.getPayAmount());
//                } else {
//                    orderRechargeInstalmentService.refundRechargeNo(orderRechargeInstalment, aliRefundAmount);
//                    aliRefundAmount = BigDecimal.ZERO;
//                }
//            }
//        }
        return 1;
    }


    /**
     * 批量删除充值订单
     *
     * @param ids 需要删除的充值订单主键
     * @return 结果
     */
    @Override
    public int deleteOrderRechargeByIds(Long[] ids) {
        return baseMapper.deleteOrderRechargeByIds(ids);
    }

    /**
     * 删除充值订单信息
     *
     * @param id 充值订单主键
     * @return 结果
     */
    @Override
    public int deleteOrderRechargeById(Long id) {
        return baseMapper.deleteOrderRechargeById(id);
    }

    @Override
    public List<OrderRechargeInstalment> getPayDetailById(Long orderId, String orderStatus) {
        return baseMapper.getPayDetailById(orderId, orderStatus);
    }


    //<editor-folder desc="充值订单相关自定义接口">

    /**
     * 新增充值订单
     *
     * @param orderRechargeCreateDTO 充值订单
     * @return 结果
     */
    @Override
    public OrderPayResultVO insertOrderRecharge(OrderRechargeCreateDTO orderRechargeCreateDTO) {
        // 创建订单 并保存
        OrderRecharge orderRecharge = this.buildOrderRechargeData(orderRechargeCreateDTO);
        //创建支付记录
        orderRecharge.setCashPayAmount(BigDecimal.ZERO);
        orderRecharge.setAliPayAmount(BigDecimal.ZERO);
        orderRecharge.setWxPayAmount(BigDecimal.ZERO);
        orderRecharge.setPayType(orderRechargeCreateDTO.getPayType());
        if (orderRechargeCreateDTO.getOrderSource().equals(OrderSourceType.OFFLINE.getCode())) {
            if (orderRechargeCreateDTO.getPayType().equals(PayType.CASH.getCode())) {
                orderRecharge.setCashPayAmount(orderRechargeCreateDTO.getPayAmount());
            }
            if (orderRechargeCreateDTO.getPayType().equals(PayType.WECHAT.getCode())) {
                String payType = null;
                try {
                    payType = PayCodeUtils.getPayTypeByCode(orderRechargeCreateDTO.getAuthCode());
                } catch (ServiceException e) {
                    return OrderPayResultVO.payError(e.getMessage());
                }
                if (payType.equals(PayType.WECHAT.getCode())) {
                    orderRecharge.setWxPayAmount(orderRechargeCreateDTO.getPayAmount());
                }
                if (payType.equals(PayType.ALIPAY.getCode())) {
                    orderRecharge.setAliPayAmount(orderRechargeCreateDTO.getPayAmount());
                }
                orderRecharge.setPayType(payType);
            }
            if (orderRechargeCreateDTO.getPayType().equals(PayType.COMBINE.getCode())) {
                BigDecimal total = CurrencyUtil.add(orderRechargeCreateDTO.getCashPayAmount(), orderRechargeCreateDTO.getOtherPayAmount());
                if (!total.equals(orderRechargeCreateDTO.getPayAmount())) {
                    return OrderPayResultVO.payError("支付金额不正确，请修改");
                }
                orderRecharge.setCashPayAmount(orderRechargeCreateDTO.getCashPayAmount());
                String payType = null;
                try {
                    payType = PayCodeUtils.getPayTypeByCode(orderRechargeCreateDTO.getAuthCode());
                } catch (ServiceException e) {
                    return OrderPayResultVO.payError(e.getMessage());
                }
                if (payType.equals(PayType.WECHAT.getCode())) {
                    orderRecharge.setWxPayAmount(orderRechargeCreateDTO.getOtherPayAmount());
                }
                if (payType.equals(PayType.ALIPAY.getCode())) {
                    orderRecharge.setAliPayAmount(orderRechargeCreateDTO.getOtherPayAmount());
                }
            }
        } else {
            if (orderRechargeCreateDTO.getPayType().equals(PayType.WECHAT.getCode())) {
                orderRecharge.setWxPayAmount(orderRecharge.getPayAmount());
            }
            if (orderRechargeCreateDTO.getPayType().equals(PayType.ALIPAY.getCode())) {
                orderRecharge.setAliPayAmount(orderRecharge.getPayAmount());
            }
        }

        OrderPayResultVO orderPayResultVO = new OrderPayResultVO();
        orderPayResultVO.setOrderNo(orderRecharge.getOrderNo());
        this.save(orderRecharge);

        //APP=APP、WEAPP=小程序、WEB=web后台
        if (orderRechargeCreateDTO.getOrderSource().equals(OrderSourceType.APP.getCode())) {
            orderPayResultVO.setAppPayRespVO(payService.appPay(PayOrderAppDTO.buildRechargeOrderPayData(orderRecharge, orderRechargeCreateDTO.getPlatform())));
            this.updateById(orderRecharge);
            return orderPayResultVO;
        }
        if (orderRechargeCreateDTO.getOrderSource().equals(OrderSourceType.OFFLINE.getCode())) {
            //现金支付
            if (orderRechargeCreateDTO.getPayType().equals(PayType.CASH.getCode())) {
                paySuccess(orderRecharge, null);
                return OrderPayResultVO.paySuccess(orderRecharge.getOrderNo());
            }
            if (orderRecharge.getWxPayAmount().compareTo(BigDecimal.ZERO) > 0 || orderRecharge.getAliPayAmount().compareTo(BigDecimal.ZERO) > 0) {
                this.updateById(orderRecharge);
                try {
                    //创建支付订单，防止出现错误
                    BigDecimal payAmount = CurrencyUtil.add(orderRecharge.getWxPayAmount(), orderRecharge.getAliPayAmount());
                    OrderPayInfo orderPayInfo = orderPayInfoService.createOrderPayInfo(orderRecharge.getOrderNo(), payAmount, orderRecharge.getWxPayAmount().compareTo(BigDecimal.ZERO) > 0 ? PayType.WECHAT.getCode() : PayType.ALIPAY.getCode());
                    //优先增加到延迟队列
                    DelayMessage delayMessage = new DelayMessage(orderPayInfo.getPayOrderNo(), DelayTagsEnum.ORDER_PAY_DELAY_QUEUE.getCode(), JSONUtil.toJsonStr(orderPayInfo));
                    //暂不执行
                    delayMessage.setIsRun(0);
                    delayQueueCache.addDelayJob(delayMessage, PayQueryTimesEnum.getDelayTime(delayMessage.getPollingNum()));
                    PayResponseDTO payResponseDTO = payService.faceToFacePay(PayOrderFaceToFaceDTO.createRechargeOrderPayData(orderPayInfo.getPayOrderNo(), orderPayInfo.getPayAmount(), orderPayInfo.getPayType(), orderRechargeCreateDTO.getAuthCode()));
                    if (payResponseDTO.getPayResult().equals(PayResult.success.getCode())) {
                        paySuccess(orderRecharge, payResponseDTO.getOutTradeNo());
                        delayQueueCache.deleteDelayJob(orderPayInfo.getPayOrderNo());
                        return OrderPayResultVO.paySuccess(orderRecharge.getOrderNo());
                    } else if (payResponseDTO.getPayResult().equals(PayResult.fail.getCode())) {
                        delayQueueCache.deleteDelayJob(orderPayInfo.getPayOrderNo());
                        return OrderPayResultVO.payError(payResponseDTO.getPayMsg());
                    } else {//更新开始执行查询
                        delayMessage.setIsRun(1);
                        delayQueueCache.addDelayJob(delayMessage, PayQueryTimesEnum.getDelayTime(delayMessage.getPollingNum()));
                        return OrderPayResultVO.payWait(orderRecharge.getOrderNo());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    return OrderPayResultVO.payError("扫收款码支付失败");
                }
            }
        }
        return orderPayResultVO;
    }

    @Override
    public OrderPayResultVO insertOrderRechargeByPasscard(OrderRechargeCreateDTO orderRechargeCreateDTO) {
        // 是卡密充值
        RechargePasswordCard rechargePasswordCard = rechargePasswordCardService.getOne(new QueryWrapper<RechargePasswordCard>().lambda()
                .eq(RechargePasswordCard::getCardNo, orderRechargeCreateDTO.getCardNo())
                .eq(RechargePasswordCard::getPassword, orderRechargeCreateDTO.getPassword())
                .eq(RechargePasswordCard::getRechargeStatus, RechargeStatusType.NOT_UES.getCode())
                .eq(RechargePasswordCard::getDelFlag, DeleteStatus.OK.getCode()));
        if (rechargePasswordCard == null) {
            throw new ServiceException("未查询到可用充值卡，请检查您的卡号密码是否正确");
        }
        //判断充值卡是否为本门店的充值卡
//        if (PlatformType.STORE.getCode().equals(AuthHolder.platform()) && rechargePasswordCard.getRechargeSourceType() != null
//                &&   (!SecurityUtils.getLoginUser().getSourceType().equals(rechargePasswordCard.getRechargeSourceType())
//                || !SecurityUtils.getLoginUser().getOrgId().equals(rechargePasswordCard.getRechargeOrgId()))
//        ){
//            throw new ServiceException("本充值卡非本门店发售，请到指定门店充值");
//        }
        // 保存订单
        OrderRecharge orderRecharge = this.buildOrderRechargeByCardPassword(rechargePasswordCard, orderRechargeCreateDTO);
        rechargePasswordCard.setRechargeUserId(orderRecharge.getAppUserId());
        rechargePasswordCard.setRechargeTime(DateUtils.getNowDate());
        rechargePasswordCard.setRechargeStatus(RechargeStatusType.HAS_USE.getCode());
        rechargePasswordCard.setOrderNo(orderRecharge.getOrderNo());
        rechargePasswordCard.buildUpdateData();
        rechargePasswordCardService.updateById(rechargePasswordCard);

        // 保存消费日志
        BillMstrOrderDTO billMstrOrderDTO = new BillMstrOrderDTO();
        billMstrOrderDTO.setAppUserId(orderRecharge.getAppUserId());
        billMstrOrderDTO.setStoreId(orderRecharge.getStoreId());
        billMstrOrderDTO.setOrderNo(orderRecharge.getOrderNo());
        billMstrOrderDTO.setOrderType(OrderType.recharge.getCode());
        billMstrOrderDTO.setRechargePayAmount(orderRecharge.getRechargeAmount());
        billMstrOrderDTO.setWelfarePayAmount(orderRecharge.getWelfareAmount());
        billMstrOrderDTO.setGivePayAmount(orderRecharge.getGiveAmount());
        billMstrOrderDTO.setRechargeCardNo(orderRecharge.getRechargeCardNo());
        BigDecimal totalPayAmount = CurrencyUtil.add(orderRecharge.getRechargeAmount(), orderRecharge.getGiveAmount(), orderRecharge.getWelfareAmount());
        billMstrOrderDTO.setPayTotalAmount(totalPayAmount);
        billMstrOrderDTO.setRemark("充值卡：" + rechargePasswordCard.getCardNo() + "卡密激活，到账" + totalPayAmount + "元");
        billMstrOrderService.saveBillMstrOrder(billMstrOrderDTO);

        OrderPayResultVO orderPayResultVO = new OrderPayResultVO();
        orderPayResultVO.setIsAllPayEnd(Boolean.TRUE);
        orderPayResultVO.setOrderNo(orderRecharge.getOrderNo());
        return orderPayResultVO;
    }

    @Override
    public void paySuccess(OrderRecharge orderRecharge, String outTradeNo) {
        if (orderRecharge.getOrderStatus().equals(OrderRechargeStatus.YES_PAY.getCode()) || orderRecharge.getOrderStatus().equals(OrderRechargeStatus.REFUND.getCode())) {
            return;
        }
        Date date = DateUtils.getNowDate();
        orderRecharge.setOutTradeOrderNo(outTradeNo);
        orderRecharge.setOrderStatus(OrderRechargeStatus.YES_PAY.getCode());
        orderRecharge.setPayTime(date);
        this.updateById(orderRecharge);
        // 同步生成密码卡
        RechargePasswordCard rechargePasswordCard = this.buildRechargePasswordCardData(orderRecharge);

        //添加用户积分
        appUserPointLogService.addPoint(orderRecharge.getAppUserId(), orderRecharge.getGivePointAmount().intValue(), orderRecharge.getOrderNo(), MemberPointSourceEnum.RECHARGEADD, "会员储值赠送");

        //保存日志
        BillMstrOrderDTO billMstrOrderDTO = new BillMstrOrderDTO();
        billMstrOrderDTO.setAppUserId(orderRecharge.getAppUserId());
        billMstrOrderDTO.setStoreId(orderRecharge.getStoreId());
        billMstrOrderDTO.setOrderNo(orderRecharge.getOrderNo());
        billMstrOrderDTO.setOrderType(OrderType.recharge.getCode());
        billMstrOrderDTO.setRechargePayAmount(orderRecharge.getRechargeAmount());
        billMstrOrderDTO.setWelfarePayAmount(orderRecharge.getWelfareAmount());
        billMstrOrderDTO.setGivePayAmount(orderRecharge.getGiveAmount());
        billMstrOrderDTO.setRechargeCardNo(orderRecharge.getRechargeCardNo());
        BigDecimal totalPayAmount = CurrencyUtil.add(orderRecharge.getRechargeAmount(), orderRecharge.getGiveAmount(), orderRecharge.getWelfareAmount());
        billMstrOrderDTO.setPayTotalAmount(totalPayAmount);
        billMstrOrderDTO.setRemark("充值卡：" + rechargePasswordCard.getCardNo() + "，储值到账" + totalPayAmount + "元");
        billMstrOrderService.saveBillMstrOrder(billMstrOrderDTO);
        log.info("本充值订单已全部支付完，订单号：{}, 支付金额：{}", orderRecharge.getOrderNo(), orderRecharge.getPayAmount());
    }

    /**
     * 充值订单 处理优惠券使用情况
     *
     * @param orderRecharge
     * @param couponIds
     */
    private void handleOrderCoupon(OrderRecharge orderRecharge, List<Long> couponIds) {
        if (couponIds == null || couponIds.size() == 0) {
            log.debug("优惠券为空，不做处理");
            return;
        }
        Map<Long, AppCouponItem> appCouponItemMap = appCouponItemService.list(new QueryWrapper<AppCouponItem>().lambda()
                        .eq(AppCouponItem::getAppUserId, orderRecharge.getAppUserId())
                        .eq(AppCouponItem::getIsUsed, SysBoolType.NO.getCode())
                        .in(AppCouponItem::getId, couponIds))
                .stream().collect(Collectors.toMap(AppCouponItem::getId, AppCouponItem -> AppCouponItem));
        if (CollUtil.isEmpty(appCouponItemMap)) {
            throw new ServiceException("未能查询到可用于抵用充值的优惠券");
        }
        if (appCouponItemMap.size() != couponIds.size()) {
            throw new ServiceException("存在不可用优惠券，请检查后再操作");
        }
        BigDecimal deductRechargeAmount = BigDecimal.ZERO;
        List<OrderRechargeCouponRelation> orderRechargeCouponRelations = new ArrayList<>();
        for (Long couponId : couponIds) {
            OrderRechargeCouponRelation orderRechargeCouponRelation = new OrderRechargeCouponRelation();
            orderRechargeCouponRelation.setOrderId(orderRecharge.getId());
            orderRechargeCouponRelation.setOrderNo(orderRecharge.getOrderNo());
            orderRechargeCouponRelation.setCouponItemId(couponId);
            orderRechargeCouponRelation.setDeductAmount(BigDecimal.ZERO);
            orderRechargeCouponRelation.buildCreateData();
            orderRechargeCouponRelations.add(orderRechargeCouponRelation);

            deductRechargeAmount = deductRechargeAmount.add(BigDecimal.ZERO);
        }
        orderRechargeCouponRelationService.saveBatch(orderRechargeCouponRelations);

        orderRecharge.setCouponDeductAmount(deductRechargeAmount);
        orderRecharge.setPayAmount
                (
                        orderRecharge.getPayAmount().subtract(deductRechargeAmount).compareTo(BigDecimal.ZERO) < 0
                                ? BigDecimal.ZERO : orderRecharge.getPayAmount().subtract(deductRechargeAmount)
                );

        //优惠券使用完后，将优惠券修改为已使用状态
        appCouponItemService.update(new UpdateWrapper<AppCouponItem>()
                .lambda().set(AppCouponItem::getIsUsed, SysBoolType.YES.getCode())
                .set(AppCouponItem::getUsedStoreId, SecurityUtils.getLoginUser().getOrgId())
                .set(AppCouponItem::getUsedTime, DateUtils.getNowDate())
                .eq(AppCouponItem::getAppUserId, orderRecharge.getAppUserId())
                .in(AppCouponItem::getId, couponIds));
    }

    private OrderRecharge buildOrderRechargeData(OrderRechargeCreateDTO orderRechargeCreateDTO) {
        OrderRecharge orderRecharge = new OrderRecharge();
        orderRecharge.buildCreateData();
        orderRecharge.setRemark(orderRechargeCreateDTO.getRemark());
        orderRecharge.setOrderNo(orderNoUtils.getRechargeOrderNo());
        orderRecharge.setAppUserId(orderRechargeCreateDTO.getAppUserId());
        orderRecharge.setPayType(orderRechargeCreateDTO.getPayType());
        orderRecharge.setRechargeType(orderRechargeCreateDTO.getRechargeType());
        orderRecharge.setRechargeTypeId(orderRechargeCreateDTO.getRechargeTypeId());
        orderRecharge.setDelFlag(DeleteStatus.OK.getCode());
        orderRecharge.setOrderStatus(OrderRechargeStatus.NO_PAY.getCode());
        orderRecharge.setOrderSource(orderRechargeCreateDTO.getOrderSource());
        //充值套餐充值
        if (orderRechargeCreateDTO.getRechargeTypeId() != null) {
            RechargeType rechargeType = rechargeTypeService.getById(orderRechargeCreateDTO.getRechargeTypeId());
            if (rechargeType == null) {
                throw new ServiceException("未查询到该充值套餐");
            }
            // 如果套餐充值 有符合的活动，则使用该活动的赠送金额
            ActivityRechargeItem giveAmountByActivity = activityRechargeItemService.getGiveAmountByActivity(orderRechargeCreateDTO.getRechargeTypeId(), orderRechargeCreateDTO.getOrgId());
            if (giveAmountByActivity != null) {
                rechargeType.setGiveAmount(giveAmountByActivity.getActivityGiveAmount());
                orderRecharge.setActivityId(giveAmountByActivity.getActivityId());
            }
            orderRecharge.setPayAmount(rechargeType.getRechargeAmount());
            orderRecharge.setRechargeAmount(rechargeType.getRechargeAmount() == null ? BigDecimal.ZERO : rechargeType.getRechargeAmount());
            orderRecharge.setWelfareAmount(BigDecimal.ZERO);
            orderRecharge.setGiveAmount(rechargeType.getGiveAmount() == null ? BigDecimal.ZERO : rechargeType.getGiveAmount());
            orderRecharge.setGivePointAmount(rechargeType.getGivePointAmount() == null ? 0 : rechargeType.getGivePointAmount());
        } else {
            orderRecharge.setPayAmount(orderRechargeCreateDTO.getPayAmount());
            orderRecharge.setRechargeAmount(orderRechargeCreateDTO.getRechargeAmount() == null ? BigDecimal.ZERO : orderRechargeCreateDTO.getRechargeAmount());
            orderRecharge.setWelfareAmount(orderRechargeCreateDTO.getWelfareAmount() == null ? BigDecimal.ZERO : orderRechargeCreateDTO.getWelfareAmount());
            orderRecharge.setGiveAmount(orderRechargeCreateDTO.getGiveAmount() == null ? BigDecimal.ZERO : orderRechargeCreateDTO.getGiveAmount());
            orderRecharge.setGivePointAmount(orderRechargeCreateDTO.getGivePointAmount() == null ? 0 : orderRechargeCreateDTO.getGivePointAmount());
        }
        orderRecharge.setCashPayAmount(BigDecimal.ZERO);
        orderRecharge.setAliPayAmount(BigDecimal.ZERO);
        orderRecharge.setWxPayAmount(BigDecimal.ZERO);
        // app支付充值
        if (OrderSourceType.APP.getCode().equals(orderRechargeCreateDTO.getOrderSource())) {
            orderRecharge.setStoreId(orderRechargeCreateDTO.getOrgId());
            orderRecharge.setSource("APP_ORDER");
        } else {
            // 门店支付充值
            orderRecharge.setSource("STORE_ORDER");
            orderRecharge.setStoreId(orderRechargeCreateDTO.getOrgId());
        }
        return orderRecharge;
    }

    /**
     * 通过密码卡，保存充值订单
     *
     * @param rechargePasswordCard
     * @param orderRechargeCreateDTO
     * @return
     */
    @Override
    public OrderRecharge buildOrderRechargeByCardPassword(RechargePasswordCard rechargePasswordCard, OrderRechargeCreateDTO orderRechargeCreateDTO) {
        OrderRecharge orderRecharge = new OrderRecharge();
        // 保存订单主表
        orderRecharge.setCreateById(rechargePasswordCard.getCreateById());
        orderRecharge.setCreateBy(rechargePasswordCard.getCreateBy());
        orderRecharge.setCreateTime(DateUtils.getNowDate());
        orderRecharge.setOrderNo(orderNoUtils.getRechargeOrderNo());
        orderRecharge.setAppUserId(orderRechargeCreateDTO.getAppUserId());
        orderRecharge.setRechargeType(orderRechargeCreateDTO.getRechargeType());
        orderRecharge.setPayTime(DateUtils.getNowDate());
        orderRecharge.setPayType(PayType.RECHARGE_CARD.getCode());
        orderRecharge.setDelFlag(DeleteStatus.OK.getCode());
        orderRecharge.setOrderStatus(OrderRechargeStatus.YES_PAY.getCode());
        orderRecharge.setOrderSource(orderRechargeCreateDTO.getOrderSource());
        orderRecharge.setRechargeCardNo(rechargePasswordCard.getCardNo());
        orderRecharge.setPayAmount(rechargePasswordCard.getRechargeAmount());
        orderRecharge.setCashPayAmount(rechargePasswordCard.getRechargeAmount());
        orderRecharge.setWxPayAmount(BigDecimal.ZERO);
        orderRecharge.setAliPayAmount(BigDecimal.ZERO);
        orderRecharge.setRechargeAmount(rechargePasswordCard.getRechargeAmount() == null ? BigDecimal.ZERO : rechargePasswordCard.getRechargeAmount());
        orderRecharge.setGiveAmount(rechargePasswordCard.getGiveAmount() == null ? BigDecimal.ZERO : rechargePasswordCard.getGiveAmount());
        orderRecharge.setGivePointAmount(rechargePasswordCard.getGivePointAmount() == null ? 0 : rechargePasswordCard.getGivePointAmount());
        this.save(orderRecharge);

        return orderRecharge;
    }

    /**
     * 保存子表-支付记录
     *
     * @param orderRecharge 充值订单实例
     * @return
     */
    public OrderRechargeInstalment buildRechargeRelationData(OrderRecharge orderRecharge, BigDecimal thisPayAmount) {
        // 保存子表
        OrderRechargeInstalment orderRechargeInstalment = new OrderRechargeInstalment();
        orderRechargeInstalment.buildCreateData();
        orderRechargeInstalment.setOrgId(orderRecharge.getStoreId());
        orderRechargeInstalment.setMstrOrderNo(orderRecharge.getOrderNo());
        orderRechargeInstalment.setPayType(orderRecharge.getPayType());
        if (orderRecharge.getIsInstalment() != null || SysBoolType.YES.getCode().equals(orderRecharge.getIsInstalment())) {
            // 分段支付
            orderRechargeInstalment.setPayAmount(thisPayAmount);
        } else {
            orderRechargeInstalment.setPayAmount(orderRecharge.getPayAmount());
        }
        orderRechargeInstalment.setOrderStatus(OrderRechargeStatus.NO_PAY.getCode());
        orderRechargeInstalment.setOrderNo(orderNoUtils.getRechargeOrderNo());
        orderRechargeInstalment.setOutTradeOrderNo(orderRecharge.getOutTradeOrderNo());
        return orderRechargeInstalment;
    }

    /**
     * 校验是否全部支付完成
     *
     * @param orderRecharge 主表信息
     * @return
     */
    public Boolean checkIsAllPay(OrderRecharge orderRecharge) {
        // 已支付 总和
        BigDecimal totalPayAmount = orderRechargeInstalmentService.getTotalPayAmount(orderRecharge.getOrderNo());
        return orderRecharge.getPayAmount().compareTo(totalPayAmount) == 0;
    }

    /**
     * 校验是否本次支付是否
     *
     * @param orderRecharge 主表信息
     * @return
     */
    public Boolean checkPayMoneyIsMore(OrderRecharge orderRecharge, BigDecimal nowPayMoney) {
        // 已支付 总和
        BigDecimal totalPayAmount = orderRechargeInstalmentService.getTotalPayAmount(orderRecharge.getOrderNo());
        BigDecimal allPay;
        if (totalPayAmount != null) {
            allPay = totalPayAmount.add(nowPayMoney);
        } else {
            allPay = nowPayMoney;
        }
        if (orderRecharge.getPayAmount().compareTo(allPay) < 0) {
            return Boolean.FALSE;
        }

        return Boolean.TRUE;
    }

    /**
     * 支付完成后， 创建密码卡， 更新订单信息
     *
     * @param orderRecharge 订单编号
     */
    @Override
    public void creatPassWordCard(OrderRecharge orderRecharge, OrderRechargeInstalment orderRechargeInstalment, OrderPayResultVO orderPayResultVO) {
        Date date = DateUtils.getNowDate();
        orderRechargeInstalment.setOrderStatus(OrderRechargeStatus.YES_PAY.getCode());
        orderRechargeInstalment.setPayTime(date);
        orderRechargeInstalmentService.updateById(orderRechargeInstalment);

        orderPayResultVO.setOrderNo(orderRechargeInstalment.getOrderNo());
        // 校验是否全部支付完成
        // 更新订单信息
        if (orderRechargeInstalment.getPayType().equals(PayType.CASH.getCode())) {
            orderRecharge.setCashPayAmount(CurrencyUtil.add(orderRecharge.getCashPayAmount(), orderRechargeInstalment.getPayAmount()));
        } else if (orderRechargeInstalment.getPayType().equals(PayType.WECHAT.getCode())) {
            orderRecharge.setWxPayAmount(CurrencyUtil.add(orderRecharge.getWxPayAmount(), orderRechargeInstalment.getPayAmount()));
        } else if (orderRechargeInstalment.getPayType().equals(PayType.ALIPAY.getCode())) {
            orderRecharge.setAliPayAmount(CurrencyUtil.add(orderRecharge.getAliPayAmount(), orderRechargeInstalment.getPayAmount()));
        }
        if (!checkIsAllPay(orderRecharge)) {
            log.info("本次支付完成，但未全部支付完，订单号：" + orderRechargeInstalment.getMstrOrderNo());
            this.updateById(orderRecharge);
            orderPayResultVO.setIsAllPayEnd(Boolean.FALSE);
            return;
        }
        orderRecharge.setOrderStatus(OrderRechargeStatus.YES_PAY.getCode());
        orderRecharge.setPayTime(date);
        this.updateById(orderRecharge);
        // 同步生成密码卡
        this.buildRechargePasswordCardData(orderRecharge);
        // 保存消费日志
        appUserBillMstrService.consumeRecord(ConsumeOrderDTO.buildOrderRechargeData(orderRecharge));

        orderPayResultVO.setIsAllPayEnd(Boolean.TRUE);
        log.info("本充值订单已全部支付完，订单号：" + orderRechargeInstalment.getMstrOrderNo());
    }


    /**
     * 支付完成后， 创建密码卡， 更新订单信息
     *
     * @param orderNo 每次支付的订单编号
     *                这里分两种情况
     *                1、 app 直接整个订单一次性支付，所以orderNo是唯一且是主订单的订单编号
     *                2、 pc端存在分段多次支付同一个订单情况， 所以上报的时候，不能用同一个订单，否则微信/支付宝会报错，
     *                这里需要唯一的，所以拿子表分段支付订单编号
     */
    @Override
    public R creatPassWordCardByPayNotify(String orderNo, String outTradeNo) {
        OrderRecharge orderRecharge = getOrderRechargeByOrderNo(orderNo);
        if (orderRecharge == null) {
            log.error("充值支付成功订单不存在：" + orderNo);
            return R.fail("充值支付成功订单不存在");
        }
        paySuccess(orderRecharge, outTradeNo);
        return R.ok();
    }

    @Override
    public OrderRecharge getOrderRechargeByOrderNo(String orderNo) {
        OrderRecharge orderRecharge = this.getOne(new QueryWrapper<OrderRecharge>().lambda().eq(OrderRecharge::getOrderNo, orderNo));
        return orderRecharge;
    }


    /**
     * 生成密码卡
     *
     * @param orderRecharge
     * @return
     */
    public RechargePasswordCard buildRechargePasswordCardData(OrderRecharge orderRecharge) {
        RechargePasswordCard rechargePasswordCard = new RechargePasswordCard();
        rechargePasswordCard.setOrderNo(orderRecharge.getOrderNo());
        rechargePasswordCard.setCardNo(orderNoUtils.getOrderNo());
        rechargePasswordCard.setUseBindStoreId(orderRecharge.getStoreId());
        rechargePasswordCard.setRechargeAmount(orderRecharge.getRechargeAmount());
        rechargePasswordCard.setGiveAmount(orderRecharge.getGiveAmount());
        rechargePasswordCard.setGivePointAmount(orderRecharge.getGivePointAmount());
        rechargePasswordCard.setWelfareAmount(orderRecharge.getWelfareAmount());

        rechargePasswordCard.setRechargeBalance(rechargePasswordCard.getRechargeAmount());
        rechargePasswordCard.setGiveBalance(rechargePasswordCard.getGiveAmount());
        rechargePasswordCard.setWelfareBalance(rechargePasswordCard.getWelfareAmount());

        rechargePasswordCard.setRechargeStatus(RechargeStatusType.HAS_USE.getCode());
        rechargePasswordCard.setRechargeTime(DateUtils.getNowDate());
        rechargePasswordCard.setRechargeUserId(orderRecharge.getAppUserId());
        rechargePasswordCard.setRechargeStoreId(orderRecharge.getStoreId());
        rechargePasswordCard.setDelFlag(DeleteStatus.OK.getCode());
        rechargePasswordCard.setCreateBy(orderRecharge.getCreateBy());
        rechargePasswordCard.setCreateById(orderRecharge.getCreateById());
        rechargePasswordCard.setCreateTime(orderRecharge.getCreateTime());
        rechargePasswordCard.setCreateType(RechargeCreateType.ONLINE_RECHARGE.getCode());
        rechargePasswordCard.setIsSupportLife(SysBoolType.YES.getCode());
        rechargePasswordCard.setIsSupportGoods(SysBoolType.YES.getCode());
        rechargePasswordCard.setIsSupportCloth(SysBoolType.YES.getCode());
        rechargePasswordCard.setIsSupportCar(SysBoolType.YES.getCode());
        rechargePasswordCardService.save(rechargePasswordCard);
        return rechargePasswordCard;
    }

    /**
     * 查询门店会员充值记录
     *
     * @param useId
     */
    @Override
    public List<OrderRechargeRecordVO> getRechargeRecordByUserId(Long useId) {
        List<OrderRechargeRecordVO> record = baseMapper.getRechargeRecordByUserId(useId);
        RechargePasswordCard rechargePasswordCard = rechargePasswordCardService.selectTotalBalanceGroupByAppUser(useId);
        if (rechargePasswordCard == null) {
            return record;
        }
        BigDecimal bigDecimal = rechargePasswordCard.getRechargeBalance().add(rechargePasswordCard.getGiveBalance());
        for (OrderRechargeRecordVO vo : record) {
            vo.setTotalBalance(bigDecimal);
        }
        return record;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int refundRechargeApply(OrderRechargeRefundDTO orderRechargeRefundDTO) {
        log.info("充值订单{}" + orderRechargeRefundDTO.getOrderId() + "申请退款");
        log.info("充值订单申请退款,操作人" + AuthHolder.userId());
        OrderRecharge orderRecharge = baseMapper.selectById(orderRechargeRefundDTO.getOrderId());
        if (orderRecharge == null) {
            throw new GlobalException("订单不存在");
        }
        if (!OrderRechargeStatus.YES_PAY.getCode().equals(orderRecharge.getOrderStatus())) {
            throw new GlobalException("订单状态不对，不能操作退款");
        }
        RechargePasswordCard rechargePasswordCard = rechargePasswordCardService.getOne(new QueryWrapper<RechargePasswordCard>().lambda()
                .eq(RechargePasswordCard::getOrderNo, orderRecharge.getOrderNo())
                .eq(RechargePasswordCard::getDelFlag, DeleteStatus.OK.getCode()), Boolean.FALSE);
        if (rechargePasswordCard == null) {
            log.info("充值订单{}" + orderRechargeRefundDTO.getOrderId() + "申请退款，未找到该笔订单对应的充值卡记录");
            throw new GlobalException("未找到该笔订单对应的充值卡记录");
        }
        rechargePasswordCard.setRefundTime(DateUtils.getNowDate());
        rechargePasswordCard.buildUpdateData();
        //已冻结
        rechargePasswordCard.setRechargeStatus(RechargeStatusType.FROZEN.getCode());
        rechargePasswordCardService.updateById(rechargePasswordCard);

        //创建退款订单
        OrderRechargeRefund orderRechargeRefund = new OrderRechargeRefund();
        orderRechargeRefund.setOrderNo(orderRecharge.getOrderNo());
        orderRechargeRefund.setRefundNo(orderNoUtils.getRechargeOrderNo());
        orderRechargeRefund.setCardNo(rechargePasswordCard.getCardNo());
        orderRechargeRefund.setRechargeStoreId(rechargePasswordCard.getRechargeStoreId());
        orderRechargeRefund.setUseBindStoreId(rechargePasswordCard.getUseBindStoreId());
        orderRechargeRefund.setRechargeUserId(orderRecharge.getAppUserId());
        orderRechargeRefund.setRefundType(orderRecharge.getPayType());
        orderRechargeRefund.setPayAmount(orderRecharge.getPayAmount());
        orderRechargeRefund.setRechargeAmount(orderRecharge.getRechargeAmount());
        orderRechargeRefund.setGiveAmount(orderRecharge.getGiveAmount());
        orderRechargeRefund.setWelfareAmount(orderRecharge.getWelfareAmount());
        orderRechargeRefund.setWelfareBalance(rechargePasswordCard.getWelfareBalance());
        orderRechargeRefund.setRechargeBalance(rechargePasswordCard.getRechargeBalance());
        orderRechargeRefund.setGiveBalance(rechargePasswordCard.getGiveBalance());
        orderRechargeRefund.setRefundAmount(rechargePasswordCard.getRechargeBalance());
        //判断退款金额，如果不是组合支付，则直接退
        orderRechargeRefund.setAliRefundAmount(BigDecimal.ZERO);
        orderRechargeRefund.setWxRefundAmount(BigDecimal.ZERO);
        orderRechargeRefund.setCashRefundAmount(BigDecimal.ZERO);
        if (orderRechargeRefund.getRefundType().equals(PayType.WECHAT.getCode())) {
            orderRechargeRefund.setWxRefundAmount(rechargePasswordCard.getRechargeBalance());
        } else if (orderRechargeRefund.getRefundType().equals(PayType.ALIPAY.getCode())) {
            orderRechargeRefund.setAliRefundAmount(rechargePasswordCard.getRechargeBalance());
        } else if (orderRechargeRefund.getRefundType().equals(PayType.CASH.getCode())) {
            orderRechargeRefund.setCashRefundAmount(rechargePasswordCard.getRechargeBalance());
        } else if (orderRechargeRefund.getRefundType().equals(PayType.COMBINE.getCode())) {
            //组合支付，优先退微信支付宝，最后退现金，如果微信支付宝金额大于余额，则只退微信支付宝
            BigDecimal remainAmount = CurrencyUtil.sub(rechargePasswordCard.getRechargeBalance(), orderRechargeRefund.getWxRefundAmount(), orderRechargeRefund.getAliRefundAmount());
            if (remainAmount.compareTo(BigDecimal.ZERO) > 0) {
                //退现金
                orderRechargeRefund.setCashRefundAmount(remainAmount);
            }
            if (orderRecharge.getAliPayAmount().compareTo(BigDecimal.ZERO) > 0) {
                orderRechargeRefund.setAliRefundAmount(rechargePasswordCard.getRechargeBalance());
            }
            if (orderRecharge.getWxPayAmount().compareTo(BigDecimal.ZERO) > 0) {
                orderRechargeRefund.setWxRefundAmount(rechargePasswordCard.getRechargeBalance());
            }
        }
        orderRechargeRefund.setRefundApplyTime(DateUtils.getNowDate());
        orderRechargeRefund.setRefundTime(DateUtils.getNowDate());
        orderRechargeRefund.setRefundReason(orderRechargeRefundDTO.getRefundDescribe());
        orderRechargeRefund.setDelFlag(DeleteStatus.OK.getCode());
        //退款中
        orderRechargeRefund.setRefundStatus(OrderRefundStatus.REFUND_APPLYING.getCode());
        orderRechargeRefund.buildCreateData();
        orderRechargeRefundService.insertOrderRechargeRefund(orderRechargeRefund);

        orderRecharge.setRefundAmount(rechargePasswordCard.getRechargeBalance());
        orderRecharge.setRefundApplyTime(DateUtils.getNowDate());
        orderRecharge.setRefundTime(DateUtils.getNowDate());
        orderRecharge.setRefundDescribe(orderRechargeRefundDTO.getRefundDescribe());
        orderRecharge.setRefundStatus(OrderRefundStatus.REFUND_APPLYING.getCode());
        orderRecharge.buildUpdateData();
        baseMapper.updateById(orderRecharge);
        // 执行退款
        return 1;
    }

    @Override
    public R refundSuccess(String orderNo) {
        OrderRecharge orderRecharge = getOrderRechargeByOrderNo(orderNo);
        if (orderRecharge == null) {
            throw new ServiceException("未查询到订单");
        }
        if (orderRecharge.getRefundStatus() != OrderRefundStatus.REFUNDING.getCode()
                && orderRecharge.getRefundStatus() != OrderRefundStatus.REFUND_APPLYING.getCode()
                && orderRecharge.getRefundStatus() != OrderRefundStatus.ERROR.getCode()) {//退款状态不正确，直接跳过
            return R.ok();
        }

        orderRecharge.setRefundStatus(OrderRefundStatus.REFUND_SUCCESS.getCode());
        this.updateById(orderRecharge);

        RechargePasswordCard rechargePasswordCard = rechargePasswordCardService.getOne(new QueryWrapper<RechargePasswordCard>().lambda()
                .eq(RechargePasswordCard::getOrderNo, orderRecharge.getOrderNo())
                .eq(RechargePasswordCard::getDelFlag, DeleteStatus.OK.getCode()), Boolean.FALSE);
        if (rechargePasswordCard == null) {
            log.error("充值卡退款成功，订单不存在：" + orderNo);
            throw new GlobalException("充值卡不存在");
        }
        rechargePasswordCard.setRechargeStatus(RechargeStatusType.REFUND.getCode());
        rechargePasswordCardService.updateById(rechargePasswordCard);
        //退用户积分
        appUserPointLogService.reducePoint(orderRecharge.getAppUserId(), orderRecharge.getGivePointAmount().intValue(), orderRecharge.getOrderNo(), MemberPointSourceEnum.REFUND_DEDUCT, "会员储值退款扣除");
        //此处添加退款记录
        appUserBillMstrService.save(appUserBillMstrService.buildBillMstr(ConsumeOrderDTO.buildOrderRechargeRefundData(orderRecharge)));
        log.debug("充值订单{}" + orderNo + "退款完成");
        return R.ok();
    }

    @Override
    public R refundClosed(String orderNo) {
        OrderRecharge orderRecharge = getOne(new QueryWrapper<OrderRecharge>().lambda().eq(OrderRecharge::getOrderNo, orderNo));
        if (orderRecharge == null) {
            throw new ServiceException("未查询到订单");
        }
        orderRecharge.setRefundStatus(OrderRefundStatus.REFUND_CANCEL.getCode());
        updateById(orderRecharge);
        return R.ok();
    }

    @Override
    public R refundError(String orderNo) {
        OrderRecharge orderRecharge = getOne(new QueryWrapper<OrderRecharge>().lambda().eq(OrderRecharge::getOrderNo, orderNo));
        if (orderRecharge == null) {
            throw new ServiceException("未查询到订单");
        }
        orderRecharge.setRefundStatus(OrderRefundStatus.ERROR.getCode());
        updateById(orderRecharge);
        return R.ok();
    }

    /**
     * 充值订单-处理支付失败
     *
     * @param orderNo
     * @return 处理支付失败
     */
    @Override
    public String handleCancelRecharge(String orderNo) {
        OrderRechargeInstalment orderRechargeInstalment = orderRechargeInstalmentService.getOne(new QueryWrapper<OrderRechargeInstalment>().lambda()
                .eq(OrderRechargeInstalment::getOrderNo, orderNo));
        OrderRecharge orderRecharge = this.getOne(new QueryWrapper<OrderRecharge>().lambda().eq(OrderRecharge::getOrderNo, orderRechargeInstalment.getMstrOrderNo()));
        if (orderRecharge == null) {
            log.info("充值订单不存在，订单编号：" + orderNo);
            return "订单不存在";
        }
        if (OrderRechargeStatus.REFUND.getCode().equals(orderRecharge.getOrderStatus())
                || OrderRefundStatus.REFUND_SUCCESS.getCode().equals(orderRecharge.getRefundStatus())) {
            log.info("充值订单已退款，不需要处理，订单编号：" + orderNo);
            return "订单已退款，不需要处理";
        }
        if (!OrderGoodsStatusType.NO_PAY.getCode().equals(orderRecharge.getOrderStatus())) {
            log.info("充值订单状态不对，无法取消，订单编号：" + orderNo);
            return "订单状态不对，无法取消";
        }
        orderRecharge.setOrderStatus(OrderRechargeStatus.CANCEL.getCode());
        orderRecharge.setRemark("支付失败取消订单");
        orderRecharge.buildUpdateData();
        baseMapper.updateById(orderRecharge);

        orderRechargeInstalment.setOrderStatus(OrderRechargeStatus.CANCEL.getCode());
        orderRechargeInstalment.setRemark("支付失败取消订单");
        orderRechargeInstalment.buildUpdateData();
        orderRechargeInstalmentService.updateById(orderRechargeInstalment);
        return "支付失败，取消订单";
    }

    @Override
    public void listFinancialStatisticsByRechargeOrderToday(OrderFinancialQueryVO orderFinancialQueryVO, OrderFinancialDayQueryDTO today) {
        // 查询今日充值订单
        List<OrderRechargeFinancialVO> todayData = baseMapper.listFinancialStatisticsByRechargeOrderToday(today,
                SecurityUtils.getLoginUser().getOrgId(),
                SecurityUtils.getLoginUser().getSourceType());
        if (CollUtil.isEmpty(todayData)) {
            orderFinancialQueryVO.setTodayChargeAmount(BigDecimal.ZERO);
        }
        // 今日充值金额
        orderFinancialQueryVO.setTodayChargeAmount(todayData.stream()
                .map(OrderRechargeFinancialVO::getPayAmount)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add));
    }

    @Override
    public void listFinancialStatisticsByRechargeOrderMTD(OrderFinancialQueryVO orderFinancialQueryVO) {
        // 查询本月充值订单
        List<OrderRechargeFinancialVO> todayData = baseMapper.listFinancialStatisticsByRechargeOrderMTD(SecurityUtils.getLoginUser().getOrgId(), SecurityUtils.getLoginUser().getSourceType());
        if (CollUtil.isEmpty(todayData)) {
            orderFinancialQueryVO.setTodayChargeAmount(BigDecimal.ZERO);
        }
        // 本月充值金额
        orderFinancialQueryVO.setTodayChargeAmount(todayData.stream()
                .map(OrderRechargeFinancialVO::getPayAmount)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add));
    }

}
