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();
 | 
						||
            }
 | 
						||
 | 
						||
        }
 | 
						||
    }
 | 
						||
}
 |