diff --git a/IRaCIS.Core.API/appsettings.json b/IRaCIS.Core.API/appsettings.json index c200d0770..01dee3b14 100644 --- a/IRaCIS.Core.API/appsettings.json +++ b/IRaCIS.Core.API/appsettings.json @@ -82,7 +82,9 @@ "DefaultInternalOrganizationName": "ExtImaging", - "ImageShareExpireDays": 10 + "ImageShareExpireDays": 10, + + "BlindTaskPrefix": "Follow Up " } //网站根地址,为了访问文件 dicom 和上传的文档... 实测发现不用将域名拼接返回,浏览器会自动加上当前ip,避免了多环境读取环境配置文件 diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 3ea518222..8b88d2ac5 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -4211,6 +4211,11 @@ 序号标记 + + + 自定义计算标记 + + 系统标准Id diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs index 15914d14c..57f0011bc 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs @@ -41,10 +41,10 @@ namespace IRaCIS.Core.Application.Service public VisitTaskHelpeService(IRepository visitTaskRepository, IRepository subjectUserRepository, IRepository trialRepository, IEasyCachingProvider provider, - IRepository subjectVisitRepository, + IRepository subjectVisitRepository, IRepository readModuleRepository, IRepository readingJudgeInfoRepository, - IRepository taskAllocationRuleRepository, IMapper mapper, IUserInfo userInfo, IRepository visitTaskReReadingRepository, IRepository trialReadingCriterionRepository) + IRepository taskAllocationRuleRepository, IMapper mapper, IUserInfo userInfo, IRepository visitTaskReReadingRepository, IRepository trialReadingCriterionRepository) { _visitTaskRepository = visitTaskRepository; _trialRepository = trialRepository; @@ -79,10 +79,10 @@ namespace IRaCIS.Core.Application.Service } - + //基于标准签名 产生任务 public async Task BaseCritrionGenerateVisitTask(Guid trialId, Guid confirmedTrialReadingCriterionId) { - + //找到一致性核查通过且没有产生任务的访视 var needGenerateVisit = await _subjectVisitRepository.Where(t => t.TrialId == trialId && t.CheckState == CheckStateEnum.CVPassed && !t.VisitTaskList.Any(u=>u.TrialReadingCriterionId== confirmedTrialReadingCriterionId &&u.SourceSubjectVisitId==t.Id)).ToListAsync(); @@ -97,127 +97,147 @@ namespace IRaCIS.Core.Application.Service int currentMaxCodeInt = cacheMaxCodeInt > dbMaxCode ? cacheMaxCodeInt : dbMaxCode; - foreach (var subjectVisit in needGenerateVisit) + + foreach (var subjectGroup in needGenerateVisit.GroupBy(t=>t.SubjectId).Select(g=> new { SubjectId= g.Key, SubjectVisitList= g.ToList() })) { - var assignConfigList = await _subjectUserRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.OrignalSubjectUserId == null && t.IsConfirmed).Select(u => new { u.DoctorUserId, u.ArmEnum }).ToListAsync(); + var assignConfigList = await _subjectUserRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectGroup.SubjectId && t.OrignalSubjectUserId == null && t.IsConfirmed).Select(u => new { u.DoctorUserId, u.ArmEnum }).ToListAsync(); - if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Double) + + var visitNumList = _subjectVisitRepository.Where(t => t.SubjectId == subjectGroup.SubjectId).Select(t=>t.VisitNum).ToList(); + + foreach (var subjectVisit in subjectGroup.SubjectVisitList) { - //每个访视 根据项目配置生成任务 双审生成两个 - var task1 = await _visitTaskRepository.AddAsync(new VisitTask() + var blindTaskName = string.Empty; + + if (trialReadingCriterionConfig.IsReadingTaskViewInOrder) { - TrialId = trialId, - SubjectId = subjectVisit.SubjectId, - IsUrgent = subjectVisit.IsUrgent, - TaskBlindName = subjectVisit.BlindName, - TaskName = subjectVisit.VisitName, - VisitTaskNum = subjectVisit.VisitNum, - //CheckPassedTime = subjectVisit.CheckPassedTime, - ArmEnum = Arm.DoubleReadingArm1,//特殊 - Code = currentMaxCodeInt + 1, - SourceSubjectVisitId = subjectVisit.Id, - TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), - ReadingCategory = ReadingCategory.Visit, - - TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId - }); - - var task2 = await _visitTaskRepository.AddAsync(new VisitTask() + blindTaskName = AppSettings.BlindTaskPrefix + visitNumList.IndexOf(subjectVisit.VisitNum); + } + else { - TrialId = trialId, - SubjectId = subjectVisit.SubjectId, - IsUrgent = subjectVisit.IsUrgent, - TaskBlindName = subjectVisit.BlindName, - TaskName = subjectVisit.VisitName, - VisitTaskNum = subjectVisit.VisitNum, - //CheckPassedTime = subjectVisit.CheckPassedTime, - ArmEnum = Arm.DoubleReadingArm2,//特殊 - Code = currentMaxCodeInt + 2, - SourceSubjectVisitId = subjectVisit.Id, - TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 2, nameof(VisitTask)), - ReadingCategory = ReadingCategory.Visit, - - TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId - }); - - currentMaxCodeInt = currentMaxCodeInt + 2; - - _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); - - - - - var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; - - if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1)) - { - task1.TaskAllocationState = defaultState; - //分配给对应Arm的人 - task1.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm1).DoctorUserId; - task1.AllocateTime = DateTime.Now; - - task1.SuggesteFinishedTime = DateTime.Now.AddDays(7); + blindTaskName = AppSettings.BlindTaskPrefix; } - if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2)) + if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Double) { - task2.TaskAllocationState = defaultState; - task2.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm2).DoctorUserId; - task2.AllocateTime = DateTime.Now; - task2.SuggesteFinishedTime = DateTime.Now.AddDays(7); + //每个访视 根据项目配置生成任务 双审生成两个 + var task1 = await _visitTaskRepository.AddAsync(new VisitTask() + { + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + IsUrgent = subjectVisit.IsUrgent, + TaskBlindName = blindTaskName, + TaskName = subjectVisit.VisitName, + VisitTaskNum = subjectVisit.VisitNum, + //CheckPassedTime = subjectVisit.CheckPassedTime, + ArmEnum = Arm.DoubleReadingArm1,//特殊 + Code = currentMaxCodeInt + 1, + SourceSubjectVisitId = subjectVisit.Id, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, + + TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId + }); + + var task2 = await _visitTaskRepository.AddAsync(new VisitTask() + { + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + IsUrgent = subjectVisit.IsUrgent, + TaskBlindName = blindTaskName, + TaskName = subjectVisit.VisitName, + VisitTaskNum = subjectVisit.VisitNum, + //CheckPassedTime = subjectVisit.CheckPassedTime, + ArmEnum = Arm.DoubleReadingArm2,//特殊 + Code = currentMaxCodeInt + 2, + SourceSubjectVisitId = subjectVisit.Id, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 2, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, + + TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId + }); + + currentMaxCodeInt = currentMaxCodeInt + 2; + + _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); + + + + + var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; + + if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1)) + { + task1.TaskAllocationState = defaultState; + //分配给对应Arm的人 + task1.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm1).DoctorUserId; + task1.AllocateTime = DateTime.Now; + + task1.SuggesteFinishedTime = DateTime.Now.AddDays(7); + } + + if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2)) + { + task2.TaskAllocationState = defaultState; + task2.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm2).DoctorUserId; + task2.AllocateTime = DateTime.Now; + task2.SuggesteFinishedTime = DateTime.Now.AddDays(7); + } + } + else if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Single) + { + + + var singleTask = await _visitTaskRepository.AddAsync(new VisitTask() + { + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + IsUrgent = subjectVisit.IsUrgent, + TaskBlindName = blindTaskName, + TaskName = subjectVisit.VisitName, + VisitTaskNum = subjectVisit.VisitNum, + //CheckPassedTime = subjectVisit.CheckPassedTime, + ArmEnum = Arm.SingleReadingArm, //特殊 + Code = currentMaxCodeInt + 1, + SourceSubjectVisitId = subjectVisit.Id, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, + TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId + }); + + + currentMaxCodeInt = currentMaxCodeInt + 1; + + _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); + + + + var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; + + if (assignConfigList.Any(t => t.ArmEnum == Arm.SingleReadingArm)) + { + singleTask.TaskAllocationState = defaultState; + + singleTask.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.SingleReadingArm).DoctorUserId; + + singleTask.AllocateTime = DateTime.Now; + + singleTask.SuggesteFinishedTime = DateTime.Now.AddDays(7); + } + + + + + } + await _visitTaskRepository.SaveChangesAsync(); } - else if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Single) - { - - - var singleTask = await _visitTaskRepository.AddAsync(new VisitTask() - { - TrialId = trialId, - SubjectId = subjectVisit.SubjectId, - IsUrgent = subjectVisit.IsUrgent, - TaskBlindName = subjectVisit.BlindName, - TaskName = subjectVisit.VisitName, - VisitTaskNum = subjectVisit.VisitNum, - //CheckPassedTime = subjectVisit.CheckPassedTime, - ArmEnum = Arm.SingleReadingArm, //特殊 - Code = currentMaxCodeInt + 1, - SourceSubjectVisitId = subjectVisit.Id, - TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), - ReadingCategory = ReadingCategory.Visit, - TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId - }); - - - currentMaxCodeInt = currentMaxCodeInt + 1; - - _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); - - - - var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; - - if(assignConfigList.Any(t => t.ArmEnum == Arm.SingleReadingArm)) - { - singleTask.TaskAllocationState = defaultState; - - singleTask.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.SingleReadingArm).DoctorUserId; - - singleTask.AllocateTime = DateTime.Now; - - singleTask.SuggesteFinishedTime = DateTime.Now.AddDays(7); - } - - - - - } - await _visitTaskRepository.SaveChangesAsync(); } + } @@ -239,114 +259,257 @@ namespace IRaCIS.Core.Application.Service switch (generateTaskCommand.ReadingCategory) { case GenerateTaskCategory.Visit: - foreach (var subjectVisit in generateTaskCommand.VisitGenerataTaskList) + + //每个Subject 的每个访视 都要根据每个标准进行任务的生成 和分配(考虑回退后 的分配) + + + foreach (var subjectGroup in generateTaskCommand.VisitGenerataTaskList.GroupBy(t=>t.SubjectId).Select(g=>new {SubjectId=g.Key,SubjectVisitList=g.ToList()})) { - foreach (var trialReadingCriterionConfig in trialReadingCriterionConfigList) + + foreach (var subjectVisit in subjectGroup.SubjectVisitList) { - - var assignConfigList = await _subjectUserRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.OrignalSubjectUserId == null && t.IsConfirmed).Select(u => new { u.DoctorUserId, u.ArmEnum }).ToListAsync(); + var visitNumList = _subjectVisitRepository.Where(t => t.SubjectId == subjectGroup.SubjectId).Select(t => t.VisitNum).ToList(); - if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Double) + foreach (var trialReadingCriterionConfig in trialReadingCriterionConfigList) { - //每个访视 根据项目配置生成任务 双审生成两个 - var task1 = await _visitTaskRepository.AddAsync(new VisitTask() + + var assignConfigList = await _subjectUserRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.OrignalSubjectUserId == null && t.IsConfirmed).Select(u => new { u.DoctorUserId, u.ArmEnum }).ToListAsync(); + + + var blindTaskName = string.Empty; + + if (trialReadingCriterionConfig.IsReadingTaskViewInOrder) { - TrialId = trialId, - SubjectId = subjectVisit.SubjectId, - IsUrgent = subjectVisit.IsUrgent, - TaskBlindName = subjectVisit.BlindName, - TaskName = subjectVisit.VisitName, - VisitTaskNum = subjectVisit.VisitNum, - //CheckPassedTime = subjectVisit.CheckPassedTime, - ArmEnum = Arm.DoubleReadingArm1,//特殊 - Code = currentMaxCodeInt + 1, - SourceSubjectVisitId = subjectVisit.Id, - TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), - ReadingCategory = ReadingCategory.Visit, - - TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId - }); - - var task2 = await _visitTaskRepository.AddAsync(new VisitTask() + blindTaskName = AppSettings.BlindTaskPrefix + visitNumList.IndexOf(subjectVisit.VisitNum); + } + else { - TrialId = trialId, - SubjectId = subjectVisit.SubjectId, - IsUrgent = subjectVisit.IsUrgent, - TaskBlindName = subjectVisit.BlindName, - TaskName = subjectVisit.VisitName, - VisitTaskNum = subjectVisit.VisitNum, - //CheckPassedTime = subjectVisit.CheckPassedTime, - ArmEnum = Arm.DoubleReadingArm2,//特殊 - Code = currentMaxCodeInt + 2, - SourceSubjectVisitId = subjectVisit.Id, - TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 2, nameof(VisitTask)), - ReadingCategory = ReadingCategory.Visit, - - TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId - }); - - currentMaxCodeInt = currentMaxCodeInt + 2; - - _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); + blindTaskName = AppSettings.BlindTaskPrefix; + } - #region 分配 - if (isAssignSubjectToDoctor) + if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Double) { - - - if (trialReadingCriterionConfig.TaskAllocateObjEnum == TaskAllocateObj.Subject) + //每个访视 根据项目配置生成任务 双审生成两个 + var task1 = await _visitTaskRepository.AddAsync(new VisitTask() { - var allocateSubjectArmList = _visitTaskRepository.Where(t => t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.TrialId == trialId && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm) - .Select(t => new { t.DoctorUserId, t.ArmEnum }).Distinct().ToList(); + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + IsUrgent = subjectVisit.IsUrgent, + TaskBlindName = blindTaskName, + TaskName = subjectVisit.VisitName, + VisitTaskNum = subjectVisit.VisitNum, + //CheckPassedTime = subjectVisit.CheckPassedTime, + ArmEnum = Arm.DoubleReadingArm1,//特殊 + Code = currentMaxCodeInt + 1, + SourceSubjectVisitId = subjectVisit.Id, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, - //当前任务没有分配医生,初次分配 不处理 只生成任务,后续根据生成的任务 再进行分配 - if (allocateSubjectArmList.Count == 0) + TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId + }); + + var task2 = await _visitTaskRepository.AddAsync(new VisitTask() + { + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + IsUrgent = subjectVisit.IsUrgent, + TaskBlindName = blindTaskName, + TaskName = subjectVisit.VisitName, + VisitTaskNum = subjectVisit.VisitNum, + //CheckPassedTime = subjectVisit.CheckPassedTime, + ArmEnum = Arm.DoubleReadingArm2,//特殊 + Code = currentMaxCodeInt + 2, + SourceSubjectVisitId = subjectVisit.Id, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 2, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, + + TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId + }); + + currentMaxCodeInt = currentMaxCodeInt + 2; + + _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); + + + #region 分配 + if (isAssignSubjectToDoctor) + { + + + if (trialReadingCriterionConfig.TaskAllocateObjEnum == TaskAllocateObj.Subject) { + var allocateSubjectArmList = _visitTaskRepository.Where(t => t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.TrialId == trialId && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm) + .Select(t => new { t.DoctorUserId, t.ArmEnum }).Distinct().ToList(); - } - else - { - #region 验证历史任务 停用影响体验 - - //if (_taskAllocationRuleRepository.Where(t => t.TrialId == trialId && t.IsEnable).Count() < 2) - //{ - // throw new BusinessValidationFailedException("能参与读片的医生数量必须>=2,自动分配任务中止"); - //} - //if (!(assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1) && assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2))) - //{ - // throw new BusinessValidationFailedException("该受试者阅片医生未配置完成"); - //} - - #endregion - - - //并且配置了医生 - if (assignConfigList.Count > 0 && trialReadingCriterionConfig.IsFollowVisitAutoAssign) + //当前任务没有分配医生,初次分配 不处理 只生成任务,后续根据生成的任务 再进行分配 + if (allocateSubjectArmList.Count == 0) { - #region 后续访视 未分配的进行再次分配,重置的或者失效的 需要重新生成新的任务 (PM 有序退回 或者PM 有序 申请重阅) - - - if (trialReadingCriterionConfig.IsReadingTaskViewInOrder) + } + else + { + //并且配置了医生 + if (assignConfigList.Count > 0 && trialReadingCriterionConfig.IsFollowVisitAutoAssign) { - //之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去 - var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit==false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); + #region 后续访视 未分配的进行再次分配,重置的或者失效的 需要重新生成新的任务 (PM 有序退回 或者PM 有序 申请重阅) - //之前有回退的,那么当前访视任务生成但是不分配 - if (beforeBackVisitTask != null) + + if (trialReadingCriterionConfig.IsReadingTaskViewInOrder) { - //不用进行额外处理 + //之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去(排除失访的) + + var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); + + //之前有回退的,那么当前访视任务生成但是不分配 + if (beforeBackVisitTask != null) + { + //不用进行额外处理 + + //访视2 PM 回退 基线回退 访视2先一致性核查通过,生成访视2任务,但是不分配 + } + else + { + #region 当前访视根据配置规则分配出去 + + var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; + + if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1)) + { + task1.TaskAllocationState = defaultState; + //分配给对应Arm的人 + task1.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm1).DoctorUserId; + task1.AllocateTime = DateTime.Now; + + task1.SuggesteFinishedTime = DateTime.Now.AddDays(7); + } + + if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2)) + { + task2.TaskAllocationState = defaultState; + task2.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm2).DoctorUserId; + task2.AllocateTime = DateTime.Now; + task2.SuggesteFinishedTime = DateTime.Now.AddDays(7); + } + + #endregion + } + + //后续最近的未一致性核查通过的访视任务 + var followBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit==false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); + + //大于当前访视 同时小于最近的未一致性核查通过的访视任务分配 或者生成 + + //存在退回访视1 又退回基线 这种情况 生成任务 考虑基线先一致性核查通过,但是访视1还未通过时 生成任务 + var followVisitTaskList = await _visitTaskRepository + .Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed && t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false, true) + .WhereIf(followBackVisitTask != null, t => t.VisitTaskNum < followBackVisitTask.VisitTaskNum) + .ToListAsync(); + + var followVisitGroup = followVisitTaskList.GroupBy(t => t.VisitTaskNum); + + //每个访视去判断 是分配还是生成(因为影响哪里有些是取消分配,有些是重阅重置) + foreach (var visitGroup in followVisitGroup) + { + + var arm1 = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.DoubleReadingArm1); + if (arm1 != null) + { + arm1.TaskAllocationState = TaskAllocationState.Allocated; + arm1.AllocateTime = DateTime.Now; + arm1.DoctorUserId = task1.DoctorUserId; + arm1.SuggesteFinishedTime = DateTime.Now.AddDays(7); + } + else + { + var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.DoubleReadingArm1).OrderByDescending(t => t.CreateTime).First(); + + var taskOne = await _visitTaskRepository.AddAsync(new VisitTask() + { + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + IsUrgent = subjectVisit.IsUrgent, + ArmEnum = Arm.DoubleReadingArm1,//特殊 + Code = currentMaxCodeInt + 1, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, + + SourceSubjectVisitId = latestTask.SourceSubjectVisitId, + VisitTaskNum = latestTask.VisitTaskNum, + TaskBlindName = AppSettings.BlindTaskPrefix + visitNumList.IndexOf(latestTask.VisitTaskNum) , + TaskName = latestTask.TaskName, + + BlindSubjectCode = latestTask.BlindSubjectCode, + BlindTrialSiteCode = latestTask.BlindTrialSiteCode, + IsAnalysisCreate = latestTask.IsAnalysisCreate, + IsSelfAnalysis = latestTask.IsSelfAnalysis, + TaskAllocationState = TaskAllocationState.Allocated, + AllocateTime = DateTime.Now, + DoctorUserId = task1.DoctorUserId, + SuggesteFinishedTime = DateTime.Now.AddDays(7), + TrialReadingCriterionId = latestTask.TrialReadingCriterionId + }); + + currentMaxCodeInt = currentMaxCodeInt + 1; + + _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); + } + + var arm2 = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.DoubleReadingArm2); + if (arm2 != null) + { + arm2.TaskAllocationState = TaskAllocationState.Allocated; + arm2.AllocateTime = DateTime.Now; + arm2.DoctorUserId = task2.DoctorUserId; + arm2.SuggesteFinishedTime = DateTime.Now.AddDays(7); + } + else + { + var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.DoubleReadingArm2).OrderByDescending(t => t.CreateTime).First(); + + var taskTwo = await _visitTaskRepository.AddAsync(new VisitTask() + { + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + IsUrgent = subjectVisit.IsUrgent, + + //CheckPassedTime = subjectVisit.CheckPassedTime, + ArmEnum = Arm.DoubleReadingArm2,//特殊 + Code = currentMaxCodeInt + 1, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, + + SourceSubjectVisitId = latestTask.SourceSubjectVisitId, + VisitTaskNum = latestTask.VisitTaskNum, + TaskBlindName = AppSettings.BlindTaskPrefix + visitNumList.IndexOf(latestTask.VisitTaskNum), + TaskName = latestTask.TaskName, + + BlindSubjectCode = latestTask.BlindSubjectCode, + BlindTrialSiteCode = latestTask.BlindTrialSiteCode, + IsAnalysisCreate = latestTask.IsAnalysisCreate, + IsSelfAnalysis = latestTask.IsSelfAnalysis, + TaskAllocationState = TaskAllocationState.Allocated, + AllocateTime = DateTime.Now, + DoctorUserId = task2.DoctorUserId, + SuggesteFinishedTime = DateTime.Now.AddDays(7), + + TrialReadingCriterionId = latestTask.TrialReadingCriterionId + }); + + currentMaxCodeInt = currentMaxCodeInt + 1; + + _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); + } + } + - //访视2 PM 回退 基线回退 访视2先一致性核查通过,生成访视2任务,但是不分配 } + //无序的时候 生成任务并分配出去 else { - #region 当前访视根据配置规则分配出去 - var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1)) @@ -367,235 +530,186 @@ namespace IRaCIS.Core.Application.Service task2.SuggesteFinishedTime = DateTime.Now.AddDays(7); } - #endregion } - //后续最近的未一致性核查通过的访视任务 - var followBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); - - //大于当前访视 同时小于最近的未一致性核查通过的访视任务分配 或者生成 - - //存在退回访视1 又退回基线 这种情况 生成任务 考虑基线先一致性核查通过,但是访视1还未通过时 生成任务 - var followVisitTaskList = await _visitTaskRepository - .Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed && t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false, true) - .WhereIf(followBackVisitTask != null, t => t.VisitTaskNum < followBackVisitTask.VisitTaskNum) - .ToListAsync(); - - var followVisitGroup = followVisitTaskList.GroupBy(t => t.VisitTaskNum); - - //每个访视去判断 是分配还是生成(因为影响哪里有些是取消分配,有些是重阅重置) - foreach (var visitGroup in followVisitGroup) - { - - var arm1 = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.DoubleReadingArm1); - if (arm1 != null) - { - arm1.TaskAllocationState = TaskAllocationState.Allocated; - arm1.AllocateTime = DateTime.Now; - arm1.DoctorUserId = task1.DoctorUserId; - arm1.SuggesteFinishedTime = DateTime.Now.AddDays(7); - } - else - { - var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.DoubleReadingArm1).OrderByDescending(t => t.CreateTime).First(); - - var taskOne = await _visitTaskRepository.AddAsync(new VisitTask() - { - TrialId = trialId, - SubjectId = subjectVisit.SubjectId, - IsUrgent = subjectVisit.IsUrgent, - ArmEnum = Arm.DoubleReadingArm1,//特殊 - Code = currentMaxCodeInt + 1, - TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), - ReadingCategory = ReadingCategory.Visit, - - SourceSubjectVisitId = latestTask.SourceSubjectVisitId, - VisitTaskNum = latestTask.VisitTaskNum, - TaskBlindName = latestTask.TaskBlindName, - TaskName = latestTask.TaskName, - - BlindSubjectCode = latestTask.BlindSubjectCode, - BlindTrialSiteCode = latestTask.BlindTrialSiteCode, - IsAnalysisCreate = latestTask.IsAnalysisCreate, - IsSelfAnalysis = latestTask.IsSelfAnalysis, - TaskAllocationState = TaskAllocationState.Allocated, - AllocateTime = DateTime.Now, - DoctorUserId = task1.DoctorUserId, - SuggesteFinishedTime = DateTime.Now.AddDays(7), - TrialReadingCriterionId = latestTask.TrialReadingCriterionId - }); - - currentMaxCodeInt = currentMaxCodeInt + 1; - - _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); - } - - var arm2 = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.DoubleReadingArm2); - if (arm2 != null) - { - arm2.TaskAllocationState = TaskAllocationState.Allocated; - arm2.AllocateTime = DateTime.Now; - arm2.DoctorUserId = task2.DoctorUserId; - arm2.SuggesteFinishedTime = DateTime.Now.AddDays(7); - } - else - { - var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.DoubleReadingArm2).OrderByDescending(t => t.CreateTime).First(); - - var taskTwo = await _visitTaskRepository.AddAsync(new VisitTask() - { - TrialId = trialId, - SubjectId = subjectVisit.SubjectId, - IsUrgent = subjectVisit.IsUrgent, - - //CheckPassedTime = subjectVisit.CheckPassedTime, - ArmEnum = Arm.DoubleReadingArm2,//特殊 - Code = currentMaxCodeInt + 1, - TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), - ReadingCategory = ReadingCategory.Visit, - - SourceSubjectVisitId = latestTask.SourceSubjectVisitId, - VisitTaskNum = latestTask.VisitTaskNum, - TaskBlindName = latestTask.TaskBlindName, - TaskName = latestTask.TaskName, - - BlindSubjectCode = latestTask.BlindSubjectCode, - BlindTrialSiteCode = latestTask.BlindTrialSiteCode, - IsAnalysisCreate = latestTask.IsAnalysisCreate, - IsSelfAnalysis = latestTask.IsSelfAnalysis, - TaskAllocationState = TaskAllocationState.Allocated, - AllocateTime = DateTime.Now, - DoctorUserId = task2.DoctorUserId, - SuggesteFinishedTime = DateTime.Now.AddDays(7), - - TrialReadingCriterionId = latestTask.TrialReadingCriterionId - }); - - currentMaxCodeInt = currentMaxCodeInt + 1; - - _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); - } - } + #endregion } - //无序的时候 生成任务并分配出去 else + //后续访视不自动分配,或者配置的医生数量不足,就不进行分配 { - var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; - - if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1)) - { - task1.TaskAllocationState = defaultState; - //分配给对应Arm的人 - task1.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm1).DoctorUserId; - task1.AllocateTime = DateTime.Now; - - task1.SuggesteFinishedTime = DateTime.Now.AddDays(7); - } - - if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2)) - { - task2.TaskAllocationState = defaultState; - task2.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm2).DoctorUserId; - task2.AllocateTime = DateTime.Now; - task2.SuggesteFinishedTime = DateTime.Now.AddDays(7); - } } - - #endregion - } - else - //后续访视不自动分配,或者配置的医生数量不足,就不进行分配 - { - } } - - } + } + #endregion } - #endregion - - } - else if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Single) - { - - - var singleTask = await _visitTaskRepository.AddAsync(new VisitTask() - { - TrialId = trialId, - SubjectId = subjectVisit.SubjectId, - IsUrgent = subjectVisit.IsUrgent, - TaskBlindName = subjectVisit.BlindName, - TaskName = subjectVisit.VisitName, - VisitTaskNum = subjectVisit.VisitNum, - //CheckPassedTime = subjectVisit.CheckPassedTime, - ArmEnum = Arm.SingleReadingArm, //特殊 - Code = currentMaxCodeInt + 1, - SourceSubjectVisitId = subjectVisit.Id, - TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), - ReadingCategory = ReadingCategory.Visit, - TrialReadingCriterionId= trialReadingCriterionConfig.TrialReadingCriterionId - }); - - - currentMaxCodeInt = currentMaxCodeInt + 1; - - _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); - - #region 分配 - - if (isAssignSubjectToDoctor) + else if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Single) { - if (trialReadingCriterionConfig.TaskAllocateObjEnum == TaskAllocateObj.Subject) + + var singleTask = await _visitTaskRepository.AddAsync(new VisitTask() + { + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + IsUrgent = subjectVisit.IsUrgent, + TaskBlindName = blindTaskName, + TaskName = subjectVisit.VisitName, + VisitTaskNum = subjectVisit.VisitNum, + //CheckPassedTime = subjectVisit.CheckPassedTime, + ArmEnum = Arm.SingleReadingArm, //特殊 + Code = currentMaxCodeInt + 1, + SourceSubjectVisitId = subjectVisit.Id, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, + TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId + }); + + + currentMaxCodeInt = currentMaxCodeInt + 1; + + _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); + + #region 分配 + + if (isAssignSubjectToDoctor) { - if (trialReadingCriterionConfig.IsFollowVisitAutoAssign) + if (trialReadingCriterionConfig.TaskAllocateObjEnum == TaskAllocateObj.Subject) { - - //该Subject 之前是否有已分配的 如果改变配置 可能会出现 一个Subject 分配的同一个医生 有的在Arm1 有的在Arm2 - var allocateSubjectArmList = _visitTaskRepository.Where(t => t.SubjectId == subjectVisit.SubjectId && t.TrialId == trialId && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm) - .Select(t => new { t.DoctorUserId, t.ArmEnum }).Distinct().ToList(); - - //不是初次分配 - if (allocateSubjectArmList.Count != 0) + if (trialReadingCriterionConfig.IsFollowVisitAutoAssign) { - if (_taskAllocationRuleRepository.Where(t => t.TrialId == trialId && t.IsEnable).Count() < 2) + + + //该Subject 之前是否有已分配的 如果改变配置 可能会出现 一个Subject 分配的同一个医生 有的在Arm1 有的在Arm2 + var allocateSubjectArmList = _visitTaskRepository.Where(t => t.SubjectId == subjectVisit.SubjectId && t.TrialId == trialId && t.DoctorUserId != null && t.ArmEnum != Arm.JudgeArm) + .Select(t => new { t.DoctorUserId, t.ArmEnum }).Distinct().ToList(); + + //不是初次分配 + if (allocateSubjectArmList.Count != 0) { - throw new BusinessValidationFailedException("能参与读片的医生数量必须>=2,自动分配任务中止"); + //if (_taskAllocationRuleRepository.Where(t => t.TrialId == trialId && t.IsEnable).Count() < 2) + //{ + // throw new BusinessValidationFailedException("能参与读片的医生数量必须>=2,自动分配任务中止"); - //break; - } + //} - //配置了医生 - if (assignConfigList.Count > 0) - { - - - - #region 重阅/退回的时候,需要将取消分配的访视类型的 任务重新分配 - - - if (trialReadingCriterionConfig.IsReadingTaskViewInOrder) + //配置了医生 + if (assignConfigList.Count > 0) { - //之前有回退的访视 那么当前访视一致性核查通过的时候,对后续访视不生成或者分配 当前访视生成但是不分配出去 - var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); + #region 重阅/退回的时候,需要将取消分配的访视类型的 任务重新分配 - - if (beforeBackVisitTask == null) + if (trialReadingCriterionConfig.IsReadingTaskViewInOrder) { - #region 访视2 PM 回退 基线回退 访视2先一致性核查通过,生成访视2任务,但是不分配 + //之前有回退到影像上传的访视 那么当前访视一致性核查通过的时候,当前访视生成但是不分配出去(排除失访的) + var beforeBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum < subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit==false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); + + if (beforeBackVisitTask == null) + { + #region 访视2 PM 回退 基线回退 访视2先一致性核查通过,生成访视2任务,但是不分配 + + var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; + + + if (assignConfigList.Any(t => t.ArmEnum == Arm.SingleReadingArm)) + { + singleTask.TaskAllocationState = defaultState; + + singleTask.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.SingleReadingArm).DoctorUserId; + + singleTask.AllocateTime = DateTime.Now; + + singleTask.SuggesteFinishedTime = DateTime.Now.AddDays(7); + } + + + #endregion + + + var followBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed && t.SourceSubjectVisit.IsLostVisit == false).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); + + //存在退回访视1 又退回基线 这种情况 生成任务 考虑基线先一致性核查通过,但是访视1还未通过时 生成任务 + var followVisitTaskList = await _visitTaskRepository + .Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed && t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false, true) + .WhereIf(followBackVisitTask != null, t => t.VisitTaskNum < followBackVisitTask.VisitTaskNum) + .ToListAsync(); + + var followVisitGroup = followVisitTaskList.GroupBy(t => t.VisitTaskNum); + + //每个访视去判断 是分配还是生成 + + + foreach (var visitGroup in followVisitGroup) + { + + var arm = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.SingleReadingArm); + if (arm != null) + { + arm.TaskAllocationState = TaskAllocationState.Allocated; + arm.AllocateTime = DateTime.Now; + arm.DoctorUserId = singleTask.DoctorUserId; + arm.SuggesteFinishedTime = DateTime.Now.AddDays(7); + } + else + { + var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.SingleReadingArm).OrderByDescending(t => t.CreateTime).First(); + + var taskOne = await _visitTaskRepository.AddAsync(new VisitTask() + { + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + IsUrgent = subjectVisit.IsUrgent, + ArmEnum = Arm.SingleReadingArm,//特殊 + Code = currentMaxCodeInt + 1, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, + + SourceSubjectVisitId = latestTask.SourceSubjectVisitId, + VisitTaskNum = latestTask.VisitTaskNum, + TaskBlindName = AppSettings.BlindTaskPrefix + visitNumList.IndexOf(latestTask.VisitTaskNum), + TaskName = latestTask.TaskName, + + BlindSubjectCode = latestTask.BlindSubjectCode, + BlindTrialSiteCode = latestTask.BlindTrialSiteCode, + IsAnalysisCreate = latestTask.IsAnalysisCreate, + IsSelfAnalysis = latestTask.IsSelfAnalysis, + TaskAllocationState = TaskAllocationState.Allocated, + AllocateTime = DateTime.Now, + DoctorUserId = singleTask.DoctorUserId + }); + + currentMaxCodeInt = currentMaxCodeInt + 1; + + _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); + } + + } + + } + //之前有回退的 后续访视不生成或者分配 当前访视生成但是不分配出去 + else + { + + //不用进行额外处理 + } + + + + } + //无序的时候 生成任务并分配出去 + else + { var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; @@ -609,130 +723,49 @@ namespace IRaCIS.Core.Application.Service singleTask.SuggesteFinishedTime = DateTime.Now.AddDays(7); } - - #endregion - - - var followBackVisitTask = await _visitTaskRepository.Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.ReadingCategory == ReadingCategory.Visit && t.SourceSubjectVisit.CheckState != CheckStateEnum.CVPassed).OrderBy(t => t.VisitTaskNum).FirstOrDefaultAsync(); - - //存在退回访视1 又退回基线 这种情况 生成任务 考虑基线先一致性核查通过,但是访视1还未通过时 生成任务 - var followVisitTaskList = await _visitTaskRepository - .Where(t => t.TrialId == trialId && t.SubjectId == subjectVisit.SubjectId && t.VisitTaskNum > subjectVisit.VisitNum && t.SourceSubjectVisit.CheckState == CheckStateEnum.CVPassed && t.ReadingCategory == ReadingCategory.Visit && t.IsAnalysisCreate == false, true) - .WhereIf(followBackVisitTask != null, t => t.VisitTaskNum < followBackVisitTask.VisitTaskNum) - .ToListAsync(); - - var followVisitGroup = followVisitTaskList.GroupBy(t => t.VisitTaskNum); - - //每个访视去判断 是分配还是生成 - - - foreach (var visitGroup in followVisitGroup) - { - - var arm = visitGroup.FirstOrDefault(t => t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.NotAllocate && t.DoctorUserId == null && t.ArmEnum == Arm.SingleReadingArm); - if (arm != null) - { - arm.TaskAllocationState = TaskAllocationState.Allocated; - arm.AllocateTime = DateTime.Now; - arm.DoctorUserId = singleTask.DoctorUserId; - arm.SuggesteFinishedTime = DateTime.Now.AddDays(7); - } - else - { - var latestTask = visitGroup.Where(t => t.ArmEnum == Arm.SingleReadingArm).OrderByDescending(t => t.CreateTime).First(); - - var taskOne = await _visitTaskRepository.AddAsync(new VisitTask() - { - TrialId = trialId, - SubjectId = subjectVisit.SubjectId, - IsUrgent = subjectVisit.IsUrgent, - ArmEnum = Arm.SingleReadingArm,//特殊 - Code = currentMaxCodeInt + 1, - TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), - ReadingCategory = ReadingCategory.Visit, - - SourceSubjectVisitId = latestTask.SourceSubjectVisitId, - VisitTaskNum = latestTask.VisitTaskNum, - TaskBlindName = latestTask.TaskBlindName, - TaskName = latestTask.TaskName, - - BlindSubjectCode = latestTask.BlindSubjectCode, - BlindTrialSiteCode = latestTask.BlindTrialSiteCode, - IsAnalysisCreate = latestTask.IsAnalysisCreate, - IsSelfAnalysis = latestTask.IsSelfAnalysis, - TaskAllocationState = TaskAllocationState.Allocated, - AllocateTime = DateTime.Now, - DoctorUserId = singleTask.DoctorUserId - }); - - currentMaxCodeInt = currentMaxCodeInt + 1; - - _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); - } - - } } - //之前有回退的 后续访视不生成或者分配 当前访视生成但是不分配出去 - else - { - //不用进行额外处理 - } - + #endregion } - //无序的时候 生成任务并分配出去 - else - { - var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; - - - if (assignConfigList.Any(t => t.ArmEnum == Arm.SingleReadingArm)) - { - singleTask.TaskAllocationState = defaultState; - - singleTask.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.SingleReadingArm).DoctorUserId; - - singleTask.AllocateTime = DateTime.Now; - - singleTask.SuggesteFinishedTime = DateTime.Now.AddDays(7); - } - - - } - - #endregion - } } - } - else - { - //后续Subect 不自动分配 不处理 - } + else + { + //后续Subect 不自动分配 不处理 + } + } + + } + #endregion } - #endregion } + + await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.Id == subjectVisit.Id, u => new SubjectVisit() { IsVisitTaskGenerated = true }); } - - await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.Id == subjectVisit.Id, u => new SubjectVisit() { IsVisitTaskGenerated = true }); } + + + + break; + + case GenerateTaskCategory.ReReading: var reReadingVisitTask = generateTaskCommand.ReReadingTask; @@ -915,7 +948,7 @@ namespace IRaCIS.Core.Application.Service SouceReadModuleId = firstTask.SouceReadModuleId, TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), TaskState = TaskState.Effect, - TaskBlindName = firstTask.TaskName, + TaskBlindName = firstTask.TaskBlindName, DoctorUserId = subjectUser == null ? null : subjectUser.DoctorUserId, TaskAllocationState = subjectUser == null ? TaskAllocationState.NotAllocate : TaskAllocationState.Allocated, AllocateTime = subjectUser == null ? null : DateTime.Now, diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index d5a36fc4f..7ad1e50de 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -594,6 +594,7 @@ namespace IRaCIS.Core.Application.Service.Allocation //以前访视未产生任务的,在查询这里要产生 var svIdList = await _subjectVisitRepository.Where(t => t.TrialId == queryVisitTask.TrialId && t.CheckState == CheckStateEnum.CVPassed && t.IsVisitTaskGenerated == false).Select(t => t.Id).ToListAsync(); + //之前没有生成任务的逻辑 但是现在加了,任务要自动生成 await _visitTaskCommonService.GenerateVisitTaskAsync(queryVisitTask.TrialId, svIdList); diff --git a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs index 8a20af5e7..8c2ae3fc2 100644 --- a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs +++ b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs @@ -99,9 +99,9 @@ namespace IRaCIS.Core.Application.Services throw new BusinessValidationFailedException("设置末次评估后,不允许添加计划外访视。"); } - if (await _repository.AnyAsync(t=>t.SubjectId==svCommand.SubjectId && t.TaskState==TaskState.Effect && t.VisitTaskNum > svCommand.VisitNum && t.SignTime != null)) + if (await _repository.AnyAsync(t=>t.SubjectId==svCommand.SubjectId && t.TaskState==TaskState.Effect && t.VisitTaskNum > svCommand.VisitNum && t.SignTime != null && t.TrialReadingCriterion.IsReadingTaskViewInOrder)) { - throw new BusinessValidationFailedException("该受试者后续访视已有任务完成阅片,不允许在此添加,如果确实需要,请回退"); + throw new BusinessValidationFailedException("该受试者后续访视已有任务完成阅片(有序阅片标准),不允许在此添加,如果确实需要,请回退"); } } diff --git a/IRaCIS.Core.Domain/_Config/_AppSettings.cs b/IRaCIS.Core.Domain/_Config/_AppSettings.cs index 1c45b841f..a2d329b5f 100644 --- a/IRaCIS.Core.Domain/_Config/_AppSettings.cs +++ b/IRaCIS.Core.Domain/_Config/_AppSettings.cs @@ -54,8 +54,8 @@ namespace IRaCIS.Core.Domain.Share public static string SystemSiteCodePrefix { get; set; } - + public static string BlindTaskPrefix { get; set; } /// /// 用户默认密码 @@ -85,6 +85,7 @@ namespace IRaCIS.Core.Domain.Share ImageShareExpireDays = configuration.GetSection("IRaCISBasicConfig").GetValue("ImageShareExpireDays"); + BlindTaskPrefix = configuration.GetSection("IRaCISBasicConfig").GetValue("BlindTaskPrefix"); } diff --git a/IRaCIS.Core.Domain/_Config/_StaticData.cs b/IRaCIS.Core.Domain/_Config/_StaticData.cs index 78c0c6923..e0732ba27 100644 --- a/IRaCIS.Core.Domain/_Config/_StaticData.cs +++ b/IRaCIS.Core.Domain/_Config/_StaticData.cs @@ -135,13 +135,10 @@ public static class StaticData public const string TrialSubjectVisitCheckList_Export = "TrialSubjectVisitCheckList_Export"; - - public const string TrialReadingTaskList_Export = "TrialReadingTaskList_Export"; public const string TrialReReadingTaskList_Export = "TrialReReadingTaskList_Export"; - public const string TrialMedicalReviewList_Export = "TrialMedicalReviewList_Export";