diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 247fd7379..461c2f746 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -3946,6 +3946,12 @@ + + + 导入OCT-FCT数据 + + + 获取OCT-脂质角度模板 @@ -3953,6 +3959,12 @@ + + + 导入OCT-脂质角度数据 + + + 自动计算 @@ -6517,6 +6529,26 @@ 外弹力膜面积- 管腔面积 + + + 斑块编号 + + + + + 第一次 + + + + + 第二次 + + + + + 第三次 + + 斑块编号 diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingCalculateViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingCalculateViewModel.cs index f580bda15..599bb8379 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingCalculateViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingCalculateViewModel.cs @@ -234,6 +234,34 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto } } + public class OCTFCTUploadData + { + /// + /// 斑块编号 + /// + public int PlaqueNum { get; set; } + + /// + /// 第一次 + /// + public int FirstData { get; set; } + + /// + /// 第二次 + /// + public int SecondData { get; set; } + + /// + /// 第三次 + /// + public int ThirdData { get; set; } + + public decimal Avg { get { + + return ( FirstData*1m + SecondData * 1m + ThirdData * 1m) / 3; + } } + } + public class OCTInfo { diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingCriterionService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingCriterionService.cs index 030ca5721..6fa5ab142 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingCriterionService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingCriterionService.cs @@ -665,19 +665,19 @@ namespace IRaCIS.Core.Application.Service.RC //needAddQuestionList.AddRange(readingQuestionTrialList); }); - // 标准的默认值 + // 标准的默认值 标准默认值 foreach (var criterion in needAddCriterionList) { switch (criterion.CriterionType) { case CriterionType.IVUS: - criterion.IsImageFilter = true; + criterion.IsImageFilter = false; criterion.IsReadingTaskViewInOrder = ReadingOrder.SubjectRandom; criterion.ImageDownloadEnum = ReadingImageDownload.Subejct; criterion.ImageUploadEnum = ReadingImageUpload.IRReadingSubejctEnable; break; case CriterionType.OCT: - criterion.IsImageFilter = true; + criterion.IsImageFilter = false; criterion.IsReadingPeriod = false; criterion.IsGlobalReading = false; criterion.IsReadingTaskViewInOrder = ReadingOrder.SubjectRandom; diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/OCTCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/OCTCalculateService.cs index 414e7cb28..ea7b703b4 100644 --- a/IRaCIS.Core.Application/Service/ReadingCalculate/OCTCalculateService.cs +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/OCTCalculateService.cs @@ -2,7 +2,9 @@ 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; @@ -18,6 +20,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate IRepository _readingTableAnswerRowInfoRepository, IRepository _readingQuestionTrialRepository, IRepository _organInfoRepository, + IHttpContextAccessor httpContext, IRepository _readingGlobalTaskInfoRepository, IRepository _subjectVisitRepository, IRepository _tumorAssessmentRepository, @@ -456,6 +459,159 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate }); } + /// + /// 导入OCT-FCT数据 + /// + /// + [HttpPost] + public async Task UploadOCTFCTTemplate() + { + var request = httpContext.HttpContext!.Request; + var file = request.Form.Files[0]; + Guid visitTaskId = Guid.Parse(request.Form["VisitTaskId"]); + var dataTable = await _generalCalculateService.GetDataTableFromUpload(file); + + var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Include(x => x.Subject).Include(x => x.TrialReadingCriterion).FirstNotNullAsync(); + + var values = new + { + 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 measuredValueList = new List(); + + try + { + for (int i = 3; i < dataTable.Rows.Count; i++) + { + measuredValueList.Add(new OCTFCTUploadData() + { + PlaqueNum = int.Parse(dataTable.Rows[i]["A"].ToString()), + FirstData = int.Parse(dataTable.Rows[i]["B"].ToString()), + SecondData = int.Parse(dataTable.Rows[i]["C"].ToString()), + ThirdData = int.Parse(dataTable.Rows[i]["D"].ToString()), + }); + } + } + catch (Exception) + { + throw new BusinessValidationFailedException(_localizer["IVUS_UplpadDataError"]); + } + + var questionInfo = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId && x.LesionType == LesionType.FCT).FirstNotNullAsync(); + var tableQuestionList = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == questionInfo.Id).ToListAsync(); + List tableAnsweRowInfos = new List(); + List tableAnswers = new List(); + + var maxnum = 0; + + + 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 avg = item.Avg.ToString(); + + + if (taskinfo.TrialReadingCriterion.DigitPlaces != -1) + { + var digitPlaces = taskinfo.TrialReadingCriterion.DigitPlaces ?? 0; + avg = decimal.Round(decimal.Parse(avg ?? "0"), digitPlaces).ToString("F" + digitPlaces.ToString()); + + } + + // 第一次 + tableAnswers.Add(new ReadingTableQuestionAnswer() + { + Answer = item.FirstData.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.FirstFCT).Select(x => x.Id).FirstOrDefault(), + }); + + tableAnswers.Add(new ReadingTableQuestionAnswer() + { + Answer = item.SecondData.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.SecondFCT).Select(x => x.Id).FirstOrDefault(), + }); + + tableAnswers.Add(new ReadingTableQuestionAnswer() + { + Answer = item.ThirdData.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.ThirdFCT).Select(x => x.Id).FirstOrDefault(), + }); + + tableAnswers.Add(new ReadingTableQuestionAnswer() + { + Answer = avg, + QuestionId = questionInfo.Id, + TrialId = taskinfo.TrialId, + VisitTaskId = taskinfo.Id, + RowId = newRowId, + RowIndex = maxnum, + TableQuestionId = tableQuestionList.Where(x => x.ReadingQuestionId == questionInfo.Id && x.QuestionMark == QuestionMark.AvgFCT).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, + }); + } + /// /// 获取OCT-脂质角度模板 /// @@ -478,6 +634,125 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate }); } + /// + /// 导入OCT-脂质角度数据 + /// + /// + [HttpPost] + public async Task UploadOCTLipidAngleTemplate() + { + var request = httpContext.HttpContext!.Request; + var file = request.Form.Files[0]; + Guid visitTaskId = Guid.Parse(request.Form["VisitTaskId"]); + var dataTable = await _generalCalculateService.GetDataTableFromUpload(file); + + var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Include(x => x.Subject).Include(x => x.TrialReadingCriterion).FirstNotNullAsync(); + + var values = new + { + 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 measuredValueList = new List(); + + try + { + for (int i = 3; i < dataTable.Rows.Count; i++) + { + measuredValueList.Add(new OCTFCTUploadData() + { + PlaqueNum = int.Parse(dataTable.Rows[i]["A"].ToString()), + FirstData = int.Parse(dataTable.Rows[i]["B"].ToString()), + + }); + } + } + catch (Exception) + { + throw new BusinessValidationFailedException(_localizer["IVUS_UplpadDataError"]); + } + + var questionInfo = await _readingQuestionTrialRepository.Where(x => x.ReadingQuestionCriterionTrialId == taskinfo.TrialReadingCriterionId && x.LesionType == LesionType.LipidAngle).FirstNotNullAsync(); + var tableQuestionList = await _readingTableQuestionTrialRepository.Where(x => x.ReadingQuestionId == questionInfo.Id).ToListAsync(); + List tableAnsweRowInfos = new List(); + List tableAnswers = new List(); + + var maxnum = 0; + + + 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 avg = item.Avg.ToString(); + + + if (taskinfo.TrialReadingCriterion.DigitPlaces != -1) + { + var digitPlaces = taskinfo.TrialReadingCriterion.DigitPlaces ?? 0; + avg = decimal.Round(decimal.Parse(avg ?? "0"), digitPlaces).ToString("F" + digitPlaces.ToString()); + + } + + // 脂质角度 + tableAnswers.Add(new ReadingTableQuestionAnswer() + { + Answer = item.FirstData.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.LipidAngle).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, + }); + } + /// /// 自动计算 @@ -702,7 +977,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate // 匹配动脉段最小FCT tableAnswers.Add(new ReadingTableQuestionAnswer() { - Answer = GetDigitPlacesData(oCTFCTInfos.Where(x => x.PlaqueNum == item).MinOrDefault(x => x.Data).ToString()), + Answer = oCTFCTInfos.Count()==0? "0.00" : GetDigitPlacesData(oCTFCTInfos.Where(x => x.PlaqueNum == item).MinOrDefault(x => x.Data).ToString()), Id = NewId.NextGuid(), QuestionId = patchDataStatisticsInfo.Id, TrialId = inDto.TrialId, @@ -715,7 +990,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate // 平均最小FCT tableAnswers.Add(new ReadingTableQuestionAnswer() { - Answer = GetDigitPlacesData(oCTFCTInfos.Where(x => x.PlaqueNum == item).Average(x => x.Data).ToString()), + Answer = oCTFCTInfos.Count() == 0 ? "0.00" : GetDigitPlacesData(oCTFCTInfos.Where(x => x.PlaqueNum == item).Average(x => x.Data).ToString()), Id = NewId.NextGuid(), QuestionId = patchDataStatisticsInfo.Id, TrialId = inDto.TrialId, @@ -728,7 +1003,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate // 脂质角度平均值 tableAnswers.Add(new ReadingTableQuestionAnswer() { - Answer = GetDigitPlacesData(lipidAngleInfos.Where(x => x.PlaqueNum == item).Average(x => x.Data).ToString()), + Answer = lipidAngleInfos.Count() == 0 ? "0.00" : GetDigitPlacesData(lipidAngleInfos.Where(x => x.PlaqueNum == item).Average(x => x.Data).ToString()), Id = NewId.NextGuid(), QuestionId = patchDataStatisticsInfo.Id, TrialId = inDto.TrialId, @@ -741,7 +1016,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate // 脂质角度最大值 tableAnswers.Add(new ReadingTableQuestionAnswer() { - Answer = GetDigitPlacesData(lipidAngleInfos.Where(x => x.PlaqueNum == item).MaxOrDefault(x => x.Data).ToString()), + Answer = lipidAngleInfos.Count() == 0 ? "0.00" : GetDigitPlacesData(lipidAngleInfos.Where(x => x.PlaqueNum == item).MaxOrDefault(x => x.Data).ToString()), Id = NewId.NextGuid(), QuestionId = patchDataStatisticsInfo.Id, TrialId = inDto.TrialId, @@ -751,6 +1026,19 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate TableQuestionId = patchDataTableQuestion.Where(x => x.QuestionMark == QuestionMark.MaxAvgLipidAngle).Select(x => x.Id).FirstOrDefault(), }); + // 待定指标 + tableAnswers.Add(new ReadingTableQuestionAnswer() + { + Answer = string.Empty, + Id = NewId.NextGuid(), + QuestionId = patchDataStatisticsInfo.Id, + TrialId = inDto.TrialId, + VisitTaskId = inDto.VisitTaskId, + RowId = newRowId, + RowIndex = item, + TableQuestionId = patchDataTableQuestion.Where(x => x.QuestionMark == QuestionMark.Undetermined).Select(x => x.Id).FirstOrDefault(), + }); + } await _readingTableAnswerRowInfoRepository.BatchDeleteNoTrackingAsync(x =>x.QuestionId== patchDataStatisticsInfo.Id && x.VisitTaskId == inDto.VisitTaskId); diff --git a/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs b/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs index e08575d27..d16a83dd6 100644 --- a/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs +++ b/IRaCIS.Core.Domain.Share/Reading/ReadEnum.cs @@ -2146,6 +2146,11 @@ public enum SUVChangeVSBaseline /// MaxAvgLipidAngle = 1020, + /// + /// 待定指标 + /// + Undetermined = 1021, + }