整理检查服务

This commit is contained in:
2022-05-29 19:12:59 +08:00
parent 5d96df5d00
commit d8098a948a
12 changed files with 1715 additions and 1989 deletions
@@ -136,9 +136,9 @@ namespace IRaCIS.Core.API.Controllers
/// <summary> 流式上传 Dicom上传 需要返回文件数量 </summary>
/// <summary> 流式上传 Dicom上传 </summary>
[Route("base")]
public virtual async Task<int> DicomFileUploadAsync(Func<string ,Stream, Task> filePathFunc)
public virtual async Task<int> DicomFileUploadAsync(Func<string, Stream, Task> filePathFunc)
{
var fileCount = 0;
@@ -155,7 +155,7 @@ namespace IRaCIS.Core.API.Controllers
if (hasContentDispositionHeader)
{
var fileName = contentDisposition.FileName.Value??String.Empty;
var fileName = contentDisposition.FileName.Value ?? String.Empty;
string mediaType = section.ContentType ?? String.Empty;
@@ -172,8 +172,6 @@ namespace IRaCIS.Core.API.Controllers
++fileCount;
await filePathFunc(entry.Key, entry.OpenEntryStream());
}
}
}
@@ -186,11 +184,8 @@ namespace IRaCIS.Core.API.Controllers
await filePathFunc(fileName, section.Body);
}
}
}
section = await reader.ReadNextSectionAsync();
}
@@ -223,186 +218,6 @@ namespace IRaCIS.Core.API.Controllers
_userInfo = userInfo;
}
/// <summary>Dicom 归档</summary>
[HttpPost, Route("Study/ArchiveStudy1/{trialId:guid}")]
[DisableFormValueModelBinding]
[DisableRequestSizeLimit]
[TypeFilter(typeof(TrialResourceFilter))]
public async Task<IResponseOutput> ArchiveStudy([FromForm] ArchiveStudyCommand archiveStudyCommand,
[FromServices] ILogger<UploadDownLoadController> _logger,
[FromServices] IEasyCachingProvider _provider,
[FromServices] IStudyService _studyService,
[FromServices] IDicomArchiveService _dicomArchiveService
)
{
string studycode = string.Empty;
var startTime = DateTime.Now;
if (_provider.Exists("StudyUid_" + archiveStudyCommand.StudyInstanceUid))
{
return ResponseOutput.NotOk("当前已有人正在上传和归档该检查!");
}
else
{
_provider.Set("StudyUid_" + archiveStudyCommand.StudyInstanceUid, _userInfo.Id, TimeSpan.FromMinutes(30));
}
var archiveResult = new DicomArchiveResult();
var archivedStudyIds = new List<Guid>();
var (seriesInstanceUidList, sopInstanceUidList) = (new List<string>(), new List<string>());
//重传的时候,找出当前检查已经上传的series instance
if (archiveStudyCommand.AbandonStudyId != null)
{
(seriesInstanceUidList, sopInstanceUidList) = _studyService.GetHasUploadSeriesAndInstance(archiveStudyCommand.AbandonStudyId.Value);
}
var savedInfo = _studyService.GetSaveToDicomInfo(archiveStudyCommand.SubjectVisitId);
var boundary = HeaderUtilities.RemoveQuotes(MediaTypeHeaderValue.Parse(Request.ContentType).Boundary).Value;
var reader = new MultipartReader(boundary, HttpContext.Request.Body);
var section = await reader.ReadNextSectionAsync();
while (section != null)
{
//采用post方式 这里多加一个判断 过滤其他参数
if (string.IsNullOrEmpty(section.ContentType))
{
section = await reader.ReadNextSectionAsync();
continue;
}
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
if (hasContentDispositionHeader)
{
string fileName = contentDisposition.FileName.Value;
try
{
string mediaType = section.ContentType;
if (mediaType.Contains("zip"))
{
var partStream = section.Body;
using (var zipArchive = new ZipArchive(partStream, ZipArchiveMode.Read))
{
foreach (var entry in zipArchive.Entries)
{
if (entry.FullName.EndsWith("/")) continue;
try
{
++archiveResult.ReceivedFileCount;
using (var memoryStream = new MemoryStream())
{
await section.Body.CopyToAsync(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
var archiveStudyId = await _dicomArchiveService.ArchiveDicomStreamAsync(memoryStream, savedInfo, seriesInstanceUidList, sopInstanceUidList);
studycode = archiveStudyId.Item2;
if (!archivedStudyIds.Contains(archiveStudyId.Item1))
archivedStudyIds.Add(archiveStudyId.Item1);
}
}
catch
{
archiveResult.ErrorFiles.Add($"{fileName}/{entry.FullName}");
}
}
}
}
++archiveResult.ReceivedFileCount;
if (mediaType.Contains("octet-stream"))
{
using (var memoryStream = new MemoryStream())
{
await section.Body.CopyToAsync(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
var archiveStudyId = await _dicomArchiveService.ArchiveDicomStreamAsync(memoryStream, savedInfo, seriesInstanceUidList, sopInstanceUidList);
studycode = archiveStudyId.Item2;
if (!archivedStudyIds.Contains(archiveStudyId.Item1))
archivedStudyIds.Add(archiveStudyId.Item1);
}
}
}
catch (Exception e)
{
_logger.LogError(e.Message + e.StackTrace);
archiveResult.ErrorFiles.Add(fileName);
_provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid);
}
}
section = await reader.ReadNextSectionAsync();
}
try
{
if (archivedStudyIds.Count > 0) // 上传成功,处理逻辑
{
// 同一个访视 多个线程上传处理 批量保存 可能造成死锁 https://www.cnblogs.com/johnblogs/p/9945767.html
await _dicomArchiveService.DicomDBDataSaveChange();
//sw.Stop();
_studyService.UploadOrReUploadNeedTodo(archiveStudyCommand, archivedStudyIds, ref archiveResult, new StudyMonitor()
{
TrialId = savedInfo.TrialId,
SiteId = savedInfo.SiteId,
SubjectId = savedInfo.SubjectId,
SubjectVisitId = savedInfo.SubjectVisitId,
StudyId = archivedStudyIds[0],
StudyCode = studycode,
UploadStartTime = startTime,
UploadFinishedTime = DateTime.Now,
//TotalMillisecondsInterval = (DateTime.Now- startTime).TotalMilliseconds,
FileSize = (decimal)HttpContext.Request.ContentLength,
FileCount = archiveResult.ReceivedFileCount,
IsDicom = true,
IsDicomReUpload = archiveStudyCommand.AbandonStudyId != null,
IP = _userInfo.IP
});
_provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid);
}
else
{
return ResponseOutput.NotOk("未完成该检查的归档");
}
}
catch (Exception e)
{
_logger.LogError(e.Message + e.StackTrace);
_provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid);
return ResponseOutput.NotOk(e.Message, ApiResponseCodeEnum.ProgramException);
}
return ResponseOutput.Ok(archiveResult);
}
/// <summary>Dicom 归档</summary>
[HttpPost, Route("Study/ArchiveStudy/{trialId:guid}")]
@@ -413,7 +228,8 @@ namespace IRaCIS.Core.API.Controllers
[FromServices] ILogger<UploadDownLoadController> _logger,
[FromServices] IEasyCachingProvider _provider,
[FromServices] IStudyService _studyService,
[FromServices] IDicomArchiveService _dicomArchiveService
[FromServices] IDicomArchiveService _dicomArchiveService,
[FromServices] IRepository _repository
)
{
@@ -438,42 +254,48 @@ namespace IRaCIS.Core.API.Controllers
//重传的时候,找出当前检查已经上传的series instance
if (archiveStudyCommand.AbandonStudyId != null)
{
(seriesInstanceUidList, sopInstanceUidList) =_studyService.GetHasUploadSeriesAndInstance(archiveStudyCommand.AbandonStudyId.Value);
(seriesInstanceUidList, sopInstanceUidList) = _studyService.GetHasUploadSeriesAndInstance(archiveStudyCommand.AbandonStudyId.Value);
}
var savedInfo = _studyService.GetSaveToDicomInfo(archiveStudyCommand.SubjectVisitId);
archiveResult.ReceivedFileCount= await DicomFileUploadAsync(async (fileName, fileStream) =>
{
archiveResult.ReceivedFileCount = await DicomFileUploadAsync(async (fileName, fileStream) =>
{
try
{
using (var memoryStream = new MemoryStream())
{
await fileStream.CopyToAsync(memoryStream);
try
{
using (var memoryStream = new MemoryStream())
{
await fileStream.CopyToAsync(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
memoryStream.Seek(0, SeekOrigin.Begin);
var archiveStudyId = await _dicomArchiveService.ArchiveDicomStreamAsync(memoryStream, savedInfo, seriesInstanceUidList, sopInstanceUidList);
studycode = archiveStudyId.Item2;
var (studyId, studyCode) = await _dicomArchiveService.ArchiveDicomStreamAsync(memoryStream, savedInfo, seriesInstanceUidList, sopInstanceUidList);
if (!archivedStudyIds.Contains(archiveStudyId.Item1))
archivedStudyIds.Add(archiveStudyId.Item1);
}
}
catch (Exception e)
{
_logger.LogError(e.Message + e.StackTrace);
archiveResult.ErrorFiles.Add(fileName);
_provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid);
}
if (!archivedStudyIds.Contains(studyId))
{
archivedStudyIds.Add(studyId);
archiveResult.ArchivedDicomStudies.Add(new DicomStudyBasicDTO() { StudyCode = studyCode, Id = studyId });
}
});
}
}
catch (Exception e)
{
_logger.LogError(e.Message + e.StackTrace);
archiveResult.ErrorFiles.Add(fileName);
_provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid);
}
});
try
@@ -485,7 +307,9 @@ namespace IRaCIS.Core.API.Controllers
await _dicomArchiveService.DicomDBDataSaveChange();
_studyService.UploadOrReUploadNeedTodo(archiveStudyCommand, archivedStudyIds, ref archiveResult, new StudyMonitor()
archiveResult.ReuploadNewStudyId = archivedStudyIds[0] == archiveStudyCommand.AbandonStudyId ? archivedStudyIds[0] : Guid.Empty;
await _repository.AddAsync(new StudyMonitor()
{
TrialId = savedInfo.TrialId,
SiteId = savedInfo.SiteId,
@@ -496,20 +320,22 @@ namespace IRaCIS.Core.API.Controllers
StudyCode = studycode,
UploadStartTime = startTime,
UploadFinishedTime = DateTime.Now,
//TotalMillisecondsInterval = (DateTime.Now- startTime).TotalMilliseconds,
FileSize = (decimal)HttpContext.Request.ContentLength,
FileCount = archiveResult.ReceivedFileCount,
IsDicom = true,
IsDicomReUpload = archiveStudyCommand.AbandonStudyId != null,
IP = _userInfo.IP
});
}, true);
//_studyService.UploadOrReUploadNeedTodo(archiveStudyCommand, archivedStudyIds, ref archiveResult, );
_provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid);
}
else
{
return ResponseOutput.NotOk("未完成该检查的归档");
return ResponseOutput.NotOk(archiveResult);
}
@@ -543,7 +369,7 @@ namespace IRaCIS.Core.API.Controllers
[HttpPost("ClinicalData/UploadVisitClinicalData/{trialId:guid}/{subjectVisitId:guid}")]
[DisableRequestSizeLimit]
[Authorize(Policy = IRaCISPolicy.CRC)]
public async Task<IResponseOutput> UploadVisitClinicalData( Guid subjectVisitId, [FromServices] IRepository _repository)
public async Task<IResponseOutput> UploadVisitClinicalData(Guid subjectVisitId, [FromServices] IRepository _repository)
{
await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);