剩余可退款金额计算错误修复

This commit is contained in:
马梓彭 2026-05-11 09:13:02 +08:00
parent a3e3c90b1f
commit faf9a8f5a0

View File

@ -2720,11 +2720,32 @@ public class UnifiedRegistrationService : ITransient
var historyRefunds = await _refundRecordRepository.GetListAsync(x => x.RegistrationId == registrationId && x.RefundStatus == 1); var historyRefunds = await _refundRecordRepository.GetListAsync(x => x.RegistrationId == registrationId && x.RefundStatus == 1);
var refundedAmount = historyRefunds.Sum(x => x.RefundAmount); var refundedAmount = historyRefunds.Sum(x => x.RefundAmount);
// 计算剩余未退款的原始金额 // 获取尚未被软删除的报名项
var remainingOriginalAmount = registration.TotalAmount - refundedAmount; var remainingItems = items.Where(x => !x.DeleteMark).ToList();
// 基于剩余金额计算可退款金额 // 计算剩余可退款金额:应该基于每个未退款的报名项分别计算,然后求和
var refundableAmount = await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime); // 这样确保每个团队/个人的退款是独立的,不受其他团队退款影响
decimal refundableAmount = 0;
// 区分不同的收费模式来计算
if (eventInfo.ChargeMode == ChargeMode.UnitPriceProject)
{
// 单价(项目)模式:每个未删除的项目独立计算退款
foreach (var item in remainingItems)
{
var itemRefund = await CalculateRefundAmountAsync(item.TotalPrice, eventInfo.MatchStartTime);
refundableAmount += itemRefund;
}
}
else
{
// 其他模式:使用传统方式计算
// 计算剩余未退款的原始金额
var remainingOriginalAmount = registration.TotalAmount - refundedAmount;
// 基于剩余金额计算可退款金额
refundableAmount = await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime);
}
// 确保可退款金额不小于0 // 确保可退款金额不小于0
refundableAmount = Math.Max(0, refundableAmount); refundableAmount = Math.Max(0, refundableAmount);
@ -2942,9 +2963,27 @@ public class UnifiedRegistrationService : ITransient
var historyRefunds = await _refundRecordRepository.GetListAsync(x => x.RegistrationId == registration.Id && x.RefundStatus == 1); var historyRefunds = await _refundRecordRepository.GetListAsync(x => x.RegistrationId == registration.Id && x.RefundStatus == 1);
var refundedAmount = historyRefunds.Sum(x => x.RefundAmount); var refundedAmount = historyRefunds.Sum(x => x.RefundAmount);
// 计算剩余可退款金额 // 计算剩余可退款金额:应该基于每个未退款的报名项分别计算,然后求和
var remainingOriginalAmount = registration.TotalAmount - refundedAmount; var remainingItems = items.Where(x => !x.DeleteMark).ToList();
var remainingRefundableAmount = await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime); decimal remainingRefundableAmount = 0;
// 区分不同的收费模式来计算
if (eventInfo.ChargeMode == ChargeMode.UnitPriceProject)
{
// 单价(项目)模式:每个未删除的项目独立计算退款
foreach (var item in remainingItems)
{
var itemRefund = await CalculateRefundAmountAsync(item.TotalPrice, eventInfo.MatchStartTime);
remainingRefundableAmount += itemRefund;
}
}
else
{
// 其他模式:使用传统方式计算
// 计算剩余未退款的原始金额
var remainingOriginalAmount = registration.TotalAmount - refundedAmount;
remainingRefundableAmount = await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime);
}
return new CalculateRefundAmountOutput return new CalculateRefundAmountOutput
{ {
@ -3071,14 +3110,13 @@ public class UnifiedRegistrationService : ITransient
// 直接对本次取消的原始金额应用退款规则 // 直接对本次取消的原始金额应用退款规则
var unitPriceEventFinalAmount = await CalculateRefundAmountAsync(unitPriceEventCancelAmount, eventInfo.MatchStartTime); var unitPriceEventFinalAmount = await CalculateRefundAmountAsync(unitPriceEventCancelAmount, eventInfo.MatchStartTime);
// 确保不超过剩余可退款金额 // 移除了错误的限制:每个团队/个人的退款应该独立计算,不受其他团队已退款金额影响
var maxUnitPriceEventRefund = await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime); // 直接返回基于本次取消金额计算的退款金额
var finalUnitPriceEventAmount = Math.Min(unitPriceEventFinalAmount, maxUnitPriceEventRefund);
_logger.LogInformation("单价(赛事)退款:取消人数={CancelCount}, 赛事单价={UnitPrice}, 本次取消原始金额={CancelAmount}, 按规则退款金额={RefundAmount}, 最终金额={FinalAmount}", _logger.LogInformation("单价(赛事)退款:取消人数={CancelCount}, 赛事单价={UnitPrice}, 本次取消原始金额={CancelAmount}, 按规则退款金额={RefundAmount}",
allCancelIds.Count, eventUnitPrice, unitPriceEventCancelAmount, unitPriceEventFinalAmount, finalUnitPriceEventAmount); allCancelIds.Count, eventUnitPrice, unitPriceEventCancelAmount, unitPriceEventFinalAmount);
return finalUnitPriceEventAmount; return unitPriceEventFinalAmount;
case ChargeMode.UnitPriceProject: case ChargeMode.UnitPriceProject:
// 【单价(项目)退款规则】 // 【单价(项目)退款规则】
@ -3098,7 +3136,10 @@ public class UnifiedRegistrationService : ITransient
// 按项目分组计算取消的人数和金额 // 按项目分组计算取消的人数和金额
foreach (var item in items) foreach (var item in items)
{ {
var itemPersons = persons.Where(p => p.RegistrationItemId == item.Id).ToList(); // 只处理未被软删除的项目中要取消的人员
if (item.DeleteMark) continue;
var itemPersons = persons.Where(p => p.RegistrationItemId == item.Id && !p.DeleteMark).ToList();
var canceledInItem = itemPersons.Count(p => allCancelIds.Contains(p.Id)); var canceledInItem = itemPersons.Count(p => allCancelIds.Contains(p.Id));
if (canceledInItem > 0) if (canceledInItem > 0)
@ -3113,14 +3154,13 @@ public class UnifiedRegistrationService : ITransient
// 直接对本次取消的原始总金额应用退款规则 // 直接对本次取消的原始总金额应用退款规则
var projectRefundAmount = await CalculateRefundAmountAsync(totalProjectCancelAmount, eventInfo.MatchStartTime); var projectRefundAmount = await CalculateRefundAmountAsync(totalProjectCancelAmount, eventInfo.MatchStartTime);
// 确保不超过剩余可退款金额 // 移除了错误的限制:每个团队/个人的退款应该独立计算,不受其他团队已退款金额影响
var maxProjectRefund = await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime); // 直接返回基于本次取消金额计算的退款金额
var finalProjectRefundAmount = Math.Min(projectRefundAmount, maxProjectRefund);
_logger.LogInformation("单价(项目)退款:本次取消总原始金额={TotalCancelAmount}, 按规则退款金额={RefundAmount}, 最终金额={FinalAmount}", _logger.LogInformation("单价(项目)退款:本次取消总原始金额={TotalCancelAmount}, 按规则退款金额={RefundAmount}",
totalProjectCancelAmount, projectRefundAmount, finalProjectRefundAmount); totalProjectCancelAmount, projectRefundAmount);
return finalProjectRefundAmount; return projectRefundAmount;
default: default:
_logger.LogInformation("未知收费模式,不退款"); _logger.LogInformation("未知收费模式,不退款");