修改上传

Uat_Study
{872297557@qq.com} 2022-11-30 17:11:19 +08:00
parent 91227c1a67
commit 8406f6a8db
3 changed files with 101 additions and 79 deletions

View File

@ -136,56 +136,55 @@ namespace IRaCIS.Core.API.Controllers
public virtual async Task DicomFileUploadAsync(Func<string, Stream, int, Task> filePathFunc, string boundary) public virtual async Task DicomFileUploadAsync(Func<string, Stream, int, Task> filePathFunc, string boundary)
{ {
var fileCount = 0; var fileCount = 0;
//var boundary = HeaderUtilities.RemoveQuotes(MediaTypeHeaderValue.Parse(Request.ContentType).Boundary).Value; var reader = new MultipartReader(boundary, HttpContext.Request.Body);
//var boundary = mediaTypeHeader.Boundary.Value;
var reader = new MultipartReader(boundary, HttpContext.Request.Body); var section = await reader.ReadNextSectionAsync();
var section = await reader.ReadNextSectionAsync(); while (section != null)
while (section != null)
{
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
if (hasContentDispositionHeader)
{ {
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
var fileName = contentDisposition.FileName.Value ?? String.Empty; if (hasContentDispositionHeader)
string mediaType = section.ContentType ?? String.Empty;
//处理压缩文件
if (fileName.Contains(".Zip", StringComparison.OrdinalIgnoreCase) || fileName.Contains(".rar", StringComparison.OrdinalIgnoreCase))
{ {
var archive = ArchiveFactory.Open(section.Body);
foreach (var entry in archive.Entries) var fileName = contentDisposition.FileName.Value ?? String.Empty;
string mediaType = section.ContentType ?? String.Empty;
//处理压缩文件
if (fileName.Contains(".Zip", StringComparison.OrdinalIgnoreCase) || fileName.Contains(".rar", StringComparison.OrdinalIgnoreCase))
{ {
if (!entry.IsDirectory) var archive = ArchiveFactory.Open(section.Body);
foreach (var entry in archive.Entries)
{
if (!entry.IsDirectory)
{
++fileCount;
await filePathFunc(entry.Key, entry.OpenEntryStream(), fileCount);
}
}
}
//普通单个文件
else
{
if (mediaType.Contains("octet-stream") || mediaType.Contains("dicom"))
{ {
++fileCount; ++fileCount;
await filePathFunc(entry.Key, entry.OpenEntryStream(), fileCount); await filePathFunc(fileName, section.Body, fileCount);
} }
} }
} }
//普通单个文件 section = await reader.ReadNextSectionAsync();
else
{
if (mediaType.Contains("octet-stream") || mediaType.Contains("dicom"))
{
++fileCount;
await filePathFunc(fileName, section.Body, fileCount);
}
}
} }
section = await reader.ReadNextSectionAsync();
}
} }
@ -240,9 +239,6 @@ namespace IRaCIS.Core.API.Controllers
//_logger.LogError("请求到达接口"); //_logger.LogError("请求到达接口");
// validation of Content-Type
// 1. first, it must be a form-data request
// 2. a boundary should be found in the Content-Type
if (!HttpContext.Request.HasFormContentType || if (!HttpContext.Request.HasFormContentType ||
!MediaTypeHeaderValue.TryParse(HttpContext.Request.ContentType, out var mediaTypeHeader) || !MediaTypeHeaderValue.TryParse(HttpContext.Request.ContentType, out var mediaTypeHeader) ||
string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value)) string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value))
@ -257,13 +253,13 @@ namespace IRaCIS.Core.API.Controllers
var startTime = DateTime.Now; var startTime = DateTime.Now;
if (_provider.Exists("StudyUid_" + archiveStudyCommand.StudyInstanceUid)) if (_provider.Exists($"StudyUid_{trialId}_{archiveStudyCommand.StudyInstanceUid}" ))
{ {
return ResponseOutput.NotOk("当前已有人正在上传和归档该检查!"); return ResponseOutput.NotOk("当前已有人正在上传和归档该检查!");
} }
else else
{ {
_provider.Set("StudyUid_" + archiveStudyCommand.StudyInstanceUid, _userInfo.Id, TimeSpan.FromMinutes(30)); _provider.Set($"StudyUid_{trialId}_{archiveStudyCommand.StudyInstanceUid}", _userInfo.Id, TimeSpan.FromMinutes(30));
} }
var (archiveResult, archivedStudyIds) = (new DicomArchiveResult(), new List<Guid>()); var (archiveResult, archivedStudyIds) = (new DicomArchiveResult(), new List<Guid>());
@ -279,42 +275,55 @@ namespace IRaCIS.Core.API.Controllers
var savedInfo = _studyService.GetSaveToDicomInfo(archiveStudyCommand.SubjectVisitId); var savedInfo = _studyService.GetSaveToDicomInfo(archiveStudyCommand.SubjectVisitId);
await DicomFileUploadAsync(async (fileName, fileStream, receivedCount) => try
{ {
try await DicomFileUploadAsync(async (fileName, fileStream, receivedCount) =>
{ {
using (var memoryStream = new MemoryStream())
{
await fileStream.CopyToAsync(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin); try
{
using (var memoryStream = new MemoryStream())
{
await fileStream.CopyToAsync(memoryStream);
var (studyId, studyCode) = await _dicomArchiveService.ArchiveDicomStreamAsync(memoryStream, savedInfo, seriesInstanceUidList, sopInstanceUidList); memoryStream.Seek(0, SeekOrigin.Begin);
if (!archivedStudyIds.Contains(studyId))
{
archivedStudyIds.Add(studyId);
archiveResult.ArchivedDicomStudies.Add(new DicomStudyBasicDTO() { StudyCode = studyCode, Id = studyId });
}
}
//await _uploadHub.Clients.All.ReceivProgressAsync(archiveStudyCommand.StudyInstanceUid, receivedCount); var (studyId, studyCode) = await _dicomArchiveService.ArchiveDicomStreamAsync(memoryStream, savedInfo, seriesInstanceUidList, sopInstanceUidList);
if (!archivedStudyIds.Contains(studyId))
{
archivedStudyIds.Add(studyId);
archiveResult.ArchivedDicomStudies.Add(new DicomStudyBasicDTO() { StudyCode = studyCode, Id = studyId });
}
}
//await _uploadHub.Clients.All.ReceivProgressAsync(archiveStudyCommand.StudyInstanceUid, receivedCount);
await _uploadHub.Clients.User(_userInfo.Id.ToString()).ReceivProgressAsync(archiveStudyCommand.StudyInstanceUid, receivedCount); await _uploadHub.Clients.User(_userInfo.Id.ToString()).ReceivProgressAsync(archiveStudyCommand.StudyInstanceUid, receivedCount);
archiveResult.ReceivedFileCount = receivedCount; archiveResult.ReceivedFileCount = receivedCount;
} }
catch (Exception e) catch (Exception e)
{ {
_logger.LogError(e.Message + e.StackTrace); _logger.LogError(e.Message + e.StackTrace);
archiveResult.ErrorFiles.Add(fileName); archiveResult.ErrorFiles.Add(fileName);
} }
}, mediaTypeHeader.Boundary.Value); }, mediaTypeHeader.Boundary.Value);
}
catch (Exception ex)
{
_provider.Remove($"StudyUid_{trialId}_{archiveStudyCommand.StudyInstanceUid}");
throw new BusinessValidationFailedException("请求异常,请重试!");
}
var studyMonitor = new StudyMonitor() var studyMonitor = new StudyMonitor()
{ {
@ -336,7 +345,6 @@ namespace IRaCIS.Core.API.Controllers
try try
{ {
if (archivedStudyIds.Count > 0) // 上传成功,处理逻辑 if (archivedStudyIds.Count > 0) // 上传成功,处理逻辑
{ {
@ -346,16 +354,13 @@ namespace IRaCIS.Core.API.Controllers
archiveResult.ReuploadNewStudyId = archivedStudyIds[0] == archiveStudyCommand.AbandonStudyId ? archivedStudyIds[0] : Guid.Empty; archiveResult.ReuploadNewStudyId = archivedStudyIds[0] == archiveStudyCommand.AbandonStudyId ? archivedStudyIds[0] : Guid.Empty;
studyMonitor.IsSuccess = true; studyMonitor.IsSuccess = true;
} }
else else
{ {
studyMonitor.IsSuccess = false; studyMonitor.IsSuccess = false;
studyMonitor.Note = JsonConvert.SerializeObject(archiveResult); studyMonitor.Note = JsonConvert.SerializeObject(archiveResult);
_provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid);
} }
@ -372,7 +377,7 @@ namespace IRaCIS.Core.API.Controllers
} }
finally finally
{ {
_provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid); _provider.Remove($"StudyUid_{trialId}_{archiveStudyCommand.StudyInstanceUid}");
studyMonitor.StudyId = archiveResult.ArchivedDicomStudies.FirstOrDefault()?.Id ?? Guid.Empty; studyMonitor.StudyId = archiveResult.ArchivedDicomStudies.FirstOrDefault()?.Id ?? Guid.Empty;
studyMonitor.StudyCode = archiveResult.ArchivedDicomStudies.FirstOrDefault()?.StudyCode; studyMonitor.StudyCode = archiveResult.ArchivedDicomStudies.FirstOrDefault()?.StudyCode;

View File

@ -23,6 +23,9 @@ namespace IRaCIS.Core.Application.Services
private static object lockCodeGenerate = new object(); private static object lockCodeGenerate = new object();
private List<Guid> _instanceIdList = new List<Guid>();
public DicomArchiveService(IRepository<DicomStudy> studyRepository, public DicomArchiveService(IRepository<DicomStudy> studyRepository,
IRepository<DicomSeries> seriesRepository, IRepository<DicomSeries> seriesRepository,
IRepository<DicomInstance> instanceRepository, IRepository<DicomInstance> instanceRepository,
@ -122,7 +125,7 @@ namespace IRaCIS.Core.Application.Services
DicomStudy dicomStudy = CreateDicomStudy(dataset, addtionalInfo, out bool isStudyNeedAdd); DicomStudy dicomStudy = CreateDicomStudy(dataset, addtionalInfo, out bool isStudyNeedAdd);
DicomSeries dicomSeries = CreateDicomSeries(dataset, dicomStudy, out bool isSeriesNeedAdd); DicomSeries dicomSeries = CreateDicomSeries(dataset, dicomStudy, out bool isSeriesNeedAdd);
DicomInstance dicomInstance = CreateDicomInstance(dataset, dicomStudy, dicomSeries); DicomInstance dicomInstance = CreateDicomInstance(dataset, dicomStudy, dicomSeries,out bool isInstanceNeedAdd);
dicomSeries.DicomStudy = dicomStudy; dicomSeries.DicomStudy = dicomStudy;
@ -147,7 +150,11 @@ namespace IRaCIS.Core.Application.Services
dicomInstance.Path = relativePath; dicomInstance.Path = relativePath;
await _instanceRepository.AddAsync(dicomInstance); if (isInstanceNeedAdd)
{
await _instanceRepository.AddAsync(dicomInstance);
}
var samplesPerPixel = dataset.GetSingleValueOrDefault(DicomTag.SamplesPerPixel, string.Empty); var samplesPerPixel = dataset.GetSingleValueOrDefault(DicomTag.SamplesPerPixel, string.Empty);
@ -379,11 +386,14 @@ namespace IRaCIS.Core.Application.Services
} }
private DicomInstance CreateDicomInstance(DicomDataset dataset, DicomStudy dicomStudy, DicomSeries dicomSeries) private DicomInstance CreateDicomInstance(DicomDataset dataset, DicomStudy dicomStudy, DicomSeries dicomSeries, out bool isInstanceNeedAdd)
{ {
string sopInstanceUid = dataset.GetString(DicomTag.SOPInstanceUID); string sopInstanceUid = dataset.GetString(DicomTag.SOPInstanceUID);
Guid instanceId = IdentifierHelper.CreateGuid(dicomStudy.StudyInstanceUid, dicomSeries.SeriesInstanceUid, sopInstanceUid, dicomStudy.TrialId.ToString()); Guid instanceId = IdentifierHelper.CreateGuid(dicomStudy.StudyInstanceUid, dicomSeries.SeriesInstanceUid, sopInstanceUid, dicomStudy.TrialId.ToString());
DicomInstance dicomInstance = new DicomInstance DicomInstance dicomInstance = new DicomInstance
{ {
Id = instanceId, Id = instanceId,
@ -417,13 +427,20 @@ namespace IRaCIS.Core.Application.Services
WindowWidth = dataset.GetSingleValueOrDefault(DicomTag.WindowWidth, string.Empty), WindowWidth = dataset.GetSingleValueOrDefault(DicomTag.WindowWidth, string.Empty),
}; };
++dicomStudy.InstanceCount; isInstanceNeedAdd = false;
++dicomSeries.InstanceCount;
if (!_instanceIdList.Contains(instanceId))
{
++dicomStudy.InstanceCount;
++dicomSeries.InstanceCount;
isInstanceNeedAdd = true;
_instanceIdList.Add(instanceId);
}
return dicomInstance; return dicomInstance;
} }

View File

@ -456,7 +456,7 @@ namespace IRaCIS.Core.Application.Contracts
[HttpGet("{trialId:guid}")] [HttpGet("{trialId:guid}")]
public async Task<TrialSurveyInitInfo> GetTrialSurveyInitInfo(Guid trialId) public async Task<TrialSurveyInitInfo> GetTrialSurveyInitInfo(Guid trialId)
{ {
var info = await _repository.Where<Trial>(t => t.Id == trialId)/*.IgnoreQueryFilters()*/.ProjectTo<TrialSurveyInitInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); var info = await _repository.Where<Trial>(t => t.Id == trialId).IgnoreQueryFilters().ProjectTo<TrialSurveyInitInfo>(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException();
return info; return info;
} }