重复报名
This commit is contained in:
parent
12562f962c
commit
e03ad5eb46
@ -923,13 +923,13 @@ public class EventClientController : IDynamicApiController
|
||||
else if (now >= reg.MatchStart && now <= reg.MatchEnd) status = EventStatus.Ongoing;
|
||||
else if (now > reg.MatchEnd) status = EventStatus.Ended;
|
||||
|
||||
// 获取 Items 和 Persons
|
||||
// 获取 Items 和 Persons - 只获取未被软删除的
|
||||
var items = await _registrationItemRepository.AsQueryable()
|
||||
.Where(i => i.RegistrationId == registrationId)
|
||||
.Where(i => i.RegistrationId == registrationId && !i.DeleteMark)
|
||||
.ToListAsync();
|
||||
|
||||
var persons = await _personRepository.AsQueryable()
|
||||
.Where(p => p.RegistrationId == registrationId)
|
||||
.Where(p => p.RegistrationId == registrationId && !p.DeleteMark)
|
||||
.ToListAsync();
|
||||
|
||||
// 计算退款金额和获取退款规则
|
||||
|
||||
@ -184,9 +184,35 @@ public class UnifiedRegistrationService : ITransient
|
||||
registration.UpdatedTime = DateTime.Now;
|
||||
registration.UpdatedUserId = input.CreatedUserId;
|
||||
|
||||
// 删除旧的明细和人员
|
||||
await _registrationItemRepository.DeleteAsync(x => x.RegistrationId == registration.Id);
|
||||
await _registrationPersonRepository.DeleteAsync(x => x.RegistrationId == registration.Id);
|
||||
// 软删除旧的明细和人员(保留历史记录,与取消报名逻辑一致)
|
||||
var oldItems = await _registrationItemRepository.GetListAsync(x => x.RegistrationId == registration.Id && !x.DeleteMark);
|
||||
var oldPersons = await _registrationPersonRepository.GetListAsync(x => x.RegistrationId == registration.Id && !x.DeleteMark);
|
||||
|
||||
var now = DateTime.Now;
|
||||
|
||||
if (oldItems.Any())
|
||||
{
|
||||
foreach (var item in oldItems)
|
||||
{
|
||||
item.DeleteMark = true;
|
||||
item.UpdatedUserId = input.CreatedUserId;
|
||||
item.UpdatedTime = now;
|
||||
}
|
||||
await _registrationItemRepository.UpdateRangeAsync(oldItems);
|
||||
_logger.LogInformation("重新报名,软删除旧项目:报名ID={RegistrationId}, 项目数={Count}", registration.Id, oldItems.Count);
|
||||
}
|
||||
|
||||
if (oldPersons.Any())
|
||||
{
|
||||
foreach (var person in oldPersons)
|
||||
{
|
||||
person.DeleteMark = true;
|
||||
person.UpdatedUserId = input.CreatedUserId;
|
||||
person.UpdatedTime = now;
|
||||
}
|
||||
await _registrationPersonRepository.UpdateRangeAsync(oldPersons);
|
||||
_logger.LogInformation("重新报名,软删除旧人员:报名ID={RegistrationId}, 人数={Count}", registration.Id, oldPersons.Count);
|
||||
}
|
||||
|
||||
return registration;
|
||||
}
|
||||
@ -2792,13 +2818,17 @@ 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,
|
||||
EventName = eventInfo?.EventName ?? "",
|
||||
TeamName = registration.TeamName ?? "",
|
||||
ChargeMode = (int)eventInfo.ChargeMode,
|
||||
ActualPaidAmount = registration.TotalAmount,
|
||||
ActualPaidAmount = actualPaidAmount,
|
||||
RefundableAmount = refundableAmount,
|
||||
RefundedAmount = refundedAmount,
|
||||
CurrentRefundAmount = refundableAmount,
|
||||
@ -2807,7 +2837,7 @@ public class UnifiedRegistrationService : ITransient
|
||||
NeedPayeeInfo = registration.PaymentMethod == 1 && registration.PaymentStatus == 1
|
||||
};
|
||||
|
||||
foreach (var item in items)
|
||||
foreach (var item in items.Where(x => !x.DeleteMark))
|
||||
{
|
||||
output.Projects.Add(new CancelPreviewProjectDto
|
||||
{
|
||||
@ -2819,7 +2849,7 @@ public class UnifiedRegistrationService : ITransient
|
||||
});
|
||||
}
|
||||
|
||||
foreach (var person in persons)
|
||||
foreach (var person in persons.Where(x => !x.DeleteMark))
|
||||
{
|
||||
output.Members.Add(new CancelPreviewMemberDto
|
||||
{
|
||||
@ -2830,7 +2860,7 @@ public class UnifiedRegistrationService : ITransient
|
||||
}
|
||||
|
||||
// 构建新版详细数据结构(按项目 -> 组别 -> 团队 -> 队员分类)
|
||||
var itemGroups = items.GroupBy(x => x.ProjectId);
|
||||
var itemGroups = items.Where(x => !x.DeleteMark).GroupBy(x => x.ProjectId);
|
||||
foreach (var itemGroup in itemGroups)
|
||||
{
|
||||
var firstItem = itemGroup.First();
|
||||
@ -2879,8 +2909,8 @@ public class UnifiedRegistrationService : ITransient
|
||||
int teamIndex = 0;
|
||||
foreach (var item in groupGroup)
|
||||
{
|
||||
// 获取该报名项目下的所有队员
|
||||
var itemPersons = persons.Where(p => p.RegistrationItemId == item.Id).ToList();
|
||||
// 获取该报名项目下的所有队员 - 只获取未被软删除的
|
||||
var itemPersons = persons.Where(p => p.RegistrationItemId == item.Id && !p.DeleteMark).ToList();
|
||||
|
||||
// 每个报名项作为一个独立的团队条目
|
||||
var teamDto = new CancelPreviewTeamDto
|
||||
@ -3025,12 +3055,16 @@ public class UnifiedRegistrationService : ITransient
|
||||
remainingRefundableAmount = 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;
|
||||
|
||||
return new CalculateRefundAmountOutput
|
||||
{
|
||||
refundAmount = refundAmount,
|
||||
refundableAmount = remainingRefundableAmount,
|
||||
refundedAmount = refundedAmount,
|
||||
actualPaidAmount = registration.TotalAmount
|
||||
actualPaidAmount = actualPaidAmount
|
||||
};
|
||||
}
|
||||
|
||||
@ -3328,9 +3362,20 @@ public class UnifiedRegistrationService : ITransient
|
||||
// 计算实际退款金额
|
||||
// 【重要】始终信任后端计算结果,前端计算只用于展示
|
||||
// 不接受前端传递的退款金额,避免资金风险
|
||||
decimal actualRefundAmount = await CalculateActualRefundAmountAsync(input, registration, eventInfo, items, persons);
|
||||
_logger.LogInformation("统一退款金额计算:报名ID={RegistrationId}, 总金额={TotalAmount}, 退款金额={ActualRefundAmount}",
|
||||
registration.Id, registration.TotalAmount, actualRefundAmount);
|
||||
var order = await _orderRepository.GetFirstAsync(o => o.RegistrationId == registration.Id && o.OrderType == 1 && !o.DeleteMark);
|
||||
var actualPaidAmount = order?.ActualAmount ?? registration.TotalAmount;
|
||||
var originalAmount = registration.TotalAmount;
|
||||
|
||||
// 先计算按原价应该退多少
|
||||
decimal originalRefundAmount = await CalculateActualRefundAmountAsync(input, registration, eventInfo, items, persons);
|
||||
|
||||
// 然后按比例计算实际退款金额(考虑优惠券折扣)
|
||||
decimal actualRefundAmount = originalAmount > 0 ? originalRefundAmount * (actualPaidAmount / originalAmount) : 0;
|
||||
// 确保退款金额不超过实际支付金额
|
||||
actualRefundAmount = Math.Min(actualRefundAmount, actualPaidAmount);
|
||||
|
||||
_logger.LogInformation("统一退款金额计算:报名ID={RegistrationId}, 原价={OriginalAmount}, 实付={ActualPaidAmount}, 按原价应退={OriginalRefundAmount}, 实际退款={ActualRefundAmount}",
|
||||
registration.Id, originalAmount, actualPaidAmount, originalRefundAmount, actualRefundAmount);
|
||||
|
||||
bool isPartialCancel = input.CancelType == 1;
|
||||
|
||||
@ -3489,12 +3534,12 @@ public class UnifiedRegistrationService : ITransient
|
||||
}
|
||||
else
|
||||
{
|
||||
registration.PaymentStatus = 3;
|
||||
registration.PaymentStatus = 4; // 已取消(与线下支付保持一致)
|
||||
registration.UpdatedUserId = operatorUserId;
|
||||
registration.UpdatedTime = now;
|
||||
registration.RegistrationRemark = input.CancelReason;
|
||||
await _registrationRepository.UpdateAsync(registration);
|
||||
_logger.LogInformation("统一所有人员已退款,更新报名状态为已退款:报名ID={RegistrationId}", registration.Id);
|
||||
_logger.LogInformation("统一所有人员已退款,更新报名状态为已取消:报名ID={RegistrationId}", registration.Id);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -3510,7 +3555,7 @@ public class UnifiedRegistrationService : ITransient
|
||||
await SoftDeleteItemsAsync(items.Select(i => i.Id).ToList(), operatorUserId, now);
|
||||
_logger.LogInformation("已软删除所有项目:报名ID={RegistrationId}", registration.Id);
|
||||
|
||||
registration.PaymentStatus = 3;
|
||||
registration.PaymentStatus = 4; // 已取消(与线下支付保持一致)
|
||||
registration.UpdatedUserId = operatorUserId;
|
||||
registration.UpdatedTime = now;
|
||||
registration.RegistrationRemark = input.CancelReason;
|
||||
@ -3568,7 +3613,7 @@ public class UnifiedRegistrationService : ITransient
|
||||
|
||||
// 创建线下支付退款记录
|
||||
await CreateRefundRecordAsync(registration, eventInfo, null, refundOrder.OrderNo,
|
||||
null, actualRefundAmount, registration.TotalAmount, input.CancelReason, operatorUserId,
|
||||
null, actualRefundAmount, actualPaidAmount, input.CancelReason, operatorUserId,
|
||||
input.PayeeName, input.PayeeBankName, input.PayeeBankAccount);
|
||||
}
|
||||
}
|
||||
@ -3624,7 +3669,7 @@ public class UnifiedRegistrationService : ITransient
|
||||
OutTradeNo = registration.OrderNo,
|
||||
OutRefundNo = outRefundNo,
|
||||
RefundAmount = AmountHelper.YuanToFen(actualRefundAmount),
|
||||
TotalAmount = AmountHelper.YuanToFen(registration.TotalAmount),
|
||||
TotalAmount = AmountHelper.YuanToFen(actualPaidAmount), // 使用实际支付金额作为总金额
|
||||
Reason = input.CancelReason
|
||||
};
|
||||
|
||||
@ -3642,7 +3687,7 @@ public class UnifiedRegistrationService : ITransient
|
||||
}
|
||||
|
||||
await CreateRefundRecordAsync(registration, eventInfo, wechatConfig, outRefundNo,
|
||||
refundResult.RefundId, actualRefundAmount, registration.TotalAmount, input.CancelReason, operatorUserId);
|
||||
refundResult.RefundId, actualRefundAmount, actualPaidAmount, input.CancelReason, operatorUserId);
|
||||
|
||||
_logger.LogInformation("统一退款成功:报名ID={RegistrationId}, 退款单号={RefundNo}, 退款金额={Amount}",
|
||||
registration.Id, outRefundNo, actualRefundAmount);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user