修复bug
This commit is contained in:
parent
daf573b94d
commit
4bd2585680
@ -225,6 +225,11 @@ public class CancelPreviewOutput
|
||||
/// </summary>
|
||||
public decimal RefundableAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 历史已退款金额
|
||||
/// </summary>
|
||||
public decimal RefundedAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前选择的退款金额(动态计算)
|
||||
/// </summary>
|
||||
|
||||
@ -319,29 +319,59 @@ namespace YD_Event.Application.Event;
|
||||
// 计算项目总时长(在查询前计算,避免在SQL中使用C#方法)
|
||||
int projTotalDuration = proj.GetTotalDurationInSeconds();
|
||||
|
||||
// 获取参赛人员,并关联用户和单位认证信息
|
||||
var persons = await _personRepository.AsQueryable()
|
||||
// 第一步:先查询主要数据和相关的 MerchantCertificationId
|
||||
var basicPersons = await _personRepository.AsQueryable()
|
||||
.InnerJoin<EventRegistration>((p, r) => p.RegistrationId == r.Id)
|
||||
.LeftJoin<MerchantCertification>((p, r, m) => r.MerchantCertificationId == m.Id)
|
||||
.Where((p, r, m) => p.ProjectId == eventProj.Id
|
||||
.Where((p, r) => p.ProjectId == eventProj.Id
|
||||
&& r.PaymentStatus != 4
|
||||
&& !p.DeleteMark
|
||||
&& p.PersonType == PersonType.Athlete)
|
||||
.OrderBy(p => p.GroupName)
|
||||
.OrderBy(p => p.Id)
|
||||
.Select((p, r, m) => new {
|
||||
Id = p.Id, // 添加 Id 属性
|
||||
.Select((p, r) => new {
|
||||
Id = p.Id,
|
||||
RegistrationItemId = p.RegistrationItemId,
|
||||
p.UserId,
|
||||
p.Name,
|
||||
p.GroupName,
|
||||
r.TeamName,
|
||||
MerchantName = m.MerchantName ?? "",
|
||||
m.AuditStatus,
|
||||
r.MerchantCertificationId,
|
||||
Duration = projTotalDuration
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
// 第二步:收集所有需要查询的 MerchantCertificationId
|
||||
var merchantCertIds = basicPersons
|
||||
.Where(x => x.MerchantCertificationId.HasValue)
|
||||
.Select(x => x.MerchantCertificationId.Value)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
// 第三步:批量查询 MerchantCertification
|
||||
Dictionary<long, MerchantCertification> merchantDict = new Dictionary<long, MerchantCertification>();
|
||||
if (merchantCertIds.Any())
|
||||
{
|
||||
var merchants = await _merchantCertificationRepository.GetListAsync(x => merchantCertIds.Contains(x.Id));
|
||||
merchantDict = merchants.ToDictionary(x => x.Id, x => x);
|
||||
}
|
||||
|
||||
// 第四步:在内存中合并数据
|
||||
var persons = basicPersons.Select(bp => new {
|
||||
bp.Id,
|
||||
bp.RegistrationItemId,
|
||||
bp.UserId,
|
||||
bp.Name,
|
||||
bp.GroupName,
|
||||
bp.TeamName,
|
||||
MerchantName = bp.MerchantCertificationId.HasValue && merchantDict.ContainsKey(bp.MerchantCertificationId.Value)
|
||||
? merchantDict[bp.MerchantCertificationId.Value].MerchantName
|
||||
: null,
|
||||
AuditStatus = bp.MerchantCertificationId.HasValue && merchantDict.ContainsKey(bp.MerchantCertificationId.Value)
|
||||
? merchantDict[bp.MerchantCertificationId.Value].AuditStatus
|
||||
: (AuditStatus?)null,
|
||||
bp.Duration
|
||||
}).ToList();
|
||||
|
||||
if (!persons.Any()) continue;
|
||||
|
||||
// 计算项目总时长
|
||||
@ -471,7 +501,14 @@ namespace YD_Event.Application.Event;
|
||||
var teamNameProp = personData.GetType().GetProperty("TeamName");
|
||||
|
||||
string? merchantName = merchantNameProp?.GetValue(personData) as string;
|
||||
AuditStatus? auditStatus = auditStatusProp?.GetValue(personData) as AuditStatus?;
|
||||
var auditStatusValue = auditStatusProp?.GetValue(personData);
|
||||
AuditStatus? auditStatus = null;
|
||||
|
||||
if (auditStatusValue != null && auditStatusValue is AuditStatus status)
|
||||
{
|
||||
auditStatus = status;
|
||||
}
|
||||
|
||||
string? teamName = teamNameProp?.GetValue(personData) as string;
|
||||
|
||||
// 优先使用认证通过的单位名称
|
||||
|
||||
@ -2468,10 +2468,21 @@ public class UnifiedRegistrationService : ITransient
|
||||
var items = await _db.Queryable<EventRegistrationItem>().Where(x => x.RegistrationId == registrationId).ToListAsync();
|
||||
var persons = await _registrationPersonRepository.GetListAsync(x => x.RegistrationId == registrationId);
|
||||
|
||||
var refundableAmount = await CalculateRefundAmountAsync(registration.TotalAmount, eventInfo.MatchStartTime);
|
||||
// 查询历史已退款金额
|
||||
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 refundableAmount = await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime);
|
||||
|
||||
// 确保可退款金额不小于0
|
||||
refundableAmount = Math.Max(0, refundableAmount);
|
||||
|
||||
_logger.LogInformation("统一取消报名预览:报名ID={RegistrationId}, 赛事名称={EventName}, 实际支付={ActualAmount}, 可退款={RefundAmount}, 支付方式={PaymentMethod}",
|
||||
registrationId, eventInfo?.EventName, registration.TotalAmount, refundableAmount, registration.PaymentMethod);
|
||||
_logger.LogInformation("统一取消报名预览:报名ID={RegistrationId}, 赛事名称={EventName}, 实际支付={ActualAmount}, 已退款={RefundedAmount}, 剩余可退款={RefundAmount}, 支付方式={PaymentMethod}",
|
||||
registrationId, eventInfo?.EventName, registration.TotalAmount, refundedAmount, refundableAmount, registration.PaymentMethod);
|
||||
|
||||
// 获取组别信息(年龄和性别限制)
|
||||
var groupIds = items.Where(x => x.EventProjectGroupId.HasValue).Select(x => x.EventProjectGroupId.Value).Distinct().ToList();
|
||||
@ -2501,6 +2512,7 @@ public class UnifiedRegistrationService : ITransient
|
||||
ChargeMode = (int)eventInfo.ChargeMode,
|
||||
ActualPaidAmount = registration.TotalAmount,
|
||||
RefundableAmount = refundableAmount,
|
||||
RefundedAmount = refundedAmount,
|
||||
CurrentRefundAmount = refundableAmount,
|
||||
PaymentMethod = registration.PaymentMethod,
|
||||
PaymentStatus = registration.PaymentStatus,
|
||||
@ -2669,15 +2681,28 @@ public class UnifiedRegistrationService : ITransient
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 查询历史已退款金额
|
||||
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;
|
||||
|
||||
// 如果没有剩余可退,直接返回0
|
||||
if (remainingOriginalAmount <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 全部取消
|
||||
if (input.CancelType == 0)
|
||||
{
|
||||
return await CalculateRefundAmountAsync(registration.TotalAmount, eventInfo.MatchStartTime);
|
||||
return await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime);
|
||||
}
|
||||
|
||||
// 部分取消
|
||||
var baseRefundAmount = await CalculateRefundAmountAsync(registration.TotalAmount, eventInfo.MatchStartTime);
|
||||
var refundRatio = registration.TotalAmount > 0 ? baseRefundAmount / registration.TotalAmount : 1;
|
||||
var baseRefundAmount = await CalculateRefundAmountAsync(remainingOriginalAmount, eventInfo.MatchStartTime);
|
||||
var refundRatio = remainingOriginalAmount > 0 ? baseRefundAmount / remainingOriginalAmount : 1;
|
||||
|
||||
var cancelMemberIds = input.PersonIds ?? new List<long>();
|
||||
var cancelTeams = input.CancelTeams ?? new List<string>();
|
||||
@ -2712,7 +2737,9 @@ public class UnifiedRegistrationService : ITransient
|
||||
return baseRefundAmount;
|
||||
}
|
||||
// 否则,按人数比例退款
|
||||
return baseRefundAmount * (decimal)cancelTeamMemberCount / persons.Count;
|
||||
var fixedPriceCalculated = baseRefundAmount * (decimal)cancelTeamMemberCount / persons.Count;
|
||||
// 确保不超过剩余可退款金额
|
||||
return Math.Min(fixedPriceCalculated, baseRefundAmount);
|
||||
|
||||
case ChargeMode.UnitPriceEvent:
|
||||
// 单价(赛事):按取消人数计算
|
||||
@ -2732,8 +2759,10 @@ public class UnifiedRegistrationService : ITransient
|
||||
}
|
||||
|
||||
var cancelCount = allCancelMemberIds.Count;
|
||||
var unitPrice = persons.Count > 0 ? registration.TotalAmount / persons.Count : 0;
|
||||
return unitPrice * cancelCount * refundRatio;
|
||||
var unitPrice = persons.Count > 0 ? remainingOriginalAmount / persons.Count : 0;
|
||||
var calculatedAmount = unitPrice * cancelCount * refundRatio;
|
||||
// 确保不超过剩余可退款金额
|
||||
return Math.Min(calculatedAmount, baseRefundAmount);
|
||||
|
||||
case ChargeMode.UnitPriceProject:
|
||||
// 单价(项目):按每个项目的人数计算
|
||||
@ -2766,7 +2795,9 @@ public class UnifiedRegistrationService : ITransient
|
||||
}
|
||||
}
|
||||
|
||||
return totalCancelAmount * refundRatio;
|
||||
var projectCalculatedAmount = totalCancelAmount * refundRatio;
|
||||
// 确保不超过剩余可退款金额
|
||||
return Math.Min(projectCalculatedAmount, baseRefundAmount);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
|
||||
@ -5034,6 +5034,11 @@
|
||||
可退款金额(全部取消时)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.CancelPreviewOutput.RefundedAmount">
|
||||
<summary>
|
||||
历史已退款金额
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.CancelPreviewOutput.CurrentRefundAmount">
|
||||
<summary>
|
||||
当前选择的退款金额(动态计算)
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
"SleepMs": 300,
|
||||
"dbconfig": {
|
||||
"ConnectionStrings": [
|
||||
"8.153.108.90,Password=yd708090,SyncTimeout=15000,ConnectTimeout=15000,ResponseTimeout=15000,defaultDatabase=7,poolsize=100,ssl=false,writeBuffer=10240,idleTimeout=30000,connectRetry=3,asyncPipeline=false",
|
||||
"8.153.108.90,Password=yd708090,SyncTimeout=15000,ConnectTimeout=15000,ResponseTimeout=15000,defaultDatabase=7,poolsize=100,ssl=false,writeBuffer=10240,idleTimeout=30000,connectRetry=3,asyncPipeline=false"
|
||||
//"8.153.108.90,Password=yd708090,SyncTimeout=15000,ConnectTimeout=15000,ResponseTimeout=15000,defaultDatabase=8,poolsize=100,ssl=false,writeBuffer=10240,idleTimeout=30000,connectRetry=3,asyncPipeline=false"
|
||||
],
|
||||
//"Sentinels": [
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user