From 4f6f15b818704079ff2e4e4719b798f48d68a335 Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期五, 11 九月 2026 13:52:19 +0800
Subject: [PATCH] update
---
backend/src/main/java/com/tourguide/modules/finance/service/GuideBalanceSettlementService.java | 42 +++++++++++++++++++++++++++++++++++++++++-
1 files changed, 41 insertions(+), 1 deletions(-)
diff --git a/backend/src/main/java/com/tourguide/modules/finance/service/GuideBalanceSettlementService.java b/backend/src/main/java/com/tourguide/modules/finance/service/GuideBalanceSettlementService.java
index f8a0a66..6c92169 100644
--- a/backend/src/main/java/com/tourguide/modules/finance/service/GuideBalanceSettlementService.java
+++ b/backend/src/main/java/com/tourguide/modules/finance/service/GuideBalanceSettlementService.java
@@ -2,6 +2,7 @@
import com.tourguide.common.exception.BusinessException;
import com.tourguide.modules.order.domain.OrderStatus;
+import com.tourguide.modules.order.domain.RefundAmountCalculator;
import com.tourguide.modules.order.domain.RefundStatus;
import com.tourguide.modules.order.entity.TourOrder;
import com.tourguide.modules.order.mapper.TourOrderMapper;
@@ -9,6 +10,7 @@
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
+import java.math.RoundingMode;
import java.time.LocalDateTime;
/** 将到期且未分账的订单收益幂等计入导游余额。 */
@@ -28,7 +30,7 @@
TourOrder order = orderMapper.selectForUpdate(orderId);
if (!canSettle(order, settledAt)) return false;
- BigDecimal earning = order.getGuideEarningAmount();
+ BigDecimal earning = effectiveEarning(order);
if (earning.signum() > 0) {
if (order.getCommissionTeamId() != null) {
balanceService.creditTeam(order.getCommissionTeamId(), earning);
@@ -43,6 +45,27 @@
return true;
}
+ /** 退款成功后冲正已入账收益;按累计退款差额计算,保证部分退款幂等。 */
+ @Transactional
+ public void reverseRefund(TourOrder order, BigDecimal previousRefundedAmount,
+ BigDecimal currentRefundedAmount) {
+ if (order == null || order.getSettledAt() == null
+ || order.getGuideEarningAmount() == null) return;
+ BigDecimal paidAmount = RefundAmountCalculator.paidAmount(order);
+ if (paidAmount.signum() <= 0) return;
+ BigDecimal previous = nonNegative(previousRefundedAmount);
+ BigDecimal current = nonNegative(currentRefundedAmount).min(paidAmount);
+ BigDecimal previousReversal = proratedEarning(order.getGuideEarningAmount(), previous, paidAmount);
+ BigDecimal currentReversal = proratedEarning(order.getGuideEarningAmount(), current, paidAmount);
+ BigDecimal reversal = currentReversal.subtract(previousReversal).setScale(2, RoundingMode.HALF_UP);
+ if (reversal.signum() <= 0) return;
+ if (order.getCommissionTeamId() != null) {
+ balanceService.debitTeamForRefund(order.getCommissionTeamId(), reversal);
+ } else if (order.getGuideId() != null) {
+ balanceService.debitForRefund(order.getGuideId(), reversal);
+ }
+ }
+
private boolean canSettle(TourOrder order, LocalDateTime now) {
return order != null
&& OrderStatus.COMPLETED.matches(order.getStatus())
@@ -54,4 +77,21 @@
&& order.getGuideEarningAmount().signum() >= 0
&& !RefundStatus.REFUNDED.matches(order.getRefundStatus());
}
+
+ private BigDecimal effectiveEarning(TourOrder order) {
+ BigDecimal earning = order.getGuideEarningAmount();
+ BigDecimal paidAmount = RefundAmountCalculator.paidAmount(order);
+ if (paidAmount.signum() <= 0) return earning;
+ BigDecimal refunded = RefundAmountCalculator.refundedAmount(order).min(paidAmount);
+ return earning.multiply(paidAmount.subtract(refunded))
+ .divide(paidAmount, 2, RoundingMode.HALF_UP);
+ }
+
+ private BigDecimal proratedEarning(BigDecimal earning, BigDecimal refunded, BigDecimal paidAmount) {
+ return earning.multiply(refunded).divide(paidAmount, 2, RoundingMode.HALF_UP);
+ }
+
+ private BigDecimal nonNegative(BigDecimal value) {
+ return value == null ? BigDecimal.ZERO : value.max(BigDecimal.ZERO);
+ }
}
--
Gitblit v1.7.1