优化报名接口速度

This commit is contained in:
马梓彭 2026-06-26 14:27:57 +08:00
parent 05cdd4a407
commit 8b6b94765c
3 changed files with 105 additions and 77 deletions

View File

@ -1382,7 +1382,11 @@ public class UnifiedRegistrationService : ITransient
/// <summary>
/// 检查报名限制
/// </summary>
public async Task<RegistrationLimitCheckOutput> CheckRegistrationLimitAsync(UnifiedRegistrationInput input, long? excludeRegistrationId = null)
public async Task<RegistrationLimitCheckOutput> CheckRegistrationLimitAsync(
UnifiedRegistrationInput input,
long? excludeRegistrationId = null,
List<EventProject>? preFetchedEventProjects = null,
List<EventProjectGroup>? preFetchedEventProjectGroups = null)
{
var result = new RegistrationLimitCheckOutput
{
@ -1392,11 +1396,15 @@ public class UnifiedRegistrationService : ITransient
_logger.LogInformation("开始检查报名限制,赛事ID: {EventId}", input.EventId);
var limit = await _limitRepository.GetFirstAsync(x => x.EventId == input.EventId && !x.DeleteMark);
var projectLimits = await _projectLimitRepository.GetListAsync(x => x.EventId == input.EventId && !x.DeleteMark);
var eventProjects = await _eventProjectRepository.GetListAsync(x => x.EventId == input.EventId);
var projects = await _projectRepository.GetListAsync(x => eventProjects.Select(ep => ep.ProjectId).Contains(x.Id) && !x.DeleteMark);
var eventProjectGroups = await _eventProjectGroupRepository.GetListAsync(x => x.EventId == input.EventId && !x.DeleteMark);
// ========== 第1组:并行查询所有独立数据源 ==========
var limitTask = _limitRepository.GetFirstAsync(x => x.EventId == input.EventId && !x.DeleteMark);
var projectLimitsTask = _projectLimitRepository.GetListAsync(x => x.EventId == input.EventId && !x.DeleteMark);
var eventProjectsTask = preFetchedEventProjects != null
? Task.FromResult(preFetchedEventProjects)
: _eventProjectRepository.GetListAsync(x => x.EventId == input.EventId);
var eventProjectGroupsTask = preFetchedEventProjectGroups != null
? Task.FromResult(preFetchedEventProjectGroups)
: _eventProjectGroupRepository.GetListAsync(x => x.EventId == input.EventId && !x.DeleteMark);
// 先获取所有报名信息,供后续检查使用
// 线上支付类型的报名记录,仅统计PaymentStatus == 1(已支付)的记录
@ -1427,13 +1435,30 @@ public class UnifiedRegistrationService : ITransient
eventRegistrationsQuery = eventRegistrationsQuery.Where(x => x.Id != excludeRegistrationId.Value);
}
var eventRegistrations = await eventRegistrationsQuery.ToListAsync();
var eventRegistrationsQueryTask = eventRegistrationsQuery.ToListAsync();
await Task.WhenAll(limitTask, projectLimitsTask, eventProjectsTask, eventProjectGroupsTask, eventRegistrationsQueryTask);
var limit = limitTask.Result;
var projectLimits = projectLimitsTask.Result;
var eventProjects = eventProjectsTask.Result;
var eventProjectGroups = eventProjectGroupsTask.Result;
var eventRegistrations = eventRegistrationsQueryTask.Result;
// ========== 第2组:并行查询依赖第1组结果的数据 ==========
var eventRegistrationIds = eventRegistrations.Select(r => r.Id).ToList();
var registrationPersons = await _registrationPersonRepository.GetListAsync(x =>
var projectsTask = _projectRepository.GetListAsync(x => eventProjects.Select(ep => ep.ProjectId).Contains(x.Id) && !x.DeleteMark);
var registrationPersonsTask = _registrationPersonRepository.GetListAsync(x =>
eventRegistrationIds.Contains(x.RegistrationId) && !x.DeleteMark);
var allRegistrationItems = await _registrationItemRepository.GetListAsync(x =>
var allRegistrationItemsTask = _registrationItemRepository.GetListAsync(x =>
eventRegistrationIds.Contains(x.RegistrationId) && !x.DeleteMark);
await Task.WhenAll(projectsTask, registrationPersonsTask, allRegistrationItemsTask);
var projects = projectsTask.Result;
var registrationPersons = registrationPersonsTask.Result;
var allRegistrationItems = allRegistrationItemsTask.Result;
_logger.LogInformation("获取到赛事报名记录: {RegistrationCount},报名人员: {PersonCount},报名项目: {ItemCount}",
eventRegistrations.Count, registrationPersons.Count, allRegistrationItems.Count);

View File

@ -899,7 +899,13 @@ public class UserEventRecordService : IDynamicApiController, ITransient
validationMemberIds.Add(input.MemberId);
}
var members = await _userRepository.GetListAsync(x => validationMemberIds.Contains(x.Id));
// 并行查询:队员信息和组别信息是独立的
var membersTask = _userRepository.GetListAsync(x => validationMemberIds.Contains(x.Id));
var eventProjectGroupTask = _eventProjectGroupRepository.GetByIdAsync(input.GroupId);
await Task.WhenAll(membersTask, eventProjectGroupTask);
var members = membersTask.Result;
var member = members.FirstOrDefault(x => x.Id == input.MemberId);
// 添加调试:如果找不到,尝试不删除标记查询
@ -929,7 +935,7 @@ public class UserEventRecordService : IDynamicApiController, ITransient
return result;
}
var eventProjectGroup = await _eventProjectGroupRepository.GetByIdAsync(input.GroupId);
var eventProjectGroup = eventProjectGroupTask.Result;
if (eventProjectGroup != null)
{
// 获取项目类型信息
@ -995,30 +1001,12 @@ public class UserEventRecordService : IDynamicApiController, ITransient
{
var userId = _authManager.UserId;
// 获取当前用户信息
var sysUser = await _sysUserRepository.GetByIdAsync(userId);
if (sysUser == null) throw Oops.Bah("用户不存在");
string userName = sysUser.Name;
string userMobile = sysUser.Mobile ?? "";
// 获取团队信息 - 优先使用新结构的 TeamId
string teamName = "临时团队";
if (input.TeamId.HasValue)
{
var team = await _db.Queryable<YD_Event.Core.Entities.Team>().FirstAsync(t => t.Id == input.TeamId.Value && !t.DeleteMark);
if (team != null)
{
teamName = team.Name;
}
}
// 获取所有成员信息
// 收集所有成员ID和组别ID(纯CPU操作,无需DB)
var allMemberIds = new List<long>();
if (input.GroupMembers != null)
{
foreach (var gm in input.GroupMembers)
{
// 检查是否有多团队数据
if (gm.Teams != null && gm.Teams.Count > 0)
{
foreach (var team in gm.Teams)
@ -1028,27 +1016,37 @@ public class UserEventRecordService : IDynamicApiController, ITransient
}
else
{
// 向后兼容单团队模式
allMemberIds.AddRange(gm.MemberIds ?? new List<long>());
}
}
}
else if (input.MemberIds != null)
{
// 向后兼容旧结构
allMemberIds.AddRange(input.MemberIds);
}
allMemberIds = allMemberIds.Distinct().ToList();
// 获取成员信息
var members = await _userRepository.GetListAsync(x => allMemberIds.Contains(x.Id));
// 获取组别信息
var groupIds = input.GroupMembers?.Select(g => g.GroupId).ToList() ?? input.GroupIds ?? new List<long>();
var eventProjectGroups = await _eventProjectGroupRepository.GetListAsync(x => groupIds.Contains(x.Id));
// 获取项目信息
// ========== 并行查询所有独立数据源 ==========
var sysUserTask = _sysUserRepository.GetByIdAsync(userId);
var teamTask = input.TeamId.HasValue
? _db.Queryable<YD_Event.Core.Entities.Team>().FirstAsync(t => t.Id == input.TeamId.Value && !t.DeleteMark)
: Task.FromResult<YD_Event.Core.Entities.Team?>(null);
var membersTask = _userRepository.GetListAsync(x => allMemberIds.Contains(x.Id));
var eventProjectGroupsTask = _eventProjectGroupRepository.GetListAsync(x => groupIds.Contains(x.Id));
await Task.WhenAll(sysUserTask, teamTask, membersTask, eventProjectGroupsTask);
var sysUser = sysUserTask.Result;
if (sysUser == null) throw Oops.Bah("用户不存在");
string userName = sysUser.Name;
string userMobile = sysUser.Mobile ?? "";
var userTeam = teamTask.Result;
string teamName = userTeam?.Name ?? "临时团队";
var members = membersTask.Result;
var eventProjectGroups = eventProjectGroupsTask.Result;
// 获取项目信息(依赖 eventProjectGroups 的结果)
var eventProjectIds = eventProjectGroups.Select(epg => epg.EventProjectId).Distinct().ToList();
var eventProjects = await _eventProjectRepository.GetListAsync(x => eventProjectIds.Contains(x.Id));
@ -1125,7 +1123,11 @@ public class UserEventRecordService : IDynamicApiController, ITransient
unifiedInput.Items.Add(item);
}
// 调用统一的限制检查方法
return await _unifiedRegistrationService.CheckRegistrationLimitAsync(unifiedInput, input.ExcludeRegistrationId);
// 调用统一的限制检查方法(传递预查询数据,避免重复DB查询)
return await _unifiedRegistrationService.CheckRegistrationLimitAsync(
unifiedInput,
input.ExcludeRegistrationId,
preFetchedEventProjects: eventProjects,
preFetchedEventProjectGroups: eventProjectGroups);
}
}

