赛事编排:导出编排,报名ID不重复
This commit is contained in:
parent
6c152e5cd6
commit
d9de064fc4
@ -49,6 +49,11 @@ public class ArrangementProjectListOutput
|
||||
/// 总时长(分钟,向上取整)
|
||||
/// </summary>
|
||||
public int TotalDurationMinutes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 团队总数(仅团队项目有效)
|
||||
/// </summary>
|
||||
public int TotalTeams { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -202,7 +202,7 @@ public class RegistrationListOutput
|
||||
public class RegistrationItemDetailDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 报名项目ID(EventRegistrationItem的ID)
|
||||
/// 报名项目ID(EventRegistrationItem的ID 或 EventRegistrationPerson的ID,根据项目类型决定)
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
|
||||
|
||||
@ -230,6 +230,7 @@ namespace YD_Event.Application.Event;
|
||||
// 设置总时长秒数和分钟数
|
||||
dto.TotalDurationSeconds = totalDurationSeconds;
|
||||
dto.TotalDurationMinutes = (int)Math.Ceiling((double)totalDurationSeconds / 60);
|
||||
dto.TotalTeams = totalTeams;
|
||||
|
||||
result.Add(dto);
|
||||
}
|
||||
@ -330,6 +331,7 @@ namespace YD_Event.Application.Event;
|
||||
.OrderBy(p => p.GroupName)
|
||||
.OrderBy(p => p.Id)
|
||||
.Select((p, r, u, m) => new {
|
||||
Id = p.Id, // 添加 Id 属性
|
||||
RegistrationItemId = p.RegistrationItemId,
|
||||
p.UserId,
|
||||
p.Name,
|
||||
@ -401,7 +403,7 @@ namespace YD_Event.Application.Event;
|
||||
|
||||
result.Add(new ArrangementPreviewOutput
|
||||
{
|
||||
RegistrationItemId = firstPerson.RegistrationItemId,
|
||||
RegistrationItemId = firstPerson.RegistrationItemId, // 团队项目保持使用 EventRegistrationItem.Id
|
||||
TimeRange = $"{proj.GetTotalDurationInSeconds()}''",
|
||||
ProjectName = proj.Name,
|
||||
ProjectType = proj.ProjectType.Description(),
|
||||
@ -432,7 +434,7 @@ namespace YD_Event.Application.Event;
|
||||
|
||||
result.Add(new ArrangementPreviewOutput
|
||||
{
|
||||
RegistrationItemId = person.RegistrationItemId,
|
||||
RegistrationItemId = person.Id, // 个人项目使用 EventRegistrationPerson.Id
|
||||
TimeRange = $"{proj.GetTotalDurationInSeconds()}''",
|
||||
ProjectName = proj.Name,
|
||||
ProjectType = proj.ProjectType.Description(),
|
||||
|
||||
@ -21,6 +21,8 @@ public class EventRegistrationService : BaseService<EventRegistration>, ITransie
|
||||
private readonly ISqlSugarRepository<YD_Event.Core.Entities.AppUser> _appUserRepository;
|
||||
private readonly ISqlSugarRepository<MerchantCertification> _merchantCertificationRepository;
|
||||
private readonly ISqlSugarRepository<EventInfo> _eventInfoRepository;
|
||||
private readonly ISqlSugarRepository<EventProject> _eventProjectRepository;
|
||||
private readonly ISqlSugarRepository<YD_Event.Core.Entities.Project> _projectRepository;
|
||||
private readonly IIdGenerator _idGenerator;
|
||||
private readonly OrderNoGeneratorService _orderNoGeneratorService;
|
||||
private readonly AuthManager _authManager;
|
||||
@ -35,6 +37,8 @@ public class EventRegistrationService : BaseService<EventRegistration>, ITransie
|
||||
ISqlSugarRepository<YD_Event.Core.Entities.AppUser> appUserRepository,
|
||||
ISqlSugarRepository<MerchantCertification> merchantCertificationRepository,
|
||||
ISqlSugarRepository<EventInfo> eventInfoRepository,
|
||||
ISqlSugarRepository<EventProject> eventProjectRepository,
|
||||
ISqlSugarRepository<YD_Event.Core.Entities.Project> projectRepository,
|
||||
IIdGenerator idGenerator,
|
||||
OrderNoGeneratorService orderNoGeneratorService,
|
||||
AuthManager authManager) : base(repository)
|
||||
@ -48,6 +52,8 @@ public class EventRegistrationService : BaseService<EventRegistration>, ITransie
|
||||
_appUserRepository = appUserRepository;
|
||||
_merchantCertificationRepository = merchantCertificationRepository;
|
||||
_eventInfoRepository = eventInfoRepository;
|
||||
_eventProjectRepository = eventProjectRepository;
|
||||
_projectRepository = projectRepository;
|
||||
_idGenerator = idGenerator;
|
||||
_orderNoGeneratorService = orderNoGeneratorService;
|
||||
_authManager = authManager;
|
||||
@ -102,6 +108,16 @@ public class EventRegistrationService : BaseService<EventRegistration>, ITransie
|
||||
.Includes(p => p.User) // 关联查询用户信息
|
||||
.Where(x => regIds.Contains(x.RegistrationId))
|
||||
.ToListAsync();
|
||||
|
||||
// 获取所有赛事项目和项目信息,用于判断项目类型
|
||||
var eventProjectIds = items.Select(x => x.ProjectId).Distinct().ToList();
|
||||
var eventProjects = await _eventProjectRepository.GetListAsync(x => eventProjectIds.Contains(x.Id));
|
||||
var projectIds = eventProjects.Select(x => x.ProjectId).Distinct().ToList();
|
||||
var projects = await _projectRepository.GetListAsync(x => projectIds.Contains(x.Id));
|
||||
|
||||
// 创建映射字典
|
||||
var eventProjectToProjectDict = eventProjects.ToDictionary(x => x.Id, x => x.ProjectId);
|
||||
Dictionary<long, YD_Event.Core.Entities.Project> projectDict = projects.ToDictionary(x => x.Id, x => x);
|
||||
|
||||
// 获取所有报名记录的 CreatedUserId
|
||||
var createdUserIds = result.Rows.Select(x => x.CreatedUserId).Distinct().ToList();
|
||||
@ -230,33 +246,70 @@ public class EventRegistrationService : BaseService<EventRegistration>, ITransie
|
||||
{
|
||||
var myPersons = persons.Where(p => p.RegistrationItemId == item.Id).ToList();
|
||||
|
||||
// 构造参与人信息字符串,统一格式为:姓名/性别/年龄/手机号
|
||||
var personInfo = string.Join(";", myPersons.Select(p =>
|
||||
// 判断项目类型
|
||||
bool isIndividualProject = false;
|
||||
if (eventProjectToProjectDict.TryGetValue(item.ProjectId, out var projectId) &&
|
||||
projectDict.TryGetValue(projectId, out var project))
|
||||
{
|
||||
// 将性别转换为中文显示
|
||||
var genderText = p.Gender switch
|
||||
isIndividualProject = YD_Event.Core.Extensions.ProjectTypeExtensions.IsIndividualProject(project);
|
||||
}
|
||||
|
||||
if (isIndividualProject)
|
||||
{
|
||||
// 个人项目:为每个运动员创建一个条目,使用 EventRegistrationPerson.Id
|
||||
foreach (var person in myPersons.Where(p => p.PersonType == PersonType.Athlete))
|
||||
{
|
||||
YD_Event.Core.Enum.Gender.Male => "男",
|
||||
YD_Event.Core.Enum.Gender.Female => "女",
|
||||
_ => "未知"
|
||||
};
|
||||
|
||||
// 获取手机号,优先使用关联用户信息,否则使用自身的 Phone 字段
|
||||
var mobile = p.User?.Mobile ?? p.Phone ?? "";
|
||||
|
||||
// 统一格式:姓名/性别/年龄/手机号
|
||||
return $"{p.Name}/{genderText}/{p.Age}/{mobile}";
|
||||
}));
|
||||
if (personInfo.Length > 100) personInfo = personInfo.Substring(0, 97) + "..."; // 截断
|
||||
// 构造参与人信息字符串
|
||||
var genderText = person.Gender switch
|
||||
{
|
||||
YD_Event.Core.Enum.Gender.Male => "男",
|
||||
YD_Event.Core.Enum.Gender.Female => "女",
|
||||
_ => "未知"
|
||||
};
|
||||
var mobile = person.User?.Mobile ?? person.Phone ?? "";
|
||||
var personInfo = $"{person.Name}/{genderText}/{person.Age}/{mobile}";
|
||||
|
||||
var detail = new RegistrationItemDetailDto
|
||||
var detail = new RegistrationItemDetailDto
|
||||
{
|
||||
Id = person.Id, // 使用 EventRegistrationPerson.Id
|
||||
ProjectName = item.ProjectName,
|
||||
GroupName = item.GroupName,
|
||||
ParticipantInfo = personInfo
|
||||
};
|
||||
dto.Items.Add(detail);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Id = item.Id,
|
||||
ProjectName = item.ProjectName,
|
||||
GroupName = item.GroupName,
|
||||
ParticipantInfo = personInfo
|
||||
};
|
||||
dto.Items.Add(detail);
|
||||
// 团队项目:保持原有逻辑,使用 EventRegistrationItem.Id
|
||||
// 构造参与人信息字符串,统一格式为:姓名/性别/年龄/手机号
|
||||
var personInfo = string.Join(";", myPersons.Select(p =>
|
||||
{
|
||||
// 将性别转换为中文显示
|
||||
var genderText = p.Gender switch
|
||||
{
|
||||
YD_Event.Core.Enum.Gender.Male => "男",
|
||||
YD_Event.Core.Enum.Gender.Female => "女",
|
||||
_ => "未知"
|
||||
};
|
||||
|
||||
// 获取手机号,优先使用关联用户信息,否则使用自身的 Phone 字段
|
||||
var mobile = p.User?.Mobile ?? p.Phone ?? "";
|
||||
|
||||
// 统一格式:姓名/性别/年龄/手机号
|
||||
return $"{p.Name}/{genderText}/{p.Age}/{mobile}";
|
||||
}));
|
||||
if (personInfo.Length > 100) personInfo = personInfo.Substring(0, 97) + "..."; // 截断
|
||||
|
||||
var detail = new RegistrationItemDetailDto
|
||||
{
|
||||
Id = item.Id, // 使用 EventRegistrationItem.Id
|
||||
ProjectName = item.ProjectName,
|
||||
GroupName = item.GroupName,
|
||||
ParticipantInfo = personInfo
|
||||
};
|
||||
dto.Items.Add(detail);
|
||||
}
|
||||
}
|
||||
|
||||
// 设置领队信息和教练信息 - 从团队中获取
|
||||
|
||||
@ -47,6 +47,7 @@ public class EventScoreService : BaseService<EventResult>, ITransient
|
||||
private readonly ISqlSugarRepository<EventResult> _resultRepository;
|
||||
private readonly ISqlSugarRepository<EventCertificate> _certificateRepository;
|
||||
private readonly ISqlSugarRepository<EventRegistration> _registrationRepository;
|
||||
private readonly ISqlSugarRepository<EventRegistrationItem> _itemRepository;
|
||||
private readonly ISqlSugarRepository<CertificateTemplate> _templateRepository;
|
||||
private readonly ISqlSugarRepository<YD_Event.Core.Entities.Certificate> _certificateMasterRepository;
|
||||
private readonly ISqlSugarRepository<YD_Event.Core.Entities.Project> _projectRepository;
|
||||
@ -66,6 +67,7 @@ public class EventScoreService : BaseService<EventResult>, ITransient
|
||||
ISqlSugarRepository<EventResult> resultRepository,
|
||||
ISqlSugarRepository<EventCertificate> certificateRepository,
|
||||
ISqlSugarRepository<EventRegistration> registrationRepository,
|
||||
ISqlSugarRepository<EventRegistrationItem> itemRepository,
|
||||
ISqlSugarRepository<CertificateTemplate> templateRepository,
|
||||
ISqlSugarRepository<YD_Event.Core.Entities.Certificate> certificateMasterRepository,
|
||||
ISqlSugarRepository<YD_Event.Core.Entities.Project> projectRepository,
|
||||
@ -84,6 +86,7 @@ public class EventScoreService : BaseService<EventResult>, ITransient
|
||||
_resultRepository = resultRepository;
|
||||
_certificateRepository = certificateRepository;
|
||||
_registrationRepository = registrationRepository;
|
||||
_itemRepository = itemRepository;
|
||||
_templateRepository = templateRepository;
|
||||
_certificateMasterRepository = certificateMasterRepository;
|
||||
_projectRepository = projectRepository;
|
||||
@ -275,7 +278,7 @@ public class EventScoreService : BaseService<EventResult>, ITransient
|
||||
/// 教练/领队列表
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 通过运动员报名记录 -> TeamMember团队关联 -> 找到同团队的教练/领队
|
||||
/// 通过运动员报名记录 -> TeamMember团队关联 -> 找到同团队的教练/领队
|
||||
/// </remarks>
|
||||
[DisplayName("教练领队列表")]
|
||||
public async Task<PageResult<CoachLeaderListOutput>> PageCoachLeader(CoachLeaderQueryInput input)
|
||||
@ -515,12 +518,21 @@ public class EventScoreService : BaseService<EventResult>, ITransient
|
||||
var allProjects = await _projectRepository.GetListAsync(x => allProjectIds.Contains(x.Id));
|
||||
var allProjectDict = allProjects.ToDictionary(p => p.Id, p => p);
|
||||
|
||||
// 步骤4:使用字典建立人员索引(按RegistrationItemId索引,取第一个人作为代表)
|
||||
// 注意:团队项目中一个 RegistrationItemId 可能对应多个运动员,但只需要第一个作为代表
|
||||
// 步骤4:使用字典建立人员索引
|
||||
// 1. 按 EventRegistrationPerson.Id 索引(用于个人项目)
|
||||
var personByIdDict = allPersonsWithTeam
|
||||
.ToDictionary(p => p.Id, p => p);
|
||||
|
||||
// 2. 按 RegistrationItemId 索引(用于团队项目)
|
||||
var personByItemIdDict = allPersonsWithTeam
|
||||
.GroupBy(p => p.RegistrationItemId)
|
||||
.ToDictionary(g => g.Key, g => g.First());
|
||||
|
||||
// 同时预加载所有 EventRegistrationItem 信息
|
||||
var registrationItemIds = allPersonsWithTeam.Select(p => p.RegistrationItemId).Distinct().ToList();
|
||||
var registrationItems = await _itemRepository.GetListAsync(x => registrationItemIds.Contains(x.Id));
|
||||
var registrationItemDict = registrationItems.ToDictionary(x => x.Id, x => x);
|
||||
|
||||
// 预加载 EventRegistration 信息,用于获取归属单位 ID
|
||||
var registrationIdsList = allPersonsWithTeam.Select(p => p.RegistrationId).Distinct().ToList();
|
||||
var registrations = await _registrationRepository.GetListAsync(r => registrationIdsList.Contains(r.Id));
|
||||
@ -541,8 +553,17 @@ public class EventScoreService : BaseService<EventResult>, ITransient
|
||||
|
||||
foreach(var row in validationResult.ValidRows)
|
||||
{
|
||||
// 使用报名ID进行匹配
|
||||
if (!personByItemIdDict.TryGetValue(row.RegistrationItemId.Value, out var person))
|
||||
// 首先尝试用 ID 查找 EventRegistrationPerson(用于个人项目)
|
||||
if (personByIdDict.TryGetValue(row.RegistrationItemId.Value, out var person))
|
||||
{
|
||||
// 找到了个人项目的记录,继续处理
|
||||
}
|
||||
// 如果没找到,再尝试用 RegistrationItemId 查找(用于团队项目)
|
||||
else if (personByItemIdDict.TryGetValue(row.RegistrationItemId.Value, out person))
|
||||
{
|
||||
// 找到了团队项目的记录,继续处理
|
||||
}
|
||||
else
|
||||
{
|
||||
notFoundPersons.Add($"报名ID:{row.RegistrationItemId.Value}");
|
||||
continue;
|
||||
|
||||
@ -4189,6 +4189,11 @@
|
||||
总时长(分钟,向上取整)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.ArrangementProjectListOutput.TotalTeams">
|
||||
<summary>
|
||||
团队总数(仅团队项目有效)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Event.Dtos.ArrangementGroupDto">
|
||||
<summary>
|
||||
编排组别DTO
|
||||
@ -5831,7 +5836,7 @@
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.RegistrationItemDetailDto.Id">
|
||||
<summary>
|
||||
报名项目ID(EventRegistrationItem的ID)
|
||||
报名项目ID(EventRegistrationItem的ID 或 EventRegistrationPerson的ID,根据项目类型决定)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.RegistrationItemDetailDto.ParticipantInfo">
|
||||
@ -8040,7 +8045,7 @@
|
||||
教练/领队列表
|
||||
</summary>
|
||||
<remarks>
|
||||
通过运动员报名记录 -> TeamMember团队关联 -> 找到同团队的教练/领队
|
||||
通过运动员报名记录 -> TeamMember团队关联 -> 找到同团队的教练/领队
|
||||
</remarks>
|
||||
</member>
|
||||
<!-- Badly formed XML comment ignored for member "M:YD_Event.Application.Event.EventScoreService.ImportScore(System.Int64,Microsoft.AspNetCore.Http.IFormFile)" -->
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user