From 3619b4b260c54146e29972044b5066aaccdd28dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E6=A2=93=E5=BD=AD?= Date: Mon, 8 Jun 2026 12:19:33 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=8A=A5=E5=90=8D=E5=90=8E?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=A1=B9=E7=9B=AE=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- YD_Event.Application/Event/EventService.cs | 511 ++++++++++++++++----- 1 file changed, 407 insertions(+), 104 deletions(-) diff --git a/YD_Event.Application/Event/EventService.cs b/YD_Event.Application/Event/EventService.cs index 86649a6..936b453 100644 --- a/YD_Event.Application/Event/EventService.cs +++ b/YD_Event.Application/Event/EventService.cs @@ -525,6 +525,16 @@ public class EventService : BaseService, ITransient var eventInfo = await _repository.GetByIdAsync(input.Id); if (eventInfo == null) throw new InvalidOperationException("赛事不存在"); + // 检查赛事状态:如果是报名状态,检查是否修改了项目和组别 + if (eventInfo.EventStatus == EventStatus.Enrolling) + { + var hasProjectOrGroupChange = await CheckIfProjectsOrGroupsChanged(input, eventInfo.Id); + if (hasProjectOrGroupChange) + { + throw Oops.Bah("当前赛事正在报名中,不允许修改项目信息"); + } + } + // 将前端传过来的Code转换为对应的Id var provinceId = eventInfo.ProvinceId; var cityId = eventInfo.CityId; @@ -585,75 +595,209 @@ public class EventService : BaseService, ITransient var projectFees = new List(); - // 3. 更新项目信息 - 使用软删避免丢失历史报名关联数据 - var oldEventProjects = await _eventProjectRepository.GetListAsync(x => x.EventId == input.Id && !x.DeleteMark); - var oldEventProjectIds = oldEventProjects.Select(x => x.Id).ToList(); - - if (oldEventProjectIds.Any()) + // 3. 更新项目信息 + if (eventInfo.EventStatus == EventStatus.Enrolling) { - // 软删旧的 EventProjectGroup(按框架模式:直接 UPDATE) - await _eventProjectGroupRepository.SoftDeleteAsync(x => oldEventProjectIds.Contains(x.EventProjectId)); + // 报名状态下,只允许修改项目价格和限报 + var oldEventProjects = await _eventProjectRepository.GetListAsync(x => x.EventId == input.Id && !x.DeleteMark); + var oldProjectDict = oldEventProjects.ToDictionary(x => x.ProjectId); - // 软删旧的 EventProjectRegistrationLimit - await _projectLimitRepository.SoftDeleteAsync(x => oldEventProjectIds.Contains(x.ProjectId)); - - // 软删旧的 EventProject - await _eventProjectRepository.SoftDeleteAsync(x => oldEventProjectIds.Contains(x.Id)); - } - - if (input.Projects != null && input.Projects.Any()) - { - foreach (var projInput in input.Projects) + if (input.Projects != null && input.Projects.Any()) { - var eventProject = new EventProject + foreach (var projInput in input.Projects) { - Id = _idGenerator.NewLong(), - EventId = eventInfo.Id, - ProjectId = projInput.ProjectId, - GenderType = projInput.GenderType, - Price = projInput.Fee, - CreatedUserId = _authManager.UserId, - CreatedTime = DateTime.Now - }; - await _eventProjectRepository.InsertAsync(eventProject); - - projectFees.Add(new ProjectFeeInput { ProjectId = eventProject.Id, Fee = projInput.Fee }); - - if (projInput.Groups != null && projInput.Groups.Any()) - { - var groups = projInput.Groups.Select(g => + if (oldProjectDict.ContainsKey(projInput.ProjectId)) { - var group = new EventProjectGroup + var eventProject = oldProjectDict[projInput.ProjectId]; + + // 只更新项目价格 + eventProject.Price = projInput.Fee; + eventProject.UpdatedTime = DateTime.Now; + await _eventProjectRepository.UpdateAsync(eventProject); + + projectFees.Add(new ProjectFeeInput { ProjectId = eventProject.Id, Fee = projInput.Fee }); + + // 更新项目限报 + var oldLimit = await _projectLimitRepository.GetFirstAsync(x => x.ProjectId == eventProject.Id && !x.DeleteMark); + + if (projInput.LimitCount.HasValue) + { + if (oldLimit != null) + { + oldLimit.LimitCount = projInput.LimitCount.Value; + oldLimit.UpdatedTime = DateTime.Now; + await _projectLimitRepository.UpdateAsync(oldLimit); + } + else + { + var projLimit = new EventProjectRegistrationLimit + { + Id = _idGenerator.NewLong(), + EventId = eventInfo.Id, + ProjectId = eventProject.Id, + LimitCount = projInput.LimitCount.Value, + CreatedUserId = _authManager.UserId, + CreatedTime = DateTime.Now + }; + await _projectLimitRepository.InsertAsync(projLimit); + } + } + else if (oldLimit != null) + { + await _projectLimitRepository.SoftDeleteAsync(x => x.Id == oldLimit.Id); + } + } + } + } + } + else + { + // 非报名状态下,全量更新项目信息 + var oldEventProjects = await _eventProjectRepository.GetListAsync(x => x.EventId == input.Id && !x.DeleteMark); + var oldProjectDict = oldEventProjects.ToDictionary(x => x.ProjectId); + var oldEventProjectIds = oldEventProjects.Select(x => x.Id).ToList(); + + if (input.Projects != null && input.Projects.Any()) + { + var newProjectIds = new List(); + + foreach (var projInput in input.Projects) + { + EventProject eventProject; + + if (oldProjectDict.ContainsKey(projInput.ProjectId)) + { + // 更新现有项目 + eventProject = oldProjectDict[projInput.ProjectId]; + eventProject.GenderType = projInput.GenderType; + eventProject.Price = projInput.Fee; + eventProject.UpdatedTime = DateTime.Now; + await _eventProjectRepository.UpdateAsync(eventProject); + newProjectIds.Add(eventProject.Id); + } + else + { + // 新增项目 + eventProject = new EventProject { Id = _idGenerator.NewLong(), EventId = eventInfo.Id, - EventProjectId = eventProject.Id, ProjectId = projInput.ProjectId, - ProjectGroupId = g.ProjectGroupId, - GroupName = g.GroupName ?? "", - BirthDateStart = g.BirthDateStart ?? DateTime.MinValue, - BirthDateEnd = g.BirthDateEnd ?? DateTime.MinValue, - Gender = g.Gender ?? Gender.All, + GenderType = projInput.GenderType, + Price = projInput.Fee, CreatedUserId = _authManager.UserId, CreatedTime = DateTime.Now }; - return group; - }).ToList(); - await _eventProjectGroupRepository.InsertRangeAsync(groups); + await _eventProjectRepository.InsertAsync(eventProject); + newProjectIds.Add(eventProject.Id); + } + + projectFees.Add(new ProjectFeeInput { ProjectId = eventProject.Id, Fee = projInput.Fee }); + + // 处理项目分组 + var oldGroups = await _eventProjectGroupRepository.GetListAsync(x => x.EventProjectId == eventProject.Id && !x.DeleteMark); + var oldGroupDict = oldGroups.ToDictionary(x => x.ProjectGroupId); + var newGroupIds = new List(); + + if (projInput.Groups != null && projInput.Groups.Any()) + { + foreach (var groupInput in projInput.Groups) + { + EventProjectGroup group; + + if (oldGroupDict.ContainsKey(groupInput.ProjectGroupId)) + { + // 更新现有分组 + group = oldGroupDict[groupInput.ProjectGroupId]; + group.GroupName = groupInput.GroupName ?? ""; + group.BirthDateStart = groupInput.BirthDateStart ?? DateTime.MinValue; + group.BirthDateEnd = groupInput.BirthDateEnd ?? DateTime.MinValue; + group.Gender = groupInput.Gender ?? Gender.All; + group.UpdatedTime = DateTime.Now; + await _eventProjectGroupRepository.UpdateAsync(group); + newGroupIds.Add(group.Id); + } + else + { + // 新增分组 + group = new EventProjectGroup + { + Id = _idGenerator.NewLong(), + EventId = eventInfo.Id, + EventProjectId = eventProject.Id, + ProjectId = projInput.ProjectId, + ProjectGroupId = groupInput.ProjectGroupId, + GroupName = groupInput.GroupName ?? "", + BirthDateStart = groupInput.BirthDateStart ?? DateTime.MinValue, + BirthDateEnd = groupInput.BirthDateEnd ?? DateTime.MinValue, + Gender = groupInput.Gender ?? Gender.All, + CreatedUserId = _authManager.UserId, + CreatedTime = DateTime.Now + }; + await _eventProjectGroupRepository.InsertAsync(group); + newGroupIds.Add(group.Id); + } + } + } + + // 软删除不再存在的分组 + var groupsToDelete = oldGroups.Where(g => !newGroupIds.Contains(g.Id)).Select(g => g.Id).ToList(); + if (groupsToDelete.Any()) + { + await _eventProjectGroupRepository.SoftDeleteAsync(x => groupsToDelete.Contains(x.Id)); + } + + // 处理项目限制 + var oldLimit = await _projectLimitRepository.GetFirstAsync(x => x.ProjectId == eventProject.Id && !x.DeleteMark); + + if (projInput.LimitCount.HasValue) + { + if (oldLimit != null) + { + // 更新现有限制 + oldLimit.LimitCount = projInput.LimitCount.Value; + oldLimit.UpdatedTime = DateTime.Now; + await _projectLimitRepository.UpdateAsync(oldLimit); + } + else + { + // 新增限制 + var projLimit = new EventProjectRegistrationLimit + { + Id = _idGenerator.NewLong(), + EventId = eventInfo.Id, + ProjectId = eventProject.Id, + LimitCount = projInput.LimitCount.Value, + CreatedUserId = _authManager.UserId, + CreatedTime = DateTime.Now + }; + await _projectLimitRepository.InsertAsync(projLimit); + } + } + else if (oldLimit != null) + { + // 删除限制 + await _projectLimitRepository.SoftDeleteAsync(x => x.Id == oldLimit.Id); + } } - if (projInput.LimitCount.HasValue) + // 软删除不再存在的项目 + var projectsToDelete = oldEventProjects.Where(ep => !newProjectIds.Contains(ep.Id)).Select(ep => ep.Id).ToList(); + if (projectsToDelete.Any()) { - var projLimit = new EventProjectRegistrationLimit - { - Id = _idGenerator.NewLong(), - EventId = eventInfo.Id, - ProjectId = eventProject.Id, - LimitCount = projInput.LimitCount.Value, - CreatedUserId = _authManager.UserId, - CreatedTime = DateTime.Now - }; - await _projectLimitRepository.InsertAsync(projLimit); + await _eventProjectGroupRepository.SoftDeleteAsync(x => projectsToDelete.Contains(x.EventProjectId)); + await _projectLimitRepository.SoftDeleteAsync(x => projectsToDelete.Contains(x.ProjectId)); + await _eventProjectRepository.SoftDeleteAsync(x => projectsToDelete.Contains(x.Id)); + } + } + else + { + // 删除所有项目 + if (oldEventProjectIds.Any()) + { + await _eventProjectGroupRepository.SoftDeleteAsync(x => oldEventProjectIds.Contains(x.EventProjectId)); + await _projectLimitRepository.SoftDeleteAsync(x => oldEventProjectIds.Contains(x.ProjectId)); + await _eventProjectRepository.SoftDeleteAsync(x => oldEventProjectIds.Contains(x.Id)); } } } @@ -689,6 +833,88 @@ public class EventService : BaseService, ITransient } } + /// + /// 检查项目或组别是否有变化 + /// + private async Task CheckIfProjectsOrGroupsChanged(UpdateEventInput input, long eventId) + { + var oldEventProjects = await _eventProjectRepository.GetListAsync(x => x.EventId == eventId && !x.DeleteMark); + + // 检查项目数量是否变化 + if ((input.Projects == null || !input.Projects.Any()) && oldEventProjects.Any()) + { + return true; // 删除了所有项目 + } + + if (input.Projects != null && input.Projects.Count() != oldEventProjects.Count) + { + return true; // 项目数量有变化 + } + + // 如果都有项目,继续比较每个项目 + if (input.Projects != null && input.Projects.Any()) + { + var oldProjectDict = oldEventProjects.ToDictionary(x => x.ProjectId); + + foreach (var inputProj in input.Projects) + { + // 检查是否有新的项目 + if (!oldProjectDict.ContainsKey(inputProj.ProjectId)) + { + return true; + } + + var oldProj = oldProjectDict[inputProj.ProjectId]; + + // 检查项目的基本信息是否变化 + if (oldProj.GenderType != inputProj.GenderType) + { + return true; + } + + // 检查组别是否变化 + var oldGroups = await _eventProjectGroupRepository.GetListAsync(x => x.EventProjectId == oldProj.Id && !x.DeleteMark); + + if ((inputProj.Groups == null || !inputProj.Groups.Any()) && oldGroups.Any()) + { + return true; // 删除了所有组别 + } + + if (inputProj.Groups != null && inputProj.Groups.Count() != oldGroups.Count) + { + return true; // 组别数量有变化 + } + + if (inputProj.Groups != null && inputProj.Groups.Any()) + { + var oldGroupDict = oldGroups.ToDictionary(x => x.ProjectGroupId); + + foreach (var inputGroup in inputProj.Groups) + { + // 检查是否有新的组别 + if (!oldGroupDict.ContainsKey(inputGroup.ProjectGroupId)) + { + return true; + } + + var oldGroup = oldGroupDict[inputGroup.ProjectGroupId]; + + // 检查组别的基本信息是否变化 + if (oldGroup.GroupName != inputGroup.GroupName || + oldGroup.BirthDateStart != (inputGroup.BirthDateStart ?? DateTime.MinValue) || + oldGroup.BirthDateEnd != (inputGroup.BirthDateEnd ?? DateTime.MinValue) || + oldGroup.Gender != (inputGroup.Gender ?? Gender.All)) + { + return true; + } + } + } + } + } + + return false; + } + /// /// 导出赛事 /// @@ -961,74 +1187,151 @@ public class EventService : BaseService, ITransient throw new InvalidOperationException("请先完成参与单位配置"); } - // 1. 更新项目信息 (全量替换) - 使用软删避免丢失历史报名关联数据 + // 1. 更新项目信息 - 优先修改现有数据,仅对新增数据执行添加操作 var oldEventProjects = await _eventProjectRepository.GetListAsync(x => x.EventId == input.EventId && !x.DeleteMark); + var oldProjectDict = oldEventProjects.ToDictionary(x => x.ProjectId); var oldEventProjectIds = oldEventProjects.Select(x => x.Id).ToList(); - if (oldEventProjectIds.Any()) - { - // 软删旧的 EventProjectGroup(按框架模式:直接 UPDATE) - await _eventProjectGroupRepository.SoftDeleteAsync(x => oldEventProjectIds.Contains(x.EventProjectId)); - - // 软删旧的 EventProjectRegistrationLimit - await _projectLimitRepository.SoftDeleteAsync(x => oldEventProjectIds.Contains(x.ProjectId)); - - // 软删旧的 EventProject - await _eventProjectRepository.SoftDeleteAsync(x => oldEventProjectIds.Contains(x.Id)); - } - + // 处理输入的项目 if (input.Projects != null && input.Projects.Any()) { + var newProjectIds = new List(); + foreach (var projInput in input.Projects) { - var eventProject = new EventProject - { - Id = _idGenerator.NewLong(), - EventId = input.EventId, - ProjectId = projInput.ProjectId, - GenderType = projInput.GenderType, - Price = projInput.Fee, - CreatedUserId = _authManager.UserId, - CreatedTime = DateTime.Now - }; - await _eventProjectRepository.InsertAsync(eventProject); + EventProject eventProject; - if (projInput.Groups != null && projInput.Groups.Any()) + if (oldProjectDict.ContainsKey(projInput.ProjectId)) { - var groups = projInput.Groups.Select(g => - { - var group = new EventProjectGroup - { - Id = _idGenerator.NewLong(), - EventId = input.EventId, - EventProjectId = eventProject.Id, - ProjectId = projInput.ProjectId, - ProjectGroupId = g.ProjectGroupId, - GroupName = g.GroupName ?? "", - BirthDateStart = g.BirthDateStart ?? DateTime.MinValue, - BirthDateEnd = g.BirthDateEnd ?? DateTime.MinValue, - Gender = g.Gender ?? Gender.All, - CreatedUserId = _authManager.UserId, - CreatedTime = DateTime.Now - }; - return group; - }).ToList(); - await _eventProjectGroupRepository.InsertRangeAsync(groups); + // 更新现有项目 + eventProject = oldProjectDict[projInput.ProjectId]; + eventProject.GenderType = projInput.GenderType; + eventProject.Price = projInput.Fee; + eventProject.UpdatedTime = DateTime.Now; + await _eventProjectRepository.UpdateAsync(eventProject); + newProjectIds.Add(eventProject.Id); } - - if (projInput.LimitCount.HasValue) + else { - var projLimit = new EventProjectRegistrationLimit + // 新增项目 + eventProject = new EventProject { Id = _idGenerator.NewLong(), EventId = input.EventId, - ProjectId = eventProject.Id, - LimitCount = projInput.LimitCount.Value, + ProjectId = projInput.ProjectId, + GenderType = projInput.GenderType, + Price = projInput.Fee, CreatedUserId = _authManager.UserId, CreatedTime = DateTime.Now }; - await _projectLimitRepository.InsertAsync(projLimit); + await _eventProjectRepository.InsertAsync(eventProject); + newProjectIds.Add(eventProject.Id); } + + // 处理项目分组 + var oldGroups = await _eventProjectGroupRepository.GetListAsync(x => x.EventProjectId == eventProject.Id && !x.DeleteMark); + var oldGroupDict = oldGroups.ToDictionary(x => x.ProjectGroupId); + var newGroupIds = new List(); + + if (projInput.Groups != null && projInput.Groups.Any()) + { + foreach (var groupInput in projInput.Groups) + { + EventProjectGroup group; + + if (oldGroupDict.ContainsKey(groupInput.ProjectGroupId)) + { + // 更新现有分组 + group = oldGroupDict[groupInput.ProjectGroupId]; + group.GroupName = groupInput.GroupName ?? ""; + group.BirthDateStart = groupInput.BirthDateStart ?? DateTime.MinValue; + group.BirthDateEnd = groupInput.BirthDateEnd ?? DateTime.MinValue; + group.Gender = groupInput.Gender ?? Gender.All; + group.UpdatedTime = DateTime.Now; + await _eventProjectGroupRepository.UpdateAsync(group); + newGroupIds.Add(group.Id); + } + else + { + // 新增分组 + group = new EventProjectGroup + { + Id = _idGenerator.NewLong(), + EventId = input.EventId, + EventProjectId = eventProject.Id, + ProjectId = projInput.ProjectId, + ProjectGroupId = groupInput.ProjectGroupId, + GroupName = groupInput.GroupName ?? "", + BirthDateStart = groupInput.BirthDateStart ?? DateTime.MinValue, + BirthDateEnd = groupInput.BirthDateEnd ?? DateTime.MinValue, + Gender = groupInput.Gender ?? Gender.All, + CreatedUserId = _authManager.UserId, + CreatedTime = DateTime.Now + }; + await _eventProjectGroupRepository.InsertAsync(group); + newGroupIds.Add(group.Id); + } + } + } + + // 软删除不再存在的分组 + var groupsToDelete = oldGroups.Where(g => !newGroupIds.Contains(g.Id)).Select(g => g.Id).ToList(); + if (groupsToDelete.Any()) + { + await _eventProjectGroupRepository.SoftDeleteAsync(x => groupsToDelete.Contains(x.Id)); + } + + // 处理项目限制 + var oldLimit = await _projectLimitRepository.GetFirstAsync(x => x.ProjectId == eventProject.Id && !x.DeleteMark); + + if (projInput.LimitCount.HasValue) + { + if (oldLimit != null) + { + // 更新现有限制 + oldLimit.LimitCount = projInput.LimitCount.Value; + oldLimit.UpdatedTime = DateTime.Now; + await _projectLimitRepository.UpdateAsync(oldLimit); + } + else + { + // 新增限制 + var projLimit = new EventProjectRegistrationLimit + { + Id = _idGenerator.NewLong(), + EventId = input.EventId, + ProjectId = eventProject.Id, + LimitCount = projInput.LimitCount.Value, + CreatedUserId = _authManager.UserId, + CreatedTime = DateTime.Now + }; + await _projectLimitRepository.InsertAsync(projLimit); + } + } + else if (oldLimit != null) + { + // 删除限制 + await _projectLimitRepository.SoftDeleteAsync(x => x.Id == oldLimit.Id); + } + } + + // 软删除不再存在的项目 + var projectsToDelete = oldEventProjects.Where(ep => !newProjectIds.Contains(ep.Id)).Select(ep => ep.Id).ToList(); + if (projectsToDelete.Any()) + { + await _eventProjectGroupRepository.SoftDeleteAsync(x => projectsToDelete.Contains(x.EventProjectId)); + await _projectLimitRepository.SoftDeleteAsync(x => projectsToDelete.Contains(x.ProjectId)); + await _eventProjectRepository.SoftDeleteAsync(x => projectsToDelete.Contains(x.Id)); + } + } + else + { + // 删除所有项目 + if (oldEventProjectIds.Any()) + { + await _eventProjectGroupRepository.SoftDeleteAsync(x => oldEventProjectIds.Contains(x.EventProjectId)); + await _projectLimitRepository.SoftDeleteAsync(x => oldEventProjectIds.Contains(x.ProjectId)); + await _eventProjectRepository.SoftDeleteAsync(x => oldEventProjectIds.Contains(x.Id)); } }