diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 45f77f15b..d61b11bb4 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -441,6 +441,12 @@ + + + 如果是基线退回 影响附加评估标准 是否参与评估 + + + 影响提示列表 重阅仅仅针对已完成的任务申请 退回针对的是未完成的(退回仅仅针对是访视类型的) @@ -2249,6 +2255,20 @@ + + + 附加评估标准 PM 退回某一访视 影响任务列表 + + + + + + + 退回任务 + + + + 名称 @@ -10482,7 +10502,7 @@ - + 获取子元素 diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs index a7ffd32b6..1795c6945 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskService.cs @@ -42,10 +42,13 @@ namespace IRaCIS.Core.Application.Service.Allocation private readonly IRepository _visitTaskReReadingRepository; private readonly IRepository _taskMedicalReviewRepository; private readonly IRepository _readingTaskQuestionAnswerRepository; - private readonly IRepository _trialReadingCriterionRepository; private readonly IRepository _readingClinicalDataReposiotry; + private readonly IRepository _subjectCriteriaEvaluationRepository; + private readonly IRepository _subjectCriteriaEvaluationVisitFilterRepository; + private readonly IRepository _trialReadingCriterionRepository; + private readonly IRepository _subjectCriteriaEvaluationVisitStudyFilterRepository; public VisitTaskService(IRepository subjectVisitRepository, IRepository visitTaskRepository, IRepository trialRepository, IRepository subjectRepository, IRepository subjectUserRepository, IRepository taskAllocationRuleRepository, @@ -53,7 +56,10 @@ namespace IRaCIS.Core.Application.Service.Allocation IRepository taskMedicalReviewRepository, IRepository readingTaskQuestionAnswerRepository , IRepository trialReadingCriterionRepository, - IRepository readingClinicalDataReposiotry + IRepository readingClinicalDataReposiotry, + IRepository subjectCriteriaEvaluationRepository, + IRepository subjectCriteriaEvaluationVisitFilterRepository, + IRepository subjectCriteriaEvaluationVisitStudyFilterRepository ) { _readingClinicalDataReposiotry = readingClinicalDataReposiotry; @@ -69,6 +75,9 @@ namespace IRaCIS.Core.Application.Service.Allocation _readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository; _trialReadingCriterionRepository = trialReadingCriterionRepository; + _subjectCriteriaEvaluationRepository = subjectCriteriaEvaluationRepository; + _subjectCriteriaEvaluationVisitFilterRepository = subjectCriteriaEvaluationVisitFilterRepository; + _subjectCriteriaEvaluationVisitStudyFilterRepository = subjectCriteriaEvaluationVisitStudyFilterRepository; } /// @@ -90,12 +99,12 @@ namespace IRaCIS.Core.Application.Service.Allocation return await _visitTaskRepository.SaveChangesAsync(); } - public async Task> GetTrialCriterionList(Guid trialId, bool isHaveSigned = true,bool? isAutoCreate = null) + public async Task> GetTrialCriterionList(Guid trialId, bool isHaveSigned = true, bool? isAutoCreate = null) { var list = await _repository.Where(t => t.TrialId == trialId && t.IsConfirm) - + .OrderBy(t => t.ShowOrder) - .Select(t => new TrialReadingCriterionDto() { TrialReadingCriterionId = t.Id, IsAutoCreate=t.IsAutoCreate,IsAdditionalAssessment=t.IsAdditionalAssessment, TrialReadingCriterionName = t.CriterionName, CriterionType = t.CriterionType, ReadingType = t.ReadingType, ReadingInfoSignTime = t.ReadingInfoSignTime }) + .Select(t => new TrialReadingCriterionDto() { TrialReadingCriterionId = t.Id, IsAutoCreate = t.IsAutoCreate, IsAdditionalAssessment = t.IsAdditionalAssessment, TrialReadingCriterionName = t.CriterionName, CriterionType = t.CriterionType, ReadingType = t.ReadingType, ReadingInfoSignTime = t.ReadingInfoSignTime }) .ToListAsync(); if (list.Count == 0) @@ -119,11 +128,16 @@ namespace IRaCIS.Core.Application.Service.Allocation [HttpPost] public async Task<(PageOutput, object?)> GetSubjectAssignAndTaskStatList(SubjectAssignStatQuery querySubjectAssign) { + + var isAddtinoarlCriterion = await _trialReadingCriterionRepository.AnyAsync(t => t.Id == querySubjectAssign.TrialReadingCriterionId && t.IsAutoCreate == false); + var subjectQuery = _subjectRepository.Where(t => t.TrialId == querySubjectAssign.TrialId && t.SubjectVisitTaskList.Any()) .WhereIf(querySubjectAssign.SiteId != null, t => t.SiteId == querySubjectAssign.SiteId) .WhereIf(querySubjectAssign.SubjectId != null, t => t.Id == querySubjectAssign.SubjectId) .WhereIf(querySubjectAssign.DoctorUserId != null, t => t.SubjectDoctorList.Any(t => t.DoctorUserId == querySubjectAssign.DoctorUserId && t.TrialReadingCriterionId == querySubjectAssign.TrialReadingCriterionId)) .WhereIf(!string.IsNullOrEmpty(querySubjectAssign.SubjectCode), t => t.Code.Contains(querySubjectAssign.SubjectCode)) + .WhereIf(isAddtinoarlCriterion, t => t.SubjectCriteriaEvaluationList.Where(t=>t.TrialReadingCriterionId==querySubjectAssign.TrialReadingCriterionId).Any(t=>t.IsJoinEvaluation)) + .ProjectTo(_mapper.ConfigurationProvider, new { trialReadingCriterionId = querySubjectAssign.TrialReadingCriterionId }); @@ -740,7 +754,7 @@ namespace IRaCIS.Core.Application.Service.Allocation var trialTaskConfig = _trialRepository.Where(t => t.Id == queryVisitTask.TrialId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); - return (pageList,trialTaskConfig); + return (pageList, trialTaskConfig); } @@ -1468,6 +1482,8 @@ namespace IRaCIS.Core.Application.Service.Allocation { //执行类似一致性核查回退流程 await VisitBackAsync(origenalTask.SourceSubjectVisitId); + + await InfluenceAddtioncalEvaluationCritrionAsync(origenalTask); } else { @@ -1929,6 +1945,10 @@ namespace IRaCIS.Core.Application.Service.Allocation } } + + + + } @@ -1959,9 +1979,9 @@ namespace IRaCIS.Core.Application.Service.Allocation var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == task.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsAutoCreate, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); - if (criterionConfig.IsAutoCreate==false) + if (criterionConfig.IsAutoCreate == false) { - return ResponseOutput.NotOk("手动生成任务的不允许影像退回"); + return ResponseOutput.NotOk("手动生成任务的不允许在此入口影像退回"); } if (task.TaskState != TaskState.Effect || task.ReadingCategory != ReadingCategory.Visit || task.ReadingTaskState == ReadingTaskState.HaveSigned) @@ -1970,7 +1990,7 @@ namespace IRaCIS.Core.Application.Service.Allocation } - if( await _subjectVisitRepository.AnyAsync(t=>t.Id==task.SourceSubjectVisitId && t.CheckState!= CheckStateEnum.CVPassed)) + if (await _subjectVisitRepository.AnyAsync(t => t.Id == task.SourceSubjectVisitId && t.CheckState != CheckStateEnum.CVPassed)) { return ResponseOutput.NotOk("当前访视已回退到影像上传,不允许继续回退!"); } @@ -2252,11 +2272,39 @@ namespace IRaCIS.Core.Application.Service.Allocation return ResponseOutput.NotOk("仅PM 可以进行回退操作"); } + + + await InfluenceAddtioncalEvaluationCritrionAsync(task); + + await _visitTaskRepository.SaveChangesAsync(); return ResponseOutput.Ok(); } + + /// + /// 如果是基线退回 影响附加评估标准 是否参与评估 + /// + /// + private async Task InfluenceAddtioncalEvaluationCritrionAsync(VisitTask task) + { + + if (_subjectVisitRepository.Any(t => t.Id == task.SourceSubjectVisitId && t.IsBaseLine)) + { + await _subjectCriteriaEvaluationRepository.UpdatePartialFromQueryAsync(t => t.TrialReadingCriterion.IsAutoCreate == false && t.SubjectId == task.SubjectId, u => new SubjectCriteriaEvaluation() + { + IsJoinEvaluation = false + }); + + //删除筛选的访视数据 + await _subjectCriteriaEvaluationVisitFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.IsAutoCreate == false && t.SubjectId == task.SubjectId); + + //删除筛选的序列数据 + await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterion.IsAutoCreate == false && t.SubjectVisit.SubjectId == task.SubjectId); + } + } + //包括临床数据签名状态 private async Task VisitBackAsync(Guid? subjectVisitId) { @@ -2512,7 +2560,6 @@ namespace IRaCIS.Core.Application.Service.Allocation { // 当前任务及其之后的所有访视任务 两个阅片人的 - // 1.后续访视不处理 //2.当前任务未完成,不会产生全局任务。后续任务均为访视任务,且均为待阅片,取消分配; filterExpression = filterExpression.And(t => t.VisitTaskNum >= filterObj.VisitTaskNum); @@ -2686,6 +2733,8 @@ namespace IRaCIS.Core.Application.Service.Allocation } + + /// /// 获取已影响的列表 /// diff --git a/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/DTO/SubjectCriteriaEvaluationViewModel.cs b/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/DTO/SubjectCriteriaEvaluationViewModel.cs index 656f271fe..4b4a6845e 100644 --- a/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/DTO/SubjectCriteriaEvaluationViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/DTO/SubjectCriteriaEvaluationViewModel.cs @@ -35,7 +35,7 @@ namespace IRaCIS.Core.Application.ViewModel public List FinalEvaluationList { get; set; }=new List(); - public List ReadingEvaluationList { get; set; } + public List ReadingEvaluationList { get; set; }=new List(); } diff --git a/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/DTO/SubjectCriteriaEvaluationVisitFilterViewModel.cs b/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/DTO/SubjectCriteriaEvaluationVisitFilterViewModel.cs index df4cf17d4..398fb0918 100644 --- a/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/DTO/SubjectCriteriaEvaluationVisitFilterViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/DTO/SubjectCriteriaEvaluationVisitFilterViewModel.cs @@ -19,7 +19,11 @@ namespace IRaCIS.Core.Application.ViewModel public DateTime? UpdateTime { get; set; } public Guid? Id { get; set; } + + public Guid TrialId { get; set; } public Guid SubjectId { get; set; } + + public string SubjectCode { get; set; } public Guid TrialReadingCriterionId { get; set; } public Guid SubjectVisitId { get; set; } @@ -78,6 +82,22 @@ namespace IRaCIS.Core.Application.ViewModel public List SubjectVisitIdList { get; set; }=new List(); } + + public class CriteriaVisitBackCommand + { + [NotDefault] + public Guid TrialReadingCriterionId { get; set; } + + [NotDefault] + public Guid TrialId { get; set; } + + [NotDefault] + public Guid SubjectId { get; set; } + + [NotDefault] + public Guid SubjectVisitId { get; set; } + } + public class VisitStudyAndSeriesQuery { [NotDefault] diff --git a/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationService.cs b/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationService.cs index 662fe3180..5d6297496 100644 --- a/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationService.cs +++ b/IRaCIS.Core.Application/Service/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationService.cs @@ -18,6 +18,7 @@ using Panda.DynamicWebApi.Attributes; using IRaCIS.Core.Domain.Share.Reading; using System.Runtime.InteropServices; using DocumentFormat.OpenXml.Bibliography; +using System.Linq.Expressions; namespace IRaCIS.Core.Application.Service { @@ -38,12 +39,15 @@ namespace IRaCIS.Core.Application.Service private readonly IRepository _trialReadingQuestionRepository; + private readonly IRepository _visitTaskRepository; + private readonly IVisitTaskHelpeService _IVisitTaskHelpeService; + private readonly IRepository _taskMedicalReviewRepository; public SubjectCriteriaEvaluationService(IRepository subjectCriteriaEvaluationRepository, IRepository subjectRepository, IRepository subjectCriteriaEvaluationVisitFilterRepository, IRepository subjectVisitRepository, IRepository subjectCriteriaEvaluationVisitStudyFilterRepository, - IRepository trialReadingCriterionRepository, IVisitTaskHelpeService IVisitTaskHelpeService, IRepository trialReadingQuestionRepository) + IRepository trialReadingCriterionRepository, IVisitTaskHelpeService IVisitTaskHelpeService, IRepository trialReadingQuestionRepository, IRepository visitTaskRepository, IRepository taskMedicalReviewRepository) { _subjectCriteriaEvaluationRepository = subjectCriteriaEvaluationRepository; _subjectRepository = subjectRepository; @@ -55,7 +59,8 @@ namespace IRaCIS.Core.Application.Service _IVisitTaskHelpeService = IVisitTaskHelpeService; _trialReadingQuestionRepository = trialReadingQuestionRepository; - + _visitTaskRepository = visitTaskRepository; + _taskMedicalReviewRepository = taskMedicalReviewRepository; } @@ -65,14 +70,14 @@ namespace IRaCIS.Core.Application.Service /// /// [HttpPost] - public async Task<(PageOutput,object)> GetSubjectCriteriaEvaluationList(SubjectCriteriaEvaluationQuery inQuery) + public async Task<(PageOutput, object)> GetSubjectCriteriaEvaluationList(SubjectCriteriaEvaluationQuery inQuery) { var trialReadingCritionList = _trialReadingCriterionRepository.Where(t => t.TrialId == inQuery.TrialId).ToList(); var resultTrialReadingCriterionId = Guid.Empty; - var resultTrialReadingCriterion = trialReadingCritionList.First(); + var resultTrialReadingCriterion = trialReadingCritionList.First(); var curentCriterionType = CriterionType.NoCriterion; @@ -89,15 +94,15 @@ namespace IRaCIS.Core.Application.Service var addtionalQustionInfoList = _trialReadingQuestionRepository.Where(t => t.ReadingQuestionCriterionTrialId == resultTrialReadingCriterionId && t.IsAdditional == true && t.Type != "group").IgnoreQueryFilters().Select(t => new { - QuestionId= t.Id, + QuestionId = t.Id, t.QuestionEnName, t.QuestionName }).ToList(); - var questionIdList= addtionalQustionInfoList.Select(t=>t.QuestionId).ToList(); + var questionIdList = addtionalQustionInfoList.Select(t => t.QuestionId).ToList(); - var subjectCriteriaEvaluationQueryable = from subject in _subjectRepository.Where(t=>t.TrialId==inQuery.TrialId) + var subjectCriteriaEvaluationQueryable = from subject in _subjectRepository.Where(t => t.TrialId == inQuery.TrialId) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubjectCode), t => t.Code.Contains(inQuery.SubjectCode)) .WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteCode), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteCode)) .WhereIf(inQuery.SubjectStatus != null, t => t.Status == inQuery.SubjectStatus) @@ -120,25 +125,18 @@ namespace IRaCIS.Core.Application.Service IsJoinEvaluation = subjectCriteriaEvaluation.IsJoinEvaluation, - ReadingEvaluationList= subject.ReadingTaskQuestionAnswerList - .Where(t=>t.ReadingQuestionCriterionTrialId == resultTrialReadingCriterionId && + ReadingEvaluationList = subject.ReadingTaskQuestionAnswerList + .Where(t => t.ReadingQuestionCriterionTrialId == resultTrialReadingCriterionId && questionIdList.Contains(t.ReadingQuestionTrialId) - && t.VisitTask.TaskState==TaskState.Effect) - .Select(u=>new EvaluationInfo() + && t.VisitTask.TaskState == TaskState.Effect) + .Select(u => new EvaluationInfo() { - QuestionId=u.ReadingQuestionTrialId, - Answer=u.Answer, - - FinalTranslateDictionaryCode=u.ReadingQuestionTrial.DictionaryCode + QuestionId = u.ReadingQuestionTrialId, + Answer = u.Answer, + + FinalTranslateDictionaryCode = u.ReadingQuestionTrial.DictionaryCode }).ToList() - //EvaluationList=subject - //.SubjectAdditionalEvaluationResult - //.Where(t=>t.IsFinalResult && t.TrialReadingCriterionId==resultTrialReadingCriterionId) - //.Select(u=>new EvaluationInfo() - //{ Answer=u.Answer,FinalTranslateDictionaryCode=u.FinalTranslateDictionaryCode,QuestioName=u.TrialReadingQuestion .QuestionName,QuestioNameEn=u.TrialReadingQuestion.QuestionEnName}).ToList() - - }; var pageList = await subjectCriteriaEvaluationQueryable.ToPagedListAsync(inQuery.PageIndex, inQuery.PageSize, inQuery.SortField == string.Empty ? nameof(SubjectCriteriaEvaluationView.SubjectCode) : inQuery.SortField, inQuery.Asc); @@ -153,33 +151,39 @@ namespace IRaCIS.Core.Application.Service if (resultTrialReadingCriterion.ReadingType == ReadingMethod.Double) { - if (item.ReadingEvaluationList.Count==2) + if (item.ReadingEvaluationList.Count == 2) { if (item.ReadingEvaluationList.All(t => t.Answer == 1.ToString())) { - item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId=item.ReadingEvaluationList.First().QuestionId, Answer = ((int)BrainMetastasisResult.Yes).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) - }); + item.FinalEvaluationList.Add(new EvaluationInfo() + { + QuestionId = item.ReadingEvaluationList.First().QuestionId, + Answer = ((int)BrainMetastasisResult.Yes).ToString(), + FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) + }); } else if (item.ReadingEvaluationList.All(t => t.Answer == 0.ToString())) { - item.FinalEvaluationList.Add(new EvaluationInfo() { + item.FinalEvaluationList.Add(new EvaluationInfo() + { QuestionId = item.ReadingEvaluationList.First().QuestionId, - Answer = ((int)BrainMetastasisResult.No).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) - }); + Answer = ((int)BrainMetastasisResult.No).ToString(), + FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) + }); } else if (item.ReadingEvaluationList.First().Answer != item.ReadingEvaluationList.Last().Answer) { - item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = item.ReadingEvaluationList.First().QuestionId, Answer = ((int)BrainMetastasisResult.Maybe).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult)}); + item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = item.ReadingEvaluationList.First().QuestionId, Answer = ((int)BrainMetastasisResult.Maybe).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) }); } else { } - + } else { - item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId= addtionalQustionInfoList.FirstOrDefault()?.QuestionId, Answer = ((int)BrainMetastasisResult.Unknown).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) }); + item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = addtionalQustionInfoList.FirstOrDefault()?.QuestionId, Answer = ((int)BrainMetastasisResult.Unknown).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) }); } } else if (resultTrialReadingCriterion.ReadingType == ReadingMethod.Single) @@ -204,7 +208,7 @@ namespace IRaCIS.Core.Application.Service { item.FinalEvaluationList.Add(new EvaluationInfo() { QuestionId = addtionalQustionInfoList.FirstOrDefault()?.QuestionId, Answer = ((int)BrainMetastasisResult.Unknown).ToString(), FinalTranslateDictionaryCode = nameof(BrainMetastasisResult) }); } - + } else { @@ -216,7 +220,7 @@ namespace IRaCIS.Core.Application.Service break; } } - + @@ -246,7 +250,7 @@ namespace IRaCIS.Core.Application.Service //找到一致性核查通过的访视 并且没有 自动影像筛选的数据 var subjectVisitIdList = await _subjectVisitRepository.Where(t => t.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId && t.CheckState == CheckStateEnum.CVPassed - && !t.SubjectCriteriaEvaluationVisitFilterList.Any(t=>t.TrialReadingCriterionId==addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId && t.SubjectId==addOrEditSubjectCriteriaEvaluation.SubjectId)).Select(t => t.Id) + && !t.SubjectCriteriaEvaluationVisitFilterList.Any(t => t.TrialReadingCriterionId == addOrEditSubjectCriteriaEvaluation.TrialReadingCriterionId && t.SubjectId == addOrEditSubjectCriteriaEvaluation.SubjectId)).Select(t => t.Id) .ToListAsync(); @@ -366,7 +370,7 @@ namespace IRaCIS.Core.Application.Service var subjectCriteriaEvaluationVisitFilter = await _subjectCriteriaEvaluationVisitFilterRepository.AddAsync(addItem); } - + foreach (var item in list) { @@ -413,15 +417,17 @@ namespace IRaCIS.Core.Application.Service .WhereIf(inQuery.ImageFilterState != null, t => t.ImageFilterState == inQuery.ImageFilterState) .WhereIf(inQuery.IsGeneratedTask != null, t => t.IsGeneratedTask == inQuery.IsGeneratedTask) on subjectVisit.Id equals subjectCriteriaEvaluationVisitFilter.SubjectVisitId - + //into d from subjectCriteriaEvaluationVisitFilter in d.DefaultIfEmpty() select new SubjectCriteriaEvaluationVisitFilterView() { VisitName = subjectVisit.VisitName, - VisitNum=subjectVisit.VisitNum, + VisitNum = subjectVisit.VisitNum, SubjectVisitId = subjectVisit.Id, + TrialId = subjectVisit.TrialId, SubjectId = subjectVisit.SubjectId, + SubjectCode= subjectVisit.Subject.Code, TrialReadingCriterionId = inQuery.TrialReadingCriterionId, LatestScanDate = subjectVisit.LatestScanDate, EarliestScanDate = subjectVisit.LatestScanDate, @@ -431,14 +437,14 @@ namespace IRaCIS.Core.Application.Service Id = subjectCriteriaEvaluationVisitFilter.Id, CreateTime = subjectCriteriaEvaluationVisitFilter.CreateTime, - CreateUserId=subjectCriteriaEvaluationVisitFilter.CreateUserId, - UpdateTime= subjectCriteriaEvaluationVisitFilter.UpdateTime, - UpdateUserId= subjectCriteriaEvaluationVisitFilter.UpdateUserId, + CreateUserId = subjectCriteriaEvaluationVisitFilter.CreateUserId, + UpdateTime = subjectCriteriaEvaluationVisitFilter.UpdateTime, + UpdateUserId = subjectCriteriaEvaluationVisitFilter.UpdateUserId, }; - return await subjectCriteriaEvaluationVisitFilterQueryable.OrderBy(t=>t.VisitNum).ToListAsync(); + return await subjectCriteriaEvaluationVisitFilterQueryable.OrderBy(t => t.VisitNum).ToListAsync(); } /// @@ -467,28 +473,20 @@ namespace IRaCIS.Core.Application.Service && t.TrialReadingCriterionId == batchGenerateTaskCommand.TrialReadingCriterionId && batchGenerateTaskCommand.SubjectVisitIdList.Contains(t.SubjectVisitId), u => new SubjectCriteriaEvaluationVisitFilter { IsGeneratedTask = true }); - await _IVisitTaskHelpeService.BaseCritrionGenerateVisitTask(batchGenerateTaskCommand.TrialId, batchGenerateTaskCommand.TrialReadingCriterionId, true, batchGenerateTaskCommand.SubjectVisitIdList); + //自动生成任务 + + var idList = batchGenerateTaskCommand.SubjectVisitIdList.Select(t => (Guid?)t).ToList(); + + //存在任务的访视 + var haveGenerateVisitIdList = await _repository.Where(t => idList.Contains(t.SourceSubjectVisitId) && t.TrialReadingCriterionId == batchGenerateTaskCommand.TrialReadingCriterionId && t.TaskState == TaskState.Effect) + .Select(t => t.SourceSubjectVisitId).ToListAsync(); + + var generateVisitIdList = idList.Except(haveGenerateVisitIdList); + + await _IVisitTaskHelpeService.BaseCritrionGenerateVisitTask(batchGenerateTaskCommand.TrialId, batchGenerateTaskCommand.TrialReadingCriterionId, true, generateVisitIdList.Select(t => (Guid)t).ToList()); } - ///// - ///// 评估访视 判断结果 影像筛选状态 手动添加/编辑接口 - ///// - ///// - ///// - //public async Task AddOrUpdateSubjectCriteriaEvaluationVisitFilter(SubjectCriteriaEvaluationVisitFilterAddOrEdit addOrEditSubjectCriteriaEvaluationVisitFilter) - //{ - - // var entity = await _subjectCriteriaEvaluationVisitFilterRepository.InsertOrUpdateAsync(addOrEditSubjectCriteriaEvaluationVisitFilter, true); - - // return ResponseOutput.Ok(entity.Id.ToString()); - - //} - - - - - /// /// 获取dicom 访视检查列表 (序列的 Id CreateTime 是否为空 代表了记录是否创建、IsConfirmed 代表 保存 确认) /// @@ -516,7 +514,7 @@ namespace IRaCIS.Core.Application.Service SeriesNumber = series.SeriesNumber, SeriesTime = series.SeriesTime, - InstanceCount=series.InstanceCount, + InstanceCount = series.InstanceCount, StudyTime = series.DicomStudy.StudyTime, StudyId = series.StudyId, SeriesId = series.Id, @@ -524,7 +522,7 @@ namespace IRaCIS.Core.Application.Service TrialReadingCriterionId = inQuery.TrialReadingCriterionId, - IsReading=visitStudyFilter.IsReading, + IsReading = visitStudyFilter.IsReading, Id = visitStudyFilter.Id, CreateTime = visitStudyFilter.CreateTime, IsConfirmed = visitStudyFilter.IsConfirmed, @@ -567,8 +565,8 @@ namespace IRaCIS.Core.Application.Service u => new SubjectCriteriaEvaluationVisitFilter() { ImageFilterState = ImageFilterState.Finished }); } - - + + await _subjectCriteriaEvaluationVisitStudyFilterRepository.SaveChangesAsync(); return ResponseOutput.Ok(); @@ -576,13 +574,122 @@ namespace IRaCIS.Core.Application.Service - //[HttpDelete("{subjectCriteriaEvaluationId:guid}")] - // public async Task DeleteSubjectCriteriaEvaluation(Guid subjectCriteriaEvaluationId) - //{ - // var success = await _subjectCriteriaEvaluationRepository.DeleteFromQueryAsync(t => t.Id == subjectCriteriaEvaluationId,true); - // return ResponseOutput.Ok(); - //} + /// + /// 附加评估标准 PM 退回某一访视 影响任务列表 + /// + /// + /// + [HttpPost] + + public async Task> GetCriteriaVisitBackInfluenceTaskList(CriteriaVisitBackCommand command) + { + var filterExpression = await GetTaskExpressionAsync(command); + + var list = await _visitTaskRepository.Where(filterExpression) + + .OrderBy(t => t.VisitTaskNum).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); + + return list; + } + + private async Task>> GetTaskExpressionAsync(CriteriaVisitBackCommand command) + { + var criterionConfig = (await _trialReadingCriterionRepository.Where(x => x.Id == command.TrialReadingCriterionId).Select(x => new { x.ReadingTool, x.IsReadingTaskViewInOrder }).FirstOrDefaultAsync()).IfNullThrowException(); + + var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == command.SubjectVisitId); + + //仅仅影响该标准自己的任务 + Expression> filterExpression = t => t.TrialId == command.TrialId && t.SubjectId == command.SubjectId && t.TaskState == TaskState.Effect && t.TaskAllocationState == TaskAllocationState.Allocated + && t.TrialReadingCriterionId == command.TrialReadingCriterionId; + + //有序 + if (criterionConfig.IsReadingTaskViewInOrder) + { + filterExpression = filterExpression.And(t => t.VisitTaskNum >= subjectVisit.VisitNum); + } + else + { + filterExpression = filterExpression.And(t => t.VisitTaskNum == subjectVisit.VisitNum); + } + + return filterExpression; + } + + /// + /// 退回任务 + /// + /// + /// + public async Task ConfirmBackCriteriaVisitTask(CriteriaVisitBackCommand command) + { + var filterExpression = await GetTaskExpressionAsync(command); + + var influenceTaskList = await _visitTaskRepository.Where(filterExpression, true).ToListAsync(); + + var subjectVisit = await _subjectVisitRepository.FindAsync(command.SubjectVisitId); + + foreach (var influenceTask in influenceTaskList) + { + //申请的访视 要不是重阅重置,要不就是失效 不会存在取消分配 + if (influenceTask.ReadingCategory == ReadingCategory.Visit && influenceTask.VisitTaskNum != subjectVisit.VisitNum) + { + //后续访视处理访视 + if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) + { + influenceTask.TaskState = TaskState.HaveReturned; + + } + else if (influenceTask.ReadingTaskState == ReadingTaskState.Reading) + { + influenceTask.TaskState = TaskState.Adbandon; + } + else + { + influenceTask.DoctorUserId = null; + influenceTask.AllocateTime = null; + influenceTask.SuggesteFinishedTime = null; + influenceTask.TaskAllocationState = TaskAllocationState.NotAllocate; + + } + } + else + { + //申请的访视 全局肿瘤学 + + if (influenceTask.ReadingTaskState == ReadingTaskState.HaveSigned) + { + influenceTask.TaskState = TaskState.HaveReturned; + } + else + { + influenceTask.TaskState = TaskState.Adbandon; + } + + } + } + + var taskIdList = influenceTaskList.Select(t => t.Id).ToList(); + var subjectVisitIdLsit = influenceTaskList.Where(t => t.SourceSubjectVisitId != null).Select(t => t.SourceSubjectVisitId).ToList(); + + //医学审核任务失效 + await _taskMedicalReviewRepository.UpdatePartialFromQueryAsync(t => taskIdList.Contains(t.VisitTaskId) && t.AuditState != MedicalReviewAuditState.HaveSigned, u => new TaskMedicalReview() { IsInvalid = true }); + + //将筛选的访视 序列状态重置 + + //重置访视数据 + await _subjectCriteriaEvaluationVisitFilterRepository.BatchUpdateNoTrackingAsync(t => t.TrialReadingCriterionId== command.TrialReadingCriterionId && t.SubjectId == command.SubjectId && subjectVisitIdLsit.Contains(t.SubjectVisitId) , + t=>new SubjectCriteriaEvaluationVisitFilter() + { + ImageFilterState=ImageFilterState.None, + ImageDeterminationResultState=ImageDeterminationResultState.None + }); + + //删除序列数据 + await _subjectCriteriaEvaluationVisitStudyFilterRepository.BatchDeleteNoTrackingAsync(t => t.TrialReadingCriterionId == command.TrialReadingCriterionId && subjectVisitIdLsit.Contains(t.SubjectVisitId)); + + await _visitTaskRepository.SaveChangesAsync(); + } } } diff --git a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs index f1e9dfd6d..ae384aa17 100644 --- a/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs +++ b/IRaCIS.Core.Application/Service/Visit/SubjectVisitService.cs @@ -30,6 +30,9 @@ namespace IRaCIS.Core.Application.Services private readonly IRepository _readingPeriodPlanRepository; private readonly IRepository _subjectRepository; + private readonly IRepository _trialReadingCriterionRepository; + private readonly IRepository _subjectCriteriaEvaluationVisitStudyFilterRepository; + public SubjectVisitService(IRepository subjectVisitRepository, IRepository clinicalDataTrialSetRepository, IRepository readingClinicalDataRepository, @@ -42,7 +45,11 @@ namespace IRaCIS.Core.Application.Services IRepository readingTableAnswerRowInfoRepository, IRepository noneDicomStudyFileRepository, IRepository readingPeriodPlanRepository, - IRepository subjectRepository) + IRepository subjectRepository, + IRepository trialReadingCriterionRepository, + IRepository subjectCriteriaEvaluationVisitStudyFilterRepository + + ) { _subjectVisitRepository = subjectVisitRepository; this._clinicalDataTrialSetRepository = clinicalDataTrialSetRepository; @@ -57,6 +64,10 @@ namespace IRaCIS.Core.Application.Services this._noneDicomStudyFileRepository = noneDicomStudyFileRepository; this._readingPeriodPlanRepository = readingPeriodPlanRepository; _subjectRepository = subjectRepository; + _trialReadingCriterionRepository = trialReadingCriterionRepository; + _subjectCriteriaEvaluationVisitStudyFilterRepository = subjectCriteriaEvaluationVisitStudyFilterRepository; + + } [HttpPost] @@ -411,7 +422,13 @@ namespace IRaCIS.Core.Application.Services } - var studyList = await _repository.Where(t => t.TrialId == indto.TrialId && t.SubjectVisitId == indto.SujectVisitId).Select(k => new VisitStudyDTO() + //如果是手动生成的标准,需要过滤检查和序列数据 + + var isManualGenerate = await _trialReadingCriterionRepository.AnyAsync(t => t.Id == taskInfo.TrialReadingCriterionId && t.IsAutoCreate == false); + + var studyList = await _repository.Where(t => t.TrialId == indto.TrialId && t.SubjectVisitId == indto.SujectVisitId) + .WhereIf(isManualGenerate,t=>t.SubjectCriteriaEvaluationVisitStudyFilterList.Any(t=>t.TrialReadingCriterionId==taskInfo.TrialReadingCriterionId && t.IsConfirmed &&t.IsReading )) + .Select(k => new VisitStudyDTO() { InstanceCount = k.InstanceCount, Modalities = k.Modalities, @@ -427,7 +444,10 @@ namespace IRaCIS.Core.Application.Services - List seriesLists = await _repository.Where(s => studyIds.Contains(s.StudyId) && s.IsReading).OrderBy(s => s.SeriesNumber). + List seriesLists = await _repository.Where(s => studyIds.Contains(s.StudyId) /*&& s.IsReading*/) + .WhereIf(isManualGenerate==false, t => t.IsReading) + .WhereIf(isManualGenerate, t => t.SubjectCriteriaEvaluationVisitStudyFilterList.Any(t => t.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && t.IsConfirmed && t.IsReading)) + .OrderBy(s => s.SeriesNumber). ThenBy(s => s.SeriesTime) .ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); foreach (var t in studyList) @@ -533,7 +553,6 @@ namespace IRaCIS.Core.Application.Services result = result.Where(x => x.SeriesCount > 0).ToList(); return result; - //return ResponseOutput.Ok(studyList.Where(t => t.SeriesList.Count > 0).ToList()); } diff --git a/IRaCIS.Core.Domain/Image/DicomSeries.cs b/IRaCIS.Core.Domain/Image/DicomSeries.cs index 094c4f623..e9a449b63 100644 --- a/IRaCIS.Core.Domain/Image/DicomSeries.cs +++ b/IRaCIS.Core.Domain/Image/DicomSeries.cs @@ -13,7 +13,10 @@ namespace IRaCIS.Core.Domain.Models public DicomStudy DicomStudy { get; set; } [JsonIgnore] - public List DicomInstanceList { get; set; } + public List DicomInstanceList { get; set; } + + [JsonIgnore] + public List SubjectCriteriaEvaluationVisitStudyFilterList { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.Identity)] diff --git a/IRaCIS.Core.Domain/Image/DicomStudy.cs b/IRaCIS.Core.Domain/Image/DicomStudy.cs index eb5b0ec4c..700e13c91 100644 --- a/IRaCIS.Core.Domain/Image/DicomStudy.cs +++ b/IRaCIS.Core.Domain/Image/DicomStudy.cs @@ -19,6 +19,9 @@ namespace IRaCIS.Core.Domain.Models [JsonIgnore] public Site Site { get; set; } + [JsonIgnore] + public List SubjectCriteriaEvaluationVisitStudyFilterList { get; set; } + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Guid SeqId { get; set; } diff --git a/IRaCIS.Core.Domain/Reading/AdditionalEvaluate/SubjectCriteriaEvaluation.cs b/IRaCIS.Core.Domain/Reading/AdditionalEvaluate/SubjectCriteriaEvaluation.cs index 72d1a76c0..1a6fcafca 100644 --- a/IRaCIS.Core.Domain/Reading/AdditionalEvaluate/SubjectCriteriaEvaluation.cs +++ b/IRaCIS.Core.Domain/Reading/AdditionalEvaluate/SubjectCriteriaEvaluation.cs @@ -19,11 +19,15 @@ namespace IRaCIS.Core.Domain.Models { [JsonIgnore] public Subject subject { get; set; } - - /// + + [JsonIgnore] + [ForeignKey("TrialReadingCriterionId")] + public ReadingQuestionCriterionTrial TrialReadingCriterion { get; set; } + + /// /// SubjectId /// - [Required] + [Required] public Guid SubjectId { get; set; } /// diff --git a/IRaCIS.Core.Domain/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationVisitFilter.cs b/IRaCIS.Core.Domain/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationVisitFilter.cs index 3586e0e0d..e5ec08770 100644 --- a/IRaCIS.Core.Domain/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationVisitFilter.cs +++ b/IRaCIS.Core.Domain/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationVisitFilter.cs @@ -16,9 +16,15 @@ namespace IRaCIS.Core.Domain.Models public class SubjectCriteriaEvaluationVisitFilter : Entity, IAuditUpdate, IAuditAdd { + [JsonIgnore] + [ForeignKey("TrialReadingCriterionId")] + public ReadingQuestionCriterionTrial TrialReadingCriterion { get; set; } + [JsonIgnore] public SubjectCriteriaEvaluation SubjectCriteriaEvaluation { get; set; } + [JsonIgnore] + public SubjectVisit SubjectVisit { get; set; } public Guid SubjectId { get; set; } diff --git a/IRaCIS.Core.Domain/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationVisitStudyFilter.cs b/IRaCIS.Core.Domain/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationVisitStudyFilter.cs index a2e6cfa9e..c9fe5ef1d 100644 --- a/IRaCIS.Core.Domain/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationVisitStudyFilter.cs +++ b/IRaCIS.Core.Domain/Reading/AdditionalEvaluate/SubjectCriteriaEvaluationVisitStudyFilter.cs @@ -15,7 +15,9 @@ namespace IRaCIS.Core.Domain.Models [Table("SubjectCriteriaEvaluationVisitStudyFilter")] public class SubjectCriteriaEvaluationVisitStudyFilter : Entity, IAuditUpdate, IAuditAdd { - + [JsonIgnore] + [ForeignKey("TrialReadingCriterionId")] + public ReadingQuestionCriterionTrial TrialReadingCriterion { get; set; } [JsonIgnore] public SubjectVisit SubjectVisit { get; set; }