修改上传
parent
91227c1a67
commit
8406f6a8db
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue