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