diff --git a/YD_Event.Application/Event/Dtos/ArrangementDtos.cs b/YD_Event.Application/Event/Dtos/ArrangementDtos.cs
index 16a8e4f..5a3ea17 100644
--- a/YD_Event.Application/Event/Dtos/ArrangementDtos.cs
+++ b/YD_Event.Application/Event/Dtos/ArrangementDtos.cs
@@ -153,4 +153,14 @@ public class ArrangementPreviewOutput
/// 场地索引
///
public int VenueIndex { get; set; }
+
+ ///
+ /// 项目总时长(秒)
+ ///
+ public int ProjectTotalDurationSeconds { get; set; }
+
+ ///
+ /// 项目总时长(格式化字符串)
+ ///
+ public string ProjectTotalDuration { get; set; }
}
diff --git a/YD_Event.Application/Event/Dtos/UserCompetitionDtos.cs b/YD_Event.Application/Event/Dtos/UserCompetitionDtos.cs
index c636862..e0c9c3a 100644
--- a/YD_Event.Application/Event/Dtos/UserCompetitionDtos.cs
+++ b/YD_Event.Application/Event/Dtos/UserCompetitionDtos.cs
@@ -753,7 +753,7 @@ public class RegistrationItemDTO
public string TeamName { get; set; }
///
- /// 综合状态 (0-待付款, 1-已支付, 2-已取消, 3-已退款, 4-已完成)
+ /// 支付状态:0-未支付/待审核,1-已支付/审核通过,2-支付失败/审核拒绝,3-已退款,4-已取消
///
public int Status { get; set; }
diff --git a/YD_Event.Application/Event/EventArrangementService.cs b/YD_Event.Application/Event/EventArrangementService.cs
index c1624e1..1d37435 100644
--- a/YD_Event.Application/Event/EventArrangementService.cs
+++ b/YD_Event.Application/Event/EventArrangementService.cs
@@ -38,6 +38,47 @@ public class EventArrangementService : BaseService 0 || seconds > 0)
+ {
+ result += $"{minutes}'";
+ if (seconds > 0)
+ {
+ var paddedSeconds = seconds.ToString().PadLeft(2, '0');
+ result += $"{paddedSeconds}\"";
+ }
+ }
+ return result;
+ }
+ }
+
///
/// 获取编排项目列表
///
@@ -196,12 +237,41 @@ public class EventArrangementService : BaseService> Preview(long eventId)
{
- // 1. 获取项目(按顺序)
+ // 1. 获取项目列表和统计数据
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));
projects = projects.OrderBy(x => x.SortIndex).ToList();
-
+ var groups = await _groupRepository.GetListAsync(x => projectIds.Contains(x.ProjectId));
+
+ // 统计各组别报名人数
+ var counts = await _personRepository.AsQueryable()
+ .InnerJoin((p, r) => p.RegistrationId == r.Id)
+ .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) })
+ .ToListAsync();
+
+ // 获取团队数
+ var personWithTeam = await _personRepository.AsQueryable()
+ .InnerJoin((p, r) => p.RegistrationId == r.Id)
+ .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 })
+ .ToListAsync();
+
+ var teamCounts = personWithTeam
+ .GroupBy(x => new { x.ProjectId, x.GroupName, x.TeamName })
+ .GroupBy(g => new { g.Key.ProjectId, g.Key.GroupName })
+ .Select(g => new { g.Key.ProjectId, g.Key.GroupName, Count = g.Count() })
+ .ToList();
+
var result = new List();
// 2. 生成排期
@@ -212,8 +282,7 @@ public class EventArrangementService : BaseService 0 ? proj.VenueCount : 1;
- // 获取参赛人员(排序:组别 -> ID)
- // 查询条件:不是取消状态的报名,并且只统计运动员
+ // 获取参赛人员
var persons = await _personRepository.AsQueryable()
.InnerJoin((p, r) => p.RegistrationId == r.Id)
.Where((p, r) => p.ProjectId == eventProj.Id
@@ -230,6 +299,39 @@ public class EventArrangementService : BaseService g.ProjectId == proj.Id).ToList();
+ foreach (var group in projGroups)
+ {
+ var countObj = counts.FirstOrDefault(c => c.ProjectId == eventProj.Id && c.GroupName == group.GroupName);
+ totalParticipants += countObj?.Count ?? 0;
+ }
+
+ int totalTeams = 0;
+ if (proj.IsTeamProject())
+ {
+ totalTeams = teamCounts
+ .Where(tc => tc.ProjectId == eventProj.Id)
+ .Sum(tc => tc.Count);
+ }
+
+ int projectTotalDurationSeconds;
+ if (proj.IsTeamProject())
+ {
+ int teamCount = totalTeams > 0 ? totalTeams : 1;
+ int rounds = (int)Math.Ceiling((double)teamCount / venueCount);
+ projectTotalDurationSeconds = rounds * proj.DurationSeconds;
+ }
+ else
+ {
+ int participantCount = totalParticipants > 0 ? totalParticipants : 1;
+ int rounds = (int)Math.Ceiling((double)participantCount / venueCount);
+ projectTotalDurationSeconds = rounds * proj.DurationSeconds;
+ }
+
+ string projectTotalDuration = FormatDurationSymbol(projectTotalDurationSeconds);
+
// 分组逻辑
int currentRound = 1;
int currentVenue = 1;
@@ -245,7 +347,9 @@ public class EventArrangementService : BaseService 0 && i - 1 >= 0)
+ {
+ int mergeEndRow = (i - 1) + 3;
+ if (mergeEndRow > projectStartRow)
+ {
+ var range = Worksheet.Cells[projectStartRow, 1, mergeEndRow, 1];
+ range.Merge = true;
+ // 设置时间列居中对齐
+ for (int r = projectStartRow; r <= mergeEndRow; r++)
+ {
+ Worksheet.Cells[r, 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
+ Worksheet.Cells[r, 1].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
+ }
+ }
+ }
+
+ currentProjectName = item.ProjectName;
+ projectStartRow = rowIndex;
+
+ // 设置项目总时长
+ Worksheet.Cells[rowIndex, 1].Value = item.ProjectTotalDuration;
+ }
+ else
+ {
+ // 同一项目的其他行不设置时间值(合并后会自动应用)
+ }
+
Worksheet.Cells[rowIndex, 2].Value = item.ProjectName;
Worksheet.Cells[rowIndex, 3].Value = item.GroupName;
Worksheet.Cells[rowIndex, 4].Value = item.TeamName ?? "";
@@ -318,6 +457,23 @@ public class EventArrangementService : BaseService 0 && _data.Count > 0)
+ {
+ int mergeEndRow = (_data.Count - 1) + 3;
+ if (mergeEndRow > projectStartRow)
+ {
+ var range = Worksheet.Cells[projectStartRow, 1, mergeEndRow, 1];
+ range.Merge = true;
+ // 设置时间列居中对齐
+ for (int r = projectStartRow; r <= mergeEndRow; r++)
+ {
+ Worksheet.Cells[r, 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
+ Worksheet.Cells[r, 1].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
+ }
+ }
+ }
+
// 设置列宽
var widths = new double[] { 12, 18, 15, 25, 15, 8, 8 };
SetColumnWidths(widths);
diff --git a/YD_Event.Application/Event/EventRegistrationService.cs b/YD_Event.Application/Event/EventRegistrationService.cs
index 84bdb08..784023e 100644
--- a/YD_Event.Application/Event/EventRegistrationService.cs
+++ b/YD_Event.Application/Event/EventRegistrationService.cs
@@ -265,11 +265,11 @@ public class EventRegistrationService : BaseService, ITransie
};
dto.TeamLeaderInfo = allLeaders.Any()
- ? string.Join(",", allLeaders.Select(l => $"{l.Name}({l.Mobile})/{getGenderText(l.Gender)}"))
+ ? string.Join(",", allLeaders.Select(l => $"{l.Name}/{getGenderText(l.Gender)}/{l.Mobile}"))
: null;
dto.CoachInfo = allCoaches.Any()
- ? string.Join(",", allCoaches.Select(c => $"{c.Name}({c.Mobile})/{getGenderText(c.Gender)}"))
+ ? string.Join(",", allCoaches.Select(c => $"{c.Name}/{getGenderText(c.Gender)}/{c.Mobile}"))
: null;
}
}
diff --git a/YD_Event.Application/Event/UnifiedRegistrationService.cs b/YD_Event.Application/Event/UnifiedRegistrationService.cs
index 440fe13..6a56f0b 100644
--- a/YD_Event.Application/Event/UnifiedRegistrationService.cs
+++ b/YD_Event.Application/Event/UnifiedRegistrationService.cs
@@ -1134,8 +1134,9 @@ public class UnifiedRegistrationService : ITransient
var eventProjectGroups = await _eventProjectGroupRepository.GetListAsync(x => x.EventId == input.EventId && !x.DeleteMark);
// 先获取所有报名信息,供后续检查使用
+ // 只统计已支付的报名记录(PaymentStatus == 1),避免未支付/已取消的报名占用名额
var eventRegistrations = await _registrationRepository.GetListAsync(x =>
- x.EventId == input.EventId && x.PaymentStatus != 4 && !x.DeleteMark);
+ x.EventId == input.EventId && x.PaymentStatus == 1 && !x.DeleteMark);
var eventRegistrationIds = eventRegistrations.Select(r => r.Id).ToList();
var registrationPersons = await _registrationPersonRepository.GetListAsync(x =>
eventRegistrationIds.Contains(x.RegistrationId) && !x.DeleteMark);
diff --git a/YD_Event.Application/Event/UserEventRecordService.cs b/YD_Event.Application/Event/UserEventRecordService.cs
index 22d06d5..4e62ec9 100644
--- a/YD_Event.Application/Event/UserEventRecordService.cs
+++ b/YD_Event.Application/Event/UserEventRecordService.cs
@@ -112,21 +112,6 @@ public class UserEventRecordService : IDynamicApiController, ITransient
.ToPagedListAsync(input);
var resultItems = list.Rows.Select(x => {
- // 计算综合状态
- int statusValue = 0;
- if (x.PaymentStatus == 4)
- statusValue = 2; // 已取消
- else if (x.PaymentStatus == 0)
- statusValue = 0; // 待付款
- else if (x.PaymentStatus == 1 && string.IsNullOrEmpty(x.MaterialUrl))
- statusValue = 1; // 已支付
- else if (x.PaymentStatus == 1 && !string.IsNullOrEmpty(x.MaterialUrl))
- statusValue = 4; // 已完成/已报名
- else if (x.PaymentStatus == 2)
- statusValue = 1; // 审核拒绝
- else if (x.PaymentStatus == 3)
- statusValue = 3; // 已退款
-
return new RegistrationItemDTO
{
RegistrationId = x.Id,
@@ -141,7 +126,7 @@ public class UserEventRecordService : IDynamicApiController, ITransient
MatchStartTime = x.MatchStartTime,
MatchEndTime = x.MatchEndTime,
TeamName = x.TeamName,
- Status = statusValue,
+ Status = x.PaymentStatus,
CreateTime = x.CreatedTime,
UpdateTime = x.UpdatedTime,
PayStatus = x.PaymentStatus,
diff --git a/YD_Event.Application/YD_Event.Application.xml b/YD_Event.Application/YD_Event.Application.xml
index 997abea..8ed6b23 100644
--- a/YD_Event.Application/YD_Event.Application.xml
+++ b/YD_Event.Application/YD_Event.Application.xml
@@ -4167,6 +4167,16 @@
场地索引
+
+
+ 项目总时长(秒)
+
+
+
+
+ 项目总时长(格式化字符串)
+
+
赛事查询输入
@@ -6969,7 +6979,7 @@
- 综合状态 (0-待付款, 1-已支付, 2-已取消, 3-已退款, 4-已完成)
+ 支付状态:0-未支付/待审核,1-已支付/审核通过,2-支付失败/审核拒绝,3-已退款,4-已取消