diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
index fd58e4f9d..f23af1399 100644
--- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
+++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
@@ -847,6 +847,11 @@
+
+
+ 后台托管服务的方式运行
+
+
指定资源Id,渲染Dicom检查的Jpeg预览图像
Dicom检查的Id
@@ -1836,7 +1841,7 @@
- 计算靶病灶状态
+ 计算分裂靶病灶状态
@@ -5071,6 +5076,11 @@
任务Id
+
+
+ 问题类型
+
+
任务Id
@@ -11500,6 +11510,14 @@
Financial---项目收入价格验证
+
+
+ 单个文件接收 归档
+
+
+
+
+
指定资源Id,获取Dicom序列所属的实例信息列表
Dicom序列的Id
diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/CStoreSCPService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/CStoreSCPService.cs
index 53ea5547e..79536d0b1 100644
--- a/IRaCIS.Core.Application/Service/ImageAndDoc/CStoreSCPService.cs
+++ b/IRaCIS.Core.Application/Service/ImageAndDoc/CStoreSCPService.cs
@@ -8,9 +8,44 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using IRaCIS.Core.Application.Contracts.Dicom;
using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
namespace IRaCIS.Core.Application.Service.ImageAndDoc
{
+ ///
+ /// 后台托管服务的方式运行
+ ///
+ //public class CStoreSCPHostedService : IHostedService
+ //{
+ // private readonly ILogger _logger;
+ // private readonly IDicomServerFactory _dicomServerFactory;
+ // private IDicomServer? _server;
+
+ // public CStoreSCPHostedService(ILogger logger, IDicomServerFactory dicomServerFactory)
+ // {
+ // _logger = logger ?? throw new ArgumentNullException(nameof(logger));
+ // _dicomServerFactory = dicomServerFactory ?? throw new ArgumentNullException(nameof(dicomServerFactory));
+ // }
+
+ // public async Task StartAsync(CancellationToken cancellationToken)
+ // {
+ // _logger.LogInformation("Starting DICOM server");
+ // _server = _dicomServerFactory.Create(104);
+ // _logger.LogInformation("DICOM server is running");
+ // }
+
+ // public Task StopAsync(CancellationToken cancellationToken)
+ // {
+ // if (_server != null)
+ // {
+ // _server.Stop();
+ // _server.Dispose();
+ // _server = null;
+ // }
+ // return Task.CompletedTask;
+ // }
+ //}
+
public class CStoreSCPService : DicomService, IDicomServiceProvider, IDicomCStoreProvider, IDicomCEchoProvider
{
diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs
index 69929b1da..31991c2cd 100644
--- a/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs
+++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs
@@ -9,6 +9,9 @@ using IRaCIS.Core.Infrastructure;
using Medallion.Threading;
using FellowOakDicom;
using FellowOakDicom.Imaging.Codec;
+using System.Data;
+using IRaCIS.Core.Domain.Models;
+using FellowOakDicom.Network;
namespace IRaCIS.Core.Application.Services
{
@@ -474,11 +477,205 @@ namespace IRaCIS.Core.Application.Services
}
+ ///
+ /// 单个文件接收 归档
+ ///
+ ///
+ ///
+ ///
+ 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(DicomTag.StudyDate).Add(dataset.GetSingleValueOrDefault(DicomTag.StudyTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue(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),
+
+
+ SiteId = Guid.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(DicomTag.SeriesDate) + dataset.GetSingleValue(DicomTag.SeriesTime), out DateTime dt) ? dt : null,
+ SeriesTime = dataset.GetSingleValueOrDefault(DicomTag.SeriesDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue(DicomTag.SeriesDate).Add(dataset.GetSingleValueOrDefault(DicomTag.SeriesTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue(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),
+
+ SiteId = Guid.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,
+
+ SiteId = Guid.Empty,
+ 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(DicomTag.ContentDate).Add(dataset.GetSingleValueOrDefault(DicomTag.ContentTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue(DicomTag.ContentTime).TimeOfDay),
+ //InstanceTime = DateTime.TryParse(dataset.GetSingleValue(DicomTag.ContentDate) + dataset.GetSingleValue(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();
+ }
+
+ }
}
}
diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/Interface/IDicomArchiveService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/Interface/IDicomArchiveService.cs
index f78222dfc..92332cb06 100644
--- a/IRaCIS.Core.Application/Service/ImageAndDoc/Interface/IDicomArchiveService.cs
+++ b/IRaCIS.Core.Application/Service/ImageAndDoc/Interface/IDicomArchiveService.cs
@@ -1,4 +1,6 @@
-namespace IRaCIS.Core.Application.Contracts.Dicom
+using FellowOakDicom;
+
+namespace IRaCIS.Core.Application.Contracts.Dicom
{
public interface IDicomArchiveService
{
@@ -18,7 +20,7 @@
////[EasyCachingAble(Expiration = 6000)]
//string GetSeriesPreview(Guid seriesId);
-
+ Task ArchiveDicomFileAsync(DicomDataset dicomDataset);
}
}