748 lines
29 KiB
C#
748 lines
29 KiB
C#
using DocumentFormat.OpenXml.Office.SpreadSheetML.Y2023.MsForms;
|
|
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 Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using MiniExcelLibs;
|
|
using Org.BouncyCastle.Asn1.X509;
|
|
using System.Data;
|
|
using System.IO;
|
|
|
|
namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
|
{
|
|
[ApiExplorerSettings(GroupName = "Image")]
|
|
public class ReadingCalculateService(IEnumerable<ICriterionCalculateService> _criterionServices,
|
|
IRepository<VisitTask> _visitTaskRepository,
|
|
IRepository<ReadingImportFile> _readingImportFileRepository,
|
|
IHttpContextAccessor httpContext,
|
|
IOSSService oSSService,
|
|
IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
|
|
IStringLocalizer _localizer, IUserInfo _userInfo
|
|
|
|
) : BaseService, IReadingCalculateService
|
|
{
|
|
private ICriterionCalculateService _useCriterion;
|
|
/// <summary>
|
|
/// 标准和服务对应
|
|
/// </summary>
|
|
Dictionary<CriterionType, Type> CalculateServiceDic = new Dictionary<CriterionType, Type>()
|
|
{
|
|
{CriterionType.RECIST1Point1,typeof(RECIST1Point1CalculateService) }, //RECIST1.1
|
|
{CriterionType.PCWG3,typeof(PCWG3CalculateService) },
|
|
{CriterionType.SelfDefine,typeof(SelfDefineCalculateService) },
|
|
{CriterionType.RECIST1Pointt1_MB,typeof(RECIST1Point1_BMCalculateService) },
|
|
{CriterionType.IRECIST1Point1,typeof(IRECIST1Point1CalculateService) },
|
|
{CriterionType.Lugano2014,typeof(LuganoCalculateService) },
|
|
{CriterionType.Lugano2014WithoutPET,typeof(LuganoWithoutPETCalculateService) },
|
|
{CriterionType.IVUS,typeof(IVUSCalculateService) },
|
|
{CriterionType.OCT,typeof(OCTCalculateService) },
|
|
{CriterionType.MRIPDFF,typeof(MRIPDFFCalculateService) },
|
|
{CriterionType.mRECISTHCC,typeof(MRECISTHCCCalculateService) },
|
|
};
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// 阅片导入
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public async Task ReadingImport()
|
|
{
|
|
var request = httpContext.HttpContext!.Request;
|
|
var file = request.Form.Files[0];
|
|
Guid visitTaskId = Guid.Parse(request.Form["VisitTaskId"]);
|
|
|
|
string tableName = request.Form["TableName"].ToString();
|
|
|
|
var service = await this.GetService(visitTaskId);
|
|
if (service != null)
|
|
{
|
|
var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).FirstNotNullAsync();
|
|
|
|
var streamCopy = new MemoryStream();
|
|
// 将上传的文件内容复制到 MemoryStream
|
|
await file.CopyToAsync(streamCopy);
|
|
// 重置流的位置,以便后续读取
|
|
streamCopy.Position = 0;
|
|
var ossRelativePath = await oSSService.UploadToOSSAsync(streamCopy, $"{visitTaskInfo.TrialId.ToString()}/InspectionUpload/ReadingImport", file.FileName);
|
|
|
|
|
|
await _readingImportFileRepository.AddAsync(new ReadingImportFile()
|
|
{
|
|
|
|
FilePath = ossRelativePath,
|
|
VisitTaskId = visitTaskId,
|
|
TrialId = visitTaskInfo.TrialId,
|
|
SubjectId = visitTaskInfo.SubjectId,
|
|
SubjectVisitId = visitTaskInfo.SourceSubjectVisitId,
|
|
TrialReadingCriterionId = visitTaskInfo.TrialReadingCriterionId,
|
|
TableName = tableName,
|
|
|
|
});
|
|
|
|
|
|
await service.ReadingImport();
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 获取Service
|
|
/// </summary>
|
|
/// <param name="visitTaskId"></param>
|
|
/// <returns></returns>
|
|
public async Task<ICriterionCalculateService> GetService(Guid visitTaskId)
|
|
{
|
|
if (_useCriterion == null)
|
|
{
|
|
var criterionId = await _visitTaskRepository.Where(x => x.Id == visitTaskId).Select(x => x.TrialReadingCriterionId).FirstNotNullAsync();
|
|
|
|
var criterionType = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == criterionId).Select(x => x.CriterionType).FirstOrDefaultAsync();
|
|
|
|
if (criterionType == null)
|
|
{
|
|
throw new BusinessValidationFailedException(_localizer["ReadingCalculate_NoDeveloped"]);
|
|
}
|
|
|
|
try
|
|
{
|
|
CriterionType thisCriterionType = criterionType;
|
|
Type thisServiceType = CalculateServiceDic[thisCriterionType];
|
|
_useCriterion = _criterionServices.FirstOrDefault(x => x.GetType().Name == thisServiceType.Name);
|
|
|
|
|
|
|
|
}
|
|
catch (Exception)
|
|
{
|
|
|
|
_useCriterion = null;
|
|
}
|
|
|
|
return _useCriterion;
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
return _useCriterion;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 自动计算 并修改值
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
public async Task CalculateTask(CalculateTaskInDto inDto)
|
|
{
|
|
|
|
_userInfo.IsNotNeedInspection = true;
|
|
var service = await this.GetService(inDto.VisitTaskId);
|
|
if (service != null)
|
|
{
|
|
await service.CalculateTask(inDto);
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 验证访视提交
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
public async Task VerifyVisitTaskQuestions(VerifyVisitTaskQuestionsInDto inDto)
|
|
{
|
|
var service = await this.GetService(inDto.VisitTaskId);
|
|
if (service != null)
|
|
{
|
|
await service.VerifyVisitTaskQuestions(inDto);
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取阅片的计算数据
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public async Task<object> GetReadingCalculationData(GetReadingCalculationDataInDto inDto)
|
|
{
|
|
var service = await this.GetService(inDto.VisitTaskId);
|
|
|
|
return await service.GetReadingCalculationData(inDto);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 将上一次的访视病灶添加到这一次
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
public async Task<AddTaskLesionAnswerFromLastTaskOutDto> AddTaskLesionAnswerFromLastTask(AddTaskLesionAnswerFromLastTaskInDto inDto)
|
|
{
|
|
var service = await this.GetService(inDto.VisitTaskId);
|
|
var visitTaskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
|
|
var result = new AddTaskLesionAnswerFromLastTaskOutDto();
|
|
var readingTaskState = visitTaskInfo.ReadingTaskState;
|
|
if (service != null && visitTaskInfo.SourceSubjectVisitId != null)
|
|
{
|
|
if (readingTaskState == ReadingTaskState.WaitReading)
|
|
{
|
|
if (visitTaskInfo.ReadingCategory == ReadingCategory.Visit)
|
|
{
|
|
result = await service.AddTaskLesionAnswerFromLastTask(inDto);
|
|
await service.CalculateTask(new CalculateTaskInDto()
|
|
{
|
|
IsChangeOtherTask = false,
|
|
VisitTaskId = inDto.VisitTaskId,
|
|
ComputationTrigger = ComputationTrigger.InitialCalculation,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
if (readingTaskState == ReadingTaskState.WaitReading)
|
|
{
|
|
await _visitTaskRepository.UpdatePartialFromQueryAsync(inDto.VisitTaskId, x => new VisitTask()
|
|
{
|
|
ReadingTaskState = ReadingTaskState.Reading,
|
|
}, true);
|
|
}
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取报告验证的信息(这里每个标准可能不一样 返回用object)
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
public async Task<GetReportVerifyOutDto> GetReportVerify(GetReportVerifyInDto inDto)
|
|
{
|
|
|
|
var service = await this.GetService(inDto.VisitTaskId);
|
|
|
|
if (service != null)
|
|
{
|
|
return await service.GetReportVerify(inDto);
|
|
}
|
|
else
|
|
{
|
|
return new GetReportVerifyOutDto() { };
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取报告图表数据
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public async Task<GetReportsChartDataOutDto> GetReportsChartData(GetReportsChartDataInDto inDto)
|
|
{
|
|
var criterionId = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => x.TrialReadingCriterionId).FirstNotNullAsync();
|
|
|
|
var criterionType = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == criterionId).Select(x => x.CriterionType).FirstOrDefaultAsync();
|
|
|
|
var data = await GetReadingReportEvaluation(new GetReadingReportEvaluationInDto()
|
|
{
|
|
TrialId = inDto.TrialId,
|
|
VisitTaskId = inDto.VisitTaskId,
|
|
});
|
|
|
|
GetReportsChartDataOutDto result = new GetReportsChartDataOutDto()
|
|
{
|
|
VisitTaskNameList = data.VisitTaskList.Select(x => x.BlindName).ToList(),
|
|
LatestScanDateList = data.VisitTaskList.Select(x => x.LatestScanDate).ToList(),
|
|
ChartDataList = new List<ReportChartData>() { },
|
|
};
|
|
|
|
|
|
result.VisitTaskNameList = data.VisitTaskList.Select(x => x.BlindName).ToList();
|
|
|
|
if (inDto.ReportChartTypeEnum != null)
|
|
{
|
|
var reportData = await GetReportsChartTypeData(new GetReportsChartTypeDataInDto()
|
|
{
|
|
CriterionType = criterionType,
|
|
Data = data,
|
|
ReportChartTypeEnum = inDto.ReportChartTypeEnum.Value,
|
|
});
|
|
result.ChartDataList = reportData.ChartDataList;
|
|
result.Unit = reportData.Unit;
|
|
}
|
|
else if (inDto.QuestionId != null)
|
|
{
|
|
var question = data.TaskQuestions.SelectMany(x => x.Childrens)
|
|
.Where(x => x.QuestionId == inDto.QuestionId.Value).FirstOrDefault();
|
|
if (question != null)
|
|
{
|
|
result.Unit = question.Unit;
|
|
ReportChartData chartData = new ReportChartData()
|
|
{
|
|
Name = question.QuestionName,
|
|
Value = new List<string>(),
|
|
};
|
|
foreach (var answer in question.Answer)
|
|
{
|
|
chartData.Value.Add(answer.Answer);
|
|
}
|
|
result.ChartDataList.Add(chartData);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
var lesion = data.TaskQuestions
|
|
// 问题 靶病灶
|
|
.SelectMany(x => x.Childrens)
|
|
// 病灶
|
|
.SelectMany(x => x.Childrens).Where(x => x.RowIndex == inDto.RowIndex)
|
|
// 表格问题
|
|
.SelectMany(x => x.Childrens).Where(x => x.TableQuestionId == inDto.TableQuestionId)
|
|
|
|
.FirstOrDefault();
|
|
|
|
if (lesion != null)
|
|
{
|
|
result.Unit = lesion.Unit;
|
|
ReportChartData chartData = new ReportChartData()
|
|
{
|
|
Name = lesion.QuestionName,
|
|
Value = new List<string>(),
|
|
};
|
|
foreach (var answer in lesion.Answer)
|
|
{
|
|
chartData.Value.Add(answer.Answer);
|
|
}
|
|
result.ChartDataList.Add(chartData);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
private async Task<GetReportsChartDataOutDto> GetReportsChartTypeData(GetReportsChartTypeDataInDto inDto)
|
|
{
|
|
var visitTaskNameList = inDto.Data.VisitTaskList.Select(x => x.BlindName).ToList();
|
|
GetReportsChartDataOutDto result = new GetReportsChartDataOutDto() {
|
|
|
|
ChartDataList=new List<ReportChartData>() { },
|
|
|
|
};
|
|
switch (inDto.ReportChartTypeEnum)
|
|
{
|
|
case ReportChartType.Target:
|
|
{
|
|
// 这是病灶
|
|
var target = inDto.Data.TaskQuestions.SelectMany(x => x.Childrens)
|
|
.Where(x => x.LesionType == LesionType.TargetLesion).SelectMany(x => x.Childrens)
|
|
.ToList();
|
|
|
|
|
|
foreach (var item in target)
|
|
{
|
|
ReportChartData chartData = new ReportChartData()
|
|
{
|
|
Name = item.QuestionName,
|
|
Value = new List<string>(),
|
|
};
|
|
|
|
for (var i = 0; i < visitTaskNameList.Count; i++)
|
|
{
|
|
|
|
switch (inDto.CriterionType)
|
|
{
|
|
case CriterionType.RECIST1Point1:
|
|
case CriterionType.RECIST1Pointt1_MB:
|
|
case CriterionType.mRECISTHCC:
|
|
case CriterionType.IRECIST1Point1:
|
|
// 淋巴结的短径
|
|
if (item.Childrens.Any(x => x.QuestionMark == QuestionMark.IsLymph && x.Answer[i].Answer.EqEnum(ReadingYesOrNo.Yes)))
|
|
{
|
|
chartData.Value.Add(item.Childrens.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Answer[i].Answer).FirstOrDefault());
|
|
result.Unit = item.Childrens.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Unit).FirstOrDefault();
|
|
}
|
|
else
|
|
{
|
|
chartData.Value.Add(item.Childrens.Where(x => x.QuestionMark == QuestionMark.MajorAxis).Select(x => x.Answer[i].Answer).FirstOrDefault());
|
|
result.Unit = item.Childrens.Where(x => x.QuestionMark == QuestionMark.ShortAxis).Select(x => x.Unit).FirstOrDefault();
|
|
}
|
|
break;
|
|
|
|
case CriterionType.Lugano2014:
|
|
case CriterionType.Lugano2014WithoutPET:
|
|
chartData.Value.Add(item.Childrens.Where(x => x.QuestionMark == QuestionMark.PPD).Select(x => x.Answer[i].Answer).FirstOrDefault());
|
|
result.Unit = item.Childrens.Where(x => x.QuestionMark == QuestionMark.PPD).Select(x => x.Unit).FirstOrDefault();
|
|
break;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
result.ChartDataList.Add(chartData);
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case ReportChartType.BaseLineTarget:
|
|
// 这是病灶
|
|
var baseTarget = inDto.Data.TaskQuestions.SelectMany(x => x.Childrens)
|
|
.Where(x => x.LesionType == LesionType.BaselineLesions).SelectMany(x => x.Childrens)
|
|
.ToList();
|
|
|
|
foreach (var item in baseTarget)
|
|
{
|
|
ReportChartData chartData = new ReportChartData()
|
|
{
|
|
Name = item.QuestionName,
|
|
Value = new List<string>(),
|
|
};
|
|
|
|
for (var i = 0; i < result.VisitTaskNameList.Count; i++)
|
|
{
|
|
|
|
chartData.Value.Add(item.Childrens.Where(x => x.QuestionMark == QuestionMark.LesionNumber).Select(x => x.Answer[i].Answer).FirstOrDefault());
|
|
result.Unit = item.Childrens.Where(x => x.QuestionMark == QuestionMark.LesionNumber).Select(x => x.Unit).FirstOrDefault();
|
|
|
|
|
|
}
|
|
|
|
result.ChartDataList.Add(chartData);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取报告图表汇总
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
[HttpPost]
|
|
public async Task<GetReportsChartSummaryOutDto> GetReportsChartSummary(GetReportsChartSummaryInDto inDto)
|
|
{
|
|
var criterion = await _readingQuestionCriterionTrialRepository.Where(x => x.Id == inDto.TrialCriterionId).FirstNotNullAsync();
|
|
var result= new GetReportsChartSummaryOutDto();
|
|
var r1Data = await GetData(new List<Arm>() { Arm.SingleReadingArm, Arm.DoubleReadingArm1 });
|
|
var r2Data = await GetData(new List<Arm>() { Arm.DoubleReadingArm2 });
|
|
|
|
var alldata = r1Data.VisitTaskList.Count() > r2Data.VisitTaskList.Count() ? r1Data : r2Data;
|
|
var visitTaskName = alldata.VisitTaskList.Select(x => x.BlindName).ToList();
|
|
var length = alldata.VisitTaskList.Count();
|
|
|
|
async Task<GetReadingReportEvaluationOutDto> GetData(List<Arm> arms)
|
|
{
|
|
var data = new GetReadingReportEvaluationOutDto() { };
|
|
var task = await _visitTaskRepository.Where(x =>
|
|
x.SubjectId == inDto.SubjectId
|
|
&& arms.Contains(x.ArmEnum)
|
|
&& x.ReadingCategory== ReadingCategory.Visit
|
|
&& x.ReadingTaskState == ReadingTaskState.HaveSigned
|
|
&& x.TaskState == TaskState.Effect
|
|
&& x.TrialReadingCriterionId==inDto.TrialCriterionId
|
|
).OrderByDescending(x => x.VisitTaskNum).FirstOrDefaultAsync();
|
|
if (task != null)
|
|
{
|
|
data = await GetReadingReportEvaluation(new GetReadingReportEvaluationInDto()
|
|
{
|
|
TrialId = task.TrialId,
|
|
VisitTaskId = task.Id,
|
|
});
|
|
}
|
|
return data;
|
|
}
|
|
|
|
|
|
EvaluationColumn BuildEvaluationTable(GetReadingReportEvaluationOutDto r1, GetReadingReportEvaluationOutDto r2)
|
|
{
|
|
EvaluationColumn result = new EvaluationColumn()
|
|
{
|
|
Evaluation = new List<List<EvaluationValue>>() { }
|
|
};
|
|
|
|
|
|
result.Evaluation.Add(visitTaskName.Select(x=> new EvaluationValue() {
|
|
Value=x
|
|
}).ToList());
|
|
|
|
var r1baseLine= r1.TaskQuestions
|
|
.SelectMany(x => x.Childrens)
|
|
.Where(x => x.QuestionType == QuestionType.ExistDisease)
|
|
.SelectMany(x => x.Answer.Select(a => new EvaluationValue
|
|
{
|
|
DictionaryCode = x.DictionaryCode,
|
|
Value = a.Answer
|
|
}))
|
|
.ToList();
|
|
|
|
|
|
var r1data = r1.TaskQuestions
|
|
.SelectMany(x => x.Childrens)
|
|
.Where(x => x.QuestionType == QuestionType.Tumor)
|
|
.SelectMany(x => x.Answer.Select(a => new EvaluationValue
|
|
{
|
|
DictionaryCode = x.DictionaryCode,
|
|
Value = a.Answer
|
|
}))
|
|
.ToList();
|
|
|
|
r1data = r1baseLine.Take(1).Concat(r1data.Skip(1)).ToList();
|
|
|
|
r1data= r1data.Concat(Enumerable.Repeat(new EvaluationValue() { Value = "" }, length))
|
|
.Take(length)
|
|
.ToList();
|
|
result.Evaluation.Add(r1data);
|
|
|
|
|
|
if (criterion.ReadingType == ReadingMethod.Double)
|
|
{
|
|
var r2baseLine = r2.TaskQuestions
|
|
.SelectMany(x => x.Childrens)
|
|
.Where(x => x.QuestionType == QuestionType.ExistDisease)
|
|
.SelectMany(x => x.Answer.Select(a => new EvaluationValue
|
|
{
|
|
DictionaryCode = x.DictionaryCode,
|
|
Value = a.Answer
|
|
}))
|
|
.ToList();
|
|
|
|
|
|
var r2data = r2.TaskQuestions
|
|
.SelectMany(x => x.Childrens)
|
|
.Where(x => x.QuestionType == QuestionType.Tumor)
|
|
.SelectMany(x => x.Answer.Select(a => new EvaluationValue
|
|
{
|
|
DictionaryCode = x.DictionaryCode,
|
|
Value = a.Answer
|
|
}))
|
|
.ToList();
|
|
|
|
r2data = r2baseLine.Take(1).Concat(r2data.Skip(1)).ToList();
|
|
|
|
r2data = r2data.Concat(Enumerable.Repeat(new EvaluationValue() { Value = "" }, length))
|
|
.Take(length)
|
|
.ToList();
|
|
result.Evaluation.Add(r2data);
|
|
}
|
|
|
|
|
|
return result;
|
|
}
|
|
|
|
List<ChartItem> BuildShowChartGroups(GetReadingReportEvaluationOutDto data, Arm arm)
|
|
{
|
|
var groups = new List<ChartItem>();
|
|
if (alldata.TaskQuestions == null || alldata.VisitTaskList == null) return groups;
|
|
foreach (var g in alldata.TaskQuestions)
|
|
{
|
|
var items = g.Childrens?.Where(c => c.ShowChartTypeEnum != ShowChartType.NotShow).ToList() ?? new List<ReadingReportDto>();
|
|
if (items.Count == 0) continue;
|
|
var chartList = new List<ReportChartData>();
|
|
foreach (var item in items)
|
|
{
|
|
var itemdata= data.TaskQuestions.SelectMany(x => x.Childrens)
|
|
.Where(x => x.QuestionId == item.QuestionId)
|
|
.FirstOrDefault();
|
|
var cd = new ReportChartData
|
|
{
|
|
Name = item?.QuestionName??string.Empty,
|
|
Value = itemdata?.Answer?.Select(a => a.Answer).ToList() ?? new List<string>()
|
|
};
|
|
chartList.Add(cd);
|
|
}
|
|
groups.Add(new ChartItem
|
|
{
|
|
Arm = arm,
|
|
ChartType = null,
|
|
GroupName = g.GroupName,
|
|
Unit = items.FirstOrDefault()?.Unit,
|
|
VisitTaskNameList = alldata.VisitTaskList.Select(x => x.BlindName).ToList(),
|
|
LatestScanDateList = alldata.VisitTaskList.Select(x => x.LatestScanDate).ToList(),
|
|
ChartDataList = chartList
|
|
});
|
|
}
|
|
return groups;
|
|
}
|
|
|
|
async Task<ChartItem> BuildTargetChart(GetReadingReportEvaluationOutDto data, Arm arm)
|
|
{
|
|
var item = new ChartItem
|
|
{
|
|
Arm = arm,
|
|
ChartType = ReportChartType.Target,
|
|
GroupName = _localizer["Tumor_TargetLesions"],
|
|
VisitTaskNameList = alldata.VisitTaskList?.Select(x => x.BlindName).ToList() ?? new List<string>(),
|
|
LatestScanDateList = alldata.VisitTaskList?.Select(x => x.LatestScanDate).ToList() ?? new List<DateTime?>(),
|
|
ChartDataList = new List<ReportChartData>(),
|
|
};
|
|
if (data.VisitTaskList != null && data.TaskQuestions != null)
|
|
{
|
|
var chart = await GetReportsChartTypeData(new GetReportsChartTypeDataInDto
|
|
{
|
|
CriterionType = criterion.CriterionType,
|
|
Data = data,
|
|
ReportChartTypeEnum = ReportChartType.Target
|
|
});
|
|
item.ChartDataList = chart.ChartDataList;
|
|
item.Unit = chart.Unit;
|
|
}
|
|
return item;
|
|
}
|
|
|
|
|
|
result.Evaluation = BuildEvaluationTable(r1Data, r2Data);
|
|
if (r1Data != null)
|
|
{
|
|
var r1Target = await BuildTargetChart(r1Data, Arm.DoubleReadingArm1);
|
|
result.TargetCharts.Add(r1Target);
|
|
var r1Groups = BuildShowChartGroups(r1Data, Arm.DoubleReadingArm1);
|
|
result.QuestionCharts.AddRange(r1Groups);
|
|
}
|
|
|
|
if (r2Data != null)
|
|
{
|
|
var r2Target = await BuildTargetChart(r2Data, Arm.DoubleReadingArm2);
|
|
result.TargetCharts.Add(r2Target);
|
|
var r2Groups = BuildShowChartGroups(r2Data, Arm.DoubleReadingArm2);
|
|
result.QuestionCharts.AddRange(r2Groups);
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取阅片报告
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public async Task<GetReadingReportEvaluationOutDto> GetReadingReportEvaluation(GetReadingReportEvaluationInDto inDto)
|
|
{
|
|
var service = await this.GetService(inDto.VisitTaskId);
|
|
|
|
if (service != null)
|
|
{
|
|
|
|
var taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).FirstNotNullAsync();
|
|
var result = await service.GetReadingReportEvaluation(inDto);
|
|
|
|
|
|
// 这里统一处理字典
|
|
|
|
Dictionary<Guid, List<CrterionDictionaryGroup>> dictionaryGroup = result.VisitTaskList.ToDictionary(x => x.VisitTaskId, x => x.CrterionDictionaryGroup);
|
|
|
|
result.TaskQuestions.ForEach(y =>
|
|
{
|
|
SetCrterionDictionaryGroup(y, dictionaryGroup);
|
|
});
|
|
|
|
// 处理标红 高亮
|
|
#region 当第N个 存在被评估为NE的单个靶病灶 评估为 为是 之后 N+1 之后的最低点访视 都标红
|
|
|
|
var index = result.TaskQuestions.SelectMany(x => x.Childrens).Where(x => x.QuestionType == QuestionType.NETarget).SelectMany(x => x.Answer).ToList().FindIndex(x => x.Answer == ExistOrNA.Exist.GetEnumInt());
|
|
|
|
if (index >= 0)
|
|
{
|
|
result.TaskQuestions.ForEach(x =>
|
|
{
|
|
x.Childrens.ForEach(y =>
|
|
{
|
|
|
|
if (y.QuestionType == QuestionType.LowVisit)
|
|
{
|
|
int idx = 0;
|
|
y.Answer.ForEach(z =>
|
|
{
|
|
if (idx > index)
|
|
{
|
|
z.IsHighlight = true;
|
|
}
|
|
idx++;
|
|
});
|
|
}
|
|
|
|
|
|
});
|
|
|
|
});
|
|
}
|
|
#endregion
|
|
|
|
|
|
|
|
return result;
|
|
}
|
|
else
|
|
{
|
|
return new GetReadingReportEvaluationOutDto();
|
|
}
|
|
}
|
|
|
|
|
|
public void SetCrterionDictionaryGroup(ReadingReportDto item, Dictionary<Guid, List<CrterionDictionaryGroup>> dictionaryGroup)
|
|
{
|
|
item.Answer.ForEach(z =>
|
|
{
|
|
try
|
|
{
|
|
z.CrterionDictionaryGroup = dictionaryGroup[z.VisitTaskId];
|
|
}
|
|
catch (Exception)
|
|
{
|
|
|
|
|
|
}
|
|
});
|
|
|
|
item.Childrens.ForEach(x =>
|
|
{
|
|
|
|
SetCrterionDictionaryGroup(x, dictionaryGroup);
|
|
});
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// 删除病灶获取起始病灶序号
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public async Task<int> GetDeleteLesionStatrIndex(DeleteReadingRowAnswerInDto inDto)
|
|
{
|
|
var service = await this.GetService(inDto.VisitTaskId);
|
|
|
|
if (service != null)
|
|
{
|
|
return await service.GetDeleteLesionStatrIndex(inDto);
|
|
}
|
|
else
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|