赛事报名限制
This commit is contained in:
parent
1cdb2aec6c
commit
9bca004d2b
@ -16,7 +16,7 @@ namespace YD_Event.Application.Certificate;
|
||||
/// <summary>
|
||||
/// 证书模板管理服务
|
||||
/// </summary>
|
||||
public class CertificateTemplateService : BaseService<CertificateTemplate>, ITransient
|
||||
public class CertificateTemplateService : BaseService<CertificateTemplate>, IDynamicApiController, ITransient
|
||||
{
|
||||
private readonly ISqlSugarRepository<CertificateTemplate> _templateRepository;
|
||||
private readonly ISqlSugarRepository<CertificatePlaceholder> _placeholderRepository;
|
||||
|
||||
@ -95,16 +95,42 @@ public class EventScoreService : BaseService<EventResult>, ITransient
|
||||
[DisplayName("运动员成绩列表")]
|
||||
public async Task<PageResult<ScoreListOutput>> PageAthlete(ScoreQueryInput input)
|
||||
{
|
||||
var pageResult = await _personRepository.AsQueryable()
|
||||
_logger.LogInformation("开始查询运动员成绩列表,赛事ID={EventId}, 项目ID={ProjectId}, 组别={GroupName}",
|
||||
input.EventId, input.ProjectId, input.GroupName);
|
||||
|
||||
var query = _personRepository.AsQueryable()
|
||||
.LeftJoin<EventRegistration>((p, r) => p.RegistrationId == r.Id)
|
||||
.LeftJoin<EventResult>((p, r, res) => p.Id == res.RegistrationPersonId)
|
||||
.LeftJoin<EventCertificate>((p, r, res, c) => res.Id == c.ResultId)
|
||||
.Where((p, r, res, c) => r.EventId == input.EventId && (p.PersonType == PersonType.Athlete || p.PersonType == PersonType.User))
|
||||
.WhereIF(input.ProjectId.HasValue, p => p.ProjectId == input.ProjectId)
|
||||
.WhereIF(!string.IsNullOrWhiteSpace(input.GroupName), p => p.GroupName == input.GroupName)
|
||||
.WhereIF(!string.IsNullOrWhiteSpace(input.Name), p => p.Name.Contains(input.Name))
|
||||
.WhereIF(!string.IsNullOrWhiteSpace(input.UnitName), (p, r) => r.TeamName.Contains(input.UnitName))
|
||||
.WhereIF(input.Gender.HasValue, p => p.Gender == input.Gender.Value)
|
||||
.Where((p, r, res, c) => r.EventId == input.EventId && (p.PersonType == PersonType.Athlete || p.PersonType == PersonType.User));
|
||||
|
||||
// 应用筛选条件
|
||||
if (input.ProjectId.HasValue)
|
||||
{
|
||||
query = query.Where(p => p.ProjectId == input.ProjectId.Value);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(input.GroupName))
|
||||
{
|
||||
query = query.Where(p => p.GroupName == input.GroupName);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(input.Name))
|
||||
{
|
||||
query = query.Where(p => p.Name.Contains(input.Name));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(input.UnitName))
|
||||
{
|
||||
query = query.Where((p, r) => r.TeamName.Contains(input.UnitName));
|
||||
}
|
||||
|
||||
if (input.Gender.HasValue)
|
||||
{
|
||||
query = query.Where(p => p.Gender == input.Gender.Value);
|
||||
}
|
||||
|
||||
var pageResult = await query
|
||||
.Select((p, r, res, c) => new ScoreListOutput
|
||||
{
|
||||
Id = p.Id,
|
||||
@ -123,6 +149,7 @@ public class EventScoreService : BaseService<EventResult>, ITransient
|
||||
item.RankText = ConvertRankToChinese(item.Rank);
|
||||
}
|
||||
|
||||
_logger.LogInformation("查询运动员成绩列表完成,共{Count}条记录", pageResult.Total);
|
||||
return pageResult;
|
||||
}
|
||||
|
||||
|
||||
@ -1154,11 +1154,33 @@ public class UnifiedRegistrationService : ITransient
|
||||
_logger.LogInformation("获取到赛事报名记录: {RegistrationCount},报名人员: {PersonCount},报名项目: {ItemCount}",
|
||||
eventRegistrations.Count, registrationPersons.Count, allRegistrationItems.Count);
|
||||
|
||||
// 检查各类型限制
|
||||
// ==================== 报名限制检查流程 ====================
|
||||
// 检查顺序说明:
|
||||
// 1. 先检查团队组别容量限制 - 检查是否超过组别限报的团队数量
|
||||
// 2. 再检查成员项目限报 - 检查队员是否超过个人/团队项目的限报数量
|
||||
// 3. 然后检查人员项目组别重复 - 检查同一人员是否在同一项目的多个组别中重复报名
|
||||
// 4. 再检查人员是否已报名 - 检查人员是否已在其他报名记录中报过同一项目组别
|
||||
// 5. 最后检查项目完成人数 - 确保人数与项目的完成人数完全一致
|
||||
|
||||
// 检查1:团队组别容量限制
|
||||
// 验证是否有组别超过了限报的团队数量(例如:某组别限报2队,但本次报了3队)
|
||||
CheckTeamGroupCapacityLimitAsync(input, result, projectLimits, eventProjects, projects, eventProjectGroups);
|
||||
|
||||
// 检查2:成员项目限报
|
||||
// 验证队员是否超过了个人项目或团队项目的限报数量(例如:某队员已报2个个人项目,限报2个,又报第3个)
|
||||
await CheckMemberProjectLimitAsync(input, result, limit, eventProjects, projects, registrationPersons, allRegistrationItems);
|
||||
|
||||
// 检查3:人员项目组别重复
|
||||
// 验证同一人员是否在本次报名中重复选择了同一项目的多个组别(例如:同一队员在同一项目的男子组和女子组都报了名)
|
||||
CheckPersonProjectDuplicateAsync(input, result, eventProjects, projects, eventProjectGroups);
|
||||
|
||||
// 检查4:人员是否已在其他报名中报名
|
||||
// 验证人员是否已在其他已支付的报名记录中报过同一项目组别(避免重复占用名额)
|
||||
CheckPersonAlreadyRegisteredAsync(input, result, eventProjects, projects, eventProjectGroups, registrationPersons, allRegistrationItems, eventRegistrationIds);
|
||||
|
||||
// 检查5:项目完成人数验证
|
||||
// 验证用户选择的参与人数必须与项目的"完成人数"完全一致(例如:项目要求完成3人,但只选了2人或选了4人)
|
||||
CheckProjectCompletionAsync(input, result, eventProjects, projects, eventProjectGroups);
|
||||
|
||||
_logger.LogInformation("报名限制检查完成,是否存在限制: {HasLimit}, 限制详情数: {LimitCount}",
|
||||
result.HasLimit, result.LimitDetails.Count);
|
||||
@ -1194,7 +1216,7 @@ public class UnifiedRegistrationService : ITransient
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查团队组别容量限制
|
||||
/// 检查团队组别容量限制(项目组别限报设置)
|
||||
/// </summary>
|
||||
private void CheckTeamGroupCapacityLimitAsync(
|
||||
UnifiedRegistrationInput input,
|
||||
@ -1204,59 +1226,69 @@ public class UnifiedRegistrationService : ITransient
|
||||
List<YD_Event.Core.Entities.Project> projects,
|
||||
List<EventProjectGroup> eventProjectGroups)
|
||||
{
|
||||
var teamGroupCountDict = new Dictionary<long, int>();
|
||||
|
||||
foreach (var item in input.Items)
|
||||
{
|
||||
if (!item.GroupId.HasValue) continue;
|
||||
|
||||
var teams = GetTeamsFromItem(item);
|
||||
var teamCountForItem = teams.Count;
|
||||
|
||||
if (teamCountForItem > 0)
|
||||
{
|
||||
if (teamGroupCountDict.ContainsKey(item.GroupId.Value))
|
||||
{
|
||||
teamGroupCountDict[item.GroupId.Value] += teamCountForItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
teamGroupCountDict[item.GroupId.Value] = teamCountForItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!teamGroupCountDict.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var groupId in teamGroupCountDict.Keys)
|
||||
{
|
||||
var eventProjectGroup = eventProjectGroups.FirstOrDefault(epg => epg.Id == groupId);
|
||||
// 获取组别信息
|
||||
var eventProjectGroup = eventProjectGroups.FirstOrDefault(epg => epg.Id == item.GroupId.Value);
|
||||
if (eventProjectGroup == null) continue;
|
||||
|
||||
|
||||
// 获取赛事项目信息
|
||||
var eventProject = eventProjects.FirstOrDefault(ep => ep.Id == eventProjectGroup.EventProjectId);
|
||||
if (eventProject == null) continue;
|
||||
|
||||
|
||||
// 获取基础项目信息
|
||||
var project = projects.FirstOrDefault(p => p.Id == eventProject.ProjectId);
|
||||
if (project == null) continue;
|
||||
|
||||
// 判断是否为团队项目
|
||||
var isTeamProject = project.IsTeamProject();
|
||||
|
||||
// 获取项目限报配置
|
||||
var projectLimit = projectLimits.FirstOrDefault(pl => pl.ProjectId == eventProject.Id);
|
||||
if (projectLimit == null) continue;
|
||||
|
||||
var submittedTeamCount = teamGroupCountDict[groupId];
|
||||
if (submittedTeamCount <= projectLimit.LimitCount) continue;
|
||||
|
||||
var project = projects.FirstOrDefault(p => p.Id == eventProject.ProjectId);
|
||||
var projectName = project?.Name ?? "未知项目";
|
||||
|
||||
_logger.LogWarning("组别容量超限,项目: {ProjectName},组别: {GroupName},限报: {LimitCount},提交: {SubmittedCount}",
|
||||
projectName, eventProjectGroup.GroupName, projectLimit.LimitCount, submittedTeamCount);
|
||||
|
||||
result.HasLimit = true;
|
||||
result.LimitDetails.Add(CreateLimitDetail(
|
||||
0,
|
||||
eventProjectGroup.GroupName ?? "未知组别",
|
||||
"ProjectGroupCapacity",
|
||||
$"项目\"{projectName}\"的组别\"{eventProjectGroup.GroupName}\"限报{projectLimit.LimitCount}队,本次提交{submittedTeamCount}队,超出限报配置"));
|
||||
if (isTeamProject)
|
||||
{
|
||||
// ==================== 团队项目验证 ====================
|
||||
// 检查该组别申报的团队数量是否超过限报配置
|
||||
var teams = GetTeamsFromItem(item);
|
||||
var submittedTeamCount = teams.Count;
|
||||
|
||||
if (submittedTeamCount > projectLimit.LimitCount)
|
||||
{
|
||||
_logger.LogWarning("团队项目组别容量超限,项目: {ProjectName},组别: {GroupName},限报: {LimitCount}队,提交: {SubmittedCount}队",
|
||||
project.Name, eventProjectGroup.GroupName, projectLimit.LimitCount, submittedTeamCount);
|
||||
|
||||
result.HasLimit = true;
|
||||
result.LimitDetails.Add(CreateLimitDetail(
|
||||
0,
|
||||
eventProjectGroup.GroupName ?? "未知组别",
|
||||
"ProjectGroupCapacity",
|
||||
$"项目组别限报设置:项目\"{project.Name}\"的组别\"{eventProjectGroup.GroupName}\"限报{projectLimit.LimitCount}队,本次提交{submittedTeamCount}队,超出限报配置"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ==================== 个人项目验证 ====================
|
||||
// 检查该组别申报的人员数量是否超过限报配置
|
||||
var persons = GetAllPersonsFromItem(item);
|
||||
var submittedPersonCount = persons.Count;
|
||||
|
||||
if (submittedPersonCount > projectLimit.LimitCount)
|
||||
{
|
||||
_logger.LogWarning("个人项目组别容量超限,项目: {ProjectName},组别: {GroupName},限报: {LimitCount}人,提交: {SubmittedCount}人",
|
||||
project.Name, eventProjectGroup.GroupName, projectLimit.LimitCount, submittedPersonCount);
|
||||
|
||||
result.HasLimit = true;
|
||||
result.LimitDetails.Add(CreateLimitDetail(
|
||||
0,
|
||||
eventProjectGroup.GroupName ?? "未知组别",
|
||||
"ProjectGroupCapacity",
|
||||
$"项目组别限报设置:项目\"{project.Name}\"的组别\"{eventProjectGroup.GroupName}\"限报{projectLimit.LimitCount}人,本次提交{submittedPersonCount}人,超出限报配置"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1402,7 +1434,7 @@ public class UnifiedRegistrationService : ITransient
|
||||
member.Id,
|
||||
member.Name ?? member.NickName ?? "未知",
|
||||
"IndividualProjectLimit",
|
||||
$"队员{member.Name}已报名{individualProjectCount}个个人项目,达到个人项目限报{limit.IndividualProjectLimit}个"));
|
||||
$"成员项目限报设置:队员\"{member.Name}\"已报名{individualProjectCount}个个人项目,个人项目限报{limit.IndividualProjectLimit}个,请减少个人项目报名数量"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1427,7 +1459,7 @@ public class UnifiedRegistrationService : ITransient
|
||||
member.Id,
|
||||
member.Name ?? member.NickName ?? "未知",
|
||||
"TeamProjectLimit",
|
||||
$"队员{member.Name}已参与{teamProjectCount}个团队项目,达到团队项目限报{limit.TeamProjectLimit}个"));
|
||||
$"成员项目限报设置:队员\"{member.Name}\"已参与{teamProjectCount}个团队项目,团队项目限报{limit.TeamProjectLimit}个,请减少团队项目报名数量"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -1499,7 +1531,7 @@ public class UnifiedRegistrationService : ITransient
|
||||
0,
|
||||
personName,
|
||||
"PersonProjectDuplicate",
|
||||
$"人员\"{personName}\"在项目\"{groupInfo.ProjectName}\"的组别\"{groupInfo.GroupName}\"中重复出现,同一人员只能在一个团队中报名同一项目组别"));
|
||||
$"人员项目重复检测:人员\"{personName}\"在项目\"{groupInfo.ProjectName}\"的组别\"{groupInfo.GroupName}\"中重复出现,同一人员只能在一个团队中报名同一项目组别"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1558,7 +1590,72 @@ public class UnifiedRegistrationService : ITransient
|
||||
0,
|
||||
person.Name,
|
||||
"PersonAlreadyRegistered",
|
||||
$"人员\"{person.Name}\"已在项目\"{projectName}\"的组别\"{eventProjectGroup.GroupName}\"中报名过,不能重复报名"));
|
||||
$"人员已报名检测:人员\"{person.Name}\"已在项目\"{projectName}\"的组别\"{eventProjectGroup.GroupName}\"中报名过,不能重复报名,避免占用多个名额"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查项目完成人数
|
||||
/// </summary>
|
||||
private void CheckProjectCompletionAsync(
|
||||
UnifiedRegistrationInput input,
|
||||
RegistrationLimitCheckOutput result,
|
||||
List<EventProject> eventProjects,
|
||||
List<YD_Event.Core.Entities.Project> projects,
|
||||
List<EventProjectGroup> eventProjectGroups)
|
||||
{
|
||||
foreach (var item in input.Items)
|
||||
{
|
||||
if (!item.GroupId.HasValue) continue;
|
||||
|
||||
// 获取组别信息
|
||||
var eventProjectGroup = eventProjectGroups.FirstOrDefault(epg => epg.Id == item.GroupId.Value);
|
||||
if (eventProjectGroup == null) continue;
|
||||
|
||||
// 获取赛事项目信息
|
||||
var eventProject = eventProjects.FirstOrDefault(ep => ep.Id == eventProjectGroup.EventProjectId);
|
||||
if (eventProject == null) continue;
|
||||
|
||||
// 获取基础项目信息
|
||||
var project = projects.FirstOrDefault(p => p.Id == eventProject.ProjectId);
|
||||
if (project == null) continue;
|
||||
|
||||
// 判断是否为团队项目
|
||||
var isTeamProject = project.IsTeamProject();
|
||||
|
||||
// 计算分配的人数(去重)
|
||||
var assignedPersons = GetAllPersonsFromItem(item);
|
||||
var totalAssignedMembers = assignedPersons
|
||||
.Where(p => p.UserId.HasValue)
|
||||
.Select(p => p.UserId.Value)
|
||||
.Distinct()
|
||||
.Count();
|
||||
|
||||
// ==================== 项目完成人数验证 ====================
|
||||
// 验证用户选择的参与人数必须与项目的"完成人数"完全一致
|
||||
if (project.CompletionCount > 0 && totalAssignedMembers != project.CompletionCount)
|
||||
{
|
||||
string errorMessage;
|
||||
if (totalAssignedMembers < project.CompletionCount)
|
||||
{
|
||||
errorMessage = isTeamProject
|
||||
? $"项目完成人数限制:项目\"{project.Name}\"的组别\"{eventProjectGroup.GroupName}\"要求完成人数为{project.CompletionCount}人,当前只分配了{totalAssignedMembers}人,请补充队员"
|
||||
: $"项目完成人数限制:项目\"{project.Name}\"的组别\"{eventProjectGroup.GroupName}\"要求完成人数为{project.CompletionCount}人,当前只分配了{totalAssignedMembers}人,请补充队员";
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMessage = isTeamProject
|
||||
? $"项目完成人数限制:项目\"{project.Name}\"的组别\"{eventProjectGroup.GroupName}\"要求完成人数为{project.CompletionCount}人,当前分配了{totalAssignedMembers}人,人数超额,请移除多余队员"
|
||||
: $"项目完成人数限制:项目\"{project.Name}\"的组别\"{eventProjectGroup.GroupName}\"要求完成人数为{project.CompletionCount}人,当前分配了{totalAssignedMembers}人,人数超额,请移除多余队员";
|
||||
}
|
||||
|
||||
result.HasLimit = true;
|
||||
result.LimitDetails.Add(CreateLimitDetail(
|
||||
0,
|
||||
eventProjectGroup.GroupName ?? "未知组别",
|
||||
"ProjectCompletion",
|
||||
errorMessage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user