diff --git a/YD_Event.Application/Event/UnifiedRegistrationService.cs b/YD_Event.Application/Event/UnifiedRegistrationService.cs index 2c853eb..bb448bf 100644 --- a/YD_Event.Application/Event/UnifiedRegistrationService.cs +++ b/YD_Event.Application/Event/UnifiedRegistrationService.cs @@ -2720,11 +2720,32 @@ public class UnifiedRegistrationService : ITransient var historyRefunds = await _refundRecordRepository.GetListAsync(x => x.RegistrationId == registrationId && x.RefundStatus == 1); 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 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 refundedAmount = historyRefunds.Sum(x => x.RefundAmount); - // 计算剩余可退款金额 - var remainingOriginalAmount = registration.TotalAmount - refundedAmount; - var remainingRefundableAmount = await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime); + // 计算剩余可退款金额:应该基于每个未退款的报名项分别计算,然后求和 + var remainingItems = items.Where(x => !x.DeleteMark).ToList(); + 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 { @@ -3071,14 +3110,13 @@ public class UnifiedRegistrationService : ITransient // 直接对本次取消的原始金额应用退款规则 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}", - allCancelIds.Count, eventUnitPrice, unitPriceEventCancelAmount, unitPriceEventFinalAmount, finalUnitPriceEventAmount); + _logger.LogInformation("单价(赛事)退款:取消人数={CancelCount}, 赛事单价={UnitPrice}, 本次取消原始金额={CancelAmount}, 按规则退款金额={RefundAmount}", + allCancelIds.Count, eventUnitPrice, unitPriceEventCancelAmount, unitPriceEventFinalAmount); - return finalUnitPriceEventAmount; + return unitPriceEventFinalAmount; case ChargeMode.UnitPriceProject: // 【单价(项目)退款规则】 @@ -3098,7 +3136,10 @@ public class UnifiedRegistrationService : ITransient // 按项目分组计算取消的人数和金额 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)); if (canceledInItem > 0) @@ -3113,14 +3154,13 @@ public class UnifiedRegistrationService : ITransient // 直接对本次取消的原始总金额应用退款规则 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}", - totalProjectCancelAmount, projectRefundAmount, finalProjectRefundAmount); + _logger.LogInformation("单价(项目)退款:本次取消总原始金额={TotalCancelAmount}, 按规则退款金额={RefundAmount}", + totalProjectCancelAmount, projectRefundAmount); - return finalProjectRefundAmount; + return projectRefundAmount; default: _logger.LogInformation("未知收费模式,不退款");