diff --git a/YD_Event.Application/Event/Dtos/EventRecordDtos.cs b/YD_Event.Application/Event/Dtos/EventRecordDtos.cs
index 155ce7a..6e1a04f 100644
--- a/YD_Event.Application/Event/Dtos/EventRecordDtos.cs
+++ b/YD_Event.Application/Event/Dtos/EventRecordDtos.cs
@@ -174,6 +174,16 @@ public class CancelPreviewOutput
///
public decimal RefundableAmount { get; set; }
+ ///
+ /// 退款规则列表
+ ///
+ public List RefundRules { get; set; } = new();
+
+ ///
+ /// 当前适用的退款规则描述
+ ///
+ public string? ApplicableRefundRule { get; set; }
+
///
/// 项目列表
///
@@ -185,6 +195,32 @@ public class CancelPreviewOutput
public List Members { get; set; } = new();
}
+///
+/// 退款规则DTO
+///
+public class RefundRuleDto
+{
+ ///
+ /// 距离比赛开始天数(起)
+ ///
+ public int DayStart { get; set; }
+
+ ///
+ /// 距离比赛开始天数(止)
+ ///
+ public int DayEnd { get; set; }
+
+ ///
+ /// 扣除比例(%)
+ ///
+ public decimal DeductPercentage { get; set; }
+
+ ///
+ /// 退款备注
+ ///
+ public string? Remark { get; set; }
+}
+
///
/// 取消报名项目DTO
///
diff --git a/YD_Event.Application/Event/Dtos/ScoreDtos.cs b/YD_Event.Application/Event/Dtos/ScoreDtos.cs
index 3b74be2..6cf7595 100644
--- a/YD_Event.Application/Event/Dtos/ScoreDtos.cs
+++ b/YD_Event.Application/Event/Dtos/ScoreDtos.cs
@@ -150,7 +150,7 @@ public class CoachLeaderListOutput
///
/// 性别
///
- public string Gender { get; set; }
+ public int Gender { get; set; }
///
/// 出生日期
@@ -160,7 +160,17 @@ public class CoachLeaderListOutput
///
/// 身份证号
///
- public string IdCardNumber { get; set; }
+ public string? IdCardNumber { get; set; }
+
+ ///
+ /// 身份证正面图片URL
+ ///
+ public string? IdCardImageUrl { get; set; }
+
+ ///
+ /// 身份证背面图片URL
+ ///
+ public string? IdCardBackImageUrl { get; set; }
///
/// 电话
diff --git a/YD_Event.Application/Event/EventScoreService.cs b/YD_Event.Application/Event/EventScoreService.cs
index 56221f2..f18264d 100644
--- a/YD_Event.Application/Event/EventScoreService.cs
+++ b/YD_Event.Application/Event/EventScoreService.cs
@@ -221,7 +221,11 @@ public class EventScoreService : BaseService, 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
})
diff --git a/YD_Event.Application/Event/UnifiedRegistrationService.cs b/YD_Event.Application/Event/UnifiedRegistrationService.cs
index 04f5435..ff86ce3 100644
--- a/YD_Event.Application/Event/UnifiedRegistrationService.cs
+++ b/YD_Event.Application/Event/UnifiedRegistrationService.cs
@@ -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;
}
diff --git a/YD_Event.Application/YD_Event.Application.xml b/YD_Event.Application/YD_Event.Application.xml
index 85282d1..03432e2 100644
--- a/YD_Event.Application/YD_Event.Application.xml
+++ b/YD_Event.Application/YD_Event.Application.xml
@@ -4920,6 +4920,16 @@
可退款金额
+
+
+ 退款规则列表
+
+
+
+
+ 当前适用的退款规则描述
+
+
项目列表
@@ -4930,6 +4940,31 @@
队员列表
+
+
+ 退款规则DTO
+
+
+
+
+ 距离比赛开始天数(起)
+
+
+
+
+ 距离比赛开始天数(止)
+
+
+
+
+ 扣除比例(%)
+
+
+
+
+ 退款备注
+
+
取消报名项目DTO
@@ -5865,6 +5900,16 @@
身份证号
+
+
+ 身份证正面图片URL
+
+
+
+
+ 身份证背面图片URL
+
+
电话
@@ -5897,7 +5942,7 @@
- 页面类型:0-未指定,1-运动员页面,2-教练页面,3-领队页面
+ 页面类型:1-运动员页面,2-教练页面,3-领队页面
用于明确区分不同角色页面的证书生成逻辑
@@ -6758,27 +6803,7 @@
- 成员ID列表(单个团队报名时使用,向后兼容)
-
-
-
-
- 团队列表(支持多个团队报名同一项目组别)
-
-
-
-
- 用户团队输入DTO
-
-
-
-
- 团队序号(用于显示,如"团队一"、"团队二")
-
-
-
-
- 该团队的成员ID列表
+ 成员ID列表
@@ -7775,13 +7800,6 @@
发放证书(支持模板选择和批量发放)
-
-
- 验证 PageType 参数是否有效
-
- 页面类型值
- 是否有效
-
根据页面类型获取允许的人员类型列表