update 退保险费方法

This commit is contained in:
Guoqs
2025-12-17 09:24:50 +08:00
parent 9fd1d645cc
commit 390c4247e8
6 changed files with 156 additions and 129 deletions

View File

@@ -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<OrderPayRecord> getOrderPayRecordList(String orderCode);
Map<String, BigDecimal> selectOrderBalancePayInfoList(String orderCode);
List<PaymentInfo> queryPaymentInfosByOrderCode(String orderCode);
List<OrderPayRecordVO> selectOrderPayRecordList(String orderCode);

View File

@@ -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查询会员信息

View File

@@ -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<String, BigDecimal> balancePayMap = orderPayRecordService.selectOrderBalancePayInfoList(orderBasicInfo.getOrderCode());
BigDecimal principalPay = balancePayMap.get("principalPay");
BigDecimal giftPay = balancePayMap.get("giftPay");
// 计算退保金额
Map<String, BigDecimal> 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 {
}
}
/**
* 计算余额退款(包含电费和保险费)
* <p>
* 业务规则:
* 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<String, BigDecimal> calculateBalanceRefund(BigDecimal principalPay, BigDecimal giftPay,
BigDecimal orderAmount, BigDecimal discountAmount,
BigDecimal insuranceAmount) {
Map<String, BigDecimal> 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;
}
/**
* 查询充电中的订单,没有数据权限校验,后管不要用
*

View File

@@ -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<String, BigDecimal> selectOrderBalancePayInfoList(String orderCode) {
Map<String, BigDecimal> resultMap = Maps.newHashMap();
// 查询余额支付订单的支付明细
List<OrderPayRecord> payRecordList = this.getOrderPayRecordList(orderCode);
// 根据payMode分组
Map<String, List<OrderPayRecord>> payRecordMap = payRecordList.stream()
.collect(Collectors.groupingBy(OrderPayRecord::getPayMode));
// 获取本金支付的记录
List<OrderPayRecord> 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<OrderPayRecord> 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<PaymentInfo> queryPaymentInfosByOrderCode(String orderCode) {
List<PaymentInfo> resultList = Lists.newArrayList();

View File

@@ -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);
}//
}
/**
* 计算余额支付下发金额