diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingQuestionViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingQuestionViewModel.cs index 487c714f8..a132692ea 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingQuestionViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingQuestionViewModel.cs @@ -426,10 +426,11 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto - public List ParentTriggerValueList { get; set; } - public List RelevanceValueList { get; set; } - - } + public List ParentTriggerValueList { get; set; } = new List(); + public List RelevanceValueList { get; set; } = new List(); + + + } /// ReadingTableQuestionSystemAddOrEdit 列表查询参数模型 public class ReadingTableQuestionSystemAddOrEdit @@ -515,8 +516,8 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto public string QuestionEnName { get; set; } = string.Empty; - public List ParentTriggerValueList { get; set; } - public List RelevanceValueList { get; set; } + public List ParentTriggerValueList { get; set; } = new List(); + public List RelevanceValueList { get; set; } = new List(); } @@ -1026,9 +1027,9 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public string GroupEnName { get; set; } = string.Empty; - public List ParentTriggerValueList { get; set; } - public List RelevanceValueList { get; set; } - public List CalculateQuestionList { get; set; } + public List ParentTriggerValueList { get; set; } = new List(); + public List RelevanceValueList { get; set; } = new List(); + public List CalculateQuestionList { get; set; } } @@ -1039,8 +1040,8 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public ValueOfType? ValueType { get; set; } - public List ParentTriggerValueList { get; set; } - public List RelevanceValueList { get; set; } + public List ParentTriggerValueList { get; set; } = new List(); + public List RelevanceValueList { get; set; } = new List(); /// /// 备注 @@ -1735,8 +1736,8 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public string GroupEnName { get; set; } = string.Empty; - public List ParentTriggerValueList { get; set; } - public List RelevanceValueList { get; set; } + public List ParentTriggerValueList { get; set; } = new List(); + public List RelevanceValueList { get; set; } = new List(); } @@ -1958,10 +1959,10 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto /// public string GroupEnName { get; set; } = string.Empty; - public List ParentTriggerValueList { get; set; } - public List RelevanceValueList { get; set; } - - } + public List ParentTriggerValueList { get; set; } = new List(); + public List RelevanceValueList { get; set; } = new List(); + + } public class GetSystemCriterionSelectDto { diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs index 9ea1eec57..ddede51cb 100644 --- a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoCalculateService.cs @@ -468,16 +468,37 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate new ReadingCalculateData (){QuestionType=QuestionType.SplenoncusChange,GetDecimalFun=GetSplenoncusChange}, // 与最低点相比脾脏垂直径长度的增加值 - new ReadingCalculateData (){QuestionType=QuestionType.SplenoncusAdd,GetDecimalFun=GetSplenoncusAdd}, + new ReadingCalculateData (){QuestionType=QuestionType.SplenoncusAdd,GetDecimalFun=GetSplenoncusAdd}, // 与基线相比脾垂直径变化值 - new ReadingCalculateData (){QuestionType=QuestionType.SplenoncusDiameterChange,GetDecimalFun=GetSplenoncusDiameterChange}, + new ReadingCalculateData (){QuestionType=QuestionType.SplenoncusDiameterChange,GetDecimalFun=GetSplenoncusDiameterChange}, // 脾肿垂直径最低点访视 - new ReadingCalculateData (){QuestionType=QuestionType.LowestSplenoncusVisit,GetStringFun=GetLowestSplenoncusVisit}, + new ReadingCalculateData (){QuestionType=QuestionType.LowestSplenoncusVisit,GetStringFun=GetLowestSplenoncusVisit}, + // 获取脾脏评估 + new ReadingCalculateData (){QuestionType=QuestionType.SplenicEvaluation,GetStringFun=GetSplenicEvaluation}, - new ReadingCalculateData (){QuestionType=QuestionType.SplenicEvaluation,GetStringFun=GetLowestSplenoncusVisit}, + //靶病灶评估 + new ReadingCalculateData (){QuestionType=QuestionType.TargetLesion,GetStringFun=GetTargetLesionEvaluate}, + + //非靶病灶评估 + new ReadingCalculateData (){QuestionType=QuestionType.NoTargetLesion,GetStringFun=GetNoTargetLesionEvaluate}, + + //新病灶评估 + new ReadingCalculateData (){QuestionType=QuestionType.NewLesions,GetStringFun=GetNewLesionEvaluate}, + + //CT/MRI + new ReadingCalculateData (){QuestionType=QuestionType.CTandMRI,GetStringFun=CTMRIEvaluation}, + + // PET 5PS评分 + new ReadingCalculateData (){QuestionType=QuestionType.PET5PS,GetStringFun=GetPET5PS}, + + //与基线相比摄取值变化 + new ReadingCalculateData (){QuestionType=QuestionType.UptakeChange,GetStringFun=GetUptakeChange}, + + // FDG-PET 评估结果 + new ReadingCalculateData (){QuestionType=QuestionType.UptakeChange,GetStringFun=GetUptakeChange}, ////靶病灶径线之和(SOD) //new ReadingCalculateData (){QuestionType=QuestionType.SOD,GetDecimalNullFun=GetSODData}, @@ -509,14 +530,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate // //被评估为NE的单个靶病灶 // new ReadingCalculateData (){QuestionType=QuestionType.NETarget,GetStringFun=GetNETarget}, - //靶病灶评估 - new ReadingCalculateData (){QuestionType=QuestionType.TargetLesion,GetStringFun=GetTargetLesionEvaluate}, - - //非靶病灶评估 - new ReadingCalculateData (){QuestionType=QuestionType.NoTargetLesion,GetStringFun=GetNoTargetLesionEvaluate}, - - //新病灶评估 - new ReadingCalculateData (){QuestionType=QuestionType.NewLesions,GetStringFun=GetNewLesionEvaluate}, + // //脾脏评估 //new ReadingCalculateData (){QuestionType=QuestionType.SplenicEvaluation,GetStringFun=GetNewLesionEvaluate}, @@ -1610,27 +1624,271 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate #region 获取脾脏评估 - ///// - ///// 获取脾脏评估 - ///// - ///// - ///// - //public async Task GetSplenicEvaluation(ReadingCalculateDto inDto) - //{ - // if (inDto.IsBaseLine) - // { - // return SpleenAssessment.Stabilization.GetEnumInt(); - // } - + /// + /// 获取脾脏评估 + /// + /// + /// + public async Task GetSplenicEvaluation(ReadingCalculateDto inDto) + { + 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 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(); - // // 1、基线 垂直径> 130 mm - // //2、与基线相比脾垂直径变化值≥10 mm - // //与基线相比脾肿大增加的百分比 > 50% - //} + + var differenceValue = presentSpd - baseLineSpleenLength; + decimal percentage = 0; + if (baseLineSpleenLength != 0) + { + percentage = differenceValue*100 / baseLineSpleenLength; + } + + // 1、基线 垂直径> 130 mm + //2、与基线相比脾垂直径变化值≥10 mm + //与基线相比脾肿大增加的百分比 > 50% + if (baseLineSpleenLength > 130 && differenceValue >= 10 && percentage > 50) + { + result = SpleenAssessment.Increase; + } + //1、基线垂直径≤130mm + //2、与基线相比脾垂直径变化值≥20 mm + //当前垂直径 > 130 mm + else if (baseLineSpleenLength <= 130 && differenceValue >= 20 && presentSpd > 130) + { + result = SpleenAssessment.Increase; + } + //1、基线 垂直径> 130 mm + //2、当前访视的前面访视中 存在垂直径≤130mm + //3、与最低点相比脾脏垂直径的增加值≥20 mm + //4、当前垂直径 > 130 mm + else if (baseLineSpleenLength > 130 && presentSpd <= 130 && differenceValue >= 20 && presentSpd > 130) + { + result = SpleenAssessment.Increase; + } + // 基线垂直径≤130mm + else if (baseLineSpleenLength <= 130) + { + result = SpleenAssessment.Normal; + } + //1、基线期 状态为“肿大” + //与基线相比脾肿大增加的百分比 > 50% + else if (baseLineState.EqEnum(SpleenState.Swelling) && percentage > 50) + { + result = SpleenAssessment.Remission; + } + else + { + result = SpleenAssessment.Remission; + } + return result.GetEnumInt(); + } + #endregion + + #region PET 5PS + + /// + /// 获取PET5PS评分 + /// + /// + /// + public async Task GetPET5PS(ReadingCalculateDto inDto) + { + if (inDto.IsBaseLine) + { + return SpleenAssessment.Stabilization.GetEnumInt(); + } + 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(); + + var existPET = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.ExistPET).Select(x => x.Answer).FirstOrDefault(); + if (existPET.EqEnum(ReadingYesOrNo.No)) + { + result = PET5PSScore.NE; + } + + // 本访视病灶的 max SUVmax(所有病灶中最大的)> 2 * 肝脏血池SUVmax + else if (maxSUVmax >2* LiverSUVmax) + { + result = PET5PSScore.Five; + } + //本访视病灶的SUVmax(所有病灶中最大的)>肝脏血池SUVmax + else if (maxSUVmax > LiverSUVmax) + { + result = PET5PSScore.Four; + } + //纵隔血池SUVmax<本访视点病灶的max SUVmax(所有病灶中最大的)≤1*肝脏血池SUVmax + else if (MediastinumSUVmax < maxSUVmax&& maxSUVmax <= LiverSUVmax) + { + result = PET5PSScore.Three; + } + //本访视点病灶的SUVmax(所有病灶中最大的)<纵隔血池SUVmax + else if (maxSUVmax < MediastinumSUVmax) + { + result = PET5PSScore.Two; + } + //无需标记,自主选择 + else + { + result = PET5PSScore.X; + } + return result.GetEnumInt(); + } + #endregion + + + #region 与基线相比摄取值变化 + + /// + /// 与基线相比摄取值变化 + /// + /// + /// + public async Task GetUptakeChange(ReadingCalculateDto inDto) + { + if (inDto.IsBaseLine) + { + return SUVChangeVSBaseline.NotEvaluable.GetEnumInt(); + } + + var result = SUVChangeVSBaseline.NotEvaluable; + var baseLineTaskId = await GetBaseLineTaskId(inDto); + + var PET5PS = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0(); + var baseLinePET5PS = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.PET5PS).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0(); + + + var existPET = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.ExistPET).Select(x => x.Answer).FirstOrDefault(); + //本访视无PET图像 + if (existPET.EqEnum(ReadingYesOrNo.No)) + { + result = SUVChangeVSBaseline.NotEvaluable; + } + //本访视PET评分>基线PET评分 + else if (PET5PS > baseLinePET5PS) + { + result = SUVChangeVSBaseline.Increase; + } + + //本访视PET评分<基线PET评分 + else if (PET5PS < baseLinePET5PS) + { + result = SUVChangeVSBaseline.Decrease; + } + + //访视PET评分 等于 基线PET评分 + else if (PET5PS == baseLinePET5PS) + { + result = SUVChangeVSBaseline.DidNotChange; + } + + return result.GetEnumInt(); + + } + #endregion + + #region FDG-PET总体评估结果 + + public async Task GetFDGPETOverallAssessment(ReadingCalculateDto inDto) + { + 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(); + + + 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() { MarrowFDG.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() { MarrowFDG.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() { MarrowFDG.NE,MarrowFDG.YesHaveNew,MarrowFDG.YesHaveNew,MarrowFDG.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() { MarrowFDG.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() { MarrowFDG.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() { MarrowFDG.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() { MarrowFDG.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 获取基线脾脏长度 @@ -1889,19 +2147,19 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate public async Task CTMRIEvaluation(ReadingCalculateDto inDto) { // 靶病灶评估 - var targetEvaluation = string.Empty; + var targetEvaluation = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.TargetLesion).Select(x => x.Answer).FirstOrDefault(); // 非靶病灶评估 - var noTargetEvaluation = string.Empty; + var noTargetEvaluation = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NETarget).Select(x => x.Answer).FirstOrDefault(); // 存在新病灶 - var existsNewTarget = string.Empty; + var existsNewTarget = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NewTargetLesion).Select(x => x.Answer).FirstOrDefault(); // 肝脏评估 - var liverEvaluation = string.Empty; + var liverEvaluation = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LiverAssessment).Select(x => x.Answer).FirstOrDefault(); // 脾脏评估 - var spleenEvaluation = string.Empty; + var spleenEvaluation = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SplenicEvaluation).Select(x => x.Answer).FirstOrDefault(); List data = new List() { diff --git a/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs b/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs index a6c2d65e8..2ed68212c 100644 --- a/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs +++ b/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs @@ -39,6 +39,34 @@ namespace IRaCIS.Core.Domain.Share HasSign = 3 } + /// + /// 骨髓中是否存在局灶性 FDG 亲和病灶的证据 + /// + public enum MarrowFDG + { + /// + /// NE + /// + NE = 1, + + /// + /// 是,存在新的/复发的FDG高亲和性病灶 + /// + YesHaveNew = 2, + + /// + /// 是,存在持续的局灶性变化 + /// + YesSustain = 3, + + /// + /// 否 + /// + No = 4, + + } + + /// /// 临床表格问题标识 /// @@ -811,6 +839,28 @@ namespace IRaCIS.Core.Domain.Share /// NotEvaluable = 5, + /// + /// 肿大 + /// + Swelling = 5, + + } + + /// + /// 是(1)或否(0) + /// + public enum ReadingYesOrNo + { + /// + /// 否 + /// + No = 0, + + /// + /// 是 + /// + Yes = 1, + } /// @@ -874,6 +924,75 @@ namespace IRaCIS.Core.Domain.Share /// NotEvaluable = 5, + } + /// + /// FDG-PET总体评估 + /// + public enum FDGPETOverallAssessment + { + /// + /// NA + /// + NA=-1, + + /// + /// CMR + /// + CMR=1, + + /// + /// PMR + /// + PMR=2, + + /// + /// NMR + /// + NMR=3, + + /// + /// PMD + /// + PMD=4, + + /// + /// NE + /// + NE=5, + + /// + /// ND + /// + ND=6, + + } + + +/// +/// 与基线相比摄取值变化 +/// +public enum SUVChangeVSBaseline + { + /// + /// 增大 + /// + Increase = 1, + + /// + /// 减少 + /// + Decrease = 2, + + /// + /// 无明显变化 + /// + DidNotChange = 3, + + /// + /// 无法评估 + /// + NotEvaluable = 4, + } /// @@ -2046,6 +2165,49 @@ namespace IRaCIS.Core.Domain.Share + + /// + /// PET 5PS 评分 + /// + public enum PET5PSScore + { + /// + /// 5分 + /// + Five = 5, + + /// + /// 4分 + /// + Four = 4, + + /// + /// 3分 + /// + Three = 3, + + /// + /// 2分 + /// + Two = 5, + + /// + /// 1分 + /// + One = 1, + + /// + /// X + /// + X = 0, + + /// + /// NE + /// + NE = -1, + + } + /// /// 新靶病灶评估 ///