对接联影,转发c-find c-move请求,并且发送c-store 请求
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
e5f6685719
commit
e496cf1117
|
|
@ -26,12 +26,25 @@ using Newtonsoft.Json;
|
|||
using FellowOakDicom.Imaging.Codec;
|
||||
using FellowOakDicom.IO.Buffer;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using FellowOakDicom.Network.Client;
|
||||
|
||||
namespace IRaCIS.Core.SCP.Service
|
||||
{
|
||||
|
||||
public class DicomSCPServiceOption
|
||||
{
|
||||
public bool IsSupportThirdService { get; set; }
|
||||
|
||||
public string ThirdSearchPacsAE { get; set; }
|
||||
|
||||
public string ThirdCallningAE { get; set; }
|
||||
|
||||
public string ThirdIP { get; set; }
|
||||
|
||||
public int THirdPort { get; set; }
|
||||
|
||||
|
||||
|
||||
public List<string> CalledAEList { get; set; }
|
||||
|
||||
public string ServerPort { get; set; }
|
||||
|
|
@ -51,12 +64,16 @@ namespace IRaCIS.Core.SCP.Service
|
|||
|
||||
private SCPImageUpload _upload { get; set; }
|
||||
|
||||
private DicomSCPServiceOption DicomSCPServiceConfig { get; set; }
|
||||
|
||||
public HospitalGroup CurrentHospitalGroup { get; set; }
|
||||
|
||||
private List<Guid> HospitalGroupIdList { get; set; }
|
||||
|
||||
private bool _releasedNormally = false;
|
||||
|
||||
private bool _isCurrentThirdForward = false;
|
||||
|
||||
|
||||
private static readonly DicomTransferSyntax[] _acceptedTransferSyntaxes = new DicomTransferSyntax[]
|
||||
{
|
||||
|
|
@ -97,6 +114,7 @@ namespace IRaCIS.Core.SCP.Service
|
|||
public Task OnReceiveAssociationRequestAsync(DicomAssociation association)
|
||||
{
|
||||
|
||||
|
||||
_upload = new SCPImageUpload() { StartTime = DateTime.Now, CallingAE = association.CallingAE, CalledAE = association.CalledAE, CallingAEIP = association.RemoteHost };
|
||||
|
||||
|
||||
|
|
@ -108,7 +126,7 @@ namespace IRaCIS.Core.SCP.Service
|
|||
|
||||
var option = _serviceProvider.GetService<IOptionsMonitor<DicomSCPServiceOption>>().CurrentValue;
|
||||
|
||||
|
||||
DicomSCPServiceConfig = option;
|
||||
|
||||
var _hospitalGroupRepository = _serviceProvider.GetService<IRepository<HospitalGroup>>();
|
||||
|
||||
|
|
@ -180,17 +198,22 @@ namespace IRaCIS.Core.SCP.Service
|
|||
|
||||
private async Task AddUploadLogAsync()
|
||||
{
|
||||
//记录监控
|
||||
//转发第三方,那么不记录日志
|
||||
if (_isCurrentThirdForward == false)
|
||||
{
|
||||
//记录监控
|
||||
|
||||
var _SCPImageUploadRepository = _serviceProvider.GetService<IRepository<SCPImageUpload>>();
|
||||
var _SCPImageUploadRepository = _serviceProvider.GetService<IRepository<SCPImageUpload>>();
|
||||
|
||||
_upload.EndTime = DateTime.Now;
|
||||
_upload.StudyCount = _ImageUploadList.Count;
|
||||
_upload.EndTime = DateTime.Now;
|
||||
_upload.StudyCount = _ImageUploadList.Count;
|
||||
|
||||
_upload.UploadJsonStr = (new SCPImageLog() { UploadList = _ImageUploadList }).ToJsonStr();
|
||||
_upload.UploadJsonStr = (new SCPImageLog() { UploadList = _ImageUploadList }).ToJsonStr();
|
||||
|
||||
//可能是测试echo 导致记录了
|
||||
await _SCPImageUploadRepository.AddAsync(_upload, _upload.FileCount > 0 ? true : false);
|
||||
}
|
||||
|
||||
//可能是测试echo 导致记录了
|
||||
await _SCPImageUploadRepository.AddAsync(_upload, _upload.FileCount > 0 ? true : false);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -292,6 +315,52 @@ namespace IRaCIS.Core.SCP.Service
|
|||
return new DicomCStoreResponse(request, DicomStatus.Success);
|
||||
}
|
||||
|
||||
var _cmoveStudyRepository = _serviceProvider.GetService<IRepository<CmoveStudy>>();
|
||||
|
||||
#region 判断是否转发第三方影像
|
||||
|
||||
var cmoveInfo = _cmoveStudyRepository.Where(t => t.StudyInstanceUIDList.Any(c => c == studyInstanceUid)).OrderByDescending(t => t.CreateTime).FirstOrDefault();
|
||||
|
||||
//确定是第三方请求
|
||||
if (cmoveInfo != null && cmoveInfo.CallingAE == DicomSCPServiceConfig.ThirdCallningAE)
|
||||
{
|
||||
_isCurrentThirdForward = true;
|
||||
|
||||
var _dicomAERepository = _serviceProvider.GetService<IRepository<DicomAE>>();
|
||||
var hirServer = await _dicomAERepository.FirstOrDefaultAsync(t => t.PacsTypeEnum == PacsType.HIRServer);
|
||||
|
||||
try
|
||||
{
|
||||
// 克隆 Dataset 避免共享引用
|
||||
var dsCopy = request.Dataset?.Clone();
|
||||
|
||||
var forwardRequest = new DicomCStoreRequest(dsCopy);
|
||||
|
||||
|
||||
// 创建客户端连接到目标 PACS
|
||||
var client = DicomClientFactory.Create(DicomSCPServiceConfig.ThirdIP, DicomSCPServiceConfig.THirdPort, false, DicomSCPServiceConfig.CalledAEList.First(), cmoveInfo.DestinationAE);
|
||||
|
||||
// 可以加入 OnResponseReceived 来处理目标 PACS 返回状态
|
||||
forwardRequest.OnResponseReceived += (rq, rp) =>
|
||||
{
|
||||
Log.Logger.Information($"Forwarded C-STORE Response: {rq.SOPInstanceUID} {rp.Status}");
|
||||
};
|
||||
|
||||
await client.AddRequestAsync(forwardRequest);
|
||||
await client.SendAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Logger.Error("Error forwarding C-STORE: " + ex.Message);
|
||||
}
|
||||
|
||||
|
||||
return new DicomCStoreResponse(request, DicomStatus.Success);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
//确保来了影像集合存在
|
||||
if (!_ImageUploadList.Any(t => t.StudyInstanceUid == studyInstanceUid))
|
||||
{
|
||||
|
|
@ -307,7 +376,7 @@ namespace IRaCIS.Core.SCP.Service
|
|||
var _seriesRepository = _serviceProvider.GetService<IRepository<SCPSeries>>();
|
||||
var _studyGroupRepository = _serviceProvider.GetService<IRepository<SCPStudyHospitalGroup>>();
|
||||
|
||||
var _cmoveStudyRepository = _serviceProvider.GetService<IRepository<CmoveStudy>>();
|
||||
|
||||
|
||||
var _distributedLockProvider = _serviceProvider.GetService<IDistributedLockProvider>();
|
||||
|
||||
|
|
|
|||
|
|
@ -24,11 +24,13 @@
|
|||
"Hangfire": "Server=106.14.89.110,1435;Database=Test_HIR_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||
},
|
||||
"DicomSCPServiceConfig": {
|
||||
"IsSupportThirdService": true,
|
||||
"ThirdSearchPacsAE": "ThirdCalledPacsAE",
|
||||
"ThirdCallningAE": "ThirdCallningAE",
|
||||
"ThirdIP": "192.168.3.15",
|
||||
"THirdPort": 112,
|
||||
"CalledAEList": [
|
||||
"STORESCP",
|
||||
"HIRAE",
|
||||
"Value2",
|
||||
"Value3"
|
||||
"HIRAE"
|
||||
],
|
||||
"ServerPort": 11112
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,320 @@
|
|||
using AutoMapper.Execution;
|
||||
using FellowOakDicom;
|
||||
using FellowOakDicom.Network;
|
||||
using FellowOakDicom.Network.Client;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Org.BouncyCastle.Bcpg;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IRaCIS.Core.API.HostService
|
||||
{
|
||||
public class DicomSCPServiceOption
|
||||
{
|
||||
public bool IsSupportThirdService { get; set; }
|
||||
|
||||
public string ThirdSearchPacsAE { get; set; }
|
||||
|
||||
public string ThirdCallningAE { get; set; }
|
||||
|
||||
public List<string> CalledAEList { get; set; }
|
||||
|
||||
public string ServerPort { get; set; }
|
||||
}
|
||||
public class DicomSCPService : DicomService, IDicomServiceProvider, IDicomCFindProvider, IDicomCEchoProvider, IDicomCMoveProvider
|
||||
{
|
||||
|
||||
private static readonly DicomTransferSyntax[] _acceptedTransferSyntaxes = new DicomTransferSyntax[]
|
||||
{
|
||||
DicomTransferSyntax.ExplicitVRLittleEndian,
|
||||
DicomTransferSyntax.ExplicitVRBigEndian,
|
||||
DicomTransferSyntax.ImplicitVRLittleEndian
|
||||
};
|
||||
|
||||
|
||||
private static readonly DicomTransferSyntax[] _acceptedImageTransferSyntaxes = new DicomTransferSyntax[]
|
||||
{
|
||||
// Lossless
|
||||
DicomTransferSyntax.JPEGLSLossless,
|
||||
DicomTransferSyntax.JPEG2000Lossless,
|
||||
DicomTransferSyntax.JPEGProcess14SV1,
|
||||
DicomTransferSyntax.JPEGProcess14,
|
||||
DicomTransferSyntax.RLELossless,
|
||||
|
||||
// Lossy
|
||||
DicomTransferSyntax.JPEGLSNearLossless,
|
||||
DicomTransferSyntax.JPEG2000Lossy,
|
||||
DicomTransferSyntax.JPEGProcess1,
|
||||
DicomTransferSyntax.JPEGProcess2_4,
|
||||
|
||||
// Uncompressed
|
||||
DicomTransferSyntax.ExplicitVRLittleEndian,
|
||||
DicomTransferSyntax.ExplicitVRBigEndian,
|
||||
DicomTransferSyntax.ImplicitVRLittleEndian
|
||||
};
|
||||
|
||||
|
||||
|
||||
private IServiceProvider _serviceProvider { get; set; }
|
||||
|
||||
private DicomSCPServiceOption DicomSCPServiceConfig { get; set; }
|
||||
|
||||
|
||||
public string CallingAE { get; protected set; }
|
||||
public string CalledAE { get; protected set; }
|
||||
|
||||
public DicomSCPService(INetworkStream stream, Encoding fallbackEncoding, Microsoft.Extensions.Logging.ILogger log, DicomServiceDependencies dependencies, IServiceProvider injectServiceProvider)
|
||||
: base(stream, fallbackEncoding, log, dependencies)
|
||||
{
|
||||
_serviceProvider = injectServiceProvider.CreateScope().ServiceProvider;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void OnConnectionClosed(Exception exception)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void OnReceiveAbort(DicomAbortSource source, DicomAbortReason reason)
|
||||
{
|
||||
Logger.LogError($"Received abort from {source}, reason is {reason}");
|
||||
}
|
||||
|
||||
public Task OnReceiveAssociationReleaseRequestAsync()
|
||||
{
|
||||
return SendAssociationReleaseResponseAsync();
|
||||
}
|
||||
|
||||
public Task OnReceiveAssociationRequestAsync(DicomAssociation association)
|
||||
{
|
||||
CallingAE = association.CallingAE;
|
||||
CalledAE = association.CalledAE;
|
||||
|
||||
Logger.LogInformation($"Received association request from AE: {CallingAE} with IP: {association.RemoteHost} ");
|
||||
|
||||
DicomSCPServiceConfig = _serviceProvider.GetService<IOptionsMonitor<DicomSCPServiceOption>>().CurrentValue;
|
||||
var calledAEList = DicomSCPServiceConfig.CalledAEList;
|
||||
|
||||
//不支持三方服务 或者CallAE不对,那么拒绝连接
|
||||
if (!calledAEList.Contains(CalledAE) || DicomSCPServiceConfig.IsSupportThirdService == false || CallingAE != DicomSCPServiceConfig.ThirdCallningAE)
|
||||
{
|
||||
Logger.LogError($"Association with {CallingAE} rejected since called aet {CalledAE} is unknown");
|
||||
return SendAssociationRejectAsync(DicomRejectResult.Permanent, DicomRejectSource.ServiceUser, DicomRejectReason.CalledAENotRecognized);
|
||||
}
|
||||
|
||||
foreach (var pc in association.PresentationContexts)
|
||||
{
|
||||
if (pc.AbstractSyntax == DicomUID.Verification
|
||||
|| pc.AbstractSyntax == DicomUID.PatientRootQueryRetrieveInformationModelFind
|
||||
|| pc.AbstractSyntax == DicomUID.PatientRootQueryRetrieveInformationModelMove
|
||||
|| pc.AbstractSyntax == DicomUID.StudyRootQueryRetrieveInformationModelFind
|
||||
|| pc.AbstractSyntax == DicomUID.StudyRootQueryRetrieveInformationModelMove)
|
||||
{
|
||||
pc.AcceptTransferSyntaxes(_acceptedTransferSyntaxes);
|
||||
}
|
||||
else if (pc.AbstractSyntax == DicomUID.PatientRootQueryRetrieveInformationModelGet
|
||||
|| pc.AbstractSyntax == DicomUID.StudyRootQueryRetrieveInformationModelGet)
|
||||
{
|
||||
pc.AcceptTransferSyntaxes(_acceptedImageTransferSyntaxes);
|
||||
}
|
||||
else if (pc.AbstractSyntax.StorageCategory != DicomStorageCategory.None)
|
||||
{
|
||||
pc.AcceptTransferSyntaxes(_acceptedImageTransferSyntaxes);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogWarning($"Requested abstract syntax {pc.AbstractSyntax} from {CallingAE} not supported");
|
||||
pc.SetResult(DicomPresentationContextResult.RejectAbstractSyntaxNotSupported);
|
||||
}
|
||||
}
|
||||
|
||||
Logger.LogInformation($"Accepted association request from {CallingAE}");
|
||||
return SendAssociationAcceptAsync(association);
|
||||
}
|
||||
|
||||
public Task<DicomCEchoResponse> OnCEchoRequestAsync(DicomCEchoRequest request)
|
||||
{
|
||||
Logger.LogInformation("Received verification request from AE {0} with IP: {1}", CallingAE, Association.RemoteHost);
|
||||
return Task.FromResult(new DicomCEchoResponse(request, DicomStatus.Success));
|
||||
}
|
||||
public async IAsyncEnumerable<DicomCFindResponse> OnCFindRequestAsync(DicomCFindRequest request)
|
||||
{
|
||||
Console.WriteLine("Received C-FIND request, forwarding to real PACS...");
|
||||
|
||||
var _dicomAERepository = _serviceProvider.GetService<IRepository<DicomAE>>();
|
||||
|
||||
var find = await _dicomAERepository.FirstOrDefaultAsync(t => t.PacsTypeEnum == PacsType.PacsServer && t.CalledAE == DicomSCPServiceConfig.ThirdSearchPacsAE);
|
||||
|
||||
var hirClient = await _dicomAERepository.FirstOrDefaultAsync(t => t.PacsTypeEnum == PacsType.HIRClient);
|
||||
|
||||
|
||||
if (find == null || hirClient == null)
|
||||
{
|
||||
Logger.LogInformation("客户端和Pacs配置未查询到");
|
||||
}
|
||||
|
||||
|
||||
// 创建 channel 用于异步传递响应
|
||||
var channel = Channel.CreateUnbounded<DicomCFindResponse>();
|
||||
|
||||
// 克隆 dataset 避免线程/状态冲突
|
||||
var clonedDataset = request.Dataset?.Clone() ?? new DicomDataset();
|
||||
var forward = new DicomCFindRequest(request.SOPClassUID, request.Level)
|
||||
{
|
||||
Dataset = clonedDataset
|
||||
};
|
||||
|
||||
// 标记是否已收到 final 状态(Success/Failure/Cancel)
|
||||
var finalReceived = false;
|
||||
|
||||
// 当远端 PACS 返回响应时,异步写入 channel
|
||||
forward.OnResponseReceived += (rq, rp) =>
|
||||
{
|
||||
var dsCopy = rp.Dataset?.Clone();
|
||||
var proxyResp = new DicomCFindResponse(request, rp.Status)
|
||||
{
|
||||
Dataset = dsCopy
|
||||
};
|
||||
channel.Writer.TryWrite(proxyResp);
|
||||
|
||||
if (!rp.Status.Equals(DicomStatus.Pending))
|
||||
{
|
||||
finalReceived = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 异步发送到真实 PACS
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var client = DicomClientFactory.Create(find.IP, find.Port, false, hirClient.CalledAE, find.CalledAE);
|
||||
await client.AddRequestAsync(forward);
|
||||
await client.SendAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error forwarding C-FIND: " + ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
channel.Writer.Complete();
|
||||
}
|
||||
});
|
||||
|
||||
// 异步 yield 返回给上游
|
||||
await foreach (var resp in channel.Reader.ReadAllAsync())
|
||||
{
|
||||
yield return resp;
|
||||
}
|
||||
|
||||
// 兜底:如果没有 final 响应,返回 Success
|
||||
if (!finalReceived)
|
||||
{
|
||||
yield return new DicomCFindResponse(request, DicomStatus.Success);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public async IAsyncEnumerable<DicomCMoveResponse> OnCMoveRequestAsync(DicomCMoveRequest request)
|
||||
{
|
||||
Console.WriteLine("Received C-Move request, forwarding to real PACS...");
|
||||
|
||||
var _dicomAERepository = _serviceProvider.GetService<IRepository<DicomAE>>();
|
||||
var _cmoveStudyRepository = _serviceProvider.GetService<IRepository<CmoveStudy>>();
|
||||
|
||||
var find = await _dicomAERepository.FirstOrDefaultAsync(t => t.PacsTypeEnum == PacsType.PacsServer && t.CalledAE == DicomSCPServiceConfig.ThirdSearchPacsAE);
|
||||
|
||||
|
||||
var hirServer = await _dicomAERepository.FirstOrDefaultAsync(t => t.PacsTypeEnum == PacsType.HIRServer);
|
||||
|
||||
var hirClient = await _dicomAERepository.FirstOrDefaultAsync(t => t.PacsTypeEnum == PacsType.HIRClient);
|
||||
|
||||
|
||||
if (find == null || hirClient == null || hirServer == null)
|
||||
{
|
||||
Logger.LogInformation("客户端和Pacs配置未查询到");
|
||||
}
|
||||
|
||||
var studyInstanceUid = request.Dataset?.GetSingleValueOrDefault(DicomTag.StudyInstanceUID, string.Empty);
|
||||
|
||||
if (studyInstanceUid.IsNotNullOrEmpty())
|
||||
{
|
||||
await _cmoveStudyRepository.AddAsync(new CmoveStudy() { CallingAE = CallingAE, CalledAE = CalledAE, DestinationAE = request.DestinationAE, StudyInstanceUIDList = new List<string>() { studyInstanceUid }, HopitalGroupIdList = new List<Guid>() }, true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
var channel = Channel.CreateUnbounded<DicomCMoveResponse>();
|
||||
var clonedDataset = request.Dataset?.Clone() ?? new DicomDataset();
|
||||
var forward = new DicomCMoveRequest(hirServer.CalledAE, studyInstanceUid)
|
||||
{
|
||||
Dataset = clonedDataset
|
||||
};
|
||||
|
||||
bool finalReceived = false;
|
||||
|
||||
// PACS 返回响应时写入 channel
|
||||
forward.OnResponseReceived += (rq, rp) =>
|
||||
{
|
||||
var dsCopy = rp.Dataset?.Clone();
|
||||
var proxyResp = new DicomCMoveResponse(request, rp.Status)
|
||||
{
|
||||
Dataset = dsCopy,
|
||||
Remaining = rp.Remaining,
|
||||
Completed = rp.Completed,
|
||||
|
||||
};
|
||||
channel.Writer.TryWrite(proxyResp);
|
||||
|
||||
if (!rp.Status.Equals(DicomStatus.Pending))
|
||||
{
|
||||
finalReceived = true;
|
||||
}
|
||||
};
|
||||
|
||||
// 异步发送到真实 PACS
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var client = DicomClientFactory.Create(find.IP, find.Port, false, hirClient.CalledAE, find.CalledAE);
|
||||
await client.AddRequestAsync(forward);
|
||||
await client.SendAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error forwarding C-MOVE: " + ex.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
channel.Writer.Complete();
|
||||
}
|
||||
});
|
||||
|
||||
// 异步 yield 回上游
|
||||
await foreach (var resp in channel.Reader.ReadAllAsync())
|
||||
{
|
||||
yield return resp;
|
||||
}
|
||||
|
||||
// 兜底
|
||||
if (!finalReceived)
|
||||
{
|
||||
yield return new DicomCMoveResponse(request, DicomStatus.Success);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
using IRaCIS.Core.API;
|
||||
using FellowOakDicom.Network;
|
||||
using FellowOakDicom;
|
||||
using IRaCIS.Core.API;
|
||||
using IRaCIS.Core.API.HostService;
|
||||
using IRaCIS.Core.Application.BusinessFilter;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
|
|
@ -126,7 +128,7 @@ builder.Services.AddhangfireSetup(_configuration);
|
|||
|
||||
|
||||
//Dicom影像渲染图片 跨平台
|
||||
builder.Services.AddDicomSetup();
|
||||
//builder.Services.AddDicomSetup();
|
||||
|
||||
// 实时应用
|
||||
builder.Services.AddSignalR();
|
||||
|
|
@ -272,6 +274,13 @@ try
|
|||
//Log.Logger.Warning($"ContentRootPath——xx:{Path.GetDirectoryName(Path.GetDirectoryName(env.ContentRootPath))}");
|
||||
#endregion
|
||||
|
||||
|
||||
DicomSetupBuilder.UseServiceProvider(app.Services);
|
||||
|
||||
var logger = app.Services.GetService<Microsoft.Extensions.Logging.ILogger<Program>>();
|
||||
|
||||
var server = DicomServerFactory.Create<DicomSCPService>(_configuration.GetSection("DicomSCPServiceConfig").GetValue<int>("ServerPort"), userState: app.Services, logger: logger);
|
||||
|
||||
app.Run();
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -53,5 +53,15 @@
|
|||
"AuthorizationCode": "zhanying123",
|
||||
"SiteUrl": "http://hir.test.extimaging.com/login",
|
||||
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
|
||||
},
|
||||
"DicomSCPServiceConfig": {
|
||||
"IsSupportThirdService": true,
|
||||
"ThirdSearchPacsAE": "ThirdCalledPacsAE",
|
||||
"ThirdCallningAE": "ThirdCallningAE",
|
||||
"CalledAEList": [
|
||||
"HIRSCU",
|
||||
"HIRSCPAE"
|
||||
],
|
||||
"ServerPort": 11112
|
||||
}
|
||||
}
|
||||
|
|
@ -229,5 +229,9 @@ namespace IRaCIS.Core.Domain.Models
|
|||
public List<Guid> HopitalGroupIdList { get; set; }
|
||||
|
||||
|
||||
[Comment("CStore-转发到目的地AE")]
|
||||
public string DestinationAE { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
19233
IRaCIS.Core.Infra.EFCore/Migrations/20251027063221_cstoreAddFiled.Designer.cs
generated
Normal file
19233
IRaCIS.Core.Infra.EFCore/Migrations/20251027063221_cstoreAddFiled.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,31 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace IRaCIS.Core.Infra.EFCore.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class cstoreAddFiled : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "DestinationAE",
|
||||
table: "CmoveStudy",
|
||||
type: "nvarchar(400)",
|
||||
maxLength: 400,
|
||||
nullable: false,
|
||||
defaultValue: "",
|
||||
comment: "CStore-转发到目的地AE");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "DestinationAE",
|
||||
table: "CmoveStudy");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -514,6 +514,12 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
|||
b.Property<Guid>("CreateUserId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<string>("DestinationAE")
|
||||
.IsRequired()
|
||||
.HasMaxLength(400)
|
||||
.HasColumnType("nvarchar(400)")
|
||||
.HasComment("CStore-转发到目的地AE");
|
||||
|
||||
b.Property<string>("HopitalGroupIdList")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
|
|
|||
Loading…
Reference in New Issue