using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.Service.Reading.Dto; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infra.EFCore.Common; using IRaCIS.Core.Infrastructure; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Panda.DynamicWebApi.Attributes; namespace IRaCIS.Core.Application.Service { /// /// 肿瘤学 /// public partial class ReadingImageTaskService : BaseService, IReadingImageTaskService { #region 肿瘤学阅片相关 /// /// 获取肿瘤学任务信息 /// /// /// /// [HttpPost] public async Task GetOncologyReadingInfo(GetOncologyReadingInfoInDto inDto) { var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.TrialReadingCriterion).FirstNotNullAsync(); if (taskInfo.ReadingCategory != ReadingCategory.Oncology) { throw new BusinessValidationFailedException(_localizer["ReadingOncology_TaskError"]); } var trialCriterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskInfo.TrialReadingCriterionId).FirstOrDefaultAsync(); GetOncologyReadingInfoOutDto result = new GetOncologyReadingInfoOutDto() { //TrialEvaluationResult = trialCriterion.EvaluationResult, IsShowDetail = trialCriterion.IsShowDetail, TrialEvaluationReason = trialCriterion.EvaluationReason, OncologyTaskId = inDto.VisitTaskId, ReadingTaskState = taskInfo.ReadingTaskState, }; // 先找到是R1还是R2的阅片 先找到全局阅片 VisitTask? globalOrVisitTaskInfo = null; var relatedVisitTaskIdList = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.RelatedVisitTaskIdList).FirstNotNullAsync(); Guid? judgeResultTaskId = null; if (taskInfo.ReadingTaskState == ReadingTaskState.HaveSigned && relatedVisitTaskIdList.Count() > 0) { judgeResultTaskId = await _visitTaskRepository.Where(x => x.Id == relatedVisitTaskIdList[0]).Select(x => x.JudgeResultTaskId).FirstOrDefaultAsync(); // 说明是裁判 取裁判结果 if (judgeResultTaskId != null) { globalOrVisitTaskInfo = await _visitTaskRepository.Where(x => x.Id == judgeResultTaskId).FirstNotNullAsync(); } else { globalOrVisitTaskInfo = await _visitTaskRepository.Where(x => x.Id == relatedVisitTaskIdList[0]).FirstNotNullAsync(); } } else { var taskNums = new List() { // 全局 (decimal) (taskInfo.VisitTaskNum - ReadingCommon.TaskNumDic[ReadingCategory.Oncology] + ReadingCommon.TaskNumDic[ReadingCategory.Global]), // 访视 (decimal)(taskInfo.VisitTaskNum - ReadingCommon.TaskNumDic[ReadingCategory.Oncology]) }; globalOrVisitTaskInfo = await _visitTaskRepository .Where(x => x.SubjectId == taskInfo.SubjectId && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && taskNums.Contains(x.VisitTaskNum) && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate && x.IsSelfAnalysis == taskInfo.IsSelfAnalysis && x.VisitTaskNum < taskInfo.VisitTaskNum ) .WhereIf(taskInfo.TrialReadingCriterion.IsGlobalReading, x => x.ReadingCategory == ReadingCategory.Global) .WhereIf(!taskInfo.TrialReadingCriterion.IsGlobalReading, x => x.ReadingCategory == ReadingCategory.Visit) .OrderByDescending(x => x.VisitTaskNum).ThenBy(x => x.ArmEnum) .FirstNotNullAsync(); } // 最后取哪组的数据 //VisitTask visitTask = new VisitTask(); List visitTaskIdList = new List(); // 判断是否产生裁判 if (globalOrVisitTaskInfo!.JudgeVisitTaskId == null) { //visitTask = globalTaskInfo; // 全局的关联访视 visitTaskIdList = await _visitTaskRepository.Where(x => x.Id == globalOrVisitTaskInfo.Id).Select(x => x.RelatedVisitTaskIdList).FirstNotNullAsync(); } else { if (judgeResultTaskId == null) { judgeResultTaskId = await _visitTaskRepository.Where(x => x.Id == globalOrVisitTaskInfo.JudgeVisitTaskId).Select(x => x.JudgeResultTaskId).FirstOrDefaultAsync(); if (judgeResultTaskId == null) { throw new BusinessValidationFailedException(_localizer["ReadingOncology_Abnormal"]); } } //visitTask = await _visitTaskRepository.Where(x => x.Id == judgeResultTaskId).FirstNotNullAsync(); visitTaskIdList = await _visitTaskRepository.Where(x => x.Id == judgeResultTaskId).Select(x => x.RelatedVisitTaskIdList).FirstNotNullAsync(); globalOrVisitTaskInfo = await _visitTaskRepository.Where(x => x.Id == judgeResultTaskId).FirstNotNullAsync(); } result.RelatedTaskId = globalOrVisitTaskInfo!.JudgeVisitTaskId ?? globalOrVisitTaskInfo.Id; result.ReadingCategory = globalOrVisitTaskInfo.ReadingCategory; result.GlobalOrVisitTaskId = globalOrVisitTaskInfo.Id; result.SubjectId = globalOrVisitTaskInfo.SubjectId; List globalVisits = new List(); if (result.ReadingCategory == ReadingCategory.Global) { globalVisits = (await this.GetGlobalReadingInfo(new GetGlobalReadingInfoInDto() { UsingOriginalData = true, VisitTaskId = result.GlobalOrVisitTaskId })).TaskList; } else { // 按照全局那边的查询法 globalVisits = await _visitTaskRepository.Where(x => x.TrialId == globalOrVisitTaskInfo.TrialId && x.SubjectId == globalOrVisitTaskInfo.SubjectId && x.ReadingCategory == ReadingCategory.Visit && x.TrialReadingCriterionId == globalOrVisitTaskInfo.TrialReadingCriterionId && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.IsAnalysisCreate == globalOrVisitTaskInfo.IsAnalysisCreate && x.ArmEnum == globalOrVisitTaskInfo.ArmEnum && x.IsSelfAnalysis == globalOrVisitTaskInfo.IsSelfAnalysis && x.ArmEnum == globalOrVisitTaskInfo.ArmEnum && x.TaskState == TaskState.Effect && x.VisitTaskNum <= globalOrVisitTaskInfo.VisitTaskNum) .OrderBy(x => x.VisitTaskNum).Select(x => new GlobalVisitInfo() { VisitName = x.TaskName, BlindName = x.TaskBlindName, VisitTaskId = x.Id, IsConvertedTask = x.IsConvertedTask, IsFirstChangeTask = x.IsConvertedTask && x.BeforeConvertedTaskId != null, ArmEnum = globalOrVisitTaskInfo.ArmEnum, VisitNum = x.SourceSubjectVisit.VisitNum, IsBaseLine = x.SourceSubjectVisit.IsBaseLine, VisitId = x.SourceSubjectVisitId!.Value, LesionCountList = x.LesionList.GroupBy(y => y.ReadingQuestionTrial.LesionType).Select(x => new LesionDto { LesionType = x.Key!.Value, Count = x.ToList().Count() }).ToList(), //CrterionDictionaryGroup= x.CrterionDictionaryGroup, AfterQuestionList = x.ReadingTaskQuestionAnswerList.Where(y => y.ReadingQuestionTrial.GlobalReadingShowType != GlobalReadingShowType.NotShow).OrderBy(y => y.ReadingQuestionTrial.ShowOrder) .Select(y => new GlobalQuestionInfo() { QuestionId = y.ReadingQuestionTrialId, QuestionName = y.ReadingQuestionTrial.QuestionName.LanguageName(y.ReadingQuestionTrial.QuestionEnName, _userInfo.IsEn_Us), QuestionEnName = y.ReadingQuestionTrial.QuestionEnName, AnswerGroup = y.ReadingQuestionTrial.AnswerGroup, QuestionType = y.ReadingQuestionTrial.QuestionType, LimitEdit = y.ReadingQuestionTrial.LimitEdit, MaxAnswerLength = y.ReadingQuestionTrial.MaxAnswerLength, FileType = y.ReadingQuestionTrial.FileType, QuestionGenre = y.ReadingQuestionTrial.QuestionGenre, DictionaryCode = y.ReadingQuestionTrial.DictionaryCode, GlobalReadingShowType = y.ReadingQuestionTrial.GlobalReadingShowType, AnswerCombination = y.ReadingQuestionTrial.AnswerCombination, JudgeType = y.ReadingQuestionTrial.JudgeType, ShowOrder = y.ReadingQuestionTrial.ShowOrder, Type = y.ReadingQuestionTrial.Type, TypeValue = y.ReadingQuestionTrial.TypeValue, ValueType = y.ReadingQuestionTrial.ValueType, IsJudgeQuestion = y.ReadingQuestionTrial.IsJudgeQuestion, Answer = y.Answer, }).ToList() }).ToListAsync(); } // 找到对应的访视 List oncologyVisits = await _visitTaskRepository.Where(x => visitTaskIdList.Contains(x.Id)) .OrderBy(x => x.VisitTaskNum).Select(x => new OncologyVisitTaskInfo() { VisitName = x.SourceSubjectVisit.VisitName, IsBaseLine = x.SourceSubjectVisit.IsBaseLine, VisitNum = x.SourceSubjectVisit.VisitNum, VisitTaskId = x.Id, // QuestionList = x.ReadingTaskQuestionAnswerList.Where(y => y.ReadingQuestionTrial.IsJudgeQuestion).OrderBy(y => y.ReadingQuestionTrial.ShowOrder) //.Select(y => new OncologyQuestion() //{ // QuestionId = y.ReadingQuestionTrialId, // QuestionName = y.ReadingQuestionTrial.QuestionName, // Answer = y.GlobalChangeAnswer //}).ToList() }).ToListAsync(); var oncologyReadingQuestions = await _readingOncologyTaskInfoRepository.Where(x => x.OncologyTaskId == inDto.VisitTaskId).Include(x => x.VisitTask).ToListAsync(); // 上一次肿瘤学阅片 var lastOncologyTask = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Oncology && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && x.TaskState == TaskState.Effect && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate && x.VisitTaskNum < taskInfo.VisitTaskNum ).OrderByDescending(x => x.VisitTaskNum).FirstOrDefaultAsync(); List lastOncologyAnswerList = new List(); if (lastOncologyTask != null && taskInfo.TaskState == TaskState.Effect && taskInfo.ReadingTaskState != ReadingTaskState.HaveSigned) { lastOncologyAnswerList = await _readingOncologyTaskInfoRepository.Where(x => x.OncologyTaskId == lastOncologyTask.Id).Include(x => x.VisitTask).ToListAsync(); } oncologyVisits.ForEach(x => { var oncologyData = oncologyReadingQuestions.Where(y => y.VisitTaskId == x.VisitTaskId).FirstOrDefault(); /// 根据任务编号匹配 不区分 r1 r2 var lastOncologyData = lastOncologyAnswerList.Where(y => y.VisitTask.VisitTaskNum == x.VisitNum).FirstOrDefault(); var evaluationResult = string.Empty; var evaluationReason = string.Empty; if (oncologyData != null && !oncologyData.EvaluationResult.IsNullOrEmpty()) { evaluationResult = oncologyData.EvaluationResult; } else if (lastOncologyData != null && !lastOncologyData.EvaluationResult.IsNullOrEmpty()) { evaluationResult = lastOncologyData.EvaluationResult; } if (oncologyData != null && !oncologyData.EvaluationReason.IsNullOrEmpty()) { evaluationReason = oncologyData.EvaluationReason; } else if (lastOncologyData != null && !lastOncologyData.EvaluationReason.IsNullOrEmpty()) { evaluationReason = lastOncologyData.EvaluationReason; } x.EvaluationResult = evaluationResult; x.EvaluationReason = evaluationReason; x.QuestionList = globalVisits.Where(y => x.VisitTaskId == y.VisitTaskId).SelectMany(y => y.AfterQuestionList).Where(x => x.GlobalAnswerType == GlobalAnswerType.Question) .Select(y => new OncologyQuestion { QuestionId = y.QuestionId ?? default(Guid), QuestionName = y.QuestionName, QuestionGenre = y.QuestionGenre, DictionaryCode = y.DictionaryCode, Answer = y.Answer }).ToList(); x.IsHaveChange = result.ReadingCategory == ReadingCategory.Visit ? false : globalVisits.Where(y => x.VisitTaskId == y.VisitTaskId).SelectMany(y => y.AfterQuestionList).Any(y => y.IsHaveChange); x.VisitRemark = result.ReadingCategory == ReadingCategory.Visit ? string.Empty : globalVisits.Where(y => x.VisitTaskId == y.VisitTaskId).SelectMany(y => y.AfterQuestionList).Where(y => y.GlobalAnswerType == GlobalAnswerType.Reason).Select(x => x.Answer).FirstOrDefault() ?? string.Empty; }); result.OncologyVisits = oncologyVisits; List assessTypeList = await _readingTrialCriterionDictionaryRepository.Where(x => x.CriterionId == taskInfo.TrialReadingCriterionId && x.ParentCode == ReadingCommon.CriterionDictionary.OncologyAssess ) .Select(x => new CriterionDictionaryInfo() { Id = x.Id, DictionaryId = x.DictionaryId, ChildGroup = x.Dictionary.ChildGroup, Code = x.Dictionary.Code, Description = x.Dictionary.Description, ShowOrder = x.Dictionary.ShowOrder, ParentCode = x.Dictionary.Parent.Code, Value = x.Dictionary.Value, ValueCN = x.Dictionary.ValueCN }).OrderBy(x => x.ParentCode).ThenBy(x => x.ShowOrder).ToListAsync(); result.AssessTypeList = assessTypeList; return result; } /// /// 修改肿瘤学阅片信息 /// /// /// [HttpPost] [TrialGlobalLimit( "AfterStopCannNotOpt" )] public async Task SetOncologyReadingInfo(SetOncologyReadingInfoInDto inDto) { await VerifyTaskIsSign(inDto.OncologyTaskId); await _readingOncologyTaskInfoRepository.BatchDeleteNoTrackingAsync(x => x.OncologyTaskId == inDto.OncologyTaskId); var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.OncologyTaskId).FirstNotNullAsync(); List readingOncologies = inDto.OncologyQuestionList.Select(x => new ReadingOncologyTaskInfo() { EvaluationReason = x.EvaluationReason, SubjectId = taskInfo.SubjectId, EvaluationResult = x.EvaluationResult, OncologyTaskId = inDto.OncologyTaskId, TrialId = taskInfo.TrialId, VisitTaskId = x.VisitTaskId }).ToList(); await _readingOncologyTaskInfoRepository.AddRangeAsync(readingOncologies); var relatedVisitTaskIdList = new List(); relatedVisitTaskIdList.Add(inDto.RelatedTaskId); var relatedVisitTaskIds = JsonConvert.SerializeObject(relatedVisitTaskIdList); // 这里先保存 签名的时候 会统一创建关系 await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == inDto.OncologyTaskId, u => new VisitTask() { RelatedVisitTaskIds = relatedVisitTaskIds }); var result = await _readingOncologyTaskInfoRepository.SaveChangesAsync(); return ResponseOutput.Ok(result); } #endregion /// /// 添加肿瘤学阅片任务 其实这里无非是要判断临床数据是否签名 但是对于添加新的阅片期 其实没有临床数据 可以走之前的逻辑 /// /// [NonDynamicMethod] public async Task AddOncologyTask(Guid oncologModuleId) { // 判断是否读片完成 var finishReading = false; var readModuleInfo = await _readModuleRepository.Where(x => x.Id == oncologModuleId && x.ModuleType == ModuleTypeEnum.Oncology).FirstOrDefaultAsync(); // 如果当前是肿瘤学 if (readModuleInfo != null) { // 先找到对应的全局阅片模块Id var isGlobalReading = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == readModuleInfo.TrialReadingCriterionId).Select(x => x.IsGlobalReading).FirstOrDefaultAsync(); var globalOrVisitTaskId = default(Guid); var globalreadModule = await _readModuleRepository.Where(x => x.SubjectVisitId == readModuleInfo.SubjectVisitId && x.TrialReadingCriterionId == readModuleInfo.TrialReadingCriterionId && x.ModuleType == ModuleTypeEnum.Global).Include(x => x.SubjectVisit).FirstOrDefaultAsync(); // 获取系统配置 var readingType = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == readModuleInfo.TrialReadingCriterionId).Select(x => x.ReadingType).FirstOrDefaultAsync(); if (globalreadModule != null && isGlobalReading) { // 找到一个全局阅片任务是否有裁判任务 globalOrVisitTaskId = await _visitTaskRepository.Where(x => x.SouceReadModuleId == globalreadModule.Id && x.TaskState == TaskState.Effect && x.ReadingCategory == ReadingCategory.Global && x.ReadingTaskState == ReadingTaskState.HaveSigned).Select(x => x.Id).FirstOrDefaultAsync(); var judgeVisitTaskId = await _visitTaskRepository.Where(x => x.SouceReadModuleId == globalreadModule.Id && x.TaskState == TaskState.Effect && x.ReadingCategory == ReadingCategory.Global && x.ReadingTaskState == ReadingTaskState.HaveSigned).Select(x => x.JudgeVisitTaskId).FirstOrDefaultAsync(); // 要判断是否为老裁判任务的Id if (judgeVisitTaskId != null) { // 如果不存在有效的裁判 if (!(await _visitTaskRepository.AnyAsync(x => x.Id == judgeVisitTaskId && x.TaskState == TaskState.Effect))) { judgeVisitTaskId = null; } } // 判断阅片是否完成 if (judgeVisitTaskId == null && (await _visitTaskRepository.Where(x => x.SouceReadModuleId == globalreadModule.Id && x.TaskState == TaskState.Effect && x.ReadingCategory == ReadingCategory.Global && x.ReadingTaskState == ReadingTaskState.HaveSigned && !x.IsAnalysisCreate && x.TrialReadingCriterionId == readModuleInfo.TrialReadingCriterionId ).CountAsync() == (int)readingType)) { finishReading = true; } else if (judgeVisitTaskId != null && (await _visitTaskRepository.AnyAsync(x => x.Id == judgeVisitTaskId.Value && x.JudgeResultTaskId != null && x.ReadingTaskState == ReadingTaskState.HaveSigned))) { finishReading = true; } } else { var visitTask = await _visitTaskRepository.Where(x => x.SourceSubjectVisitId == readModuleInfo.SubjectVisitId && x.TaskState == TaskState.Effect && x.TrialReadingCriterionId == readModuleInfo.TrialReadingCriterionId && x.ReadingCategory == ReadingCategory.Visit && x.ReadingTaskState == ReadingTaskState.HaveSigned).FirstNotNullAsync(); globalOrVisitTaskId = visitTask.Id; var judgeVisitTaskId = visitTask.JudgeVisitTaskId; // 要判断是否为老裁判任务的Id if (judgeVisitTaskId != null) { // 如果不存在有效的裁判 if (!(await _visitTaskRepository.AnyAsync(x => x.Id == judgeVisitTaskId && x.TaskState == TaskState.Effect))) { judgeVisitTaskId = null; } } // 判断阅片是否完成 if (judgeVisitTaskId == null && (await _visitTaskRepository.Where(x => x.SourceSubjectVisitId == readModuleInfo.SubjectVisitId && x.TaskState == TaskState.Effect && x.ReadingTaskState == ReadingTaskState.HaveSigned && !x.IsAnalysisCreate && x.TrialReadingCriterionId == readModuleInfo.TrialReadingCriterionId ).CountAsync() == (int)readingType)) { finishReading = true; } else if (judgeVisitTaskId != null && (await _visitTaskRepository.AnyAsync(x => x.Id == judgeVisitTaskId.Value && x.JudgeResultTaskId != null && x.ReadingTaskState == ReadingTaskState.HaveSigned))) { finishReading = true; } } if (finishReading) { // 获取临床数据 var clinicalData = await _readingClinicalDataService.GetClinicalDataList(new GetReadingOrTaskClinicalDataListInDto() { SubjectId = readModuleInfo.SubjectId, ReadingId = readModuleInfo.Id, TrialId = readModuleInfo.TrialId, TrialReadingCriterionId = readModuleInfo.TrialReadingCriterionId, }); // 判断是否临床数据都已经签名 if (!clinicalData.Any(x => !x.IsSign)) { List needReadList = new List(); needReadList.Add(new ReadingGenerataTaskDTO() { IsUrgent = readModuleInfo.IsUrgent ?? false, SubjectId = readModuleInfo.SubjectId, ReadingName = readModuleInfo.ModuleName, //VisitNum = readModuleInfo.SubjectVisit.VisitNum, ReadModuleId = readModuleInfo.Id, ReadingCategory = ReadingCategory.Oncology, }); var originalVisit = await _visitTaskRepository.Where(x => x.Id == globalOrVisitTaskId ).OrderByDescending(x => x.VisitTaskNum).ThenBy(x => x.ArmEnum).FirstNotNullAsync(); var originalVisitId = default(Guid); if (originalVisit.JudgeVisitTaskId != null) { originalVisitId = (await _visitTaskRepository.Where(x => x.Id == originalVisit.JudgeVisitTaskId).Select(x => x.JudgeResultTaskId).FirstOrDefaultAsync()) ?? originalVisit.Id; } else { originalVisitId = originalVisit.Id; } await _visitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand() { OriginalVisitId = originalVisitId, ReadingCategory = GenerateTaskCategory.Oncology, TrialId = readModuleInfo.TrialId, ReadingGenerataTaskList = needReadList }); } } } } /// /// 提交肿瘤阅片结果 /// /// /// [NonDynamicMethod] public async Task SubmitOncologyReadingInfo(SubmitOncologyReadingInfoInDto inDto) { await VerifyTaskIsSign(inDto.OncologyTaskId); //var result = await this.SaveGlobalReadingInfo(inDto); //await FinishReadUpdateState(inDto.OncologyTaskId); await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.OncologyTaskId, x => new VisitTask() { ReadingTaskState = ReadingTaskState.HaveSigned, SignTime = DateTime.Now, }); await _visitTaskRepository.SaveChangesAsync(); // 创建任务关联关系 await this.CreateTaskRelated(inDto.OncologyTaskId); return ResponseOutput.Ok(true); } } }