//--------------------------------------------------------------------
// 此代码由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;
using IRaCIS.Core.Infra.EFCore.Common;
using Microsoft.Extensions.Caching.Memory;
using IRaCIS.Core.Application.Service.Reading.Dto;
namespace IRaCIS.Core.Application.Service
{
///
/// 阅片计算
///
[ApiExplorerSettings(GroupName = "Reading")]
public class ReadingCalculateService : BaseService, IReadingCalculateService
{
private readonly IRepository _readingTableQuestionAnswerRepository;
private readonly IRepository _visitTaskRepository;
private readonly IRepository _readingQuestionCriterionTrialRepository;
private readonly IRepository _readingTableQuestionTrialRepository;
private readonly IRepository _readingQuestionTrialRepository;
private readonly IRepository _subjectVisitRepository;
private readonly IRepository _tumorAssessmentRepository;
private readonly IRepository _readingTaskQuestionAnswerRepository;
public ReadingCalculateService(
IRepository readingTableQuestionAnswerRepository,
IRepository visitTaskRepository,
IRepository readingQuestionCriterionTrialRepository,
IRepository readingTableQuestionTrialRepository,
IRepository readingQuestionTrialRepository,
IRepository subjectVisitRepository,
IRepository tumorAssessmentRepository,
IRepository readingTaskQuestionAnswerRepository
)
{
this._readingTableQuestionAnswerRepository = readingTableQuestionAnswerRepository;
this._visitTaskRepository = visitTaskRepository;
this._readingQuestionCriterionTrialRepository = readingQuestionCriterionTrialRepository;
this._readingTableQuestionTrialRepository = readingTableQuestionTrialRepository;
this._readingQuestionTrialRepository = readingQuestionTrialRepository;
this._subjectVisitRepository = subjectVisitRepository;
this._tumorAssessmentRepository = tumorAssessmentRepository;
this._readingTaskQuestionAnswerRepository = readingTaskQuestionAnswerRepository;
}
#region 临时对象 单个请求的生命周期 避免重复查询数据库
private List visitTaskAnswerList;
private decimal? sODData;
#endregion
///
/// 计算任务
///
///
///
[HttpPost]
public async Task CalculateTask(CalculateTaskInDto inDto)
{
ReadingCalculateDto readingData = await GetReadingCalculateDto(inDto.VisitTaskId);
readingData.IsChangeOtherTask = inDto.IsChangeOtherTask;
await ReadingCalculate(readingData);
}
///
/// 自动计算
///
///
///
public async Task ReadingCalculate(ReadingCalculateDto inDto)
{
// 找到所有访视任务的Id
var visitTaskIds = await _visitTaskRepository.Where(x => !x.IsAnalysisCreate && x.ReadingCategory == ReadingCategory.Visit &&
x.TaskState == TaskState.Effect && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.DoctorUserId == inDto.DoctorUserId).Select(x => x.Id).ToListAsync();
#region 计算 这里顺序非常重要 后面计算的值要依赖前面计算的结果
var needAddList = new List();
// 循环找要计算的值进行计算
foreach (var item in inDto.QuestionInfo.Where(x => x.QuestionType != null))
{
switch (item.QuestionType)
{
// 靶病灶径线之和(SOD)
case QuestionType.SOD:
needAddList.Add(new ReadingTaskQuestionAnswer()
{
Answer = (await GetSODData(inDto)).ToString(),
ReadingQuestionTrialId = item.QuestionId,
});
break;
// 非淋巴结靶病灶长径之和
case QuestionType.SumOfDiameter:
needAddList.Add(new ReadingTaskQuestionAnswer()
{
Answer = (await GetSumOfDiameter(inDto)).ToString(),
ReadingQuestionTrialId = item.QuestionId,
});
break;
// 与基线SOD相比变化量(mm)
case QuestionType.SODChange:
needAddList.Add(new ReadingTaskQuestionAnswer()
{
Answer = (await GetSODChange(inDto)).ToString(),
ReadingQuestionTrialId = item.QuestionId,
});
break;
// 与基线访视相比SOD变化百分比
case QuestionType.SODPercent:
needAddList.Add(new ReadingTaskQuestionAnswer()
{
Answer = (await GetSODPercent(inDto)).ToString(),
ReadingQuestionTrialId = item.QuestionId,
});
break;
// 与整个访视期间最低点相比增加的值(mm) 其他任务需要改
case QuestionType.LowestIncrease:
if (!inDto.IsChangeOtherTask)
{
needAddList.Add(new ReadingTaskQuestionAnswer()
{
Answer = (await GetLowestIncrease(inDto)).ToString(),
ReadingQuestionTrialId = item.QuestionId,
});
}
else
{
await ChangeAllLowestIncrease(new ChangeAllTaskDto()
{
calculateDto = inDto,
QuestionId = item.QuestionId,
});
}
break;
// 与整个访视期间最低点相比增加的百分比 其他任务需要改
case QuestionType.LowPercent:
if (!inDto.IsChangeOtherTask)
{
needAddList.Add(new ReadingTaskQuestionAnswer()
{
Answer = (await GetLowPercent(inDto)).ToString(),
ReadingQuestionTrialId = item.QuestionId,
});
}
else
{
await ChangeAllLowPercent(inDto, item.QuestionId);
}
break;
// 整个访视期间最低点访视名称 其他任务需要改
case QuestionType.LowVisit:
var answer = (await GetLowVisit(inDto)).ToString();
if (!inDto.IsChangeOtherTask)
{
needAddList.Add(new ReadingTaskQuestionAnswer()
{
Answer = answer,
ReadingQuestionTrialId = item.QuestionId,
});
}
else
{
if (inDto.IsChangeOtherTask)
{
await this.ChangeAllVisitTaskAnswer(visitTaskIds, item.QuestionId, answer);
}
}
break;
// 是否存在非淋巴结靶病灶
case QuestionType.IsLymphTarget:
needAddList.Add(new ReadingTaskQuestionAnswer()
{
Answer = await GetIsLymphTarget(inDto),
ReadingQuestionTrialId = item.QuestionId,
});
break;
// 是否存在淋巴结靶病灶且该病灶比上一访视短径增加5MM以上
case QuestionType.IsAddFive:
needAddList.Add(new ReadingTaskQuestionAnswer()
{
Answer = await GetIsAddFive(inDto),
ReadingQuestionTrialId = item.QuestionId,
});
break;
// 被评估为NE的单个靶病灶
case QuestionType.NETarget:
needAddList.Add(new ReadingTaskQuestionAnswer()
{
Answer = await GetNETarget(inDto),
ReadingQuestionTrialId = item.QuestionId,
});
break;
// 整体肿瘤评估
case QuestionType.Tumor:
needAddList.Add(new ReadingTaskQuestionAnswer()
{
Answer = await GetTumor(inDto),
ReadingQuestionTrialId = item.QuestionId,
});
break;
}
}
var questionIds = needAddList.Select(x => x.ReadingQuestionTrialId).ToList();
await _readingTaskQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => questionIds.Contains(x.ReadingQuestionTrialId) && x.VisitTaskId == inDto.VisitTaskId);
needAddList.ForEach(x =>
{
x.SubjectId = inDto.SubjectId;
x.ReadingQuestionCriterionTrialId = inDto.CriterionId;
x.VisitTaskId = inDto.VisitTaskId;
x.TrialId = inDto.TrialId;
x.SubjectId = inDto.SubjectId;
});
await _readingTaskQuestionAnswerRepository.AddRangeAsync(needAddList);
await _readingTaskQuestionAnswerRepository.SaveChangesAsync();
#endregion
}
///
/// 验证访视提交
///
///
///
public async Task VerifyVisitTaskQuestions(VerifyVisitTaskQuestionsInDto inDto)
{
await this.CalculateTask(new CalculateTaskInDto()
{
VisitTaskId = inDto.VisitTaskId,
IsChangeOtherTask = true
});
visitTaskAnswerList = null;
ReadingCalculateDto data = await GetReadingCalculateDto(inDto.VisitTaskId);
VerifyVisitTaskQuestionsOutDto result = new VerifyVisitTaskQuestionsOutDto() {
IsVerified=true,
ErrorMessage=string.Empty,
};
List types = new List() {
new VerifyVisitTaskDto (){ QuestionType=QuestionType.TargetLesion,Fun=this.GetTargetLesionEvaluate },
new VerifyVisitTaskDto (){ QuestionType=QuestionType.NoTargetLesion,Fun=this.GetNoTargetLesionEvaluate },
new VerifyVisitTaskDto (){ QuestionType=QuestionType.NewLesions,Fun=this.GetNewLesionEvaluate }
};
foreach (var type in types)
{
var question=data.QuestionInfo.Where(x => x.QuestionType == type.QuestionType).FirstOrDefault();
if (question != null)
{
var calculateAnswer = await type.Fun(data);
if (question.Answer != calculateAnswer)
{
result.IsVerified = false;
var msg = $"问题【{question.QuesionName}】的答案为【{question.Answer}】但是计算答案为【{calculateAnswer}】";
result.ErrorMessage += result.ErrorMessage == string.Empty ? msg : "," + msg;
}
}
}
return result;
}
///
/// 获取ReadingCalculateDto
///
///
///
public async Task GetReadingCalculateDto(Guid visitTaskId)
{
var visitTask = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync();
var criterionId = await _readingQuestionCriterionTrialRepository.Where(x => x.TrialId == visitTask.TrialId && x.IsConfirm).Select(x => x.Id).FirstOrDefaultAsync();
List questionInfos = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == criterionId).Select(x => new QuestionInfo()
{
LesionType = x.LesionType,
QuestionId = x.Id,
QuesionName=x.QuestionName,
QuestionType = x.QuestionType,
}).ToListAsync();
var questionAnswers = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId).Select(x => new
{
x.ReadingQuestionTrialId,
x.Answer
}).ToListAsync();
var tableQuestion = await _readingTableQuestionAnswerRepository.Where(x => x.VisitTaskId == visitTaskId).Include(x => x.ReadingTableQuestionTrial).Select(x => new TableQuestionInfo()
{
Answer = x.Answer,
QuestionMark = x.ReadingTableQuestionTrial.QuestionMark,
TableQuestionId = x.TableQuestionId,
QuestionId = x.QuestionId,
RowIndex = x.RowIndex,
}).ToListAsync();
foreach (var item in questionInfos)
{
item.Answer = questionAnswers.Where(y => y.ReadingQuestionTrialId == item.QuestionId).Select(x => x.Answer).FirstOrDefault() ?? string.Empty;
var thisItemTableQuestions = tableQuestion.Where(x => x.QuestionId == item.QuestionId).ToList();
item.TableRowInfoList = thisItemTableQuestions.GroupBy(x => new { x.RowIndex })
.Select(g => new TableRowInfo()
{
RowIndex = g.Key.RowIndex,
TableQuestionList = g.ToList()
}).ToList();
}
ReadingCalculateDto readingData = new ReadingCalculateDto()
{
SubjectId = visitTask.SubjectId,
VisitTaskId = visitTaskId,
SubjectVisitId = visitTask.SourceSubjectVisitId.Value,
QuestionInfo = questionInfos,
CriterionId = criterionId,
TrialId = visitTask.TrialId,
DoctorUserId = visitTask.DoctorUserId,
};
return readingData;
}
#region 获取SOD
///
/// 获取SOD
///
///
/// 靶病灶径线之和(SOD)
/// 非淋巴结的长径 和淋巴结的短径
///
///
public async Task GetSODData(ReadingCalculateDto inDto)
{
if (sODData != null)
{
return sODData.Value;
}
var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList();
decimal result = 0;
foreach (var item in tableQuestion)
{
if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && (x.Answer == "是"||x.Answer.ToLower()=="true".ToLower())))
{
// 淋巴结的短径
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 == "是" || x.Answer.ToLower() == "true".ToLower())))
{
// 非淋巴结的长径
result += item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.MajorAxis).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0();
}
}
sODData = result;
return sODData.Value;
}
#endregion
#region 非淋巴结靶病灶长径之和
///
/// 非淋巴结靶病灶长径之和
///
///
///
public async Task GetSumOfDiameter(ReadingCalculateDto inDto)
{
var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList();
decimal result = 0;
foreach (var item in tableQuestion)
{
if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && (x.Answer == "是" || x.Answer.ToLower() == "false".ToLower())))
{
// 非淋巴结的长径
result += item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.MajorAxis).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0();
}
}
return result;
}
#endregion
#region 与基线SOD相比变化量(mm)
///
/// 与基线SOD相比变化量(mm)
///
///
///
public async Task GetSODChange(ReadingCalculateDto inDto)
{
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- minSOD) * 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 == "是" || x.Answer.ToLower() == "true".ToLower())))
{
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).Include(x => x.ReadingTableQuestionTrial).ToListAsync();
var rowIndexs = lastQuestionAsnwer.Where(x=>x.ReadingTableQuestionTrial.QuestionMark==QuestionMark.IsLymph&& (x.Answer == "是" || x.Answer.ToLower() == "true".ToLower())).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 = 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)
{
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 修改与整个访视期间最低点相比增加的值(mm)
///
/// 修改与整个访视期间最低点相比增加的值(mm)
///
///
///
///
public async Task ChangeAllLowestIncrease(ChangeAllTaskDto inDto)
{
var visitTaskList = await GetVisitTaskAnswerList(inDto.calculateDto);
var lowSod = visitTaskList.Select(x => x.SOD).OrderBy(x => x).FirstOrDefault();
foreach (var item in visitTaskList)
{
await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => x.VisitTaskId == item.VisitTaskId && x.ReadingQuestionTrialId == inDto.QuestionId, x => new ReadingTaskQuestionAnswer()
{
Answer = (item.SOD - lowSod).ToString()
}) ;
}
}
#endregion
#region 修改整个访视期间最低点相比增加的百分比
///
/// 修改整个访视期间最低点相比增加的百分比
///
///
///
///
public async Task ChangeAllLowPercent(ReadingCalculateDto inDto, Guid questionId)
{
var visitTaskList = await GetVisitTaskAnswerList(inDto);
var lowSod = visitTaskList.Select(x => x.SOD).OrderBy(x => x).FirstOrDefault();
foreach (var item in visitTaskList)
{
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 == questionId, x => new ReadingTaskQuestionAnswer()
{
Answer = percent.ToString()
});
}
}
#endregion
#endregion
#region 通用方法
#region 修改所有访视任务的答案
///
/// 修改所有访视任务的答案
///
///
///
///
///
private async Task ChangeAllVisitTaskAnswer(List visitTaskGuids, Guid questionId, string answer)
{
await _readingTaskQuestionAnswerRepository.BatchUpdateNoTrackingAsync(x => visitTaskGuids.Contains(x.VisitTaskId) && x.ReadingQuestionTrialId == questionId, x => new ReadingTaskQuestionAnswer()
{
Answer = answer
});
}
#endregion
#region 获取基线SOD
///
/// 获取基线SOD
///
///
///
private async Task GetBaseLineSOD(ReadingCalculateDto inDto)
{
if (await _visitTaskRepository.AnyAsync(x => x.Id == inDto.VisitTaskId && x.SourceSubjectVisit.IsBaseLine&&!x.IsAnalysisCreate&&x.DoctorUserId==inDto.DoctorUserId))
{
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&&x.DoctorUserId==inDto.DoctorUserId)
.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
#region 获取访视任务信息
///
/// 获取访视任务信息
///
///
///
public async Task> GetVisitTaskAnswerList(ReadingCalculateDto inDto)
{
if (visitTaskAnswerList == null)
{
visitTaskAnswerList = 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 VisitTaskAnswerInfo
{
VisitTaskId = x.VisitTaskId,
QuestionId = x.ReadingQuestionTrialId,
VisitName = x.VisitTask.SourceSubjectVisit.VisitName,
SOD = x.Answer.IsNullOrEmptyReturn0(),
}).ToListAsync();
}
return visitTaskAnswerList;
}
#endregion
///
/// 获取上一个访视任务Id
///
///
private async Task GetLastVisitTaskId(ReadingCalculateDto inDto)
{
// 拿到这一个访视
var thisNum = await _subjectVisitRepository.Where(x => x.Id == inDto.SubjectVisitId).Select(x => x.VisitNum).FirstOrDefaultAsync();
// 先找到上一个访视
var lastVisitId = await _subjectVisitRepository.Where(x => x.SubjectId == inDto.SubjectId && x.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&&x.DoctorUserId==inDto.DoctorUserId).Select(x => x.Id).FirstOrDefaultAsync();
return LastVisitTaskId;
}
#endregion
#region 计算阅片问题 外层问题
#region 获取靶病灶评估
///
/// 获取靶病灶评估
///
///
///
public async Task GetTargetLesionEvaluate(ReadingCalculateDto inDto)
{
var tableQuestion = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.TableRowInfoList).ToList();
TargetLesionCalculateDto resultData = new TargetLesionCalculateDto()
{
//非淋巴结靶病灶长径之和 decimal
SumOfDiameter = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SumOfDiameter).Sum(x => x.Answer.IsNullOrEmptyReturn0()),
//所有淋巴结靶病灶的短径小于10mm bool
DiameterLessThan10 = true,
// SOD 百分比与基线期SOD相比减小≥30% bool
SODPercentBigger30 = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SODPercent).Sum(x => x.Answer.IsNullOrEmptyReturn0()) >= (decimal)0.3,
// SOD 百分比 与基线期SOD相比减小<30% bool
SODPercentLess30 = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.SODPercent).Sum(x => x.Answer.IsNullOrEmptyReturn0()) < (decimal)0.3,
// SOD 百分比 整体访视期间最低点SOD相比增加<20%
LowPercentLess20 = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LowPercent).Sum(x => x.Answer.IsNullOrEmptyReturn0()) < (decimal)0.2,
// SOD 百分比 比整体访视期间最低点SOD增加≥20%
LowPercentBigger20 = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LowPercent).Sum(x => x.Answer.IsNullOrEmptyReturn0()) >= (decimal)0.2,
// SOD 变化值 比整体访视期间最低点SOD绝对增加值<5 mm
LowChangeLess5 = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.LowestIncrease).Sum(x => x.Answer.IsNullOrEmptyReturn0()) < 5,
// 比整体访视期间最低点SOD绝对增加值≥5 mm
LowChangeBigger5 = 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 == "不可评估"),
//// 上次访视点整体肿瘤评估
LastTargetLesionEvaluate = string.Empty,
// 当前访视点非淋巴结病灶长径>0
CurrentMajoreBigger0 = true,
// 至少一个淋巴结靶病灶短径≥10 mm
CurrenShortBigger10 = true,
// 该淋巴结靶病灶短径绝对增加值≥5 mm
IsAddFive = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.IsAddFive && x.Answer == "是").Count() > 0,
};
foreach (var item in tableQuestion)
{
if (item.TableQuestionList.Any(x => x.QuestionMark == QuestionMark.IsLymph && (x.Answer == "是" || x.Answer.ToLower() == "true".ToLower())))
{
// 淋巴结的短径
resultData.DiameterLessThan10 = (item.TableQuestionList.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Answer).FirstOrDefault()).IsNullOrEmptyReturn0() < 10;
// 至少一个淋巴结靶病灶短径≥10 mm
resultData.CurrenShortBigger10 = (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 == "否" || x.Answer.ToLower() == "false".ToLower())))
{
// 当前访视点非淋巴结病灶
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;
string result = string.Empty;
if (resultData.SumOfDiameter == 0 && resultData.DiameterLessThan10 && !resultData.ExixtsNETargetLesion)
{
result = "CR";
}
else if (
(resultData.SODPercentBigger30 && resultData.LowPercentLess20 && !resultData.ExixtsNETargetLesion)
||
(resultData.SODPercentBigger30 && resultData.LowChangeLess5 && !resultData.ExixtsNETargetLesion)
)
{
result = "PR";
}
else if (
(resultData.SODPercentLess30 && resultData.LowPercentLess20 && !resultData.ExixtsNETargetLesion)
||
(resultData.SODPercentLess30 && resultData.LowChangeLess5 && !resultData.ExixtsNETargetLesion)
)
{
result = "SD";
}
else if (resultData.LowPercentBigger20 && resultData.LowChangeBigger5)
{
result = "PD";
}
else if (
(resultData.LowPercentLess20 && resultData.ExixtsNETargetLesion)
||
(resultData.LowPercentBigger20 && resultData.LowChangeLess5 && resultData.ExixtsNETargetLesion)
)
{
result = "NE";
}
else if (!resultData.ExixtsNETargetLesion)
{
result = "ND";
}
else if (
(resultData.LastTargetLesionEvaluate == "CR" && resultData.CurrenShortBigger10 && resultData.IsAddFive)
||
(resultData.LastTargetLesionEvaluate == "CR" && resultData.CurrentMajoreBigger0)
)
{
result = "PD";
}
return result;
}
#endregion
#region 获取非靶病灶评估
///
/// 获取非靶病灶评估
///
///
///
public async Task GetNoTargetLesionEvaluate(ReadingCalculateDto inDto)
{
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 == "显著增大"))
{
return "PD";
}
//所有单个病灶/病灶组状态评估状态为“消失”
else if (!tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer != "消失"))
{
return "PD";
}
// 任意单个病灶/病灶组评估为“无法评估”并且没有“显著增大”
else if (tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer == "无法评估") &&
!tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer != "显著增大")
)
{
return "NE";
}
// 基线时没有非靶病灶
else if (tableQuestions.Count() == 0)
{
return "ND";
}
// 所有单个病灶/病灶组评估为”存在”或者有些评估为“消失”有些评估为“存在”,且没有“显著增大”和“无法评估”的病灶
else if (!tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer != "存在")
|| (tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer == "存在" || x.Answer == "消失") && !tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && (x.Answer != "显著增大" || x.Answer != "无法评估")))
)
{
return "NN";
}
else
{
return string.Empty;
}
}
#endregion
#region 获取新病灶评估
///
/// 获取新病灶评估
///
///
///
public async Task GetNewLesionEvaluate(ReadingCalculateDto inDto)
{
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 == "明确"))
{
return "是";
}
//当前访视不存在明确新病灶且存在至少一个疑似新病灶
else if (!tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer != "明确") ||
tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer == "疑似")
)
{
return "疑似";
}
//只要有任何一个新病灶状态为“无法评估”
else if (tableQuestions.Any(x => x.QuestionMark == QuestionMark.State && x.Answer == "无法评估"))
{
return "NE";
}
else
{
return "否";
}
}
#endregion
#endregion
}
}