using IRaCIS.Core.Domain.Share; using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Application.Service.Reading.Dto; using MassTransit; using IRaCIS.Core.Infra.EFCore.Common; using Panda.DynamicWebApi.Attributes; using AutoMapper; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Infrastructure; using Newtonsoft.Json; using IRaCIS.Core.Application.Service; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.Filter; namespace IRaCIS.Application.Services { /// /// 全局阅片 /// public partial class ReadingImageTaskService : BaseService, IReadingImageTaskService { /// /// 提交全局阅片结果 /// /// /// //[NonDynamicMethod] public async Task SubmitGlobalReadingInfo(SubmitGlobalReadingInfoInDto inDto) { //var result = await this.SaveGlobalReadingInfo(inDto); await VerifyTaskIsSign(inDto.GlobalTaskId); await this.SubmitTaskChangeState(inDto.GlobalTaskId); return ResponseOutput.Ok(true); } /// /// 批量提交全局阅片信息 /// /// /// [HttpPost] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] public async Task BatchSubmitGlobalReadingInfo(BatchSubmitGlobalReadingInfo inDto) { await VerifyTaskIsSign(inDto.GlobalTaskId); var criterionType = await _visitTaskRepository.Where(x => x.Id == inDto.GlobalTaskId).Select(x => x.TrialReadingCriterion.CriterionType).FirstNotNullAsync(); foreach (var item in inDto.VisitTaskAnswerList) { foreach (var answer in item.AnswerList) { await _readingGlobalTaskInfoRepository.BatchDeleteNoTrackingAsync(x => x.GlobalTaskId == inDto.GlobalTaskId && x.TaskId == item.VisitTaskId && x.GlobalAnswerType == answer.GlobalAnswerType && x.QuestionId == answer.QuestionId); if (criterionType == CriterionType.PCWG3) { await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.VisitTaskId && x.ReadingQuestionTrialId == answer.QuestionId && x.Answer != answer.Answer && answer.Answer != string.Empty && answer.Answer != null , x => new ReadingTaskQuestionAnswer() { Answer= answer.Answer, GlobalChangeAnswer = answer.Answer, IsGlobalChange = true, }); } else { await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.VisitTaskId && x.ReadingQuestionTrialId == answer.QuestionId && x.Answer != answer.Answer && answer.Answer != string.Empty && answer.Answer != null , x => new ReadingTaskQuestionAnswer() { GlobalChangeAnswer = answer.Answer, IsGlobalChange = true, }); } } } var answers= inDto.VisitTaskAnswerList.SelectMany(x => x.AnswerList.Select(y => new ReadingGlobalTaskInfo() { Answer = y.Answer, QuestionId = y.QuestionId, SubjectId = inDto.SubjectId, GlobalTaskId = inDto.GlobalTaskId, GlobalAnswerType = y.GlobalAnswerType, TaskId = x.VisitTaskId, TrialId = inDto.TrialId, })).ToList(); await _readingGlobalTaskInfoRepository.AddRangeAsync(answers); await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == inDto.GlobalTaskId, u => new VisitTask() { ReadingTaskState = ReadingTaskState.Reading }); var result = await _readingGlobalTaskInfoRepository.SaveChangesAsync(); return ResponseOutput.Ok(result); } #region 全局阅片相关 /// /// 保存全局阅片结果 /// /// /// [HttpPost] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] public async Task SaveGlobalReadingInfo(SaveGlobalReadingInfoInDto inDto) { await VerifyTaskIsSign(inDto.GlobalTaskId); var visitTaskId = inDto.QuestionList.Select(x => x.VisitTaskId).FirstOrDefault(); foreach (var item in inDto.QuestionList) { await _readingGlobalTaskInfoRepository.BatchDeleteNoTrackingAsync(x => x.GlobalTaskId == inDto.GlobalTaskId && x.TaskId == item.VisitTaskId && x.GlobalAnswerType == item.GlobalAnswerType && x.QuestionId == item.QuestionId); await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.VisitTaskId && x.ReadingQuestionTrialId == item.QuestionId && x.Answer != item.Answer && item.Answer != string.Empty && item.Answer != null , x => new ReadingTaskQuestionAnswer() { GlobalChangeAnswer = item.Answer, IsGlobalChange = true, }); } var createtime = DateTime.Now; await _readingGlobalTaskInfoRepository.AddRangeAsync(inDto.QuestionList.Select(x => new ReadingGlobalTaskInfo() { Answer = x.Answer, QuestionId = x.QuestionId, SubjectId = inDto.SubjectId, GlobalTaskId = inDto.GlobalTaskId, GlobalAnswerType = x.GlobalAnswerType, TaskId = x.VisitTaskId, TrialId = inDto.TrialId, CreateTime= createtime, }).ToList()); await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == inDto.GlobalTaskId, u => new VisitTask() { ReadingTaskState = ReadingTaskState.Reading }); var result = await _readingGlobalTaskInfoRepository.SaveChangesAsync(); return ResponseOutput.Ok(result); } /// /// 获取全局阅片信息 /// /// /// [HttpPost] public async Task GetGlobalReadingInfo(GetGlobalReadingInfoInDto inDto) { var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x=>x.Subject).FirstNotNullAsync(); if (taskInfo.ReadingCategory != ReadingCategory.Global) { throw new BusinessValidationFailedException(_localizer["ReadingGlobal_NotGlobal"]); } GetGlobalReadingInfoOutDto result = new GetGlobalReadingInfoOutDto() { GlobalTaskId = inDto.VisitTaskId, ReadingTaskState = taskInfo.ReadingTaskState, }; result.OtherGlobalTaskId = await _visitTaskRepository.Where(x => x.SouceReadModuleId == taskInfo.SouceReadModuleId && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate && x.IsSelfAnalysis == taskInfo.IsSelfAnalysis && x.TaskState == TaskState.Effect && x.DoctorUserId != taskInfo.DoctorUserId ).Select(x => x.Id).FirstOrDefaultAsync(); result.TaskBlindName = taskInfo.TaskBlindName; if (taskInfo.IsAnalysisCreate) { result.SubjectCode = taskInfo.BlindSubjectCode; } else { result.SubjectCode = taskInfo.Subject.Code; } var judgeInfo = await _visitTaskRepository.Where(x => x.SubjectId == taskInfo.SubjectId && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && x.TaskState == TaskState.Effect && x.ArmEnum == taskInfo.ArmEnum && x.ReadingCategory == ReadingCategory.Judge && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate && x.IsSelfAnalysis == taskInfo.IsSelfAnalysis && x.DoctorUserId == taskInfo.DoctorUserId && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.VisitTaskNum == taskInfo.VisitTaskNum + ReadingCommon.TaskNumDic[ReadingCategory.Judge] && x.ReReadingApplyState != ReReadingApplyState.Agree).FirstOrDefaultAsync(); if (judgeInfo != null) { result.JudgeTaskId = judgeInfo.Id; result.JudgeTaskName = judgeInfo.TaskBlindName; } // 一致性分析按照doctorId 其他按照分组 var queruTask = _visitTaskRepository.Where(x => x.TrialId == taskInfo.TrialId && x.SubjectId == taskInfo.SubjectId && x.ReadingCategory == ReadingCategory.Visit && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate && x.ArmEnum == taskInfo.ArmEnum && x.IsSelfAnalysis == taskInfo.IsSelfAnalysis && x.DoctorUserId == taskInfo.DoctorUserId && x.TaskState == TaskState.Effect && x.VisitTaskNum < taskInfo.VisitTaskNum); if (taskInfo.ReadingTaskState == ReadingTaskState.HaveSigned) { queruTask = _visitTaskRepository.Where(x => taskInfo.RelatedVisitTaskIdList.Contains(x.Id)); } result.TaskList = await queruTask .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 = taskInfo.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, BeforeQuestionList = 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(); var globalQuestionList = await _readingQuestionTrialRepository.Where(x => x.GlobalReadingShowType != GlobalReadingShowType.NotShow && x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId).IgnoreAutoIncludes().ToListAsync(); result.TaskList.ForEach(x => { x.CrterionDictionaryGroup = ReadingCommon.GetCrterionDictionaryGroup(x.IsConvertedTask); if (x.BeforeQuestionList.Count() != globalQuestionList.Count()) { var beforeQuestionIds = x.BeforeQuestionList.Select(x => x.QuestionId).ToList(); globalQuestionList.ForEach(y => { if (!beforeQuestionIds.Contains(y.Id)) { x.BeforeQuestionList.Add(new GlobalQuestionInfo() { QuestionId = y.Id, QuestionName = y.QuestionName.LanguageName(y.QuestionEnName, _userInfo.IsEn_Us), QuestionEnName = y.QuestionEnName, AnswerGroup = y.AnswerGroup, QuestionType = y.QuestionType, LimitEdit = y.LimitEdit, MaxAnswerLength = y.MaxAnswerLength, FileType = y.FileType, QuestionGenre = y.QuestionGenre, ShowOrder=y.ShowOrder, DictionaryCode = y.DictionaryCode, GlobalReadingShowType = y.GlobalReadingShowType, AnswerCombination = y.AnswerCombination, JudgeType = y.JudgeType, Type = y.Type, TypeValue = y.TypeValue, ValueType = y.ValueType, IsJudgeQuestion = y.IsJudgeQuestion, Answer = string.Empty, }); } }); } x.BeforeQuestionList = x.BeforeQuestionList.OrderBy(y => y.ShowOrder).ToList(); }); var globalReadingQuestion = await _readingGlobalTaskInfoRepository.Where(x => x.GlobalTaskId == inDto.VisitTaskId).ToListAsync(); var criterionType = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == taskInfo.TrialReadingCriterionId).Select(x => x.CriterionType).FirstOrDefaultAsync(); // Before的Answer取自于 上一次全局阅片的结果, 如果没有上一次全局阅片的结果 取访视的答案 var lastGlobalTask = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Global && x.TrialReadingCriterionId == taskInfo.TrialReadingCriterionId && x.SubjectId == taskInfo.SubjectId && x.IsAnalysisCreate == taskInfo.IsAnalysisCreate && x.TaskState == TaskState.Effect && x.VisitTaskNum < taskInfo.VisitTaskNum) .Where(x => x.DoctorUserId == taskInfo.DoctorUserId) .OrderByDescending(x=>x.VisitTaskNum) .FirstOrDefaultAsync(); List? globalAnswers = new List(); if (lastGlobalTask != null) { globalAnswers = await _readingGlobalTaskInfoRepository.Where(x => x.GlobalTaskId == lastGlobalTask.Id).ToListAsync(); } if (criterionType != CriterionType.PCWG3) { result.TaskList.ForEach(x => { x.BeforeQuestionList.ForEach(y => { var globalAnswer = globalAnswers.Where(z => z.QuestionId == y.QuestionId&&z.TaskId==x.VisitTaskId).Select(z => z.Answer).FirstOrDefault(); if (!globalAnswer.IsNullOrEmpty()) { y.Answer = globalAnswer??string.Empty; y.IsGlobalAnswer = true; } }); }); } result.TaskList.ForEach(x => { x.AfterQuestionList = x.BeforeQuestionList .GroupJoin( globalReadingQuestion , l => new { a = l.QuestionId, b = x.VisitTaskId } , r => new { a = r.QuestionId, b = r.TaskId } , (l, r) => new { question = l, global = r }) .SelectMany(lr => lr.global.DefaultIfEmpty(), (lr, r) => new GlobalQuestionInfo { Answer = lr.global == null || lr.global.Count() == 0 ? (inDto.UsingOriginalData ? lr.question.Answer : string.Empty) : (lr.global.Select(x => x.Answer).FirstOrDefault().IsNullOrEmpty() && inDto.UsingOriginalData ? lr.question.Answer : lr.global.Select(x => x.Answer).FirstOrDefault() ), VisitAnswer = lr.question.Answer, IsHaveChange = lr.global.Any(x=>x.QuestionId!=null&&!x.Answer.IsNullOrEmpty()) ? true : false, QuestionId = lr.question.QuestionId, QuestionName = lr.question.QuestionName.LanguageName(lr.question.QuestionEnName, _userInfo.IsEn_Us), QuestionType = lr.question.QuestionType, LimitEdit=lr.question.LimitEdit, MaxAnswerLength=lr.question.MaxAnswerLength, FileType=lr.question.FileType, QuestionGenre = lr.question.QuestionGenre, DictionaryCode = lr.question.DictionaryCode, GlobalReadingShowType = lr.question.GlobalReadingShowType, Type = lr.question.Type, GlobalAnswerType = GlobalAnswerType.Question, AnswerGroup = lr.question.AnswerGroup, AnswerCombination = lr.question.AnswerCombination, IsJudgeQuestion=lr.question.IsJudgeQuestion, JudgeType = lr.question.JudgeType, TypeValue = lr.question.TypeValue, ValueType= lr.question.ValueType, }).ToList(); List questionTypes = new List() { }; if (criterionType != CriterionType.PCWG3) { var agreeOrNotAnswer = globalReadingQuestion.Where(y => y.TaskId == x.VisitTaskId && y.GlobalAnswerType == GlobalAnswerType.AgreeOrNot).Select(x => x.Answer).FirstOrDefault() ?? string.Empty; if (agreeOrNotAnswer.IsNullOrEmpty()&& lastGlobalTask!=null&& lastGlobalTask.RelatedVisitTaskIdList.Contains(x.VisitTaskId)) { agreeOrNotAnswer = "1"; } x.AgreeOrNot = new List() { new GlobalQuestionInfo() { Answer = agreeOrNotAnswer, QuestionName = "", Type = "input", GlobalAnswerType=GlobalAnswerType.AgreeOrNot, GlobalReadingShowType= GlobalReadingShowType.AllShow, } }; questionTypes.Add(new GetGlobalQuestionType() { GlobalAnswerType = GlobalAnswerType.UpdateType, QuestionName = "评估更新类型" }); } else { x.AgreeOrNot = new List() { }; } questionTypes.Add(new GetGlobalQuestionType() { GlobalAnswerType = GlobalAnswerType.Reason, QuestionName = "全局阅片备注" }); foreach (var item in questionTypes) { x.AfterQuestionList.Add(new GlobalQuestionInfo() { Answer = globalReadingQuestion.Where(y => y.TaskId == x.VisitTaskId && y.GlobalAnswerType == item.GlobalAnswerType).Select(x => x.Answer).FirstOrDefault() ?? string.Empty, QuestionName = item.QuestionName, Type = "input", GlobalAnswerType = item.GlobalAnswerType, GlobalReadingShowType= GlobalReadingShowType.AllShow, }); } }); if (criterionType == CriterionType.PCWG3) { // 找到上一个全局阅片 result.TaskList.ForEach(x => { foreach (var item in x.AfterQuestionList.Where(x => x.QuestionType == QuestionType.SiteVisitForTumorEvaluation)) { var answer = item.Answer; var globalanswer = globalAnswers.Where(y => y.TaskId == x.VisitTaskId && y.QuestionId == item.QuestionId).FirstOrDefault(); if (globalanswer != null) { answer = globalanswer.Answer; } else { answer = x.BeforeQuestionList.Where(x => x.QuestionType == QuestionType.SiteVisitForTumorEvaluation).Select(x => x.Answer).FirstOrDefault() ?? string.Empty; } if (item.Answer.IsNullOrEmpty()) { item.Answer = answer; } item.VisitAnswer = answer; } // 在修改前 去除这个问题 x.BeforeQuestionList = x.BeforeQuestionList.Where(x => x.QuestionType != QuestionType.SiteVisitForTumorEvaluation).ToList(); x.AfterQuestionList = x.AfterQuestionList.Where(x => x.QuestionType == QuestionType.SiteVisitForTumorEvaluation|| x.GlobalAnswerType != GlobalAnswerType.Question).ToList(); }); } var subjectVisitId = await _readModuleRepository.Where(x => x.Id == taskInfo.SouceReadModuleId).Select(x => x.SubjectVisitId).FirstOrDefaultAsync(); var isBaseLine = await _subjectVisitRepository.Where(x => x.Id == subjectVisitId).Select(x => x.IsBaseLine).FirstOrDefaultAsync(); List assessTypeList = await _readingTrialCriterionDictionaryRepository.Where(x => x.CriterionId == taskInfo.TrialReadingCriterionId && x.ParentCode == ReadingCommon.CriterionDictionary.GlobalAssess ) //.WhereIf(isBaseLine,x=>x.IsBaseLineUse) //.WhereIf(!isBaseLine,x=>x.IsFollowVisitUse) .Select(x => new CriterionDictionaryInfo() { Id = x.Id, DictionaryId = x.DictionaryId, ChildGroup = x.Dictionary.ChildGroup, IsBaseLineUse=x.IsBaseLineUse, IsFollowVisitUse=x.IsFollowVisitUse, 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; // 返回之前处理字典 result.TaskList.ForEach(x => { x.AfterQuestionList.ForEach(y => { y.CrterionDictionaryGroup = x.CrterionDictionaryGroup; }); x.BeforeQuestionList.ForEach(y => { y.CrterionDictionaryGroup = x.CrterionDictionaryGroup; }); x.AgreeOrNot.ForEach(y => { y.CrterionDictionaryGroup = x.CrterionDictionaryGroup; }); }); return result; } #endregion } }