using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.Service.Reading.Dto; using IRaCIS.Core.Application.Service.ReadingCalculate.Interface; using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infra.EFCore.Common; using IRaCIS.Core.Infrastructure; using MassTransit; using Microsoft.AspNetCore.Mvc; namespace IRaCIS.Core.Application.Service.ReadingCalculate { [ApiExplorerSettings(GroupName = "Reading")] public class LuganoWithoutPETCalculateService(IRepository _readingTableQuestionAnswerRepository, IRepository _visitTaskRepository, IRepository _readingQuestionCriterionTrialRepository, IRepository _readingTableQuestionTrialRepository, IRepository _readingTaskQuestionMarkRepository, IRepository _readingTableAnswerRowInfoRepository, IRepository _readingGlobalTaskInfoRepository, IRepository _readingQuestionTrialRepository, IRepository _organInfoRepository, IRepository _subjectVisitRepository, IRepository _dicomStudyRepository, IRepository _tumorAssessmentRepository, ISubjectVisitService _subjectVisitService, IGeneralCalculateService _generalCalculateService, IRepository _readingTaskQuestionAnswerRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ICriterionCalculateService, ILuganoCalculateService { /// /// 获取阅片的计算数据 /// /// /// public async Task GetReadingCalculationData(GetReadingCalculationDataInDto inDto) { ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(inDto.VisitTaskId); readingData.ComputationTrigger = ComputationTrigger.LiverBloodPool; var baseLinePET5PS = 0m; if (!readingData.IsBaseLine) { var baseLineTaskId = await GetBaseLineTaskId(readingData); baseLinePET5PS = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); } return new { BaseLinePET5PS = baseLinePET5PS, //计算的5ps评分 CalculatePET5PS = await GetPET5PS(readingData), }; } #region 临时对象 单个请求的生命周期 避免重复查询数据库 private List visitTaskAnswerList; /// /// 获取Sod的值 /// private decimal? sODData; /// /// 基线任务Id /// private Guid? BaseLineTaskId; /// /// 影像是否无法融合 /// private bool? isUnableFuse; private string nAString = "NA"; #endregion #region 删除病灶获取起始病灶序号 /// /// 删除病灶获取起始病灶序号(RECIST1Point1 固定是1) /// /// public async Task GetDeleteLesionStatrIndex(DeleteReadingRowAnswerInDto inDto) { return 1; } #endregion #region 获取阅片报告 /// /// 获取阅片报告 /// /// /// [HttpPost] public async Task GetReadingReportEvaluation(GetReadingReportEvaluationInDto indto) { GetReadingReportEvaluationOutDto result = new GetReadingReportEvaluationOutDto(); result.CalculateResult = await this.GetReportVerify(new GetReportVerifyInDto() { VisitTaskId = indto.VisitTaskId }); var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == indto.VisitTaskId).FirstNotNullAsync(); result.ReadingTaskState = visitTaskInfo.ReadingTaskState; var taskInfoList = await _generalCalculateService.GetReadingReportTaskList(indto.VisitTaskId); result.VisitTaskList = taskInfoList; var visitTaskIds = taskInfoList.Select(x => x.VisitTaskId).ToList(); var criterionId = visitTaskInfo.TrialReadingCriterionId; var questionList = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == criterionId && x.ShowQuestion != ShowQuestion.Hide).ToListAsync(); var tableQuestionList = await _readingTableQuestionTrialRepository.Where(x => x.TrialCriterionId == criterionId).OrderBy(x => x.ShowOrder).ToListAsync(); var tableAnsweRowInfos = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == indto.VisitTaskId).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); result.LesionCountList = tableAnsweRowInfos.GroupBy(x => x.LesionType).Select(x => new LesionDto { LesionType = x.Key, Count = x.ToList().Count() }).ToList(); var answers = await _readingTaskQuestionAnswerRepository.Where(x => visitTaskIds.Contains(x.VisitTaskId)).ToListAsync(); var tableAnswers = await _readingTableQuestionAnswerRepository.Where(x => visitTaskIds.Contains(x.VisitTaskId)).ToListAsync(); var globalanswerList = await _readingGlobalTaskInfoRepository.Where(x => visitTaskIds.Contains(x.TaskId) && x.GlobalVisitTask.TaskState == TaskState.Effect && x.Answer != string.Empty).Select(x => new { x.TaskId, x.GlobalVisitTask.VisitTaskNum, x.QuestionId, x.Answer }).ToListAsync(); var alltableAnsweRowInfos = await _readingTableAnswerRowInfoRepository.Where(x => visitTaskIds.Contains(x.VisitTaskId)).ToListAsync(); var organIds = alltableAnsweRowInfos.Where(x => x.OrganInfoId != null).Select(x => x.OrganInfoId).Distinct().ToList(); var organInfos = await _organInfoRepository.Where(x => organIds.Contains(x.Id)).ToListAsync(); var needChangeType = new List() { QuestionMark.Organ, QuestionMark.Location, QuestionMark.Part, }; // 第一级 #region 构造问题 List questions = questionList.Where(x => x.Type == ReadingQestionType.Group).OrderBy(x => x.ShowOrder).Select(x => new ReadingReportDto() { QuestionId = x.Id, GroupName = x.GroupName, GroupEnName = x.GroupEnName, IsShowInDicom = x.IsShowInDicom, Type = x.Type, GroupId = x.GroupId, QuestionType = x.QuestionType, LesionType = x.LesionType, QuestionGenre = x.QuestionGenre, DataSource = x.DataSource, DictionaryCode = x.DictionaryCode, TypeValue = x.TypeValue, QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us), ShowOrder = x.ShowOrder, ValueType = x.ValueType, Unit = x.Unit, CustomUnit = x.CustomUnit, ReportLayType = ReportLayType.Group, HighlightAnswer = x.HighlightAnswer, HighlightAnswerList = x.HighlightAnswerList, }).ToList(); // 分组 foreach (var item in questions) { item.Childrens = questionList.Where(x => x.GroupId == item.QuestionId).OrderBy(x => x.ShowOrder).Select(x => new ReadingReportDto() { GroupName = x.GroupName, QuestionId = x.Id, IsShowInDicom = x.IsShowInDicom, GroupEnName = x.GroupEnName, QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us), LesionType = x.LesionType, QuestionGenre = x.QuestionGenre, DataSource = x.DataSource, DictionaryCode = x.DictionaryCode, Type = x.Type, QuestionType = x.QuestionType, TypeValue = x.TypeValue, ShowOrder = x.ShowOrder, OrderMark = x.OrderMark, ValueType = x.ValueType, Unit = x.Unit, CustomUnit = x.CustomUnit, ReportLayType = ReportLayType.Question, HighlightAnswer = x.HighlightAnswer, HighlightAnswerList = x.HighlightAnswerList, }).ToList(); // 问题 foreach (var question in item.Childrens) { foreach (var task in taskInfoList) { var globalAnswer = globalanswerList.Where(x => x.TaskId == task.VisitTaskId && x.QuestionId == question.QuestionId).OrderByDescending(x => x.VisitTaskNum).FirstOrDefault(); var answer = answers.Where(x => x.VisitTaskId == task.VisitTaskId && x.ReadingQuestionTrialId == question.QuestionId).FirstOrDefault(); question.Answer.Add(new TaskQuestionAnswer() { Answer = answer == null ? string.Empty : answer.Answer, IsGlobalChange = globalAnswer == null ? false : true, GlobalChangeAnswer = globalAnswer == null ? string.Empty : globalAnswer.Answer, TaskName = task.TaskName, VisitTaskId = task.VisitTaskId, }); } // 构造表格行数据 var rowlist = tableAnsweRowInfos.Where(x => x.QuestionId == question.QuestionId).OrderBy(x => x.RowIndex).ToList(); question.Childrens = rowlist.Select(x => new ReadingReportDto() { QuestionName = question.OrderMark + x.RowIndex.GetLesionMark(), SplitOrMergeLesionName = x.MergeName.IsNullOrEmpty() ? x.SplitName : x.MergeName, SplitOrMergeType = x.SplitOrMergeType, LesionType = question.LesionType, IsShowInDicom = question.IsShowInDicom, IsCanEditPosition = x.IsCanEditPosition, RowIndex = x.RowIndex, BlindName = x.BlindName, ReportLayType = ReportLayType.Lesions, }).ToList(); foreach (var row in question.Childrens) { // tableQuestion row.Childrens = tableQuestionList.Where(x => x.ReadingQuestionId == question.QuestionId).Select(x => new ReadingReportDto() { QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us), QuestionId = x.ReadingQuestionId, TableQuestionId = x.Id, Type = x.Type, LesionType = question.LesionType, TableQuestionType = x.TableQuestionType, RowId = row.RowId, IsShowInDicom = question.IsShowInDicom, DataSource = x.DataSource, DictionaryCode = x.DictionaryCode, QuestionMark = x.QuestionMark, TypeValue = x.TypeValue, RowIndex = row.RowIndex, ShowOrder = x.ShowOrder, ValueType = x.ValueType, Unit = x.Unit, ReportLayType = ReportLayType.TableQuestion, }).ToList(); foreach (var tableQuestion in row.Childrens) { foreach (var task in taskInfoList) { var rowinfo = alltableAnsweRowInfos.Where(x => x.VisitTaskId == task.VisitTaskId && x.QuestionId == tableQuestion.QuestionId && x.RowIndex == tableQuestion.RowIndex).FirstOrDefault(); var taskQuestionAnswer = new TaskQuestionAnswer() { Answer = tableAnswers.Where(x => x.VisitTaskId == task.VisitTaskId && x.QuestionId == tableQuestion.QuestionId && x.RowIndex == tableQuestion.RowIndex && x.TableQuestionId == tableQuestion.TableQuestionId).Select(x => x.Answer).FirstIsNullReturnEmpty(), TaskName = task.TaskName, VisitTaskId = task.VisitTaskId, }; if (rowinfo != null && rowinfo.OrganInfoId != null) { var organInfo = organInfos.Where(x => x.Id == rowinfo.OrganInfoId).FirstOrDefault(); if (organInfo != null && needChangeType.Contains(tableQuestion.QuestionMark)) { if (_userInfo.IsEn_Us) { switch (tableQuestion.QuestionMark) { case QuestionMark.Organ: taskQuestionAnswer.Answer = organInfo.TULOCEN; break; case QuestionMark.Location: if (organInfo.IsCanEditPosition) { } else { taskQuestionAnswer.Answer = organInfo.TULATEN; } break; case QuestionMark.Part: taskQuestionAnswer.Answer = organInfo.PartEN; break; } } else { switch (tableQuestion.QuestionMark) { case QuestionMark.Organ: taskQuestionAnswer.Answer = organInfo.TULOC; break; case QuestionMark.Location: if (organInfo.IsCanEditPosition) { } else { taskQuestionAnswer.Answer = organInfo.TULAT; } break; case QuestionMark.Part: taskQuestionAnswer.Answer = organInfo.Part; break; } } } } tableQuestion.Answer.Add(taskQuestionAnswer); } } } }; } #endregion result.TaskQuestions = questions; return result; } #endregion /// /// 获取是否是最大suvmax 病灶 /// /// /// [HttpPost] public async Task GetIsSuvMaxLesion(GetIsSuvMaxLesionInDto inDto) { ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(inDto.VisitTaskId); var maxSuv = await GetSuvMax(readingData); var rowInfo = readingData.QuestionInfo.SelectMany(x => x.TableRowInfoList).ToList(); var tableQuestions = rowInfo.SelectMany(x => x.TableQuestionList).Where(x => x.RowId == inDto.RowId).ToList(); var lesionMaxSuv = tableQuestions.Where(x => x.QuestionMark == QuestionMark.SUVmax).Select(x => x.Answer.IsNullOrEmptyReturn0()).MaxOrDefault(); return new GetIsSuvMaxLesionOutDto() { IsSuvMaxLesion = maxSuv == lesionMaxSuv }; } /// /// 获取是否可选择不能融合影像 /// /// /// [HttpPost] public async Task GetCanChooseNotMerge(GetCanChooseNotMergeInDto inDto) { ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(inDto.VisitTaskId); List questionTypes = new List() { QuestionType.LiverSUVmax, QuestionType.MediastinumSUVmax, QuestionType.SUVmax, QuestionType.SUVmaxLesion, }; var pet5ps = readingData.QuestionInfo.Where(x => x.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstOrDefault(); GetCanChooseNotMergeOutDto getCanChooseNotMergeOutDto = new GetCanChooseNotMergeOutDto() { IsCanChooseNotMerge = !readingData.QuestionInfo.Any(x => questionTypes.Contains(x.QuestionType) && x.Answer != string.Empty) }; return getCanChooseNotMergeOutDto; } /// /// 测试计算 /// /// /// /// [HttpPost] public async Task TestCalculate(Guid visitTaskId, QuestionType type) { ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(visitTaskId); await ReadingCalculate(readingData, new List() { type }); } /// /// 获取最低PDD信息 /// /// /// [HttpPost] public async Task GetLowPPDInfo(GetPPDInfoInDto inDto) { GetPPDInfoOutDto result = new GetPPDInfoOutDto(); var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).ProjectTo(_mapper.ConfigurationProvider).FirstNotNullAsync(); var visitTaskIds = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Visit && x.TrialReadingCriterionId == taskinfo.TrialReadingCriterionId && x.IsAnalysisCreate == taskinfo.IsAnalysisCreate && x.DoctorUserId == taskinfo.DoctorUserId && x.IsSelfAnalysis == taskinfo.IsSelfAnalysis && x.SubjectId == taskinfo.SubjectId && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ArmEnum == taskinfo.ArmEnum && x.VisitTaskNum < taskinfo.VisitTaskNum && x.TaskState == TaskState.Effect ).OrderByDescending(x => x.VisitTaskNum).Select(x => x.Id).ToListAsync(); var answerList = await _readingTableQuestionAnswerRepository.Where(x => visitTaskIds.Contains(x.VisitTaskId) && x.QuestionId == inDto.QuestionId && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.PPD && x.RowIndex == inDto.RowIndex) .Select(x => new { x.Answer, x.VisitTaskId, }).ToListAsync(); var lowPddTaskid = answerList.Select(x => new { Answer = x.Answer.IsNullOrEmptyReturn0(), x.VisitTaskId }).OrderBy(x => x.Answer).Select(x => x.VisitTaskId).FirstOrDefault(); if (lowPddTaskid != default(Guid)) { var lowPPDAnswerList = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == lowPddTaskid && x.QuestionId == inDto.QuestionId && x.RowIndex == inDto.RowIndex).Include(x => x.ReadingTableQuestionTrial) .Select(x => new { x.Answer, x.ReadingTableQuestionTrial.QuestionMark, }).ToListAsync(); result.NadirPPD = lowPPDAnswerList.Where(x => x.QuestionMark == QuestionMark.PPD).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); result.LowPPDLDi = lowPPDAnswerList.Where(x => x.QuestionMark == QuestionMark.MajorAxis).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); result.LowPPDSDi = lowPPDAnswerList.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); result.LowPPDVisit = await _visitTaskRepository.Where(x => x.Id == lowPddTaskid).Select(x => x.TaskBlindName).FirstOrDefaultAsync(); } return result; } /// /// 计算任务 /// /// /// [HttpPost] public async Task CalculateTask(CalculateTaskInDto inDto) { ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(inDto.VisitTaskId); readingData.IsChangeOtherTask = inDto.IsChangeOtherTask; readingData.ComputationTrigger = inDto.ComputationTrigger; await ReadingCalculate(readingData); } /// /// 获取报告验证的信息(这里每个标准可能不一样 返回用object) /// /// /// public async Task GetReportVerify(GetReportVerifyInDto inDto) { var calculateDto = await _generalCalculateService.GetReadingCalculateDto(inDto.VisitTaskId); return new GetReportVerifyOutDto() { TumorEvaluate = calculateDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.ImgOncology).Select(x => x.Answer).FirstOrDefault(), IsExistDisease = await this.GetReportIsExistDisease(inDto.VisitTaskId), }; } /// /// 自动计算 /// /// /// /// public async Task ReadingCalculate(ReadingCalculateDto inDto, List? calculateType = null) { #region 计算 这里顺序非常重要 后面计算的值要依赖前面计算的结果 var needAddList = new List(); List calculateList = new List() { // 是否存在Pet new ReadingCalculateData (){QuestionType=QuestionType.ExistPET,GetStringFun=GetExistPET ,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, } }, //垂直径乘积之和(SPD) new ReadingCalculateData (){QuestionType=QuestionType.SPD,GetDecimalFun=GetSPD,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.CTSave,ComputationTrigger.RemoveLesion,}}, // 与基线相比SPD变化的百分比 new ReadingCalculateData (){QuestionType=QuestionType.SPDChange,GetStringFun=CompareBaselineSPD,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.CTSave,ComputationTrigger.RemoveLesion,}}, // 脾脏垂直径 new ReadingCalculateData (){QuestionType=QuestionType.SpleenLength,GetDecimalNullFun=GetSpleenLength,ComputationTriggerList=new List(){ ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,}}, // 与基线相比脾肿大增加的百分比 new ReadingCalculateData (){QuestionType=QuestionType.SplenoncusChange,GetStringFun=GetSplenoncusChange,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,}}, // 与最低点相比脾脏垂直径长度的增加值 new ReadingCalculateData (){QuestionType=QuestionType.SplenoncusAdd,GetStringFun=GetSplenoncusAdd,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,}}, // 与基线相比脾垂直径变化值 new ReadingCalculateData (){QuestionType=QuestionType.SplenoncusDiameterChange,GetStringFun=GetSplenoncusDiameterChange,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,}}, // 脾肿垂直径最低点访视 new ReadingCalculateData (){QuestionType=QuestionType.LowestSplenoncusVisit,GetStringFun=GetLowestSplenoncusVisit,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,}}, // 获取脾脏状态 new ReadingCalculateData (){QuestionType=QuestionType.SplenicStatus,GetStringFun=GetSplenicStatus,ComputationTriggerList=new List(){ ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,}}, // 获取脾脏评估 new ReadingCalculateData (){QuestionType=QuestionType.SplenicEvaluation,GetStringFun=GetSplenicEvaluation,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,ComputationTrigger.SplenicEvaluation,}}, //靶病灶评估 new ReadingCalculateData (){QuestionType=QuestionType.TargetLesion,GetStringFun=GetTargetLesionEvaluate,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.CTSave,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,ComputationTrigger.MergeLesion,}}, //非靶病灶评估 new ReadingCalculateData (){QuestionType=QuestionType.NoTargetLesion,GetStringFun=GetNoTargetLesionEvaluate,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.CTSave,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, //新病灶评估 new ReadingCalculateData (){QuestionType=QuestionType.NewLesionEvaluation,GetStringFun=GetNewLesionEvaluate,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.CTSave,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, //获取肝脏评估 new ReadingCalculateData (){QuestionType=QuestionType.LiverAssessment,GetStringFun=GetLiverAssessment,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.LiverStatus,}}, // 骨髓中是否存在局灶性 FDG亲和病灶的证据 new ReadingCalculateData (){QuestionType=QuestionType.EvidenceFocalFDG,GetStringFun=GetEvidenceFocalFDG,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.ImageQuality, }}, //CT/MRI new ReadingCalculateData (){QuestionType=QuestionType.CTandMRI,GetStringFun=CTMRIEvaluation,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.LiverStatus,ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,ComputationTrigger.SplenicEvaluation,ComputationTrigger.CTSave,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,ComputationTrigger.MergeLesion,}}, //SUVmax new ReadingCalculateData (){QuestionType=QuestionType.SUVmax,GetDecimalNullFun=GetSuvMax,ComputationTriggerList=new List(){ ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, // PET 5PS评分 new ReadingCalculateData (){QuestionType=QuestionType.PET5PS,GetStringFun=GetPET5PS,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.ImageQuality, ComputationTrigger.LiverBloodPool,ComputationTrigger.MediastinalPool,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, // 修改PET 5PS评分备注 new ReadingCalculateData (){QuestionType=QuestionType.PSScoreRemarks,GetStringFun=GetPET5PSRemark,ComputationTriggerList=new List(){ ComputationTrigger.LiverBloodPool,ComputationTrigger.MediastinalPool,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, //与基线相比摄取值变化 new ReadingCalculateData (){QuestionType=QuestionType.UptakeChange,GetStringFun=GetUptakeChange,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.ImageQuality, ComputationTrigger.LiverBloodPool,ComputationTrigger.MediastinalPool,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, // FDG-PET 评估结果 new ReadingCalculateData (){QuestionType=QuestionType.FDGPET,GetStringFun=GetFDGPETOverallAssessment,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.ImageQuality, ComputationTrigger.LiverBloodPool,ComputationTrigger.MediastinalPool,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,ComputationTrigger.PDGPET,}}, // 上一次 FDG-PET 评估结果 new ReadingCalculateData (){QuestionType=QuestionType.LastFDGPET,GetStringFun=GetLastFDGPETOverallAssessment,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, // 影像学整体肿瘤评估 new ReadingCalculateData (){QuestionType=QuestionType.ImgOncology,GetStringFun=GetImgOncology,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.ImageQuality, ComputationTrigger.LiverStatus,ComputationTrigger.SplenicApexPosition,ComputationTrigger.PositionSpleenFloor,ComputationTrigger.SplenicEvaluation,ComputationTrigger.LiverBloodPool,ComputationTrigger.MediastinalPool,ComputationTrigger.CTSave,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,ComputationTrigger.PDGPET,ComputationTrigger.MergeLesion,}}, // SUVmax所在病灶 new ReadingCalculateData (){QuestionType=QuestionType.SUVmaxLesion,GetStringFun=GetSuvMaxFocus,ComputationTriggerList=new List(){ ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, //是否存在疾病 new ReadingCalculateData (){QuestionType=QuestionType.ExistDisease,GetStringFun=GetIsExistDisease,ComputationTriggerList=new List(){ ComputationTrigger.InitialCalculation, ComputationTrigger.CTSave,ComputationTrigger.MergeSave,ComputationTrigger.RemoveLesion,}}, ////靶病灶径线之和(SOD) //new ReadingCalculateData (){QuestionType=QuestionType.SOD,GetDecimalNullFun=GetSODData}, ////非淋巴结靶病灶长径之和 //new ReadingCalculateData (){QuestionType=QuestionType.SumOfDiameter,GetDecimalNullFun=GetSumOfDiameter}, ////与基线SOD相比变化量(mm) // new ReadingCalculateData (){QuestionType=QuestionType.SODChange,GetDecimalNullFun=GetSODChange}, ////与基线访视相比SOD变化百分比 // new ReadingCalculateData (){QuestionType=QuestionType.SODPercent,GetDecimalNullFun=GetSODPercent}, ////与整个访视期间SOD最低点相比增加的值(mm) //其他任务需要改 // new ReadingCalculateData (){QuestionType=QuestionType.LowestIncrease,GetDecimalNullFun=GetLowestIncrease,/*ChangeAllTaskFun=ChangeAllLowestIncrease*/}, // //与整个访视期间SOD最低点相比增加的百分比 //其他任务需要改 // new ReadingCalculateData (){QuestionType=QuestionType.LowPercent,GetDecimalNullFun=GetLowPercent,/*ChangeAllTaskFun=ChangeAllLowPercent*/}, ////整个访视期间SOD最低点访视名称 //其他任务需要改 // new ReadingCalculateData (){QuestionType=QuestionType.LowVisit,GetStringFun=GetLowVisit,/*ChangeAllTaskFun=ChangeAllLowVisitName*/}, // //是否存在非淋巴结靶病灶 // new ReadingCalculateData (){QuestionType=QuestionType.IsLymphTarget,GetStringFun=GetIsLymphTarget}, // //是否存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上 // new ReadingCalculateData (){QuestionType=QuestionType.IsAddFive,GetStringFun=GetIsAddFive}, // //被评估为NE的单个靶病灶 // new ReadingCalculateData (){QuestionType=QuestionType.NETarget,GetStringFun=GetNETarget}, // //脾脏评估 //new ReadingCalculateData (){QuestionType=QuestionType.SplenicEvaluation,GetStringFun=GetNewLesionEvaluate}, // //整体肿瘤评估 // new ReadingCalculateData (){QuestionType=QuestionType.Tumor,GetStringFun=GetTumor}, // //是否存在疾病 // new ReadingCalculateData (){QuestionType=QuestionType.ExistDisease,GetStringFun=GetIsExistDisease}, }; // 没有靶病灶只计算最后几个 //if (inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).Sum(x => x.TableRowInfoList.Count()) == 0) //{ // List questionTypes = new List() // { // QuestionType.TargetLesion, // QuestionType.NoTargetLesion, // QuestionType.NewLesions, // QuestionType.Tumor, // QuestionType.ExistDisease, // }; // // 没有靶病灶就删除其他几个答案的值 // var isNeedDeleteTypes = calculateList.Where(x => !questionTypes.Contains(x.QuestionType)).Select(x => x.QuestionType).ToList(); // var isNeedDeleteIds = inDto.QuestionInfo.Where(x => x.QuestionType != null && isNeedDeleteTypes.Contains(x.QuestionType.Value)).Select(x => x.QuestionId).ToList(); // await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && isNeedDeleteIds.Contains(x.ReadingQuestionTrialId), x => new ReadingTaskQuestionAnswer // { // Answer = string.Empty // }); // calculateList = calculateList.Where(x => questionTypes.Contains(x.QuestionType)).ToList(); //} if (calculateType != null) { calculateList = calculateList.Where(x => calculateType.Contains(x.QuestionType)).ToList(); } calculateList = calculateList.Where(x => x.ComputationTriggerList.Contains(inDto.ComputationTrigger)).ToList(); var typeNAList = new List { QuestionType.SODChange, QuestionType.SODPercent, QuestionType.LowestIncrease, QuestionType.LowPercent, }; foreach (var calculate in calculateList) { var item = inDto.QuestionInfo.FirstOrDefault(x => x.QuestionType == calculate.QuestionType); if (item != null) { //计算答案 if (inDto.IsOnlyChangeAllTask == false) { #region 计算答案 if (calculate.GetDecimalFun != null) { item.Answer = (await calculate.GetDecimalFun(inDto)).ToString(); } else if (calculate.GetDecimalNullFun != null) { var value = await calculate.GetDecimalNullFun(inDto); item.Answer = value == null ? string.Empty : value.Value.ToString(); } else if (calculate.GetStringFun != null) { item.Answer = await calculate.GetStringFun(inDto); } #endregion // 修改修约小数位数 List valueOfTypes = new List() { ValueOfType.Decimals, ValueOfType.Percentage }; if (inDto.DigitPlaces != -1) { try { if (valueOfTypes.Contains(item.ValueType)) { item.Answer = decimal.Round(decimal.Parse(item.Answer ?? "0"), inDto.DigitPlaces).ToString("F" + inDto.DigitPlaces.ToString()); } } catch (Exception) { } } needAddList.Add(new ReadingTaskQuestionAnswer() { Answer = item.Answer, ReadingQuestionTrialId = item.QuestionId, }); } // 修改全局 if (inDto.IsChangeOtherTask && calculate.ChangeAllTaskFun != null) { await calculate.ChangeAllTaskFun(new ChangeAllTaskDto() { calculateDto = inDto, QuestionId = item.QuestionId, }); } } } var questionIds = needAddList.Select(x => x.ReadingQuestionTrialId).ToList(); await _readingTaskQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => questionIds.Contains(x.ReadingQuestionTrialId) && x.VisitTaskId == inDto.VisitTaskId); needAddList.ForEach(x => { x.SubjectId = inDto.SubjectId; x.ReadingQuestionCriterionTrialId = inDto.CriterionId; x.VisitTaskId = inDto.VisitTaskId; x.TrialId = inDto.TrialId; x.SubjectId = inDto.SubjectId; }); await _readingTaskQuestionAnswerRepository.AddRangeAsync(needAddList); await _readingTaskQuestionAnswerRepository.SaveChangesAsync(); #endregion } /// /// 获取影像是否无法融合 /// /// /// public async Task ImageQualityIsUnableFuse(ReadingCalculateDto inDto) { if (isUnableFuse != null) { return isUnableFuse.Value; } else { var imageQualityProblem = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.ImageQualityProblem).Select(x => x.Answer).FirstOrDefault(); isUnableFuse = imageQualityProblem == ((int)ImageQualityIssues.PETCTFailureFuse).ToString(); return isUnableFuse.Value; } } /// /// 获取报告整体整体评估 /// /// /// public async Task GetReportTumor(Guid visitTaskId) { return await GetTumor(await _generalCalculateService.GetReadingCalculateDto(visitTaskId)); } /// /// 获取报告是否存在疾病 /// /// /// public async Task GetReportIsExistDisease(Guid visitTaskId) { return await GetIsExistDisease(await _generalCalculateService.GetReadingCalculateDto(visitTaskId)); } /// /// 验证访视提交 /// /// /// public async Task VerifyVisitTaskQuestions(VerifyVisitTaskQuestionsInDto inDto) { if (await _readingTaskQuestionAnswerRepository.AnyAsync(x => x.ReadingQuestionTrial.QuestionType == QuestionType.ImageQualityAssessment && x.VisitTaskId == inDto.VisitTaskId && x.Answer == ImageQualityEvaluation.Abnormal.GetEnumInt())) { return; } var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); var tableAnswerList = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && (x.Answer == string.Empty || x.Answer == null) && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State ) .Select(x => new { x.ReadingQuestionTrial.OrderMark, x.RowIndex, QuestionMark = x.ReadingTableQuestionTrial.QuestionMark, Answer = x.Answer, }).ToListAsync(); string errorMassage = string.Empty; var rowAnswerList = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && (x.MeasureData == string.Empty || x.MeasureData == null)) .Select(x => new { x.ReadingQuestionTrial.OrderMark, x.RowIndex, x.Id, }).ToListAsync(); var unableEvaluateRowIds = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && (x.Answer == TargetState.UnableEvaluate.GetEnumInt() || x.Answer == TargetState.Loss.GetEnumInt()) && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State ) .Select(x => x.RowId).Distinct().ToListAsync(); List measureDataList = rowAnswerList.Where(x => !unableEvaluateRowIds.Contains(x.Id)).Select(x => x.OrderMark + x.RowIndex.GetLesionMark()).ToList(); List stateIsNullList = tableAnswerList.Select(x => x.OrderMark + x.RowIndex.GetLesionMark()).ToList(); List allExists = measureDataList.Intersect(stateIsNullList).ToList(); measureDataList = measureDataList.Except(allExists).ToList(); stateIsNullList = stateIsNullList.Except(allExists).ToList(); if (measureDataList.Count() > 0) { errorMassage += _localizer["ReadingCalculate_NoMarker", string.Join(',', measureDataList)] + ","; } if (tableAnswerList.Count > 0) { errorMassage += _localizer["ReadingCalculate_StatusIsEmpty", string.Join(',', stateIsNullList)] + ","; } if (allExists.Count > 0) { errorMassage += _localizer["ReadingCalculate_NoMarkerEmpty", string.Join(',', stateIsNullList)] + ","; } // 判断是否有pet if (await _readingTaskQuestionAnswerRepository.AnyAsync(x => x.ReadingQuestionTrial.QuestionType == QuestionType.ExistPET && x.VisitTaskId == inDto.VisitTaskId && x.Answer == ReadingYesOrNo.Yes.GetEnumInt())) { List required = new List() { QuestionType.LiverSUVmax, QuestionType.MediastinumSUVmax, QuestionType.SUVmax, QuestionType.SUVmaxLesion, QuestionType.PET5PS, }; if (taskinfo.VisitTaskNum != 0m) { required.Add(QuestionType.UptakeChange); required.Add(QuestionType.EvidenceFocalFDG); } if ((await _readingTaskQuestionAnswerRepository.CountAsync(x => required.Contains(x.ReadingQuestionTrial.QuestionType) && x.VisitTaskId == inDto.VisitTaskId && x.Answer != string.Empty)) != required.Count()) { if (taskinfo.VisitTaskNum != 0m) { errorMassage += _localizer["ReadingCalculate_LuganoPetVerification"]; } else { errorMassage += _localizer["ReadingCalculate_LuganoBaseLinePetVerification"]; } } } if (errorMassage != string.Empty) { //errorMassage = errorMassage; throw new BusinessValidationFailedException(errorMassage); } } /// /// 计算融合靶病灶的状态 /// /// /// public async Task CalculateMergeTargetLesionStatus(CalculateTargetLesionStatusInDto inDto) { var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); // 找到靶病灶问题 var targetQuestion = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId && x.LesionType == LesionType.TargetLesion).FirstOrDefaultAsync(); if (targetQuestion != null) { // 找到状态问题 var stateQuestion = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == targetQuestion.Id && x.QuestionMark == QuestionMark.State).FirstOrDefaultAsync(); if (stateQuestion != null) { //// 找到主病灶的状态 //var state = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == (int)Math.Floor(inDto.RowNumber) && x.TableQuestionId == stateQuestion.Id).Select(x => x.Answer).FirstOrDefaultAsync(); // 长径 var majorAxis = (await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == inDto.RowNumber && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.MajorAxis && x.QuestionId == targetQuestion.Id ).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); // 短径 var shortAxis = (await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == inDto.RowNumber && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.ShortAxis && x.QuestionId == targetQuestion.Id ).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); // 找到ppd问题 var ppdQuestion = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == targetQuestion.Id && x.QuestionMark == QuestionMark.PPD).FirstOrDefaultAsync(); if (ppdQuestion != null) { var pPdAnswer = (await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.PPD && x.QuestionId == targetQuestion.Id && x.RowIndex == inDto.RowNumber ).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); // 是否符合疾病进展 var accord = false; var lowPPDInfo = await GetLowPPDInfo(new GetPPDInfoInDto() { RowIndex = inDto.RowNumber, VisitTaskId = inDto.VisitTaskId, QuestionId = inDto.QuestionId, }); if (lowPPDInfo.NadirPPD != 0) { //当前融合靶病灶LDi>15 mm && //(当前融合靶病灶的ppd-最低点PPD)/最低点PPD ≥50 % if (majorAxis >= 15 && (pPdAnswer - lowPPDInfo.NadirPPD) * 100 / lowPPDInfo.NadirPPD >= 50) { accord = true; } } // 符合疾病进展 if (accord) { await _readingTableQuestionAnswerRepository.UpdatePartialFromQueryAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == inDto.RowNumber && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && x.QuestionId == targetQuestion.Id, x => new ReadingTableQuestionAnswer() { Answer = TargetState.DiseaseProgression.GetEnumInt() } ); } //else if (state == TargetState.DiseaseProgression.GetEnumInt()) //{ // //await _readingTableQuestionAnswerRepository.UpdatePartialFromQueryAsync(x => // // x.VisitTaskId == inDto.VisitTaskId && // // x.RowIndex == inDto.RowNumber && // // x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && // // x.QuestionId == targetQuestion.Id, x => new ReadingTableQuestionAnswer() // // { // // Answer = TargetState.Exist.GetEnumInt() // // } // // ); //} } } } } /// /// 计算分裂靶病灶状态 /// /// /// public async Task CalculateTargetLesionStatus(CalculateTargetLesionStatusInDto inDto) { if (inDto.RowNumber % 1 != 0) { var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); // 找到靶病灶问题 var targetQuestion = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId && x.LesionType == LesionType.TargetLesion).FirstOrDefaultAsync(); if (targetQuestion != null) { // 找到状态问题 var stateQuestion = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == targetQuestion.Id && x.QuestionMark == QuestionMark.State).FirstOrDefaultAsync(); if (stateQuestion != null) { // 找到主病灶的状态 var state = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == (int)Math.Floor(inDto.RowNumber) && x.TableQuestionId == stateQuestion.Id).Select(x => x.Answer).FirstOrDefaultAsync(); // 长径 var majorAxis = (await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex >= (int)Math.Floor(inDto.RowNumber) && x.RowIndex < ((int)Math.Floor(inDto.RowNumber) + 1) && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.MajorAxis && x.QuestionId == targetQuestion.Id ).Select(x => x.Answer).ToListAsync()).Select(x => x.IsNullOrEmptyReturn0()).Sum(); // 短径 var shortAxis = (await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex >= (int)Math.Floor(inDto.RowNumber) && x.RowIndex < ((int)Math.Floor(inDto.RowNumber) + 1) && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.ShortAxis && x.QuestionId == targetQuestion.Id ).Select(x => x.Answer).ToListAsync()).Select(x => x.IsNullOrEmptyReturn0()).Sum(); // 找到ppd问题 var ppdQuestion = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == targetQuestion.Id && x.QuestionMark == QuestionMark.PPD).FirstOrDefaultAsync(); if (ppdQuestion != null) { var ppdAnswerList = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.PPD && x.QuestionId == targetQuestion.Id && x.RowIndex >= (int)Math.Floor(inDto.RowNumber) && x.RowIndex < ((int)Math.Floor(inDto.RowNumber) + 1) ).Select(x => x.Answer).ToListAsync(); var allPPd = ppdAnswerList.Select(x => x.IsNullOrEmptyReturn0()).Sum(); // 是否符合疾病进展 var accord = false; var lowPPDInfo = await GetLowPPDInfo(new GetPPDInfoInDto() { RowIndex = (int)Math.Floor(inDto.RowNumber), VisitTaskId = inDto.VisitTaskId, QuestionId = inDto.QuestionId, }); if (lowPPDInfo.NadirPPD != 0) { //15mm < 当前靶病灶LDi≤20mm && //&& 相比最低点PPD增加百分比 ≥50% && //(相比PPD最低点LDi增加值 ≥5 mm //or相比PPD最低点SDi增加值≥5 mm) if (15 < majorAxis && majorAxis <= 20 && (allPPd - lowPPDInfo.NadirPPD) * 100 / lowPPDInfo.NadirPPD >= 50 && (majorAxis - lowPPDInfo.LowPPDLDi >= 5 || shortAxis - lowPPDInfo.LowPPDSDi >= 5) ) { accord = true; } //当前靶病灶LDi>20 mm //相比最低点PPD增加百分比 ≥50% // (相比PPD最低点LDi增加值 ≥10 mm // 或者相比PPD最低点SDi增加值Sdi ≥10 mm) if (majorAxis > 20 && (allPPd - lowPPDInfo.NadirPPD) * 100 / lowPPDInfo.NadirPPD >= 50 && (majorAxis - lowPPDInfo.LowPPDLDi >= 10 || shortAxis - lowPPDInfo.LowPPDSDi >= 10) ) { accord = true; } } // 符合疾病进展 if (accord) { await _readingTableQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == (int)Math.Floor(inDto.RowNumber) && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && x.QuestionId == targetQuestion.Id, x => new ReadingTableQuestionAnswer() { Answer = TargetState.DiseaseProgression.GetEnumInt() } ); } else if (state == TargetState.DiseaseProgression.GetEnumInt()) { await _readingTableQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == (int)Math.Floor(inDto.RowNumber) && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && x.QuestionId == targetQuestion.Id, x => new ReadingTableQuestionAnswer() { Answer = TargetState.Exist.GetEnumInt() } ); } await _readingTableQuestionAnswerRepository.SaveChangesAsync(); } } } } } /// /// 获取分裂病灶的PPd之和 不包括当前的主病灶 /// /// [HttpPost] public async Task> GetSplitPPdSum(GetSplitPPdInDto inDto) { List result = new List(); var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync(); var targetQuestion = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskInfo.TrialReadingCriterionId && x.LesionType == LesionType.TargetLesion).FirstOrDefaultAsync(); if (targetQuestion != null) { var ppdAnswerList = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && //x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.PPD && x.QuestionId == targetQuestion.Id) .Select(x => new { x.RowId, x.RowIndex, x.Answer, x.ReadingTableQuestionTrial.QuestionMark, }).ToListAsync(); var answerList = ppdAnswerList.Select(x => new { x.RowId, x.RowIndex, Answer = x.Answer.IsNullOrEmptyReturn0(), x.QuestionMark, }).ToList(); var maxRowIndex = answerList.MaxOrDefault(x => x.RowIndex); for (int i = 1; i < maxRowIndex; i++) { result.Add(new GetSplitPPdOutDto() { RowId = answerList.Where(x => x.RowIndex == i).Select(x => x.RowId).FirstOrDefault(), RowIndex = answerList.Where(x => x.RowIndex == i).Select(x => x.RowIndex).FirstOrDefault().ToString(), AllPPD = answerList.Where(x => x.QuestionMark == QuestionMark.PPD).Where(x => x.RowIndex > i && x.RowIndex < (i + 1)).Sum(x => x.Answer), AllLDi = answerList.Where(x => x.QuestionMark == QuestionMark.MajorAxis).Where(x => x.RowIndex > i && x.RowIndex < (i + 1)).Sum(x => x.Answer), AllSDi = answerList.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Where(x => x.RowIndex > i && x.RowIndex < (i + 1)).Sum(x => x.Answer), }); } } return result; } #region 将上一次的访视病灶添加到这一次 /// /// 将上一次的访视病灶添加到这一次 /// /// /// public async Task AddTaskLesionAnswerFromLastTask(AddTaskLesionAnswerFromLastTaskInDto inDto) { var visitTaskId = inDto.VisitTaskId; var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync(); var baseLineVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == taskinfo.SubjectId && x.IsBaseLine).Select(x => x.Id).FirstOrDefaultAsync(); ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(visitTaskId); await ReadingCalculate(readingData, new List() { QuestionType.ExistPET }); // 判断当前任务是否是基线 if (taskinfo.SourceSubjectVisitId != baseLineVisitId) { // 判断当前任务是是否有表格问题答案 if (!(await _readingTableQuestionAnswerRepository.AnyAsync(x => x.VisitTaskId == visitTaskId))) { var LastVisitTaskId = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Visit && x.TrialReadingCriterionId == taskinfo.TrialReadingCriterionId && x.IsAnalysisCreate == taskinfo.IsAnalysisCreate && x.DoctorUserId == taskinfo.DoctorUserId && x.IsSelfAnalysis == taskinfo.IsSelfAnalysis && x.SubjectId == taskinfo.SubjectId && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.VisitTaskNum < taskinfo.VisitTaskNum && x.TaskState == TaskState.Effect && x.ArmEnum == taskinfo.ArmEnum ).OrderByDescending(x => x.VisitTaskNum).Select(x => x.Id).FirstOrDefaultAsync(); var copyTableAnswers = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == LastVisitTaskId).Select(x => new CopyTableAnswerDto() { Answer = x.Answer, QuestionId = x.QuestionId, RowId = x.RowId, QuestionMark = x.ReadingTableQuestionTrial.QuestionMark, TableQuestionId = x.TableQuestionId, RowIndex = x.RowIndex, TrialId = x.TrialId }).ToListAsync(); var tableRowAnswers = await _readingTableAnswerRowInfoRepository.Where(x => x.VisitTaskId == LastVisitTaskId).OrderBy(x => x.RowIndex).ProjectTo(_mapper.ConfigurationProvider).ToListAsync(); tableRowAnswers.ForEach(x => { switch (x.SplitOrMergeType) { case SplitOrMergeType.Merge: case SplitOrMergeType.Merged: x.SplitOrMergeType = SplitOrMergeType.Merged; break; case SplitOrMergeType.MergeMain: case SplitOrMergeType.MergeMained: x.SplitOrMergeType = SplitOrMergeType.MergeMained; break; default: x.SplitOrMergeType = null; break; } x.VisitTaskId = visitTaskId; x.IsCurrentTaskAdd = false; x.Id = NewId.NextGuid(); x.SeriesId = null; x.InstanceId = null; x.MeasureData = string.Empty; x.PicturePath = string.Empty; }); tableRowAnswers.ForEach(x => { x.SplitRowId = tableRowAnswers.Where(y => y.OriginalId == x.SplitRowId).FirstOrDefault()?.Id; x.MergeRowId = tableRowAnswers.Where(y => y.OriginalId == x.MergeRowId).FirstOrDefault()?.Id; }); List needCopyMarks = new List() { QuestionMark.IsLymph, QuestionMark.Lesion, QuestionMark.Organ, QuestionMark.Location, QuestionMark.Part, QuestionMark.BodyPartDescription, QuestionMark.LowPPDLDi, QuestionMark.LowPPDSDi, QuestionMark.NadirPPD, QuestionMark.LowPPDVisit, }; var rowIndexList = copyTableAnswers.Select(x => x.RowIndex).Distinct().ToList(); // 找到靶病灶问题Id var questionId = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId && x.LesionType == LesionType.TargetLesion).Select(x => x.Id).FirstNotNullAsync(); foreach (var item in rowIndexList) { var lowPPD = await this.GetLowPPDInfo(new GetPPDInfoInDto() { VisitTaskId = visitTaskId, QuestionId = questionId, RowIndex = item }); copyTableAnswers.Where(x => x.RowIndex == item).ForEach(x => { switch (x.QuestionMark) { case QuestionMark.LowPPDLDi: x.Answer = lowPPD.LowPPDLDi == null ? string.Empty : lowPPD.LowPPDLDi.Value.ToString(); break; case QuestionMark.LowPPDSDi: x.Answer = lowPPD.LowPPDSDi == null ? string.Empty : lowPPD.LowPPDSDi.Value.ToString(); break; case QuestionMark.NadirPPD: x.Answer = lowPPD.NadirPPD == null ? string.Empty : lowPPD.NadirPPD.Value.ToString(); break; case QuestionMark.LowPPDVisit: x.Answer = lowPPD.LowPPDVisit == null ? string.Empty : lowPPD.LowPPDVisit.ToString(); break; } }); } var tableAnswers = new List(); // 处理状态 var mergedRowIds = tableRowAnswers.Where(x => x.SplitOrMergeType == SplitOrMergeType.Merged).Select(x => x.Id).ToList(); copyTableAnswers.ForEach(x => { var tableAnswer = new ReadingTableQuestionAnswer() { Id = NewId.NextGuid(), Answer = needCopyMarks.Contains(x.QuestionMark) ? x.Answer : string.Empty, QuestionId = x.QuestionId, RowIndex = x.RowIndex, RowId = tableRowAnswers.Where(y => y.OriginalId == x.RowId).Select(x => x.Id).FirstOrDefault(), TableQuestionId = x.TableQuestionId, TrialId = x.TrialId, VisitTaskId = visitTaskId, }; if (mergedRowIds.Contains(tableAnswer.RowId) && x.QuestionMark == QuestionMark.State) { tableAnswer.Answer = TargetState.Loss.GetEnumInt(); } tableAnswers.Add(tableAnswer); }); var questionMarkList = await _readingTaskQuestionMarkRepository.Where(x => x.VisitTaskId == LastVisitTaskId).Select(x => new ReadingTaskQuestionMark() { VisitTaskId = visitTaskId, FirstAddTaskId = x.FirstAddTaskId, QuestionId = x.QuestionId, QuestionType = x.QuestionType, OrderMarkName = x.OrderMarkName, }).ToListAsync(); questionMarkList.ForEach(x => { x.Id = NewId.NextGuid(); }); var addList = _mapper.Map>(tableRowAnswers).OrderBy(x => x.RowIndex).ToList(); foreach (var item in addList) { await _readingTableAnswerRowInfoRepository.AddAsync(item); await _readingTableQuestionAnswerRepository.SaveChangesAsync(); } await _readingTaskQuestionMarkRepository.AddRangeAsync(questionMarkList); //await _readingTableAnswerRowInfoRepository.AddRangeAsync(addList); await _readingTableQuestionAnswerRepository.AddRangeAsync(tableAnswers); //addList.ForEach(x => //{ // x.MergeRow = null; // x.SplitRow = null; //}); await _readingTableQuestionAnswerRepository.SaveChangesAsync(); } } return new AddTaskLesionAnswerFromLastTaskOutDto() { IsBaseLine = taskinfo.SourceSubjectVisitId == baseLineVisitId, }; } #endregion #region 获取SOD /// /// 获取SOD /// /// /// 靶病灶径线之和(SOD) /// 非淋巴结的长径 和淋巴结的短径 /// /// public async Task GetSODData(ReadingCalculateDto inDto) { if (sODData != null) { return sODData.Value; } var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList(); if (tableQuestion.Count() == 0) { return null; } decimal result = 0; foreach (var item in tableQuestion) { if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(YesOrNoOrNa.Yes))) { // 淋巴结的短径 result += (item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Answer).FirstOrDefault()).IsNullOrEmptyReturn0(); } if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(YesOrNoOrNa.No))) { // 非淋巴结的长径 result += item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.MajorAxis).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); } } sODData = result; return sODData.Value; } #endregion #region 非淋巴结靶病灶长径之和 /// /// 非淋巴结靶病灶长径之和 /// /// /// public async Task GetSumOfDiameter(ReadingCalculateDto inDto) { var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList(); if (tableQuestion.Count() == 0) { return null; } decimal result = 0; foreach (var item in tableQuestion) { if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(YesOrNoOrNa.No))) { // 非淋巴结的长径 result += item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.MajorAxis).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); } } return result; } #endregion #region 与基线SOD相比变化量(mm) /// /// 与基线SOD相比变化量(mm) /// /// /// public async Task GetSODChange(ReadingCalculateDto inDto) { var value = await GetSODData(inDto); if (value == null || inDto.IsBaseLine) { return null; } return value.NullChange0() - await GetBaseLineSOD(inDto); } #endregion #region 与基线访视相比SOD变化百分比 /// /// 与基线访视相比SOD变化百分比 /// /// /// public async Task GetSODPercent(ReadingCalculateDto inDto) { var thisSOD = await GetSODData(inDto); if (thisSOD == null || inDto.IsBaseLine) { return null; } var baseLineSOD = await GetBaseLineSOD(inDto); if (baseLineSOD == 0) { return 100; } else { return (thisSOD.NullChange0() - baseLineSOD) * 100 / baseLineSOD; } } #endregion #region 与整个访视期间SOD最低点相比增加的值(mm) /// /// 与整个访视期间SOD最低点相比增加的值(mm) /// /// /// /// 要更新之前的 /// /// public async Task GetLowestIncrease(ReadingCalculateDto inDto) { var value = await GetSODData(inDto); if (value == null || inDto.IsBaseLine) { return null; } var decimalAnswerList = await GetLowSODVisit(inDto); var minSOD = decimalAnswerList.OrderBy(x => x.SOD).Select(x => x.SOD).FirstOrDefault(); return value.NullChange0() - minSOD; } #endregion #region 与整个访视期间SOD最低点相比增加的百分比 /// /// 与整个访视期间SOD最低点相比增加的百分比 /// /// /// /// 要更新之前的 /// /// public async Task GetLowPercent(ReadingCalculateDto inDto) { var thisSOD = await GetSODData(inDto); if (thisSOD == null || inDto.IsBaseLine) { return null; } var decimalAnswerList = await GetLowSODVisit(inDto); var minSOD = decimalAnswerList.OrderBy(x => x.SOD).Select(x => x.SOD).FirstOrDefault(); if (minSOD == 0) { return 100; } else { return (thisSOD.NullChange0() - minSOD) * 100 / minSOD; } } #endregion #region 整个访视期间SOD最低点访视名称 /// /// 整个访视期间SOD最低点访视名称 /// /// /// /// 要更新之前的 /// /// public async Task GetLowVisit(ReadingCalculateDto inDto) { if (inDto.IsBaseLine) { return nameof(YesOrNoOrNa.NA); } var targetCount = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).Count(); if (targetCount == 0) { return nameof(YesOrNoOrNa.NA); } var decimalAnswerList = await GetLowSODVisit(inDto); return decimalAnswerList.OrderBy(x => x.SOD).Select(x => x.BlindName).FirstOrDefault() ?? string.Empty; } #endregion #region 是否存在非淋巴结靶病灶 /// /// 是否存在非淋巴结靶病灶 /// /// /// public async Task GetIsLymphTarget(ReadingCalculateDto inDto) { var result = IsLymph.No.GetEnumInt(); var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList(); foreach (var item in tableQuestion) { if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(IsLymph.No))) { result = IsLymph.Yes.GetEnumInt(); } } return result; } #endregion #region 是否存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上 /// /// 是否存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上 /// /// /// public async Task GetIsAddFive(ReadingCalculateDto inDto) { if (inDto.IsBaseLine) { return YesOrNoOrNa.NA.GetEnumInt(); } var addFiveList = await GetIsAddFiveRowIndexs(inDto); var isExists = addFiveList.Count() > 0 ? true : false; return isExists ? YesOrNoOrNa.Yes.GetEnumInt() : YesOrNoOrNa.No.GetEnumInt(); } /// /// 获取存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上的病灶 /// /// /// public async Task> GetIsAddFiveRowIndexs(ReadingCalculateDto inDto) { List result = new List(); var LastVisitTaskId = await this.GetLastVisitTaskId(inDto); var questionIds = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).Select(x => x.QuestionId).ToList(); var lastQuestionAsnwer = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == LastVisitTaskId && questionIds.Contains(x.QuestionId)).Include(x => x.ReadingQuestionTrial).Include(x => x.ReadingTableQuestionTrial).ToListAsync(); var rowIndexs = lastQuestionAsnwer.Where(x => x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(YesOrNoOrNa.Yes)).Select(x => x.RowIndex).Distinct().OrderBy(x => x).ToList(); var thisQuestionAsnwer = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList(); foreach (var item in rowIndexs) { var lastValue = lastQuestionAsnwer.Where(x => x.RowIndex == item && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); var thisRowData = thisQuestionAsnwer.Where(x => x.RowIndex == item).SelectMany(x => x.TableQuestionList).ToList(); var thisValue = thisRowData.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); if (thisValue - lastValue >= 5) { result.Add(item); } } return result; } #endregion #region 被评估为NE的单个靶病灶 /// /// 被评估为NE的单个靶病灶 /// /// /// public async Task GetNETarget(ReadingCalculateDto inDto) { if (inDto.IsBaseLine) { return ExistOrNA.NA.GetEnumInt(); } var result = inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.NE)); return result ? ExistOrNA.Exist.GetEnumInt() : ExistOrNA.NotExist.GetEnumInt(); } #endregion #region 整体肿瘤评估 /// /// 整体肿瘤评估 /// /// /// public async Task GetTumor(ReadingCalculateDto inDto) { if (inDto.IsBaseLine) { return OverallAssessment.NA.GetEnumInt(); } var targetLesion = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.TargetLesion).Select(x => x.Answer).FirstOrDefault(); var noTargetLesion = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NoTargetLesion).Select(x => x.Answer).FirstOrDefault(); var newLesions = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NewLesions).Select(x => x.Answer).FirstOrDefault(); var result = await _tumorAssessmentRepository.Where(x => x.TargetLesion == (TargetAssessment)int.Parse(targetLesion.IsNullOrEmpty() ? TargetAssessment.NA.GetEnumInt() : targetLesion) && x.NonTargetLesions == (NoTargetAssessment)int.Parse(noTargetLesion.IsNullOrEmpty() ? NoTargetAssessment.NA.GetEnumInt() : noTargetLesion) && x.NewLesion == (NewLesionAssessment)int.Parse(newLesions.IsNullOrEmpty() ? NewLesionAssessment.NA.GetEnumInt() : newLesions)).Select(x => x.OverallEfficacy).ToListAsync(); return result.Count == 0 ? OverallAssessment.NE.GetEnumInt() : result[0].GetEnumInt(); } #endregion #region 是否存在疾病 /// /// 是否存在疾病 /// /// /// public async Task GetIsExistDisease(ReadingCalculateDto inDto) { if (!inDto.IsBaseLine) { return string.Empty; } var lesionCount = inDto.QuestionInfo.SelectMany(x => x.TableRowInfoList).Count(); return lesionCount > 0 ? ExistDisease.Yes.GetEnumInt() : ExistDisease.No.GetEnumInt(); } #endregion #region 修改其他标准 #region 修改整个访视期间SOD最低点相比增加的百分比 /// /// 修改整个访视期间SOD最低点相比增加的百分比 /// /// /// //public async Task ChangeAllLowPercent(ChangeAllTaskDto inDto) //{ // var visitTaskList = await GetVisitTaskAnswerList(inDto.calculateDto); // var lowSod = (await GetLowSODVisit(inDto.calculateDto)).Select(x => x.SOD).OrderBy(x => x).FirstOrDefault(); // foreach (var item in visitTaskList.Where(x => x.VisitTaskId != inDto.calculateDto.BaseLineTaskId)) // { // decimal percent = 0; // if (lowSod == 0) // { // percent = 100; // } // else // { // percent = decimal.Round((item.SOD - lowSod) * 100 / lowSod, 2); // } // await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.VisitTaskId && x.ReadingQuestionTrialId == inDto.QuestionId, x => new ReadingTaskQuestionAnswer() // { // Answer = percent.ToString() // }); // } //} #endregion #region 修改最低方式点名称 /// /// 修改最低方式点名称 /// /// /// public async Task ChangeAllLowVisitName(ChangeAllTaskDto inDto) { // 找到所有访视任务的Id var visitTaskIds = await _visitTaskRepository.Where(x => x.IsAnalysisCreate == inDto.IsAnalysisCreate && x.ReadingCategory == ReadingCategory.Visit && x.TrialReadingCriterionId == inDto.calculateDto.TrialReadingCriterionId && x.TaskState == TaskState.Effect && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ArmEnum == inDto.calculateDto.ArmEnum).Select(x => x.Id).ToListAsync(); var answer = (await GetLowSODVisit(inDto.calculateDto)).OrderBy(x => x.SOD).Select(x => x.BlindName).FirstOrDefault(); visitTaskIds = visitTaskIds.Where(x => x != inDto.calculateDto.BaseLineTaskId).ToList(); await this.ChangeAllVisitTaskAnswer(visitTaskIds, inDto.QuestionId, answer); } #endregion #endregion #region 通用方法 #region 修改所有访视任务的答案 /// /// 修改所有访视任务的答案 /// /// /// /// /// private async Task ChangeAllVisitTaskAnswer(List visitTaskGuids, Guid questionId, string answer) { await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => visitTaskGuids.Contains(x.VisitTaskId) && x.ReadingQuestionTrialId == questionId, x => new ReadingTaskQuestionAnswer() { Answer = answer }); } #endregion #region 获取基线任务ID /// /// 获取基线任务的Id /// /// /// private async Task GetBaseLineTaskId(ReadingCalculateDto inDto) { if (this.BaseLineTaskId == null) { this.BaseLineTaskId = await _visitTaskRepository.Where(x => x.SubjectId == inDto.SubjectId && x.ReadingCategory == ReadingCategory.Visit && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId && x.SourceSubjectVisit.IsBaseLine && x.TaskState == TaskState.Effect && x.IsAnalysisCreate == inDto.IsAnalysisCreate && x.DoctorUserId == inDto.DoctorUserId && x.IsSelfAnalysis == inDto.IsSelfAnalysis && x.ArmEnum == inDto.ArmEnum) .Select(x => x.Id).FirstOrDefaultAsync(); } return this.BaseLineTaskId.Value; } #endregion #region 获取基线SOD /// /// 获取基线SOD /// /// /// private async Task GetBaseLineSOD(ReadingCalculateDto inDto) { if (await _visitTaskRepository.AnyAsync(x => x.Id == inDto.VisitTaskId && x.SourceSubjectVisit.IsBaseLine && x.IsAnalysisCreate == inDto.IsAnalysisCreate && x.ArmEnum == inDto.ArmEnum)) { return 0; } // 先找到基线的任务 var baseLineTaskId = await _visitTaskRepository.Where(x => x.SubjectId == inDto.SubjectId && x.ReadingCategory == ReadingCategory.Visit && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId && x.SourceSubjectVisit.IsBaseLine && x.TaskState == TaskState.Effect && x.IsAnalysisCreate == inDto.IsAnalysisCreate && x.DoctorUserId == inDto.DoctorUserId && x.IsSelfAnalysis == inDto.IsSelfAnalysis && x.ArmEnum == inDto.ArmEnum) .Select(x => x.Id).FirstOrDefaultAsync(); var baseLineSOD = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SOD).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); return baseLineSOD; } #endregion /// /// 获取最低方式 /// /// /// public async Task> GetLowSODVisit(ReadingCalculateDto inDto) { var taskAnswerList = await GetVisitTaskAnswerList(inDto); taskAnswerList = taskAnswerList.Where(x => x.VisitTaskId != inDto.VisitTaskId).ToList(); var taskIds = taskAnswerList.Select(x => x.VisitTaskId).ToList(); // 排除无法评估 var unableEvaluateTaskIds = await _readingTableQuestionAnswerRepository.Where(x => taskIds.Contains(x.VisitTaskId) && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State && x.ReadingQuestionTrial.LesionType == LesionType.TargetLesion && x.Answer == TargetState.UnableEvaluate.GetEnumInt() ) .Select(x => x.VisitTaskId).Distinct().ToListAsync(); taskAnswerList = taskAnswerList.Where(x => !unableEvaluateTaskIds.Contains(x.VisitTaskId)).ToList(); return taskAnswerList.OrderBy(x => x.SOD).ToList(); } #region 获取访视任务信息 /// /// 获取访视任务信息 /// /// /// public async Task> GetVisitTaskAnswerList(ReadingCalculateDto inDto) { if (visitTaskAnswerList == null) { // 查询的时候要把自己排除 因为查询出来的可能不是计算出的最新的 visitTaskAnswerList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId != inDto.VisitTaskId && x.VisitTask.ReadingCategory == ReadingCategory.Visit && x.VisitTask.IsAnalysisCreate == inDto.IsAnalysisCreate && x.VisitTask.IsSelfAnalysis == inDto.IsSelfAnalysis && x.VisitTask.VisitTaskNum < inDto.VisitTaskNum && x.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId && x.SubjectId == inDto.SubjectId && x.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned && x.VisitTask.ArmEnum == inDto.ArmEnum && x.VisitTask.TaskState == TaskState.Effect && x.ReadingQuestionTrial.QuestionType == QuestionType.SpleenLength) .Select(x => new VisitTaskAnswerInfo { VisitTaskId = x.VisitTaskId, QuestionId = x.ReadingQuestionTrialId, VisitName = x.VisitTask.SourceSubjectVisit.VisitName, BlindName = x.VisitTask.TaskBlindName, SpleenLength = x.Answer.IsNullOrEmptyReturn0(), }).ToListAsync(); //// 这里是需要加上自己的 基线不用管 //if (visitTaskAnswerList.Count > 0) //{ // visitTaskAnswerList.Add(new VisitTaskAnswerInfo() // { // VisitTaskId = inDto.VisitTaskId, // BlindName = inDto.TaskBlindName, // QuestionId = visitTaskAnswerList[0].QuestionId, // VisitName = inDto.VisitName, // SOD = (await GetSODData(inDto)).ToString().IsNullOrEmptyReturn0(), // }); //} } return visitTaskAnswerList; } #endregion /// /// 获取上一个访视任务Id /// /// private async Task GetLastVisitTaskId(ReadingCalculateDto inDto) { // 拿到这一个访视 var thisNum = await _subjectVisitRepository.Where(x => x.Id == inDto.SubjectVisitId).Select(x => x.VisitNum).FirstOrDefaultAsync(); // 先找到上一个访视 var lastVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == inDto.SubjectId && !x.IsLostVisit && x.VisitNum < thisNum).OrderByDescending(x => x.VisitNum).Select(x => x.Id).FirstOrDefaultAsync(); // 找到访视任务Id var LastVisitTaskId = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Visit && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId && x.TaskState == TaskState.Effect && x.IsAnalysisCreate == inDto.IsAnalysisCreate && x.SourceSubjectVisitId == lastVisitId && x.ArmEnum == inDto.ArmEnum).Select(x => x.Id).FirstOrDefaultAsync(); return LastVisitTaskId; } #endregion #region 计算阅片问题 外层问题 #region 获取SPD /// /// 获取SPD /// /// /// public async Task GetSPD(ReadingCalculateDto inDto) { decimal result = 0; var rowInfo = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList(); var tableQuestionList = rowInfo.SelectMany(x => x.TableQuestionList).ToList(); result = tableQuestionList.Where(x => x.QuestionMark == QuestionMark.PPD).Sum(x => x.Answer.IsNullOrEmptyReturn0()); return result; } #endregion #region 脾脏垂直径 /// /// 获取脾脏垂直径 /// /// /// public async Task GetSpleenLength(ReadingCalculateDto inDto) { // 脾尖答案 var splenicTopAnswer = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SplenicTopPosition).Select(x => x.Answer).FirstOrDefault(); // 脾底答案 var splenicBottomAnswer = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SplenicBottomPosition).Select(x => x.Answer).FirstOrDefault(); decimal? spleenLength = null; if (splenicTopAnswer != null && splenicBottomAnswer != null && splenicTopAnswer != string.Empty && splenicBottomAnswer != string.Empty) { spleenLength = splenicTopAnswer.IsNullOrEmptyReturn0() - splenicBottomAnswer.IsNullOrEmptyReturn0(); if (spleenLength < 0) { spleenLength = 0 - spleenLength; } return spleenLength; } return spleenLength; } #endregion #region 与基线相比SPD变化的百分比 /// /// 与基线相比SPD变化的百分比 /// /// /// public async Task CompareBaselineSPD(ReadingCalculateDto inDto) { if (inDto.IsBaseLine) { return "NA"; } var baseLineTaskId = await GetBaseLineTaskId(inDto); var baseLineSpd = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SPD).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); var presentSpd = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SPD).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); if (baseLineSpd != 0) { return ReserveDecimal((presentSpd - baseLineSpd) * 100 / baseLineSpd, inDto.DigitPlaces); } else { return "NA"; } } #endregion #region 与基线相比脾肿大增加的百分比 /// /// 与基线相比脾肿大增加的百分比 /// [(当前垂直径-130)-(基线垂直径-130)]/(基线垂直径-130) /// /// /// public async Task GetSplenoncusChange(ReadingCalculateDto inDto) { if (inDto.IsBaseLine) { return "NA"; } var baseLineSpleenLength = await GetBaseLineSpleenLength(inDto); var presentSpleenLength = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SpleenLength).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); if (baseLineSpleenLength - 130 > 0 && presentSpleenLength > 130) { return ReserveDecimal((presentSpleenLength - 130 - (baseLineSpleenLength - 130)) * 100 / (baseLineSpleenLength - 130), inDto.DigitPlaces); } else { return "NA"; } } #endregion #region 与最低点相比脾脏垂直径长度的增加值 /// /// 与最低点相比脾脏垂直径长度的增加值 /// /// /// public async Task GetSplenoncusAdd(ReadingCalculateDto inDto) { var TaskAnswer = await GetVisitTaskAnswerList(inDto); if (inDto.IsBaseLine) { return "NA"; } if (TaskAnswer.Count() == 0) { return "0"; } var presentSpd = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SpleenLength).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); var lowSplenoncus = TaskAnswer.OrderBy(x => x.SpleenLength).Select(x => x.SpleenLength).FirstOrDefault(); return (presentSpd - lowSplenoncus).ToString(); } #endregion #region 脾肿垂直径最低点访视 /// /// 脾肿垂直径最低点访视 /// /// /// public async Task GetLowestSplenoncusVisit(ReadingCalculateDto inDto) { var taskAnswer = await GetVisitTaskAnswerList(inDto); if (inDto.IsBaseLine) { return "NA"; } if (taskAnswer.Count() == 0) { return "NA"; } var lowSplenoncus = taskAnswer.OrderBy(x => x.SpleenLength).FirstOrDefault(); return lowSplenoncus.BlindName; } #endregion #region 获取脾脏状态 /// /// 获取脾脏状态 /// /// /// /// [HttpPost] public async Task GetSplenicState(Guid visitTaskId, decimal spleenLength) { var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync(); ReadingCalculateDto inDto = await _generalCalculateService.GetReadingCalculateDto(visitTaskId); var result = SpleenAssessment.NotEvaluable; if (spleenLength < 0) { return SpleenAssessment.NotEvaluable.GetEnumInt(); } else if (0 < spleenLength && spleenLength <= 130) { return SpleenAssessment.Normal.GetEnumInt(); } else if (inDto.IsBaseLine) { return SpleenAssessment.Swelling.GetEnumInt(); } var lowSpleenLength = await this.GetLowSpleenLength(taskinfo); var presentSpd = spleenLength; var baseLineSpleenLength = await GetBaseLineSpleenLength(inDto); var baseLineTaskId = await GetBaseLineTaskId(inDto); var baseLineState = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SplenicStatus).Select(x => x.Answer).FirstOrDefaultAsync(); var differenceValue = presentSpd - baseLineSpleenLength; var differenceLowValue = presentSpd - lowSpleenLength; decimal getPercentage() { decimal percentage = 0; if (baseLineSpleenLength != 0) { percentage = differenceValue * 100 / (baseLineSpleenLength - 130); } return percentage; } // 1、基线 垂直径> 130 mm //2、与基线相比脾垂直径变化值≥10 mm // 当前垂直径>130 mm //与基线相比脾肿大增加的百分比 > 50% if (baseLineSpleenLength > 130 && differenceValue >= 10 && spleenLength > 130 && getPercentage() > 50) { result = SpleenAssessment.Increase; } //1、基线垂直径≤130mm //2、与基线相比脾垂直径变化值≥20 mm //当前垂直径 > 130 mm else if (baseLineSpleenLength <= 130 && differenceValue >= 20 && presentSpd > 130) { result = SpleenAssessment.Increase; } //1、基线 垂直径> 130 mm //2、当前访视的前面访视中 存在垂直径≤130mm //3、与最低点相比脾脏垂直径的增加值≥20 mm //4、当前垂直径 > 130 mm else if (baseLineSpleenLength > 130 && lowSpleenLength <= 130 && differenceLowValue >= 20 && presentSpd > 130) { result = SpleenAssessment.Increase; } // 当前垂直径≤130mm else if (spleenLength <= 130) { result = SpleenAssessment.Normal; } //1、基线期 状态为“肿大” // 当前垂直径>130 mm //与基线相比脾肿大增加的百分比 < -50% else if (baseLineState.EqEnum(SpleenAssessment.Swelling) && spleenLength > 130 && getPercentage() < -50) { result = SpleenAssessment.Remission; } else { result = SpleenAssessment.Stabilization; } return result.GetEnumInt(); } #endregion /// /// 获取最低垂直径 /// /// private async Task GetLowSpleenLength(VisitTask taskinfo) { var visitTaskIds = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Visit && x.TrialReadingCriterionId == taskinfo.TrialReadingCriterionId && x.IsAnalysisCreate == taskinfo.IsAnalysisCreate && x.DoctorUserId == taskinfo.DoctorUserId && x.IsSelfAnalysis == taskinfo.IsSelfAnalysis && x.SubjectId == taskinfo.SubjectId && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ArmEnum == taskinfo.ArmEnum && x.VisitTaskNum < taskinfo.VisitTaskNum && x.TaskState == TaskState.Effect ).OrderByDescending(x => x.VisitTaskNum).Select(x => x.Id).ToListAsync(); var questionId = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId && x.QuestionType == QuestionType.SpleenLength).Select(x => x.Id).FirstNotNullAsync(); var answerList = await _readingTaskQuestionAnswerRepository.Where(x => visitTaskIds.Contains(x.VisitTaskId) && x.ReadingQuestionTrialId == questionId) .Select(x => new { x.Answer, x.VisitTaskId, }).ToListAsync(); var lowSpleenLength = answerList.Select(x => new { Answer = x.Answer.IsNullOrEmptyReturn0(), x.VisitTaskId }).OrderBy(x => x.Answer).Select(x => x.Answer).FirstOrDefault(); return lowSpleenLength; } /// /// 获取脾脏验证 /// /// /// [HttpPost] public async Task GetSplenicVerify(Guid visitTaskId) { ReadingCalculateDto inDto = await _generalCalculateService.GetReadingCalculateDto(visitTaskId); // 基线垂直径 var baseLineSpleenLength = await GetBaseLineSpleenLength(inDto); var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync(); var baseLineTaskId = await GetBaseLineTaskId(inDto); // 最低垂直经 var lowSpleenLength = await this.GetLowSpleenLength(taskinfo); // 基线状态 var baseLineState = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SplenicStatus).Select(x => x.Answer).FirstOrDefaultAsync(); return new { //基线垂直径 BaseLineSpleenLength = baseLineSpleenLength, // 最低垂直经 LowSpleenLength = lowSpleenLength, // 基线状态 BaseLineState = baseLineState, // 脾脏状态 SplenicStatus = await GetSplenicStatus(inDto), }; } /// /// 获取脾脏状态 /// /// /// public async Task GetSplenicStatus(ReadingCalculateDto inDto) { var spleenLength = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SpleenLength).Select(x => x.Answer).FirstOrDefault(); if (spleenLength == string.Empty) { return string.Empty; } else { return await GetSplenicState(inDto.VisitTaskId, spleenLength.IsNullOrEmptyReturn0()); } } #region 获取脾脏评估 /// /// 获取脾脏评估 /// /// /// public async Task GetSplenicEvaluation(ReadingCalculateDto inDto) { return inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SplenicStatus).Select(x => x.Answer).FirstIsNullReturnEmpty(); //if (inDto.IsBaseLine) //{ // return SpleenAssessment.Stabilization.GetEnumInt(); //} //var result = SpleenAssessment.Stabilization; //var presentSpd = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SpleenLength).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); //var baseLineSpleenLength = await GetBaseLineSpleenLength(inDto); //var baseLineTaskId = await GetBaseLineTaskId(inDto); //var baseLineState = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SplenicStatus).Select(x => x.Answer).FirstOrDefaultAsync(); //var differenceValue = presentSpd - baseLineSpleenLength; //decimal percentage = 0; //if (baseLineSpleenLength != 0) //{ // percentage = differenceValue * 100 / baseLineSpleenLength; //} //// 1、基线 垂直径> 130 mm ////2、与基线相比脾垂直径变化值≥10 mm ////与基线相比脾肿大增加的百分比 > 50% //if (baseLineSpleenLength > 130 && differenceValue >= 10 && percentage > 50) //{ // result = SpleenAssessment.Increase; //} ////1、基线垂直径≤130mm ////2、与基线相比脾垂直径变化值≥20 mm ////当前垂直径 > 130 mm //else if (baseLineSpleenLength <= 130 && differenceValue >= 20 && presentSpd > 130) //{ // result = SpleenAssessment.Increase; //} ////1、基线 垂直径> 130 mm ////2、当前访视的前面访视中 存在垂直径≤130mm ////3、与最低点相比脾脏垂直径的增加值≥20 mm ////4、当前垂直径 > 130 mm //else if (baseLineSpleenLength > 130 && presentSpd <= 130 && differenceValue >= 20 && presentSpd > 130) //{ // result = SpleenAssessment.Increase; //} //// 基线垂直径≤130mm //else if (baseLineSpleenLength <= 130) //{ // result = SpleenAssessment.Normal; //} ////1、基线期 状态为“肿大” ////与基线相比脾肿大增加的百分比 > 50% //else if (baseLineState.EqEnum(SpleenState.Swelling) && percentage > 50) //{ // result = SpleenAssessment.Remission; //} //else //{ // result = SpleenAssessment.Remission; //} //return result.GetEnumInt(); } #endregion #region PET 5PS /// /// 获取PET5PS评分 /// /// /// public async Task GetPET5PS(ReadingCalculateDto inDto) { // 如果是保存影像进来 PET-CT不能融合 就是NE if (inDto.ComputationTrigger == ComputationTrigger.ImageQuality) { if (await ImageQualityIsUnableFuse(inDto)) { return PET5PSScore.NE.GetEnumInt(); } } // 先在数据库查这几个值 List needSearchTypes = new List() { QuestionType.SUVmax, QuestionType.PET5PS, }; var dataBaseDataList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && needSearchTypes.Contains(x.ReadingQuestionTrial.QuestionType)).Select(x => new { x.Answer, x.ReadingQuestionTrial.QuestionType }).ToListAsync(); // 数据库中最大SUVmax var dataBaseSUVmax = dataBaseDataList.Where(x => x.QuestionType == QuestionType.SUVmax).Select(x => x.Answer).FirstIsNullReturnEmpty(); // 如果不是保存肝脏血池和纵隔血池 if (inDto.ComputationTrigger != ComputationTrigger.InitialCalculation && inDto.ComputationTrigger != ComputationTrigger.LiverBloodPool && inDto.ComputationTrigger != ComputationTrigger.MediastinalPool && dataBaseSUVmax == (await GetSuvMax(inDto)).ToString()) { return dataBaseDataList.Where(x => x.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstIsNullReturnEmpty(); } //if (inDto.IsBaseLine) //{ // return SpleenAssessment.Stabilization.GetEnumInt(); //} else if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.ExistPET && x.Answer == ReadingYesOrNo.No.GetEnumInt())) { return PET5PSScore.NE.GetEnumInt(); } var existPET = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.ExistPET).Select(x => x.Answer).FirstOrDefault(); if (existPET.EqEnum(ReadingYesOrNo.No)) { return PET5PSScore.NE.GetEnumInt(); } PET5PSScore result = PET5PSScore.X; // 最大Suvmax var maxSUVmax = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SUVmax).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); // 肝脏血池Suvmax var LiverSUVmax = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LiverSUVmax).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); // 纵膈血池 var MediastinumSUVmax = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.MediastinumSUVmax).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); if (existPET.EqEnum(ReadingYesOrNo.No)) { result = PET5PSScore.NE; } // 本访视病灶的 max SUVmax(所有病灶中最大的)> 2 * 肝脏血池SUVmax else if (maxSUVmax > 2 * LiverSUVmax && LiverSUVmax != 0m) { result = PET5PSScore.Five; } //本访视病灶的SUVmax(所有病灶中最大的)>肝脏血池SUVmax else if (maxSUVmax > LiverSUVmax && LiverSUVmax != 0) { result = PET5PSScore.Four; } //纵隔血池SUVmax<本访视点病灶的max SUVmax(所有病灶中最大的)≤1*肝脏血池SUVmax else if (MediastinumSUVmax < maxSUVmax && maxSUVmax <= LiverSUVmax && MediastinumSUVmax != 0) { result = PET5PSScore.Three; } //本访视点病灶的SUVmax(所有病灶中最大的)<=纵隔血池SUVmax else if (maxSUVmax <= MediastinumSUVmax && maxSUVmax != 0) { result = PET5PSScore.Two; } //无需标记,自主选择 else { return string.Empty; } return result.GetEnumInt(); } #endregion #region 修改PET 5PS评分备注 /// /// 获取PET5PS评分备注 /// /// /// public async Task GetPET5PSRemark(ReadingCalculateDto inDto) { List needSearchTypes = new List() { QuestionType.PET5PS, QuestionType.PSScoreRemarks, }; var dataBaseDataList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && needSearchTypes.Contains(x.ReadingQuestionTrial.QuestionType)).Select(x => new { x.Answer, x.ReadingQuestionTrial.QuestionType }).ToListAsync(); ; // 数据库中PET5PS var pET5PS = dataBaseDataList.Where(x => x.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstIsNullReturnEmpty(); // 如果PET5PS没变 就不重新计算 if (pET5PS == (await GetPET5PS(inDto)).ToString()) { return dataBaseDataList.Where(x => x.QuestionType == QuestionType.PSScoreRemarks).Select(x => x.Answer).FirstIsNullReturnEmpty(); } else { return string.Empty; } } #endregion #region 与基线相比摄取值变化 /// /// 与基线相比摄取值变化 /// /// /// public async Task GetUptakeChange(ReadingCalculateDto inDto) { var existPET = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.ExistPET).Select(x => x.Answer).FirstOrDefault(); if (await ImageQualityIsUnableFuse(inDto) || existPET.EqEnum(ReadingYesOrNo.No)) { if (inDto.IsBaseLine) { return string.Empty; } else { return SUVChangeVSBaseline.NotEvaluable.GetEnumInt(); } } //PET5ps评分改变时,才计算 List needSearchTypes = new List() { QuestionType.PET5PS, QuestionType.UptakeChange, }; var dataBaseDataList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && needSearchTypes.Contains(x.ReadingQuestionTrial.QuestionType)).Select(x => new { x.Answer, x.ReadingQuestionTrial.QuestionType }).ToListAsync(); ; // 数据库中PET5ps评分 var dataBasePET5ps = dataBaseDataList.Where(x => x.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstIsNullReturnEmpty(); if (dataBasePET5ps == await GetPET5PS(inDto)) { return dataBaseDataList.Where(x => x.QuestionType == QuestionType.UptakeChange).Select(x => x.Answer).FirstIsNullReturnEmpty(); } if (inDto.IsBaseLine) { return SUVChangeVSBaseline.NA.GetEnumInt(); } var result = SUVChangeVSBaseline.NotEvaluable; var baseLineTaskId = await GetBaseLineTaskId(inDto); var PET5PS = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); if (PET5PS == 0) { return string.Empty; } var baseLinePET5PSValue = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstOrDefaultAsync(); var baseLinePET5PS = baseLinePET5PSValue.IsNullOrEmptyReturn0(); // 基线为NE或者X 为空 if (baseLinePET5PSValue.EqEnum(PET5PSScore.X) || baseLinePET5PSValue.EqEnum(PET5PSScore.NE)) { return string.Empty; } //本访视PET评分>基线PET评分 else if (PET5PS > baseLinePET5PS) { result = SUVChangeVSBaseline.Increase; } //本访视PET评分<基线PET评分 else if (PET5PS < baseLinePET5PS) { result = SUVChangeVSBaseline.Decrease; } //访视PET评分 等于 基线PET评分 else if (PET5PS == baseLinePET5PS) { return string.Empty; //result = SUVChangeVSBaseline.DidNotChange; } return result.GetEnumInt(); } #endregion /// /// 获取上一次FDGPET 评估 /// /// /// public async Task GetLastFDGPETOverallAssessment(ReadingCalculateDto inDto) { if (inDto.IsBaseLine) { return FDGPETOverallAssessment.NA.GetEnumInt(); } var lastTaskId = await GetLastVisitTaskId(inDto); var answer = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == lastTaskId).Include(x => x.ReadingQuestionTrial).Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.FDGPET).Select(x => x.Answer).FirstOrDefaultAsync(); return answer ?? string.Empty; } #region FDG-PET总体评估结果 /// /// FDG-PET总体评估结果 /// /// /// public async Task GetFDGPETOverallAssessment(ReadingCalculateDto inDto) { // 如果是保存影像进来 PET-CT不能融合 就是NE if (inDto.ComputationTrigger == ComputationTrigger.ImageQuality) { if (await ImageQualityIsUnableFuse(inDto)) { if (inDto.IsBaseLine) { return FDGPETOverallAssessment.NA.GetEnumInt(); } else { return FDGPETOverallAssessment.NE.GetEnumInt(); } } } if (inDto.IsBaseLine) { return FDGPETOverallAssessment.NA.GetEnumInt(); } var notExistPET = inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.ExistPET && x.Answer == ReadingYesOrNo.No.GetEnumInt()); if (notExistPET || (await ImageQualityIsUnableFuse(inDto))) { return FDGPETOverallAssessment.NE.GetEnumInt(); } //FDGPETOverallAssessment result = FDGPETOverallAssessment.NA; // PET5PS var pET5PS = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstOrDefault(); // UptakeChange var uptakeChange = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.UptakeChange).Select(x => x.Answer).FirstOrDefault(); // EvidenceFocalFDG var evidenceFocalFDG = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.EvidenceFocalFDG).Select(x => x.Answer).FirstOrDefault(); return CalculationFDGPETOverallAssessment(pET5PS, uptakeChange, evidenceFocalFDG); } /// /// 计算FDG-PET总体评估结果【测试】 /// /// PET5PS评分 /// 与基线相比摄取值变化 /// 骨髓中是否存在局灶性 FDG亲和病灶的证据 /// public string CalculationFDGPETOverallAssessment(string? pET5PS, string uptakeChange, string? evidenceFocalFDG) { List data = new List() { //NE NE NE NE new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { PET5PSScore.NE }), Column2=ReadingCommon.EnumToString(new List() { SUVChangeVSBaseline.NotEvaluable }), Column3=ReadingCommon.EnumToString(new List() { FDGAffinityFociInBM.NE}), Column4=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), }, //NE/5分/4分/3分/2分/1分/X NE/增大/减少/无明显变化 是,存在新的/复发的FDG高亲和性病灶 PMD new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { PET5PSScore.NE,PET5PSScore.Five,PET5PSScore.Four,PET5PSScore.Three,PET5PSScore.Two,PET5PSScore.One,PET5PSScore.X, }), Column2=ReadingCommon.EnumToString(new List() { SUVChangeVSBaseline.NotEvaluable,SUVChangeVSBaseline.Increase,SUVChangeVSBaseline.Decrease,SUVChangeVSBaseline.DidNotChange, }), Column3=ReadingCommon.EnumToString(new List() { FDGAffinityFociInBM.YesHaveNew,}), Column4=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMD }), }, //5分/4分 增大 NE/(是,存在新的/复发的FDG高亲和性病灶)/(是,存在持续的局灶性变化)/否 PMD new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { PET5PSScore.Five,PET5PSScore.Four, }), Column2=ReadingCommon.EnumToString(new List() { SUVChangeVSBaseline.Increase }), Column3=ReadingCommon.EnumToString(new List() { FDGAffinityFociInBM.NE, FDGAffinityFociInBM.YesHaveNew, FDGAffinityFociInBM.YesSustain, FDGAffinityFociInBM.No}), Column4=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMD }), }, //3分/2分/1分/X NE/增大/减少/无明显变化 否 CMR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { PET5PSScore.Three,PET5PSScore.Two,PET5PSScore.One,PET5PSScore.X, }), Column2=ReadingCommon.EnumToString(new List() { SUVChangeVSBaseline.NotEvaluable,SUVChangeVSBaseline.Increase,SUVChangeVSBaseline.Decrease,SUVChangeVSBaseline.DidNotChange, }), Column3=ReadingCommon.EnumToString(new List() { FDGAffinityFociInBM.No}), Column4=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.CMR }), }, //3分/2分/1分/X NE/增大/减少/无明显变化 是,存在持续的局灶性变化 PMR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { PET5PSScore.Three,PET5PSScore.Two,PET5PSScore.One,PET5PSScore.X, }), Column2=ReadingCommon.EnumToString(new List() { SUVChangeVSBaseline.NotEvaluable,SUVChangeVSBaseline.Increase,SUVChangeVSBaseline.Decrease,SUVChangeVSBaseline.DidNotChange, }), Column3=ReadingCommon.EnumToString(new List() { FDGAffinityFociInBM.YesSustain }), Column4=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMR }), }, //5分/4分 减少 否/是,存在持续的局灶性变化 PMR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { PET5PSScore.Five,PET5PSScore.Four }), Column2=ReadingCommon.EnumToString(new List() { SUVChangeVSBaseline.Decrease }), Column3=ReadingCommon.EnumToString(new List() { FDGAffinityFociInBM.No, FDGAffinityFociInBM.YesSustain}), Column4=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMR }), }, //5分/4分 无明显变化 否/是,存在持续的局灶性变化 NMR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { PET5PSScore.Five,PET5PSScore.Four }), Column2=ReadingCommon.EnumToString(new List() { SUVChangeVSBaseline.DidNotChange }), Column3=ReadingCommon.EnumToString(new List() { FDGAffinityFociInBM.No, FDGAffinityFociInBM.YesSustain}), Column4=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NMR }), }, }; var resultdata = data.Where(x => (x.NotEq.Contains(1) ? !x.Column1.Contains(pET5PS) : x.Column1.Contains(pET5PS) || x.Column1.Count() == 0) && (x.NotEq.Contains(2) ? !x.Column2.Contains(uptakeChange) : x.Column2.Contains(uptakeChange) || x.Column2.Count() == 0) && (x.NotEq.Contains(3) ? !x.Column3.Contains(evidenceFocalFDG) : x.Column3.Contains(evidenceFocalFDG) || x.Column3.Count() == 0)) .Select(x => x.Column4.FirstOrDefault()) .FirstOrDefault(); return resultdata ?? string.Empty; } #endregion #region 骨髓中是否存在局灶性 FDG亲和病灶的证据 /// /// 骨髓中是否存在局灶性 FDG亲和病灶的证据 /// /// /// public async Task GetEvidenceFocalFDG(ReadingCalculateDto inDto) { if (await ImageQualityIsUnableFuse(inDto) || inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.ExistPET && x.Answer == ReadingYesOrNo.No.GetEnumInt())) { if (inDto.IsBaseLine) { return string.Empty; } else { return FDGAffinityFociInBM.NE.GetEnumInt(); } } else { return inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.EvidenceFocalFDG).Select(x => x.Answer).FirstOrDefault() ?? string.Empty; } } #endregion #region 肝脏评估 /// /// 获取肝脏评估 /// /// /// public async Task GetLiverAssessment(ReadingCalculateDto inDto) { return inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LiverState).Select(x => x.Answer).FirstIsNullReturnEmpty(); } #endregion #region SuvMax所在病灶 /// /// SuvMax所在病灶 /// /// /// public async Task GetSuvMaxFocus(ReadingCalculateDto inDto) { var rowInfo = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList(); if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.ExistPET && x.Answer == ReadingYesOrNo.No.GetEnumInt()) || !inDto.QuestionInfo.SelectMany(x => x.TableRowInfoList).Any(x => x.OtherMeasureData != null && x.OtherMeasureData != string.Empty)) { return string.Empty; } var tableQuestions = rowInfo.SelectMany(x => x.TableQuestionList).ToList(); var maxSuv = tableQuestions.Where(x => x.QuestionMark == QuestionMark.SUVmax).Select(x => new { x.RowIndex, Answer = x.Answer.IsNullOrEmptyReturn0(), }).OrderByDescending(x => x.Answer).FirstOrDefault(); if (maxSuv == null || maxSuv.Answer == 0m) { return "NE"; } else { var orderMark = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).FirstOrDefault()!.OrderMark; return orderMark + maxSuv.RowIndex.GetLesionMark(); } } #endregion #region SuvMax /// /// 最大sum /// /// /// public async Task GetSuvMax(ReadingCalculateDto inDto) { if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.ExistPET && x.Answer == ReadingYesOrNo.No.GetEnumInt()) || !inDto.QuestionInfo.SelectMany(x => x.TableRowInfoList).Any(x => x.OtherMeasureData != null && x.OtherMeasureData != string.Empty)) { return null; } var rowInfo = inDto.QuestionInfo.SelectMany(x => x.TableRowInfoList).ToList(); var tableQuestions = rowInfo.SelectMany(x => x.TableQuestionList).ToList(); var maxSuv = tableQuestions.Where(x => x.QuestionMark == QuestionMark.SUVmax).Select(x => x.Answer.IsNullOrEmptyReturn0()).MaxOrDefault(); return maxSuv; } #endregion /// /// 是否存在PET /// /// /// public async Task GetExistPET(ReadingCalculateDto inDto) { //var studyList = await this._subjectVisitService.GetReadingVisitStudyList(new Contracts.GetReadingVisitStudyListIndto() //{ // TrialId = inDto.TrialId, // SujectVisitId = inDto.SubjectVisitId, // VisitTaskId=inDto.VisitTaskId, //}); var existPet = await _dicomStudyRepository.Where(x => x.TrialId == inDto.TrialId && x.SubjectVisitId == inDto.SubjectVisitId).AnyAsync(x => x.Modalities.Contains("PT")); return existPet ? ReadingYesOrNo.Yes.GetEnumInt() : ReadingYesOrNo.No.GetEnumInt(); } #region 影像学整体肿瘤评估 /// /// 影像学整体肿瘤评估 /// /// /// public async Task GetImgOncology(ReadingCalculateDto inDto) { if (inDto.IsBaseLine) { return ImagingOverallAssessment_Lugano.NA.GetEnumInt(); } //var imageQualityEvaluation = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.ImageQualityAssessment&&x.Answer.EqEnum(ImageQualityEvaluation.Abnormal)).FirstOrDefault(); //if (imageQualityEvaluation != null) //{ // return ImagingOverallAssessment_Lugano.NE.GetEnumInt(); //} // CTandMRI var cTandMRIData = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.CTandMRI).Select(x => x.Answer).FirstOrDefault(); // FDGPET var fDGPETData = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.FDGPET).Select(x => x.Answer).FirstOrDefault(); var baseLineTaskId = await GetBaseLineTaskId(inDto); // lastFDGPET var lastFDGPETData = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LastFDGPET).Select(x => x.Answer).FirstOrDefault(); return CalculationGetImgOncology(cTandMRIData, fDGPETData, lastFDGPETData); } /// /// 计算整体肿瘤评估 【测试】 /// /// CT/MRI总体评估 /// FDG-PET总体评估 /// 上一次 FDG-PET总体评估 /// public string CalculationGetImgOncology(string? cTandMRIData, string? fDGPETData, string? lastFDGPETData) { List data = new List() { //1、ND NE NE/NA ND new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.ND }), Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA}), Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.ND }), }, //2、ND/PD/CR/NE/PR/SD PMD PMD/CMR/PMR/NMR/NE/NA PMD/PD new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.ND, CTMRIOverallAssessment.PD,CTMRIOverallAssessment.CR,CTMRIOverallAssessment.NE,CTMRIOverallAssessment.PR,CTMRIOverallAssessment.SD}), Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMD, }), Column3=ReadingCommon.EnumToString(new List() {FDGPETOverallAssessment.PMD, FDGPETOverallAssessment.CMR,FDGPETOverallAssessment.PMR, FDGPETOverallAssessment.NMR, FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA }), Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.PMDPD }), }, //3、ND/PD/CR/NE/PR/SD NE PMD PMD/PD new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.ND, CTMRIOverallAssessment.PD,CTMRIOverallAssessment.CR,CTMRIOverallAssessment.NE,CTMRIOverallAssessment.PR,CTMRIOverallAssessment.SD}), Column2=ReadingCommon.EnumToString(new List() {FDGPETOverallAssessment.NE }), Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMD, }), Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.PMDPD }), }, //4、PD NE CMR/PMR/NMR/NE/NA PMD/PD new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PD}), Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE, }), Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.CMR,FDGPETOverallAssessment.PMR, FDGPETOverallAssessment.NMR, FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA }), Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.PMDPD }), }, //5、NE NE NE/NA NE new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.NE }), Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA }), Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.NE }), }, //6、CR、PR、SD、NE、ND、PD CMR CMR/PMR/NMR/PMD/NE/NA CMR/CR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.CR,CTMRIOverallAssessment.PR,CTMRIOverallAssessment.SD,CTMRIOverallAssessment.NE,CTMRIOverallAssessment.ND,CTMRIOverallAssessment.PD }), Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.CMR }), Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.CMR,FDGPETOverallAssessment.PMR, FDGPETOverallAssessment.NMR, FDGPETOverallAssessment.PMD, FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA }), Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.CMRCR }), }, //7、CR NE NE/NA CMR/CR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.CR }), Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA,}), Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.CMRCR }), }, //8、CR、PR、SD、NE、ND NE CMR CMR/CR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.CR,CTMRIOverallAssessment.PR,CTMRIOverallAssessment.SD,CTMRIOverallAssessment.NE,CTMRIOverallAssessment.ND }), Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.CMR,}), Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.CMRCR }), }, //9、ND/PD/CR/NE/PR/SD PMR PMD/CMR/PMR/NMR/NE PMR/PR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.ND, CTMRIOverallAssessment.PD,CTMRIOverallAssessment.CR,CTMRIOverallAssessment.NE,CTMRIOverallAssessment.PR,CTMRIOverallAssessment.SD }), Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMR }), Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMD, FDGPETOverallAssessment.CMR,FDGPETOverallAssessment.PMR, FDGPETOverallAssessment.NMR, FDGPETOverallAssessment.NE,FDGPETOverallAssessment.NA, }), Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.PMRPR }), }, //10、PR NE NE/NA PMR/PR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA,}), Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.PMRPR }), }, //11、CR/PR/SD/NE/ND NE PMR PMR/PR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.CR,CTMRIOverallAssessment.PR,CTMRIOverallAssessment.SD,CTMRIOverallAssessment.NE,CTMRIOverallAssessment.ND }), Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMR}), Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.PMRPR }), }, //12、ND/PD/CR/NE/PR/SD NMR PMD/CMR/PMR/NMR/NE NMR/SD new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.ND,CTMRIOverallAssessment.PD,CTMRIOverallAssessment.CR,CTMRIOverallAssessment.NE,CTMRIOverallAssessment.PR,CTMRIOverallAssessment.SD }), Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NMR }), Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.PMD, FDGPETOverallAssessment.CMR, FDGPETOverallAssessment.PMR, FDGPETOverallAssessment.NMR, FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA,}), Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.NMRSD }), }, //13、CR/PR/SD/ND/NE NE NMR NMR/SD new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.CR, CTMRIOverallAssessment.PR, CTMRIOverallAssessment.SD, CTMRIOverallAssessment.ND, CTMRIOverallAssessment.NE }), Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NMR}), Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.NMRSD }), }, //14、SD NE NE NMR/SD new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.SD }), Column2=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE }), Column3=ReadingCommon.EnumToString(new List() { FDGPETOverallAssessment.NE, FDGPETOverallAssessment.NA,}), Column4=ReadingCommon.EnumToString(new List() { ImagingOverallAssessment_Lugano.NMRSD }), }, }; var resultdata = data.Where(x => (x.NotEq.Contains(1) ? !x.Column1.Contains(cTandMRIData) : x.Column1.Contains(cTandMRIData) || x.Column1.Count() == 0) && (x.NotEq.Contains(2) ? !x.Column2.Contains(fDGPETData) : x.Column2.Contains(fDGPETData) || x.Column2.Count() == 0) && (x.NotEq.Contains(3) ? !x.Column3.Contains(lastFDGPETData) : x.Column3.Contains(lastFDGPETData) || x.Column3.Count() == 0)) .Select(x => x.Column4.FirstOrDefault()) .FirstOrDefault(); return resultdata ?? string.Empty; } #endregion #region 获取基线脾脏长度 /// /// 获取基线脾脏长度 /// /// /// public async Task GetBaseLineSpleenLength(ReadingCalculateDto inDto) { var baseLineTaskId = await GetBaseLineTaskId(inDto); var baseLineSpleenLength = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SpleenLength).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); return baseLineSpleenLength; } #endregion #region 与最低点相比脾脏垂直径长度的增加值 /// /// 与最低点相比脾脏垂直径长度的增加值 /// /// /// public async Task GetSplenoncusDiameterChange(ReadingCalculateDto inDto) { if (inDto.IsBaseLine) { return "NA"; } var baseLineTaskId = await GetBaseLineTaskId(inDto); var presentSpleenLength = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SpleenLength).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); var baseLineSpleenLength = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SpleenLength).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); return (presentSpleenLength - baseLineSpleenLength).ToString(); } #endregion #region 获取靶病灶评估 /// /// 获取靶病灶评估 /// /// /// public async Task GetTargetLesionEvaluate(ReadingCalculateDto inDto) { var rowInfo = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList(); if (inDto.IsBaseLine) { return TargetAssessment.NA.GetEnumInt(); } var tableQuestions = rowInfo.SelectMany(x => x.TableQuestionList).ToList(); TargetAssessment result = TargetAssessment.SD; //或者当前访视非淋巴结靶病灶全部消失; //并且 2.当前访视淋巴结靶病灶的状态全部变为“消失”。 var eqCR = true; //当前访视中,靶病灶的Σ PPD; decimal spd = 0; foreach (var item in rowInfo) { if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(YesOrNoOrNa.No))) { // 或者当前访视非淋巴结靶病灶全部消失; eqCR = eqCR && item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(TargetState.Loss)); } spd += (item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.PPD).Select(x => x.Answer).FirstOrDefault()).IsNullOrEmptyReturn0(); if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(YesOrNoOrNa.Yes))) { // 当前访视淋巴结靶病灶的状态全部变为“消失” eqCR = eqCR && item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.State && (x.Answer.EqEnum(TargetState.Loss) || x.Answer.EqEnum(TargetState.TooSmall))); } } // 1、与基线相比SPD变化的百分比 ≥50%,; var eqPR = false; if (inDto.IsBaseLine) { eqPR = false; } else { // 先找到基线的任务 var baseLineTaskId = await _visitTaskRepository.Where(x => x.SubjectId == inDto.SubjectId && x.ReadingCategory == ReadingCategory.Visit && x.TrialReadingCriterionId == inDto.TrialReadingCriterionId && x.SourceSubjectVisit.IsBaseLine && x.TaskState == TaskState.Effect && x.IsAnalysisCreate == inDto.IsAnalysisCreate && x.DoctorUserId == inDto.DoctorUserId && x.IsSelfAnalysis == inDto.IsSelfAnalysis && x.ArmEnum == inDto.ArmEnum) .Select(x => x.Id).FirstOrDefaultAsync(); var baseLineSPD = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SPD).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); var presentSPD = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SPD).Select(x => x.Answer).FirstIsNullReturnEmpty().IsNullOrEmptyReturn0(); if (baseLineSPD > 0) { eqPR = (presentSPD - baseLineSPD) / baseLineSPD <= -0.5m; } } //基线未选择靶病灶 if (rowInfo.Count() == 0) { result = TargetAssessment.ND; } // 任一单个病灶进展即可 else if (tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(TargetState.DiseaseProgression))) { result = TargetAssessment.PD; } //当前访视存在至少一个状态为“不可评估”的靶病灶。 else if ( tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(TargetState.UnableEvaluate))) { result = TargetAssessment.NE; } //当前访视非淋巴结靶病灶全部消失 && (当前访视淋巴结靶病灶的状态全部变为“消失” 或者 "太小" ) else if (eqCR) { result = TargetAssessment.CR; } // 与基线相比SPD变化的百分比 <=-50%,; else if (eqPR) { result = TargetAssessment.PR; } return result.GetEnumInt(); } #endregion #region 获取非靶病灶评估 /// /// 获取非靶病灶评估 /// /// /// public async Task GetNoTargetLesionEvaluate(ReadingCalculateDto inDto) { NoTargetAssessment result = NoTargetAssessment.PD; if (inDto.IsBaseLine) { return NoTargetAssessment.NA.GetEnumInt(); } var tableRows = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.NonTargetLesions).SelectMany(x => x.TableRowInfoList).ToList(); var tableQuestions = tableRows.SelectMany(x => x.TableQuestionList).ToList(); //基线未选择非靶病灶 if (tableQuestions.Count() == 0) { result = NoTargetAssessment.ND; } // 随访至少存在一个状态为“显著增大”的非靶病灶 else if (tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NoTargetState.Increase))) { result = NoTargetAssessment.PD; } // 随访存在至少一个状态为“不可评估”的非靶病灶 else if (tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NoTargetState.UnableEvaluate))) { result = NoTargetAssessment.NE; } //所有单个病灶/病灶组状态评估状态为“消失” else if (tableQuestions.Count(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NoTargetState.Loss)) == tableQuestions.Count(x => x.QuestionMark == QuestionMark.State) && tableQuestions.Count(x => x.QuestionMark == QuestionMark.State) > 0) { result = NoTargetAssessment.CR; } else { result = NoTargetAssessment.PRSD; } return result.GetEnumInt(); } #endregion #region 获取新病灶评估 /// /// 获取新病灶评估 /// /// /// public async Task GetNewLesionEvaluate(ReadingCalculateDto inDto) { NewLesionAssessment result = NewLesionAssessment.No; if (inDto.IsBaseLine) { return NewLesionAssessment.NA.GetEnumInt(); } var tableRows = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.NewLesions).SelectMany(x => x.TableRowInfoList).ToList(); var tableQuestions = tableRows.SelectMany(x => x.TableQuestionList).ToList(); // 当前访视存在至少一个明确新病灶 if (tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewLesionState.Exist))) { result = NewLesionAssessment.Yes; } //只要有任何一个新病灶状态为“无法评估” else if (tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewLesionState.UnableEvaluate))) { result = NewLesionAssessment.NE; } //当前访视不存在明确新病灶且存在至少一个疑似新病灶 else if (!tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewLesionState.Exist)) && tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewLesionState.Suspected)) ) { result = NewLesionAssessment.Suspected; } else { result = NewLesionAssessment.No; } return result.GetEnumInt(); } #endregion #region CTMRI 总体评估 /// /// CTMRI 总体评估 /// /// /// public async Task CTMRIEvaluation(ReadingCalculateDto inDto) { if (inDto.IsBaseLine) { return CTMRIOverallAssessment.NA.GetEnumInt(); } // 靶病灶评估 var targetEvaluation = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.TargetLesion).Select(x => x.Answer).FirstOrDefault(); // 非靶病灶评估 var noTargetEvaluation = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NoTargetLesion).Select(x => x.Answer).FirstOrDefault(); // 存在新病灶 var existsNewTarget = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NewLesionEvaluation).Select(x => x.Answer).FirstOrDefault(); // 肝脏评估 var liverEvaluation = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LiverAssessment).Select(x => x.Answer).FirstOrDefault(); // 脾脏评估 var spleenEvaluation = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SplenicEvaluation).Select(x => x.Answer).FirstOrDefault(); return CalculationCTMRIEvaluation(targetEvaluation, noTargetEvaluation, existsNewTarget, liverEvaluation, spleenEvaluation); } /// /// 计算CTMRI 总体评估 【测试】 /// /// 靶病灶评估 /// 非靶病灶评估 /// 存在新病灶 /// 肝脏评估 /// 脾脏评估 /// [HttpPost] public string CalculationCTMRIEvaluation(string? targetEvaluation, string? noTargetEvaluation, string? existsNewTarget, string? liverEvaluation, string? spleenEvaluation) { List data = new List() { //ND ND 否/疑似 正常 正常 ND new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.ND }), Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No, NewLesionAssessment.Suspected }), Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Normal }), Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.ND }), }, //PD 任一结果 任一结果 任一结果 任一结果 PD new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.PD }), Column2=ReadingCommon.EnumToString(new List() { }), Column3=ReadingCommon.EnumToString(new List() { }), Column4=ReadingCommon.EnumToString(new List() { }), Column5=ReadingCommon.EnumToString(new List() { }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PD }), }, //任一结果 PD 任一结果 任一结果 任一结果 PD new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { }), Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.PD }), Column3=ReadingCommon.EnumToString(new List() {}), Column4=ReadingCommon.EnumToString(new List() { }), Column5=ReadingCommon.EnumToString(new List() { }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PD }), }, //任一结果 任一结果 是 任一结果 任一结果 PD new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { }), Column2=ReadingCommon.EnumToString(new List() { }), Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.Yes }), Column4=ReadingCommon.EnumToString(new List() { }), Column5=ReadingCommon.EnumToString(new List() { }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PD }), }, //任一结果 任一结果 任一结果 显著增大 任一结果 PD new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { }), Column2=ReadingCommon.EnumToString(new List() { }), Column3=ReadingCommon.EnumToString(new List() { }), Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Increase }), Column5=ReadingCommon.EnumToString(new List() { }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PD }), }, //任一结果 任一结果 任一结果 任一结果 显著增大 PD new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { }), Column2=ReadingCommon.EnumToString(new List() { }), Column3=ReadingCommon.EnumToString(new List() {}), Column4=ReadingCommon.EnumToString(new List() { }), Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Increase }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PD }), }, //CR CR/ND 否 正常 正常 CR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.CR }), Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR, NoTargetAssessment.ND }), Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No }), Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Normal }), Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.CR }), }, //ND CR 否 正常 正常 CR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR }), Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No }), Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Normal }), Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.CR }), }, //NE 非PD 否/疑似/无法评估 非显著增大 非显著增大 NE new CalculationDto(){ NotEq=new List(){ 2,4,5}, Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.NE }), Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.PD }), Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No,NewLesionAssessment.Suspected, NewLesionAssessment.NE}), Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Increase }), Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Increase }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.NE }), }, //ND NE 否/疑似/无法评估(不为是) 正常/稳定/无法评估/部分缓解(非显著增大) 正常/稳定/无法评估/部分缓解(非显著增大) NE new CalculationDto(){ NotEq=new List(){ 3,4,5}, Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.NE }), Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.Yes }), Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Increase }), Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Increase }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.NE }), }, //ND ND 无法评估 正常/稳定/无法评估/部分缓解(非显著增大) 正常/稳定/无法评估/部分缓解(非显著增大) NE new CalculationDto(){ NotEq=new List(){ 4,5}, Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.ND }), Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.NE }), Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Increase }), Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Increase }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.NE }), }, //ND ND 否/疑似 无法评估 正常/稳定/无法评估/部分缓解(非显著增大) NE new CalculationDto(){ NotEq=new List(){ 5}, Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.ND }), Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No,NewLesionAssessment.Suspected }), Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.NotEvaluable }), Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Increase }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.NE }), }, // ND ND 否/疑似 正常/稳定 NE NE new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.ND }), Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No,NewLesionAssessment.Suspected }), Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Normal,LiverAssessment.Stabilization }), Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.NotEvaluable }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.NE }), }, //1 PR CR或PR/SD或NE或ND 否/疑似/无法评估NE 正常/稳定/NE 正常/部分缓解/稳定/NE PR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.PR }), Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR,NoTargetAssessment.PRSD,NoTargetAssessment.NE,NoTargetAssessment.ND }), Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No,NewLesionAssessment.Suspected,NewLesionAssessment.NE }), Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Normal,LiverAssessment.Stabilization,LiverAssessment.NotEvaluable}), Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal,SpleenAssessment.Remission,SpleenAssessment.Stabilization,SpleenAssessment.NotEvaluable }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), }, //2 CR (PR/SD)或者NE 否/疑似/无法评估 正常/稳定/NE 正常/部分缓解/稳定/NE PR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.CR }), Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.PRSD,NoTargetAssessment.NE }), Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No,NewLesionAssessment.Suspected ,NewLesionAssessment.NE}), Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Normal,LiverAssessment.Stabilization,LiverAssessment.NotEvaluable}), Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal,SpleenAssessment.Remission ,SpleenAssessment.Stabilization,SpleenAssessment.NotEvaluable}), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), }, //3 CR CR/ND 疑似/无法评估 正常/稳定/NE 正常/部分缓解/稳定/NE PR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.CR }), Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR,NoTargetAssessment.ND }), Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.Suspected, NewLesionAssessment.NE }), Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Normal,LiverAssessment.Stabilization,LiverAssessment.NotEvaluable}), Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal,SpleenAssessment.Remission ,SpleenAssessment.Stabilization,SpleenAssessment.NotEvaluable }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), }, //4 CR CR/ND 否 稳定/NE 正常/部分缓解/稳定/NE PR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.CR }), Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR,NoTargetAssessment.ND }), Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No }), Column4=ReadingCommon.EnumToString(new List() {LiverAssessment.Stabilization,LiverAssessment.NotEvaluable}), Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal,SpleenAssessment.Remission ,SpleenAssessment.Stabilization,SpleenAssessment.NotEvaluable }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), }, //5 CR CR/ND 否 正常 部分缓解/稳定/NE PR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.CR }), Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR,NoTargetAssessment.ND }), Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No }), Column4=ReadingCommon.EnumToString(new List() {LiverAssessment.Normal}), Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Remission ,SpleenAssessment.Stabilization,SpleenAssessment.NotEvaluable }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), }, // 6 ND CR 疑似/无法评估 正常/稳定/NE 正常/部分缓解/稳定/NE PR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR }), Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.Suspected, NewLesionAssessment.NE }), Column4=ReadingCommon.EnumToString(new List() { LiverAssessment.Normal,LiverAssessment.Stabilization,LiverAssessment.NotEvaluable}), Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal,SpleenAssessment.Remission,SpleenAssessment.Stabilization,SpleenAssessment.NotEvaluable }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), }, // 7 ND CR 否 稳定/NE 正常/部分缓解/稳定/NE PR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR }), Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No }), Column4=ReadingCommon.EnumToString(new List() {LiverAssessment.Stabilization,LiverAssessment.NotEvaluable}), Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Normal,SpleenAssessment.Remission,SpleenAssessment.Stabilization,SpleenAssessment.NotEvaluable }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), }, // 8 ND CR 否 正常 部分缓解/稳定/NE PR new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { TargetAssessment.ND }), Column2=ReadingCommon.EnumToString(new List() { NoTargetAssessment.CR }), Column3=ReadingCommon.EnumToString(new List() { NewLesionAssessment.No }), Column4=ReadingCommon.EnumToString(new List() {LiverAssessment.Normal}), Column5=ReadingCommon.EnumToString(new List() { SpleenAssessment.Remission,SpleenAssessment.Stabilization,SpleenAssessment.NotEvaluable }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.PR }), }, new CalculationDto(){ Column1=ReadingCommon.EnumToString(new List() { }), Column2=ReadingCommon.EnumToString(new List() { }), Column3=ReadingCommon.EnumToString(new List() { }), Column4=ReadingCommon.EnumToString(new List() { }), Column5=ReadingCommon.EnumToString(new List() { }), Column6=ReadingCommon.EnumToString(new List() { CTMRIOverallAssessment.SD }), }, }; var index = data.FindIndex(x => (x.NotEq.Contains(1) ? !x.Column1.Contains(targetEvaluation) : x.Column1.Contains(targetEvaluation) || x.Column1.Count() == 0) && (x.NotEq.Contains(2) ? !x.Column2.Contains(noTargetEvaluation) : x.Column2.Contains(noTargetEvaluation) || x.Column2.Count() == 0) && (x.NotEq.Contains(3) ? !x.Column3.Contains(existsNewTarget) : x.Column3.Contains(existsNewTarget) || x.Column3.Count() == 0) && (x.NotEq.Contains(4) ? !x.Column4.Contains(liverEvaluation) : x.Column4.Contains(liverEvaluation) || x.Column4.Count() == 0) && (x.NotEq.Contains(5) ? !x.Column5.Contains(spleenEvaluation) : x.Column5.Contains(spleenEvaluation) || x.Column5.Count() == 0)) ; var result = data.Where(x => (x.NotEq.Contains(1) ? !x.Column1.Contains(targetEvaluation) : x.Column1.Contains(targetEvaluation) || x.Column1.Count() == 0) && (x.NotEq.Contains(2) ? !x.Column2.Contains(noTargetEvaluation) : x.Column2.Contains(noTargetEvaluation) || x.Column2.Count() == 0) && (x.NotEq.Contains(3) ? !x.Column3.Contains(existsNewTarget) : x.Column3.Contains(existsNewTarget) || x.Column3.Count() == 0) && (x.NotEq.Contains(4) ? !x.Column4.Contains(liverEvaluation) : x.Column4.Contains(liverEvaluation) || x.Column4.Count() == 0) && (x.NotEq.Contains(5) ? !x.Column5.Contains(spleenEvaluation) : x.Column5.Contains(spleenEvaluation) || x.Column5.Count() == 0)) .Select(x => x.Column6.FirstOrDefault()) .FirstOrDefault(); return result ?? string.Empty; } #endregion /// /// 保留小数 /// /// /// /// public string ReserveDecimal(decimal answer, int digitPlaces) { return decimal.Round(answer, digitPlaces).ToString(); } #region 脾脏评估 ///// ///// 获取脾脏评估 ///// ///// ///// //public async Task GetSplenicEvaluation(ReadingCalculateDto inDto) //{ //} #endregion #endregion } }