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") + ")"); } }