退款配置
This commit is contained in:
parent
c9eb639123
commit
349bd553df
@ -174,6 +174,16 @@ public class CancelPreviewOutput
|
||||
/// </summary>
|
||||
public decimal RefundableAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 退款规则列表
|
||||
/// </summary>
|
||||
public List<RefundRuleDto> RefundRules { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 当前适用的退款规则描述
|
||||
/// </summary>
|
||||
public string? ApplicableRefundRule { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 项目列表
|
||||
/// </summary>
|
||||
@ -185,6 +195,32 @@ public class CancelPreviewOutput
|
||||
public List<CancelPreviewMemberDto> Members { get; set; } = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退款规则DTO
|
||||
/// </summary>
|
||||
public class RefundRuleDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 距离比赛开始天数(起)
|
||||
/// </summary>
|
||||
public int DayStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 距离比赛开始天数(止)
|
||||
/// </summary>
|
||||
public int DayEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扣除比例(%)
|
||||
/// </summary>
|
||||
public decimal DeductPercentage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 退款备注
|
||||
/// </summary>
|
||||
public string? Remark { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取消报名项目DTO
|
||||
/// </summary>
|
||||
|
||||
@ -150,7 +150,7 @@ public class CoachLeaderListOutput
|
||||
/// <summary>
|
||||
/// 性别
|
||||
/// </summary>
|
||||
public string Gender { get; set; }
|
||||
public int Gender { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 出生日期
|
||||
@ -160,7 +160,17 @@ public class CoachLeaderListOutput
|
||||
/// <summary>
|
||||
/// 身份证号
|
||||
/// </summary>
|
||||
public string IdCardNumber { get; set; }
|
||||
public string? IdCardNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 身份证正面图片URL
|
||||
/// </summary>
|
||||
public string? IdCardImageUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 身份证背面图片URL
|
||||
/// </summary>
|
||||
public string? IdCardBackImageUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 电话
|
||||
|
||||
@ -221,7 +221,11 @@ public class EventScoreService : BaseService<EventResult>, ITransient
|
||||
Id = p.Id,
|
||||
Name = p.Name,
|
||||
Age = p.Age,
|
||||
IdCardNumber = p.IdCardImageUrl,
|
||||
Gender = (int)p.Gender,
|
||||
BirthDate = p.BirthDate,
|
||||
IdCardNumber = p.IdCardNumber,
|
||||
IdCardImageUrl = p.IdCardImageUrl,
|
||||
IdCardBackImageUrl = p.IdCardBackImageUrl,
|
||||
Mobile = p.Mobile,
|
||||
CertificateId = 0 // 需要单独查询,此处先设为0
|
||||
})
|
||||
|
||||
@ -2445,6 +2445,38 @@ public class UnifiedRegistrationService : ITransient
|
||||
});
|
||||
}
|
||||
|
||||
var refundConfigs = await _refundConfigService.GetList();
|
||||
refundConfigs = refundConfigs.Where(x => x.Status == Core.Enum.AvailabilityStatus.Enable).OrderBy(x => x.DayStart).ToList();
|
||||
|
||||
foreach (var config in refundConfigs)
|
||||
{
|
||||
output.RefundRules.Add(new RefundRuleDto
|
||||
{
|
||||
DayStart = config.DayStart,
|
||||
DayEnd = config.DayEnd,
|
||||
DeductPercentage = config.DeductPercentage,
|
||||
Remark = config.Remark
|
||||
});
|
||||
}
|
||||
|
||||
var daysRemaining = (eventInfo.MatchStartTime - DateTime.Now).TotalDays;
|
||||
if (daysRemaining < 0) daysRemaining = 0;
|
||||
|
||||
var matchConfig = refundConfigs.FirstOrDefault(c =>
|
||||
daysRemaining >= c.DayStart &&
|
||||
(c.DayEnd == int.MaxValue ? true : daysRemaining < c.DayEnd)
|
||||
);
|
||||
|
||||
if (matchConfig != null)
|
||||
{
|
||||
var refundPercentage = 100 - matchConfig.DeductPercentage;
|
||||
output.ApplicableRefundRule = $"距离比赛开始还有 {Math.Round(daysRemaining, 1)} 天,退款比例为 {refundPercentage}%,扣除 {matchConfig.DeductPercentage}%。";
|
||||
}
|
||||
else
|
||||
{
|
||||
output.ApplicableRefundRule = "距离比赛开始还有 " + Math.Round(daysRemaining, 1) + " 天,全额退款。";
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@ -2544,6 +2576,36 @@ public class UnifiedRegistrationService : ITransient
|
||||
|
||||
if (registration.TotalAmount > 0 && !string.IsNullOrEmpty(registration.OrderNo) && actualRefundAmount > 0)
|
||||
{
|
||||
var originalOrder = await _orderRepository.GetFirstAsync(o => o.OrderNo == registration.OrderNo);
|
||||
if (originalOrder != null)
|
||||
{
|
||||
var refundOrder = new YD_Event.Core.Entities.Order
|
||||
{
|
||||
Id = _idGenerator.NewLong(),
|
||||
OrderNo = await _orderNoGeneratorService.GenerateRefundOrderNoAsync(),
|
||||
OrderType = 2,
|
||||
MerchantId = originalOrder.MerchantId,
|
||||
MerchantCertificationId = originalOrder.MerchantCertificationId,
|
||||
EventId = originalOrder.EventId,
|
||||
RegistrationId = originalOrder.RegistrationId,
|
||||
RelatedOrderId = originalOrder.Id,
|
||||
OriginalAmount = originalOrder.ActualAmount,
|
||||
ActualAmount = actualRefundAmount,
|
||||
DiscountAmount = 0,
|
||||
OrderStatus = OrderStatus.Refunded,
|
||||
PaymentTime = now,
|
||||
Remark = input.CancelReason,
|
||||
CreatedTime = now,
|
||||
CreatedUserId = operatorUserId,
|
||||
Status = AvailabilityStatus.Enable
|
||||
};
|
||||
await _orderRepository.InsertAsync(refundOrder);
|
||||
output.RefundNo = refundOrder.OrderNo;
|
||||
|
||||
_logger.LogInformation("退款订单创建成功:报名ID={RegistrationId}, 原订单号={OriginalOrderNo}, 退款订单号={RefundOrderNo}, 退款金额={Amount}",
|
||||
registration.Id, originalOrder.OrderNo, refundOrder.OrderNo, actualRefundAmount);
|
||||
}
|
||||
|
||||
var merchant = await _merchantRepository.GetFirstAsync(x => x.Id == eventInfo.MerchantId);
|
||||
|
||||
if (merchant != null)
|
||||
@ -2553,7 +2615,10 @@ public class UnifiedRegistrationService : ITransient
|
||||
if (wechatConfig != null)
|
||||
{
|
||||
var outRefundNo = await _orderNoGeneratorService.GenerateRefundOrderNoAsync();
|
||||
output.RefundNo = outRefundNo;
|
||||
if (string.IsNullOrEmpty(output.RefundNo))
|
||||
{
|
||||
output.RefundNo = outRefundNo;
|
||||
}
|
||||
|
||||
var refundRequest = new Core.Infrastructure.WeChat.Dto.CreateRefundRequest
|
||||
{
|
||||
@ -2574,8 +2639,6 @@ public class UnifiedRegistrationService : ITransient
|
||||
registration.Id, refundResult.Message);
|
||||
output.Success = false;
|
||||
output.Message = refundResult.Message;
|
||||
output.RefundAmount = 0;
|
||||
output.RefundNo = null;
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
@ -4920,6 +4920,16 @@
|
||||
可退款金额
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.CancelPreviewOutput.RefundRules">
|
||||
<summary>
|
||||
退款规则列表
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.CancelPreviewOutput.ApplicableRefundRule">
|
||||
<summary>
|
||||
当前适用的退款规则描述
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.CancelPreviewOutput.Projects">
|
||||
<summary>
|
||||
项目列表
|
||||
@ -4930,6 +4940,31 @@
|
||||
队员列表
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Event.Dtos.RefundRuleDto">
|
||||
<summary>
|
||||
退款规则DTO
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.RefundRuleDto.DayStart">
|
||||
<summary>
|
||||
距离比赛开始天数(起)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.RefundRuleDto.DayEnd">
|
||||
<summary>
|
||||
距离比赛开始天数(止)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.RefundRuleDto.DeductPercentage">
|
||||
<summary>
|
||||
扣除比例(%)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.RefundRuleDto.Remark">
|
||||
<summary>
|
||||
退款备注
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Event.Dtos.CancelPreviewProjectDto">
|
||||
<summary>
|
||||
取消报名项目DTO
|
||||
@ -5865,6 +5900,16 @@
|
||||
身份证号
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.CoachLeaderListOutput.IdCardImageUrl">
|
||||
<summary>
|
||||
身份证正面图片URL
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.CoachLeaderListOutput.IdCardBackImageUrl">
|
||||
<summary>
|
||||
身份证背面图片URL
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.CoachLeaderListOutput.Mobile">
|
||||
<summary>
|
||||
电话
|
||||
@ -5897,7 +5942,7 @@
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.IssueCertificateInput.PageType">
|
||||
<summary>
|
||||
页面类型:0-未指定,1-运动员页面,2-教练页面,3-领队页面
|
||||
页面类型:1-运动员页面,2-教练页面,3-领队页面
|
||||
用于明确区分不同角色页面的证书生成逻辑
|
||||
</summary>
|
||||
</member>
|
||||
@ -6758,27 +6803,7 @@
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.UserGroupMemberInput.MemberIds">
|
||||
<summary>
|
||||
成员ID列表(单个团队报名时使用,向后兼容)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.UserGroupMemberInput.Teams">
|
||||
<summary>
|
||||
团队列表(支持多个团队报名同一项目组别)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Event.Dtos.UserTeamInput">
|
||||
<summary>
|
||||
用户团队输入DTO
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.UserTeamInput.TeamIndex">
|
||||
<summary>
|
||||
团队序号(用于显示,如"团队一"、"团队二")
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.UserTeamInput.MemberIds">
|
||||
<summary>
|
||||
该团队的成员ID列表
|
||||
成员ID列表
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Event.Dtos.UserOrderPreviewOutput">
|
||||
@ -7775,13 +7800,6 @@
|
||||
发放证书(支持模板选择和批量发放)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Event.EventScoreService.IsValidPageType(System.Int32)">
|
||||
<summary>
|
||||
验证 PageType 参数是否有效
|
||||
</summary>
|
||||
<param name="pageType">页面类型值</param>
|
||||
<returns>是否有效</returns>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Event.EventScoreService.GetAllowedPersonTypes(System.Int32)">
|
||||
<summary>
|
||||
根据页面类型获取允许的人员类型列表
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user