diff --git a/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs index 11ab31092..051cce253 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/EFSetup.cs @@ -75,12 +75,9 @@ namespace IRaCIS.Core.API options.UseTriggers(triggerOptions => { - triggerOptions.AddTrigger(); - triggerOptions.AddTrigger(); - triggerOptions.AddTrigger(); - triggerOptions.AddTrigger(); - triggerOptions.AddTrigger(); - triggerOptions.AddTrigger(); + triggerOptions.AddTrigger(); + triggerOptions.AddTrigger(); + triggerOptions.AddTrigger(); triggerOptions.AddTrigger(); triggerOptions.AddTrigger(); triggerOptions.AddTrigger(); diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 1a320e129..71f0abd1a 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -16097,32 +16097,19 @@ - + - + 访视 质疑状态 触发修改 + + - + - + 访视 质疑状态 触发修改 - - - - 处理 访视 末次评估 会影响Subject 状态 - - - - - 处理 访视 末次评估 会影响Subject 状态 - - - - - 处理生成阅片期 以及后续访视状态 - - - + + @@ -16134,26 +16121,6 @@ 维护 IsFrontTaskNeedSignButNotSign 字段 另外附加评估结果 - - - 添加访视计划 要给改项目下的所有Subject 添加该访视 - - - - - 添加访视计划 要给改项目下的所有Subject 添加该访视 - - - - - 处理 访视 末次评估 会影响Subject 状态 - - - - - 处理 访视 末次评估 会影响Subject 状态 - - 因为可能先一致性核查通过,生成其他标准的任务了,新签名的标准也需要产生任务 @@ -16185,6 +16152,25 @@ + + + 添加访视计划 要给改项目下的所有Subject 添加该访视 + + + + + 添加访视计划 要给改项目下的所有Subject 添加该访视 + + + + + 手动设置出组状态 + + + + + + 处理 访视 1、提交状态 2、执行状态 3、最早最晚 拍片日期 @@ -16209,6 +16195,33 @@ + + + 访视保存后: 末次访视设置和取消触发 Subject状态,以后后续访视状态的修改,以及自动生成阅片期和任务 + 访视保存前:一致性核查通过,生成任务 + + + + + 访视保存后: 末次访视设置和取消触发 Subject状态,以后后续访视状态的修改,以及自动生成阅片期和任务 + 访视保存前:一致性核查通过,生成任务 + + + + + 处理生成阅片期 以及后续访视状态 + + + + + + + 验证末次访视 + + + + + Id(阅片期Id 或者 访视ID) diff --git a/IRaCIS.Core.Application/Triggers/AfterSaveTrigger/AddCRCCliniaclDataTrigger.cs b/IRaCIS.Core.Application/Triggers/AfterSaveTrigger/AddCRCCliniaclDataTrigger.cs deleted file mode 100644 index c726a6d2f..000000000 --- a/IRaCIS.Core.Application/Triggers/AfterSaveTrigger/AddCRCCliniaclDataTrigger.cs +++ /dev/null @@ -1,26 +0,0 @@ -using EntityFrameworkCore.Triggered; -using IRaCIS.Core.Application.Service.Reading.Interface; - -namespace IRaCIS.Core.Application.Triggers -{ - public class AddCRCCliniaclDataTrigger( - IRepository _subjectVisitRepository, - IClinicalAnswerService _iClinicalAnswerService) : IAfterSaveTrigger - { - - - //注意删除不能用扩展方法,必须用EF跟踪的实体 否则不能取到 SubjectVisitId - public async Task AfterSave(ITriggerContext context, CancellationToken cancellationToken) - { - var subjectVisit = context.Entity; - - await _iClinicalAnswerService.AutoAddCRCClinical(new Service.Reading.Dto.AutoAddClinicalInDto() - { - TrialId = subjectVisit.TrialId, - SubjectId = subjectVisit.SubjectId, - - }); - } - - } -} diff --git a/IRaCIS.Core.Application/Triggers/AfterSaveTrigger/ChallengeStateTrigger.cs b/IRaCIS.Core.Application/Triggers/AfterSaveTrigger/ChallengeStateTrigger.cs index ab7324d88..a582e4a84 100644 --- a/IRaCIS.Core.Application/Triggers/AfterSaveTrigger/ChallengeStateTrigger.cs +++ b/IRaCIS.Core.Application/Triggers/AfterSaveTrigger/ChallengeStateTrigger.cs @@ -4,7 +4,11 @@ using IRaCIS.Core.Domain.Share; namespace IRaCIS.Core.Application.Triggers { - //访视 质疑状态 触发修改 + /// + /// 访视 质疑状态 触发修改 + /// + /// + /// public class ChallengeStateTrigger(IRepository _qcChallengeRepository, IRepository _subjectVisitRepository) : IAfterSaveTrigger { diff --git a/IRaCIS.Core.Application/Triggers/BeforeSaveTrigger/AddSubjectTrigger.cs b/IRaCIS.Core.Application/Triggers/BeforeSaveTrigger/AddSubjectTrigger.cs deleted file mode 100644 index d9b4cd2dd..000000000 --- a/IRaCIS.Core.Application/Triggers/BeforeSaveTrigger/AddSubjectTrigger.cs +++ /dev/null @@ -1,59 +0,0 @@ -using AutoMapper; -using EntityFrameworkCore.Triggered; -using MassTransit; - -namespace IRaCIS.Core.Application.Triggers -{ - /// - /// 添加访视计划 要给改项目下的所有Subject 添加该访视 - /// - public class AddSubjectTrigger( - IRepository _subjectVisitRepository, - IRepository _visitStageRepository, - IRepository _trialRepository, - IMapper _mapper) : IBeforeSaveTrigger - { - - - public async Task BeforeSave(ITriggerContext context, CancellationToken cancellationToken) - { - var subject = context.Entity; - - if (context.ChangeType == ChangeType.Added) - { - - - - //添加受试者的时候,获取访视计划列表,添加到受试者访视表。 - var visitPlanList = await _visitStageRepository.Where(t => t.TrialId == subject.TrialId && t.IsConfirmed).ToListAsync(); - - var svList = _mapper.Map>(visitPlanList); - - var IsEnrollementQualificationConfirm = await _trialRepository.Where(t => t.Id == subject.TrialId).Select(u => u.IsEnrollementQualificationConfirm).FirstOrDefaultAsync(); - - - - - - svList.ForEach(t => - { - t.Subject = subject; - t.SubjectId = subject.Id; - t.TrialId = subject.TrialId; - t.TrialSiteId = subject.TrialSiteId; - t.IsEnrollmentConfirm = t.IsBaseLine ? IsEnrollementQualificationConfirm : false; - t.Id = NewId.NextGuid(); - - }); - - - await _subjectVisitRepository.AddRangeAsync(svList); - - await _subjectVisitRepository.SaveChangesAsync(); - - - - } - } - } -} \ No newline at end of file diff --git a/IRaCIS.Core.Application/Triggers/BeforeSaveTrigger/SubjectVisitCheckPassedTrigger.cs b/IRaCIS.Core.Application/Triggers/BeforeSaveTrigger/SubjectVisitCheckPassedTrigger.cs deleted file mode 100644 index 075fabb41..000000000 --- a/IRaCIS.Core.Application/Triggers/BeforeSaveTrigger/SubjectVisitCheckPassedTrigger.cs +++ /dev/null @@ -1,67 +0,0 @@ -using EntityFrameworkCore.Triggered; -using IRaCIS.Core.Application.Interfaces; -using IRaCIS.Core.Domain.Share; - -namespace IRaCIS.Core.Application.Triggers -{ - /// - /// 处理 访视 末次评估 会影响Subject 状态 - /// - public class SubjectVisitCheckPassedTrigger( - IVisitTaskHelpeService _visitTaskHelpeService, - IRepository _subjectRepository, - IRepository _trialReadingCriterionRepository, - ISubjectCriteriaEvaluationService _subjectCriteriaEvaluationService, - IRepository _subjectCriteriaEvaluationRepository) : IBeforeSaveTrigger - { - - - public async Task BeforeSave(ITriggerContext context, CancellationToken cancellationToken) - { - var subjectVisit = context.Entity; - - - if (context.ChangeType == ChangeType.Modified) - { - - // 一致性核查通过 生成读片任务 - if (context.UnmodifiedEntity?.CheckState != subjectVisit.CheckState && subjectVisit.CheckState == CheckStateEnum.CVPassed) - { - //退回或者重阅的任务一致性核查通过了 此时设置Subject 重阅影响状态 - if (context.Entity.IsPMBackOrReReading == true) - { - await _subjectRepository.UpdatePartialFromQueryAsync(context.Entity.SubjectId, u => new Subject() { IsReReadingOrBackInfluenceAnalysis = false }); - } - - context.Entity.IsPMBackOrReReading = false; - - //找到手动生成任务的标准 - var criterionList = await _trialReadingCriterionRepository.Where(t => t.IsAutoCreate == false && t.IsSigned == true).Select(t => new { t.Id, t.TrialId, t.IsReadingTaskViewInOrder }).ToListAsync(); - - foreach (var criterion in criterionList) - { - //if(!await _SubjectCriteriaEvaluationVisitFilterRepository.AnyAsync(t=>t.SubjectId==subjectVisit.SubjectId&& t.SubjectVisitId==subjectVisit.Id && t.TrialReadingCriterionId == criterion.Id)) - //{ - // await _SubjectCriteriaEvaluationVisitFilterRepository.AddAsync(new SubjectCriteriaEvaluationVisitFilter() { SubjectId = subjectVisit.SubjectId, SubjectVisitId = subjectVisit.Id, TrialReadingCriterionId = criterion.Id }); - //} - - //如果参与评估,那么久对当前访视进行自动筛选 - if (await _subjectCriteriaEvaluationRepository.AnyAsync(t => t.SubjectId == subjectVisit.SubjectId && t.TrialReadingCriterionId == criterion.Id && t.IsJoinEvaluation)) - { - await _subjectCriteriaEvaluationService.AutoSubjectCriteriaEvaluationVisitFilter(subjectVisit.SubjectId, subjectVisit.Id, criterion.Id); - - } - - - - - } - - await _visitTaskHelpeService.GenerateVisitTaskAsync(subjectVisit.TrialId, new List() { subjectVisit.Id }, true); - - } - - } - } - } -} \ No newline at end of file diff --git a/IRaCIS.Core.Application/Triggers/AfterSaveTrigger/SubjectStateTrigger.cs b/IRaCIS.Core.Application/Triggers/SubjectTrigger.cs similarity index 63% rename from IRaCIS.Core.Application/Triggers/AfterSaveTrigger/SubjectStateTrigger.cs rename to IRaCIS.Core.Application/Triggers/SubjectTrigger.cs index cfc46e118..37e338a1c 100644 --- a/IRaCIS.Core.Application/Triggers/AfterSaveTrigger/SubjectStateTrigger.cs +++ b/IRaCIS.Core.Application/Triggers/SubjectTrigger.cs @@ -1,28 +1,36 @@ -using EntityFrameworkCore.Triggered; +using AutoMapper; +using EntityFrameworkCore.Triggered; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infrastructure; +using MassTransit; using Microsoft.Extensions.Localization; namespace IRaCIS.Core.Application.Triggers { /// - /// + /// 添加访视计划 要给改项目下的所有Subject 添加该访视 /// - public class SubjectStateTrigger( - IStringLocalizer _localizer, - IRepository _subjectVisitRepository) : IAfterSaveTrigger + public class SubjectTrigger( + IStringLocalizer _localizer, + IRepository _subjectVisitRepository, + IRepository _visitStageRepository, + IRepository _trialRepository, + IMapper _mapper) : IBeforeSaveTrigger, IAfterSaveTrigger { - - + /// + /// 手动设置出组状态 + /// + /// + /// + /// + /// public async Task AfterSave(ITriggerContext context, CancellationToken cancellationToken) { - - var dbSubject = context.Entity; - if (context.ChangeType == ChangeType.Modified) { - //Site变更 + var dbSubject = context.Entity; + //Site变更 if (context.Entity.TrialSiteId != context.UnmodifiedEntity?.TrialSiteId) { var subjectId = context.Entity.Id; @@ -31,8 +39,6 @@ namespace IRaCIS.Core.Application.Triggers await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == subjectId, u => new SubjectVisit() { TrialSiteId = trialSiteId }); - - #region 废弃 ////如果访视结束了 需要删除计划外未执行的访视 //if (mapedSubject.Status == SubjectStatus.EndOfVisit) @@ -81,11 +87,40 @@ namespace IRaCIS.Core.Application.Triggers } } + } + } + public async Task BeforeSave(ITriggerContext context, CancellationToken cancellationToken) + { + var subject = context.Entity; + + if (context.ChangeType == ChangeType.Added) + { + + //添加受试者的时候,获取访视计划列表,添加到受试者访视表。 + var visitPlanList = await _visitStageRepository.Where(t => t.TrialId == subject.TrialId && t.IsConfirmed).ToListAsync(); + + var svList = _mapper.Map>(visitPlanList); + + var IsEnrollementQualificationConfirm = await _trialRepository.Where(t => t.Id == subject.TrialId).Select(u => u.IsEnrollementQualificationConfirm).FirstOrDefaultAsync(); + + svList.ForEach(t => + { + t.Subject = subject; + t.SubjectId = subject.Id; + t.TrialId = subject.TrialId; + t.TrialSiteId = subject.TrialSiteId; + t.IsEnrollmentConfirm = t.IsBaseLine ? IsEnrollementQualificationConfirm : false; + t.Id = NewId.NextGuid(); + + }); + + await _subjectVisitRepository.AddRangeAsync(svList); + + await _subjectVisitRepository.SaveChangesAsync(); } - } } -} +} \ No newline at end of file diff --git a/IRaCIS.Core.Application/Triggers/AfterSaveTrigger/SubjectVisitFinalVisitTrigger.cs b/IRaCIS.Core.Application/Triggers/SubjectVisitTrigger.cs similarity index 61% rename from IRaCIS.Core.Application/Triggers/AfterSaveTrigger/SubjectVisitFinalVisitTrigger.cs rename to IRaCIS.Core.Application/Triggers/SubjectVisitTrigger.cs index b12e1a32d..0fa6ff6c9 100644 --- a/IRaCIS.Core.Application/Triggers/AfterSaveTrigger/SubjectVisitFinalVisitTrigger.cs +++ b/IRaCIS.Core.Application/Triggers/SubjectVisitTrigger.cs @@ -1,4 +1,6 @@ using EntityFrameworkCore.Triggered; +using IRaCIS.Core.Application.Interfaces; +using IRaCIS.Core.Application.Service.Reading.Interface; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infrastructure; @@ -8,18 +10,23 @@ using Microsoft.Extensions.Localization; namespace IRaCIS.Core.Application.Triggers { /// - /// 处理 访视 末次评估 会影响Subject 状态 + /// 访视保存后: 末次访视设置和取消触发 Subject状态,以后后续访视状态的修改,以及自动生成阅片期和任务 + /// 访视保存前:一致性核查通过,生成任务 /// - public class SubjectVisitFinalVisitTrigger( + public class SubjectVisitTrigger( IRepository _subjectVisitRepository, IRepository _readModuleRepository, IRepository _subjectRepository, IRepository _visitTaskRepository, - IVisitTaskHelpeService _ivisitTaskHelpeService, IStringLocalizer _localizer, IRepository _trialRepository, - IRepository _readingQuestionCriterionTrialRepository - ) : IAfterSaveTrigger + IRepository _readingQuestionCriterionTrialRepository, + IClinicalAnswerService _iClinicalAnswerService, + IRepository _trialReadingCriterionRepository, + ISubjectCriteriaEvaluationService _subjectCriteriaEvaluationService, + IRepository _subjectCriteriaEvaluationRepository, + IVisitTaskHelpeService _visitTaskHelpeService + ) : IAfterSaveTrigger, IBeforeSaveTrigger { @@ -40,28 +47,78 @@ namespace IRaCIS.Core.Application.Triggers await VerifyDealFinalVisitAsync(subjectVisit); await DealGenerateReadModuleAndSubjectVisit(subjectVisit); - - } else { //回退 - await _subjectRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisit.SubjectId, u => new Subject() { Status = SubjectStatus.OnVisit, FinalSubjectVisitId = null }); await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == subjectVisit.SubjectId && t.VisitExecuted == VisitExecutedEnum.Unavailable, u => new SubjectVisit() { VisitExecuted = VisitExecutedEnum.UnExecuted }); - - } } } - else if (context.ChangeType == ChangeType.Added && subjectVisit.IsFinalVisit) + else if (context.ChangeType == ChangeType.Added) { - await VerifyDealFinalVisitAsync(subjectVisit); - await DealGenerateReadModuleAndSubjectVisit(subjectVisit); + if (subjectVisit.IsFinalVisit) + { + await VerifyDealFinalVisitAsync(subjectVisit); + + await DealGenerateReadModuleAndSubjectVisit(subjectVisit); + } + + //访视添加后 自动处理临床数据 移动 + await _iClinicalAnswerService.AutoAddCRCClinical(new Service.Reading.Dto.AutoAddClinicalInDto() + { + TrialId = subjectVisit.TrialId, + SubjectId = subjectVisit.SubjectId, + + }); + } + } + + public async Task BeforeSave(ITriggerContext context, CancellationToken cancellationToken) + { + var subjectVisit = context.Entity; + + if (context.ChangeType == ChangeType.Modified) + { + + // 一致性核查通过 生成读片任务 + if (context.UnmodifiedEntity?.CheckState != subjectVisit.CheckState && subjectVisit.CheckState == CheckStateEnum.CVPassed) + { + //退回或者重阅的任务一致性核查通过了 此时设置Subject 重阅影响状态 + if (context.Entity.IsPMBackOrReReading == true) + { + await _subjectRepository.UpdatePartialFromQueryAsync(context.Entity.SubjectId, u => new Subject() { IsReReadingOrBackInfluenceAnalysis = false }); + } + + context.Entity.IsPMBackOrReReading = false; + + //找到手动生成任务的标准 + var criterionList = await _trialReadingCriterionRepository.Where(t => t.IsAutoCreate == false && t.IsSigned == true).Select(t => new { t.Id, t.TrialId, t.IsReadingTaskViewInOrder }).ToListAsync(); + + foreach (var criterion in criterionList) + { + //if(!await _SubjectCriteriaEvaluationVisitFilterRepository.AnyAsync(t=>t.SubjectId==subjectVisit.SubjectId&& t.SubjectVisitId==subjectVisit.Id && t.TrialReadingCriterionId == criterion.Id)) + //{ + // await _SubjectCriteriaEvaluationVisitFilterRepository.AddAsync(new SubjectCriteriaEvaluationVisitFilter() { SubjectId = subjectVisit.SubjectId, SubjectVisitId = subjectVisit.Id, TrialReadingCriterionId = criterion.Id }); + //} + + //如果参与评估,那么久对当前访视进行自动筛选 + if (await _subjectCriteriaEvaluationRepository.AnyAsync(t => t.SubjectId == subjectVisit.SubjectId && t.TrialReadingCriterionId == criterion.Id && t.IsJoinEvaluation)) + { + await _subjectCriteriaEvaluationService.AutoSubjectCriteriaEvaluationVisitFilter(subjectVisit.SubjectId, subjectVisit.Id, criterion.Id); + + } + } + + await _visitTaskHelpeService.GenerateVisitTaskAsync(subjectVisit.TrialId, new List() { subjectVisit.Id }, true); + + } + } } @@ -102,7 +159,6 @@ namespace IRaCIS.Core.Application.Triggers var readModule = await _readModuleRepository.Where(x => x.ReadingSetType == ReadingSetType.ImageReading && x.TrialReadingCriterionId == item.Id && x.SubjectVisitId == subjectVisitId).FirstOrDefaultAsync(); if (readModule == null) - { ReadModule newReadModule = new ReadModule() @@ -128,7 +184,7 @@ namespace IRaCIS.Core.Application.Triggers foreach (var visitTask in visitTaskList) { - await _ivisitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand() + await _visitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand() { OriginalVisitId = visitTask.Id, ReadingCategory = GenerateTaskCategory.Global, @@ -158,6 +214,12 @@ namespace IRaCIS.Core.Application.Triggers #endregion } + /// + /// 验证末次访视 + /// + /// + /// + /// private async Task VerifyDealFinalVisitAsync(SubjectVisit subjectVisit) { if (await _subjectVisitRepository.AnyAsync(t => t.SubjectId == subjectVisit.SubjectId && t.VisitNum > subjectVisit.VisitNum &&