修复bug
This commit is contained in:
parent
f285c439a8
commit
493ead2d0f
@ -905,11 +905,7 @@ public class UploadVoucherInput
|
||||
[Required]
|
||||
public DateTime PayTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支付渠道 (微信/支付宝/银行转账)
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string PayChannel { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 交易流水号 (可选)
|
||||
|
||||
@ -38,7 +38,9 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
||||
_eventInfoRepository = eventInfoRepository;
|
||||
}
|
||||
|
||||
// 格式化时长显示(符号格式:X'X")
|
||||
/// <summary>
|
||||
/// 格式化时长显示(符号格式:X'X")
|
||||
/// </summary>
|
||||
private string FormatDurationSymbol(int totalSeconds)
|
||||
{
|
||||
if (totalSeconds <= 0)
|
||||
@ -88,20 +90,19 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
||||
var eventProjects = await _eventProjectRepository.GetListAsync(x => x.EventId == eventId);
|
||||
var projectIds = eventProjects.Select(x => x.ProjectId).Distinct().ToList();
|
||||
var projects = await _projectRepository.GetListAsync(x => projectIds.Contains(x.Id));
|
||||
|
||||
|
||||
// 按照 SortIndex 对 projects 排序
|
||||
var sortedProjects = projects.OrderBy(x => x.SortIndex).ToList();
|
||||
|
||||
|
||||
var groups = await _groupRepository.GetListAsync(x => projectIds.Contains(x.ProjectId));
|
||||
|
||||
// 统计各组别报名人数(统计所有非取消状态的报名,并且只统计运动员
|
||||
var counts = await _personRepository.AsQueryable()
|
||||
.InnerJoin<EventRegistration>((p, r) => p.RegistrationId == r.Id)
|
||||
.Where((p, r) => r.EventId == eventId
|
||||
.Where((p, r) => r.EventId == eventId
|
||||
&& r.PaymentStatus != 4 // 排除已取消的报名
|
||||
&& !p.DeleteMark // 排除已删除的人员
|
||||
&& p.PersonType == PersonType.Athlete // 只统计运动员
|
||||
)
|
||||
&& p.PersonType == PersonType.Athlete) // 只统计运动员
|
||||
.GroupBy((p, r) => new { p.ProjectId, p.GroupName })
|
||||
.Select((p, r) => new { p.ProjectId, p.GroupName, Count = SqlFunc.AggregateCount(p.Id) })
|
||||
.ToListAsync();
|
||||
@ -109,9 +110,9 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
||||
// 获取所有相关的人员和报名记录(用于统计团队数)
|
||||
var personWithTeam = await _personRepository.AsQueryable()
|
||||
.InnerJoin<EventRegistration>((p, r) => p.RegistrationId == r.Id)
|
||||
.Where((p, r) => r.EventId == eventId
|
||||
&& r.PaymentStatus != 4
|
||||
&& !p.DeleteMark
|
||||
.Where((p, r) => r.EventId == eventId
|
||||
&& r.PaymentStatus != 4
|
||||
&& !p.DeleteMark
|
||||
&& p.PersonType == PersonType.Athlete
|
||||
&& r.TeamName != null)
|
||||
.Select((p, r) => new { p.ProjectId, p.GroupName, r.TeamName })
|
||||
@ -136,7 +137,7 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
||||
ProjectId = eventProj.Id,
|
||||
ProjectName = proj.Name,
|
||||
ProjectType = proj.ProjectType.Description(),
|
||||
DurationSeconds = proj.DurationSeconds,
|
||||
DurationSeconds = proj.GetTotalDurationInSeconds(),
|
||||
VenueCount = proj.VenueCount,
|
||||
SortIndex = proj.SortIndex,
|
||||
Groups = new List<ArrangementGroupDto>()
|
||||
@ -146,18 +147,18 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
||||
foreach (var group in projGroups)
|
||||
{
|
||||
var countObj = counts.FirstOrDefault(c => c.ProjectId == eventProj.Id && c.GroupName == group.GroupName);
|
||||
dto.Groups.Add(new ArrangementGroupDto
|
||||
{
|
||||
GroupName = group.GroupName,
|
||||
ParticipantCount = countObj?.Count ?? 0
|
||||
dto.Groups.Add(new ArrangementGroupDto
|
||||
{
|
||||
GroupName = group.GroupName,
|
||||
ParticipantCount = countObj?.Count ?? 0
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 根据项目类型计算总时长
|
||||
int venueCount = proj.VenueCount > 0 ? proj.VenueCount : 1;
|
||||
int totalParticipants = dto.Groups.Sum(g => g.ParticipantCount);
|
||||
int totalTeams = 0;
|
||||
|
||||
|
||||
// 如果是团队项目,计算团队总数
|
||||
if (proj.IsTeamProject())
|
||||
{
|
||||
@ -189,16 +190,16 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
||||
// 团队项目:(队伍数 ÷ 场地数) × 项目时长
|
||||
int teamCount = totalTeams > 0 ? totalTeams : 1;
|
||||
int rounds = (int)Math.Ceiling((double)teamCount / venueCount);
|
||||
totalDurationSeconds = rounds * proj.DurationSeconds;
|
||||
totalDurationSeconds = rounds * proj.GetTotalDurationInSeconds();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 个人项目:(报名人数 ÷ 场地数) × 项目时长
|
||||
int participantCount = totalParticipants > 0 ? totalParticipants : 1;
|
||||
int rounds = (int)Math.Ceiling((double)participantCount / venueCount);
|
||||
totalDurationSeconds = rounds * proj.DurationSeconds;
|
||||
totalDurationSeconds = rounds * proj.GetTotalDurationInSeconds();
|
||||
}
|
||||
|
||||
|
||||
// 设置总时长秒数和分钟数
|
||||
dto.TotalDurationSeconds = totalDurationSeconds;
|
||||
dto.TotalDurationMinutes = (int)Math.Ceiling((double)totalDurationSeconds / 60);
|
||||
@ -223,13 +224,14 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
||||
var ep = eventProjects.FirstOrDefault(x => x.Id == setting.ProjectId);
|
||||
if (ep != null)
|
||||
{
|
||||
await _projectRepository.UpdateAsync(x => new YD_Event.Core.Entities.Project
|
||||
{
|
||||
VenueCount = setting.VenueCount,
|
||||
SortIndex = setting.SortIndex,
|
||||
DurationSeconds = setting.DurationSeconds,
|
||||
DurationMinutes = setting.DurationSeconds / 60
|
||||
}, x => x.Id == ep.ProjectId);
|
||||
var project = await _projectRepository.GetByIdAsync(ep.ProjectId);
|
||||
if (project != null)
|
||||
{
|
||||
project.VenueCount = setting.VenueCount;
|
||||
project.SortIndex = setting.SortIndex;
|
||||
project.SetTotalDurationInSeconds(setting.DurationSeconds);
|
||||
await _projectRepository.UpdateAsync(project);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -244,7 +246,7 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
||||
var eventProjects = await _eventProjectRepository.GetListAsync(x => x.EventId == eventId);
|
||||
var projectIds = eventProjects.Select(x => x.ProjectId).Distinct().ToList();
|
||||
var projects = await _projectRepository.GetListAsync(x => projectIds.Contains(x.Id));
|
||||
|
||||
|
||||
// 按照 SortIndex 对 projects 排序
|
||||
var sortedProjects = projects.OrderBy(x => x.SortIndex).ToList();
|
||||
var groups = await _groupRepository.GetListAsync(x => projectIds.Contains(x.ProjectId));
|
||||
@ -252,9 +254,9 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
||||
// 统计各组别报名人数
|
||||
var counts = await _personRepository.AsQueryable()
|
||||
.InnerJoin<EventRegistration>((p, r) => p.RegistrationId == r.Id)
|
||||
.Where((p, r) => r.EventId == eventId
|
||||
&& r.PaymentStatus != 4
|
||||
&& !p.DeleteMark
|
||||
.Where((p, r) => r.EventId == eventId
|
||||
&& r.PaymentStatus != 4
|
||||
&& !p.DeleteMark
|
||||
&& p.PersonType == PersonType.Athlete)
|
||||
.GroupBy((p, r) => new { p.ProjectId, p.GroupName })
|
||||
.Select((p, r) => new { p.ProjectId, p.GroupName, Count = SqlFunc.AggregateCount(p.Id) })
|
||||
@ -263,9 +265,9 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
||||
// 获取团队数
|
||||
var personWithTeam = await _personRepository.AsQueryable()
|
||||
.InnerJoin<EventRegistration>((p, r) => p.RegistrationId == r.Id)
|
||||
.Where((p, r) => r.EventId == eventId
|
||||
&& r.PaymentStatus != 4
|
||||
&& !p.DeleteMark
|
||||
.Where((p, r) => r.EventId == eventId
|
||||
&& r.PaymentStatus != 4
|
||||
&& !p.DeleteMark
|
||||
&& p.PersonType == PersonType.Athlete
|
||||
&& r.TeamName != null)
|
||||
.Select((p, r) => new { p.ProjectId, p.GroupName, r.TeamName })
|
||||
@ -278,27 +280,29 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
||||
.ToList();
|
||||
|
||||
var result = new List<ArrangementPreviewOutput>();
|
||||
|
||||
// 2. 生成排期 - 按照排序后的项目顺序
|
||||
|
||||
// 2. 生成排期 - 按照排序后的项目顺序处理
|
||||
foreach (var proj in sortedProjects)
|
||||
{
|
||||
var eventProj = eventProjects.FirstOrDefault(x => x.ProjectId == proj.Id);
|
||||
if (eventProj == null) continue;
|
||||
|
||||
int venueCount = proj.VenueCount > 0 ? proj.VenueCount : 1;
|
||||
|
||||
|
||||
// 获取参赛人员
|
||||
var persons = await _personRepository.AsQueryable()
|
||||
.InnerJoin<EventRegistration>((p, r) => p.RegistrationId == r.Id)
|
||||
.Where((p, r) => p.ProjectId == eventProj.Id
|
||||
&& r.PaymentStatus != 4
|
||||
&& !p.DeleteMark
|
||||
.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) => new {
|
||||
p.Name, p.GroupName, r.TeamName,
|
||||
Duration = proj.DurationSeconds
|
||||
.Select((p, r) => new {
|
||||
p.Name,
|
||||
p.GroupName,
|
||||
r.TeamName,
|
||||
Duration = proj.GetTotalDurationInSeconds()
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
@ -326,13 +330,13 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
||||
{
|
||||
int teamCount = totalTeams > 0 ? totalTeams : 1;
|
||||
int rounds = (int)Math.Ceiling((double)teamCount / venueCount);
|
||||
projectTotalDurationSeconds = rounds * proj.DurationSeconds;
|
||||
projectTotalDurationSeconds = rounds * proj.GetTotalDurationInSeconds();
|
||||
}
|
||||
else
|
||||
{
|
||||
int participantCount = totalParticipants > 0 ? totalParticipants : 1;
|
||||
int rounds = (int)Math.Ceiling((double)participantCount / venueCount);
|
||||
projectTotalDurationSeconds = rounds * proj.DurationSeconds;
|
||||
projectTotalDurationSeconds = rounds * proj.GetTotalDurationInSeconds();
|
||||
}
|
||||
|
||||
string projectTotalDuration = FormatDurationSymbol(projectTotalDurationSeconds);
|
||||
@ -340,12 +344,12 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
||||
// 分组逻辑
|
||||
int currentRound = 1;
|
||||
int currentVenue = 1;
|
||||
|
||||
|
||||
foreach (var person in persons)
|
||||
{
|
||||
result.Add(new ArrangementPreviewOutput
|
||||
{
|
||||
TimeRange = $"{proj.DurationSeconds}''",
|
||||
TimeRange = $"{proj.GetTotalDurationInSeconds()}''",
|
||||
ProjectName = proj.Name,
|
||||
ProjectType = proj.ProjectType.Description(),
|
||||
GroupName = person.GroupName,
|
||||
|
||||
@ -273,14 +273,12 @@ public class UserEventRecordService : IDynamicApiController, ITransient
|
||||
var registration = await _registrationRepository.GetFirstAsync(x => x.Id == registrationId && x.CreatedUserId == userId);
|
||||
if (registration == null) throw Oops.Bah("报名记录不存在");
|
||||
|
||||
// 仅 status = 待付款 允许上传
|
||||
if (registration.PaymentStatus != 0) throw Oops.Bah("当前状态不允许上传凭证");
|
||||
|
||||
|
||||
var uploadResult = await _fileService.Upload(input.File);
|
||||
var fileInfo = uploadResult.First();
|
||||
|
||||
registration.PaymentProofUrl = fileInfo.Url;
|
||||
registration.PaymentStatus = 0;
|
||||
registration.UpdatedTime = DateTime.Now;
|
||||
await _registrationRepository.UpdateAsync(registration);
|
||||
|
||||
|
||||
@ -116,6 +116,16 @@ public class OrderListOutput
|
||||
/// 退款时间
|
||||
/// </summary>
|
||||
public DateTime? RefundTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联原始订单的实付金额(仅退款订单时有效)
|
||||
/// </summary>
|
||||
public decimal? RelatedOrderActualAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否为退款订单
|
||||
/// </summary>
|
||||
public bool IsRefundOrder { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -237,6 +247,16 @@ public class OrderDetailOutput
|
||||
/// 联系人电话
|
||||
/// </summary>
|
||||
public string ContactPhone { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联原始订单的实付金额(仅退款订单时有效)
|
||||
/// </summary>
|
||||
public decimal? RelatedOrderActualAmount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否为退款订单
|
||||
/// </summary>
|
||||
public bool IsRefundOrder { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -231,7 +231,9 @@ public class OrderService : BaseService<YD_Event.Core.Entities.Order>, ITransien
|
||||
CreatedTime = o.CreatedTime,
|
||||
PaymentTime = o.PaymentTime,
|
||||
RefundAmount = o.OrderType == 2 ? o.ActualAmount : 0, // 如果是退款订单,ActualAmount即为退款金额
|
||||
RefundTime = o.OrderType == 2 ? o.PaymentTime : null // 退款时间
|
||||
RefundTime = o.OrderType == 2 ? o.PaymentTime : null, // 退款时间
|
||||
RelatedOrderActualAmount = o.OrderType == 2 ? ro.ActualAmount : null, // 退款订单显示原始订单实付金额
|
||||
IsRefundOrder = o.OrderType == 2
|
||||
})
|
||||
.ToPagedListAsync(input);
|
||||
|
||||
@ -250,7 +252,7 @@ public class OrderService : BaseService<YD_Event.Core.Entities.Order>, ITransien
|
||||
.LeftJoin<EventRegistration>((o, e, r) => o.RegistrationId == r.Id)
|
||||
.LeftJoin<YD_Event.Core.Entities.Order>((o, e, r, ro) => o.RelatedOrderId == ro.Id)
|
||||
.Where(o => o.Id == id)
|
||||
.Select((o, e, r, ro) => new { Order = o, EventName = e.EventName, Registration = r, RelatedOrderNo = ro.OrderNo });
|
||||
.Select((o, e, r, ro) => new { Order = o, EventName = e.EventName, Registration = r, RelatedOrderNo = ro.OrderNo, RelatedOrderActualAmount = ro.ActualAmount });
|
||||
|
||||
var orderInfo = await query.FirstAsync();
|
||||
|
||||
@ -307,7 +309,9 @@ public class OrderService : BaseService<YD_Event.Core.Entities.Order>, ITransien
|
||||
CreatedTime = orderInfo.Order.CreatedTime,
|
||||
RelatedOrderNo = orderInfo.RelatedOrderNo,
|
||||
ContactName = orderInfo.Registration?.ContactName,
|
||||
ContactPhone = orderInfo.Registration?.ContactPhone
|
||||
ContactPhone = orderInfo.Registration?.ContactPhone,
|
||||
RelatedOrderActualAmount = orderInfo.Order.OrderType == 2 ? orderInfo.RelatedOrderActualAmount : null,
|
||||
IsRefundOrder = orderInfo.Order.OrderType == 2
|
||||
};
|
||||
}
|
||||
|
||||
@ -528,7 +532,9 @@ public class OrderService : BaseService<YD_Event.Core.Entities.Order>, ITransien
|
||||
o.OrderStatus == OrderStatus.Refunded ? "已退款" :
|
||||
o.OrderStatus == OrderStatus.Shipped ? "已发货" :
|
||||
o.OrderStatus == OrderStatus.Completed ? "已完成" : "",
|
||||
CreatedTime = o.CreatedTime
|
||||
CreatedTime = o.CreatedTime,
|
||||
RelatedOrderActualAmount = o.OrderType == 2 ? ro.ActualAmount : null,
|
||||
IsRefundOrder = o.OrderType == 2
|
||||
})
|
||||
.ToListAsync();
|
||||
|
||||
@ -559,7 +565,7 @@ public class OrderService : BaseService<YD_Event.Core.Entities.Order>, ITransien
|
||||
var totalActual = orders.Where(x => x.OrderType == "收入").Sum(x => x.ActualAmount);
|
||||
|
||||
// 汇总信息行
|
||||
var summaryRange = worksheet.Cells[rowIndex, 1, rowIndex, 14];
|
||||
var summaryRange = worksheet.Cells[rowIndex, 1, rowIndex, 15];
|
||||
summaryRange.Merge = true;
|
||||
summaryRange.Value = $"汇总信息: 原金额:{totalOriginal}, 优惠金额:{totalDiscount}, 退款金额:{totalRefund}, 实付金额:{totalActual}";
|
||||
var summaryStyle = summaryRange.Style;
|
||||
@ -576,7 +582,7 @@ public class OrderService : BaseService<YD_Event.Core.Entities.Order>, ITransien
|
||||
{
|
||||
"订单编号", "单位名称", "所属赛事", "订单类型", "关联订单",
|
||||
"支付方式", "报名方式", "报名用户", "报名账号", "原金额(元)",
|
||||
"优惠金额(元)", "退款金额(元)", "实付金额(元)", "生成时间"
|
||||
"优惠金额(元)", "退款金额(元)", "原始订单实付金额(元)", "实付金额(元)", "生成时间"
|
||||
};
|
||||
|
||||
for (int i = 0; i < headers.Length; i++)
|
||||
@ -600,6 +606,7 @@ public class OrderService : BaseService<YD_Event.Core.Entities.Order>, ITransien
|
||||
{
|
||||
var refundAmount = item.OrderType == "退款" ? item.ActualAmount : 0;
|
||||
var actualPayAmount = item.OrderType == "收入" ? item.ActualAmount : 0;
|
||||
var relatedAmount = item.IsRefundOrder ? item.RelatedOrderActualAmount : null;
|
||||
|
||||
worksheet.Cells[rowIndex, 1].Value = item.OrderNo;
|
||||
worksheet.Cells[rowIndex, 2].Value = item.UnitName;
|
||||
@ -613,21 +620,23 @@ public class OrderService : BaseService<YD_Event.Core.Entities.Order>, ITransien
|
||||
worksheet.Cells[rowIndex, 10].Value = item.OriginalAmount;
|
||||
worksheet.Cells[rowIndex, 11].Value = item.DiscountAmount;
|
||||
worksheet.Cells[rowIndex, 12].Value = refundAmount;
|
||||
worksheet.Cells[rowIndex, 13].Value = actualPayAmount;
|
||||
worksheet.Cells[rowIndex, 14].Value = item.CreatedTime.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
worksheet.Cells[rowIndex, 13].Value = relatedAmount;
|
||||
worksheet.Cells[rowIndex, 14].Value = actualPayAmount;
|
||||
worksheet.Cells[rowIndex, 15].Value = item.CreatedTime.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
// 设置金额格式
|
||||
worksheet.Cells[rowIndex, 10].Style.Numberformat.Format = "0.00";
|
||||
worksheet.Cells[rowIndex, 11].Style.Numberformat.Format = "0.00";
|
||||
worksheet.Cells[rowIndex, 12].Style.Numberformat.Format = "0.00";
|
||||
worksheet.Cells[rowIndex, 13].Style.Numberformat.Format = "0.00";
|
||||
worksheet.Cells[rowIndex, 14].Style.Numberformat.Format = "0.00";
|
||||
|
||||
SetDataRowStyle(worksheet, rowIndex, 14);
|
||||
SetDataRowStyle(worksheet, rowIndex, 15);
|
||||
rowIndex++;
|
||||
}
|
||||
|
||||
// 设置列宽
|
||||
var columnWidths = new double[] { 18, 15, 15, 10, 12, 10, 10, 12, 14, 12, 14, 14, 12, 18 };
|
||||
var columnWidths = new double[] { 18, 15, 15, 10, 12, 10, 10, 12, 14, 12, 14, 14, 18, 12, 18 };
|
||||
for (int i = 0; i < columnWidths.Length; i++)
|
||||
{
|
||||
worksheet.Column(i + 1).Width = columnWidths[i];
|
||||
|
||||
@ -7276,11 +7276,6 @@
|
||||
支付时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.UploadVoucherInput.PayChannel">
|
||||
<summary>
|
||||
支付渠道 (微信/支付宝/银行转账)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.UploadVoucherInput.TransactionId">
|
||||
<summary>
|
||||
交易流水号 (可选)
|
||||
@ -7766,6 +7761,11 @@
|
||||
赛事编排服务
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Event.EventArrangementService.FormatDurationSymbol(System.Int32)">
|
||||
<summary>
|
||||
格式化时长显示(符号格式:X'X")
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Event.EventArrangementService.GetList(System.Int64)">
|
||||
<summary>
|
||||
获取编排项目列表
|
||||
@ -9966,6 +9966,16 @@
|
||||
退款时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Order.Dtos.OrderListOutput.RelatedOrderActualAmount">
|
||||
<summary>
|
||||
关联原始订单的实付金额(仅退款订单时有效)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Order.Dtos.OrderListOutput.IsRefundOrder">
|
||||
<summary>
|
||||
是否为退款订单
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Order.Dtos.OrderDetailOutput">
|
||||
<summary>
|
||||
订单详情输出
|
||||
@ -10086,6 +10096,16 @@
|
||||
联系人电话
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Order.Dtos.OrderDetailOutput.RelatedOrderActualAmount">
|
||||
<summary>
|
||||
关联原始订单的实付金额(仅退款订单时有效)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Order.Dtos.OrderDetailOutput.IsRefundOrder">
|
||||
<summary>
|
||||
是否为退款订单
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Order.Dtos.OrderItemDto">
|
||||
<summary>
|
||||
订单项目DTO
|
||||
|
||||
144
YD_Event.Core/Extensions/ProjectTimeExtensions.cs
Normal file
144
YD_Event.Core/Extensions/ProjectTimeExtensions.cs
Normal file
@ -0,0 +1,144 @@
|
||||
using YD_Event.Core.Entities;
|
||||
|
||||
namespace YD_Event.Core.Extensions;
|
||||
|
||||
/// <summary>
|
||||
/// 项目时间处理扩展类
|
||||
/// 用于统一处理 Project 实体的时间计算逻辑
|
||||
/// </summary>
|
||||
public static class ProjectTimeExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取项目的总时长(秒)
|
||||
/// </summary>
|
||||
/// <param name="project">项目实体</param>
|
||||
/// <returns>总时长(秒)</returns>
|
||||
/// <exception cref="ArgumentNullException">当 project 为 null 时抛出</exception>
|
||||
public static int GetTotalDurationInSeconds(this Project project)
|
||||
{
|
||||
if (project == null)
|
||||
throw new ArgumentNullException(nameof(project));
|
||||
|
||||
// 边界情况处理:确保值不小于 0
|
||||
int minutes = Math.Max(0, project.DurationMinutes);
|
||||
int seconds = Math.Max(0, project.DurationSeconds);
|
||||
|
||||
// 确保秒数不超过 59(一分钟内的秒数)
|
||||
seconds = Math.Min(seconds, 59);
|
||||
|
||||
return minutes * 60 + seconds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置项目的总时长(秒)
|
||||
/// 自动计算并更新 DurationMinutes 和 DurationSeconds
|
||||
/// </summary>
|
||||
/// <param name="project">项目实体</param>
|
||||
/// <param name="totalSeconds">总时长(秒)</param>
|
||||
/// <exception cref="ArgumentNullException">当 project 为 null 时抛出</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">当 totalSeconds 小于 0 时抛出</exception>
|
||||
public static void SetTotalDurationInSeconds(this Project project, int totalSeconds)
|
||||
{
|
||||
if (project == null)
|
||||
throw new ArgumentNullException(nameof(project));
|
||||
|
||||
if (totalSeconds < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(totalSeconds), "总时长不能小于 0");
|
||||
|
||||
// 计算分钟和秒
|
||||
project.DurationMinutes = totalSeconds / 60;
|
||||
project.DurationSeconds = totalSeconds % 60;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 标准化项目的时间字段
|
||||
/// 确保 DurationSeconds 在 0-59 范围内,并正确处理负值
|
||||
/// </summary>
|
||||
/// <param name="project">项目实体</param>
|
||||
/// <exception cref="ArgumentNullException">当 project 为 null 时抛出</exception>
|
||||
public static void NormalizeDuration(this Project project)
|
||||
{
|
||||
if (project == null)
|
||||
throw new ArgumentNullException(nameof(project));
|
||||
|
||||
// 先获取总秒数
|
||||
int totalSeconds = project.GetTotalDurationInSeconds();
|
||||
|
||||
// 重新设置,确保标准化
|
||||
project.SetTotalDurationInSeconds(totalSeconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取格式化的时长显示字符串(例如:"2分30秒" 或 "30秒")
|
||||
/// </summary>
|
||||
/// <param name="project">项目实体</param>
|
||||
/// <returns>格式化的时长字符串</returns>
|
||||
/// <exception cref="ArgumentNullException">当 project 为 null 时抛出</exception>
|
||||
public static string GetFormattedDuration(this Project project)
|
||||
{
|
||||
if (project == null)
|
||||
throw new ArgumentNullException(nameof(project));
|
||||
|
||||
int totalSeconds = project.GetTotalDurationInSeconds();
|
||||
int minutes = totalSeconds / 60;
|
||||
int seconds = totalSeconds % 60;
|
||||
|
||||
if (minutes == 0)
|
||||
{
|
||||
return $"{seconds}秒";
|
||||
}
|
||||
else if (seconds == 0)
|
||||
{
|
||||
return $"{minutes}分";
|
||||
}
|
||||
else
|
||||
{
|
||||
return $"{minutes}分{seconds}秒";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取符号格式的时长显示(例如:"2'30\"" 或 "30\"")
|
||||
/// </summary>
|
||||
/// <param name="project">项目实体</param>
|
||||
/// <returns>符号格式的时长字符串</returns>
|
||||
/// <exception cref="ArgumentNullException">当 project 为 null 时抛出</exception>
|
||||
public static string GetSymbolFormattedDuration(this Project project)
|
||||
{
|
||||
if (project == null)
|
||||
throw new ArgumentNullException(nameof(project));
|
||||
|
||||
int totalSeconds = project.GetTotalDurationInSeconds();
|
||||
int hours = totalSeconds / 3600;
|
||||
int remainingSeconds = totalSeconds % 3600;
|
||||
int minutes = remainingSeconds / 60;
|
||||
int seconds = remainingSeconds % 60;
|
||||
|
||||
if (hours == 0)
|
||||
{
|
||||
if (seconds == 0)
|
||||
{
|
||||
return $"{minutes}'";
|
||||
}
|
||||
else
|
||||
{
|
||||
string paddedSeconds = seconds.ToString().PadLeft(2, '0');
|
||||
return $"{minutes}'{paddedSeconds}\"";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string result = $"{hours}h";
|
||||
if (minutes > 0 || seconds > 0)
|
||||
{
|
||||
result += $"{minutes}'";
|
||||
if (seconds > 0)
|
||||
{
|
||||
string paddedSeconds = seconds.ToString().PadLeft(2, '0');
|
||||
result += $"{paddedSeconds}\"";
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4755,6 +4755,54 @@
|
||||
赞助单位
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Core.Extensions.ProjectTimeExtensions">
|
||||
<summary>
|
||||
项目时间处理扩展类
|
||||
用于统一处理 Project 实体的时间计算逻辑
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Core.Extensions.ProjectTimeExtensions.GetTotalDurationInSeconds(YD_Event.Core.Entities.Project)">
|
||||
<summary>
|
||||
获取项目的总时长(秒)
|
||||
</summary>
|
||||
<param name="project">项目实体</param>
|
||||
<returns>总时长(秒)</returns>
|
||||
<exception cref="T:System.ArgumentNullException">当 project 为 null 时抛出</exception>
|
||||
</member>
|
||||
<member name="M:YD_Event.Core.Extensions.ProjectTimeExtensions.SetTotalDurationInSeconds(YD_Event.Core.Entities.Project,System.Int32)">
|
||||
<summary>
|
||||
设置项目的总时长(秒)
|
||||
自动计算并更新 DurationMinutes 和 DurationSeconds
|
||||
</summary>
|
||||
<param name="project">项目实体</param>
|
||||
<param name="totalSeconds">总时长(秒)</param>
|
||||
<exception cref="T:System.ArgumentNullException">当 project 为 null 时抛出</exception>
|
||||
<exception cref="T:System.ArgumentOutOfRangeException">当 totalSeconds 小于 0 时抛出</exception>
|
||||
</member>
|
||||
<member name="M:YD_Event.Core.Extensions.ProjectTimeExtensions.NormalizeDuration(YD_Event.Core.Entities.Project)">
|
||||
<summary>
|
||||
标准化项目的时间字段
|
||||
确保 DurationSeconds 在 0-59 范围内,并正确处理负值
|
||||
</summary>
|
||||
<param name="project">项目实体</param>
|
||||
<exception cref="T:System.ArgumentNullException">当 project 为 null 时抛出</exception>
|
||||
</member>
|
||||
<member name="M:YD_Event.Core.Extensions.ProjectTimeExtensions.GetFormattedDuration(YD_Event.Core.Entities.Project)">
|
||||
<summary>
|
||||
获取格式化的时长显示字符串(例如:"2分30秒" 或 "30秒")
|
||||
</summary>
|
||||
<param name="project">项目实体</param>
|
||||
<returns>格式化的时长字符串</returns>
|
||||
<exception cref="T:System.ArgumentNullException">当 project 为 null 时抛出</exception>
|
||||
</member>
|
||||
<member name="M:YD_Event.Core.Extensions.ProjectTimeExtensions.GetSymbolFormattedDuration(YD_Event.Core.Entities.Project)">
|
||||
<summary>
|
||||
获取符号格式的时长显示(例如:"2'30\"" 或 "30\"")
|
||||
</summary>
|
||||
<param name="project">项目实体</param>
|
||||
<returns>符号格式的时长字符串</returns>
|
||||
<exception cref="T:System.ArgumentNullException">当 project 为 null 时抛出</exception>
|
||||
</member>
|
||||
<member name="T:YD_Event.Core.Extensions.ProjectTypeExtensions">
|
||||
<summary>
|
||||
项目类型判断扩展方法
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user