longz
2026-07-20 c7a07de51029c17847ce72e10817bb46a46a41a3
fix: 修复工行退款未到账
4个文件已修改
97 ■■■■■ 已修改文件
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ChargingSimulationSupport.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/task/TaskUtil.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/service/impl/ChargingSimulationSupportTest.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/ChargingSimulationSupport.java
@@ -54,7 +54,11 @@
            return BigDecimal.ZERO.setScale(2);
        }
        BigDecimal thirdAmount = money(order.getThirdPayAmount());
        if (thirdAmount.compareTo(BigDecimal.ZERO) > 0 || Integer.valueOf(1).equals(order.getPayMethod())) {
        if (thirdAmount.compareTo(BigDecimal.ZERO) > 0) {
            return thirdAmount;
        }
        if (Integer.valueOf(1).equals(order.getPayMethod())
                && !"ICBC".equalsIgnoreCase(order.getSourceName())) {
            return thirdAmount;
        }
        return money(order.getRechargeAmount())
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -2142,27 +2142,19 @@
        if (chargingOrder.getOrderSource() == 1) {
            BigDecimal rechargeAmount = chargingOrder.getRechargeAmount();
            Integer rechargePaymentType = chargingOrder.getRechargePaymentType();
            Integer payMethod = chargingOrder.getPayMethod();
            //构建退款明细
            TChargingOrderRefund chargingOrderRefund = new TChargingOrderRefund();
            chargingOrderRefund.setChargingOrderId(chargingOrder.getId());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
            chargingOrderRefund.setRefundCode("CDF" + sdf.format(new Date()) + Double.valueOf(Math.random() * 1000).intValue());
            chargingOrderRefund.setRefundAmount(money);
            BigDecimal thirdRefundAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
            BigDecimal balanceRefundAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
            if (Integer.valueOf(1).equals(payMethod)) {
                balanceRefundAmount = money.min(money(chargingOrder.getBalancePayAmount())).setScale(2, RoundingMode.HALF_UP);
            } else if (Integer.valueOf(2).equals(payMethod)) {
                BigDecimal refundableThirdAmount = money(chargingOrder.getThirdPayAmount()).subtract(money(chargingOrder.getThirdRefundAmount()));
                if (refundableThirdAmount.compareTo(BigDecimal.ZERO) < 0) {
                    refundableThirdAmount = BigDecimal.ZERO;
                }
                thirdRefundAmount = money.min(refundableThirdAmount).setScale(2, RoundingMode.HALF_UP);
                balanceRefundAmount = money.subtract(thirdRefundAmount).min(money(chargingOrder.getBalancePayAmount())).setScale(2, RoundingMode.HALF_UP);
            } else {
                thirdRefundAmount = money;
            }
            BigDecimal refundableThirdAmount = getRefundableThirdPayAmount(chargingOrder)
                    .subtract(money(chargingOrder.getThirdRefundAmount())).max(BigDecimal.ZERO);
            BigDecimal refundableBalanceAmount = money(chargingOrder.getBalancePayAmount())
                    .subtract(money(chargingOrder.getBalanceRefundAmount())).max(BigDecimal.ZERO);
            BigDecimal thirdRefundAmount = money.min(refundableThirdAmount).setScale(2, RoundingMode.HALF_UP);
            BigDecimal balanceRefundAmount = money.subtract(thirdRefundAmount)
                    .min(refundableBalanceAmount).setScale(2, RoundingMode.HALF_UP);
            chargingOrderRefund.setBalanceRefundAmount(balanceRefundAmount);
            chargingOrderRefund.setThirdRefundAmount(thirdRefundAmount);
            chargingOrderRefund.setRefundStatus(1);
@@ -4830,7 +4822,7 @@
                return R.fail("退款金额不能超过剩余可退金额");
            }
            BigDecimal refundedThirdAmount = money(order.getThirdRefundAmount());
            BigDecimal refundableThirdAmount = money(order.getThirdPayAmount()).subtract(refundedThirdAmount);
            BigDecimal refundableThirdAmount = getRefundableThirdPayAmount(order).subtract(refundedThirdAmount);
            if (refundableThirdAmount.compareTo(BigDecimal.ZERO) < 0) {
                refundableThirdAmount = BigDecimal.ZERO;
            }
@@ -5095,7 +5087,7 @@
            chargingOrderRefund.setRefundTotalAmount(money(tChargingOrder.getRefundAmount()).add(manualRefundAmount));
            chargingOrderRefund.setPayAmount(money(tChargingOrder.getPaymentAmount()));
            BigDecimal refundedThirdAmount = money(tChargingOrder.getThirdRefundAmount());
            BigDecimal refundableThirdAmount = money(tChargingOrder.getThirdPayAmount()).subtract(refundedThirdAmount);
            BigDecimal refundableThirdAmount = getRefundableThirdPayAmount(tChargingOrder).subtract(refundedThirdAmount);
            if (refundableThirdAmount.compareTo(BigDecimal.ZERO) < 0) {
                refundableThirdAmount = BigDecimal.ZERO;
            }
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/util/task/TaskUtil.java
@@ -39,10 +39,13 @@
import com.ruoyi.other.api.vo.ExchangeCodeConsumeResultVO;
import com.ruoyi.payment.api.feignClient.AliPaymentClient;
import com.ruoyi.payment.api.feignClient.H5AliPaymentClient;
import com.ruoyi.payment.api.feignClient.IcbcPaymentClient;
import com.ruoyi.payment.api.feignClient.WxPaymentClient;
import com.ruoyi.payment.api.model.RefundReq;
import com.ruoyi.payment.api.model.RefundResp;
import com.ruoyi.payment.api.model.WxPaymentRefundModel;
import com.ruoyi.payment.api.vo.IcbcRefundReq;
import com.ruoyi.payment.api.vo.IcbcRefundResp;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
@@ -140,6 +143,9 @@
    private WxPaymentClient wxPaymentClient;
    @Resource
    private IcbcPaymentClient icbcPaymentClient;
    @Resource
    private AliPaymentClient aliPaymentClient;
    @Resource
    private H5AliPaymentClient h5AliPaymentClient;
@@ -188,6 +194,12 @@
        BigDecimal thirdPayAmount = money(order.getThirdPayAmount());
        if (thirdPayAmount.compareTo(BigDecimal.ZERO) > 0) {
            return thirdPayAmount;
        }
        if ("ICBC".equalsIgnoreCase(order.getSourceName())) {
            return money(order.getRechargeAmount())
                    .subtract(money(order.getBalancePayAmount()))
                    .max(BigDecimal.ZERO)
                    .setScale(2, RoundingMode.HALF_UP);
        }
        if (Integer.valueOf(3).equals(order.getPayMethod())) {
            return money(order.getRechargeAmount());
@@ -789,28 +801,24 @@
                        //开始构建退款费用
                        refundAmount = refundAmount.setScale(2, RoundingMode.HALF_EVEN);
                        BigDecimal refundableThirdPayAmount = getRefundableThirdPayAmount(order);
                        BigDecimal refundableAmount = refundableThirdPayAmount.add(money(order.getBalancePayAmount())).setScale(2, RoundingMode.HALF_UP);
                        BigDecimal remainingThirdAmount = refundableThirdPayAmount
                                .subtract(money(order.getThirdRefundAmount())).max(BigDecimal.ZERO);
                        BigDecimal remainingBalanceAmount = money(order.getBalancePayAmount())
                                .subtract(money(order.getBalanceRefundAmount())).max(BigDecimal.ZERO);
                        BigDecimal refundableAmount = remainingThirdAmount.add(remainingBalanceAmount).setScale(2, RoundingMode.HALF_UP);
                        // 白名单全部免费只记录预估预充金额,实际渠道退款金额保持0,防止补偿任务重复发起退款。
                        BigDecimal recordedRefundAmount = isWhitelistAllFreeOrder(order) ? money(order.getRechargeAmount()) : refundAmount;
                        BigDecimal channelRefundAmount = isWhitelistAllFreeOrder(order)
                                ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP)
                                : refundAmount.min(refundableAmount).setScale(2, RoundingMode.HALF_UP);
                        Integer rechargePaymentType = order.getRechargePaymentType();
                        Integer payMethod = order.getPayMethod();
                        BigDecimal thirdRefundAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
                        BigDecimal balanceRefundAmount = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
                        if (Integer.valueOf(1).equals(payMethod)) {
                            balanceRefundAmount = channelRefundAmount.min(money(order.getBalancePayAmount())).setScale(2, RoundingMode.HALF_UP);
                        } else if (Integer.valueOf(2).equals(payMethod)) {
                            thirdRefundAmount = channelRefundAmount.min(refundableThirdPayAmount).setScale(2, RoundingMode.HALF_UP);
                            balanceRefundAmount = channelRefundAmount.subtract(thirdRefundAmount).min(money(order.getBalancePayAmount())).setScale(2, RoundingMode.HALF_UP);
                        } else {
                            thirdRefundAmount = channelRefundAmount.min(refundableThirdPayAmount).setScale(2, RoundingMode.HALF_UP);
                        }
                        BigDecimal thirdRefundAmount = channelRefundAmount.min(remainingThirdAmount).setScale(2, RoundingMode.HALF_UP);
                        BigDecimal balanceRefundAmount = channelRefundAmount.subtract(thirdRefundAmount)
                                .min(remainingBalanceAmount).setScale(2, RoundingMode.HALF_UP);
                        if (channelRefundAmount.compareTo(BigDecimal.ZERO) > 0) {
                            refundAmount = thirdRefundAmount.add(balanceRefundAmount).setScale(2, RoundingMode.HALF_UP);
                            order.setThirdRefundAmount(thirdRefundAmount);
                            order.setBalanceRefundAmount(balanceRefundAmount);
                            order.setThirdRefundAmount(money(order.getThirdRefundAmount()).add(thirdRefundAmount));
                            order.setBalanceRefundAmount(money(order.getBalanceRefundAmount()).add(balanceRefundAmount));
                            order.setRefundAmount(recordedRefundAmount);
                            order.setRefundStatus(refundAmount.compareTo(BigDecimal.ZERO) > 0 ? 1 : 2);
                            chargingOrderService.updateById(order);
@@ -840,6 +848,25 @@
                                order.setRefundStatus(2);
                                order.setRefundTime(LocalDateTime.now());
                                chargingOrderService.updateById(order);
                            } else if ("ICBC".equalsIgnoreCase(order.getSourceName())) {
                                IcbcRefundReq req = new IcbcRefundReq();
                                req.setOutTradeNo(order.getCode());
                                req.setOrderId(order.getRechargeSerialNumber());
                                req.setOutRefundNo(chargingOrderRefund.getRefundCode());
                                req.setRefundAmount(thirdRefundAmount);
                                req.setTotalAmount(getRefundableThirdPayAmount(order));
                                req.setReason("充电完成退款");
                                R<IcbcRefundResp> result = icbcPaymentClient.refund(req);
                                IcbcRefundResp resp = result == null ? null : result.getData();
                                if (result != null && result.getCode() == 200 && resp != null && "SUCCESS".equals(resp.getStatus())) {
                                    chargingOrderRefundService.save(chargingOrderRefund);
                                    String refundId = StringUtils.isNotEmpty(resp.getRefundId()) ? resp.getRefundId() : resp.getOutRefundNo();
                                    chargingOrderService.chargingOrderStartupFailureWxRefund(
                                            chargingOrderRefund.getRefundCode(), refundId, "SUCCESS", resp.getRefundTime());
                                } else {
                                    log.error("工行充电完成退款失败,订单号:{},退款单号:{},返回:{}",
                                            order.getCode(), chargingOrderRefund.getRefundCode(), result == null ? null : result.getMsg());
                                }
                            } else if (1 == rechargePaymentType) {
                                WxPaymentRefundModel model = new WxPaymentRefundModel();
                                model.setOut_trade_no(order.getCode());
ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/service/impl/ChargingSimulationSupportTest.java
@@ -62,6 +62,16 @@
        assertEquals("余额+工行支付", ChargingSimulationSupport.paymentMode(legacyMixed));
        assertEquals(new BigDecimal("6.00"), ChargingSimulationSupport.thirdPayAmount(legacyMixed));
        TChargingOrder legacyIcbc = new TChargingOrder();
        legacyIcbc.setPayMethod(1);
        legacyIcbc.setRechargePaymentType(1);
        legacyIcbc.setSourceName("ICBC");
        legacyIcbc.setRechargeAmount(new BigDecimal("3.00"));
        legacyIcbc.setBalancePayAmount(BigDecimal.ZERO);
        assertEquals("工行支付", ChargingSimulationSupport.paymentMode(legacyIcbc));
        assertEquals(new BigDecimal("3.00"), ChargingSimulationSupport.thirdPayAmount(legacyIcbc));
    }
    @Test