610 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			610 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C#
		
	
	
| using FellowOakDicom;
 | ||
| using FellowOakDicom.Imaging.Codec;
 | ||
| using IRaCIS.Core.Application.Contracts;
 | ||
| using IRaCIS.Core.Application.Contracts.Dicom;
 | ||
| using IRaCIS.Core.Application.Helper;
 | ||
| using IRaCIS.Core.Domain.Share;
 | ||
| using IRaCIS.Core.Infrastructure;
 | ||
| using Medallion.Threading;
 | ||
| using Microsoft.AspNetCore.Hosting;
 | ||
| using System.Data;
 | ||
| using System.Text;
 | ||
| using ZiggyCreatures.Caching.Fusion;
 | ||
| 
 | ||
| namespace IRaCIS.Core.Application.Services
 | ||
| {
 | ||
|     public class DicomArchiveService(IRepository<DicomStudy> _studyRepository,
 | ||
|          IRepository<DicomSeries> _seriesRepository,
 | ||
|          IRepository<DicomInstance> _instanceRepository,
 | ||
|          IRepository<Dictionary> _dictionaryRepository,
 | ||
|          IRepository<SystemAnonymization> _systemAnonymizationRepository,
 | ||
|          IDistributedLockProvider _distributedLockProvider,
 | ||
|          IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment, IFusionCache _fusionCache) : BaseService, IDicomArchiveService
 | ||
|     {
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         private List<Guid> _instanceIdList = new List<Guid>();
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         public async Task<bool> DicomDBDataSaveChange()
 | ||
|         {
 | ||
|             var success = await _studyRepository.SaveChangesAsync();
 | ||
|             return success;
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         public async Task<(Guid StudyId, string StudyCode)> ArchiveDicomStreamAsync(Stream dicomStream,
 | ||
|             DicomTrialSiteSubjectInfo addtionalInfo, List<string> seriesInstanceUidList, List<string> instanceUidList)
 | ||
|         {
 | ||
| 
 | ||
| 
 | ||
|             DicomFile dicomFile = await DicomFile.OpenAsync(dicomStream, Encoding.Default);
 | ||
| 
 | ||
|             DicomDataset dataset = dicomFile.Dataset;
 | ||
| 
 | ||
|             //如果数据库存在该instance 记录 那么就不处理
 | ||
|             string sopInstanceUid = dataset.GetString(DicomTag.SOPInstanceUID);
 | ||
|             string studyInstanceUid = dataset.GetString(DicomTag.StudyInstanceUID);
 | ||
| 
 | ||
|             if (instanceUidList.Any(t => t == sopInstanceUid))
 | ||
|             {
 | ||
|                 return (IdentifierHelper.CreateGuid(studyInstanceUid, addtionalInfo.TrialId.ToString()), string.Empty);
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             var anonymizeList = await _fusionCache.GetOrSetAsync(CacheKeys.SystemAnonymization, _ => CacheHelper.GetSystemAnonymizationListAsync(_systemAnonymizationRepository), TimeSpan.FromDays(7));
 | ||
| 
 | ||
|             var fixedFiledList = anonymizeList.Where(t => t.IsFixed).ToList();
 | ||
|             var ircFiledList = anonymizeList.Where(t => t.IsFixed == false).ToList();
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|             foreach (var item in fixedFiledList)
 | ||
|             {
 | ||
| 
 | ||
|                 var dicomTag = new DicomTag(Convert.ToUInt16(item.Group, 16), Convert.ToUInt16(item.Element, 16));
 | ||
| 
 | ||
|                 dataset.AddOrUpdate(dicomTag, item.ReplaceValue);
 | ||
|             }
 | ||
| 
 | ||
|             foreach (var item in ircFiledList)
 | ||
|             {
 | ||
| 
 | ||
|                 var dicomTag = new DicomTag(Convert.ToUInt16(item.Group, 16), Convert.ToUInt16(item.Element, 16));
 | ||
| 
 | ||
|                 if (dicomTag == DicomTag.ClinicalTrialProtocolID)
 | ||
|                 {
 | ||
|                     dataset.AddOrUpdate(dicomTag, addtionalInfo.TrialCode);
 | ||
| 
 | ||
|                 }
 | ||
|                 if (dicomTag == DicomTag.ClinicalTrialSiteID)
 | ||
|                 {
 | ||
|                     dataset.AddOrUpdate(dicomTag, addtionalInfo.TrialSiteCode);
 | ||
| 
 | ||
|                 }
 | ||
|                 if (dicomTag == DicomTag.ClinicalTrialSubjectID)
 | ||
|                 {
 | ||
|                     dataset.AddOrUpdate(dicomTag, addtionalInfo.SubjectCode);
 | ||
| 
 | ||
|                 }
 | ||
|                 if (dicomTag == DicomTag.ClinicalTrialTimePointID)
 | ||
|                 {
 | ||
|                     dataset.AddOrUpdate(dicomTag, addtionalInfo.VisitNum.ToString());
 | ||
| 
 | ||
|                 }
 | ||
|                 if (dicomTag == DicomTag.PatientID)
 | ||
|                 {
 | ||
|                     dataset.AddOrUpdate(dicomTag, addtionalInfo.TrialCode + "_" + addtionalInfo.SubjectCode);
 | ||
| 
 | ||
|                 }
 | ||
| 
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             DicomStudy dicomStudy = CreateDicomStudy(dataset, addtionalInfo, out bool isStudyNeedAdd);
 | ||
|             DicomSeries dicomSeries = CreateDicomSeries(dataset, dicomStudy, out bool isSeriesNeedAdd);
 | ||
|             DicomInstance dicomInstance = CreateDicomInstance(dataset, dicomStudy, dicomSeries, out bool isInstanceNeedAdd);
 | ||
| 
 | ||
|             dicomSeries.DicomStudy = dicomStudy;
 | ||
| 
 | ||
| 
 | ||
|             var createtime = DateTime.Now;
 | ||
| 
 | ||
|             if (isStudyNeedAdd)
 | ||
|             {
 | ||
|                 // 添加检查
 | ||
|                 await _studyRepository.AddAsync(dicomStudy);
 | ||
|             }
 | ||
| 
 | ||
|             if (isSeriesNeedAdd)
 | ||
|             {
 | ||
|                 dicomSeries.DicomStudy = dicomStudy;
 | ||
|                 // 添加序列
 | ||
|                 await _seriesRepository.AddAsync(dicomSeries);
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             var (physicalPath, relativePath) = FileStoreHelper.GetDicomInstanceFilePath(_hostEnvironment, dicomStudy.TrialId, dicomStudy.SubjectId, dicomStudy.SubjectVisitId, dicomStudy.Id, dicomInstance.Id);
 | ||
| 
 | ||
|             dicomInstance.Path = relativePath;
 | ||
| 
 | ||
|             if (isInstanceNeedAdd)
 | ||
|             {
 | ||
|                 await _instanceRepository.AddAsync(dicomInstance);
 | ||
| 
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             var samplesPerPixel = dataset.GetSingleValueOrDefault(DicomTag.SamplesPerPixel, string.Empty);
 | ||
|             var photometricInterpretation = dataset.GetSingleValueOrDefault(DicomTag.PhotometricInterpretation, string.Empty);
 | ||
| 
 | ||
|             if (samplesPerPixel == "1" && (photometricInterpretation.ToUpper() == "MONOCHROME2" || photometricInterpretation.ToUpper() == "MONOCHROME1"))//MONOCHROME2
 | ||
|             {
 | ||
|                 if (dataset.InternalTransferSyntax.IsEncapsulated)
 | ||
|                 {
 | ||
|                     //正常保存  不做处理
 | ||
|                     await dicomFile.SaveAsync(physicalPath);
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {   //JPEGLSLossless 保存
 | ||
|                     await dicomFile.Clone(DicomTransferSyntax.JPEGLSLossless).SaveAsync(physicalPath);
 | ||
|                 }
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 if (dataset.InternalTransferSyntax.IsEncapsulated)
 | ||
|                 {
 | ||
|                     //正常保存  不做处理
 | ||
|                     await dicomFile.SaveAsync(physicalPath);
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     //RLELossless 保存
 | ||
|                     await dicomFile.Clone(DicomTransferSyntax.RLELossless).SaveAsync(physicalPath); //RLELossless
 | ||
| 
 | ||
|                 }
 | ||
|             }
 | ||
|             return (dicomInstance.StudyId, dicomStudy.StudyCode);
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         private DicomStudy CreateDicomStudy(DicomDataset dataset, DicomTrialSiteSubjectInfo addtionalInfo, out bool isStudyNeedAdd)
 | ||
|         {
 | ||
| 
 | ||
|             string studyInstanceUid = dataset.GetString(DicomTag.StudyInstanceUID);
 | ||
|             Guid studyId = IdentifierHelper.CreateGuid(studyInstanceUid, addtionalInfo.TrialId.ToString());
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|             // 每个线程都查询数据库最大的,和缓存中最大的,取最大值为基数生成Code
 | ||
|             //var id = Thread.CurrentThread.ManagedThreadId.ToString("00");
 | ||
| 
 | ||
|             //虽然每个文件都会进来,但是只要查询过,就会跟踪,不会再次查询数据库  这里线程并发会有问题,得加锁,不然生成Code 出错
 | ||
|             DicomStudy dicomStudy = _studyRepository.ImageFind(studyId, typeof(DicomStudy));
 | ||
| 
 | ||
|             if (dicomStudy != null)
 | ||
|             {
 | ||
|                 isStudyNeedAdd = false;
 | ||
|                 return dicomStudy;
 | ||
|             }
 | ||
| 
 | ||
|             //_logger.LogWarning($"Thread {id} ,studyUid{studyInstanceUid}, 生成StudyId:{studyId}");
 | ||
| 
 | ||
|             isStudyNeedAdd = true;
 | ||
| 
 | ||
|             //dataset.GetSingleValue<string>(DicomTag.StudyDate) + dataset.GetSingleValue<string>(DicomTag.StudyTime)
 | ||
| 
 | ||
|             var modality = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty);
 | ||
| 
 | ||
|             var dicModalityList = _dictionaryRepository.Where(t => t.Code == "Modality").SelectMany(t => t.ChildList.Select(c => c.Value)).ToList();
 | ||
| 
 | ||
|             var modalityForEdit = dicModalityList.Contains(modality) ? modality : String.Empty;
 | ||
| 
 | ||
|             if (modality == "MR")
 | ||
|             {
 | ||
|                 modalityForEdit = "MRI";
 | ||
|             }
 | ||
| 
 | ||
|             if (modality == "PT")
 | ||
|             {
 | ||
|                 modalityForEdit = "PET";
 | ||
|             }
 | ||
|             if (modality == "PT、CT")
 | ||
|             {
 | ||
|                 modalityForEdit = "PET-CT";
 | ||
|             }
 | ||
| 
 | ||
|             dicomStudy = new DicomStudy
 | ||
|             {
 | ||
|                 Id = studyId,
 | ||
|                 StudyInstanceUid = studyInstanceUid,
 | ||
|                 /* StudyTime = dataset.GetSingleValueOrDefault(DicomTag.StudyDate, DateTime.Now).Add(dataset.GetSingleValueOrDefault(DicomTag.StudyTime, DateTime.Now).TimeOfDay),*///dataset.GetDateTime(DicomTag.StudyDate, DicomTag.StudyTime),
 | ||
|                 StudyTime = dataset.GetSingleValueOrDefault(DicomTag.StudyDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue<DateTime>(DicomTag.StudyDate).Add(dataset.GetSingleValueOrDefault(DicomTag.StudyTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue<DateTime>(DicomTag.StudyTime).TimeOfDay),
 | ||
|                 Modalities = modality,
 | ||
|                 ModalityForEdit = modalityForEdit,
 | ||
|                 Description = dataset.GetSingleValueOrDefault(DicomTag.StudyDescription, string.Empty),
 | ||
|                 InstitutionName = dataset.GetSingleValueOrDefault(DicomTag.InstitutionName, string.Empty),
 | ||
|                 PatientId = dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty),
 | ||
|                 PatientName = dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty),
 | ||
|                 PatientAge = dataset.GetSingleValueOrDefault(DicomTag.PatientAge, string.Empty),
 | ||
|                 PatientSex = dataset.GetSingleValueOrDefault(DicomTag.PatientSex, string.Empty),
 | ||
|                 BodyPartExamined = dataset.GetSingleValueOrDefault(DicomTag.BodyPartExamined, string.Empty),
 | ||
| 
 | ||
|                 StudyId = dataset.GetSingleValueOrDefault(DicomTag.StudyID, string.Empty),
 | ||
|                 AccessionNumber = dataset.GetSingleValueOrDefault(DicomTag.AccessionNumber, string.Empty),
 | ||
| 
 | ||
|                 //需要特殊处理
 | ||
|                 PatientBirthDate = dataset.GetSingleValueOrDefault(DicomTag.PatientBirthDate, string.Empty),
 | ||
| 
 | ||
| 
 | ||
|                 AcquisitionTime = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionTime, string.Empty),
 | ||
|                 AcquisitionNumber = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionNumber, string.Empty),
 | ||
|                 TriggerTime = dataset.GetSingleValueOrDefault(DicomTag.TriggerTime, string.Empty),
 | ||
| 
 | ||
| 
 | ||
|                 TrialId = addtionalInfo.TrialId,
 | ||
|                 SubjectId = addtionalInfo.SubjectId,
 | ||
|                 SubjectVisitId = addtionalInfo.SubjectVisitId,
 | ||
|                 //IsDoubleReview = addtionalInfo.IsDoubleReview,
 | ||
|                 SeriesCount = 0,
 | ||
|                 InstanceCount = 0
 | ||
|             };
 | ||
| 
 | ||
|             if (dicomStudy.PatientBirthDate.Length == 8)
 | ||
|             {
 | ||
|                 dicomStudy.PatientBirthDate = $"{dicomStudy.PatientBirthDate[0]}{dicomStudy.PatientBirthDate[1]}{dicomStudy.PatientBirthDate[2]}{dicomStudy.PatientBirthDate[3]}-{dicomStudy.PatientBirthDate[4]}{dicomStudy.PatientBirthDate[5]}-{dicomStudy.PatientBirthDate[6]}{dicomStudy.PatientBirthDate[7]}";
 | ||
|             }
 | ||
| 
 | ||
|             var @lock = _distributedLockProvider.CreateLock($"StudyCode");
 | ||
| 
 | ||
|             using (@lock.Acquire())
 | ||
|             {
 | ||
|                 //查询数据库获取最大的Code 没有记录则为0
 | ||
|                 var dbStudyCodeIntMax = _studyRepository.Where(s => s.TrialId == addtionalInfo.TrialId).Select(t => t.Code).DefaultIfEmpty().Max();
 | ||
| 
 | ||
|                 //获取缓存中的值 并发的时候,需要记录,已被占用的值 这样其他线程在此占用的最大的值上递增
 | ||
|                 var cacheMaxCodeInt = _fusionCache.GetOrDefault<int>(CacheKeys.TrialStudyMaxCode(addtionalInfo.TrialId));
 | ||
| 
 | ||
|                 int currentNextCodeInt = cacheMaxCodeInt > dbStudyCodeIntMax ? cacheMaxCodeInt + 1 : dbStudyCodeIntMax + 1;
 | ||
| 
 | ||
|                 dicomStudy.Code = currentNextCodeInt;
 | ||
| 
 | ||
|                 dicomStudy.StudyCode = AppSettings.GetCodeStr(currentNextCodeInt, nameof(DicomStudy));
 | ||
| 
 | ||
|                 _fusionCache.Set(CacheKeys.TrialStudyMaxCode(addtionalInfo.TrialId), dicomStudy.Code, TimeSpan.FromMinutes(30));
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             return dicomStudy;
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|         private DicomSeries CreateDicomSeries(DicomDataset dataset, DicomStudy dicomStudy, out bool isSeriesNeedAdd)
 | ||
|         {
 | ||
|             string seriesInstanceUid = dataset.GetString(DicomTag.SeriesInstanceUID);
 | ||
|             Guid seriesId = IdentifierHelper.CreateGuid(dicomStudy.StudyInstanceUid, seriesInstanceUid, dicomStudy.TrialId.ToString());
 | ||
| 
 | ||
|             //有几个序列会查询几次
 | ||
| 
 | ||
|             DicomSeries dicomSeries = _seriesRepository.ImageFind(seriesId, typeof(DicomSeries));
 | ||
| 
 | ||
|             if (dicomSeries != null)
 | ||
|             {
 | ||
|                 isSeriesNeedAdd = false;
 | ||
|                 return dicomSeries;
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 //var id = Thread.CurrentThread.ManagedThreadId.ToString("00");
 | ||
| 
 | ||
|                 isSeriesNeedAdd = true;
 | ||
|                 dicomSeries = new DicomSeries
 | ||
|                 {
 | ||
|                     Id = seriesId,
 | ||
|                     StudyId = dicomStudy.Id,
 | ||
| 
 | ||
|                     StudyInstanceUid = dicomStudy.StudyInstanceUid,
 | ||
|                     SeriesInstanceUid = seriesInstanceUid,
 | ||
|                     SeriesNumber = dataset.GetSingleValueOrDefault(DicomTag.SeriesNumber, 1),
 | ||
|                     //SeriesTime = dataset.GetSingleValueOrDefault(DicomTag.SeriesDate, DateTime.Now).Add(dataset.GetSingleValueOrDefault(DicomTag.SeriesTime, DateTime.Now).TimeOfDay),
 | ||
|                     //SeriesTime = DateTime.TryParse(dataset.GetSingleValue<string>(DicomTag.SeriesDate) + dataset.GetSingleValue<string>(DicomTag.SeriesTime), out DateTime dt) ? dt : null,
 | ||
|                     SeriesTime = dataset.GetSingleValueOrDefault(DicomTag.SeriesDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue<DateTime>(DicomTag.SeriesDate).Add(dataset.GetSingleValueOrDefault(DicomTag.SeriesTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue<DateTime>(DicomTag.SeriesTime).TimeOfDay),
 | ||
|                     Modality = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty),
 | ||
|                     Description = dataset.GetSingleValueOrDefault(DicomTag.SeriesDescription, string.Empty),
 | ||
|                     SliceThickness = dataset.GetSingleValueOrDefault(DicomTag.SliceThickness, string.Empty),
 | ||
| 
 | ||
|                     ImagePositionPatient = dataset.GetSingleValueOrDefault(DicomTag.ImagePositionPatient, string.Empty),
 | ||
|                     ImageOrientationPatient = dataset.GetSingleValueOrDefault(DicomTag.ImageOrientationPatient, string.Empty),
 | ||
|                     BodyPartExamined = dataset.GetSingleValueOrDefault(DicomTag.BodyPartExamined, string.Empty),
 | ||
|                     SequenceName = dataset.GetSingleValueOrDefault(DicomTag.SequenceName, string.Empty),
 | ||
|                     ProtocolName = dataset.GetSingleValueOrDefault(DicomTag.ProtocolName, string.Empty),
 | ||
|                     ImagerPixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.ImagerPixelSpacing, string.Empty),
 | ||
| 
 | ||
|                     AcquisitionTime = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionTime, string.Empty),
 | ||
|                     AcquisitionNumber = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionNumber, string.Empty),
 | ||
|                     TriggerTime = dataset.GetSingleValueOrDefault(DicomTag.TriggerTime, string.Empty),
 | ||
| 
 | ||
|                     TrialId = dicomStudy.TrialId,
 | ||
|                     SubjectId = dicomStudy.SubjectId,
 | ||
|                     SubjectVisitId = dicomStudy.SubjectVisitId,
 | ||
| 
 | ||
|                     InstanceCount = 0
 | ||
|                 };
 | ||
| 
 | ||
|                 ++dicomStudy.SeriesCount;
 | ||
| 
 | ||
| 
 | ||
|                 //_logger.LogWarning($"线程:{id},sericeId:{seriesId},count:{SeriesDic.Keys.Count}");
 | ||
| 
 | ||
|                 return 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,
 | ||
|                 StudyId = dicomStudy.Id,
 | ||
|                 SeriesId = dicomSeries.Id,
 | ||
| 
 | ||
|                 TrialId = dicomStudy.TrialId,
 | ||
|                 SubjectId = dicomStudy.SubjectId,
 | ||
|                 SubjectVisitId = dicomStudy.SubjectVisitId,
 | ||
| 
 | ||
|                 StudyInstanceUid = dicomStudy.StudyInstanceUid,
 | ||
|                 SeriesInstanceUid = dicomSeries.SeriesInstanceUid,
 | ||
|                 SopInstanceUid = sopInstanceUid,
 | ||
|                 InstanceNumber = dataset.GetSingleValueOrDefault(DicomTag.InstanceNumber, 1),
 | ||
|                 InstanceTime = dataset.GetSingleValueOrDefault(DicomTag.ContentDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue<DateTime>(DicomTag.ContentDate).Add(dataset.GetSingleValueOrDefault(DicomTag.ContentTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue<DateTime>(DicomTag.ContentTime).TimeOfDay),
 | ||
|                 //InstanceTime = DateTime.TryParse(dataset.GetSingleValue<string>(DicomTag.ContentDate) + dataset.GetSingleValue<string>(DicomTag.ContentTime), out DateTime dt) ? dt : null,
 | ||
|                 //InstanceTime = dataset.GetSingleValueOrDefault(DicomTag.ContentDate,(DateTime?)null)?.Add(dataset.GetSingleValueOrDefault(DicomTag.ContentTime, TimeSpan.Zero)),
 | ||
|                 //dataset.GetSingleValueOrDefault(DicomTag.ContentDate,DateTime.Now);//, DicomTag.ContentTime)
 | ||
|                 CPIStatus = false,
 | ||
|                 ImageRows = dataset.GetSingleValueOrDefault(DicomTag.Rows, 0),
 | ||
|                 ImageColumns = dataset.GetSingleValueOrDefault(DicomTag.Columns, 0),
 | ||
|                 SliceLocation = dataset.GetSingleValueOrDefault(DicomTag.SliceLocation, 0),
 | ||
| 
 | ||
|                 SliceThickness = dataset.GetSingleValueOrDefault(DicomTag.SliceThickness, string.Empty),
 | ||
|                 NumberOfFrames = dataset.GetSingleValueOrDefault(DicomTag.NumberOfFrames, 0),
 | ||
|                 PixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.PixelSpacing, string.Empty),
 | ||
|                 ImagerPixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.ImagerPixelSpacing, string.Empty),
 | ||
|                 FrameOfReferenceUID = dataset.GetSingleValueOrDefault(DicomTag.FrameOfReferenceUID, string.Empty),
 | ||
|                 WindowCenter = dataset.GetSingleValueOrDefault(DicomTag.WindowCenter, string.Empty),
 | ||
|                 WindowWidth = dataset.GetSingleValueOrDefault(DicomTag.WindowWidth, string.Empty),
 | ||
|             };
 | ||
| 
 | ||
|             isInstanceNeedAdd = false;
 | ||
| 
 | ||
|             if (!_instanceIdList.Contains(instanceId))
 | ||
|             {
 | ||
|                 ++dicomStudy.InstanceCount;
 | ||
|                 ++dicomSeries.InstanceCount;
 | ||
| 
 | ||
|                 isInstanceNeedAdd = true;
 | ||
| 
 | ||
|                 _instanceIdList.Add(instanceId);
 | ||
|             }
 | ||
| 
 | ||
|             return dicomInstance;
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 单个文件接收 归档
 | ||
|         /// </summary>
 | ||
|         /// <param name="dataset"></param>
 | ||
|         /// <returns></returns>
 | ||
|         /// <exception cref="NotImplementedException"></exception>
 | ||
|         public async Task ArchiveDicomFileAsync(DicomDataset dataset)
 | ||
|         {
 | ||
|             string studyInstanceUid = dataset.GetString(DicomTag.StudyInstanceUID);
 | ||
|             string seriesInstanceUid = dataset.GetString(DicomTag.SeriesInstanceUID);
 | ||
|             string sopInstanceUid = dataset.GetString(DicomTag.SOPInstanceUID);
 | ||
| 
 | ||
|             Guid studyId = IdentifierHelper.CreateGuid(studyInstanceUid);
 | ||
|             Guid seriesId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid);
 | ||
|             Guid instanceId = IdentifierHelper.CreateGuid(studyInstanceUid, seriesInstanceUid, sopInstanceUid);
 | ||
| 
 | ||
|             var isStudyNeedAdd = false;
 | ||
|             var isSeriesNeedAdd = false;
 | ||
|             var isInstanceNeedAdd = false;
 | ||
| 
 | ||
|             var @lock = _distributedLockProvider.CreateLock($"StudyInstanceUid");
 | ||
| 
 | ||
|             using (@lock.Acquire())
 | ||
|             {
 | ||
|                 var findStudy = await _studyRepository.FirstOrDefaultAsync(t => t.Id == studyId);
 | ||
|                 var findSerice = await _seriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId);
 | ||
|                 var findInstance = await _instanceRepository.FirstOrDefaultAsync(t => t.Id == instanceId);
 | ||
| 
 | ||
| 
 | ||
|                 if (findStudy == null)
 | ||
|                 {
 | ||
|                     isStudyNeedAdd = true;
 | ||
|                     findStudy = new DicomStudy
 | ||
|                     {
 | ||
|                         Id = studyId,
 | ||
|                         StudyInstanceUid = studyInstanceUid,
 | ||
|                         StudyTime = dataset.GetSingleValueOrDefault(DicomTag.StudyDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue<DateTime>(DicomTag.StudyDate).Add(dataset.GetSingleValueOrDefault(DicomTag.StudyTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue<DateTime>(DicomTag.StudyTime).TimeOfDay),
 | ||
|                         //Modalities = modality,
 | ||
|                         //ModalityForEdit = modalityForEdit,
 | ||
|                         Description = dataset.GetSingleValueOrDefault(DicomTag.StudyDescription, string.Empty),
 | ||
|                         InstitutionName = dataset.GetSingleValueOrDefault(DicomTag.InstitutionName, string.Empty),
 | ||
|                         PatientId = dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty),
 | ||
|                         PatientName = dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty),
 | ||
|                         PatientAge = dataset.GetSingleValueOrDefault(DicomTag.PatientAge, string.Empty),
 | ||
|                         PatientSex = dataset.GetSingleValueOrDefault(DicomTag.PatientSex, string.Empty),
 | ||
|                         BodyPartExamined = dataset.GetSingleValueOrDefault(DicomTag.BodyPartExamined, string.Empty),
 | ||
| 
 | ||
|                         StudyId = dataset.GetSingleValueOrDefault(DicomTag.StudyID, string.Empty),
 | ||
|                         AccessionNumber = dataset.GetSingleValueOrDefault(DicomTag.AccessionNumber, string.Empty),
 | ||
| 
 | ||
|                         //需要特殊处理
 | ||
|                         PatientBirthDate = dataset.GetSingleValueOrDefault(DicomTag.PatientBirthDate, string.Empty),
 | ||
| 
 | ||
| 
 | ||
|                         AcquisitionTime = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionTime, string.Empty),
 | ||
|                         AcquisitionNumber = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionNumber, string.Empty),
 | ||
|                         TriggerTime = dataset.GetSingleValueOrDefault(DicomTag.TriggerTime, string.Empty),
 | ||
| 
 | ||
| 
 | ||
|                         TrialId = Guid.Empty,
 | ||
|                         SubjectId = Guid.Empty,
 | ||
|                         SubjectVisitId = Guid.Empty,
 | ||
|                         //IsDoubleReview = addtionalInfo.IsDoubleReview,
 | ||
|                         SeriesCount = 0,
 | ||
|                         InstanceCount = 0
 | ||
|                     };
 | ||
| 
 | ||
|                     //特殊逻辑
 | ||
| 
 | ||
|                     var modality = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty);
 | ||
| 
 | ||
|                     var dicModalityList = _dictionaryRepository.Where(t => t.Code == "Modality").SelectMany(t => t.ChildList.Select(c => c.Value)).ToList();
 | ||
| 
 | ||
|                     var modalityForEdit = dicModalityList.Contains(modality) ? modality : String.Empty;
 | ||
| 
 | ||
|                     if (modality == "MR")
 | ||
|                     {
 | ||
|                         modalityForEdit = "MRI";
 | ||
|                     }
 | ||
| 
 | ||
|                     if (modality == "PT")
 | ||
|                     {
 | ||
|                         modalityForEdit = "PET";
 | ||
|                     }
 | ||
|                     if (modality == "PT、CT")
 | ||
|                     {
 | ||
|                         modalityForEdit = "PET-CT";
 | ||
|                     }
 | ||
| 
 | ||
|                     findStudy.Modalities = modality;
 | ||
|                     findStudy.ModalityForEdit = modalityForEdit;
 | ||
| 
 | ||
|                     if (findStudy.PatientBirthDate.Length == 8)
 | ||
|                     {
 | ||
|                         findStudy.PatientBirthDate = $"{findStudy.PatientBirthDate[0]}{findStudy.PatientBirthDate[1]}{findStudy.PatientBirthDate[2]}{findStudy.PatientBirthDate[3]}-{findStudy.PatientBirthDate[4]}{findStudy.PatientBirthDate[5]}-{findStudy.PatientBirthDate[6]}{findStudy.PatientBirthDate[7]}";
 | ||
|                     }
 | ||
|                 }
 | ||
| 
 | ||
| 
 | ||
|                 if (findSerice == null)
 | ||
|                 {
 | ||
|                     isSeriesNeedAdd = true;
 | ||
| 
 | ||
|                     findSerice = new DicomSeries
 | ||
|                     {
 | ||
|                         Id = seriesId,
 | ||
|                         StudyId = findStudy.Id,
 | ||
| 
 | ||
|                         StudyInstanceUid = findStudy.StudyInstanceUid,
 | ||
|                         SeriesInstanceUid = seriesInstanceUid,
 | ||
|                         SeriesNumber = dataset.GetSingleValueOrDefault(DicomTag.SeriesNumber, 1),
 | ||
|                         //SeriesTime = dataset.GetSingleValueOrDefault(DicomTag.SeriesDate, DateTime.Now).Add(dataset.GetSingleValueOrDefault(DicomTag.SeriesTime, DateTime.Now).TimeOfDay),
 | ||
|                         //SeriesTime = DateTime.TryParse(dataset.GetSingleValue<string>(DicomTag.SeriesDate) + dataset.GetSingleValue<string>(DicomTag.SeriesTime), out DateTime dt) ? dt : null,
 | ||
|                         SeriesTime = dataset.GetSingleValueOrDefault(DicomTag.SeriesDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue<DateTime>(DicomTag.SeriesDate).Add(dataset.GetSingleValueOrDefault(DicomTag.SeriesTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue<DateTime>(DicomTag.SeriesTime).TimeOfDay),
 | ||
|                         Modality = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty),
 | ||
|                         Description = dataset.GetSingleValueOrDefault(DicomTag.SeriesDescription, string.Empty),
 | ||
|                         SliceThickness = dataset.GetSingleValueOrDefault(DicomTag.SliceThickness, string.Empty),
 | ||
| 
 | ||
|                         ImagePositionPatient = dataset.GetSingleValueOrDefault(DicomTag.ImagePositionPatient, string.Empty),
 | ||
|                         ImageOrientationPatient = dataset.GetSingleValueOrDefault(DicomTag.ImageOrientationPatient, string.Empty),
 | ||
|                         BodyPartExamined = dataset.GetSingleValueOrDefault(DicomTag.BodyPartExamined, string.Empty),
 | ||
|                         SequenceName = dataset.GetSingleValueOrDefault(DicomTag.SequenceName, string.Empty),
 | ||
|                         ProtocolName = dataset.GetSingleValueOrDefault(DicomTag.ProtocolName, string.Empty),
 | ||
|                         ImagerPixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.ImagerPixelSpacing, string.Empty),
 | ||
| 
 | ||
|                         AcquisitionTime = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionTime, string.Empty),
 | ||
|                         AcquisitionNumber = dataset.GetSingleValueOrDefault(DicomTag.AcquisitionNumber, string.Empty),
 | ||
|                         TriggerTime = dataset.GetSingleValueOrDefault(DicomTag.TriggerTime, string.Empty),
 | ||
| 
 | ||
|                         TrialId = Guid.Empty,
 | ||
|                         SubjectId = Guid.Empty,
 | ||
|                         SubjectVisitId = Guid.Empty,
 | ||
| 
 | ||
|                         InstanceCount = 0
 | ||
|                     };
 | ||
| 
 | ||
|                     ++findStudy.SeriesCount;
 | ||
|                 }
 | ||
| 
 | ||
| 
 | ||
|                 if (findInstance == null)
 | ||
|                 {
 | ||
|                     isInstanceNeedAdd = true;
 | ||
|                     findInstance = new DicomInstance
 | ||
|                     {
 | ||
|                         Id = instanceId,
 | ||
|                         StudyId = findStudy.Id,
 | ||
|                         SeriesId = findSerice.Id,
 | ||
|                         StudyInstanceUid = findStudy.StudyInstanceUid,
 | ||
|                         SeriesInstanceUid = findSerice.SeriesInstanceUid,
 | ||
| 
 | ||
|                         TrialId = Guid.Empty,
 | ||
|                         SubjectId = Guid.Empty,
 | ||
|                         SubjectVisitId = Guid.Empty,
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                         SopInstanceUid = sopInstanceUid,
 | ||
|                         InstanceNumber = dataset.GetSingleValueOrDefault(DicomTag.InstanceNumber, 1),
 | ||
|                         InstanceTime = dataset.GetSingleValueOrDefault(DicomTag.ContentDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue<DateTime>(DicomTag.ContentDate).Add(dataset.GetSingleValueOrDefault(DicomTag.ContentTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue<DateTime>(DicomTag.ContentTime).TimeOfDay),
 | ||
|                         //InstanceTime = DateTime.TryParse(dataset.GetSingleValue<string>(DicomTag.ContentDate) + dataset.GetSingleValue<string>(DicomTag.ContentTime), out DateTime dt) ? dt : null,
 | ||
|                         //InstanceTime = dataset.GetSingleValueOrDefault(DicomTag.ContentDate,(DateTime?)null)?.Add(dataset.GetSingleValueOrDefault(DicomTag.ContentTime, TimeSpan.Zero)),
 | ||
|                         //dataset.GetSingleValueOrDefault(DicomTag.ContentDate,DateTime.Now);//, DicomTag.ContentTime)
 | ||
|                         CPIStatus = false,
 | ||
|                         ImageRows = dataset.GetSingleValueOrDefault(DicomTag.Rows, 0),
 | ||
|                         ImageColumns = dataset.GetSingleValueOrDefault(DicomTag.Columns, 0),
 | ||
|                         SliceLocation = dataset.GetSingleValueOrDefault(DicomTag.SliceLocation, 0),
 | ||
| 
 | ||
|                         SliceThickness = dataset.GetSingleValueOrDefault(DicomTag.SliceThickness, string.Empty),
 | ||
|                         NumberOfFrames = dataset.GetSingleValueOrDefault(DicomTag.NumberOfFrames, 0),
 | ||
|                         PixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.PixelSpacing, string.Empty),
 | ||
|                         ImagerPixelSpacing = dataset.GetSingleValueOrDefault(DicomTag.ImagerPixelSpacing, string.Empty),
 | ||
|                         FrameOfReferenceUID = dataset.GetSingleValueOrDefault(DicomTag.FrameOfReferenceUID, string.Empty),
 | ||
|                         WindowCenter = dataset.GetSingleValueOrDefault(DicomTag.WindowCenter, string.Empty),
 | ||
|                         WindowWidth = dataset.GetSingleValueOrDefault(DicomTag.WindowWidth, string.Empty),
 | ||
|                     };
 | ||
| 
 | ||
|                     ++findStudy.InstanceCount;
 | ||
|                     ++findSerice.InstanceCount;
 | ||
|                 }
 | ||
| 
 | ||
|                 if (isStudyNeedAdd)
 | ||
|                 {
 | ||
|                     await _studyRepository.AddAsync(findStudy);
 | ||
|                 }
 | ||
|                 if (isSeriesNeedAdd)
 | ||
|                 {
 | ||
|                     await _seriesRepository.AddAsync(findSerice);
 | ||
|                 }
 | ||
|                 if (isInstanceNeedAdd)
 | ||
|                 {
 | ||
|                     await _instanceRepository.AddAsync(findInstance);
 | ||
|                 }
 | ||
|                 await _studyRepository.SaveChangesAsync();
 | ||
|             }
 | ||
| 
 | ||
|         }
 | ||
|     }
 | ||
| }
 |