From 8406f6a8dba199c979bfbf6b1f88fdf443f4793a Mon Sep 17 00:00:00 2001 From: "{872297557@qq.com}" <872297557@qq.com> Date: Wed, 30 Nov 2022 17:11:19 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/UploadDownLoadController.cs | 147 +++++++++--------- .../ImageAndDoc/DicomArchiveService.cs | 31 +++- .../SiteSurvey/TrialSiteSurveyService.cs | 2 +- 3 files changed, 101 insertions(+), 79 deletions(-) diff --git a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs index 8cec2af40..2178dac27 100644 --- a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs +++ b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs @@ -136,56 +136,55 @@ namespace IRaCIS.Core.API.Controllers public virtual async Task DicomFileUploadAsync(Func filePathFunc, string boundary) { - var fileCount = 0; + var fileCount = 0; - //var boundary = HeaderUtilities.RemoveQuotes(MediaTypeHeaderValue.Parse(Request.ContentType).Boundary).Value; - //var boundary = mediaTypeHeader.Boundary.Value; + var reader = new MultipartReader(boundary, HttpContext.Request.Body); - var reader = new MultipartReader(boundary, HttpContext.Request.Body); + var section = await reader.ReadNextSectionAsync(); - var section = await reader.ReadNextSectionAsync(); - - while (section != null) - { - var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition); - - if (hasContentDispositionHeader) + while (section != null) { + var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition); - 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 (hasContentDispositionHeader) { - 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; - await filePathFunc(entry.Key, entry.OpenEntryStream(), fileCount); + await filePathFunc(fileName, section.Body, fileCount); } + } } - //普通单个文件 - else - { - if (mediaType.Contains("octet-stream") || mediaType.Contains("dicom")) - { - ++fileCount; - - await filePathFunc(fileName, section.Body, fileCount); - } - - } + section = await reader.ReadNextSectionAsync(); } - section = await reader.ReadNextSectionAsync(); - } + + } @@ -240,9 +239,6 @@ namespace IRaCIS.Core.API.Controllers //_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 || !MediaTypeHeaderValue.TryParse(HttpContext.Request.ContentType, out var mediaTypeHeader) || string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value)) @@ -257,13 +253,13 @@ namespace IRaCIS.Core.API.Controllers var startTime = DateTime.Now; - if (_provider.Exists("StudyUid_" + archiveStudyCommand.StudyInstanceUid)) + if (_provider.Exists($"StudyUid_{trialId}_{archiveStudyCommand.StudyInstanceUid}" )) { return ResponseOutput.NotOk("当前已有人正在上传和归档该检查!"); } 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()); @@ -279,42 +275,55 @@ namespace IRaCIS.Core.API.Controllers var savedInfo = _studyService.GetSaveToDicomInfo(archiveStudyCommand.SubjectVisitId); - await DicomFileUploadAsync(async (fileName, fileStream, receivedCount) => - { + try + { - try - { - using (var memoryStream = new MemoryStream()) - { - await fileStream.CopyToAsync(memoryStream); + await DicomFileUploadAsync(async (fileName, fileStream, receivedCount) => + { - 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); - if (!archivedStudyIds.Contains(studyId)) - { - archivedStudyIds.Add(studyId); - archiveResult.ArchivedDicomStudies.Add(new DicomStudyBasicDTO() { StudyCode = studyCode, Id = studyId }); - } - } + memoryStream.Seek(0, SeekOrigin.Begin); - //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) - { - _logger.LogError(e.Message + e.StackTrace); + } + catch (Exception e) + { + _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() { @@ -336,7 +345,6 @@ namespace IRaCIS.Core.API.Controllers try { - if (archivedStudyIds.Count > 0) // 上传成功,处理逻辑 { @@ -346,16 +354,13 @@ namespace IRaCIS.Core.API.Controllers archiveResult.ReuploadNewStudyId = archivedStudyIds[0] == archiveStudyCommand.AbandonStudyId ? archivedStudyIds[0] : Guid.Empty; - studyMonitor.IsSuccess = true; } else { studyMonitor.IsSuccess = false; - studyMonitor.Note = JsonConvert.SerializeObject(archiveResult); - _provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid); - + studyMonitor.Note = JsonConvert.SerializeObject(archiveResult); } @@ -372,7 +377,7 @@ namespace IRaCIS.Core.API.Controllers } finally { - _provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid); + _provider.Remove($"StudyUid_{trialId}_{archiveStudyCommand.StudyInstanceUid}"); studyMonitor.StudyId = archiveResult.ArchivedDicomStudies.FirstOrDefault()?.Id ?? Guid.Empty; studyMonitor.StudyCode = archiveResult.ArchivedDicomStudies.FirstOrDefault()?.StudyCode; diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs index 00d1f6e51..b335fa5e8 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs @@ -23,6 +23,9 @@ namespace IRaCIS.Core.Application.Services private static object lockCodeGenerate = new object(); + + private List _instanceIdList = new List(); + public DicomArchiveService(IRepository studyRepository, IRepository seriesRepository, IRepository instanceRepository, @@ -122,7 +125,7 @@ namespace IRaCIS.Core.Application.Services DicomStudy dicomStudy = CreateDicomStudy(dataset, addtionalInfo, out bool isStudyNeedAdd); 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; @@ -147,7 +150,11 @@ namespace IRaCIS.Core.Application.Services dicomInstance.Path = relativePath; - await _instanceRepository.AddAsync(dicomInstance); + if (isInstanceNeedAdd) + { + await _instanceRepository.AddAsync(dicomInstance); + + } 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); Guid instanceId = IdentifierHelper.CreateGuid(dicomStudy.StudyInstanceUid, dicomSeries.SeriesInstanceUid, sopInstanceUid, dicomStudy.TrialId.ToString()); + + + DicomInstance dicomInstance = new DicomInstance { Id = instanceId, @@ -417,13 +427,20 @@ namespace IRaCIS.Core.Application.Services WindowWidth = dataset.GetSingleValueOrDefault(DicomTag.WindowWidth, string.Empty), }; - ++dicomStudy.InstanceCount; - ++dicomSeries.InstanceCount; + isInstanceNeedAdd = false; + if (!_instanceIdList.Contains(instanceId)) + { + ++dicomStudy.InstanceCount; + ++dicomSeries.InstanceCount; + + isInstanceNeedAdd = true; + + _instanceIdList.Add(instanceId); + } + return dicomInstance; - - } diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs index bf1e53370..ecee1ebe3 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs @@ -456,7 +456,7 @@ namespace IRaCIS.Core.Application.Contracts [HttpGet("{trialId:guid}")] public async Task GetTrialSurveyInitInfo(Guid trialId) { - var info = await _repository.Where(t => t.Id == trialId)/*.IgnoreQueryFilters()*/.ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); + var info = await _repository.Where(t => t.Id == trialId).IgnoreQueryFilters().ProjectTo(_mapper.ConfigurationProvider).FirstOrDefaultAsync().IfNullThrowException(); return info; }