using IRaCIS.Core.Application.Service.Reading.Dto; using IRaCIS.Core.Domain.Share; using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Domain.Models; using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.ViewModel; using Panda.DynamicWebApi.Attributes; using IRaCIS.Core.Infra.EFCore.Common; using Microsoft.Extensions.Caching.Memory; using IRaCIS.Core.Infrastructure; using MassTransit; using System.Reflection.Metadata.Ecma335; using System.Linq; using NPOI.SS.Formula.Functions; using DocumentFormat.OpenXml.Drawing.Charts; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Service.ReadingCalculate.Interface; using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing; namespace IRaCIS.Core.Application.Service.ReadingCalculate { [ApiExplorerSettings(GroupName = "Reading")] public class LuganoCalculateService : BaseService, ICriterionCalculateService, ILuganoCalculateService { private readonly IRepository _readingTableQuestionAnswerRepository; private readonly IRepository _visitTaskRepository; private readonly IRepository _readingQuestionCriterionTrialRepository; private readonly IRepository _readingTableQuestionTrialRepository; private readonly IRepository _readingTaskQuestionMarkRepository; private readonly IRepository _readingTableAnswerRowInfoRepository; private readonly IRepository _readingGlobalTaskInfoRepository; private readonly IRepository _readingQuestionTrialRepository; private readonly IRepository _organInfoRepository; private readonly IRepository _subjectVisitRepository; private readonly IRepository _dicomStudyRepository; private readonly IRepository _tumorAssessmentRepository; private readonly ISubjectVisitService _subjectVisitService; private readonly IGeneralCalculateService _generalCalculateService; private readonly IRepository _readingTaskQuestionAnswerRepository; public LuganoCalculateService( 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 ) { this._readingTableQuestionAnswerRepository = readingTableQuestionAnswerRepository; this._visitTaskRepository = visitTaskRepository; this._readingQuestionCriterionTrialRepository = readingQuestionCriterionTrialRepository; this._readingTableQuestionTrialRepository = readingTableQuestionTrialRepository; this._readingTaskQuestionMarkRepository = readingTaskQuestionMarkRepository; this._readingTableAnswerRowInfoRepository = readingTableAnswerRowInfoRepository; this._readingGlobalTaskInfoRepository = readingGlobalTaskInfoRepository; this._readingQuestionTrialRepository = readingQuestionTrialRepository; this._organInfoRepository = organInfoRepository; this._subjectVisitRepository = subjectVisitRepository; this._dicomStudyRepository = dicomStudyRepository; this._tumorAssessmentRepository = tumorAssessmentRepository; this._subjectVisitService = subjectVisitService; this._generalCalculateService = generalCalculateService; this._readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository; } /// /// 获取阅片的计算数据 /// /// /// public async Task GetReadingCalculationData(GetReadingCalculationDataInDto inDto) { ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(inDto.VisitTaskId); 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, }; } #region 临时对象 单个请求的生命周期 避免重复查询数据库 private List visitTaskAnswerList; /// /// 获取Sod的值 /// private decimal? sODData; /// /// 基线任务Id /// private Guid? BaseLineTaskId; 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, }).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, }).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 /// /// 测试计算 /// /// /// /// [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}, //垂直径乘积之和(SPD) new ReadingCalculateData (){QuestionType=QuestionType.SPD,GetDecimalFun=GetSPD}, // 与基线相比SPD变化的百分比 new ReadingCalculateData (){QuestionType=QuestionType.SPDChange,GetStringFun=CompareBaselineSPD}, // 与基线相比脾肿大增加的百分比 new ReadingCalculateData (){QuestionType=QuestionType.SplenoncusChange,GetStringFun=GetSplenoncusChange}, // 与最低点相比脾脏垂直径长度的增加值 new ReadingCalculateData (){QuestionType=QuestionType.SplenoncusAdd,GetStringFun=GetSplenoncusAdd}, // 与基线相比脾垂直径变化值 new ReadingCalculateData (){QuestionType=QuestionType.SplenoncusDiameterChange,GetStringFun=GetSplenoncusDiameterChange}, // 脾肿垂直径最低点访视 new ReadingCalculateData (){QuestionType=QuestionType.LowestSplenoncusVisit,GetStringFun=GetLowestSplenoncusVisit}, // 获取脾脏评估 new ReadingCalculateData (){QuestionType=QuestionType.SplenicEvaluation,GetStringFun=GetSplenicEvaluation}, //靶病灶评估 new ReadingCalculateData (){QuestionType=QuestionType.TargetLesion,GetStringFun=GetTargetLesionEvaluate}, //非靶病灶评估 new ReadingCalculateData (){QuestionType=QuestionType.NoTargetLesion,GetStringFun=GetNoTargetLesionEvaluate}, //新病灶评估 new ReadingCalculateData (){QuestionType=QuestionType.NewLesionEvaluation,GetStringFun=GetNewLesionEvaluate}, //获取肝脏评估 new ReadingCalculateData (){QuestionType=QuestionType.LiverAssessment,GetStringFun=GetLiverAssessment}, // // 骨髓中是否存在局灶性 FDG亲和病灶的证据 //new ReadingCalculateData (){QuestionType=QuestionType.EvidenceFocalFDG,GetStringFun=GetEvidenceFocalFDG,ComputationTrigger=ComputationTrigger.Lesion}, //CT/MRI new ReadingCalculateData (){QuestionType=QuestionType.CTandMRI,GetStringFun=CTMRIEvaluation}, // PET 5PS评分 new ReadingCalculateData (){QuestionType=QuestionType.PET5PS,GetStringFun=GetPET5PS,ComputationTrigger=ComputationTrigger.Lesion}, // 修改PET 5PS评分备注 new ReadingCalculateData (){QuestionType=QuestionType.PSScoreRemarks,GetStringFun=GetPET5PSRemark,ComputationTrigger=ComputationTrigger.Lesion}, //与基线相比摄取值变化 new ReadingCalculateData (){QuestionType=QuestionType.UptakeChange,GetStringFun=GetUptakeChange,ComputationTrigger=ComputationTrigger.Lesion}, // FDG-PET 评估结果 new ReadingCalculateData (){QuestionType=QuestionType.FDGPET,GetStringFun=GetFDGPETOverallAssessment}, // 上一次 FDG-PET 评估结果 new ReadingCalculateData (){QuestionType=QuestionType.LastFDGPET,GetStringFun=GetLastFDGPETOverallAssessment}, // 影像学整体肿瘤评估 new ReadingCalculateData (){QuestionType=QuestionType.ImgOncology,GetStringFun=GetImgOncology}, //SUVmax new ReadingCalculateData (){QuestionType=QuestionType.SUVmax,GetDecimalNullFun=GetSuvMax}, // SUVmax所在病灶 new ReadingCalculateData (){QuestionType=QuestionType.SUVmaxLesion,GetStringFun=GetSuvMaxFocus}, //是否存在疾病 new ReadingCalculateData (){QuestionType=QuestionType.ExistDisease,GetStringFun=GetIsExistDisease}, ////靶病灶径线之和(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.ComputationTrigger == null || x.ComputationTrigger == 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 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.UpdatePartialFromQueryAsync(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.UpdatePartialFromQueryAsync(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(); 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 与基线相比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 percentage = 0; if (baseLineSpleenLength != 0) { percentage = differenceValue * 100 / (baseLineSpleenLength-130); } // 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 && lowSpleenLength <= 130 && differenceLowValue >= 20 && presentSpd > 130) { result = SpleenAssessment.Increase; } // 当前垂直径≤130mm else if (spleenLength <= 130) { result = SpleenAssessment.Normal; } //1、基线期 状态为“肿大” //与基线相比脾肿大增加的百分比 < -50% else if (baseLineState.EqEnum(SpleenAssessment.Swelling) && percentage < -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, }; } #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) { //if (inDto.IsBaseLine) //{ // return SpleenAssessment.Stabilization.GetEnumInt(); //} 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 { Console.WriteLine("计算了PET5PS,当前接口" + _userInfo.RequestUrl + "当前结果"); return string.Empty; } Console.WriteLine("计算了PET5PS,当前接口" + _userInfo.RequestUrl+"当前结果"+ result.GetEnumInt()); return result.GetEnumInt(); } #endregion #region 修改PET 5PS评分备注 /// /// 获取PET5PS评分备注 /// /// /// public async Task GetPET5PSRemark(ReadingCalculateDto inDto) { return string.Empty; } #endregion #region 与基线相比摄取值变化 /// /// 与基线相比摄取值变化 /// /// /// public async Task GetUptakeChange(ReadingCalculateDto inDto) { if (inDto.IsBaseLine) { return SUVChangeVSBaseline.NA.GetEnumInt(); } if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.ExistPET && x.Answer == ReadingYesOrNo.No.GetEnumInt())) { return SUVChangeVSBaseline.NotEvaluable.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(); var baseLinePET5PS = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); var existPET = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.ExistPET).Select(x => x.Answer).FirstOrDefault(); //本访视无PET图像 if (existPET.EqEnum(ReadingYesOrNo.No)) { result = SUVChangeVSBaseline.NotEvaluable; } //本访视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) { if (inDto.IsBaseLine) { return FDGPETOverallAssessment.NA.GetEnumInt(); } var notExistPET = inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.ExistPET && x.Answer == ReadingYesOrNo.No.GetEnumInt()); if (notExistPET) { 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 (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.ExistPET && x.Answer == ReadingYesOrNo.No.GetEnumInt())) { 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 } }