irc-netcore-api/IRaCIS.Core.Application/Service/ReadingCalculate/IVUSCalculateService.cs

1105 lines
49 KiB
C#
Raw Blame History

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden 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 DocumentFormat.OpenXml.EMMA;
using DocumentFormat.OpenXml.Presentation;
using IRaCIS.Core.Application.Service.Reading.Dto;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure;
using MassTransit;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using MiniExcelLibs;
namespace IRaCIS.Core.Application.Service.ReadingCalculate
{
[ApiExplorerSettings(GroupName = "Reading")]
public class IVUSCalculateService(
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,
IVisitTaskHelpeService _visitTaskHelpeService,
IHttpContextAccessor httpContext,
ILogger<IRECIST1Point1CalculateService> _logger) : BaseService, ICriterionCalculateService
{
/// <summary>
/// 获取阅片的计算数据
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<object> GetReadingCalculationData(GetReadingCalculationDataInDto inDto)
{
return new
{
};
}
#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
//public async Task<FileResult> GetMeasuredValueTemplate(GetMeasuredValueTemplateInDto inDto)
//{
//}
#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);
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;
readingData.ComputationTrigger = inDto.ComputationTrigger;
await ReadingCalculate(readingData);
}
/// <summary>
/// 获取报告验证的信息(这里每个标准可能不一样 返回用object)
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<GetReportVerifyOutDto> GetReportVerify(GetReportVerifyInDto inDto)
{
return new GetReportVerifyOutDto()
{
TumorEvaluate = string.Empty,
IsExistDisease = string.Empty,
};
}
/// <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<ReadingTaskQuestionAnswer>();
// 计算斑块数据统计和PVA数据
await this.CalculatePatchDataStatisticsAndPVA(inDto);
inDto = await _generalCalculateService.GetReadingCalculateDto(inDto.VisitTaskId);
List<ReadingCalculateData> calculateList = new List<ReadingCalculateData>()
{
// 斑块1-PAV
new ReadingCalculateData (){QuestionType=QuestionType.Plaque1PVA,GetDecimalNullFun=GetPlaque1PVA},
// 斑块2-PAV
new ReadingCalculateData (){QuestionType=QuestionType.Plaque2PVA,GetDecimalNullFun=GetPlaque2PVA},
// 斑块3-PAV
new ReadingCalculateData (){QuestionType=QuestionType.Plaque3PVA,GetDecimalNullFun=GetPlaque3PVA},
};
if (calculateType != null)
{
calculateList = calculateList.Where(x => calculateType.Contains(x.QuestionType)).ToList();
}
foreach (var calculate in calculateList)
{
var item = inDto.QuestionInfo.FirstOrDefault(x => x.QuestionType == calculate.QuestionType);
if (item != null)
{
//计算答案
#region 计算答案
if (calculate.GetDecimalFun != null)
{
item.Answer = (await calculate.GetDecimalFun(inDto)).ToString();
}
else if (calculate.GetDecimalNullFun != null)
{
var value = await calculate.GetDecimalNullFun(inDto);
item.Answer = value == null ? "NA" : 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, MidpointRounding.AwayFromZero).ToString("F" + inDto.DigitPlaces.ToString());
}
}
catch (Exception)
{
}
}
needAddList.Add(new ReadingTaskQuestionAnswer()
{
Answer = item.Answer,
ReadingQuestionTrialId = item.QuestionId,
});
}
}
var questionIds = needAddList.Select(x => x.ReadingQuestionTrialId).ToList();
await _readingTaskQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => questionIds.Contains(x.ReadingQuestionTrialId) && x.VisitTaskId == inDto.VisitTaskId);
needAddList.ForEach(x =>
{
x.SubjectId = inDto.SubjectId;
x.ReadingQuestionCriterionTrialId = inDto.CriterionId;
x.VisitTaskId = inDto.VisitTaskId;
x.TrialId = inDto.TrialId;
x.SubjectId = inDto.SubjectId;
});
await _readingTaskQuestionAnswerRepository.AddRangeAsync(needAddList);
await _readingTaskQuestionAnswerRepository.SaveChangesAsync();
#endregion
}
/// <summary>
/// 获取IVUS模板
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<FileResult> GetIVUSTemplate(GetExportTemplateInDto inDto)
{
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x=>x.Subject).FirstNotNullAsync();
var values = new TemplateData()
{
SubjectID = (taskinfo.BlindSubjectCode.IsNullOrEmpty() ? taskinfo.Subject.Code : taskinfo.BlindSubjectCode),
TaskBlindName = taskinfo.TaskBlindName,
};
return await _visitTaskHelpeService.ExportTemplateAsync(new IRaCIS.Application.Contracts.ExportTemplateAsyncDto()
{
ExportFileName= "IVUS_Template",
TemplateCode= StaticData.Export.IVUSTheMeasuredValueOfEachMatchedFragment,
Data= values
});
}
/// <summary>
/// 导入IVUS数据
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task UploadIVUSTemplate()
{
var request = httpContext.HttpContext!.Request;
var file = request.Form.Files[0];
Guid visitTaskId = Guid.Parse(request.Form["VisitTaskId"]);
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Include(x => x.Subject).Include(x => x.TrialReadingCriterion).FirstNotNullAsync();
var uploadInfo =await _generalCalculateService.GetDataTableFromUpload(file, "IVUSTemplate", taskinfo.TrialId);
List<string> sheetNames = new List<string>()
{
"各匹配片段测量值","MeasuredValue"
};
if (sheetNames.Intersect(uploadInfo.SheetNames).Count() == 0)
{
throw new BusinessValidationFailedException(_localizer["IVUS_UplpadDataError"]);
}
var dataTable = uploadInfo.DataTable;
var values = new TemplateData()
{
SubjectID = taskinfo.BlindSubjectCode.IsNullOrEmpty() ? taskinfo.Subject.Code : taskinfo.BlindSubjectCode,
TaskBlindName = taskinfo.TaskBlindName,
};
if (values.SubjectID != dataTable.Rows[0]["B"].ToString() || values.TaskBlindName != dataTable.Rows[1]["B"].ToString())
{
throw new BusinessValidationFailedException(_localizer["IVUS_UploadVisitTaskError"]);
}
List<IVUSMeasuredValue> measuredValueList = new List<IVUSMeasuredValue>();
for (int i = 3; i < dataTable.Rows.Count; i++)
{
IVUSMeasuredValue iVUSMeasuredValue = new IVUSMeasuredValue() { };
try
{
iVUSMeasuredValue = new IVUSMeasuredValue()
{
PlaqueNum = int.Parse(dataTable.Rows[i]["A"].ToString()),
Emm = decimal.Parse(dataTable.Rows[i]["B"].ToString()),
Lumen = decimal.Parse(dataTable.Rows[i]["C"].ToString()),
};
}
catch (Exception)
{
throw new BusinessValidationFailedException(_localizer["IVUS_UplpadDataError"]);
}
if (iVUSMeasuredValue.Emm <= iVUSMeasuredValue.Lumen)
{
throw new BusinessValidationFailedException(_localizer["IVUS_EmmBiggerThenLumen"]);
}
measuredValueList.Add(iVUSMeasuredValue);
}
measuredValueList = measuredValueList.OrderBy(x => x.PlaqueNum).ToList();
var questionInfo = await _readingQuestionTrialRepository.Where(x =>x.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId&& x.LesionType == LesionType.MatchValues).FirstNotNullAsync();
var tableQuestionList = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == questionInfo.Id).ToListAsync();
List<ReadingTableAnswerRowInfo> tableAnsweRowInfos = new List<ReadingTableAnswerRowInfo>();
List<ReadingTableQuestionAnswer> tableAnswers = new List<ReadingTableQuestionAnswer>();
var maxnum = _readingTableAnswerRowInfoRepository.Where(x => x.QuestionId == questionInfo.Id && x.VisitTaskId == taskinfo.Id).MaxOrDefault(x => x.RowIndex);
foreach (var item in measuredValueList)
{
maxnum = maxnum + 1;
var newRowId = NewId.NextGuid();
// 斑块数据统计
tableAnsweRowInfos.Add(new ReadingTableAnswerRowInfo()
{
Id = newRowId,
QuestionId = questionInfo.Id,
VisitTaskId = taskinfo.Id,
TrialId = taskinfo.TrialId,
RowIndex = maxnum,
IsCurrentTaskAdd = true,
BlindName = taskinfo.TaskBlindName,
OrderMark = questionInfo.OrderMark,
FristAddTaskNum = taskinfo.VisitTaskNum,
FristAddTaskId = taskinfo.Id,
RowMark = questionInfo.OrderMark + decimal.Parse(maxnum.ToString()).GetLesionMark()
});
// 编号
tableAnswers.Add(new ReadingTableQuestionAnswer()
{
Answer = item.PlaqueNum.ToString(),
QuestionId = questionInfo.Id,
TrialId = taskinfo.TrialId,
VisitTaskId = taskinfo.Id,
RowId = newRowId,
RowIndex = maxnum,
TableQuestionId = tableQuestionList.Where(x => x.ReadingQuestionId == questionInfo.Id && x.QuestionMark == QuestionMark.PlaqueNumber).Select(x => x.Id).FirstOrDefault(),
});
var emm = item.Emm.ToString();
var lumen=item.Lumen.ToString();
var emmSubtractionLumen = item.EmmSubtractionLumen.ToString();
if (taskinfo.TrialReadingCriterion.DigitPlaces != -1)
{
var digitPlaces= taskinfo.TrialReadingCriterion.DigitPlaces??0;
emm = decimal.Round(decimal.Parse(emm ?? "0"), digitPlaces, MidpointRounding.AwayFromZero).ToString("F" + digitPlaces.ToString());
lumen = decimal.Round(decimal.Parse(lumen ?? "0"), digitPlaces, MidpointRounding.AwayFromZero).ToString("F" + digitPlaces.ToString());
emmSubtractionLumen = decimal.Round(decimal.Parse(emmSubtractionLumen ?? "0"), digitPlaces, MidpointRounding.AwayFromZero).ToString("F" + digitPlaces.ToString());
}
// EMM
tableAnswers.Add(new ReadingTableQuestionAnswer()
{
Answer = emm,
QuestionId = questionInfo.Id,
TrialId = taskinfo.TrialId,
VisitTaskId = taskinfo.Id,
RowId = newRowId,
RowIndex = maxnum,
TableQuestionId = tableQuestionList.Where(x => x.ReadingQuestionId == questionInfo.Id && x.QuestionMark == QuestionMark.ElasticArea).Select(x => x.Id).FirstOrDefault(),
});
tableAnswers.Add(new ReadingTableQuestionAnswer()
{
Answer = lumen,
QuestionId = questionInfo.Id,
TrialId = taskinfo.TrialId,
VisitTaskId = taskinfo.Id,
RowId = newRowId,
RowIndex = maxnum,
TableQuestionId = tableQuestionList.Where(x => x.ReadingQuestionId == questionInfo.Id && x.QuestionMark == QuestionMark.LumenArea).Select(x => x.Id).FirstOrDefault(),
});
tableAnswers.Add(new ReadingTableQuestionAnswer()
{
Answer = emmSubtractionLumen,
QuestionId = questionInfo.Id,
TrialId = taskinfo.TrialId,
VisitTaskId = taskinfo.Id,
RowId = newRowId,
RowIndex = maxnum,
TableQuestionId = tableQuestionList.Where(x => x.ReadingQuestionId == questionInfo.Id && x.QuestionMark == QuestionMark.ElasticAreaDiffValue).Select(x => x.Id).FirstOrDefault(),
});
}
await _readingTableAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x => x.QuestionId == questionInfo.Id && x.VisitTaskId == taskinfo.Id);
await _readingTableQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => x.QuestionId == questionInfo.Id && x.VisitTaskId == taskinfo.Id);
await _readingTableAnswerRowInfoRepository.AddRangeAsync(tableAnsweRowInfos);
await _readingTableQuestionAnswerRepository.AddRangeAsync(tableAnswers);
await _readingTableQuestionAnswerRepository.SaveChangesAsync();
await this.CalculateTask(new CalculateTaskInDto()
{
VisitTaskId = taskinfo.Id,
});
}
/// <summary>
/// 计算斑块数据统计和PVA数据
/// </summary>
/// <returns></returns>
public async Task CalculatePatchDataStatisticsAndPVA(ReadingCalculateDto inDto)
{
// 斑块的表格问题Id
var questionInfo = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.PatchDataStatistics).FirstOrDefault();
// pAV 问题信息
var pAVquestionInfo = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.PAV).FirstOrDefault();
// 测量值集合
var matchValuesAnswerList = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.MatchValues).SelectMany(x => x.TableRowInfoList).ToList();
// 获取编号
var nums = matchValuesAnswerList.SelectMany(x => x.TableQuestionList).Where(x => x.QuestionMark == QuestionMark.PlaqueNumber).Select(x => int.Parse(x.Answer)).Distinct().OrderBy(x => x).ToList();
// 斑块的表格问题集合
var tableQuestionList = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == questionInfo.QuestionId).ToListAsync();
// pAV表格问题
var pAvTableQuestionList = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == pAVquestionInfo.QuestionId).ToListAsync();
List <ReadingTableAnswerRowInfo> tableAnsweRowInfos = new List<ReadingTableAnswerRowInfo>();
List<ReadingTableQuestionAnswer> tableAnswers = new List<ReadingTableQuestionAnswer>();
foreach (var item in nums)
{
var newRowId = NewId.NextGuid();
var thisnumTableRows = inDto.QuestionInfo.Where(x => x.LesionType == LesionType.MatchValues).SelectMany(x => x.TableRowInfoList).Where(x => x.TableQuestionList.Any(y => y.QuestionMark == QuestionMark.PlaqueNumber && y.Answer == item.ToString())).ToList();
// 斑块数据统计
tableAnsweRowInfos.Add(new ReadingTableAnswerRowInfo()
{
Id = newRowId,
QuestionId = questionInfo!.QuestionId,
VisitTaskId = inDto.VisitTaskId,
TrialId = inDto.TrialId,
RowIndex = item,
IsCurrentTaskAdd = true,
BlindName = inDto.BlindName,
OrderMark = questionInfo.OrderMark,
FristAddTaskNum = inDto.VisitTaskNum,
FristAddTaskId = inDto.VisitTaskId,
RowMark = questionInfo.OrderMark + decimal.Parse(item.ToString()).GetLesionMark()
});
// 斑块
tableAnswers.Add(new ReadingTableQuestionAnswer()
{
Answer = item.ToString(),
Id = NewId.NextGuid(),
QuestionId = questionInfo!.QuestionId,
TrialId = inDto.TrialId,
VisitTaskId = inDto.VisitTaskId,
RowId = newRowId,
RowIndex = item,
TableQuestionId = tableQuestionList.Where(x => x.QuestionMark == QuestionMark.PlaqueNumber).Select(x => x.Id).FirstOrDefault(),
});
#region 数据计算
var emm = thisnumTableRows.SelectMany(x => x.TableQuestionList)
.Where(x => x.QuestionMark == QuestionMark.ElasticArea).Select(x => x.Answer.IsNullOrEmptyReturn0()).Sum().ToString();
var EEMLumen = thisnumTableRows.SelectMany(x => x.TableQuestionList)
.Where(x => x.QuestionMark == QuestionMark.ElasticAreaDiffValue).Select(x => x.Answer.IsNullOrEmptyReturn0()).Sum().ToString();
var pav = "";
if (emm != null && EEMLumen != null)
{
var emmNum =decimal.Parse(emm ?? "0");
var EEMLumenNum =decimal.Parse(EEMLumen ?? "0");
if (emmNum != 0)
{
pav = (EEMLumenNum * 100 / emmNum).ToString();
}
}
if (inDto.DigitPlaces != -1)
{
emm = decimal.Round(decimal.Parse(emm ?? "0"), inDto.DigitPlaces, MidpointRounding.AwayFromZero).ToString("F" + inDto.DigitPlaces.ToString());
EEMLumen = decimal.Round(decimal.Parse(EEMLumen ?? "0"), inDto.DigitPlaces, MidpointRounding.AwayFromZero).ToString("F" + inDto.DigitPlaces.ToString());
pav = decimal.Round(decimal.Parse(pav ?? "0"), inDto.DigitPlaces, MidpointRounding.AwayFromZero).ToString("F" + inDto.DigitPlaces.ToString());
}
#endregion
#region 冠状动脉粥样硬化体积百分比PAV
var newPAVRowId = NewId.NextGuid();
// 斑块数据统计
tableAnsweRowInfos.Add(new ReadingTableAnswerRowInfo()
{
Id = newPAVRowId,
QuestionId = pAVquestionInfo!.QuestionId,
VisitTaskId = inDto.VisitTaskId,
TrialId = inDto.TrialId,
RowIndex = item,
IsCurrentTaskAdd = true,
BlindName = inDto.BlindName,
OrderMark = pAVquestionInfo.OrderMark,
FristAddTaskNum = inDto.VisitTaskNum,
FristAddTaskId = inDto.VisitTaskId,
RowMark = pAVquestionInfo.OrderMark + decimal.Parse(item.ToString()).GetLesionMark()
});
// 斑块
tableAnswers.Add(new ReadingTableQuestionAnswer()
{
Answer = item.ToString(),
Id = NewId.NextGuid(),
QuestionId = pAVquestionInfo!.QuestionId,
TrialId = inDto.TrialId,
VisitTaskId = inDto.VisitTaskId,
RowId = newPAVRowId,
RowIndex = item,
TableQuestionId = pAvTableQuestionList.Where(x => x.QuestionMark == QuestionMark.PlaqueNumber).Select(x => x.Id).FirstOrDefault(),
});
// PAV
tableAnswers.Add(new ReadingTableQuestionAnswer()
{
Answer = pav,
Id = NewId.NextGuid(),
QuestionId = pAVquestionInfo!.QuestionId,
TrialId = inDto.TrialId,
VisitTaskId = inDto.VisitTaskId,
RowId = newPAVRowId,
RowIndex = item,
TableQuestionId = pAvTableQuestionList.Where(x => x.QuestionMark == QuestionMark.PAV).Select(x => x.Id).FirstOrDefault(),
});
#endregion
// EMM 求和
tableAnswers.Add(new ReadingTableQuestionAnswer()
{
Answer = emm,
QuestionId = questionInfo!.QuestionId,
TrialId = inDto.TrialId,
VisitTaskId = inDto.VisitTaskId,
RowId = newRowId,
RowIndex = item,
TableQuestionId = tableQuestionList.Where(x => x.QuestionMark == QuestionMark.EEMSum).Select(x => x.Id).FirstOrDefault(),
});
// (EEM-Lumen)求和
tableAnswers.Add(new ReadingTableQuestionAnswer()
{
Answer = EEMLumen,
Id = NewId.NextGuid(),
QuestionId = questionInfo!.QuestionId,
TrialId = inDto.TrialId,
VisitTaskId = inDto.VisitTaskId,
RowId = newRowId,
RowIndex = item,
TableQuestionId = tableQuestionList.Where(x => x.QuestionMark == QuestionMark.EEMSubtractLumenSum).Select(x => x.Id).FirstOrDefault(),
});
}
await _readingTableAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x => (x.QuestionId == questionInfo.QuestionId || x.QuestionId == pAVquestionInfo.QuestionId) && x.VisitTaskId == inDto.VisitTaskId);
await _readingTableQuestionAnswerRepository.BatchDeleteNoTrackingAsync(x => (x.QuestionId == questionInfo.QuestionId || x.QuestionId == pAVquestionInfo.QuestionId) && x.VisitTaskId == inDto.VisitTaskId);
await _readingTableAnswerRowInfoRepository.AddRangeAsync(tableAnsweRowInfos);
await _readingTableQuestionAnswerRepository.AddRangeAsync(tableAnswers);
await _readingTableQuestionAnswerRepository.SaveChangesAsync();
}
/// <summary>
/// 验证访视提交
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task VerifyVisitTaskQuestions(VerifyVisitTaskQuestionsInDto inDto)
{
}
/// <summary>
/// 获取斑块1-PAV
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<decimal?> GetPlaque1PVA(ReadingCalculateDto inDto)
{
return inDto.QuestionInfo.Where(x => x.LesionType == LesionType.PAV).SelectMany(x => x.TableRowInfoList).Where(x=>x.TableQuestionList.Any(y=>y.QuestionMark==QuestionMark.PlaqueNumber&&y.Answer.IsNullOrEmptyReturn0()==1)).SelectMany(x => x.TableQuestionList)
.Where(x => x.QuestionMark == QuestionMark.PAV).Select(x=>x.Answer).FirstIsNullReturnEmpty().IsNullOrEmptyReturnNull();
}
/// <summary>
/// 获取斑块2-PAV
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<decimal?> GetPlaque2PVA(ReadingCalculateDto inDto)
{
return inDto.QuestionInfo.Where(x => x.LesionType == LesionType.PAV).SelectMany(x => x.TableRowInfoList).Where(x => x.TableQuestionList.Any(y => y.QuestionMark == QuestionMark.PlaqueNumber && y.Answer.IsNullOrEmptyReturn0() == 2)).SelectMany(x => x.TableQuestionList)
.Where(x => x.QuestionMark == QuestionMark.PAV).Select(x => x.Answer).FirstIsNullReturnEmpty().IsNullOrEmptyReturnNull();
}
/// <summary>
/// 获取斑块3-PAV
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<decimal?> GetPlaque3PVA(ReadingCalculateDto inDto)
{
return inDto.QuestionInfo.Where(x => x.LesionType == LesionType.PAV).SelectMany(x => x.TableRowInfoList).Where(x => x.TableQuestionList.Any(y => y.QuestionMark == QuestionMark.PlaqueNumber && y.Answer.IsNullOrEmptyReturn0() == 3)).SelectMany(x => x.TableQuestionList)
.Where(x => x.QuestionMark == QuestionMark.PAV).Select(x => x.Answer).FirstIsNullReturnEmpty().IsNullOrEmptyReturnNull();
}
///// <summary>
///// 计算NTAV的EEM
///// </summary>
///// <param name="inDto"></param>
///// <returns></returns>
//public async Task<decimal?> GetEEM(ReadingCalculateDto inDto)
//{
// if (inDto.QuestionInfo.Where(x => x.LesionType == LesionType.MatchValues).SelectMany(x => x.TableRowInfoList).Count() == 0)
// {
// return null;
// }
// return inDto.QuestionInfo.Where(x => x.LesionType == LesionType.MatchValues).SelectMany(x => x.TableRowInfoList).SelectMany(x => x.TableQuestionList)
// .Where(x => x.QuestionMark == QuestionMark.ElasticArea).Select(x => x.Answer.IsNullOrEmptyReturn0()).Sum();
//}
///// <summary>
///// 获取(EEM-Lumen)求和
///// </summary>
///// <param name="inDto"></param>
///// <returns></returns>
//public async Task<decimal?> GetEEMLumenSum(ReadingCalculateDto inDto)
//{
// if (inDto.QuestionInfo.Where(x => x.LesionType == LesionType.MatchValues).SelectMany(x => x.TableRowInfoList).Count() == 0)
// {
// return null;
// }
// return inDto.QuestionInfo.Where(x => x.LesionType == LesionType.MatchValues).SelectMany(x => x.TableRowInfoList).SelectMany(x => x.TableQuestionList)
// .Where(x => x.QuestionMark == QuestionMark.ElasticAreaDiffValue).Select(x => x.Answer.IsNullOrEmptyReturn0()).Sum();
//}
///// <summary>
///// 计算NTAV的EEM-Lumen求和/回撤中的图像数
///// </summary>
///// <param name="inDto"></param>
///// <returns></returns>
//public async Task<decimal?> GetNTAVEEMLumenSumOrRetraceImageCount(ReadingCalculateDto inDto)
//{
// var eEMLumenSum = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.EEMLumenSum).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0();
// var retracedFramesNumber = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.RetracedFramesNumber).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0();
// if (eEMLumenSum == 0 || retracedFramesNumber == 0)
// {
// return null;
// }
// return eEMLumenSum / retracedFramesNumber;
//}
///// <summary>
///// 冠状动脉粥样硬化体积百分比PAV
///// </summary>
///// <remarks>
///// EEM-Lumen求和/EEM求和✖100单位%
///// </remarks>
///// <param name="inDto"></param>
///// <returns></returns>
//public async Task<decimal?> GetPAV(ReadingCalculateDto inDto)
//{
// var eEMLumenSum = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.EEMLumenSum).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0();
// var eEMSum = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.EEMSum).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0();
// if (eEMSum == 0)
// {
// return null;
// }
// else
// {
// return eEMLumenSum / eEMSum * 100;
// }
//}
///// <summary>
///// 总动脉粥样硬化体积NTAV
///// </summary>
///// <param name="inDto"></param>
///// <returns></returns>
//public async Task<decimal?> GetNTAV(ReadingCalculateDto inDto)
//{
// var result = await GetNTAVEEMLumenSumOrRetraceImageCount(inDto);
// var medianFrame = inDto.QuestionInfo.Where(x => x.QuestionType == QuestionType.MedianFrame).Select(x => x.Answer).FirstOrDefault().IsNullOrEmptyReturn0();
// if (result == null || medianFrame == 0)
// {
// return null;
// }
// else
// {
// return result.Value * medianFrame;
// }
//}
#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();
return new AddTaskLesionAnswerFromLastTaskOutDto()
{
IsBaseLine = taskinfo.SourceSubjectVisitId == baseLineVisitId,
};
}
#endregion
}
}