View File

@ -1075,7 +1075,13 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient
validationMemberIds.Add(input.MemberId);
}
var members = await _userRepository.GetListAsync(x => validationMemberIds.Contains(x.Id));
// 并行查询:队员信息和组别信息是独立的
var membersTask = _userRepository.GetListAsync(x => validationMemberIds.Contains(x.Id));
var eventProjectGroupTask = _eventProjectGroupRepository.GetByIdAsync(input.GroupId);
await Task.WhenAll(membersTask, eventProjectGroupTask);
var members = membersTask.Result;
var member = members.FirstOrDefault(x => x.Id == input.MemberId);
if (member == null)
{
@ -1092,7 +1098,7 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient
return result;
}
var eventProjectGroup = await _eventProjectGroupRepository.GetByIdAsync(input.GroupId);
var eventProjectGroup = eventProjectGroupTask.Result;
if (eventProjectGroup != null)
{
// 获取项目类型信息
@ -1158,30 +1164,12 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient
{
var userId = _authManager.UserId;
// 获取当前用户信息
var sysUser = await _sysUserRepository.GetByIdAsync(userId);
if (sysUser == null) throw Oops.Bah("用户不存在");
string userName = sysUser.Name;
string userMobile = sysUser.Mobile ?? "";
// 获取团队信息 - 优先使用新结构的 TeamId
string teamName = "临时团队";
if (input.TeamId.HasValue)
{
var team = await _db.Queryable<YD_Event.Core.Entities.Team>().FirstAsync(t => t.Id == input.TeamId.Value && !t.DeleteMark);
if (team != null)
{
teamName = team.Name;
}
}
// 获取所有成员信息
// 收集所有成员ID和组别ID(纯CPU操作,无需DB)
var allMemberIds = new List<long>();
if (input.GroupMembers != null)
{
foreach (var gm in input.GroupMembers)
{
// 检查是否有多团队数据
if (gm.Teams != null && gm.Teams.Count > 0)
{
foreach (var team in gm.Teams)
@ -1191,27 +1179,37 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient
}
else
{
// 向后兼容单团队模式
allMemberIds.AddRange(gm.MemberIds ?? new List<long>());
}
}
}
else if (input.MemberIds != null)
{
// 向后兼容旧结构
allMemberIds.AddRange(input.MemberIds);
}
allMemberIds = allMemberIds.Distinct().ToList();
// 获取成员信息
var members = await _userRepository.GetListAsync(x => allMemberIds.Contains(x.Id));
// 获取组别信息
var groupIds = input.GroupMembers?.Select(g => g.GroupId).ToList() ?? input.GroupIds ?? new List<long>();
var eventProjectGroups = await _eventProjectGroupRepository.GetListAsync(x => groupIds.Contains(x.Id));
// 获取项目信息
// ========== 并行查询所有独立数据源 ==========
var sysUserTask = _sysUserRepository.GetByIdAsync(userId);
var teamTask = input.TeamId.HasValue
? _db.Queryable<YD_Event.Core.Entities.Team>().FirstAsync(t => t.Id == input.TeamId.Value && !t.DeleteMark)
: Task.FromResult<YD_Event.Core.Entities.Team?>(null);
var membersTask = _userRepository.GetListAsync(x => allMemberIds.Contains(x.Id));
var eventProjectGroupsTask = _eventProjectGroupRepository.GetListAsync(x => groupIds.Contains(x.Id));
await Task.WhenAll(sysUserTask, teamTask, membersTask, eventProjectGroupsTask);
var sysUser = sysUserTask.Result;
if (sysUser == null) throw Oops.Bah("用户不存在");
string userName = sysUser.Name;
string userMobile = sysUser.Mobile ?? "";
var userTeam = teamTask.Result;
string teamName = userTeam?.Name ?? "临时团队";
var members = membersTask.Result;
var eventProjectGroups = eventProjectGroupsTask.Result;
// 获取项目信息(依赖 eventProjectGroups 的结果)
var eventProjectIds = eventProjectGroups.Select(epg => epg.EventProjectId).Distinct().ToList();
var eventProjects = await _eventProjectRepository.GetListAsync(x => eventProjectIds.Contains(x.Id));
@ -1319,8 +1317,11 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient
}
}
// 调用统一报名服务检查限制
return await _unifiedRegistrationService.CheckRegistrationLimitAsync(unifiedInput);
// 调用统一报名服务检查限制(传递预查询数据,避免重复DB查询)
return await _unifiedRegistrationService.CheckRegistrationLimitAsync(
unifiedInput,
preFetchedEventProjects: eventProjects,
preFetchedEventProjectGroups: eventProjectGroups);
}
/// <summary>