From 887559501291c3ffdde985e6f2b5730a0a13f70a Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Tue, 16 May 2023 10:32:53 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=BC=A0=20=E5=BF=83=E8=B7=B3?= =?UTF-8?q?=E5=8C=85=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ImageAndDoc/DTO/UnionStudyViewDodel.cs | 2 + .../Service/ImageAndDoc/StudyService.cs | 297 ++++++++++-------- 2 files changed, 172 insertions(+), 127 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs index 86033717f..3d473fa80 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/UnionStudyViewDodel.cs @@ -178,6 +178,8 @@ namespace IRaCIS.Core.Application.Contracts public class PreArchiveDicomStudyCommand { + //public string StudyInstanceUid { get; set; } + [NotDefault] public Guid TrialId { get; set; } [NotDefault] diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs index f75eceb3a..501f86ae4 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs @@ -21,7 +21,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc [ApiExplorerSettings(GroupName = "Image")] public class StudyService : BaseService, IStudyService { - private static object lockCodeGenerate = new object(); + private static object lockObj = new object(); private static readonly AsyncLock _mutex = new AsyncLock(); private static readonly AsyncLock _mutex2 = new AsyncLock(); @@ -93,8 +93,18 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc public async Task PreArchiveDicomStudy(PreArchiveDicomStudyCommand preArchiveStudyCommand) { - - + //lock (lockObj) + //{ + // if (_provider.Exists($"StudyUid_{preArchiveStudyCommand.TrialId}_{preArchiveStudyCommand.StudyInstanceUid}")) + // { + // //---当前已有人正在上传和归档该检查! + // return ResponseOutput.NotOk(StaticData.International("UploadDownLoad_ArchiveInProgress")); + // } + // else + // { + // _provider.Set($"StudyUid_{preArchiveStudyCommand.TrialId}_{preArchiveStudyCommand.StudyInstanceUid}", _userInfo.Id, TimeSpan.FromSeconds(30)); + // } + //} var studyMonitor = new StudyMonitor() { @@ -111,7 +121,6 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc IsDicomReUpload = preArchiveStudyCommand.IsDicomReUpload, FileSize = preArchiveStudyCommand.FileSize, FileCount = preArchiveStudyCommand.FileCount, - //FailedFileCount = preArchiveStudyCommand.FailedFileCount, }; @@ -123,123 +132,76 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc } + public IResponseOutput DicomUploadInprogress(Guid trialId, string studyInstanceUid) + { + _provider.Set($"StudyUid_{trialId}_{studyInstanceUid}", _userInfo.Id, TimeSpan.FromSeconds(30)); + + return ResponseOutput.Ok(); + + } + + [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] public async Task AddOrUpdateArchiveStudy(NewArchiveStudyCommand incommand) { - var trialId = incommand.TrialId; - - var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == incommand.StudyMonitorId); - studyMonitor.UploadFinishedTime = DateTime.Now; - studyMonitor.ArchiveFinishedTime = DateTime.Now; - studyMonitor.FailedFileCount = incommand.FailedFileCount; - studyMonitor.IsSuccess = true; - - //上传 - if (studyMonitor.IsDicomReUpload == false) + try { - var study = _mapper.Map(incommand.Study); + var trialId = incommand.TrialId; - using (await _mutex.LockAsync()) + var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == incommand.StudyMonitorId); + studyMonitor.UploadFinishedTime = DateTime.Now; + studyMonitor.ArchiveFinishedTime = DateTime.Now; + studyMonitor.FailedFileCount = incommand.FailedFileCount; + studyMonitor.IsSuccess = true; + + //上传 + if (studyMonitor.IsDicomReUpload == false) { - //查询数据库获取最大的Code 没有记录则为0 - var dbStudyCodeIntMax = _dicomstudyRepository.Where(s => s.TrialId == trialId).Select(t => t.Code).DefaultIfEmpty().Max(); + var study = _mapper.Map(incommand.Study); - //获取缓存中的值 并发的时候,需要记录,已被占用的值 这样其他线程在此占用的最大的值上递增 - var cacheMaxCodeInt = _provider.Get($"{trialId}_{StaticData.CacheKey.StudyMaxCode}").Value; - - int currentNextCodeInt = cacheMaxCodeInt > dbStudyCodeIntMax ? cacheMaxCodeInt + 1 : dbStudyCodeIntMax + 1; - - study.Code = currentNextCodeInt; - - study.StudyCode = AppSettings.GetCodeStr(currentNextCodeInt, nameof(DicomStudy)); - - _provider.Set($"{trialId}_{StaticData.CacheKey.StudyMaxCode}", study.Code, TimeSpan.FromMinutes(30)); - - } - - - study.Id = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString()); - study.TrialId = incommand.TrialId; - study.SiteId = incommand.SiteId; - study.SubjectId = incommand.SubjectId; - study.SubjectVisitId = incommand.SubjectVisitId; - - - //特殊处理逻辑 - study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Distinct()); - SpecialArchiveStudyDeal(study); - - await _dicomstudyRepository.AddAsync(study); - - - studyMonitor.StudyId = study.Id; - studyMonitor.StudyCode = study.StudyCode; - - - foreach (var seriesItem in incommand.Study.SeriesList) - { - var series = _mapper.Map(seriesItem); - - series.Id = IdentifierHelper.CreateGuid(seriesItem.SeriesInstanceUid, incommand.TrialId.ToString()); - series.StudyId = study.Id; - - series.TrialId = incommand.TrialId; - series.SiteId = incommand.SiteId; - series.SubjectId = incommand.SubjectId; - series.SubjectVisitId = incommand.SubjectVisitId; - - await _dicomSeriesRepository.AddAsync(series); - - foreach (var instanceItem in seriesItem.InstanceList) + using (await _mutex.LockAsync()) { - var isntance = _mapper.Map(instanceItem); - isntance.StudyId = study.Id; - isntance.SeriesId = series.Id; + //查询数据库获取最大的Code 没有记录则为0 + var dbStudyCodeIntMax = _dicomstudyRepository.Where(s => s.TrialId == trialId).Select(t => t.Code).DefaultIfEmpty().Max(); - isntance.TrialId = incommand.TrialId; - isntance.SiteId = incommand.SiteId; - isntance.SubjectId = incommand.SubjectId; - isntance.SubjectVisitId = incommand.SubjectVisitId; + //获取缓存中的值 并发的时候,需要记录,已被占用的值 这样其他线程在此占用的最大的值上递增 + var cacheMaxCodeInt = _provider.Get($"{trialId}_{StaticData.CacheKey.StudyMaxCode}").Value; + + int currentNextCodeInt = cacheMaxCodeInt > dbStudyCodeIntMax ? cacheMaxCodeInt + 1 : dbStudyCodeIntMax + 1; + + study.Code = currentNextCodeInt; + + study.StudyCode = AppSettings.GetCodeStr(currentNextCodeInt, nameof(DicomStudy)); + + _provider.Set($"{trialId}_{StaticData.CacheKey.StudyMaxCode}", study.Code, TimeSpan.FromMinutes(30)); - await _dicomInstanceRepository.AddAsync(isntance); } - } + study.Id = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString()); + study.TrialId = incommand.TrialId; + study.SiteId = incommand.SiteId; + study.SubjectId = incommand.SubjectId; + study.SubjectVisitId = incommand.SubjectVisitId; - } - else - { + //特殊处理逻辑 + study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Distinct()); + SpecialArchiveStudyDeal(study); - var studyId = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString()); ; - - var study = await _dicomstudyRepository.FirstOrDefaultAsync(t => t.Id == studyId); - - //_mapper.Map(incommand.Study, study); - - //特殊处理逻辑 - study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Union(study.Modalities.Split("、", StringSplitOptions.RemoveEmptyEntries)).Distinct()); - SpecialArchiveStudyDeal(study); + await _dicomstudyRepository.AddAsync(study); + studyMonitor.StudyId = study.Id; + studyMonitor.StudyCode = study.StudyCode; - // 少了整个序列 - //某个序列下少了instance - foreach (var seriesItem in incommand.Study.SeriesList) - { - var seriesId = IdentifierHelper.CreateGuid(seriesItem.StudyInstanceUid, seriesItem.SeriesInstanceUid, trialId.ToString()); - - DicomSeries dicomSeries = await _dicomSeriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId); - - //判断重复 - if (dicomSeries == null) + foreach (var seriesItem in incommand.Study.SeriesList) { var series = _mapper.Map(seriesItem); - series.Id = seriesId; + series.Id = IdentifierHelper.CreateGuid(seriesItem.SeriesInstanceUid, incommand.TrialId.ToString()); series.StudyId = study.Id; series.TrialId = incommand.TrialId; @@ -247,49 +209,120 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc series.SubjectId = incommand.SubjectId; series.SubjectVisitId = incommand.SubjectVisitId; + await _dicomSeriesRepository.AddAsync(series); - dicomSeries = await _dicomSeriesRepository.AddAsync(series); + foreach (var instanceItem in seriesItem.InstanceList) + { + var isntance = _mapper.Map(instanceItem); + isntance.StudyId = study.Id; + isntance.SeriesId = series.Id; - //新的序列 那么 检查的序列数量+1 - study.SeriesCount += 1; + isntance.TrialId = incommand.TrialId; + isntance.SiteId = incommand.SiteId; + isntance.SubjectId = incommand.SubjectId; + isntance.SubjectVisitId = incommand.SubjectVisitId; + + await _dicomInstanceRepository.AddAsync(isntance); + } } - else + + + + + } + else + { + + var studyId = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString()); ; + + var study = await _dicomstudyRepository.FirstOrDefaultAsync(t => t.Id == studyId); + + //_mapper.Map(incommand.Study, study); + + //特殊处理逻辑 + study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Union(study.Modalities.Split("、", StringSplitOptions.RemoveEmptyEntries)).Distinct()); + SpecialArchiveStudyDeal(study); + + + + // 少了整个序列 + + //某个序列下少了instance + foreach (var seriesItem in incommand.Study.SeriesList) { - //该序列掉了instance - dicomSeries.InstanceCount += seriesItem.InstanceCount; + var seriesId = IdentifierHelper.CreateGuid(seriesItem.StudyInstanceUid, seriesItem.SeriesInstanceUid, trialId.ToString()); + + DicomSeries dicomSeries = await _dicomSeriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId); + + //判断重复 + if (dicomSeries == null) + { + var series = _mapper.Map(seriesItem); + + series.Id = seriesId; + series.StudyId = study.Id; + + series.TrialId = incommand.TrialId; + series.SiteId = incommand.SiteId; + series.SubjectId = incommand.SubjectId; + series.SubjectVisitId = incommand.SubjectVisitId; + + + dicomSeries = await _dicomSeriesRepository.AddAsync(series); + + //新的序列 那么 检查的序列数量+1 + study.SeriesCount += 1; + } + else + { + //该序列掉了instance + dicomSeries.InstanceCount += seriesItem.InstanceCount; + } + + dicomSeries.IamgeResizePath = seriesItem.IamgeResizePath; + + foreach (var instanceItem in seriesItem.InstanceList) + { + var insntance = _mapper.Map(instanceItem); + insntance.Id = IdentifierHelper.CreateGuid(insntance.StudyInstanceUid, insntance.SeriesInstanceUid, insntance.SopInstanceUid, trialId.ToString()); + insntance.StudyId = study.Id; + insntance.SeriesId = dicomSeries.Id; + + insntance.TrialId = incommand.TrialId; + insntance.SiteId = incommand.SiteId; + insntance.SubjectId = incommand.SubjectId; + insntance.SubjectVisitId = incommand.SubjectVisitId; + + await _dicomInstanceRepository.AddAsync(insntance); + } + + + // 不管是新的序列 还是 该序列 掉了Instance 重传的时候 检查的instance 数量都会增加 + study.InstanceCount += seriesItem.InstanceCount; + } - dicomSeries.IamgeResizePath = seriesItem.IamgeResizePath; - - foreach (var instanceItem in seriesItem.InstanceList) - { - var insntance = _mapper.Map(instanceItem); - insntance.Id = IdentifierHelper.CreateGuid(insntance.StudyInstanceUid, insntance.SeriesInstanceUid, insntance.SopInstanceUid, trialId.ToString()); - insntance.StudyId = study.Id; - insntance.SeriesId = dicomSeries.Id; - - insntance.TrialId = incommand.TrialId; - insntance.SiteId = incommand.SiteId; - insntance.SubjectId = incommand.SubjectId; - insntance.SubjectVisitId = incommand.SubjectVisitId; - - await _dicomInstanceRepository.AddAsync(insntance); - } - - - // 不管是新的序列 还是 该序列 掉了Instance 重传的时候 检查的instance 数量都会增加 - study.InstanceCount += seriesItem.InstanceCount; } + using (await _mutex2.LockAsync()) + { + await _dicomInstanceRepository.SaveChangesAsync(); + + } } - - using (await _mutex2.LockAsync()) + catch (Exception ex) { - await _dicomInstanceRepository.SaveChangesAsync(); + return ResponseOutput.NotOk(ex.Message); } + finally + { + _provider.Remove($"StudyUid_{incommand.TrialId}_{incommand.Study.StudyInstanceUid}"); + } + + @@ -729,7 +762,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc var result = new VerifyStudyUploadResult(); - if (_provider.Exists("StudyUid_" + studyInstanceUid)) + if (_provider.Exists($"StudyUid_{trialId}_{studyInstanceUid}")) { result.AllowUpload = false; @@ -790,6 +823,16 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc } } result.StudyInstanceUid = studyInstanceUid; + + + if (result.AllowReUpload || result.AllowUpload) + { + lock (lockObj) + { + _provider.Set($"StudyUid_{trialId}_{studyInstanceUid}", _userInfo.Id, TimeSpan.FromMinutes(30)); + } + } + return result; }