494 lines
17 KiB
C#
494 lines
17 KiB
C#
using IRaCIS.Core.Application.Helper;
|
|
using IRaCIS.Core.Application.Service.Reading.Dto;
|
|
using IRaCIS.Core.Application.ViewModel;
|
|
using IRaCIS.Core.Domain.Share;
|
|
using IRaCIS.Core.Infrastructure;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using MiniExcelLibs;
|
|
using System.Data;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace IRaCIS.Core.Application.Service.ReadingCalculate
|
|
{
|
|
[ApiExplorerSettings(GroupName = "Image")]
|
|
public class ReadingCalculateService(IEnumerable<ICriterionCalculateService> _criterionServices,
|
|
IRepository<VisitTask> _visitTaskRepository,
|
|
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.IVUS,typeof(IVUSCalculateService) },
|
|
{CriterionType.OCT,typeof(OCTCalculateService) },
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// <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<FileResult> DownLoadReadReport(DownLoadReadReportInDto inDto)
|
|
{
|
|
var service = await this.GetService(inDto.VisitTaskId);
|
|
if (service != null)
|
|
{
|
|
inDto.DownLoadGuid = Guid.NewGuid();
|
|
Stream stream = await service.DownLoadReadReportStream(inDto);
|
|
|
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
{
|
|
FileStreamResult actionResult = new FileStreamResult(stream, new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"));
|
|
|
|
actionResult.FileDownloadName = "ReadReoprtTemplate.docx";
|
|
|
|
|
|
this.DeleteFile(inDto);
|
|
return actionResult;
|
|
}
|
|
else
|
|
{
|
|
FileStreamResult actionResult = new FileStreamResult(stream, new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"));
|
|
actionResult.FileDownloadName = "ReadReoprtTemplate.pdf";
|
|
this.DeleteFile(inDto);
|
|
return actionResult;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
throw new BusinessValidationFailedException("error");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 删除文件
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
|
|
public void DeleteFile(DownLoadReadReportInDto inDto)
|
|
{
|
|
|
|
|
|
|
|
try
|
|
{
|
|
File.Delete(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $@"wwwroot/ReadReoprtTemplate/downLoad/{inDto.DownLoadGuid}.docx"));
|
|
|
|
}
|
|
catch (Exception)
|
|
{
|
|
|
|
}
|
|
|
|
try
|
|
{
|
|
File.Delete(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $@"wwwroot/ReadReoprtTemplate/downLoad/{inDto.DownLoadGuid}.pdf"));
|
|
|
|
}
|
|
catch (Exception)
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 下载阅片报告流
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="BusinessValidationFailedException"></exception>
|
|
public async Task<Stream> DownLoadReadReportStream(DownLoadReadReportInDto inDto)
|
|
{
|
|
var service = await this.GetService(inDto.VisitTaskId);
|
|
if (service != null)
|
|
{
|
|
inDto.DownLoadGuid = Guid.NewGuid();
|
|
var result = await service.DownLoadReadReportStream(inDto);
|
|
this.DeleteFile(inDto);
|
|
return result;
|
|
|
|
}
|
|
else
|
|
{
|
|
throw new BusinessValidationFailedException(_localizer["ReadingCalculate_DownLoadReadReport"]);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取并生成报告URL
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
public async Task<string> GetVisitReadReportUrl(CaGetVisitReadReportUrl inDto)
|
|
{
|
|
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.Subject).Include(x => x.SourceSubjectVisit).FirstNotNullAsync();
|
|
if (taskinfo.ReportExportUrl != string.Empty)
|
|
{
|
|
return taskinfo.ReportExportUrl;
|
|
}
|
|
else
|
|
{
|
|
var stream = await DownLoadReadReportStream(new DownLoadReadReportInDto()
|
|
{
|
|
VisitTaskId = inDto.VisitTaskId,
|
|
DownLoadGuid= Guid.NewGuid(),
|
|
});
|
|
var url = await _oSSService.UploadToOSSAsync(stream, $"ReadingReport/{taskinfo.TrialId.ToString()}/{taskinfo.Id.ToString()}", $"{taskinfo.Subject.Code}_{taskinfo.SourceSubjectVisit.VisitName}.pdf", false);
|
|
|
|
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask()
|
|
{
|
|
ReportExportUrl = url
|
|
});
|
|
return url;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 下载肿瘤评估流
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="BusinessValidationFailedException"></exception>
|
|
public async Task<Stream> DownLoadTumorEvaluationStream(DownLoadReadReportInDto inDto)
|
|
{
|
|
var service = await this.GetService(inDto.VisitTaskId);
|
|
if (service != null)
|
|
{
|
|
inDto.DownLoadGuid = Guid.NewGuid();
|
|
var result = await service.DownLoadTumorEvaluationStream(inDto);
|
|
this.DeleteFile(inDto);
|
|
return result;
|
|
|
|
}
|
|
else
|
|
{
|
|
throw new BusinessValidationFailedException(_localizer["ReadingCalculate_DownLoadReadReport"]);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取肿瘤并生成报告URL
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
public async Task<string> GetTumorEvaluationReportUrl(CaGetVisitReadReportUrl inDto)
|
|
{
|
|
var taskinfo = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Include(x => x.Subject).Include(x => x.SourceSubjectVisit).FirstNotNullAsync();
|
|
if (taskinfo.TumorEvaluationUrl != string.Empty)
|
|
{
|
|
return taskinfo.TumorEvaluationUrl;
|
|
}
|
|
else
|
|
{
|
|
var stream = await DownLoadTumorEvaluationStream(new DownLoadReadReportInDto()
|
|
{
|
|
VisitTaskId = inDto.VisitTaskId,
|
|
DownLoadGuid = Guid.NewGuid(),
|
|
});
|
|
var url = await _oSSService.UploadToOSSAsync(stream, $"ReadingReport/{taskinfo.TrialId.ToString()}/{taskinfo.Id.ToString()}", $"TumorEvaluation_{taskinfo.Subject.Code}_{taskinfo.SourceSubjectVisit.VisitName}.pdf", false);
|
|
|
|
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask()
|
|
{
|
|
TumorEvaluationUrl = url
|
|
});
|
|
return url;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 下载肿瘤评估
|
|
/// </summary>
|
|
/// <param name="inDto"></param>
|
|
/// <returns></returns>
|
|
/// <exception cref="BusinessValidationFailedException"></exception>
|
|
public async Task<FileResult> DownLoadTumorEvaluation(DownLoadReadReportInDto inDto)
|
|
{
|
|
var service = await this.GetService(inDto.VisitTaskId);
|
|
if (service != null)
|
|
{
|
|
inDto.DownLoadGuid = Guid.NewGuid();
|
|
Stream stream = await service.DownLoadTumorEvaluationStream(inDto);
|
|
|
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
{
|
|
FileStreamResult actionResult = new FileStreamResult(stream, new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"));
|
|
|
|
actionResult.FileDownloadName = "ReadReoprtTemplateTumorEvaluation.docx";
|
|
|
|
|
|
this.DeleteFile(inDto);
|
|
return actionResult;
|
|
}
|
|
else
|
|
{
|
|
FileStreamResult actionResult = new FileStreamResult(stream, new Microsoft.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"));
|
|
actionResult.FileDownloadName = "ReadReoprtTemplateTumorEvaluation.pdf";
|
|
this.DeleteFile(inDto);
|
|
return actionResult;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
throw new BusinessValidationFailedException("error");
|
|
}
|
|
}
|
|
|
|
|
|
/// <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>
|
|
/// <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);
|
|
});
|
|
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|