From 67c52979ceca3d49af33aca5ea663cca954c82b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E6=A2=93=E5=BD=AD?= Date: Tue, 12 May 2026 13:58:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E4=BC=98=E6=83=A0=E5=8A=B5?= =?UTF-8?q?=E5=90=8E=E7=9A=84=E5=AE=9E=E9=99=85=E9=87=91=E9=A2=9D=E9=80=80?= =?UTF-8?q?=E6=AC=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Event/UnifiedRegistrationService.cs | 69 ++++++++++++------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/YD_Event.Application/Event/UnifiedRegistrationService.cs b/YD_Event.Application/Event/UnifiedRegistrationService.cs index 16b1483..2f09deb 100644 --- a/YD_Event.Application/Event/UnifiedRegistrationService.cs +++ b/YD_Event.Application/Event/UnifiedRegistrationService.cs @@ -2765,10 +2765,14 @@ public class UnifiedRegistrationService : ITransient // 获取尚未被软删除的报名项 var remainingItems = items.Where(x => !x.DeleteMark).ToList(); - // 计算剩余可退款金额 - decimal refundableAmount = 0; + // 查询订单获取实际支付金额(考虑优惠券抵扣) - 先获取,因为后面需要用来计算 + var order = await _orderRepository.GetFirstAsync(x => x.RegistrationId == registrationId && x.OrderType == 1 && !x.DeleteMark); + var actualPaidAmount = order?.ActualAmount ?? registration.TotalAmount; + var originalAmount = registration.TotalAmount; + + // 区分不同的收费模式来计算(基于原价) + decimal originalRefundableAmount = 0; - // 区分不同的收费模式来计算 if (eventInfo.ChargeMode == ChargeMode.UnitPriceProject) { // 单价(项目)模式:每个未删除的项目独立计算退款 @@ -2777,7 +2781,7 @@ public class UnifiedRegistrationService : ITransient var itemPersons = persons.Where(p => p.RegistrationItemId == item.Id && !p.DeleteMark).ToList(); var itemOriginalAmount = item.UnitPrice * itemPersons.Count; var itemRefund = await CalculateRefundAmountAsync(itemOriginalAmount, eventInfo.MatchStartTime); - refundableAmount += itemRefund; + originalRefundableAmount += itemRefund; } } else if (eventInfo.ChargeMode == ChargeMode.UnitPriceEvent) @@ -2798,20 +2802,25 @@ public class UnifiedRegistrationService : ITransient // 剩余可退款的人数 var remainingPersonCount = personGroups.Count; var remainingOriginalAmount = eventUnitPrice * remainingPersonCount; - refundableAmount = await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime); + originalRefundableAmount = await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime); } else { // 定价(赛事)模式:使用传统方式计算 var remainingOriginalAmount = registration.TotalAmount - refundedAmount; - refundableAmount = await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime); + originalRefundableAmount = await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime); } // 确保可退款金额不小于0 - refundableAmount = Math.Max(0, refundableAmount); + originalRefundableAmount = Math.Max(0, originalRefundableAmount); - _logger.LogInformation("统一取消报名预览:报名ID={RegistrationId}, 赛事名称={EventName}, 实际支付={ActualAmount}, 已退款={RefundedAmount}, 剩余可退款={RefundAmount}, 支付方式={PaymentMethod}", - registrationId, eventInfo?.EventName, registration.TotalAmount, refundedAmount, refundableAmount, registration.PaymentMethod); + // 按比例转换为基于实际支付的可退款金额 + decimal refundableAmount = originalAmount > 0 ? originalRefundableAmount * (actualPaidAmount / originalAmount) : 0; + refundableAmount = RoundUpToTwoDecimalPlaces(refundableAmount); + refundableAmount = Math.Min(refundableAmount, actualPaidAmount - refundedAmount); + + _logger.LogInformation("统一取消报名预览:报名ID={RegistrationId}, 赛事名称={EventName}, 原价={OriginalAmount}, 实际支付={ActualAmount}, 已退款={RefundedAmount}, 原价可退款={OriginalRefundableAmount}, 实际可退款={RefundableAmount}, 支付方式={PaymentMethod}", + registrationId, eventInfo?.EventName, originalAmount, actualPaidAmount, refundedAmount, originalRefundableAmount, refundableAmount, registration.PaymentMethod); // 获取组别信息(年龄和性别限制) var groupIds = items.Where(x => x.EventProjectGroupId.HasValue).Select(x => x.EventProjectGroupId.Value).Distinct().ToList(); @@ -2833,10 +2842,6 @@ public class UnifiedRegistrationService : ITransient projects = projectList.ToDictionary(x => x.Id); } - // 查询订单获取实际支付金额(考虑优惠券抵扣) - var order = await _orderRepository.GetFirstAsync(x => x.RegistrationId == registrationId && x.OrderType == 1 && !x.DeleteMark); - var actualPaidAmount = order?.ActualAmount ?? registration.TotalAmount; - var output = new CancelPreviewOutput { RegistrationId = registration.Id, @@ -3011,6 +3016,11 @@ public class UnifiedRegistrationService : ITransient var items = await _db.Queryable().Where(x => x.RegistrationId == input.RegistrationId).ToListAsync(); var persons = await _registrationPersonRepository.GetListAsync(x => x.RegistrationId == input.RegistrationId); + // 查询订单获取实际支付金额(考虑优惠券抵扣) + var order = await _orderRepository.GetFirstAsync(x => x.RegistrationId == input.RegistrationId && x.OrderType == 1 && !x.DeleteMark); + var actualPaidAmount = order?.ActualAmount ?? registration.TotalAmount; + var originalAmount = registration.TotalAmount; + // 构建一个临时的CancelExecuteInput来复用计算逻辑 var tempInput = new CancelExecuteInput { @@ -3020,16 +3030,21 @@ public class UnifiedRegistrationService : ITransient CancelTeams = input.CancelTeams }; - // 计算退款金额 - var refundAmount = await CalculateActualRefundAmountAsync(tempInput, registration, eventInfo, items, persons); + // 先计算按原价应该退多少 + decimal originalRefundAmount = await CalculateActualRefundAmountAsync(tempInput, registration, eventInfo, items, persons); + + // 按比例计算实际退款金额(基于实际支付金额) + decimal actualRefundAmount = originalAmount > 0 ? originalRefundAmount * (actualPaidAmount / originalAmount) : 0; + actualRefundAmount = RoundUpToTwoDecimalPlaces(actualRefundAmount); + actualRefundAmount = Math.Min(actualRefundAmount, actualPaidAmount); // 查询历史已退款金额 var historyRefunds = await _refundRecordRepository.GetListAsync(x => x.RegistrationId == registration.Id && x.RefundStatus == 1); var refundedAmount = historyRefunds.Sum(x => x.RefundAmount); - // 计算剩余可退款金额 + // 计算剩余可退款金额(基于实际支付金额) var remainingItems = items.Where(x => !x.DeleteMark).ToList(); - decimal remainingRefundableAmount = 0; + decimal remainingOriginalRefundableAmount = 0; // 区分不同的收费模式来计算 if (eventInfo.ChargeMode == ChargeMode.UnitPriceProject) @@ -3040,7 +3055,7 @@ public class UnifiedRegistrationService : ITransient var itemPersons = persons.Where(p => p.RegistrationItemId == item.Id && !p.DeleteMark).ToList(); var itemOriginalAmount = item.UnitPrice * itemPersons.Count; var itemRefund = await CalculateRefundAmountAsync(itemOriginalAmount, eventInfo.MatchStartTime); - remainingRefundableAmount += itemRefund; + remainingOriginalRefundableAmount += itemRefund; } } else if (eventInfo.ChargeMode == ChargeMode.UnitPriceEvent) @@ -3061,23 +3076,27 @@ public class UnifiedRegistrationService : ITransient // 剩余可退款的人数 var remainingPersonCount = personGroups.Count; var remainingOriginalAmount = eventUnitPrice * remainingPersonCount; - remainingRefundableAmount = await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime); + remainingOriginalRefundableAmount = await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime); } else { // 定价(赛事)模式:使用传统方式计算 var remainingOriginalAmount = registration.TotalAmount - refundedAmount; - remainingRefundableAmount = await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime); + remainingOriginalRefundableAmount = await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime); } - // 查询订单获取实际支付金额(考虑优惠券抵扣) - var order = await _orderRepository.GetFirstAsync(x => x.RegistrationId == input.RegistrationId && x.OrderType == 1 && !x.DeleteMark); - var actualPaidAmount = order?.ActualAmount ?? registration.TotalAmount; + // 按比例计算剩余可退款金额(基于实际支付金额) + decimal remainingActualRefundableAmount = originalAmount > 0 ? remainingOriginalRefundableAmount * (actualPaidAmount / originalAmount) : 0; + remainingActualRefundableAmount = RoundUpToTwoDecimalPlaces(remainingActualRefundableAmount); + remainingActualRefundableAmount = Math.Min(remainingActualRefundableAmount, actualPaidAmount - refundedAmount); + + _logger.LogInformation("计算退款金额:报名ID={RegistrationId}, 原价={OriginalAmount}, 实付={ActualPaidAmount}, 按原价应退={OriginalRefundAmount}, 实际退款={ActualRefundAmount}, 剩余原价可退={RemainingOriginalRefundableAmount}, 剩余实际可退={RemainingActualRefundableAmount}, 已退={RefundedAmount}", + registration.Id, originalAmount, actualPaidAmount, originalRefundAmount, actualRefundAmount, remainingOriginalRefundableAmount, remainingActualRefundableAmount, refundedAmount); return new CalculateRefundAmountOutput { - refundAmount = refundAmount, - refundableAmount = remainingRefundableAmount, + refundAmount = actualRefundAmount, + refundableAmount = remainingActualRefundableAmount, refundedAmount = refundedAmount, actualPaidAmount = actualPaidAmount };