From 390c4247e81e57e5a8f154e38590ddbe53c6a49f Mon Sep 17 00:00:00 2001
From: Guoqs <123@jsowell.com>
Date: Wed, 17 Dec 2025 09:24:50 +0800
Subject: [PATCH] =?UTF-8?q?update=20=E9=80=80=E4=BF=9D=E9=99=A9=E8=B4=B9?=
=?UTF-8?q?=E6=96=B9=E6=B3=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
TestCalculateBalanceRefund.java | 122 ------------------
.../pile/service/OrderPayRecordService.java | 3 +
.../impl/MemberBasicInfoServiceImpl.java | 6 +
.../impl/OrderBasicInfoServiceImpl.java | 112 +++++++++++++++-
.../impl/OrderPayRecordServiceImpl.java | 36 ++++++
.../programlogic/AbstractProgramLogic.java | 6 +-
6 files changed, 156 insertions(+), 129 deletions(-)
delete mode 100644 TestCalculateBalanceRefund.java
diff --git a/TestCalculateBalanceRefund.java b/TestCalculateBalanceRefund.java
deleted file mode 100644
index 7821e95e7..000000000
--- a/TestCalculateBalanceRefund.java
+++ /dev/null
@@ -1,122 +0,0 @@
-import java.math.BigDecimal;
-import java.util.HashMap;
-import java.util.Map;
-
-public class TestCalculateBalanceRefund {
-
- /**
- * 计算余额退款(包含电费和保险费)
- *
- * 业务规则:
- * 1. 总支付金额 = principalPay + giftPay
- * 2. 电费预付款 = 总支付金额 - insuranceAmount
- * 3. 实际电费消费金额 = orderAmount - discountAmount
- * 4. 支付时优先使用本金,消费时也优先扣除本金
- * 5. 保险费优先从本金中扣除
- * 6. 电费实际消费金额 > 1 时,保险费不退;否则需要退保险费
- *
- * @param principalPay 本金支付金额
- * @param giftPay 赠金支付金额
- * @param orderAmount 消费金额
- * @param discountAmount 折扣金额
- * @param insuranceAmount 保险费金额
- * @return Map包含:returnPrincipal(本金退款for电费),returnGift(赠金退款for电费),
- * returnPrincipalForInsurance(本金退款for保险费),returnGiftForInsurance(赠金退款for保险费)
- */
- protected static Map calculateBalanceRefund(BigDecimal principalPay, BigDecimal giftPay,
- BigDecimal orderAmount, BigDecimal discountAmount,
- BigDecimal insuranceAmount) {
- Map resultMap = new HashMap<>();
-
- // 参数校验,null值处理为0
- principalPay = principalPay == null ? BigDecimal.ZERO : principalPay;
- giftPay = giftPay == null ? BigDecimal.ZERO : giftPay;
- orderAmount = orderAmount == null ? BigDecimal.ZERO : orderAmount;
- discountAmount = discountAmount == null ? BigDecimal.ZERO : discountAmount;
- insuranceAmount = insuranceAmount == null ? BigDecimal.ZERO : insuranceAmount;
-
- // 总支付金额
- BigDecimal totalPay = principalPay.add(giftPay);
-
- // 电费预付款 = 总支付金额 - 保险费
- BigDecimal electricityPrepayment = totalPay.subtract(insuranceAmount);
-
- // 实际电费消费金额 = 消费金额 - 折扣金额
- BigDecimal actualElectricityConsumption = orderAmount.subtract(discountAmount);
- if (actualElectricityConsumption.compareTo(BigDecimal.ZERO) < 0) {
- actualElectricityConsumption = BigDecimal.ZERO;
- }
-
- // 支付时优先用本金,保险费全部从本金中扣除
- // 本金用于保险费的部分(优先从本金扣除保险费)
- BigDecimal principalForInsurance = principalPay.min(insuranceAmount);
- // 赠金用于保险费的部分(如果本金不够支付保险费,从赠金中扣除)
- BigDecimal giftForInsurance = insuranceAmount.subtract(principalForInsurance);
- if (giftForInsurance.compareTo(BigDecimal.ZERO) < 0) {
- giftForInsurance = BigDecimal.ZERO;
- }
- // 本金用于电费的部分 = 总本金 - 本金用于保险费的部分
- BigDecimal principalForElectricity = principalPay.subtract(principalForInsurance);
- // 赠金用于电费的部分 = 总赠金 - 赠金用于保险费的部分
- BigDecimal giftForElectricity = giftPay.subtract(giftForInsurance);
-
- // 计算电费退款(消费时优先扣除本金)
- BigDecimal principalConsumed = principalForElectricity.min(actualElectricityConsumption);
- BigDecimal giftConsumed = actualElectricityConsumption.subtract(principalConsumed);
- if (giftConsumed.compareTo(BigDecimal.ZERO) < 0) {
- giftConsumed = BigDecimal.ZERO;
- }
-
- // 电费退款
- BigDecimal returnPrincipal = principalForElectricity.subtract(principalConsumed);
- BigDecimal returnGift = giftForElectricity.subtract(giftConsumed);
- if (returnPrincipal.compareTo(BigDecimal.ZERO) < 0) {
- returnPrincipal = BigDecimal.ZERO;
- }
- if (returnGift.compareTo(BigDecimal.ZERO) < 0) {
- returnGift = BigDecimal.ZERO;
- }
-
- // 计算保险费退款:电费实际消费金额 > 1 时,保险费不退;否则需要退保险费
- BigDecimal returnPrincipalForInsurance = BigDecimal.ZERO;
- BigDecimal returnGiftForInsurance = BigDecimal.ZERO;
-
- if (actualElectricityConsumption.compareTo(BigDecimal.ONE) <= 0) {
- // 需要退保险费
- returnPrincipalForInsurance = principalForInsurance;
- returnGiftForInsurance = giftForInsurance;
- }
-
- resultMap.put("returnPrincipal", returnPrincipal);
- resultMap.put("returnGift", returnGift);
- resultMap.put("returnPrincipalForInsurance", returnPrincipalForInsurance);
- resultMap.put("returnGiftForInsurance", returnGiftForInsurance);
-
- System.out.println("计算余额退款: 本金支付=" + principalPay + ", 赠金支付=" + giftPay +
- ", 消费金额=" + orderAmount + ", 折扣金额=" + discountAmount +
- ", 保险费=" + insuranceAmount + ", 实际电费消费=" + actualElectricityConsumption +
- ", 电费退款(本金=" + returnPrincipal + ", 赠金=" + returnGift +
- "), 保险费退款(本金=" + returnPrincipalForInsurance + ", 赠金=" + returnGiftForInsurance + ")");
-
- return resultMap;
- }
-
- public static void main(String[] args) {
- System.out.println("测试用例1: 本金30.5, 赠金20, 消费10, 折扣0, 保险费0.5");
- BigDecimal principalPay = new BigDecimal("30.5");
- BigDecimal giftPay = new BigDecimal("20");
- BigDecimal orderAmount = new BigDecimal("10");
- BigDecimal discountAmount = new BigDecimal("0");
- BigDecimal insuranceAmount = new BigDecimal("0.5");
-
- Map result = calculateBalanceRefund(principalPay, giftPay, orderAmount, discountAmount, insuranceAmount);
- System.out.println("结果: " + result);
- System.out.println();
-
- System.out.println("期望结果: 电费退款(本金=20.5, 赠金=19.5), 保险费退款(本金=0, 赠金=0)");
- System.out.println("实际结果: 电费退款(本金=" + result.get("returnPrincipal") +
- ", 赠金=" + result.get("returnGift") +
- "), 保险费退款(本金=" + result.get("returnPrincipalForInsurance") +
- ", 赠金=" + result.get("returnGiftForInsurance") + ")");
- }
-}
\ No newline at end of file
diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/OrderPayRecordService.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/OrderPayRecordService.java
index f19e22a86..aa9712e80 100644
--- a/jsowell-pile/src/main/java/com/jsowell/pile/service/OrderPayRecordService.java
+++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/OrderPayRecordService.java
@@ -7,6 +7,7 @@ import com.jsowell.pile.vo.web.OrderDetailInfoVO;
import java.math.BigDecimal;
import java.util.List;
+import java.util.Map;
public interface OrderPayRecordService{
@@ -32,6 +33,8 @@ public interface OrderPayRecordService{
List getOrderPayRecordList(String orderCode);
+ Map selectOrderBalancePayInfoList(String orderCode);
+
List queryPaymentInfosByOrderCode(String orderCode);
List selectOrderPayRecordList(String orderCode);
diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/MemberBasicInfoServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/MemberBasicInfoServiceImpl.java
index 4a364c152..a4e048af8 100644
--- a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/MemberBasicInfoServiceImpl.java
+++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/MemberBasicInfoServiceImpl.java
@@ -216,6 +216,12 @@ public class MemberBasicInfoServiceImpl implements MemberBasicInfoService {
return 0;
}
+ // 为0也返回
+ if (BigDecimal.ZERO.compareTo(updateGiftBalance) == 0 && BigDecimal.ZERO.compareTo(updatePrincipalBalance) == 0) {
+ log.info("修改用户余额-金额为0, 直接返回:{}", JSON.toJSONString(dto));
+ return 0;
+ }
+
// 没有传过来目标运营商,有可能是希晓的小程序在线充值
if (StringUtils.isBlank(dto.getTargetMerchantId())) {
// 根据memberId查询会员信息
diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java
index 6b48c614e..0375336f3 100644
--- a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java
+++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java
@@ -809,16 +809,24 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService {
// 判断订单的支付方式
String payMode = orderBasicInfo.getPayMode();
if (StringUtils.equals(payMode, OrderPayModeEnum.PAYMENT_OF_PRINCIPAL_BALANCE.getValue())) {
- BigDecimal returnPrincipal = BigDecimal.ZERO;
- BigDecimal returnGift = BigDecimal.ZERO;
+ // 查询余额支付订单的支付明细
+ Map balancePayMap = orderPayRecordService.selectOrderBalancePayInfoList(orderBasicInfo.getOrderCode());
+ BigDecimal principalPay = balancePayMap.get("principalPay");
+ BigDecimal giftPay = balancePayMap.get("giftPay");
+
+ // 计算退保金额
+ Map refundMap = calculateBalanceRefund(principalPay, giftPay, orderBasicInfo.getOrderAmount(), orderBasicInfo.getDiscountAmount(), insuranceAmount);
+ BigDecimal returnPrincipalForInsurance = refundMap.get("returnPrincipalForInsurance");
+ BigDecimal returnGiftForInsurance = refundMap.get("returnGiftForInsurance");
+
// 余额支付
UpdateMemberBalanceDTO updateMemberBalanceDTO = UpdateMemberBalanceDTO.builder()
.memberId(orderBasicInfo.getMemberId())
.targetMerchantId(orderBasicInfo.getMerchantId())
.type(MemberWalletEnum.TYPE_IN.getValue()) // 进账
.subType(MemberWalletEnum.SUBTYPE_ORDER_SETTLEMENT_REFUND.getValue()) // 订单结算退款
- .updatePrincipalBalance(orderBasicInfo.getInsuranceAmount())
- .updateGiftBalance(returnGift)
+ .updatePrincipalBalance(returnPrincipalForInsurance)
+ .updateGiftBalance(returnGiftForInsurance)
.relatedOrderCode(orderBasicInfo.getOrderCode())
.build();
// 更新会员钱包/余额退回到钱包
@@ -845,6 +853,102 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService {
}
}
+ /**
+ * 计算余额退款(包含电费和保险费)
+ *
+ * 业务规则:
+ * 1. 总支付金额 = principalPay + giftPay
+ * 2. 电费预付款 = 总支付金额 - insuranceAmount
+ * 3. 实际电费消费金额 = orderAmount - discountAmount
+ * 4. 支付时优先使用本金,消费时也优先扣除本金
+ * 5. 电费实际消费金额 > 1 时,保险费不退;否则需要退保险费
+ *
+ * @param principalPay 本金支付金额
+ * @param giftPay 赠金支付金额
+ * @param orderAmount 消费金额
+ * @param discountAmount 折扣金额
+ * @param insuranceAmount 保险费金额
+ * @return Map包含:returnPrincipal(本金退款for电费),returnGift(赠金退款for电费),
+ * returnPrincipalForInsurance(本金退款for保险费),returnGiftForInsurance(赠金退款for保险费)
+ */
+ private Map calculateBalanceRefund(BigDecimal principalPay, BigDecimal giftPay,
+ BigDecimal orderAmount, BigDecimal discountAmount,
+ BigDecimal insuranceAmount) {
+ Map resultMap = Maps.newHashMap();
+
+ // 参数校验,null值处理为0
+ principalPay = principalPay == null ? BigDecimal.ZERO : principalPay;
+ giftPay = giftPay == null ? BigDecimal.ZERO : giftPay;
+ orderAmount = orderAmount == null ? BigDecimal.ZERO : orderAmount;
+ discountAmount = discountAmount == null ? BigDecimal.ZERO : discountAmount;
+ insuranceAmount = insuranceAmount == null ? BigDecimal.ZERO : insuranceAmount;
+
+ // 总支付金额
+ BigDecimal totalPay = principalPay.add(giftPay);
+
+ // 电费预付款 = 总支付金额 - 保险费
+ BigDecimal electricityPrepayment = totalPay.subtract(insuranceAmount);
+
+ // 实际电费消费金额 = 消费金额 - 折扣金额
+ BigDecimal actualElectricityConsumption = orderAmount.subtract(discountAmount);
+ if (actualElectricityConsumption.compareTo(BigDecimal.ZERO) < 0) {
+ actualElectricityConsumption = BigDecimal.ZERO;
+ }
+
+ // 支付时优先用本金,保险费全部从本金中扣除
+ // 本金用于保险费的部分(优先从本金扣除保险费)
+ BigDecimal principalForInsurance = principalPay.min(insuranceAmount);
+ // 赠金用于保险费的部分(如果本金不够支付保险费,从赠金中扣除)
+ BigDecimal giftForInsurance = insuranceAmount.subtract(principalForInsurance);
+ if (giftForInsurance.compareTo(BigDecimal.ZERO) < 0) {
+ giftForInsurance = BigDecimal.ZERO;
+ }
+ // 本金用于电费的部分 = 总本金 - 本金用于保险费的部分
+ BigDecimal principalForElectricity = principalPay.subtract(principalForInsurance);
+ // 赠金用于电费的部分 = 总赠金 - 赠金用于保险费的部分
+ BigDecimal giftForElectricity = giftPay.subtract(giftForInsurance);
+
+ // 计算电费退款(消费时优先扣除本金)
+ BigDecimal principalConsumed = principalForElectricity.min(actualElectricityConsumption);
+ BigDecimal giftConsumed = actualElectricityConsumption.subtract(principalConsumed);
+ if (giftConsumed.compareTo(BigDecimal.ZERO) < 0) {
+ giftConsumed = BigDecimal.ZERO;
+ }
+
+ // 电费退款
+ BigDecimal returnPrincipal = principalForElectricity.subtract(principalConsumed);
+ BigDecimal returnGift = giftForElectricity.subtract(giftConsumed);
+ if (returnPrincipal.compareTo(BigDecimal.ZERO) < 0) {
+ returnPrincipal = BigDecimal.ZERO;
+ }
+ if (returnGift.compareTo(BigDecimal.ZERO) < 0) {
+ returnGift = BigDecimal.ZERO;
+ }
+
+ // 计算保险费退款:电费实际消费金额 > 1 时,保险费不退;否则需要退保险费
+ BigDecimal returnPrincipalForInsurance = BigDecimal.ZERO;
+ BigDecimal returnGiftForInsurance = BigDecimal.ZERO;
+
+ if (actualElectricityConsumption.compareTo(BigDecimal.ONE) < 0) {
+ // 需要退保险费
+ returnPrincipalForInsurance = principalForInsurance;
+ returnGiftForInsurance = giftForInsurance;
+ }
+
+ resultMap.put("returnPrincipal", returnPrincipal);
+ resultMap.put("returnGift", returnGift);
+ resultMap.put("returnPrincipalForInsurance", returnPrincipalForInsurance);
+ resultMap.put("returnGiftForInsurance", returnGiftForInsurance);
+
+ logger.info("计算余额退款: 本金支付={}, 赠金支付={}, 消费金额={}, 折扣金额={}, 保险费={}, " +
+ "实际电费消费={}, 电费退款(本金={}, 赠金={}), 保险费退款(本金={}, 赠金={})",
+ principalPay, giftPay, orderAmount, discountAmount, insuranceAmount,
+ actualElectricityConsumption, returnPrincipal, returnGift,
+ returnPrincipalForInsurance, returnGiftForInsurance);
+
+ return resultMap;
+ }
+
/**
* 查询充电中的订单,没有数据权限校验,后管不要用
*
diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderPayRecordServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderPayRecordServiceImpl.java
index 1126a8a3f..626d6fab4 100644
--- a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderPayRecordServiceImpl.java
+++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderPayRecordServiceImpl.java
@@ -3,6 +3,7 @@ package com.jsowell.pile.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import com.jsowell.adapay.vo.PaymentInfo;
import com.jsowell.common.constant.CacheConstants;
import com.jsowell.common.constant.Constants;
@@ -30,6 +31,7 @@ import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@@ -80,6 +82,40 @@ public class OrderPayRecordServiceImpl implements OrderPayRecordService {
return orderPayRecordMapper.getOrderPayRecordList(orderCode);
}
+ /**
+ * 查询余额支付订单的支付明细
+ * @param orderCode
+ * @return
+ */
+ @Override
+ public Map selectOrderBalancePayInfoList(String orderCode) {
+ Map resultMap = Maps.newHashMap();
+ // 查询余额支付订单的支付明细
+ List payRecordList = this.getOrderPayRecordList(orderCode);
+
+ // 根据payMode分组
+ Map> payRecordMap = payRecordList.stream()
+ .collect(Collectors.groupingBy(OrderPayRecord::getPayMode));
+
+ // 获取本金支付的记录
+ List principalPayRecordList = payRecordMap.get(OrderPayRecordEnum.PRINCIPAL_BALANCE_PAYMENT.getValue());
+ BigDecimal principalPay = BigDecimal.ZERO;
+ if (CollectionUtils.isNotEmpty(principalPayRecordList)) {
+ principalPay = principalPayRecordList.stream().map(OrderPayRecord::getPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+ }
+
+ // 获取赠送金支付的记录
+ List giftPayRecordList = payRecordMap.get(OrderPayRecordEnum.GIFT_BALANCE_PAYMENT.getValue());
+ BigDecimal giftPay = BigDecimal.ZERO;
+ if (CollectionUtils.isNotEmpty(giftPayRecordList)) {
+ giftPay = giftPayRecordList.stream().map(OrderPayRecord::getPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
+ }
+ resultMap.put("principalPay", principalPay);
+ resultMap.put("giftPay", giftPay);
+ return resultMap;
+ }
+
+
@Override
public List queryPaymentInfosByOrderCode(String orderCode) {
List resultList = Lists.newArrayList();
diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/programlogic/AbstractProgramLogic.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/programlogic/AbstractProgramLogic.java
index 8902d1a5c..ea8c73f45 100644
--- a/jsowell-pile/src/main/java/com/jsowell/pile/service/programlogic/AbstractProgramLogic.java
+++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/programlogic/AbstractProgramLogic.java
@@ -1240,7 +1240,7 @@ public abstract class AbstractProgramLogic implements InitializingBean {
BigDecimal returnPrincipalForInsurance = BigDecimal.ZERO;
BigDecimal returnGiftForInsurance = BigDecimal.ZERO;
- if (actualElectricityConsumption.compareTo(BigDecimal.ONE) <= 0) {
+ if (actualElectricityConsumption.compareTo(BigDecimal.ONE) < 0) {
// 需要退保险费
returnPrincipalForInsurance = principalForInsurance;
returnGiftForInsurance = giftForInsurance;
@@ -1264,12 +1264,12 @@ public abstract class AbstractProgramLogic implements InitializingBean {
BigDecimal principalPay = new BigDecimal("30.5");
BigDecimal giftPay = new BigDecimal("20");
BigDecimal orderAmount = new BigDecimal("10");
- BigDecimal discountAmount = new BigDecimal("9.1");
+ BigDecimal discountAmount = new BigDecimal("9.0");
BigDecimal insuranceAmount = new BigDecimal("0.5");
calculateBalanceRefund(principalPay, giftPay, orderAmount, discountAmount, insuranceAmount);
- }//
+ }
/**
* 计算余额支付下发金额