赛事报名
This commit is contained in:
parent
814c5672f2
commit
8bd8961896
@ -119,6 +119,11 @@ public class ArrangementPreviewOutput
|
||||
/// </summary>
|
||||
public string ProjectName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 项目类型
|
||||
/// </summary>
|
||||
public string ProjectType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 组别名称
|
||||
/// </summary>
|
||||
|
||||
@ -81,7 +81,39 @@ public class UnifiedRegistrationItemInput
|
||||
public string? GroupName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 参赛人员列表
|
||||
/// 团队列表(支持多个团队报名同一项目组别)
|
||||
/// </summary>
|
||||
public List<UnifiedTeamInput> Teams { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 参赛人员列表(单个团队报名时使用,向后兼容)
|
||||
/// </summary>
|
||||
public List<UnifiedPersonInput> Persons { get; set; } = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 统一团队输入DTO
|
||||
/// </summary>
|
||||
public class UnifiedTeamInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 团队ID(可选,已有团队时使用)
|
||||
/// </summary>
|
||||
public long? TeamId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 团队名称
|
||||
/// </summary>
|
||||
[MaxLength(100, ErrorMessage = "团队名称不能超过100个字符")]
|
||||
public string? TeamName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 团队序号(用于显示,如"团队一"、"团队二")
|
||||
/// </summary>
|
||||
public int TeamIndex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 该团队的参赛人员列表
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "参赛人员列表不能为空")]
|
||||
[MinLength(1, ErrorMessage = "请至少填写一个参赛人员")]
|
||||
|
||||
@ -177,6 +177,7 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
||||
{
|
||||
TimeRange = $"{proj.DurationSeconds}''",
|
||||
ProjectName = proj.Name,
|
||||
ProjectType = proj.ProjectType.Description(),
|
||||
GroupName = person.GroupName,
|
||||
TeamName = person.TeamName,
|
||||
AthleteName = person.Name,
|
||||
|
||||
@ -72,7 +72,11 @@ public class EventRegistrationService : BaseService<EventRegistration>, ITransie
|
||||
{
|
||||
var regIds = result.Rows.Select(x => x.Id).ToList();
|
||||
var items = await _itemRepository.GetListAsync(x => regIds.Contains(x.RegistrationId));
|
||||
var persons = await _personRepository.GetListAsync(x => regIds.Contains(x.RegistrationId));
|
||||
// 使用关联查询获取报名人员及其关联的用户信息
|
||||
var persons = await _personRepository.AsQueryable()
|
||||
.Includes(p => p.User) // 关联查询用户信息
|
||||
.Where(x => regIds.Contains(x.RegistrationId))
|
||||
.ToListAsync();
|
||||
|
||||
foreach (var dto in result.Rows)
|
||||
{
|
||||
@ -83,8 +87,16 @@ public class EventRegistrationService : BaseService<EventRegistration>, ITransie
|
||||
{
|
||||
var myPersons = persons.Where(p => p.RegistrationItemId == item.Id).ToList();
|
||||
|
||||
// 构造参与人信息字符串
|
||||
var personInfo = string.Join(";", myPersons.Select(p => $"{p.Name}/{p.Gender}/{p.Age}/{p.IdCard}"));
|
||||
// 构造参与人信息字符串,可以使用关联的 User 信息
|
||||
var personInfo = string.Join(";", myPersons.Select(p =>
|
||||
{
|
||||
// 如果有关联的用户信息,可以使用更完整的信息
|
||||
if (p.User != null)
|
||||
{
|
||||
return $"{p.Name}({p.User.Mobile})/{p.Gender}/{p.Age}";
|
||||
}
|
||||
return $"{p.Name}/{p.Gender}/{p.Age}/{p.IdCard}";
|
||||
}));
|
||||
if (personInfo.Length > 100) personInfo = personInfo.Substring(0, 97) + "..."; // 截断
|
||||
|
||||
var detail = new RegistrationItemDetailDto
|
||||
|
||||
@ -412,16 +412,63 @@ public class UnifiedRegistrationService : ITransient
|
||||
return result;
|
||||
}
|
||||
|
||||
// 2.1 验证队员资质(年龄和性别)
|
||||
var qualificationResult = ValidatePersonQualifications(item.Persons, eventProjectGroup);
|
||||
if (!qualificationResult.IsValid)
|
||||
// 处理团队列表(支持多团队报名)
|
||||
var teamsToValidate = new List<UnifiedTeamInput>();
|
||||
|
||||
if (item.Teams != null && item.Teams.Any())
|
||||
{
|
||||
// 使用新的团队列表格式
|
||||
teamsToValidate.AddRange(item.Teams);
|
||||
}
|
||||
else if (item.Persons != null && item.Persons.Any())
|
||||
{
|
||||
// 向后兼容:使用旧的单个团队格式
|
||||
teamsToValidate.Add(new UnifiedTeamInput
|
||||
{
|
||||
TeamIndex = 1,
|
||||
Persons = item.Persons
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
result.IsValid = false;
|
||||
result.ErrorMessage = qualificationResult.ErrorMessage;
|
||||
result.Details.AddRange(qualificationResult.Details);
|
||||
result.ErrorMessage = $"请为项目添加至少一个团队和队员";
|
||||
result.Details.Add(new ValidationDetail
|
||||
{
|
||||
ItemName = "团队验证",
|
||||
IsPassed = false,
|
||||
Message = result.ErrorMessage
|
||||
});
|
||||
return result;
|
||||
}
|
||||
result.Details.AddRange(qualificationResult.Details);
|
||||
|
||||
// 验证每个团队
|
||||
foreach (var team in teamsToValidate)
|
||||
{
|
||||
if (team.Persons == null || !team.Persons.Any())
|
||||
{
|
||||
result.IsValid = false;
|
||||
result.ErrorMessage = $"团队{team.TeamIndex}请至少添加一个队员";
|
||||
result.Details.Add(new ValidationDetail
|
||||
{
|
||||
ItemName = "团队验证",
|
||||
IsPassed = false,
|
||||
Message = result.ErrorMessage
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
// 验证队员资质(年龄和性别)
|
||||
var qualificationResult = ValidatePersonQualifications(team.Persons, eventProjectGroup);
|
||||
if (!qualificationResult.IsValid)
|
||||
{
|
||||
result.IsValid = false;
|
||||
result.ErrorMessage = qualificationResult.ErrorMessage;
|
||||
result.Details.AddRange(qualificationResult.Details);
|
||||
return result;
|
||||
}
|
||||
result.Details.AddRange(qualificationResult.Details);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -430,7 +477,7 @@ public class UnifiedRegistrationService : ITransient
|
||||
/// <summary>
|
||||
/// 验证队员资质(年龄和性别)
|
||||
/// </summary>
|
||||
private RegistrationValidationResult ValidatePersonQualifications(List<UnifiedPersonInput> persons, EventProjectGroup group)
|
||||
public RegistrationValidationResult ValidatePersonQualifications(List<UnifiedPersonInput> persons, EventProjectGroup group)
|
||||
{
|
||||
var result = new RegistrationValidationResult
|
||||
{
|
||||
@ -565,51 +612,74 @@ public class UnifiedRegistrationService : ITransient
|
||||
var baseProject = baseProjects.FirstOrDefault(p => p.Id == eventProject.ProjectId);
|
||||
var groupName = GetGroupName(item, eventProjectGroups);
|
||||
|
||||
// 计算费用
|
||||
var (unitPrice, totalPrice) = CalculateItemPrice(feeConfig, eventProject, item.Persons.Count);
|
||||
|
||||
var regItemId = _idGenerator.NewLong();
|
||||
var regItem = new EventRegistrationItem
|
||||
// 处理团队列表(支持多团队报名)
|
||||
var teamsToProcess = new List<UnifiedTeamInput>();
|
||||
|
||||
if (item.Teams != null && item.Teams.Any())
|
||||
{
|
||||
Id = regItemId,
|
||||
RegistrationId = registration.Id,
|
||||
ProjectId = item.ProjectId,
|
||||
EventProjectGroupId = item.GroupId,
|
||||
ProjectName = baseProject?.Name ?? "",
|
||||
GroupName = groupName,
|
||||
ProjectTypeName = baseProject?.ProjectType.Description() ?? "",
|
||||
UnitPrice = unitPrice,
|
||||
PersonCount = item.Persons.Count,
|
||||
TotalPrice = totalPrice,
|
||||
CreatedUserId = input.CreatedUserId,
|
||||
CreatedTime = DateTime.Now
|
||||
};
|
||||
regItems.Add(regItem);
|
||||
|
||||
totalPersonCount += item.Persons.Count;
|
||||
|
||||
// 添加参赛人员
|
||||
foreach (var pInput in item.Persons)
|
||||
// 使用新的团队列表格式
|
||||
teamsToProcess.AddRange(item.Teams);
|
||||
}
|
||||
else if (item.Persons != null && item.Persons.Any())
|
||||
{
|
||||
persons.Add(new EventRegistrationPerson
|
||||
// 向后兼容:使用旧的单个团队格式
|
||||
teamsToProcess.Add(new UnifiedTeamInput
|
||||
{
|
||||
Id = _idGenerator.NewLong(),
|
||||
TeamIndex = 1,
|
||||
Persons = item.Persons
|
||||
});
|
||||
}
|
||||
|
||||
// 为每个团队创建报名明细
|
||||
foreach (var team in teamsToProcess)
|
||||
{
|
||||
// 计算费用
|
||||
var (unitPrice, totalPrice) = CalculateItemPrice(feeConfig, eventProject, team.Persons.Count);
|
||||
|
||||
var regItemId = _idGenerator.NewLong();
|
||||
var regItem = new EventRegistrationItem
|
||||
{
|
||||
Id = regItemId,
|
||||
RegistrationId = registration.Id,
|
||||
RegistrationItemId = regItemId,
|
||||
ProjectId = item.ProjectId,
|
||||
EventProjectGroupId = item.GroupId,
|
||||
GroupName = groupName,
|
||||
ProjectName = baseProject?.Name ?? "",
|
||||
Name = pInput.Name,
|
||||
Gender = pInput.Gender,
|
||||
IdCard = pInput.IdCardNumber,
|
||||
BirthDate = pInput.BirthDate,
|
||||
Phone = pInput.Mobile,
|
||||
Age = CalculateAge(pInput.BirthDate),
|
||||
PersonType = PersonType.Athlete,
|
||||
GroupName = groupName,
|
||||
ProjectTypeName = baseProject?.ProjectType.Description() ?? "",
|
||||
UnitPrice = unitPrice,
|
||||
PersonCount = team.Persons.Count,
|
||||
TotalPrice = totalPrice,
|
||||
CreatedUserId = input.CreatedUserId,
|
||||
CreatedTime = DateTime.Now
|
||||
});
|
||||
};
|
||||
regItems.Add(regItem);
|
||||
|
||||
totalPersonCount += team.Persons.Count;
|
||||
|
||||
// 添加参赛人员
|
||||
foreach (var pInput in team.Persons)
|
||||
{
|
||||
persons.Add(new EventRegistrationPerson
|
||||
{
|
||||
Id = _idGenerator.NewLong(),
|
||||
RegistrationId = registration.Id,
|
||||
RegistrationItemId = regItemId,
|
||||
ProjectId = item.ProjectId,
|
||||
EventProjectGroupId = item.GroupId,
|
||||
GroupName = groupName,
|
||||
ProjectName = baseProject?.Name ?? "",
|
||||
Name = pInput.Name,
|
||||
Gender = pInput.Gender,
|
||||
IdCard = pInput.IdCardNumber,
|
||||
BirthDate = pInput.BirthDate,
|
||||
Phone = pInput.Mobile,
|
||||
Age = CalculateAge(pInput.BirthDate),
|
||||
PersonType = PersonType.Athlete,
|
||||
UserId = pInput.UserId,
|
||||
CreatedUserId = input.CreatedUserId,
|
||||
CreatedTime = DateTime.Now
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -874,7 +944,7 @@ public class UnifiedRegistrationService : ITransient
|
||||
var eventProject = eventProjects.FirstOrDefault(ep => ep.Id == eventProjectGroup.EventProjectId);
|
||||
if (eventProject == null) continue;
|
||||
|
||||
var projectLimit = projectLimits.FirstOrDefault(pl => pl.ProjectId == eventProject.ProjectId);
|
||||
var projectLimit = projectLimits.FirstOrDefault(pl => pl.ProjectId == eventProject.Id);
|
||||
if (projectLimit == null) continue;
|
||||
|
||||
var submittedTeamCount = groupTeamCount[groupId];
|
||||
|
||||
@ -922,26 +922,41 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient
|
||||
var eventProjectGroup = await _eventProjectGroupRepository.GetByIdAsync(input.GroupId);
|
||||
if (eventProjectGroup != null)
|
||||
{
|
||||
var projectGroup = await _projectGroupRepository.GetByIdAsync(eventProjectGroup.ProjectGroupId);
|
||||
|
||||
// 优先使用EventProjectGroup中保存的信息,如果没有则使用原始ProjectGroup的信息
|
||||
var birthDateStart = eventProjectGroup.BirthDateStart != DateTime.MinValue ? eventProjectGroup.BirthDateStart : (projectGroup?.BirthDateStart ?? DateTime.MinValue);
|
||||
var birthDateEnd = eventProjectGroup.BirthDateEnd != DateTime.MinValue ? eventProjectGroup.BirthDateEnd : (projectGroup?.BirthDateEnd ?? DateTime.MaxValue);
|
||||
var gender = eventProjectGroup.Gender;
|
||||
|
||||
var birthDate = member.BirthDate.Value;
|
||||
if (birthDate < birthDateStart || birthDate > birthDateEnd)
|
||||
// 创建单个队员的验证输入
|
||||
var persons = new List<UnifiedPersonInput>
|
||||
{
|
||||
result.AgeValid = false;
|
||||
result.IsValid = false;
|
||||
result.Message = "队员年龄不符合组别要求";
|
||||
}
|
||||
new UnifiedPersonInput
|
||||
{
|
||||
UserId = member.Id,
|
||||
Name = member.Name ?? "",
|
||||
IdCardNumber = member.IdCardNumber ?? "",
|
||||
Gender = member.Gender,
|
||||
Mobile = member.Mobile,
|
||||
BirthDate = member.BirthDate.Value
|
||||
}
|
||||
};
|
||||
|
||||
if (gender != member.Gender && gender != Gender.Unknown && gender != Gender.All)
|
||||
// 使用统一的验证方法进行验证
|
||||
var validationResult = _unifiedRegistrationService.ValidatePersonQualifications(persons, eventProjectGroup);
|
||||
|
||||
if (!validationResult.IsValid)
|
||||
{
|
||||
result.GenderValid = false;
|
||||
result.IsValid = false;
|
||||
result.Message = "队员性别不符合组别要求";
|
||||
result.Message = validationResult.ErrorMessage ?? "验证失败";
|
||||
|
||||
// 根据验证详情设置具体的验证状态
|
||||
var ageDetail = validationResult.Details?.FirstOrDefault(d => d.ItemName == "年龄验证" || d.ItemName == "年龄跨组验证");
|
||||
var genderDetail = validationResult.Details?.FirstOrDefault(d => d.ItemName == "性别验证");
|
||||
|
||||
if (ageDetail != null && !ageDetail.IsPassed)
|
||||
{
|
||||
result.AgeValid = false;
|
||||
}
|
||||
|
||||
if (genderDetail != null && !genderDetail.IsPassed)
|
||||
{
|
||||
result.GenderValid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -987,7 +1002,7 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient
|
||||
var eventProject = eventProjects.FirstOrDefault(ep => ep.Id == eventProjectGroup.EventProjectId);
|
||||
if (eventProject == null) continue;
|
||||
|
||||
var projectLimit = projectLimits.FirstOrDefault(pl => pl.ProjectId == eventProject.ProjectId);
|
||||
var projectLimit = projectLimits.FirstOrDefault(pl => pl.ProjectId == eventProject.Id);
|
||||
if (projectLimit == null) continue;
|
||||
|
||||
// 统计该项目下已报名的队伍数量
|
||||
@ -1101,7 +1116,7 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient
|
||||
|
||||
// 查找该组别的项目限报配置
|
||||
var eventProject = eventProjects.FirstOrDefault(ep => ep.Id == eventProjectGroup.EventProjectId);
|
||||
var projectLimit = projectLimits.FirstOrDefault(pl => pl.ProjectId == eventProject?.ProjectId);
|
||||
var projectLimit = projectLimits.FirstOrDefault(pl => pl.ProjectId == eventProject?.Id);
|
||||
var maxTeams = projectLimit?.LimitCount ?? 2; // 默认2队
|
||||
|
||||
result.Add(new GroupTeamLimitOutput
|
||||
|
||||
@ -4020,6 +4020,11 @@
|
||||
项目名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.ArrangementPreviewOutput.ProjectType">
|
||||
<summary>
|
||||
项目类型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.ArrangementPreviewOutput.GroupName">
|
||||
<summary>
|
||||
组别名称
|
||||
@ -5635,9 +5640,39 @@
|
||||
组别名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.UnifiedRegistrationItemInput.Teams">
|
||||
<summary>
|
||||
团队列表(支持多个团队报名同一项目组别)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.UnifiedRegistrationItemInput.Persons">
|
||||
<summary>
|
||||
参赛人员列表
|
||||
参赛人员列表(单个团队报名时使用,向后兼容)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Event.Dtos.UnifiedTeamInput">
|
||||
<summary>
|
||||
统一团队输入DTO
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.UnifiedTeamInput.TeamId">
|
||||
<summary>
|
||||
团队ID(可选,已有团队时使用)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.UnifiedTeamInput.TeamName">
|
||||
<summary>
|
||||
团队名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.UnifiedTeamInput.TeamIndex">
|
||||
<summary>
|
||||
团队序号(用于显示,如"团队一"、"团队二")
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Event.Dtos.UnifiedTeamInput.Persons">
|
||||
<summary>
|
||||
该团队的参赛人员列表
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Event.Dtos.UnifiedPersonInput">
|
||||
|
||||
@ -12,7 +12,7 @@ public class EventProjectRegistrationLimit : Entity<long>, ISoftDelete, ICreated
|
||||
public long EventId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联的项目ID
|
||||
/// 关联的赛事项目ID
|
||||
/// </summary>
|
||||
public long ProjectId { get; set; }
|
||||
|
||||
|
||||
@ -33,6 +33,19 @@ public class EventRegistrationPerson : Entity<long>, ISoftDelete, ICreatedUserId
|
||||
/// </summary>
|
||||
public PersonType PersonType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联的用户ID(必填)
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = false)]
|
||||
public long UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联的用户信息(导航属性)
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
[Navigate(NavigateType.OneToOne, nameof(UserId))]
|
||||
public AppUser? User { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 姓名
|
||||
/// </summary>
|
||||
|
||||
@ -1626,7 +1626,7 @@
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.EventProjectRegistrationLimit.ProjectId">
|
||||
<summary>
|
||||
关联的项目ID
|
||||
关联的赛事项目ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.EventProjectRegistrationLimit.LimitCount">
|
||||
@ -2059,6 +2059,11 @@
|
||||
人员类型:1-运动员,2-教练,3-领队
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.EventRegistrationPerson.UserId">
|
||||
<summary>
|
||||
关联的用户ID(可选)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.EventRegistrationPerson.Name">
|
||||
<summary>
|
||||
姓名
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user