//-------------------------------------------------------------------- // 此代码由T4模板自动生成 byzhouhang 20210918 // 生成时间 2022-08-22 09:33:24 // 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。 //-------------------------------------------------------------------- using IRaCIS.Core.Domain.Models; using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Application.Interfaces; using IRaCIS.Core.Application.ViewModel; using Panda.DynamicWebApi.Attributes; using IRaCIS.Core.Domain.Share; namespace IRaCIS.Core.Application.Service { /// /// 阅片计算 /// [NonDynamicWebApi] [ApiExplorerSettings(GroupName = "Reading")] public class ReadingCalculateService : BaseService, IReadingCalculateService { private readonly IRepository _readingTableQuestionAnswerRepository; private readonly IRepository _visitTaskRepository; private readonly IRepository _readingTableQuestionTrialRepository; private readonly IRepository _subjectVisitRepository; private readonly IRepository _tumorAssessmentRepository; private readonly IRepository _readingTaskQuestionAnswerRepository; public ReadingCalculateService( IRepository readingTableQuestionAnswerRepository, IRepository visitTaskRepository, IRepository readingTableQuestionTrialRepository, IRepository subjectVisitRepository, IRepository tumorAssessmentRepository, IRepository ReadingTaskQuestionAnswerRepository ) { this._readingTableQuestionAnswerRepository = readingTableQuestionAnswerRepository; this._visitTaskRepository = visitTaskRepository; this._readingTableQuestionTrialRepository = readingTableQuestionTrialRepository; this._subjectVisitRepository = subjectVisitRepository; this._tumorAssessmentRepository = tumorAssessmentRepository; this._readingTaskQuestionAnswerRepository = ReadingTaskQuestionAnswerRepository; } #region 获取SOD /// /// 获取SOD /// /// /// 靶病灶径线之和(SOD) /// 非淋巴结的长径 和淋巴结的短径 /// /// public async Task GetSODData(ReadingCalculateDto inDto) { var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList(); decimal result = 0; foreach (var item in tableQuestion) { if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer == "是")) { // 淋巴结的短径 result += decimal.Parse(item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Answer).FirstOrDefault() ?? "0"); } if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer == "否")) { // 非淋巴结的长径 result += decimal.Parse(item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.MajorAxis).Select(x => x.Answer).FirstOrDefault() ?? "0"); } } return result; } #endregion #region 非淋巴结靶病灶长径之和 /// /// 非淋巴结靶病灶长径之和 /// /// /// public async Task GetSumOfDiameter(ReadingCalculateDto inDto) { var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList(); decimal result = 0; foreach (var item in tableQuestion) { if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer == "否")) { // 非淋巴结的长径 result += decimal.Parse(item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.MajorAxis).Select(x => x.Answer).FirstOrDefault() ?? "0"); } } return result; } #endregion #region 与基线SOD相比变化量(mm) /// /// 与基线SOD相比变化量(mm) /// /// /// public async Task GetSODChange(ReadingCalculateDto inDto) { return await GetSODData(inDto) - await GetBaseLineSOD(inDto); } #endregion #region 与整个访视期间最低点相比增加的百分比 /// /// 与整个访视期间最低点相比增加的百分比 /// /// /// public async Task GetSODPercent(ReadingCalculateDto inDto) { var thisSOD = await GetSODData(inDto); var baseLineSOD = await GetBaseLineSOD(inDto); if (baseLineSOD == 0) { return 100; } else { return decimal.Round(thisSOD * 100 / baseLineSOD, 2); } } #endregion #region 与整个访视期间最低点相比增加的值(mm) /// /// 与整个访视期间最低点相比增加的值(mm) /// /// /// /// 要更新之前的 /// /// public async Task GetLowestIncrease(ReadingCalculateDto inDto) { var decimalAnswerList = await GetVisitTaskAnswerList(inDto); var minSOD = decimalAnswerList.OrderBy(x => x.SOD).Select(x => x.SOD).FirstOrDefault(); return await GetSODData(inDto) - minSOD; } #endregion #region 与整个访视期间最低点相比增加的百分比 /// /// 与整个访视期间最低点相比增加的百分比 /// /// /// /// 要更新之前的 /// /// public async Task GetLowPercent(ReadingCalculateDto inDto) { var thisSOD = await GetSODData(inDto); var decimalAnswerList = await GetVisitTaskAnswerList(inDto); var minSOD = decimalAnswerList.OrderBy(x => x.SOD).Select(x => x.SOD).FirstOrDefault(); if (minSOD == 0) { return 100; } else { return decimal.Round(thisSOD * 100 / minSOD, 2); } } #endregion #region 整个访视期间最低点访视名称 /// /// 整个访视期间最低点访视名称 /// /// /// /// 要更新之前的 /// /// public async Task GetLowVisit(ReadingCalculateDto inDto) { var decimalAnswerList = await GetVisitTaskAnswerList(inDto); return decimalAnswerList.OrderBy(x => x.SOD).Select(x => x.VisitName).FirstOrDefault() ?? string.Empty; } #endregion #region 是否存在非淋巴结靶病灶 /// /// 是否存在非淋巴结靶病灶 /// /// /// public async Task GetIsLymphTarget(ReadingCalculateDto inDto) { 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 == "是")) { return "是"; } } return "否"; } #endregion #region 是否存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上 /// /// 是否存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上 /// /// /// public async Task GetIsAddFive(ReadingCalculateDto inDto) { 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).ToListAsync(); var rowIndexs = lastQuestionAsnwer.Where(x=>x.ReadingTableQuestionTrial.QuestionMark==QuestionMark.IsLymph&&x.Answer=="是").Select(x => x.RowIndex).Distinct().OrderBy(x => x).ToList(); var thisQuestionAsnwer = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList(); var isExists = false; foreach (var item in rowIndexs) { var lastValue = decimal.Parse(lastQuestionAsnwer.Where(x => x.RowIndex == item && x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Answer).FirstOrDefault() ?? "0"); var thisRowData = thisQuestionAsnwer.Where(x => x.RowIndex == item).SelectMany(x => x.TableQuestionList).ToList(); var thisValue = decimal.Parse(thisRowData.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Answer).FirstOrDefault() ?? "0"); if (thisValue - lastValue > 5) { isExists = true; } } return isExists; } #endregion #region 被评估为NE的单个靶病灶 /// /// 被评估为NE的单个靶病灶 /// /// /// public async Task GetNETarget(ReadingCalculateDto inDto) { var result = inDto.QuestionInfo.Any(x => x.QuestionType == QuestionType.TargetLesion && x.Answer == "NE"); return result ? "有" : "无"; } #endregion #region 整体肿瘤评估 /// /// 整体肿瘤评估 /// /// /// public async Task GetTumor(ReadingCalculateDto inDto) { 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 == targetLesion && x.NonTargetLesions == noTargetLesion && x.NewLesion == newLesions).Select(x => x.OverallEfficacy).FirstOrDefaultAsync(); return result ?? string.Empty; } #endregion #region 通用方法 #region 获取基线SOD /// /// 获取基线SOD /// /// /// private async Task GetBaseLineSOD(ReadingCalculateDto inDto) { if (await _visitTaskRepository.AnyAsync(x => x.Id == inDto.VisitTaskId && x.SourceSubjectVisit.IsBaseLine&&!x.IsAnalysisCreate)) { return 0; } // 先找到基线的任务 var baseLineTaskId = await _visitTaskRepository.Where(x => x.SubjectId == inDto.SubjectId && x.ReadingCategory == ReadingCategory.Visit && x.SourceSubjectVisit.IsBaseLine && x.TaskState == TaskState.Effect&&!x.IsAnalysisCreate) .Select(x => x.Id).FirstOrDefaultAsync(); var baseLineSOD = decimal.Parse(await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == baseLineTaskId && x.ReadingQuestionTrial.QuestionType == QuestionType.SOD).Select(x => x.Answer).FirstOrDefaultAsync() ?? "0"); return baseLineSOD; } #endregion #region 获取访视任务信息 /// /// 获取访视任务信息 /// /// /// private async Task> GetVisitTaskAnswerList(ReadingCalculateDto inDto) { var answerList = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTask.ReadingCategory == ReadingCategory.Visit && x.SubjectId == inDto.SubjectId && x.VisitTask.ReadingTaskState == ReadingTaskState.HaveSigned && x.VisitTask.TaskState == TaskState.Effect && x.ReadingQuestionTrial.QuestionType == QuestionType.SOD) .Select(x => new { VisitName = x.VisitTask.SourceSubjectVisit.VisitName, SOD = x.Answer }).ToListAsync(); var decimalAnswerList = answerList.Select(x => new VisitTaskAnswerInfo { VisitName = x.VisitName, SOD = decimal.Parse(x.SOD ?? "0"), }).ToList(); return decimalAnswerList; } #endregion /// /// 获取上一个访视任务Id /// /// private async Task GetLastVisitTaskId(ReadingCalculateDto inDto) { // 拿到这一个访视 var thisNum = await _subjectVisitRepository.Where(x => x.Id == inDto.SubjectVisitId).Select(x => x.VisitNum).FirstOrDefaultAsync(); // 先找到上一个访视 var lastVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == inDto.SubjectId && x.VisitNum < thisNum).OrderByDescending(x => x.VisitNum).Select(x => x.Id).FirstOrDefaultAsync(); // 找到访视任务Id var LastVisitTaskId = await _visitTaskRepository.Where(x => x.ReadingCategory == ReadingCategory.Visit && x.TaskState == TaskState.Effect && !x.IsAnalysisCreate && x.SourceSubjectVisitId == lastVisitId).Select(x => x.Id).FirstOrDefaultAsync(); return LastVisitTaskId; } #endregion } }