irc-netcore-api/IRaCIS.Core.Application/Service/ReadingCalculate/IRECIST1Point1CalculateServ...

3941 lines
193 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Models;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MiniSoftware;
using System.Runtime.InteropServices;
using System.Text;
namespace IRaCIS.Core.Application.Service.ReadingCalculate
{
[ApiExplorerSettings(GroupName = "Reading")]
public class IRECIST1Point1CalculateService(IRepository<ReadingTableQuestionAnswer> _readingTableQuestionAnswerRepository,
IRepository<VisitTask> _visitTaskRepository,
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
IRepository<ReadingTableQuestionTrial> _readingTableQuestionTrialRepository,
IRepository<ReadingTableAnswerRowInfo> _readingTableAnswerRowInfoRepository,
IRepository<ReadingQuestionTrial> _readingQuestionTrialRepository,
IRepository<OrganInfo> _organInfoRepository,
IRepository<ReadingGlobalTaskInfo> _readingGlobalTaskInfoRepository,
IRepository<SubjectVisit> _subjectVisitRepository,
IRepository<TumorAssessment_IRECIST1Point1> _tumorAssessmentRepository,
IGeneralCalculateService _generalCalculateService,
IRepository<ReadingTaskQuestionAnswer> _readingTaskQuestionAnswerRepository,
IRepository<Subject> _subjectRepository,
IRepository<User> _userRepository,
IServiceProvider ServiceProvider,
IOptionsMonitor<SystemHospitalOption> _hospital,
IRepository<Dictionary> _dictionaryRepository,
IRepository<DicomStudy> _dicomStudyRepository,
IRepository<SubjectPatient> _subjectPatientRepository,
ILogger<IRECIST1Point1CalculateService> _logger, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ICriterionCalculateService
{
/// <summary>
/// 获取阅片的计算数据
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<object> GetReadingCalculationData(GetReadingCalculationDataInDto inDto)
{
return new
{
};
}
/// <summary>
/// 下载阅片报告
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<Stream> DownLoadReadReportStream(DownLoadReadReportInDto inDto)
{
var downFile = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $@"wwwroot/ReadReoprtTemplate/downLoad/{inDto.DownLoadGuid}");
Directory.CreateDirectory(downFile);
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId && x.ReadingCategory == ReadingCategory.Visit)
.Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
var visitInfo = await _subjectVisitRepository.Where(x => x.Id == taskinfo.SourceSubjectVisitId).Include(x => x.StudyList).FirstNotNullAsync();
var subjectInfo = await _subjectRepository.Where(x => x.Id == taskinfo.SubjectId).Include(x => x.SubjectPatientList).FirstNotNullAsync();
var doctor = await _userRepository.Where(x => x.Id == taskinfo.DoctorUserId).FirstOrDefaultAsync();
var trialQuestion = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId).ToListAsync();
var tableQuestion = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionTrial.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId).ToListAsync();
var dicotionCode = trialQuestion.Where(x => x.DictionaryCode != string.Empty).Select(x => x.DictionaryCode).Distinct().ToList();
dicotionCode.AddRange(tableQuestion.Where(x => x.DictionaryCode != string.Empty).Select(x => x.DictionaryCode).Distinct());
var dictionList = await _dictionaryRepository.Where(x => dicotionCode.Contains(x.Code)).Include(x => x.ChildList).ToListAsync();
List<Guid> taskIds = new List<Guid>() { };
var relatedVisitTask = await ServiceProvider.GetService<IReadingImageTaskService>().GetRelatedVisitTask(new GetRelatedVisitTaskInDto()
{
VisitTaskId = inDto.VisitTaskId
});
var relatedCount = relatedVisitTask.Item1.Count();
if (relatedCount <= 3)
{
taskIds = relatedVisitTask.Item1.Select(x => x.VisitTaskId).ToList();
}
else
{
var count = relatedVisitTask.Item1.Count();
taskIds.Add(relatedVisitTask.Item1[0].VisitTaskId);
taskIds.Add(relatedVisitTask.Item1[count - 2].VisitTaskId);
taskIds.Add(relatedVisitTask.Item1[count - 1].VisitTaskId);
}
relatedVisitTask.Item1 = relatedVisitTask.Item1.Where(x => taskIds.Contains(x.VisitTaskId)).ToList();
// 所有访视问题的答案
var answerList = await _readingTaskQuestionAnswerRepository.Where(x => taskIds.Contains(x.VisitTaskId)).Include(x => x.ReadingQuestionTrial).ToListAsync();
// 单位字典
var unitDictionary = await _dictionaryRepository.Where(x => x.Code == "ValueUnit").Include(x => x.ChildList).ToListAsync();
var imageProblem = _generalCalculateService.GetTaskanswer(answerList, dictionList, unitDictionary, inDto.VisitTaskId, QuestionType.ImageQualityAssessment);
var rowinfoList = await _readingTableAnswerRowInfoRepository.Where(x => taskIds.Contains(x.VisitTaskId)).Include(x => x.VisitTask).Include(x => x.ReadingQuestionTrial).ToListAsync();
var tableAnswerList = await _readingTableQuestionAnswerRepository.Where(x => taskIds.Contains(x.VisitTaskId)).Include(x => x.ReadingQuestionTrial).Include(x => x.ReadingTableQuestionTrial).ToListAsync();
#region 获取各个病灶
List<Dictionary<string, object>> getLesionInfo(LesionType lesionType)
{
List<decimal> targetFocusNum = rowinfoList.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.ReadingQuestionTrial.LesionType == lesionType).Select(x => x.RowIndex).OrderBy(x => x).ToList();
List<Dictionary<string, object>> targetInfo = new List<Dictionary<string, object>>();
foreach (var item in targetFocusNum)
{
var bodyPartDescription = _generalCalculateService.GetTaskTableAnswer(tableAnswerList, dictionList, unitDictionary, inDto.VisitTaskId, lesionType, QuestionMark.BodyPartDescription, item);
var rowMark = rowinfoList.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == item && x.ReadingQuestionTrial.LesionType == lesionType).Select(x => x.RowMark).FirstIsNullReturnEmpty();
var reportMark = rowinfoList.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.RowIndex == item && x.ReadingQuestionTrial.LesionType == lesionType).Select(x => x.ReportMark).FirstIsNullReturnEmpty();
if (reportMark != string.Empty)
{
rowMark = $"{rowMark}{reportMark}";
}
Dictionary<string, object> target = new Dictionary<string, object>()
{
{ "RowMark",rowMark},
{ "Organ",_generalCalculateService.GetTaskTableAnswer(tableAnswerList,dictionList,unitDictionary,inDto.VisitTaskId,lesionType,QuestionMark.Organ,item)+""+_generalCalculateService.GetTaskTableAnswer(tableAnswerList,dictionList,unitDictionary,inDto.VisitTaskId,lesionType,QuestionMark.Part,item)+ (bodyPartDescription==string.Empty?string.Empty:""+bodyPartDescription) },
{ "FirstVisit",getStateInfo(0,item, lesionType) },
{ "SecondVisit", relatedCount>=2?getStateInfo(1,item,lesionType):string.Empty },
{ "ThirdlyVisit", relatedCount>=3?getStateInfo(2,item,lesionType):string.Empty },
};
targetInfo.Add(target);
}
return targetInfo;
}
string getStateInfo(int index, decimal item, LesionType lesionType)
{
// 非淋巴结取长径 淋巴结取长短径
var state = _generalCalculateService.GetTaskTableAnswer(tableAnswerList, dictionList, unitDictionary, taskIds[index], lesionType, QuestionMark.State, item);
var majorAxis = _generalCalculateService.GetTaskTableAnswer(tableAnswerList, dictionList, unitDictionary, taskIds[index], lesionType, QuestionMark.MajorAxis, item);
var isLymph = _generalCalculateService.GetTaskTableAnswer(tableAnswerList, dictionList, unitDictionary, taskIds[index], lesionType, QuestionMark.IsLymph, item);
var shortAxis = _generalCalculateService.GetTaskTableAnswer(tableAnswerList, dictionList, unitDictionary, taskIds[index], lesionType, QuestionMark.ShortAxis, item);
var result = string.Empty;
if (!state.IsNullOrEmpty())
{
result = state;
}
if (!majorAxis.IsNullOrEmpty())
{
result += result == string.Empty ? $"L{majorAxis}" : $"L{majorAxis}";
}
if (isLymph.EqEnum(YesOrNoOrNa.Yes) && !shortAxis.IsNullOrEmpty())
{
result += result == string.Empty ? $"S{shortAxis}" : $"S{shortAxis}";
}
return result;
}
#endregion
#region 外层问题处理
// 获取外层问题
List<Dictionary<string, object>> getQuestionAnswerList(List<ExportReportQuestion> exports)
{
List<Dictionary<string, object>> questionAnswerList = new List<Dictionary<string, object>>();
foreach (var item in exports)
{
Dictionary<string, object> questionAnswer = new Dictionary<string, object>()
{
{"Name",item.QuestionName },
{"FirstVisit", _generalCalculateService.GetTaskanswer(answerList,dictionList,unitDictionary,taskIds[0],item.QuestionType)},
{"SecondVisit", relatedCount>=2? _generalCalculateService.GetTaskanswer(answerList,dictionList,unitDictionary,taskIds[1],item.QuestionType):string.Empty },
{"ThirdlyVisit", relatedCount>=3? _generalCalculateService.GetTaskanswer(answerList,dictionList,unitDictionary,taskIds[2],item.QuestionType):string.Empty },
};
questionAnswerList.Add(questionAnswer);
}
return questionAnswerList;
}
#endregion
var studyInfo = (await _dicomStudyRepository.Where(x => x.SubjectVisitId == taskinfo.SourceSubjectVisitId).Select(x => new
{
x.Modalities,
x.StudyTime,
x.BodyPartExamined,
x.Description
}).OrderBy(x => x.StudyTime).ToListAsync()).Select(x => new Dictionary<string, object>() {
{ "Modalities",x.Modalities},
{ "StudyTime",x.StudyTime?.ToString("yyyy-MM-dd")},
{ "Description",x.Description},
{ "ImageProblem",imageProblem},
}).ToList();
var subjectPatientList = await _subjectPatientRepository.Where(x => x.SubjectId == subjectInfo.Id).Include(x => x.Patient).ToListAsync();
var resultList = new List<ExportReportQuestion>()
{ new ExportReportQuestion (){ QuestionName="靶病灶径线之和SOD",QuestionType=QuestionType.SOD},
new ExportReportQuestion (){ QuestionName="非淋巴结靶病灶长径之和",QuestionType=QuestionType.SumOfDiameter},
new ExportReportQuestion (){ QuestionName="与基线相比SOD变化量",QuestionType=QuestionType.SODChange},
new ExportReportQuestion (){ QuestionName="与基线相比SOD变化百分比",QuestionType=QuestionType.SODPercent},
new ExportReportQuestion (){ QuestionName="与最低点相比SOD变化量",QuestionType=QuestionType.LowestIncrease},
new ExportReportQuestion (){ QuestionName="与最低点相比SOD变化百分比",QuestionType=QuestionType.LowPercent},
new ExportReportQuestion (){ QuestionName="最低点访视",QuestionType=QuestionType.LowVisit},
};
var isConvertedTask = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.IsConvertedTask).FirstOrDefaultAsync();
if (isConvertedTask)
{
resultList.AddRange(new List<ExportReportQuestion>()
{ new ExportReportQuestion (){ QuestionName="与触发iRECIST访视相比SOD变化量",QuestionType=QuestionType.ComparedTriggeringSODChange},
new ExportReportQuestion (){ QuestionName="新靶病灶直径之和iSOD",QuestionType=QuestionType.ISOD},
new ExportReportQuestion (){ QuestionName="与触发iRECIST访视相比iSOD变化量",QuestionType=QuestionType.ComparedTriggeringiSODChange},
});
}
var assessmentResult = string.Empty;
if (visitInfo.IsBaseLine)
{
var existDisease = answerList.Where(x => x.ReadingQuestionTrial.QuestionType == QuestionType.ExistDisease).Select(x => x.Answer).FirstIsNullReturnEmpty().EqEnum(ExistDisease.No) ? "不" : string.Empty;
assessmentResult = $"{existDisease}存在疾病";
}
else
{
assessmentResult = $"整体肿瘤评估结果为{_generalCalculateService.GetTaskanswer(answerList, dictionList, unitDictionary, inDto.VisitTaskId, QuestionType.Tumor)}";
}
var value = new Dictionary<string, object>()
{
// { "Logo" ,await _generalCalculateService.GetWordPictureMaxWL(_options.CurrentValue.MinIO.viewEndpoint+_hospital.CurrentValue.HospitalLogoPath ,System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $@"wwwroot/ReadReoprtTemplate/downLoad/{inDto.DownLoadGuid}"),110,100) },
{ "HospitalName",_hospital.CurrentValue.HospitalName } ,// 医院名称
{ "SubjectName",subjectInfo.ShortName }, //患者姓名
{ "SubjectSex", subjectInfo.Sex==string.Empty?string.Empty: subjectInfo.Sex=="M"?"男":"女" }, //患者性别
{ "SubjectAge",subjectInfo.Age==null?string.Empty: subjectInfo.Age +"岁" }, //患者年龄
{ "SubjectCode",subjectPatientList.Select(x=>x.Patient).OrderByDescending(x=>x.CreateTime).Select(x=>x.PatientIdStr).FirstIsNullReturnEmpty() }, //患者编号
{ "VisitName",visitInfo.VisitName }, //访视名称
{ "LatestScanDate",visitInfo.StudyList.Min(x=>x.StudyTime)?.ToString("yyyy-MM-dd") }, //随访日期
{ "CriterionName",taskinfo.TrialReadingCriterion.CriterionName }, //评估标准
{ "AssessmentResult", assessmentResult }, //评估结果
{ "DoctorName",doctor.LastName + doctor.FirstName}, //医生姓名
{ "SignTime",taskinfo.SignTime?.ToString("yyyy-MM-dd HH:mm:ss") }, //签名时间
{ "StudyInfo",studyInfo }, // 检查信息
{ "FirstVisit", relatedVisitTask.Item1[0].TaskName},
{ "SecondVisit",relatedCount>=2?relatedVisitTask.Item1[1].TaskName:string.Empty},
{ "ThirdlyVisit", relatedCount>=3?relatedVisitTask.Item1[2].TaskName:string.Empty},
{ "TargetInfo", getLesionInfo(LesionType.TargetLesion)}, // 靶病灶
{ "NoTargetInfo", getLesionInfo(LesionType.NonTargetLesions)}, // 非把病灶
{ "NewTargetInfo", getLesionInfo(LesionType.NewLesions)},// 新病灶
{ "NewITargetInfo", getLesionInfo(LesionType.NewTargetLesion)}, // 新靶病灶
{ "NewNoTargetInfo", getLesionInfo(LesionType.NewNonTargetLesion)}, // 新非靶病灶
{ "OtherPreviousNewInfo", getLesionInfo(LesionType.OtherPreviousNewLesion)}, // 其它既往新病灶
{ "TriggeringIRECSITInfo", getLesionInfo(LesionType.TriggeringIRECSIT)}, // 触发iRECSIT后的新病灶
{ "TargetImage", await _generalCalculateService.GetLesionPic(rowinfoList, LesionType.TargetLesion,inDto.DownLoadGuid)}, // 靶病灶图片
{ "NoTargetImage",await _generalCalculateService.GetLesionPic(rowinfoList, LesionType.NonTargetLesions,inDto.DownLoadGuid)}, // 非靶病灶图片
{ "NewImage", await _generalCalculateService.GetLesionPic(rowinfoList, LesionType.NewLesions,inDto.DownLoadGuid)}, // 新病灶图片
{ "NewITargetImage",await _generalCalculateService.GetLesionPic(rowinfoList, LesionType.NewTargetLesion,inDto.DownLoadGuid)}, // 新靶病灶
{ "NewNoTargetImage",await _generalCalculateService.GetLesionPic(rowinfoList, LesionType.NewNonTargetLesion,inDto.DownLoadGuid)}, // 新非靶病灶
{ "OtherPreviousNewImage", await _generalCalculateService.GetLesionPic(rowinfoList, LesionType.OtherPreviousNewLesion,inDto.DownLoadGuid)}, // 其它既往新病灶
{ "TriggeringIRECSITImage",await _generalCalculateService.GetLesionPic(rowinfoList, LesionType.TriggeringIRECSIT,inDto.DownLoadGuid)}, // 触发iRECSIT后的新病灶
{ "Result",getQuestionAnswerList(resultList)}, // 评估结果
{ "Curative",getQuestionAnswerList(new List<ExportReportQuestion>()
{ new ExportReportQuestion (){ QuestionName="靶病灶评估",QuestionType=QuestionType.TargetLesion},
new ExportReportQuestion (){ QuestionName="非靶病灶评估",QuestionType=QuestionType.NoTargetLesion},
new ExportReportQuestion (){ QuestionName="存在新病灶",QuestionType=QuestionType.NewLesions},
new ExportReportQuestion (){ QuestionName="存在疾病",QuestionType=QuestionType.ExistDisease},
new ExportReportQuestion (){ QuestionName="整体肿瘤评估",QuestionType=QuestionType.Tumor},
})}, // 疗效结果
{ "ReportNo",await _generalCalculateService.GetReportExportNo(taskinfo) } ,
};
value = _generalCalculateService.StringEmptyTurnedLine(value);
var templatePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"wwwroot/ReadReoprtTemplate/ReportTemplate_RECIST1.1_CN_V1.docx");
if (isConvertedTask)
{
templatePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"wwwroot/ReadReoprtTemplate/ReportTemplate_IRECIST_CN_V1.docx");
}
var outputFilePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $@"wwwroot/ReadReoprtTemplate/downLoad/{inDto.DownLoadGuid}.docx");
MiniWord.SaveAsByTemplate(outputFilePath, templatePath, value);
Directory.Delete(downFile, true);
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Stream stream = _generalCalculateService.ReadAndReturnStream(outputFilePath);
return stream;
}
else
{
var pdfurl = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"wwwroot/ReadReoprtTemplate/downLoad");
FileConvertHelper.ConvertWordToPdf(outputFilePath, pdfurl);
Stream stream = _generalCalculateService.ReadAndReturnStream(pdfurl + $"/{inDto.DownLoadGuid}.pdf");
return stream;
}
}
#region 临时对象 单个请求的生命周期 避免重复查询数据库
private List<VisitTaskAnswerInfo> visitTaskAnswerList;
/// <summary>
/// 获取Sod的值
/// </summary>
private decimal? sODData;
/// <summary>
/// 获取iSod的值
/// </summary>
private decimal? iSODData;
private string nAString = "NA";
/// <summary>
/// 上一次访视Id
/// </summary>
public Guid? lastVisitTaskId;
/// <summary>
/// 首次转变的任务ID
/// </summary>
public Guid? firstChangeTaskId;
/// <summary>
/// 触发任务list
/// </summary>
public List<TirggerTaskInfo>? compareTaskList = null;
#endregion
#region 删除病灶获取起始病灶序号
/// <summary>
/// 删除病灶获取起始病灶序号RECIST1Point1 固定是1
/// </summary>
/// <returns></returns>
public async Task<int> GetDeleteLesionStatrIndex(DeleteReadingRowAnswerInDto inDto)
{
return 1;
}
#endregion
#region 获取阅片报告
/// <summary>
/// 获取阅片报告
/// </summary>
/// <param name="indto"></param>
/// <returns></returns>
[HttpPost]
public async Task<GetReadingReportEvaluationOutDto> GetReadingReportEvaluation(GetReadingReportEvaluationInDto indto)
{
GetReadingReportEvaluationOutDto result = new GetReadingReportEvaluationOutDto();
var isConvertTask = await _visitTaskRepository.Where(x => x.Id == indto.VisitTaskId).Select(x => x.IsConvertedTask).FirstNotNullAsync();
var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == indto.VisitTaskId).FirstNotNullAsync();
result.CalculateResult = await this.GetReportVerify(new GetReportVerifyInDto()
{
VisitTaskId = indto.VisitTaskId,
IsConvertTask = isConvertTask,
BeforeConvertedTaskId = visitTaskInfo.BeforeConvertedTaskId,
});
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)
.WhereIf(isConvertTask, x => x.ConvertShowType == ConvertShowType.All || x.ConvertShowType == ConvertShowType.AfterShow)
.WhereIf(!isConvertTask, x => x.ConvertShowType == ConvertShowType.All || x.ConvertShowType == ConvertShowType.BeforeShow)
.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<TableAnsweRowInfo>(_mapper.ConfigurationProvider).ToListAsync();
result.LesionCountList = tableAnsweRowInfos.GroupBy(x => x.LesionType).Select(x => new LesionDto
{
LesionType = x.Key!.Value,
Count = x.ToList().Count()
}).ToList();
var lesionsIndexs = await _readingTableAnswerRowInfoRepository.Where(x => visitTaskIds.Contains(x.VisitTaskId)).GroupBy(x => new { x.QuestionId }).Select(x => new lesionsIndexDto()
{
QuestionId = x.Key.QuestionId,
Rowindexs = x.Select(x => x.RowIndex).Distinct().OrderBy(x => x).ToList()
}).ToListAsync();
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?>() {
QuestionMark.Organ,
QuestionMark.Location,
QuestionMark.Part,
};
// 第一级
#region 构造问题
List<ReadingReportDto> questions = questionList.Where(x => x.Type == ReadingQestionType.Group).OrderBy(x => x.ShowOrder).Select(x => new ReadingReportDto()
{
QuestionId = x.Id,
GroupName = x.GroupName,
GroupEnName = x.GroupEnName,
IsShowInDicom = x.IsShowInDicom,
Type = x.Type,
GroupId = x.GroupId,
QuestionType = x.QuestionType,
LesionType = x.LesionType,
QuestionGenre = x.QuestionGenre,
DataSource = x.DataSource,
DictionaryCode = x.DictionaryCode,
TypeValue = x.TypeValue,
QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us),
ShowOrder = x.ShowOrder,
ValueType = x.ValueType,
Unit = x.Unit,
CustomUnit = x.CustomUnit,
ReportLayType = ReportLayType.Group,
HighlightAnswer = x.HighlightAnswer,
HighlightAnswerList = x.HighlightAnswerList,
}).ToList();
// 分组
foreach (var item in questions)
{
item.Childrens = questionList.Where(x => x.GroupId == item.QuestionId).OrderBy(x => x.ShowOrder).Select(x => new ReadingReportDto()
{
GroupName = x.GroupName,
QuestionId = x.Id,
IsShowInDicom = x.IsShowInDicom,
GroupEnName = x.GroupEnName,
QuestionName = x.QuestionName.LanguageName(x.QuestionEnName, _userInfo.IsEn_Us),
LesionType = x.LesionType,
QuestionGenre = x.QuestionGenre,
DataSource = x.DataSource,
DictionaryCode = x.DictionaryCode,
Type = x.Type,
QuestionType = x.QuestionType,
TypeValue = x.TypeValue,
ShowOrder = x.ShowOrder,
OrderMark = x.OrderMark,
ValueType = x.ValueType,
Unit = x.Unit,
CustomUnit = x.CustomUnit,
ReportLayType = ReportLayType.Question,
HighlightAnswer = x.HighlightAnswer,
HighlightAnswerList = x.HighlightAnswerList,
}).ToList();
// 问题
foreach (var question in item.Childrens)
{
foreach (var task in taskInfoList)
{
var globalAnswer = globalanswerList.Where(x => x.TaskId == task.VisitTaskId && x.QuestionId == question.QuestionId).OrderByDescending(x => x.VisitTaskNum).FirstOrDefault();
var answer = answers.Where(x => x.VisitTaskId == task.VisitTaskId && x.ReadingQuestionTrialId == question.QuestionId).FirstOrDefault();
question.Answer.Add(new TaskQuestionAnswer()
{
Answer = answer == null ? string.Empty : answer.Answer,
IsGlobalChange = globalAnswer == null ? false : true,
GlobalChangeAnswer = globalAnswer == null ? string.Empty : globalAnswer.Answer,
TaskName = task.TaskName,
VisitTaskId = task.VisitTaskId,
});
}
// 构造表格行数据
var rowlist = tableAnsweRowInfos.Where(x => x.QuestionId == question.QuestionId).OrderBy(x => x.RowIndex).ToList();
question.Childrens = new List<ReadingReportDto>();
var rowoindexs = lesionsIndexs.Where(x => x.QuestionId == question.QuestionId).Select(x => x.Rowindexs.OrderBy(y => y).ToList()).FirstOrDefault();
rowoindexs = rowoindexs == null ? new List<decimal>() : rowoindexs;
foreach (var rowoindex in rowoindexs)
{
var rowinfo = rowlist.Where(x => x.RowIndex == rowoindex).FirstOrDefault();
question.Childrens.Add(new ReadingReportDto()
{
QuestionName = question.OrderMark + rowoindex.GetLesionMark(),
RowId = rowinfo?.Id,
IsShowInDicom = question.IsShowInDicom,
SplitOrMergeLesionName = rowinfo != null ? (rowinfo.MergeName.IsNullOrEmpty() ? rowinfo.SplitName : rowinfo.MergeName) : string.Empty,
SplitOrMergeType = rowinfo != null ? (rowinfo.SplitOrMergeType) : null,
LesionType = question.LesionType,
IsCanEditPosition = rowinfo != null ? (rowinfo.IsCanEditPosition) : false,
RowIndex = rowoindex,
BlindName = rowinfo != null ? rowinfo.BlindName : string.Empty,
ReportLayType = ReportLayType.Lesions,
ReportMark = rowinfo != null ? rowinfo.ReportMark : string.Empty,
});
}
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
/// <summary>
/// 测试计算
/// </summary>
/// <param name="visitTaskId"></param>
/// <param name="type"></param>
/// <returns></returns>
[HttpGet]
public async Task TestCalculate(Guid visitTaskId, QuestionType? type)
{
//_logger.LogError("测试计算");
ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(visitTaskId);
// await _generalCalculateService.LogRecord(readingData, "其他既往新病灶", LesionType.OtherPreviousNewLesion);
if (type == null)
{
await ReadingCalculate(readingData);
}
else
{
await ReadingCalculate(readingData, new List<QuestionType>() { type.Value });
}
}
/// <summary>
/// 计算任务
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task CalculateTask(CalculateTaskInDto inDto)
{
ReadingCalculateDto readingData = await _generalCalculateService.GetReadingCalculateDto(inDto.VisitTaskId);
readingData.IsChangeOtherTask = inDto.IsChangeOtherTask;
await ReadingCalculate(readingData);
}
/// <summary>
/// 获取报告验证的信息(这里每个标准可能不一样 返回用object)
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<GetReportVerifyOutDto> GetReportVerify(GetReportVerifyInDto inDto)
{
var tumorEvaluate = string.Empty;
var readingCalculateDto = await _generalCalculateService.GetReadingCalculateDto(inDto.VisitTaskId);
if (!inDto.IsConvertTask)
{
tumorEvaluate = await GetTumor(readingCalculateDto);
}
else if (inDto.BeforeConvertedTaskId != null)
{
tumorEvaluate = await GetConvertingTumor(readingCalculateDto);
}
else
{
tumorEvaluate = await GetIRECSITTargetLesionEvaluate(readingCalculateDto);
}
return new GetReportVerifyOutDto()
{
TumorEvaluate = tumorEvaluate,
IsExistDisease = await this.GetReportIsExistDisease(inDto.VisitTaskId),
};
}
/// <summary>
/// 自动计算
/// </summary>
/// <param name="inDto"></param>
/// <param name="calculateType"></param>
/// <returns></returns>
public async Task ReadingCalculate(ReadingCalculateDto inDto, List<QuestionType>? calculateType = null)
{
#region 计算 这里顺序非常重要 后面计算的值要依赖前面计算的结果
var needAddList = new List<ReadingTaskQuestionAnswerDto>();
List<ReadingCalculateData> calculateList = new List<ReadingCalculateData>()
{
//靶病灶径线之和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},
// 与触发iRECIST访视相比SOD变化量
new ReadingCalculateData (){QuestionType=QuestionType.ComparedTriggeringSODChange,GetStringFun=GetComparedTriggeringSODChange,IsConvertedTask=true},
// 新靶病灶直径之和iSOD
new ReadingCalculateData (){QuestionType=QuestionType.ISOD,GetDecimalNullFun=GetiSODData,IsConvertedTask=true},
// 与触发iRECIST访视相比iSOD变化量
new ReadingCalculateData (){QuestionType=QuestionType.ComparedTriggeringiSODChange,GetStringFun=GetComparedTriggeringiSODChange,IsConvertedTask=true},
// 靶病灶评估
new ReadingCalculateData (){QuestionType=QuestionType.TargetLesion,GetStringFun=GetTargetLesionEvaluate,IsConvertedTask=false},
// IRECIST靶病灶评估
new ReadingCalculateData (){QuestionType=QuestionType.TargetLesion,GetStringFun=GetIRECISTTargetLesionEvaluate,IsConvertedTask=true},
// 转化时靶病灶评估
new ReadingCalculateData (){QuestionType=QuestionType.TargetLesion,GetStringFun=GetConvertingTargetLesionEvaluate,IsConvertedTask=true,IsBeTransforming=true},
//非靶病灶评估
new ReadingCalculateData (){QuestionType=QuestionType.NoTargetLesion,GetStringFun=GetNoTargetLesionEvaluate,IsConvertedTask=false},
//IRECIST非靶病灶评估
new ReadingCalculateData (){QuestionType=QuestionType.NoTargetLesion,GetStringFun=GetIRECISTNoTargetLesionEvaluate,IsConvertedTask=true},
// 转化时非靶病灶评估
new ReadingCalculateData (){QuestionType=QuestionType.NoTargetLesion,GetStringFun=GetConvertingNoTargetLesionEvaluate,IsConvertedTask=true ,IsBeTransforming=true},
// IRECIST新靶病灶评估
new ReadingCalculateData (){QuestionType=QuestionType.NewTargetLesion,GetStringFun=GetNewTargetLesionEvaluate,IsConvertedTask=true},
// IRECIST新非靶病灶评估
new ReadingCalculateData (){QuestionType=QuestionType.NewNoTargetLesion,GetStringFun=GetNewNoTargetLesionEvaluate,IsConvertedTask=true},
// IRECIST其它既往新病灶评估
new ReadingCalculateData (){QuestionType=QuestionType.OtherNewTargetLesion,GetStringFun=GetOtherNewTargetLesionEvaluate,IsConvertedTask=true},
// IRECIST触发iRECIST后新病灶评估
new ReadingCalculateData (){QuestionType=QuestionType.IRECISTNewTargetLesion,GetStringFun=GetNewLesionAfterTriggeringiRECSITAssessment,IsConvertedTask=true},
//IRECIST新病灶评估
new ReadingCalculateData (){QuestionType=QuestionType.NewLesionEvaluation,GetStringFun=GetNewLesionAssessment,IsConvertedTask=true},
//是否存在新病灶
new ReadingCalculateData (){QuestionType=QuestionType.NewLesions,GetStringFun=GetNewLesionEvaluate,IsConvertedTask=false},
// IRECIST是否存在新病灶 IRECIST
new ReadingCalculateData (){QuestionType=QuestionType.NewLesions,GetStringFun=GetNewLesionIRECSITEvaluate,IsConvertedTask=true},
//是否存在疾病
new ReadingCalculateData (){QuestionType=QuestionType.ExistDisease,GetStringFun=GetIsExistDisease},
//整体肿瘤评估
new ReadingCalculateData (){QuestionType=QuestionType.Tumor,GetStringFun=GetTumor,IsConvertedTask=false},
// 转化时整体肿瘤评估
new ReadingCalculateData (){QuestionType=QuestionType.Tumor,GetStringFun=GetConvertingTumor,IsConvertedTask=true,IsBeTransforming=true},
//IRECIST整体肿瘤评估
new ReadingCalculateData (){QuestionType=QuestionType.Tumor,GetStringFun=GetIRECSITTargetLesionEvaluate,IsConvertedTask=true},
};
// 过滤转化的
calculateList = calculateList.Where(x => x.IsConvertedTask == inDto.IsConvertedTask || x.IsConvertedTask == null).ToList();
if (inDto.IsConvertedTask)
{
if (inDto.BeforeConvertedTaskId != null)
{
List<QuestionType> questionTypes = calculateList.Where(x => x.IsBeTransforming).Select(x => x.QuestionType).ToList();
// 排除这几个 且不为正在转化的
calculateList = calculateList.Where(x => !(questionTypes.Contains(x.QuestionType) && x.IsBeTransforming == false)).ToList();
}
else
{
calculateList = calculateList.Where(x => x.IsBeTransforming == false).ToList();
}
}
// 没有靶病灶只计算最后几个
if (inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).Sum(x => x.TableRowInfoList.Count()) == 0)
{
List<QuestionType> questionTypes = new List<QuestionType>()
{
QuestionType.ISOD,
QuestionType.ComparedTriggeringiSODChange,
QuestionType.ComparedTriggeringSODChange,
QuestionType.TargetLesion,
QuestionType.NoTargetLesion,
QuestionType.NewLesions,
QuestionType.Tumor,
QuestionType.ExistDisease,
QuestionType.NewTargetLesion,
QuestionType.NewNoTargetLesion,
QuestionType.OtherNewTargetLesion,
QuestionType.IRECISTNewTargetLesion,
QuestionType.NewLesionEvaluation,
};
// 没有靶病灶就删除其他几个答案的值
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();
}
var typeNAList = new List<QuestionType>
{
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);
if (value == null)
{
if (typeNAList.Contains(item.QuestionType ?? QuestionType.SOD))
{
item.Answer = nameof(YesOrNoOrNa.NA);
}
else
{
item.Answer = this.nAString;
}
}
else
{
item.Answer = value == null ? "" : value.Value.ToString();
}
}
else if (calculate.GetStringFun != null)
{
item.Answer = await calculate.GetStringFun(inDto);
}
#endregion
// 修改修约小数位数
List<ValueOfType?> valueOfTypes = new List<ValueOfType?>() {
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 ReadingTaskQuestionAnswerDto()
{
Answer = item.Answer,
QuestionType = calculate.QuestionType,
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);
// 这里在某些条件下 要删除 sod变化量 和isod变化量
// 靶病灶评估为IUPD或者ICPD
var targetLesionIsIUorIC = needAddList.Any(x => x.QuestionType == QuestionType.TargetLesion && (x.Answer.EqEnum(TargetAssessment.iUPD) || x.Answer.EqEnum(TargetAssessment.iCPD)));
// 新靶病灶为IUPD或者ICPD
var newTargetLesionIsIUorIC = needAddList.Any(x => x.QuestionType == QuestionType.NewTargetLesion && (x.Answer.EqEnum(NewTargetLesionAssessment.iUPD) || x.Answer.EqEnum(NewTargetLesionAssessment.iCPD)));
needAddList.ForEach(x =>
{
if (x.QuestionType == QuestionType.ComparedTriggeringSODChange && !targetLesionIsIUorIC)
{
x.Answer = string.Empty;
}
else if (x.QuestionType == QuestionType.ComparedTriggeringiSODChange && !newTargetLesionIsIUorIC)
{
x.Answer = string.Empty;
}
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
}
///// <summary>
///// 获取报告整体整体评估
///// </summary>
///// <param name="visitTaskId"></param>
///// <returns></returns>
//public async Task<string> GetReportTumor(Guid visitTaskId)
//{
// return await GetTumor(await _generalCalculateService.GetReadingCalculateDto(visitTaskId));
//}
/// <summary>
/// 获取报告是否存在疾病
/// </summary>
/// <param name="visitTaskId"></param>
/// <returns></returns>
public async Task<string> GetReportIsExistDisease(Guid visitTaskId)
{
return await GetIsExistDisease(await _generalCalculateService.GetReadingCalculateDto(visitTaskId));
}
/// <summary>
/// 验证访视提交
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
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 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.ReadingTableQuestionTrial.QuestionMark == QuestionMark.State
).Where(x =>
(x.ReadingQuestionTrial.LesionType == LesionType.TargetLesion && x.Answer == TargetState.UnableEvaluate.GetEnumInt())
|| (x.ReadingQuestionTrial.LesionType == LesionType.NewLesions && x.Answer == NewLesionState.UnableEvaluate.GetEnumInt())
|| (x.ReadingQuestionTrial.LesionType == LesionType.NonTargetLesions && x.Answer == NoTargetState.UnableEvaluate.GetEnumInt())
|| (x.ReadingQuestionTrial.LesionType == LesionType.NewTargetLesion && x.Answer == NewTargetLesionState.NotEvaluable.GetEnumInt())
|| (x.ReadingQuestionTrial.LesionType == LesionType.NewNonTargetLesion && x.Answer == NewNoTargetLesionState.NotEvaluable.GetEnumInt())
|| (x.ReadingQuestionTrial.LesionType == LesionType.OtherPreviousNewLesion && x.Answer == OtherPreviousNewLesionState.NotEvaluable.GetEnumInt())
|| (x.ReadingQuestionTrial.LesionType == LesionType.TriggeringIRECSIT && x.Answer == NewLesionAfterTriggeringiRECSITState.NotEvaluable.GetEnumInt())
)
.Select(x => x.RowId).Distinct().ToListAsync();
List<string> measureDataList = rowAnswerList.Where(x => !unableEvaluateRowIds.Contains(x.Id)).Select(x => x.OrderMark + x.RowIndex.GetLesionMark()).ToList();
List<string> stateIsNullList = tableAnswerList.Select(x => x.OrderMark + x.RowIndex.GetLesionMark()).ToList();
List<string> 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)] + ",";
}
if (errorMassage != string.Empty)
{
throw new BusinessValidationFailedException(errorMassage);
}
}
#region 将上一次的访视病灶添加到这一次
/// <summary>
/// 将上一次的访视病灶添加到这一次
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<AddTaskLesionAnswerFromLastTaskOutDto> AddTaskLesionAnswerFromLastTask(AddTaskLesionAnswerFromLastTaskInDto inDto)
{
var visitTaskId = inDto.VisitTaskId;
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
var baseLineVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == taskinfo.SubjectId && x.IsBaseLine).Select(x => x.Id).FirstOrDefaultAsync();
// 判断当前任务是否是基线
if (taskinfo.SourceSubjectVisitId != baseLineVisitId)
{
// 判断当前任务是是否有表格问题答案
if (!(await _readingTableQuestionAnswerRepository.AnyAsync(x => x.VisitTaskId == visitTaskId)))
{
if (taskinfo.BeforeConvertedTaskId != null)
{
await _generalCalculateService.AddConvertedTaskFocus(taskinfo.Id, taskinfo.BeforeConvertedTaskId.Value);
}
else
{
var LastVisitTaskId = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Visit &&
x.TrialReadingCriterionId == taskinfo.TrialReadingCriterionId &&
x.IsAnalysisCreate == taskinfo.IsAnalysisCreate &&
x.ArmEnum == taskinfo.ArmEnum &&
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).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).ProjectTo<CopyTableAnswerRowInfo>(_mapper.ConfigurationProvider).ToListAsync();
tableRowAnswers.ForEach(x =>
{
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).Select(y => y.Id).FirstOrDefault();
x.MergeRowId = tableRowAnswers.Where(y => y.OriginalId == x.MergeRowId).Select(y => y.Id).FirstOrDefault();
});
List<QuestionMark?> notNeedCopyMarks = new List<QuestionMark?>()
{
QuestionMark.MajorAxis,
QuestionMark.ShortAxis,
QuestionMark.State,
};
//if (taskinfo.IsConvertedTask)
//{
// notNeedCopyMarks = new List<QuestionMark?>()
//{
// QuestionMark.MajorAxis,
// QuestionMark.ShortAxis,
//};
//}
var tableAnswers = copyTableAnswers.Select(x => new ReadingTableQuestionAnswer
{
Id = NewId.NextGuid(),
Answer = notNeedCopyMarks.Contains(x.QuestionMark) ? string.Empty : x.Answer,
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,
});
var addList = _mapper.Map<List<ReadingTableAnswerRowInfo>>(tableRowAnswers);
await _readingTableAnswerRowInfoRepository.AddRangeAsync(addList);
await _readingTableQuestionAnswerRepository.AddRangeAsync(tableAnswers);
await _readingTableQuestionAnswerRepository.SaveChangesAsync();
}
}
}
return new AddTaskLesionAnswerFromLastTaskOutDto()
{
IsBaseLine = taskinfo.SourceSubjectVisitId == baseLineVisitId,
};
}
#endregion
#region 获取SOD
/// <summary>
/// 获取SOD
/// </summary>
/// <remarks>
/// 靶病灶径线之和SOD
/// 非淋巴结的长径 和淋巴结的短径
/// </remarks>
/// <returns></returns>
public async Task<decimal?> 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 非淋巴结靶病灶长径之和
/// <summary>
/// 非淋巴结靶病灶长径之和
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<decimal?> 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
/// <summary>
/// 与基线SOD相比变化量mm
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<decimal?> GetSODChange(ReadingCalculateDto inDto)
{
var value = await GetSODData(inDto);
if (value == null || inDto.IsBaseLine)
{
return null;
}
return value.NullChange0() - await GetBaseLineSOD(inDto);
}
#endregion
#region 与基线访视相比SOD变化百分比
/// <summary>
/// 与基线访视相比SOD变化百分比
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<decimal?> 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
/// <summary>
/// 与整个访视期间SOD最低点相比增加的值mm
/// </summary>
/// <param name="inDto"></param>
/// <remarks>
/// 要更新之前的
/// </remarks>
/// <returns></returns>
public async Task<decimal?> 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最低点相比增加的百分比
/// <summary>
/// 与整个访视期间SOD最低点相比增加的百分比
/// </summary>
/// <param name="inDto"></param>
/// <remarks>
/// 要更新之前的
/// </remarks>
/// <returns></returns>
public async Task<decimal?> 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最低点访视名称
/// <summary>
/// 整个访视期间SOD最低点访视名称
/// </summary>
/// <param name="inDto"></param>
/// <remarks>
/// 要更新之前的
/// </remarks>
/// <returns></returns>
public async Task<string> 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 是否存在非淋巴结靶病灶
/// <summary>
/// 是否存在非淋巴结靶病灶
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> 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以上
/// <summary>
/// 是否存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> 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();
}
/// <summary>
/// 获取存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上的病灶
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<List<decimal>> GetIsAddFiveRowIndexs(ReadingCalculateDto inDto)
{
List<decimal> result = new List<decimal>();
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的单个靶病灶
/// <summary>
/// 被评估为NE的单个靶病灶
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> 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 整体肿瘤评估
/// <summary>
/// 整体肿瘤评估
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> 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 是否存在疾病
/// <summary>
/// 是否存在疾病
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> 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 与触发iRECIST访视相比SOD变化量
/// <summary>
/// 与触发iRECIST访视相比SOD变化量
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> GetComparedTriggeringSODChange(ReadingCalculateDto inDto)
{
var compareTaskId = await this.GetCompareTaskId(inDto, QuestionType.TargetLesion);
if (compareTaskId == null)
{
return string.Empty;
}
var lastTaskId = await GetLastVisitTaskId(inDto);
// 靶病灶评估为IUPD或者ICPD
var targetLesionIsIUorIC = await _readingTaskQuestionAnswerRepository.AnyAsync(x => x.VisitTaskId == lastTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.TargetLesion && (x.Answer == TargetAssessment.iUPD.GetEnumInt() || x.Answer == TargetAssessment.iCPD.GetEnumInt()));
if (!targetLesionIsIUorIC)
{
return string.Empty;
}
var compareTaskSOD = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == compareTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SOD).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0();
var value = await GetSODData(inDto);
if (value == null || inDto.IsBaseLine || !inDto.IsConvertedTask || inDto.BeforeConvertedTaskId != null)
{
return string.Empty;
}
return (value.NullChange0() - compareTaskSOD).ToString();
}
#endregion
#region 新靶病灶直径之和iSOD
/// <summary>
/// 获取iSOD
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<decimal?> GetiSODData(ReadingCalculateDto inDto)
{
if (!inDto.IsConvertedTask)
{
return null;
}
if (iSODData != null)
{
return iSODData.Value;
}
var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.NewTargetLesion).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();
}
}
iSODData = result;
return iSODData.Value;
}
#endregion
#region 与触发iRECIST访视相比iSOD变化量
/// <summary>
/// 与触发iRECIST访视相比iSOD变化量
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> GetComparedTriggeringiSODChange(ReadingCalculateDto inDto)
{
var compareTaskId = await this.GetCompareTaskId(inDto, QuestionType.NewTargetLesion);
if (compareTaskId == null)
{
return string.Empty;
}
var lastTaskId = await GetLastVisitTaskId(inDto);
// 新靶病灶为IUPD或者ICPD
var newTargetLesionIsIUorIC = await _readingTaskQuestionAnswerRepository.AnyAsync(x => x.VisitTaskId == lastTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.NewTargetLesion && (x.Answer == NewTargetLesionAssessment.iUPD.GetEnumInt() || x.Answer == NewTargetLesionAssessment.iCPD.GetEnumInt()));
if (!newTargetLesionIsIUorIC)
{
return string.Empty;
}
var compareTaskiSOD = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == compareTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.ISOD).Select(x => x.Answer).FirstOrDefaultAsync()).IsNullOrEmptyReturn0();
var value = await GetiSODData(inDto);
if (value == null || inDto.IsBaseLine || !inDto.IsConvertedTask || inDto.BeforeConvertedTaskId != null)
{
return string.Empty;
}
return (value.NullChange0() - compareTaskiSOD).ToString();
}
#endregion
#region 修改其他标准
#region 修改与整个访视期间SOD最低点相比增加的值mm
/// <summary>
/// 修改与整个访视期间SOD最低点相比增加的值mm
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task ChangeAllLowestIncrease(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))
{
await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.VisitTaskId && x.ReadingQuestionTrialId == inDto.QuestionId, x => new ReadingTaskQuestionAnswer()
{
Answer = (item.SOD - lowSod).ToString()
});
}
}
#endregion
#region 修改整个访视期间SOD最低点相比增加的百分比
/// <summary>
/// 修改整个访视期间SOD最低点相比增加的百分比
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
//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 修改最低方式点名称
/// <summary>
/// 修改最低方式点名称
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
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 修改所有访视任务的答案
/// <summary>
/// 修改所有访视任务的答案
/// </summary>
/// <param name="visitTaskGuids"></param>
/// <param name="questionId"></param>
/// <param name="answer"></param>
/// <returns></returns>
private async Task ChangeAllVisitTaskAnswer(List<Guid> visitTaskGuids, Guid questionId, string answer)
{
await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => visitTaskGuids.Contains(x.VisitTaskId) && x.ReadingQuestionTrialId == questionId, x => new ReadingTaskQuestionAnswer()
{
Answer = answer
});
}
#endregion
#region 获取基线SOD
/// <summary>
/// 获取基线SOD
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
private async Task<decimal> 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.ArmEnum == inDto.ArmEnum
&& 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
/// <summary>
/// 获取最低方式
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<List<VisitTaskAnswerInfo>> 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 获取访视任务信息
/// <summary>
/// 获取访视任务信息
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<List<VisitTaskAnswerInfo>> 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.ReadingQuestionCriterionTrialId == inDto.TrialReadingCriterionId
&& x.VisitTask.VisitTaskNum < inDto.VisitTaskNum
&& x.SubjectId == inDto.SubjectId && x.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned && x.VisitTask.ArmEnum == inDto.ArmEnum && x.VisitTask.TaskState == TaskState.Effect && x.ReadingQuestionTrial.QuestionType == QuestionType.SOD)
.Select(x => new VisitTaskAnswerInfo
{
VisitTaskId = x.VisitTaskId,
QuestionId = x.ReadingQuestionTrialId,
VisitName = x.VisitTask.SourceSubjectVisit.VisitName,
BlindName = x.VisitTask.TaskBlindName,
SOD = 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
/// <summary>
/// 获取上一个访视任务Id
/// </summary>
/// <returns></returns>
private async Task<Guid> GetLastVisitTaskId(ReadingCalculateDto inDto)
{
if (lastVisitTaskId != null)
{
return lastVisitTaskId.Value;
}
else
{
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
var lastTaskId = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Visit &&
x.TrialReadingCriterionId == taskinfo.TrialReadingCriterionId &&
x.IsAnalysisCreate == taskinfo.IsAnalysisCreate &&
x.ArmEnum == taskinfo.ArmEnum &&
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).FirstOrDefaultAsync();
lastVisitTaskId = lastTaskId;
return lastTaskId;
}
}
/// <summary>
/// 获取比较任务Id 需要之前一次访视为IUPD或者ICPD
/// </summary>
/// <returns></returns>
private async Task<Guid?> GetCompareTaskId(ReadingCalculateDto inDto, QuestionType questionType)
{
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
var lastTaskId = await GetLastVisitTaskId(inDto);
if (compareTaskList == null)
{
// 先找到第一个转变任务的number 直接找是否为转变任务 查询耗性能
var firstChangeVisitTaskNum = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Visit &&
x.TrialReadingCriterionId == taskinfo.TrialReadingCriterionId &&
x.IsAnalysisCreate == taskinfo.IsAnalysisCreate &&
x.ArmEnum == taskinfo.ArmEnum &&
x.IsSelfAnalysis == taskinfo.IsSelfAnalysis &&
x.SubjectId == taskinfo.SubjectId && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ArmEnum == taskinfo.ArmEnum
&& x.BeforeConvertedTaskId != null && x.TaskState == TaskState.Effect
).OrderBy(x => x.VisitTaskNum).Select(x => x.VisitTaskNum).FirstOrDefaultAsync();
// 找到转变之后 所有任务
compareTaskList = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Visit &&
x.TrialReadingCriterionId == taskinfo.TrialReadingCriterionId &&
x.IsAnalysisCreate == taskinfo.IsAnalysisCreate &&
x.ArmEnum == taskinfo.ArmEnum &&
x.IsSelfAnalysis == taskinfo.IsSelfAnalysis &&
x.SubjectId == taskinfo.SubjectId && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.ArmEnum == taskinfo.ArmEnum &&
x.VisitTaskNum >= firstChangeVisitTaskNum && x.VisitTaskNum < taskinfo.VisitTaskNum && x.TaskState == TaskState.Effect
).OrderBy(x => x.VisitTaskNum).Select(x => new TirggerTaskInfo()
{
VisitTaskId = x.Id,
VisitNum = x.VisitTaskNum,
}).ToListAsync();
// 获取所有任务Id
var visitTaskids = compareTaskList.Select(x => x.VisitTaskId).ToList();
// 找到所有任务的靶病灶评估和非靶病灶评估
var answers = await _readingTaskQuestionAnswerRepository.Where(x => (x.ReadingQuestionTrial.QuestionType == QuestionType.TargetLesion || x.ReadingQuestionTrial.QuestionType == QuestionType.NewTargetLesion) &&
visitTaskids.Contains(x.VisitTaskId)
).Select(x => new TirggerAnswerInfo()
{
VisitTaskId = x.VisitTaskId,
Answer = x.Answer,
QuestionType = x.ReadingQuestionTrial.QuestionType!.Value
}).ToListAsync();
compareTaskList.ForEach(y =>
{
y.TargetAssessmentIsIUorIC = answers.Any(x => x.VisitTaskId == y.VisitTaskId && x.QuestionType == QuestionType.TargetLesion && (x.Answer == TargetAssessment.iUPD.GetEnumInt() || x.Answer == TargetAssessment.iCPD.GetEnumInt()));
y.NewTargetLesionAssessmentIsIUorIC = answers.Any(x => x.VisitTaskId == y.VisitTaskId && x.QuestionType == QuestionType.NewTargetLesion && (x.Answer == NewTargetLesionAssessment.iUPD.GetEnumInt() || x.Answer == NewTargetLesionAssessment.iCPD.GetEnumInt()));
});
}
Guid? compareTaskId = null;
if (compareTaskList.Count() == 0)
{
return compareTaskId;
}
switch (questionType)
{
case QuestionType.TargetLesion:
for (int i = compareTaskList.Count() - 1; i >= 0; i--)
{
if (i == 0)
{
return compareTaskList[0].VisitTaskId;
}
else
{
if (compareTaskList[i].TargetAssessmentIsIUorIC && !compareTaskList[i - 1].TargetAssessmentIsIUorIC)
{
return compareTaskList[i].VisitTaskId;
}
}
}
break;
case QuestionType.NewTargetLesion:
for (int i = compareTaskList.Count() - 1; i >= 0; i--)
{
if (i == 0)
{
return compareTaskList[0].VisitTaskId;
}
else
{
if (compareTaskList[i].NewTargetLesionAssessmentIsIUorIC && !compareTaskList[i - 1].NewTargetLesionAssessmentIsIUorIC)
{
return compareTaskList[i].VisitTaskId;
}
}
}
break;
}
return compareTaskId;
}
#endregion
#region 计算阅片问题 外层问题
#region IRECIST计算
#region 获取IRECIST靶病灶评估
/// <summary>
/// 获取IRECIST靶病灶评估
/// </summary>
/// <param name="inDto"></param>
/// <remarks>
/// if基线没有靶病灶
/// {
/// 靶病灶疗效为 ND
/// }
/// else if (上一访视评估为iCPD && 本次访视满足RECIST1.1的PD条件)
/// {
/// 靶病灶疗效为 ICPD
/// }
/// else if (上一访视评估为iUPD&&与触发iRECIST访视相比本次访视SOD增加不小于5mm)
/// {
/// 靶病灶疗效为 ICPD
/// }
/// else if (本次访视满足RECIST1.1的PD条件 )
/// {
/// 靶病灶疗效为 iUPD
/// } else if (有任一靶病灶为NE状态)
/// {
/// 靶病灶疗效为 NE
/// }
/// else if (所有非淋巴结靶病灶消失径线总和为0 mm && 所有淋巴结靶病灶的短径缩小到 < 10 mm && 非靶病灶中淋巴结病灶全部消失)
/// {
/// 靶病灶疗效为 iCR
/// } else if (与基线期SOD相比减小≥30 %||(所有非淋巴结靶病灶消失径线总和为0 mm && 所有淋巴结靶病灶的短径缩小到 < 10 mm&&非靶病灶中有淋巴结病灶为非消失))
/// {
/// 靶病灶疗效为 iPR
/// }
/// else
/// {
/// 靶病灶疗效为 iSD
/// }
///
/// </remarks>
/// <returns></returns>
public async Task<string> GetIRECISTTargetLesionEvaluate(ReadingCalculateDto inDto)
{
var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList();
var lastVisitTaskId = await GetLastVisitTaskId(inDto);
var targetLesionQuestionId = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.TargetLesion).Select(x => x.QuestionId).FirstOrDefault();
var sodQuestionId = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SOD).Select(x => x.QuestionId).FirstOrDefault();
IRECISTTargetLesionDto resultData = new IRECISTTargetLesionDto()
{
// 基线没有靶病灶
NotExistsTargetLesion = tableQuestion.Count() == 0,
// 上一访视评估
LastTaskTarget = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == lastVisitTaskId && x.ReadingQuestionTrialId == targetLesionQuestionId)
.Select(x => x.Answer).FirstOrDefaultAsync()) ?? string.Empty,
// 满足RECISTPD
MeetRECISTPD = (await GetTargetLesionEvaluate(inDto)) == TargetAssessment.PD.GetEnumInt(),
// 本次访视SOD与触发iRECIST访视相比本次访视SOD增加不小于5mm
SODTiggerAddGreaterThan5 = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.ComparedTriggeringSODChange).Sum(x => x.Answer.IsNullOrEmptyReturn0()) >= 5,
//比整体访视期间最低点SOD增加≥20 %
LowSodAddGreaterThan20Percent = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LowPercent).Sum(x => x.Answer.IsNullOrEmptyReturn0()) >= 20,
// 比整体访视期间最低点SOD绝对增加值≥5 mm
LowSodAddGreaterThan5 = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LowestIncrease).Sum(x => x.Answer.IsNullOrEmptyReturn0()) >= 5,
// 当前访视至少有一个“存在”状态的靶病灶
HaveExistLesion = tableQuestion.SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(TargetState.Exist)),
// 有任一靶病灶为NE状态
HaveNeLesion = tableQuestion.SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(TargetState.UnableEvaluate)),
// 所有非淋巴结靶病灶消失径线总和为0
AllLesionVanish = true,
// 所有淋巴结靶病灶的短径缩小到 < 10 mm
AllMinorAxisLessThan10 = true,
// 与基线期SOD相比减小≥30 %
BaseLineLessThan30 = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SODPercent).Sum(x => x.Answer.IsNullOrEmptyReturn0()) <= -30,
//非靶病灶中淋巴结病灶全部消失
NoTargetLymphLoss = true,
};
var noTargetTableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.NonTargetLesions).SelectMany(x => x.TableRowInfoList).ToList();
foreach (var item in noTargetTableQuestion)
{
if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(YesOrNoOrNa.Yes)))
{
resultData.NoTargetLymphLoss = resultData.NoTargetLymphLoss && item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.State).Select(x => x.Answer).FirstOrDefault() == NoTargetState.Loss.GetEnumInt();
}
}
foreach (var item in tableQuestion)
{
if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(YesOrNoOrNa.Yes)))
{
// 淋巴结的短径
resultData.AllMinorAxisLessThan10 = resultData.AllMinorAxisLessThan10 && (item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Answer).FirstOrDefault()).IsNullOrEmptyReturn0() < 10;
}
if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && !x.Answer.EqEnum(YesOrNoOrNa.Yes)))
{
resultData.AllLesionVanish = resultData.AllLesionVanish && item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.State).Select(x => x.Answer).FirstOrDefault() == TargetState.Loss.GetEnumInt();
}
}
TargetAssessment result = TargetAssessment.SD;
// if基线没有靶病灶
if (resultData.NotExistsTargetLesion)
{
// 靶病灶疗效为 ND
result = TargetAssessment.ND;
}
// else if (上一访视评估为iCPD && 本次访视满足RECIST1.1的PD条件)
else if (resultData.LastTaskTarget.EqEnum(TargetAssessment.iCPD) && resultData.MeetRECISTPD)
{
// 靶病灶疗效为 ICPD
result = TargetAssessment.iCPD;
}
// else if (上一访视评估为iUPD&&与触发iRECIST访视相比本次访视SOD增加不小于5mm)
else if (resultData.LastTaskTarget.EqEnum(TargetAssessment.iUPD) && resultData.SODTiggerAddGreaterThan5)
{
// 靶病灶疗效为 ICPD
result = TargetAssessment.iCPD;
}
// } else if (本次访视满足RECIST1.1的PD条件 )
else if (resultData.MeetRECISTPD)
{
// 靶病灶疗效为 iUPD
result = TargetAssessment.iUPD;
}
// else if (有任一靶病灶为NE状态)
else if (resultData.HaveNeLesion)
{
// 靶病灶疗效为 NE
result = TargetAssessment.NE;
}
// else if (所有非淋巴结靶病灶消失径线总和为0 mm && 所有淋巴结靶病灶的短径缩小到 < 10 mm && 非靶病灶中淋巴结病灶全部消失)
else if (resultData.AllLesionVanish && resultData.AllMinorAxisLessThan10 && resultData.NoTargetLymphLoss)
{
// 靶病灶疗效为 iCR
result = TargetAssessment.iCR;
}
// else if (与基线期SOD相比减小≥30 %||(所有非淋巴结靶病灶消失径线总和为0 mm && 所有淋巴结靶病灶的短径缩小到 < 10 mm&&非靶病灶中有淋巴结病灶为非消失))
else if (resultData.BaseLineLessThan30 || (resultData.AllLesionVanish && resultData.AllMinorAxisLessThan10 && !resultData.NoTargetLymphLoss))
{
// 靶病灶疗效为 iPR
result = TargetAssessment.iPR;
}
// else
else
{
// 靶病灶疗效为 iSD
result = TargetAssessment.iSD;
}
return result.GetEnumInt();
}
#endregion
#region IRECIST非靶病灶评估
/// <summary>
/// IRECIST非靶病灶评估
/// </summary>
/// <remarks>
/// if基线没有非靶病灶
/// {
/// 非靶病灶疗效为 ND
/// }
/// else if (上次非靶病灶评估结果为iUPD && (任一非靶病灶状态评估为“进一步增大iCPD||出现至少1个上一访视未评估为“显著增大iUPD”的病灶本次访视评估为“显著增大iUPD”))
/// {
/// 非靶病灶疗效为 iCPD
/// }
/// else if (上次非靶病灶评估结果为iCPD && 任一非靶病灶状态评估为“进一步增大iCPD”或“显著增大iUPD”)
/// {
/// 非靶病灶疗效为 iCPD
/// }
/// else if (满足RECIST1.1的PD标准)
/// {
/// 非靶病灶疗效为 iUPD
/// }
/// else if (有任一非靶病灶为NE状态)
/// {
/// 非靶病灶疗效为 NE
/// }
/// else if (全部非靶病灶均为“消失”状态)
/// {
/// 非靶病灶疗效为 iCR
/// }
/// else
/// {
/// 非靶病灶疗效为 iNN
/// }
/// </remarks>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> GetIRECISTNoTargetLesionEvaluate(ReadingCalculateDto inDto)
{
var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.NonTargetLesions).SelectMany(x => x.TableRowInfoList).ToList();
var lastVisitTaskId = await GetLastVisitTaskId(inDto);
var noTargetQuestionId = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NoTargetLesion).Select(x => x.QuestionId).FirstOrDefault();
// 找上一次任务 未被评为显著增大的非靶病灶
ReadingCalculateDto lastTaskCalculateDto = await _generalCalculateService.GetReadingCalculateDto(lastVisitTaskId);
var lastTaskNoiUPDIndexs = lastTaskCalculateDto.QuestionInfo.Where(x => x.LesionType == LesionType.NonTargetLesions).SelectMany(x => x.TableRowInfoList)
.Where(x => x.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.State && !x.Answer.EqEnum(NoTargetState.IUPD))).Select(x => x.RowIndex).ToList();
IRECISTNoTargetLesion data = new IRECISTNoTargetLesion()
{
// 基线没有非靶病灶
NotExistsNoTargetLesion = tableQuestion.Count() == 0,
// 上次非靶病灶评估结果
LastNoTargetLesion = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == lastVisitTaskId && x.ReadingQuestionTrialId == noTargetQuestionId)
.Select(x => x.Answer).FirstOrDefaultAsync()) ?? string.Empty,
// 任一非靶病灶状态评估为“进一步增大iCPD
ExistiCPD = tableQuestion.SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NoTargetState.ICPD)),
// 出现至少1个上一访视未评估为“显著增大iUPD”的病灶本次访视评估为“显著增大iUPD
LastNoUPD = tableQuestion.Where(x => lastTaskNoiUPDIndexs.Contains(x.RowIndex)).SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NoTargetState.IUPD)),
// 任一非靶病灶状态评估为 iUPD
ExistiUPD = tableQuestion.SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NoTargetState.IUPD)),
// 满足RECIST1.1PD
RECISTPD = (await GetNoTargetLesionEvaluate(inDto)).EqEnum(NoTargetAssessment.PD),
// 有任一非靶病灶为NE状态
HaveNeLesion = tableQuestion.SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NoTargetState.UnableEvaluate)),
// 全部为消失
AllVanish = true,
};
foreach (var item in tableQuestion)
{
data.AllVanish = data.AllVanish && item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NoTargetState.Loss));
}
NoTargetAssessment result = NoTargetAssessment.iNN;
// if基线没有非靶病灶
if (data.NotExistsNoTargetLesion)
{
// 非靶病灶疗效为 ND
result = NoTargetAssessment.ND;
}
// else if (上次非靶病灶评估结果为iUPD && (任一非靶病灶状态评估为“进一步增大iCPD||出现至少1个上一访视未评估为“显著增大iUPD”的病灶本次访视评估为“显著增大iUPD”))
else if (data.LastNoTargetLesion.EqEnum(NoTargetAssessment.iUPD) && (data.ExistiCPD || data.LastNoUPD))
{
// 非靶病灶疗效为 iCPD
result = NoTargetAssessment.iCPD;
}
// else if (上次非靶病灶评估结果为iCPD && 任一非靶病灶状态评估为“进一步增大iCPD”或“显著增大iUPD”)
else if (data.LastNoTargetLesion.EqEnum(NoTargetAssessment.iCPD) && (data.ExistiCPD || data.ExistiUPD))
{
// 非靶病灶疗效为 iCPD
result = NoTargetAssessment.iCPD;
}
// else if (满足RECIST1.1的PD标准)
else if (data.RECISTPD)
{
// 非靶病灶疗效为 iUPD
result = NoTargetAssessment.iUPD;
}
// else if (有任一非靶病灶为NE状态)
else if (data.HaveNeLesion)
{
// 非靶病灶疗效为 NE
result = NoTargetAssessment.NE;
}
// else if (全部非靶病灶均为“消失”状态)
else if (data.AllVanish)
{
// 非靶病灶疗效为 iCR
result = NoTargetAssessment.iCR;
}
// else
else
{
// 非靶病灶疗效为 iNN
result = NoTargetAssessment.iNN;
}
return result.GetEnumInt();
}
#endregion
#region IRECIST新靶病灶评估
/// <summary>
/// 获取IRECIST新靶病灶评估
/// </summary>
/// <remarks>
/// if所有新靶病灶消失或一直不存在任何新靶病灶
/// {
/// 疗效为 ND
/// }
/// else if (上一访视新靶病灶评估为“iUPD” && 与触发iRECIS任务iSod增加大于5mm)
/// {
/// 疗效为 iCPD
/// }
/// else if (上一访视新靶病灶评估为“iCPD”&& (当有“存在”状态的淋巴结新靶病灶||当有“存在”或“太小”状态的非淋巴结新靶病灶))
/// {
/// 疗效为 iCPD
/// }
/// else if (当有“存在”状态的淋巴结新靶病灶||当有“存在”或“太小”状态的非淋巴结新靶病灶)
/// {
/// 疗效为 iUPD
/// }
/// else if (至少有一个新靶病无法评估)
/// {
/// 疗效为 NE
/// }
/// else
///{
/// //错误级别日志:项目、标准、受试者、阅片人、任务。输出新靶病灶数据:
///}
/// </remarks>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> GetNewTargetLesionEvaluate(ReadingCalculateDto inDto)
{
var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.NewTargetLesion).SelectMany(x => x.TableRowInfoList).ToList();
if (inDto.IsBaseLine)
{
return TargetAssessment.NA.GetEnumInt();
}
var lastVisitTaskId = await GetLastVisitTaskId(inDto);
var newTargetLesionQuestionId = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NewTargetLesion).Select(x => x.QuestionId).FirstOrDefault();
var isodQuestionId = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.ISOD).Select(x => x.QuestionId).FirstOrDefault();
IRECISTNewTargetLesionDto data = new IRECISTNewTargetLesionDto()
{
// 不存在新靶病灶
NotExistsNewTargetLesion = tableQuestion.Count() == 0,
// 所有状态为消失
AllVanish = true,
// 上一访视新靶病灶评估
LastTaskNewTargetLesion = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == lastVisitTaskId && x.ReadingQuestionTrialId == newTargetLesionQuestionId)
.Select(x => x.Answer).FirstOrDefaultAsync()) ?? string.Empty,
//与触发iRECIS任务iSod增加大于5mm
ISODAdd5mm = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.ComparedTriggeringiSODChange).Sum(x => x.Answer.IsNullOrEmptyReturn0()) >= 5,
//有"存在"状态的新靶病灶
HaveExixtsState = tableQuestion.SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewTargetLesionState.Exist)),
// 至少有一个新靶病无法评估
ExixtsUnevaluableState = tableQuestion.SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewTargetLesionState.NotEvaluable)),
// 当有“存在”状态的淋巴结新靶病灶
ExixtsLymphTarget = false,
// 当有“存在”或“太小”状态的非淋巴结新靶病灶
ExixtsOrLessNoLymphTarget = false,
};
foreach (var item in tableQuestion)
{
data.AllVanish = data.AllVanish && item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewTargetLesionState.Loss));
data.ExixtsLymphTarget = data.ExixtsLymphTarget ||
(
item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewTargetLesionState.Exist)) &&
item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(YesOrNoOrNa.Yes))
);
data.ExixtsOrLessNoLymphTarget = data.ExixtsOrLessNoLymphTarget ||
(
(
item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewTargetLesionState.Exist))
|| item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewTargetLesionState.TooSmall))
)
&&
item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && !x.Answer.EqEnum(YesOrNoOrNa.Yes))
);
}
NewTargetLesionAssessment? result = NewTargetLesionAssessment.ND;
// if所有新靶病灶消失或一直不存在任何新靶病灶
if (data.NotExistsNewTargetLesion || data.AllVanish)
{
// 疗效为 ND
result = NewTargetLesionAssessment.ND;
}
// else if (上一访视新靶病灶评估为“iUPD” && 与触发iRECIS任务iSod增加大于5mm)
else if (data.LastTaskNewTargetLesion.EqEnum(NewTargetLesionAssessment.iUPD) && data.ISODAdd5mm)
{
// 疗效为 iCPD
result = NewTargetLesionAssessment.iCPD;
}
// else if (上一访视新靶病灶评估为“iCPD”&& (当有“存在”状态的淋巴结新靶病灶||当有“存在”或“太小”状态的非淋巴结新靶病灶))
else if (data.LastTaskNewTargetLesion.EqEnum(NewTargetLesionAssessment.iCPD) && (data.ExixtsLymphTarget || data.ExixtsOrLessNoLymphTarget))
{
// 疗效为 iCPD
result = NewTargetLesionAssessment.iCPD;
}
// else if (当有“存在”状态的淋巴结新靶病灶||当有“存在”或“太小”状态的非淋巴结新靶病灶)
else if (data.HaveExixtsState || data.ExixtsOrLessNoLymphTarget)
{
// 疗效为 iUPD
result = NewTargetLesionAssessment.iUPD;
}
// else if (至少有一个新靶病无法评估)
else if (data.ExixtsUnevaluableState)
{
// 疗效为 NE
result = NewTargetLesionAssessment.NE;
}
else
{
//错误级别日志:项目、标准、受试者、阅片人、任务。输出新靶病灶数据:
await _generalCalculateService.LogRecord(inDto, "新靶病灶", LesionType.NewTargetLesion);
}
return result == null ? string.Empty : result.Value.GetEnumInt();
}
#endregion
#region 获取新非靶病灶评估
/// <summary>
/// 获取新非靶病灶评估
/// </summary>
/// <remarks>
/// if所有新非靶病灶消失或一直不存在任何新非靶病灶时评估为该结果
/// {
/// 疗效为 ND
/// }
/// else if (上一访视新非靶病灶评估为“iUPD” && 满足任一新非靶病灶状态为“增大”)
/// {
/// 疗效为 iCPD
/// }
/// else if (上一访视新非靶病灶评估为“iCPD”&& 有"存在"状态的新非靶病灶)
/// {
/// 疗效为 iCPD
/// }
/// else if (当有存在状态的新非靶病灶)
/// {
/// 疗效为 iUPD
/// }
/// else if (至少有一个新非靶病无法评估)
/// {
/// 疗效为 NE
/// }
/// else
/// {
/// //错误级别日志:项目、标准、受试者、阅片人、任务。当前新非靶病灶的病灶数据输出:
/// }
/// </remarks>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> GetNewNoTargetLesionEvaluate(ReadingCalculateDto inDto)
{
var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.NewNonTargetLesion).SelectMany(x => x.TableRowInfoList).ToList();
var newTargetLesionQuestionId = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NewTargetLesion).Select(x => x.QuestionId).FirstOrDefault();
var lastVisitTaskId = await GetLastVisitTaskId(inDto);
var newNoTargetLesionQuestionId = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NewNoTargetLesion).Select(x => x.QuestionId).FirstOrDefault();
IRECISTNewNoTargetLesionDto data = new IRECISTNewNoTargetLesionDto()
{
// 不存在新非靶病灶
NotExistsNewNoTargetLesion = tableQuestion.Count() == 0,
// 所有状态为消失
AllVanish = tableQuestion.Count() == tableQuestion.Where(x => x.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewNoTargetLesionState.Loss))).Count(),
// 上一访视新非靶病灶评估
LastTaskNewNoTargetLesion = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == lastVisitTaskId && x.ReadingQuestionTrialId == newNoTargetLesionQuestionId)
.Select(x => x.Answer).FirstOrDefaultAsync()) ?? string.Empty,
//当前访视的新靶病灶评估
NewTargetLesion = inDto.QuestionInfo.Where(x => x.QuestionId == newTargetLesionQuestionId).Select(x => x.Answer).FirstIsNullReturnEmpty(),
// 任一新非靶病灶状态为“增大”
ExixtsEnlargementState = tableQuestion.SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewNoTargetLesionState.Progression)),
// 有"存在"状态的病灶
HaveExixtsState = tableQuestion.SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewNoTargetLesionState.Exist)),
// 至少有一个病灶无法评估
ExixtsUnevaluableState = tableQuestion.SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewNoTargetLesionState.NotEvaluable)),
};
NewNoTargetLesionAssessment result = NewNoTargetLesionAssessment.ND;
// if所有新非靶病灶消失或一直不存在任何新非靶病灶时评估为该结果
if (data.NotExistsNewNoTargetLesion || data.AllVanish)
{
// 疗效为 ND
result = NewNoTargetLesionAssessment.ND;
}
// else if (上一访视新非靶病灶评估为“iUPD” && 满足任一新非靶病灶状态为“增大”)
else if (data.LastTaskNewNoTargetLesion.EqEnum(NewNoTargetLesionAssessment.iUPD) && data.ExixtsEnlargementState)
{
// 疗效为 iCPD
result = NewNoTargetLesionAssessment.iCPD;
}
// else if (上一访视新非靶病灶评估为“iCPD”&& 有"存在"状态的新非靶病灶)
else if (data.LastTaskNewNoTargetLesion.EqEnum(NewNoTargetLesionAssessment.iCPD) && data.HaveExixtsState)
{
// 疗效为 iCPD
result = NewNoTargetLesionAssessment.iCPD;
}
// else if (当有存在状态的新非靶病灶)
else if (data.HaveExixtsState)
{
// 疗效为 iUPD
result = NewNoTargetLesionAssessment.iUPD;
}
// else if (至少有一个新非靶病无法评估)
else if (data.ExixtsUnevaluableState)
{
// 疗效为 NE
result = NewNoTargetLesionAssessment.NE;
}
else
{
// 错误级别日志:项目、标准、受试者、阅片人、任务。当前新非靶病灶的病灶数据输出:
await _generalCalculateService.LogRecord(inDto, "新非靶病灶", LesionType.NewNonTargetLesion);
}
return result.GetEnumInt();
}
#endregion
#region 其它既往新病灶评估
/// <summary>
/// 获取其它既往新病灶评估
/// </summary>
/// <remarks>
/// if有其它既往新病灶消失或一直不存在任何其它既往新病灶
/// {
/// 疗效为 ND
/// }
/// else if (存在状态为“明确”的其它既往新病灶)
/// {
/// 疗效为 iUPD
/// }
/// else if (至少有一个其它既往新病灶无法评估)
/// {
/// 疗效为 NE
/// }
/// else if (至少有一个其它既往新病灶为疑似状态)
/// {
/// 疗效为 疑似
/// }
/// else
/// {
/// //错误级别日志:项目、标准、受试者、阅片人、任务。输出其它既往新病灶数据:
/// }
/// </remarks>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> GetOtherNewTargetLesionEvaluate(ReadingCalculateDto inDto)
{
var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.OtherPreviousNewLesion).SelectMany(x => x.TableRowInfoList).ToList();
var lastVisitTaskId = await GetLastVisitTaskId(inDto);
IRECISTOtherNewTargetLesionDto data = new IRECISTOtherNewTargetLesionDto()
{
// 不存在其他既往新病灶记录
NotExistsOtherNewTargetLesion = tableQuestion.Count() == 0,
// 所有其他既往新病灶状态都为消失
AllVanish = tableQuestion.Count() == tableQuestion.Where(x => x.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(OtherPreviousNewLesionState.Loss))).Count(),
// 存在“明确”状态
ExistsClear = tableQuestion.SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(OtherPreviousNewLesionState.Exists)),
// 至少有一个病灶无法评估
ExixtsUnevaluableState = tableQuestion.SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(OtherPreviousNewLesionState.NotEvaluable)),
// 至少有一个其它既往新病灶为疑似状态
ExixtsSuspectedState = tableQuestion.SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(OtherPreviousNewLesionState.Equivocal)),
};
OtherPreviousNewLesionAssessment result = OtherPreviousNewLesionAssessment.ND;
// if有其它既往新病灶消失或一直不存在任何其它既往新病灶
if (data.NotExistsOtherNewTargetLesion || data.AllVanish)
{
// 疗效为 ND
result = OtherPreviousNewLesionAssessment.ND;
}
// else if (存在状态为“明确”的其它既往新病灶)
else if (data.ExistsClear)
{
// 疗效为 iUPD
result = OtherPreviousNewLesionAssessment.iUPD;
}
// else if (至少有一个其它既往新病灶无法评估)
else if (data.ExixtsUnevaluableState)
{
// 疗效为 NE
result = OtherPreviousNewLesionAssessment.NE;
}
// else if (至少有一个其它既往新病灶为疑似状态)
else if (data.ExixtsSuspectedState)
{
// 疗效为 疑似
result = OtherPreviousNewLesionAssessment.Equivocal;
}
else
{
//错误级别日志:项目、标准、受试者、阅片人、任务。输出其它既往新病灶数据:
await _generalCalculateService.LogRecord(inDto, "其它既往新病灶", LesionType.OtherPreviousNewLesion);
}
return result.GetEnumInt();
}
#endregion
#region 触发iRECIST后新病灶评估
/// <summary>
///
/// </summary>
/// <remarks>
/// if现至少1个“存在”状态的触发iRECIST后新病灶
/// {
/// 疗效为 是
/// }
/// else if (只要有一个触发iRECIST后新病灶评估为NE)
/// {
/// 疗效为 NE
/// }
/// else if (只要有一个触发iRECIST后新病灶评估为疑似)
/// {
/// 疗效为 疑似
/// }
/// else
/// {
/// 疗效为 否
/// }
///
/// </remarks>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> GetNewLesionAfterTriggeringiRECSITAssessment(ReadingCalculateDto inDto)
{
var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TriggeringIRECSIT).SelectMany(x => x.TableRowInfoList).ToList();
NewLesionAfterTriggeringiRECSITAssessment result = NewLesionAfterTriggeringiRECSITAssessment.No;
// if现至少1个“存在”状态的触发iRECIST后新病灶
if (tableQuestion.SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewLesionAfterTriggeringiRECSITState.Exist)))
{
// 疗效为 是
result = NewLesionAfterTriggeringiRECSITAssessment.Yes;
}
// else if (只要有一个触发iRECIST后新病灶评估为NE)
else if (tableQuestion.SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewLesionAfterTriggeringiRECSITState.NotEvaluable)))
{
// 疗效为 NE
result = NewLesionAfterTriggeringiRECSITAssessment.NE;
}
// else if (只要有一个触发iRECIST后新病灶评估为疑似)
else if (tableQuestion.SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewLesionAfterTriggeringiRECSITState.Equivocal)))
{
// 疗效为 疑似
result = NewLesionAfterTriggeringiRECSITAssessment.Equivocal;
}
// else
else
{
// 疗效为 否
result = NewLesionAfterTriggeringiRECSITAssessment.No;
}
return result.GetEnumInt();
}
#endregion
#region 获取新病灶评估
/// <summary>
/// 获取新病灶评估
/// </summary>
/// <remarks>
/// if(新靶病灶为ND&&新非靶病灶为ND&&其它既往新病灶为ND&&不存在触发iRECIST后新病灶
/// {
/// 疗效为 ND
/// }
/// else if (新靶病灶为iCPD||新非靶病灶为iCPD)
/// {
/// 疗效为 iCPD
/// }
/// else if (前一访视新病灶评估为iCPD && (新靶病灶有存在病灶 || 新非靶病灶有存在状态病灶 || 其它既往新病灶有存在的病灶 || 触发iRECIST后新病灶有存在病灶))
/// {
/// 疗效为 iCPD
/// }
/// else if (前一访视新病灶评估为iUPD && 新靶病灶上个访视评估为NE本次访视评估为iUPD)
/// {
/// 疗效为 iCPD
/// }
/// else if (前一访视新病灶评估为iUPD && 新非靶病灶上个访视评估为NE本次访视评估为iUPD)
/// {
/// 疗效为 iCPD
/// }
/// else if (前一访视新病灶评估为iUPD && 其它既往新病灶上个访视评估为NE或疑似本次访视评估为iUPD)
/// {
/// 疗效为 iCPD
/// }
/// else if (前一访视新病灶评估为iUPD && 触发iRECIST后新病灶评估上个访视评估为NE或否或疑似本次访视评估为是)
/// {
/// 疗效为 iCPD
/// }
/// else if (新靶病灶评估为iUPD || 新非靶病灶评估为iUPD || 其它既往新病灶评估为iUPD || 触发iRECIST后新病灶评估上个访视评估为是)
/// {
/// 疗效为 iUPD
/// }
/// else if (新靶病灶、新非靶病灶、其它既往新病灶,触发iRECIST后新病灶 任一项评估为NE)
/// {
/// 疗效为 NE
/// }
/// else if (其它既往新病灶或触发iRECIST后新病灶评估为“疑似”)
/// {
/// 疗效为 疑似
/// }
/// else
/// {
/// //错误级别日志:项目、标准、受试者、阅片人、任务。输出新病灶数据:
/// }
/// </remarks>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> GetNewLesionAssessment(ReadingCalculateDto inDto)
{
NewLesionAssessment? result = null;
var lastVisitTaskId = await GetLastVisitTaskId(inDto);
ReadingCalculateDto lastTaskCalculateDto = await _generalCalculateService.GetReadingCalculateDto(lastVisitTaskId);
IRECISTNewLesionAssessmentDto data = new IRECISTNewLesionAssessmentDto()
{
//上一次任务的新病灶评估为iUPD
LastTaskNewLesioniUPD = lastTaskCalculateDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.iUPD)),
//上一次任务的新病灶评估为iCPD
LastTaskNewLesioniCPD = lastTaskCalculateDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.iCPD)),
// 存在触发iRECIST后新病灶
ExistxIRECISTNewLesion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TriggeringIRECSIT).SelectMany(x => x.TableRowInfoList).SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && (x.Answer.EqEnum(NewLesionAfterTriggeringiRECSITState.Exist) || x.Answer.EqEnum(NewLesionAfterTriggeringiRECSITState.Equivocal))),
};
// if(新靶病灶为ND && 新非靶病灶为ND && 其它既往新病灶为ND && 不存在触发iRECIST后新病灶
if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewTargetLesion && x.Answer.EqEnum(NewTargetLesionAssessment.ND))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewNoTargetLesion && x.Answer.EqEnum(NewNoTargetLesionAssessment.ND))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.OtherNewTargetLesion && x.Answer.EqEnum(OtherPreviousNewLesionAssessment.ND))
&& !data.ExistxIRECISTNewLesion)
{
// 疗效为 ND
result = NewLesionAssessment.ND;
}
// else if (新靶病灶为iCPD||新非靶病灶为iCPD)
else if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewTargetLesion && x.Answer.EqEnum(NewTargetLesionAssessment.iCPD))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewNoTargetLesion && x.Answer.EqEnum(NewNoTargetLesionAssessment.iCPD)))
{
// 疗效为 iCPD
result = NewLesionAssessment.iCPD;
}
// else if (前一访视新病灶评估为iCPD && (新靶病灶评估为iCPD或iUPD || 新非靶病灶评估为iCPD或iUPD || 其它既往新病灶评估为iUPD || 触发iRECIST后新病灶评估为是))
else if (data.LastTaskNewLesioniCPD &&
(
inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewTargetLesion && (x.Answer.EqEnum(NewTargetLesionAssessment.iCPD) || x.Answer.EqEnum(NewTargetLesionAssessment.iUPD)))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewNoTargetLesion && (x.Answer.EqEnum(NewNoTargetLesionAssessment.iCPD) || x.Answer.EqEnum(NewNoTargetLesionAssessment.iUPD)))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.OtherNewTargetLesion && x.Answer.EqEnum(OtherPreviousNewLesionAssessment.iUPD))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.IRECISTNewTargetLesion && x.Answer.EqEnum(NewLesionAfterTriggeringiRECSITAssessment.Yes))
)
)
{
// 疗效为 iCPD
result = NewLesionAssessment.iCPD;
}
// else if (前一访视新病灶评估为iUPD && 新靶病灶上个访视评估为NE或ND本次访视评估为iUPD)
else if (data.LastTaskNewLesioniUPD &&
lastTaskCalculateDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewTargetLesion && (x.Answer.EqEnum(NewTargetLesionAssessment.NE) || x.Answer.EqEnum(NewTargetLesionAssessment.ND)))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewTargetLesion && x.Answer.EqEnum(NewTargetLesionAssessment.iUPD))
)
{
// 疗效为 iCPD
result = NewLesionAssessment.iCPD;
}
// else if (前一访视新病灶评估为iUPD && 新非靶病灶上个访视评估为NE或ND本次访视评估为iUPD)
else if (data.LastTaskNewLesioniUPD
&& lastTaskCalculateDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewNoTargetLesion && (x.Answer.EqEnum(NewNoTargetLesionAssessment.NE) || x.Answer.EqEnum(NewNoTargetLesionAssessment.ND)))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewNoTargetLesion && x.Answer.EqEnum(NewNoTargetLesionAssessment.iUPD))
)
{
// 疗效为 iCPD
result = NewLesionAssessment.iCPD;
}
// else if (前一访视新病灶评估为iUPD && 其它既往新病灶上个访视评估为NE、ND或疑似本次访视评估为iUPD)
else if (data.LastTaskNewLesioniUPD
&& lastTaskCalculateDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.OtherNewTargetLesion && (x.Answer.EqEnum(OtherPreviousNewLesionAssessment.NE) || x.Answer.EqEnum(OtherPreviousNewLesionAssessment.ND) || x.Answer.EqEnum(OtherPreviousNewLesionAssessment.Equivocal)))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.OtherNewTargetLesion && x.Answer.EqEnum(OtherPreviousNewLesionAssessment.iUPD))
)
{
// 疗效为 iCPD
result = NewLesionAssessment.iCPD;
}
// else if (前一访视新病灶评估为iUPD && 触发iRECIST后新病灶评估上个访视评估为NE或否或疑似本次访视评估为是)
else if (data.LastTaskNewLesioniUPD
&& lastTaskCalculateDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.IRECISTNewTargetLesion && (x.Answer.EqEnum(NewLesionAfterTriggeringiRECSITAssessment.NE) || x.Answer.EqEnum(NewLesionAfterTriggeringiRECSITAssessment.No) || x.Answer.EqEnum(NewLesionAfterTriggeringiRECSITAssessment.Equivocal)))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.IRECISTNewTargetLesion && x.Answer.EqEnum(NewLesionAfterTriggeringiRECSITAssessment.Yes))
)
{
// 疗效为 iCPD
result = NewLesionAssessment.iCPD;
}
// else if (新靶病灶评估为iUPD || 新非靶病灶评估为iUPD || 其它既往新病灶评估为iUPD || 触发iRECIST后新病灶评估为是)
else if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewTargetLesion && x.Answer.EqEnum(NewTargetLesionAssessment.iUPD))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewNoTargetLesion && x.Answer.EqEnum(NewNoTargetLesionAssessment.iUPD))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.OtherNewTargetLesion && x.Answer.EqEnum(OtherPreviousNewLesionAssessment.iUPD))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.IRECISTNewTargetLesion && x.Answer.EqEnum(NewLesionAfterTriggeringiRECSITAssessment.Yes))
)
{
// 疗效为 iUPD
result = NewLesionAssessment.iUPD;
}
// else if (新靶病灶、新非靶病灶、其它既往新病灶,触发iRECIST后新病灶 任一项评估为NE)
else if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewTargetLesion && x.Answer.EqEnum(NewTargetLesionAssessment.NE))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewNoTargetLesion && x.Answer.EqEnum(NewNoTargetLesionAssessment.NE))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.OtherNewTargetLesion && x.Answer.EqEnum(OtherPreviousNewLesionAssessment.NE))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.IRECISTNewTargetLesion && x.Answer.EqEnum(NewLesionAfterTriggeringiRECSITAssessment.NE))
)
{
// 疗效为 NE
result = NewLesionAssessment.NE;
}
// else if (其它既往新病灶或触发iRECIST后新病灶评估为“疑似”)
else if (
inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.OtherNewTargetLesion && x.Answer.EqEnum(OtherPreviousNewLesionAssessment.Equivocal))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.IRECISTNewTargetLesion && x.Answer.EqEnum(NewLesionAfterTriggeringiRECSITAssessment.Equivocal))
)
{
// 疗效为 疑似
result = NewLesionAssessment.Suspected;
}
else
{
//错误级别日志:项目、标准、受试者、阅片人、任务。输出新病灶数据:
// 这里是记录日志 不需要国际化
var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).Include(x => x.Trial).FirstNotNullAsync();
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.Subject).Include(x => x.DoctorUser).FirstNotNullAsync();
StringBuilder builder = new StringBuilder();
builder.AppendLine($"");
builder.AppendLine($"【项目】:【{criterionInfo.Trial.TrialCode}】");
builder.AppendLine($"【项目Id】:【{criterionInfo.TrialId}】");
builder.AppendLine($"【标准】:【{criterionInfo.CriterionName}】");
builder.AppendLine($"【标准Id】:【{criterionInfo.Id}】");
builder.AppendLine($"【受试者】:【{taskInfo.Subject.ShortName}】");
builder.AppendLine($"【受试者Id】:【{taskInfo.Subject.Id}】");
builder.AppendLine($"【阅片人】:【{taskInfo.DoctorUser.FirstName}】");
builder.AppendLine($"【阅片人Id】:【{taskInfo.DoctorUser.Id}】");
builder.AppendLine($"【任务】:【{taskInfo.TaskBlindName}】");
builder.AppendLine($"【任务Id】:【{taskInfo.Id}】");
builder.AppendLine($"【病灶类型】:【新病灶】");
builder.AppendLine($"【新靶病灶评估】:【{inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NewTargetLesion).Select(x => x.Answer).FirstIsNullReturnEmpty()}】");
builder.AppendLine($"【新非靶病灶评估】:【{inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NewNoTargetLesion).Select(x => x.Answer).FirstIsNullReturnEmpty()}】");
builder.AppendLine($"【其它既往新病灶评估】:【{inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.OtherNewTargetLesion).Select(x => x.Answer).FirstIsNullReturnEmpty()}】");
builder.AppendLine($"【触发iRECIST后新病灶评估】:【{inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.IRECISTNewTargetLesion).Select(x => x.Answer).FirstIsNullReturnEmpty()}】");
_logger.LogError(builder.ToString());
}
return result == null ? string.Empty : ((NewLesionAssessment)result).GetEnumInt();
}
#endregion
#region 获取新病灶评估
/// <summary>
/// 获取新病灶评估
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> GetNewLesionIRECSITEvaluate(ReadingCalculateDto inDto)
{
// 逻辑改了 现在转变后全部都是NA;
return NewLesionAssessment.NA.GetEnumInt();
//NewLesionAssessment result = NewLesionAssessment.No;
//if (inDto.IsBaseLine)
//{
// return NewLesionAssessment.NA.GetEnumInt();
//}
//var newTargetQuestions = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.NewTargetLesion).SelectMany(x => x.TableRowInfoList).SelectMany(x => x.TableQuestionList).ToList();
//var newNonTargetQuestions = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.NewNonTargetLesion).SelectMany(x => x.TableRowInfoList).SelectMany(x => x.TableQuestionList).ToList();
//var OtherPreviousNewLesionQuestions = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.OtherPreviousNewLesion).SelectMany(x => x.TableRowInfoList).SelectMany(x => x.TableQuestionList).ToList();
//var triggeringQuestions = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TriggeringIRECSIT).SelectMany(x => x.TableRowInfoList).SelectMany(x => x.TableQuestionList).ToList();
//// 当前访视存在至少一个明确新病灶
//if (newTargetQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewTargetLesionState.Exist))
// || newNonTargetQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewNoTargetLesionState.Exist))
// || OtherPreviousNewLesionQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(OtherPreviousNewLesionState.Exists))
// || triggeringQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewLesionAfterTriggeringiRECSITState.Exist))
// )
//{
// result = NewLesionAssessment.Yes;
//}
////只要有任何一个新病灶状态为“无法评估”
//else if (newTargetQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewTargetLesionState.NotEvaluable))
// || newNonTargetQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewNoTargetLesionState.NotEvaluable))
// || OtherPreviousNewLesionQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(OtherPreviousNewLesionState.NotEvaluable))
// || triggeringQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewLesionAfterTriggeringiRECSITState.NotEvaluable))
// )
//{
// result = NewLesionAssessment.NE;
//}
////当前访视不存在明确新病灶且存在至少一个疑似新病灶
//else if ( (!OtherPreviousNewLesionQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(OtherPreviousNewLesionState.Exists)) && OtherPreviousNewLesionQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(OtherPreviousNewLesionState.Equivocal)))
// || (!triggeringQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewLesionAfterTriggeringiRECSITState.Exist)) && triggeringQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NewLesionAfterTriggeringiRECSITState.Equivocal)))
// )
//{
// result = NewLesionAssessment.Suspected;
//}
//else
//{
// result = NewLesionAssessment.No;
//}
//return result.GetEnumInt();
}
#endregion
#region iRECSIT整体肿瘤评估
/// <summary>
///
/// </summary>
/// <remarks>
/// if上一访视整体肿瘤评估评估为iCPD && 靶病灶评估、非靶病灶评估或新病灶评估任一项为iCPD或iCPD
/// {
/// 疗效为 iCPD
/// }
/// else if (上一访视整体肿瘤评估评估为iUPD && 靶病灶评估、非靶病灶评估或新病灶评估任一项从前一访视iUPD结果评估为当前访视iCPD)
/// {
/// 疗效为 iCPD
/// }
/// else if (上一访视整体肿瘤评估评估为iUPD && 靶病灶评估、非靶病灶评估或新病灶评估任一项从前一访视非iUPD结果评估为当前访视iUPD)
/// {
/// 疗效为 iCPD
/// }
/// else if (靶病灶评估为iUPD || 非靶病灶评估为iUPD || 新病灶评估为iUPD)
/// {
/// 疗效为 iUPD
/// }
/// else if ((靶病灶评估为iCR && 非靶病灶评估为iCR && 新病灶评估为ND)|| (靶病灶评估为ND && 非靶病灶评估为iCR && 新病灶评估为ND) || (靶病灶评估为iCR && 非靶病灶评估为ND && 新病灶评估为ND))
/// {
/// 疗效为 iCR
/// }
/// else if (靶病灶评估为iPR && 非靶病灶评估为iCRiNNNE或ND && 新病灶评估为ND或疑似或NE)
/// {
/// 疗效为 iPR
/// }
/// else if (靶病灶评估为iCR && 非靶病灶评估为iNN或NE && 新病灶评估为ND或疑似或NE)
/// {
/// 疗效为 iPR
/// }
/// else if (靶病灶评估为iCR && 非靶病灶评估为iCR或ND && 新病灶评估为疑似或NE)
/// {
/// 疗效为 iPR
/// }
/// else if (靶病灶评估为ND && 非靶病灶评估为iCR && 新病灶评估为疑似或NE)
/// {
/// 疗效为 iPR
/// }
/// else if (靶病灶评估为iSD && 非靶病灶评估为iCRiNNNE或ND && 新病灶评估为ND或疑似或NE)
/// {
/// 疗效为 iSD
/// }
/// else if (靶病灶评估为ND && 非靶病灶评估为iNN && 新病灶评估为ND或疑似或NE)
/// {
/// 疗效为 iNN
/// }
/// else if (靶病灶评估为ND && 非靶病灶评估为ND && 新病灶评估为ND或疑似)
/// {
/// 疗效为 ND
/// }
/// else if (靶病灶评估为NE && 非靶病灶评估为iCRiNNNE或ND && 新病灶评估为ND或疑似或NE)
/// {
/// 疗效为 NE
/// }
/// else if (靶病灶评估为ND && 非靶病灶评估为NE && 新病灶评估为ND或疑似或NE)
/// {
/// 疗效为 NE
/// }
/// else if (靶病灶评估为ND && 非靶病灶评估为ND && 新病灶评估为NE)
/// {
/// 疗效为 NE
/// }
/// else
/// {
/// //错误级别日志:项目、标准、受试者、阅片人、任务。输出靶病灶、非靶病灶、新病灶的评估结果:
/// }
/// </remarks>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> GetIRECSITTargetLesionEvaluate(ReadingCalculateDto inDto)
{
var lastVisitTaskId = await GetLastVisitTaskId(inDto);
ReadingCalculateDto lastTaskCalculateDto = await _generalCalculateService.GetReadingCalculateDto(lastVisitTaskId);
OverallAssessment? result = null;
IRECISTTargetLesionEvaluateDto data = new IRECISTTargetLesionEvaluateDto()
{
LastTaskLesioniUPDOriCPD = lastTaskCalculateDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.Tumor && (x.Answer.EqEnum(OverallAssessment.iCPD) || x.Answer.EqEnum(OverallAssessment.iUPD))),
};
// if上一访视整体肿瘤评估评估为iCPD && 靶病灶评估、非靶病灶评估或新病灶评估任一项为iCPD或iCPD
if (lastTaskCalculateDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.Tumor && x.Answer.EqEnum(OverallAssessment.iCPD))
&& (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && (x.Answer.EqEnum(TargetAssessment.iCPD) || x.Answer.EqEnum(TargetAssessment.iUPD)))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && (x.Answer.EqEnum(NoTargetAssessment.iCPD) || x.Answer.EqEnum(NoTargetAssessment.iUPD)))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && (x.Answer.EqEnum(NewLesionAssessment.iCPD) || x.Answer.EqEnum(NewLesionAssessment.iUPD)))))
{
// 疗效为 iCPD
result = OverallAssessment.iCPD;
}
// else if (上一访视整体肿瘤评估评估为iUPD&&靶病灶评估、非靶病灶评估或新病灶评估任一项从前一访视iUPD结果评估为当前访视iCPD)
else if (lastTaskCalculateDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.Tumor && x.Answer.EqEnum(OverallAssessment.iUPD))
&& (
(
lastTaskCalculateDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.iUPD))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.iCPD))
)
||
(
lastTaskCalculateDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.iUPD))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.iCPD))
)
||
(
lastTaskCalculateDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.iUPD)))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.iCPD))
)
)
{
// 疗效为 iCPD
result = OverallAssessment.iCPD;
}
// else if (上一访视整体肿瘤评估评估为iUPD&&靶病灶评估、非靶病灶评估或新病灶评估任一项从前一访视非iUPD结果评估为当前访视iUPD)
else if (lastTaskCalculateDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.Tumor && x.Answer.EqEnum(OverallAssessment.iUPD))
&& (
(
lastTaskCalculateDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && !x.Answer.EqEnum(TargetAssessment.iUPD))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.iUPD))
)
||
(
lastTaskCalculateDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && !x.Answer.EqEnum(NoTargetAssessment.iUPD))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.iUPD))
)
||
(
lastTaskCalculateDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && !x.Answer.EqEnum(NewLesionAssessment.iUPD)))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.iUPD))
)
)
{
// 疗效为 iCPD
result = OverallAssessment.iCPD;
}
// else if (靶病灶评估为iUPD || 非靶病灶评估为iUPD || 新病灶评估为iUPD)
else if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.iUPD))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.iUPD))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.iUPD)))
{
// 疗效为 iUPD
result = OverallAssessment.iUPD;
}
//
// else if ((靶病灶评估为iCR && 非靶病灶评估为iCR && 新病灶评估为ND) || (靶病灶评估为ND && 非靶病灶评估为iCR && 新病灶评估为ND) || (靶病灶评估为iCR && 非靶病灶评估为ND && 新病灶评估为ND))
else if (
(inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.iCR))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.iCR))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.ND))
)
||
(inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.ND))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.iCR))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.ND))
)
||
(inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.iCR))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.ND))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.ND))
)
)
{
// 疗效为 iCR
result = OverallAssessment.iCR;
}
// else if (靶病灶评估为iPR && 非靶病灶评估为iCRiNNNE或ND && 新病灶评估为ND或疑似或NE)
else if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.iPR))
&& (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.iCR))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.iNN))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.NE))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.ND))
) && (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.ND))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.Suspected))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.NE))
))
{
// 疗效为 iPR
result = OverallAssessment.iPR;
}
// else if (靶病灶评估为iCR && 非靶病灶评估为iNN或NE && 新病灶评估为ND或疑似或NE)
else if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.iCR))
&& (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.iNN))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.NE))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.ND))
) && (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.ND))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.Suspected))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.NE))
))
{
// 疗效为 iPR
result = OverallAssessment.iPR;
}
// else if (靶病灶评估为iCR && 非靶病灶评估为iCR或ND && 新病灶评估为疑似或NE)
else if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.iCR))
&& (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.iCR))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.ND))
) && (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.Suspected))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.NE))
))
{
// 疗效为 iPR
result = OverallAssessment.iPR;
}
// else if (靶病灶评估为ND && 非靶病灶评估为iCR && 新病灶评估为疑似或NE)
else if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.ND))
&& (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.iCR))
) && (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.Suspected))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.NE))
))
{
// 疗效为 iPR
result = OverallAssessment.iPR;
}
// else if (靶病灶评估为iSD && 非靶病灶评估为iCRiNNNE或ND && 新病灶评估为ND或疑似或NE)
else if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.iSD))
&& (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.iCR))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.iNN))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.NE))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.ND))
) && (
inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.ND))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.Suspected))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.NE))
))
{
// 疗效为 iSD
result = OverallAssessment.iSD;
}
// else if (靶病灶评估为ND && 非靶病灶评估为iNN && 新病灶评估为ND或疑似或NE)
else if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.ND))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.iNN))
&& (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.ND))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.Suspected))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.NE))
))
{
// 疗效为 iNN
result = OverallAssessment.iNN;
}
// else if (靶病灶评估为ND && 非靶病灶评估为ND && 新病灶评估为ND或疑似)
else if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.ND))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.ND))
&& (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.ND))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.Suspected))
))
{
// 疗效为 ND
result = OverallAssessment.ND;
}
// else if (靶病灶评估为NE && 非靶病灶评估为iCRiNNNE或ND && 新病灶评估为ND或疑似或NE)
else if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.NE))
&& (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.iCR))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.iNN))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.NE))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.ND))
) && (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.ND))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.Suspected))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.NE))
))
{
// 疗效为 NE
result = OverallAssessment.NE;
}
// else if (靶病灶评估为ND && 非靶病灶评估为NE && 新病灶评估为ND或疑似或NE)
else if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.ND))
&& (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.NE))
) && (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.ND))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.Suspected))
|| inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.NE))
))
{
// 疗效为 NE
result = OverallAssessment.NE;
}
// else if (靶病灶评估为ND && 非靶病灶评估为ND && 新病灶评估为NE)
else if (inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer.EqEnum(TargetAssessment.ND))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NoTargetLesion && x.Answer.EqEnum(NoTargetAssessment.ND))
&& inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.NewLesionEvaluation && x.Answer.EqEnum(NewLesionAssessment.NE))
)
{
// 疗效为 NE
result = OverallAssessment.NE;
}
else
{
//错误级别日志:项目、标准、受试者、阅片人、任务。输出靶病灶、非靶病灶、新病灶的评估结果:
// 这里是记录日志 不需要国际化
var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialReadingCriterionId).Include(x => x.Trial).FirstNotNullAsync();
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.Subject).Include(x => x.DoctorUser).FirstNotNullAsync();
StringBuilder builder = new StringBuilder();
builder.AppendLine($"");
builder.AppendLine($"【项目】:【{criterionInfo.Trial.TrialCode}】");
builder.AppendLine($"【项目Id】:【{criterionInfo.TrialId}】");
builder.AppendLine($"【标准】:【{criterionInfo.CriterionName}】");
builder.AppendLine($"【标准Id】:【{criterionInfo.Id}】");
builder.AppendLine($"【受试者】:【{taskInfo.Subject.ShortName}】");
builder.AppendLine($"【受试者Id】:【{taskInfo.Subject.Id}】");
builder.AppendLine($"【阅片人】:【{taskInfo.DoctorUser.FirstName}】");
builder.AppendLine($"【阅片人Id】:【{taskInfo.DoctorUser.Id}】");
builder.AppendLine($"【任务】:【{taskInfo.TaskBlindName}】");
builder.AppendLine($"【任务Id】:【{taskInfo.Id}】");
builder.AppendLine($"【病灶类型】:【新病灶】");
builder.AppendLine($"【靶病灶评估】:【{inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.TargetLesion).Select(x => x.Answer).FirstIsNullReturnEmpty()}】");
builder.AppendLine($"【非靶病灶评估】:【{inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NoTargetLesion).Select(x => x.Answer).FirstIsNullReturnEmpty()}】");
builder.AppendLine($"【新病灶评估】:【{inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.NewLesionEvaluation).Select(x => x.Answer).FirstIsNullReturnEmpty()}】");
_logger.LogError(builder.ToString());
}
return result == null ? string.Empty : ((OverallAssessment)result).GetEnumInt();
}
#endregion
#endregion
#region 转化时计算
#region 获取转化的靶病灶评估
/// <summary>
/// 获取转化的靶病灶评估
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> GetConvertingTargetLesionEvaluate(ReadingCalculateDto inDto)
{
var beforeConvertedAnswer = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.BeforeConvertedTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.TargetLesion).Select(x => x.Answer).FirstOrDefaultAsync();
Dictionary<string, string> answerConverDic = new Dictionary<string, string>()
{
{TargetAssessment.SD.GetEnumInt(),TargetAssessment.iSD.GetEnumInt() },
{TargetAssessment.PR.GetEnumInt(),TargetAssessment.iPR.GetEnumInt() },
{TargetAssessment.PD.GetEnumInt(),TargetAssessment.iUPD.GetEnumInt() },
{TargetAssessment.CR.GetEnumInt(), TargetAssessment.iCR.GetEnumInt() },
};
try
{
return answerConverDic[beforeConvertedAnswer];
}
catch (Exception)
{
return beforeConvertedAnswer == null ? string.Empty : beforeConvertedAnswer;
}
}
#endregion
#region 获取转化的非靶病灶评估
/// <summary>
/// 获取转化的非靶病灶评估
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> GetConvertingNoTargetLesionEvaluate(ReadingCalculateDto inDto)
{
var beforeConvertedAnswer = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.BeforeConvertedTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.NoTargetLesion).Select(x => x.Answer).FirstOrDefaultAsync();
Dictionary<string, string> answerConverDic = new Dictionary<string, string>()
{
{NoTargetAssessment.NN.GetEnumInt(),NoTargetAssessment.iNN.GetEnumInt() },
{NoTargetAssessment.PD.GetEnumInt(),NoTargetAssessment.iUPD.GetEnumInt() },
{NoTargetAssessment.CR.GetEnumInt(), NoTargetAssessment.iCR.GetEnumInt() },
};
try
{
return answerConverDic[beforeConvertedAnswer];
}
catch (Exception)
{
return beforeConvertedAnswer == null ? string.Empty : beforeConvertedAnswer;
}
}
#endregion
#region 获取转化的整体肿瘤评估
/// <summary>
/// 获取转化的整体肿瘤评估
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> GetConvertingTumor(ReadingCalculateDto inDto)
{
var beforeConvertedAnswer = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.BeforeConvertedTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.Tumor).Select(x => x.Answer).FirstOrDefaultAsync();
Dictionary<string, string> answerConverDic = new Dictionary<string, string>()
{
{OverallAssessment.NN.GetEnumInt(),OverallAssessment.iNN.GetEnumInt() },
{OverallAssessment.PD.GetEnumInt(),OverallAssessment.iUPD.GetEnumInt() },
{OverallAssessment.CR.GetEnumInt(), OverallAssessment.iCR.GetEnumInt() },
{OverallAssessment.SD.GetEnumInt(), OverallAssessment.iSD.GetEnumInt() },
{OverallAssessment.PR.GetEnumInt(), OverallAssessment.iPR.GetEnumInt() },
};
try
{
return answerConverDic[beforeConvertedAnswer];
}
catch (Exception)
{
return beforeConvertedAnswer == null ? string.Empty : beforeConvertedAnswer;
}
}
#endregion
#endregion
#region 获取靶病灶评估
/// <summary>
/// 获取靶病灶评估
/// </summary>
/// <param name="inDto"></param>
/// <remarks>
/// 靶病灶疗效评估算法-20230306确认版本
///if基线没有靶病灶
///{
/// 靶病灶疗效为 ND
///}else
///{
/// 初始化靶病灶疗效为 SD
///
/// if (与基线期SOD相比减小≥30 %
/// {
/// 靶病灶疗效为 PR
///
/// }
///
///if (非淋巴结靶病灶长径之和 == 0 并且所有淋巴结靶病灶的短径 < 10且淋巴结非靶病灶全部消失)
/// {
/// 靶病灶疗效为 CR
///
/// }
///
///if 有被评估为NE的单个靶病灶
/// {
/// 靶病灶疗效为 NE
///
/// }
///
///if (最低点SOD > 0)
///{
/// if比整体访视期间最低点SOD增加≥20 % 且与整个访视期间最低点相比增加的值≥5 mm
/// {
/// 靶病灶疗效为 PD
///
/// }
///}
///else
///{
/// //进入该分支最低点SOD=0
/// if (当前访视SOD > 0 且与整个访视期间最低点相比增加的值≥5 mm)
/// {
/// 靶病灶疗效为PD
///
/// }
///}
///
///if上次访视点评估是CR
/// {
/// if (当前访视点淋巴结病灶,至少一个淋巴结靶病灶短径≥10 mm 并且该淋巴结靶病灶短径绝对增加值≥5 mm)
/// {
/// 靶病灶疗效为 PD
///
/// }
/// if (当前访视点非淋巴结病灶至少一个非淋巴结靶病灶的长径0 mm。)
/// {
/// 靶病灶疗效为 PD
///
/// }
///}
///}
/// </remarks>
/// <returns></returns>
public async Task<string> GetTargetLesionEvaluate(ReadingCalculateDto inDto)
{
var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList();
if (inDto.IsBaseLine)
{
return TargetAssessment.NA.GetEnumInt();
}
TargetLesionCalculateDto resultData = new TargetLesionCalculateDto()
{
// 是否存在靶病灶
ExistsTargetLesion = tableQuestion.Count() > 0,
// 最低SOD
LowSod = (await GetLowSODVisit(inDto)).Select(x => x.SOD).FirstOrDefault(),
// 当前Sod
PresentSod = (await GetSODData(inDto)) ?? 0,
//非淋巴结靶病灶长径之和 decimal
SumOfDiameter = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SumOfDiameter).Sum(x => x.Answer.IsNullOrEmptyReturn0()),
//所有淋巴结靶病灶的短径小于10mm bool
DiameterLessThan10 = true,
// SOD变化百分比
SODPercent = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SODPercent).Sum(x => x.Answer.IsNullOrEmptyReturn0()),
// SOD 百分比与基线期SOD相比减小≥30% bool
SODPercentBigger30 = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SODPercent).Sum(x => x.Answer.IsNullOrEmptyReturn0()) <= -30,
// SOD 百分比 与基线期SOD相比减小30% bool
SODPercentLess30 = 0 > inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SODPercent).Sum(x => x.Answer.IsNullOrEmptyReturn0()) &&
inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SODPercent).Sum(x => x.Answer.IsNullOrEmptyReturn0()) > -30,
// SOD 百分比 整体访视期间SOD最低点SOD相比增加20%
LowSODPercentLess20 = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LowPercent).Sum(x => x.Answer.IsNullOrEmptyReturn0()) < 20,
// SOD 百分比 比整体访视期间SOD最低点SOD增加≥20%
LowSODPercentBigger20 = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LowPercent).Sum(x => x.Answer.IsNullOrEmptyReturn0()) >= 20,
// SOD 变化值 比整体访视期间SOD最低点SOD绝对增加值5 mm
LowSODChangeLess5 = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LowestIncrease).Sum(x => x.Answer.IsNullOrEmptyReturn0()) < 5,
// 比整体访视期间SOD最低点SOD绝对增加值≥5 mm
LowSODChangeBigger5 = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LowestIncrease).Sum(x => x.Answer.IsNullOrEmptyReturn0()) >= 5,
// 被评估为NE的单个靶病灶 是否存在状态为不可评估的靶病灶
ExixtsNETargetLesion = tableQuestion.SelectMany(x => x.TableQuestionList).Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(TargetState.UnableEvaluate)),
//// 上次访视点整体肿瘤评估
LastTargetLesionEvaluate = string.Empty,
// 当前访视点非淋巴结病灶至少一个非淋巴结靶病灶的长径0 mm
CurrentMajoreBigger0 = false,
// 当前访视点淋巴结病灶, 至少一个淋巴结靶病灶短径≥10 mm
CurrenShortBigger10 = false,
// 靶病灶短径增加值有5mm的Index
AddFiveIndexs = await GetIsAddFiveRowIndexs(inDto),
// 短径有10mm的Index
ShortBigger10Indexs = new List<decimal>(),
//淋巴结非靶病灶状态全部为消失
NonTargetStateIsLoss = true,
// 该淋巴结靶病灶短径绝对增加值≥5 mm
IsAddFive = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.IsAddFive && x.Answer.EqEnum(YesOrNoOrNa.Yes)).Count() > 0,
};
var nonTargetTableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.NonTargetLesions).SelectMany(x => x.TableRowInfoList).ToList();
foreach (var item in nonTargetTableQuestion)
{
if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(YesOrNoOrNa.Yes)))
{
// 淋巴结非靶病灶状态全部为消失
resultData.NonTargetStateIsLoss = resultData.NonTargetStateIsLoss && item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.State).Select(x => x.Answer).FirstOrDefault() == NoTargetState.Loss.GetEnumInt();
}
}
foreach (var item in tableQuestion)
{
if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer.EqEnum(YesOrNoOrNa.Yes)))
{
// 淋巴结的短径
resultData.DiameterLessThan10 = resultData.DiameterLessThan10 && (item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Answer).FirstOrDefault()).IsNullOrEmptyReturn0() < 10;
var shortIsBigger10 = (item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Answer).FirstOrDefault()).IsNullOrEmptyReturn0() >= 10;
resultData.CurrenShortBigger10 = resultData.CurrenShortBigger10 || shortIsBigger10;
if (shortIsBigger10)
{
resultData.ShortBigger10Indexs.Add(item.RowIndex);
}
}
if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && !x.Answer.EqEnum(YesOrNoOrNa.Yes)))
{
// 当前访视点非淋巴结病灶至少一个非淋巴结靶病灶的长径
resultData.CurrentMajoreBigger0 = resultData.CurrentMajoreBigger0 || (item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.MajorAxis).Select(x => x.Answer).FirstOrDefault()).IsNullOrEmptyReturn0() > 0;
}
}
var lastVisitTaskId = await GetLastVisitTaskId(inDto);
var questionId = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.Tumor).Select(x => x.QuestionId).FirstOrDefault();
resultData.LastTargetLesionEvaluate = (await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == lastVisitTaskId && x.ReadingQuestionTrialId == questionId)
.Select(x => x.Answer).FirstOrDefaultAsync()) ?? string.Empty;
TargetAssessment result = TargetAssessment.SD;
//if基线没有靶病灶
if (!resultData.ExistsTargetLesion)
{
// 靶病灶疗效为 ND
result = TargetAssessment.ND;
}
else
{
//初始化靶病灶疗效为 SD
result = TargetAssessment.SD;
//if (与基线期SOD相比减小≥30 %
if (resultData.SODPercentBigger30)
{
//靶病灶疗效为 PR
result = TargetAssessment.PR;
}
//if (非淋巴结靶病灶长径之和 == 0 并且所有淋巴结靶病灶的短径 < 10且淋巴结非靶病灶全部消失)
if (resultData.SumOfDiameter == 0 && resultData.DiameterLessThan10 && resultData.NonTargetStateIsLoss)
{
//靶病灶疗效为 CR
result = TargetAssessment.CR;
}
// if 有被评估为NE的单个靶病灶
if (resultData.ExixtsNETargetLesion)
{
// 靶病灶疗效为 NE
result = TargetAssessment.NE;
}
//if (最低点SOD > 0)
if (resultData.LowSod > 0)
{
// if比整体访视期间最低点SOD增加≥20 % 且与整个访视期间最低点相比增加的值≥5 mm
if (resultData.LowSODPercentBigger20 && resultData.LowSODChangeBigger5)
{
// 靶病灶疗效为 PD
result = TargetAssessment.PD;
}
}
else
{
//进入该分支最低点SOD=0
// if (当前访视SOD > 0 且与整个访视期间最低点相比增加的值≥5 mm)
if (resultData.PresentSod > 0 && resultData.LowSODChangeBigger5)
{
// 靶病灶疗效为PD
result = TargetAssessment.PD;
}
}
//if上次访视点评估是CR
if (resultData.LastTargetLesionEvaluate.EqEnum(OverallAssessment.CR))
{
//if (当前访视点淋巴结病灶,至少一个淋巴结靶病灶短径≥10 mm 并且该淋巴结靶病灶短径绝对增加值≥5 mm)
// 换句话说 就是 短径≥10 的病灶 和 短径增加值≥5的病灶 的交集数量大于0
if (resultData.ShortBigger10Indexs.Intersect(resultData.AddFiveIndexs).ToList().Count() > 0)
{
//靶病灶疗效为 PD
result = TargetAssessment.PD;
}
//if (当前访视点非淋巴结病灶至少一个非淋巴结靶病灶的长径0 mm。)
if (resultData.CurrentMajoreBigger0)
{
//靶病灶疗效为 PD
result = TargetAssessment.PD;
}
}
#region 之前的逻辑 备注
//if (resultData.LastTargetLesionEvaluate.EqEnum(TargetAssessment.CR))
//{
// if (resultData.ExixtsNETargetLesion)
// {
// result = TargetAssessment.NE;
// }
// if (resultData.CurrenShortBigger10 && resultData.IsAddFive)
// {
// result = TargetAssessment.PD;
// }
// if (resultData.CurrentMajoreBigger0)
// {
// result = TargetAssessment.PD;
// }
//}
//else
//{
// if (resultData.LowSod != 0 && resultData.LowPercentBigger20 && resultData.LowChangeBigger5)
// {
// result = TargetAssessment.PD;
// }
// else
// {
// if (resultData.ExixtsNETargetLesion)
// {
// result = TargetAssessment.NE;
// }
// else
// {
// if (resultData.SODPercentBigger30)
// {
// if (resultData.LowPercentLess20 || resultData.LowChangeLess5)
// {
// result = TargetAssessment.PR;
// }
// if (resultData.SumOfDiameter == 0 && resultData.DiameterLessThan10 && resultData.NonTargetStateIsLoss)
// {
// result = TargetAssessment.CR;
// }
// }
// }
// }
//}
#endregion
}
return result.GetEnumInt();
}
#endregion
#region 获取非靶病灶评估
/// <summary>
/// 获取非靶病灶评估
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> GetNoTargetLesionEvaluate(ReadingCalculateDto inDto)
{
NoTargetAssessment result = NoTargetAssessment.NN;
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.Any(x => x.QuestionMark == QuestionMark.State && (x.Answer.EqEnum(NoTargetState.Increase) || x.Answer.EqEnum(NoTargetState.IUPD))))
{
result = NoTargetAssessment.PD;
}
// 任意单个病灶/病灶组评估为“无法评估”并且没有“显著增大”
else if (tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NoTargetState.UnableEvaluate)) &&
!tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NoTargetState.Increase))
)
{
result = NoTargetAssessment.NE;
}
// 所有单个病灶/病灶组评估为”存在”或者有些评估为“消失”有些评估为“存在”,且没有“显著增大”和“无法评估”的病灶
else if (tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer.EqEnum(NoTargetState.Exist))
&& !tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && (x.Answer.EqEnum(NoTargetState.Increase) || x.Answer.EqEnum(NoTargetState.UnableEvaluate)))
)
{
result = NoTargetAssessment.NN;
}
//所有单个病灶/病灶组状态评估状态为“消失”
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 if (tableQuestions.Count() == 0)
{
result = NoTargetAssessment.ND;
}
else
{
return string.Empty;
}
return result.GetEnumInt();
}
#endregion
#region 获取新病灶评估
/// <summary>
/// 获取新病灶评估
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<string> 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
#endregion
}
}