From fdaf7180c0330be0490463092344bc0ed8f9d14c Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Fri, 15 May 2026 18:06:35 +0800
Subject: [PATCH 01/21] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8C=BB=E5=AD=A6?=
=?UTF-8?q?=E5=AE=A1=E6=A0=B8=E5=88=A4=E6=96=AD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Service/Document/TrialEmailNoticeConfigService.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs b/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs
index 2ddbfada5..fd5e34832 100644
--- a/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs
+++ b/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs
@@ -138,7 +138,7 @@ namespace IRaCIS.Core.Application.Service
var isNeedSend = true;
//手动发送的时候,也有可能答案是是 此时是 这里不发送,发送已经生成的文件
- if (answer == "是" && isHandSend == null)
+ if ((answer == "是" || answer == "Yes") && isHandSend == null)
{
isNeedSend = true;
@@ -1183,7 +1183,7 @@ x.ReadingTableQuestionTrial.QuestionMark == QuestionMark.LesionNumber && x.Readi
///
///
///
- private async Task TranslatePdStateAsync(Guid visitTaskId, ReadingCategory readingCategory, CriterionType criterionType, UserWorkLanguage userWorkLanguage, bool? IsGlobalGenerate = null )
+ private async Task TranslatePdStateAsync(Guid visitTaskId, ReadingCategory readingCategory, CriterionType criterionType, UserWorkLanguage userWorkLanguage, bool? IsGlobalGenerate = null)
{
var answer = string.Empty;
From c4570ebe625849cade07fc2efb6eafa110464b03 Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Mon, 18 May 2026 15:33:09 +0800
Subject: [PATCH 02/21] =?UTF-8?q?=E4=BF=AE=E6=94=B9SCP=E6=9C=8D=E5=8A=A1?=
=?UTF-8?q?=E5=90=8C=E6=AD=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
IRC.Core.SCP/Service/FileUploadRecordService.cs | 10 +++++++---
IRC.Core.SCP/Service/OSSService.cs | 2 +-
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/IRC.Core.SCP/Service/FileUploadRecordService.cs b/IRC.Core.SCP/Service/FileUploadRecordService.cs
index 3d4ff7880..831d884e7 100644
--- a/IRC.Core.SCP/Service/FileUploadRecordService.cs
+++ b/IRC.Core.SCP/Service/FileUploadRecordService.cs
@@ -63,6 +63,8 @@ public class FileUploadRecordAddOrEdit
public bool? IsNeedSync { get; set; }
public string UploadRegion { get; set; }
public string TargetRegion { get; set; }
+
+ public bool? IsSync { get; set; }
}
public interface IFileUploadRecordService
{
@@ -129,9 +131,9 @@ public class FileUploadRecordService(IRepository _fileUploadRe
{
addOrEditFileUploadRecord.IsNeedSync = true;
- addOrEditFileUploadRecord.Priority = 0;
-
+ addOrEditFileUploadRecord.Priority = addOrEditFileUploadRecord.Priority ?? 0;
+ addOrEditFileUploadRecord.IsSync = false;
}
else
{
@@ -147,7 +149,9 @@ public class FileUploadRecordService(IRepository _fileUploadRe
//系统文件,默认同步
addOrEditFileUploadRecord.IsNeedSync = true;
- addOrEditFileUploadRecord.Priority = 0;
+ addOrEditFileUploadRecord.IsSync = false;
+
+ addOrEditFileUploadRecord.Priority = addOrEditFileUploadRecord.Priority ?? 0;
}
var entity = await _fileUploadRecordRepository.InsertOrUpdateAsync(addOrEditFileUploadRecord, true);
diff --git a/IRC.Core.SCP/Service/OSSService.cs b/IRC.Core.SCP/Service/OSSService.cs
index 7657d8c51..962c86581 100644
--- a/IRC.Core.SCP/Service/OSSService.cs
+++ b/IRC.Core.SCP/Service/OSSService.cs
@@ -828,7 +828,7 @@ public class OSSService(IOptionsMonitor options,
uploadInfo.FileSize = fileStream.CanSeek ? fileStream.Length : 0;
uploadInfo.Path = returnPath;
uploadInfo.FileName = fileRealName;
- uploadInfo.FileType = Path.GetExtension(returnPath);
+ uploadInfo.FileType = Path.GetExtension(returnPath).TrimStart('.');
await _fileUploadRecordService.AddOrUpdateFileUploadRecord(uploadInfo);
From ad5c36930eb31f95649ebaaf4b14e42d5abdffc3 Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Mon, 18 May 2026 16:22:04 +0800
Subject: [PATCH 03/21] =?UTF-8?q?=E4=BF=AE=E6=94=B9SCP=E6=9C=8D=E5=8A=A1?=
=?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
IRC.Core.SCP/appsettings.Test_IRC_SCP.json | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/IRC.Core.SCP/appsettings.Test_IRC_SCP.json b/IRC.Core.SCP/appsettings.Test_IRC_SCP.json
index 022a47cd3..f2415cb51 100644
--- a/IRC.Core.SCP/appsettings.Test_IRC_SCP.json
+++ b/IRC.Core.SCP/appsettings.Test_IRC_SCP.json
@@ -7,7 +7,28 @@
}
},
"ObjectStoreService": {
+ // 使用的对象存储服务类型
"ObjectStoreUse": "AliyunOSS",
+ "IsOpenStoreSync": true,
+ "ApiDeployRegion": "CN",
+ "SyncConfigList": [
+ {
+ "Domain": "irc.test.extimaging.com",
+ "Primary": "AliyunOSS",
+ "Target": "AWS",
+ "UploadRegion": "CN",
+ "TargetRegion": "US",
+ "IsOpenSync": true
+ },
+ {
+ "Domain": "lili.test.extimaging.com",
+ "Primary": "AWS",
+ "Target": "AliyunOSS",
+ "UploadRegion": "US",
+ "TargetRegion": "CN",
+ "IsOpenSync": true
+ }
+ ],
"AliyunOSS": {
"RegionId": "cn-shanghai",
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
From 592de4deb4088ddfbea32a9cb47ee9b98d699dbe Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Mon, 18 May 2026 16:53:26 +0800
Subject: [PATCH 04/21] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=90=8C=E6=AD=A5?=
=?UTF-8?q?=E9=85=8D=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
IRC.Core.SCP/Service/OSSService.cs | 129 +++++++++++++++------
IRC.Core.SCP/Service/_MapConfig.cs | 16 +++
IRC.Core.SCP/appsettings.Test_IRC_SCP.json | 21 ++++
3 files changed, 130 insertions(+), 36 deletions(-)
create mode 100644 IRC.Core.SCP/Service/_MapConfig.cs
diff --git a/IRC.Core.SCP/Service/OSSService.cs b/IRC.Core.SCP/Service/OSSService.cs
index 962c86581..df4f5cb39 100644
--- a/IRC.Core.SCP/Service/OSSService.cs
+++ b/IRC.Core.SCP/Service/OSSService.cs
@@ -194,7 +194,7 @@ public interface IOSSService
List GetRootFolderNames();
- public ObjectStoreDTO GetObjectStoreTempToken(string? domain = null, bool? isGetAllTempToken = null);
+ public ObjectStoreDTO GetObjectStoreTempToken(string? domain = null, bool? isGetAllTempToken = null, string? objectUse = null);
public Task MoveObject(string sourcePath, string destPath, bool overwrite = true);
@@ -1856,23 +1856,39 @@ public class OSSService(IOptionsMonitor options,
- public ObjectStoreDTO GetObjectStoreTempToken(string? domain = null, bool? isGetAllTempToken = null)
+ public ObjectStoreDTO GetObjectStoreTempToken(string? domain = null, bool? isGetAllTempToken = null, string? objectUse = null)
{
- //如果传递了域名,并且打开了存储同步,根据域名使用的具体存储覆盖之前的配置,否则就用固定的配置
- if (ObjectStoreServiceOptions.IsOpenStoreSync && domain.IsNotNullOrEmpty())
+ string objectStoreUse = string.Empty;
+ //使用指定配置
+ if (objectUse != null)
{
- var userDomain = domain?.Trim();
-
- var find = ObjectStoreServiceOptions.SyncConfigList.FirstOrDefault(t => t.Domain == userDomain);
- if (find != null)
+ objectStoreUse = objectUse?.Trim() ?? string.Empty;
+ }
+ //根据域名动态判断
+ else
+ {
+ //如果传递了域名,并且打开了存储同步,根据域名使用的具体存储覆盖之前的配置,否则就用固定的配置
+ if (ObjectStoreServiceOptions.IsOpenStoreSync && domain.IsNotNullOrEmpty() && ObjectStoreServiceOptions.SyncConfigList.Any(t => t.Domain == domain))
{
- ObjectStoreServiceOptions.ObjectStoreUse = find.Primary;
+
+ var find = ObjectStoreServiceOptions.SyncConfigList.FirstOrDefault(t => t.Domain == domain);
+ if (find != null)
+ {
+ objectStoreUse = find.Primary;
+ }
+
+ }
+ else
+ {
+ //兜底,如果是本地测试环境,那就使用部署默认配置
+ objectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse;
}
}
- var objectStoreDTO = new ObjectStoreDTO() { ObjectStoreUse = ObjectStoreServiceOptions.ObjectStoreUse, IsOpenStoreSync = ObjectStoreServiceOptions.IsOpenStoreSync, SyncConfigList = ObjectStoreServiceOptions.SyncConfigList };
- if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS" || isGetAllTempToken == true)
+ var objectStoreDTO = new ObjectStoreDTO() { ObjectStoreUse = objectStoreUse, IsOpenStoreSync = ObjectStoreServiceOptions.IsOpenStoreSync, SyncConfigList = ObjectStoreServiceOptions.SyncConfigList };
+
+ if (objectStoreUse == "AliyunOSS" || isGetAllTempToken == true)
{
var ossOptions = ObjectStoreServiceOptions.AliyunOSS;
@@ -1920,11 +1936,11 @@ public class OSSService(IOptionsMonitor options,
objectStoreDTO.AliyunOSS = tempToken;
}
- else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
+ if (objectStoreUse == "MinIO")
{
objectStoreDTO.MinIO = ObjectStoreServiceOptions.MinIO;
}
- else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS" || isGetAllTempToken == true)
+ if (objectStoreUse == "AWS" || isGetAllTempToken == true)
{
var awsOptions = ObjectStoreServiceOptions.AWS;
@@ -1969,7 +1985,8 @@ public class OSSService(IOptionsMonitor options,
objectStoreDTO.AWS = tempToken;
}
- else
+
+ if (objectStoreUse.IsNullOrEmpty())
{
throw new BusinessValidationFailedException("未定义的存储介质类型");
}
@@ -1980,7 +1997,7 @@ public class OSSService(IOptionsMonitor options,
public async Task SyncFileAsync(string objectKey, ObjectStoreUse source, ObjectStoreUse destination, CancellationToken ct = default)
{
- GetObjectStoreTempToken(isGetAllTempToken: true);
+ var tempConfig = GetObjectStoreTempToken(isGetAllTempToken: true);
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
@@ -1999,36 +2016,76 @@ public class OSSService(IOptionsMonitor options,
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
+ // ⭐ 关键变量
+ IDisposable? owner = null;
+ Stream sourceStream;
+ long contentLength;
- // 根据源选择流式下载
- Stream sourceStream = source switch
+ // ========= 获取流 + 长度 =========
+ switch (source)
{
- ObjectStoreUse.AliyunOSS => _ossClient.GetObject(aliConfig.BucketName, objectKey).Content,
- ObjectStoreUse.AWS => (await amazonS3Client.GetObjectAsync(awsConfig.BucketName, objectKey, ct)).ResponseStream,
- _ => throw new BusinessValidationFailedException("未定义的同步类型")
- };
+ case ObjectStoreUse.AliyunOSS:
+ {
- if (source == ObjectStoreUse.AliyunOSS)
+ var obj = _ossClient.GetObject(
+ aliConfig.BucketName,
+ objectKey);
+
+ owner = obj;
+ sourceStream = obj.Content;
+ contentLength = obj.ContentLength;
+ break;
+ }
+
+ case ObjectStoreUse.AWS:
+ {
+ var response = await amazonS3Client.GetObjectAsync(
+ awsConfig.BucketName,
+ objectKey,
+ ct);
+
+ owner = response;
+ sourceStream = response.ResponseStream;
+ contentLength = response.Headers.ContentLength;
+ break;
+ }
+
+ default:
+ throw new BusinessValidationFailedException("未定义的同步类型");
+ }
+
+ try
{
- var putRequest = new Amazon.S3.Model.PutObjectRequest
+ // ========= 上传 =========
+ if (destination == ObjectStoreUse.AWS)
{
- BucketName = awsConfig.BucketName,
- Key = objectKey,
- InputStream = sourceStream
- };
+ var putRequest = new Amazon.S3.Model.PutObjectRequest
+ {
+ BucketName = awsConfig.BucketName,
+ Key = objectKey,
+ InputStream = sourceStream,
+ Headers = { ContentLength = contentLength }
+ };
- await amazonS3Client.PutObjectAsync(putRequest, ct);
+ await amazonS3Client.PutObjectAsync(putRequest, ct);
+ }
+ else if (destination == ObjectStoreUse.AliyunOSS)
+ {
+ _ossClient.PutObject(
+ aliConfig.BucketName,
+ objectKey,
+ sourceStream);
+ }
+ else
+ {
+ throw new BusinessValidationFailedException("未定义的同步类型");
+ }
}
- else if (source == ObjectStoreUse.AWS)
+ finally
{
- _ossClient.PutObject(aliConfig.BucketName, objectKey, sourceStream);
+ // ⭐⭐⭐ 真正释放 HTTP 连接
+ owner?.Dispose();
}
- else
- {
- throw new BusinessValidationFailedException("未定义的同步类型");
- }
-
- await sourceStream.DisposeAsync(); // 释放流
}
}
diff --git a/IRC.Core.SCP/Service/_MapConfig.cs b/IRC.Core.SCP/Service/_MapConfig.cs
new file mode 100644
index 000000000..d61e18c25
--- /dev/null
+++ b/IRC.Core.SCP/Service/_MapConfig.cs
@@ -0,0 +1,16 @@
+using AutoMapper;
+using IRaCIS.Core.Domain.Models;
+using IRaCIS.Core.SCP.Service;
+
+
+namespace IRaCIS.Core.Application.Service
+{
+ public class CommonConfig : Profile
+ {
+ public CommonConfig()
+ {
+ CreateMap().ReverseMap();
+ }
+ }
+
+}
diff --git a/IRC.Core.SCP/appsettings.Test_IRC_SCP.json b/IRC.Core.SCP/appsettings.Test_IRC_SCP.json
index f2415cb51..289de42a4 100644
--- a/IRC.Core.SCP/appsettings.Test_IRC_SCP.json
+++ b/IRC.Core.SCP/appsettings.Test_IRC_SCP.json
@@ -50,6 +50,27 @@
"secretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
"bucketName": "hir-test",
"viewEndpoint": "http://106.14.89.110:9001/hir-test/"
+ },
+ // AWS S3 对象存储服务的配置
+ "AWS": {
+ // AWS S3 的Region
+ "Region": "us-east-1",
+ // AWS S3 的内部访问端点
+ "EndPoint": "s3.us-east-1.amazonaws.com",
+ // 是否使用 SSL
+ "UseSSL": true,
+ // AWS S3 的角色 ARN
+ "RoleArn": "arn:aws:iam::471112624751:role/uat_s3_access",
+ // AWS S3 的访问密钥 ID
+ "AccessKeyId": "AKIAW3MEAFJX7IPXISP4",
+ // AWS S3 的访问密钥 Secret
+ "SecretAccessKey": "Pgrg3le5jPxZQ7MR1yYNS30J0XRyJeKVyIIjElXc",
+ // AWS S3 的Bucket名称
+ "BucketName": "ei-med-s3-lili-uat-store",
+ // AWS S3 的访问端点
+ "ViewEndpoint": "https://ei-med-s3-lili-uat-store.s3.amazonaws.com",
+ // AWS S3 的持续数秒
+ "DurationSeconds": 7200
}
},
From f7bc32ed90a683833f06a988a7270172db3b7129 Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Mon, 18 May 2026 17:13:59 +0800
Subject: [PATCH 05/21] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BB=91=E5=AE=9A?=
=?UTF-8?q?=E9=85=8D=E7=BD=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../IRaCIS.Core.Application.xml | 2 +-
.../Service/Visit/PatientService.cs | 29 ++++++++++++++++---
2 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
index 657a1f9fc..7b1bf3fa3 100644
--- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
+++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml
@@ -15963,7 +15963,7 @@
-
+
提交 患者检查和访视的绑定
diff --git a/IRaCIS.Core.Application/Service/Visit/PatientService.cs b/IRaCIS.Core.Application/Service/Visit/PatientService.cs
index dcfcf84a0..c66066eab 100644
--- a/IRaCIS.Core.Application/Service/Visit/PatientService.cs
+++ b/IRaCIS.Core.Application/Service/Visit/PatientService.cs
@@ -5,6 +5,7 @@ using IRaCIS.Core.Application.Contracts.Dicom.DTO;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure;
+using MassTransit;
using Microsoft.AspNetCore.Mvc;
using Pipelines.Sockets.Unofficial.Arenas;
using System.Linq.Dynamic.Core;
@@ -382,7 +383,8 @@ namespace IRaCIS.Core.Application.Service
public async Task SubmitVisitStudyBinding(SubmitVisitStudyBindingCommand inCommand,
[FromServices] IRepository _dicomstudyRepository,
[FromServices] IRepository _dicomSeriesRepository,
- [FromServices] IRepository _dicomInstanceRepository)
+ [FromServices] IRepository _dicomInstanceRepository,
+ [FromServices] IRepository _fileUploadRecordRepository)
{
//这里要做校验 + 同时验证本地系统里面的影像是否存在pacs推过来的
@@ -403,6 +405,9 @@ namespace IRaCIS.Core.Application.Service
var subjectVisitId = inCommand.SubjectVisitId;
var trialId = inCommand.TrialId;
+ var studyCode = "";
+ var studyUid = "";
+
var @lock = _distributedLockProvider.CreateLock($"StudyCode");
using (await @lock.AcquireAsync())
@@ -430,6 +435,8 @@ namespace IRaCIS.Core.Application.Service
newStuty.SubjectId = subjectId;
newStuty.SubjectVisitId = subjectVisitId;
+ studyCode = newStuty.StudyCode;
+
await _dicomStudyRepository.AddAsync(newStuty);
@@ -457,12 +464,22 @@ namespace IRaCIS.Core.Application.Service
}
await _dicomInstanceRepository.AddRangeAsync(newInstanceList);
+
+
+ //回更StudyCode
+ await _fileUploadRecordRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.Path.Contains(newStuty.StudyInstanceUid), u => new FileUploadRecord() { StudyCode = studyCode });
+
+
+ await _scpPatientRepository.BatchUpdateNoTrackingAsync(t => t.Id == find.SCPStudy.PatientId, u => new SCPPatient() { SubjectId = subjectId });
+ await _scpStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == scpStudyId, u => new SCPStudy() { SubjectVisitId = subjectVisitId });
+
}
+
currentNextCodeInt++;
- await _scpPatientRepository.BatchUpdateNoTrackingAsync(t => t.Id == find.SCPStudy.PatientId, u => new SCPPatient() { SubjectId = subjectId });
- await _scpStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == scpStudyId, u => new SCPStudy() { SubjectVisitId = subjectVisitId });
+
+
}
@@ -549,6 +566,10 @@ namespace IRaCIS.Core.Application.Service
}
}
+
+ //回更StudyCode
+ await _fileUploadRecordRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.Path.Contains(studyu.StudyInstanceUid), u => new FileUploadRecord() { StudyCode = studyCode });
+
await _scpPatientRepository.BatchUpdateNoTrackingAsync(t => t.Id == scpStudy.PatientId, u => new SCPPatient() { SubjectId = subjectId });
await _scpStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == scpStudyId, u => new SCPStudy() { SubjectVisitId = subjectVisitId });
}
@@ -557,7 +578,7 @@ namespace IRaCIS.Core.Application.Service
}
-
+
await _scpStudyRepository.SaveChangesAsync();
From 4a2b9fdb419eb351f0489f7797b32bf44dfeff57 Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Mon, 18 May 2026 17:15:43 +0800
Subject: [PATCH 06/21] =?UTF-8?q?=E8=BE=93=E5=85=A5=E9=94=99=E8=AF=AF?=
=?UTF-8?q?=E4=BF=AE=E6=94=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
IRaCIS.Core.Application/Service/Visit/PatientService.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/IRaCIS.Core.Application/Service/Visit/PatientService.cs b/IRaCIS.Core.Application/Service/Visit/PatientService.cs
index c66066eab..38d1aa768 100644
--- a/IRaCIS.Core.Application/Service/Visit/PatientService.cs
+++ b/IRaCIS.Core.Application/Service/Visit/PatientService.cs
@@ -568,7 +568,7 @@ namespace IRaCIS.Core.Application.Service
//回更StudyCode
- await _fileUploadRecordRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.Path.Contains(studyu.StudyInstanceUid), u => new FileUploadRecord() { StudyCode = studyCode });
+ await _fileUploadRecordRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.Path.Contains(study.StudyInstanceUid), u => new FileUploadRecord() { StudyCode = studyCode });
await _scpPatientRepository.BatchUpdateNoTrackingAsync(t => t.Id == scpStudy.PatientId, u => new SCPPatient() { SubjectId = subjectId });
await _scpStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == scpStudyId, u => new SCPStudy() { SubjectVisitId = subjectVisitId });
From bbe1642786a3a72ac46d29c57f84d75b5f94ce42 Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Mon, 18 May 2026 17:30:22 +0800
Subject: [PATCH 07/21] =?UTF-8?q?=E5=9B=9E=E6=9B=B4=E5=90=8C=E6=AD=A5?=
=?UTF-8?q?=E8=AE=B0=E5=BD=95=E7=9A=84=20subjectId=20svId?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Service/Visit/PatientService.cs | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/IRaCIS.Core.Application/Service/Visit/PatientService.cs b/IRaCIS.Core.Application/Service/Visit/PatientService.cs
index 38d1aa768..80b8057e8 100644
--- a/IRaCIS.Core.Application/Service/Visit/PatientService.cs
+++ b/IRaCIS.Core.Application/Service/Visit/PatientService.cs
@@ -43,7 +43,7 @@ namespace IRaCIS.Core.Application.Service
var instanceList = await _instanceRepository.Where(s => s.StudyId == scpStudyId).OrderBy(t => t.SeriesId).ThenBy(t => t.InstanceNumber)
.ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
- .Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames, t.InstanceNumber,t.FileSize }).ToListAsync();//.GroupBy(u => u.SeriesId);
+ .Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames, t.InstanceNumber, t.FileSize }).ToListAsync();//.GroupBy(u => u.SeriesId);
foreach (var series in seriesList)
{
@@ -56,7 +56,7 @@ namespace IRaCIS.Core.Application.Service
//HtmlPath = string.Empty,
Path = k.Path,
InstanceNumber = k.InstanceNumber,
- FileSize=k.FileSize,
+ FileSize = k.FileSize,
}).ToList();
}
@@ -379,7 +379,7 @@ namespace IRaCIS.Core.Application.Service
///
[HttpPost]
[UnitOfWork]
- [TrialGlobalLimit( "AfterStopCannNotOpt" )]
+ [TrialGlobalLimit("AfterStopCannNotOpt")]
public async Task SubmitVisitStudyBinding(SubmitVisitStudyBindingCommand inCommand,
[FromServices] IRepository _dicomstudyRepository,
[FromServices] IRepository _dicomSeriesRepository,
@@ -467,14 +467,14 @@ namespace IRaCIS.Core.Application.Service
//回更StudyCode
- await _fileUploadRecordRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.Path.Contains(newStuty.StudyInstanceUid), u => new FileUploadRecord() { StudyCode = studyCode });
+ await _fileUploadRecordRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.Path.Contains(newStuty.StudyInstanceUid), u => new FileUploadRecord() { StudyCode = studyCode, SubjectId = newStuty.SubjectId, SubjectVisitId = newStuty.SubjectVisitId });
await _scpPatientRepository.BatchUpdateNoTrackingAsync(t => t.Id == find.SCPStudy.PatientId, u => new SCPPatient() { SubjectId = subjectId });
await _scpStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == scpStudyId, u => new SCPStudy() { SubjectVisitId = subjectVisitId });
}
-
+
currentNextCodeInt++;
@@ -568,7 +568,7 @@ namespace IRaCIS.Core.Application.Service
//回更StudyCode
- await _fileUploadRecordRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.Path.Contains(study.StudyInstanceUid), u => new FileUploadRecord() { StudyCode = studyCode });
+ await _fileUploadRecordRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.Path.Contains(study.StudyInstanceUid), u => new FileUploadRecord() { StudyCode = studyCode, SubjectId = study.SubjectId, SubjectVisitId = study.SubjectVisitId });
await _scpPatientRepository.BatchUpdateNoTrackingAsync(t => t.Id == scpStudy.PatientId, u => new SCPPatient() { SubjectId = subjectId });
await _scpStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == scpStudyId, u => new SCPStudy() { SubjectVisitId = subjectVisitId });
@@ -578,7 +578,7 @@ namespace IRaCIS.Core.Application.Service
}
-
+
await _scpStudyRepository.SaveChangesAsync();
From 80b3defd374c3fa89d3a04922b5f65e454ae8e5d Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Mon, 18 May 2026 17:57:10 +0800
Subject: [PATCH 08/21] =?UTF-8?q?=E4=BB=8Epacs=20=E6=B7=BB=E5=8A=A0?=
=?UTF-8?q?=E6=A3=80=E6=9F=A5=E4=BF=AE=E6=94=B9=E9=A1=B9=E7=9B=AE=E6=A3=80?=
=?UTF-8?q?=E6=9F=A5=E6=9C=80=E5=A4=A7=E7=BC=96=E5=8F=B7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
IRaCIS.Core.Application/Service/Visit/PatientService.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/IRaCIS.Core.Application/Service/Visit/PatientService.cs b/IRaCIS.Core.Application/Service/Visit/PatientService.cs
index 80b8057e8..026b02280 100644
--- a/IRaCIS.Core.Application/Service/Visit/PatientService.cs
+++ b/IRaCIS.Core.Application/Service/Visit/PatientService.cs
@@ -412,7 +412,7 @@ namespace IRaCIS.Core.Application.Service
using (await @lock.AcquireAsync())
{
- var dbStudyCodeIntMax = _dicomStudyRepository.Where(s => s.TrialId == inCommand.TrialId).Select(t => t.Code).DefaultIfEmpty().Max();
+ var dbStudyCodeIntMax = _trialRepository.Where(s => s.Id == trialId, ignoreQueryFilters: true).Select(t => t.MaxDicomCode).DefaultIfEmpty().Max();
int currentNextCodeInt = dbStudyCodeIntMax + 1;
@@ -469,7 +469,7 @@ namespace IRaCIS.Core.Application.Service
//回更StudyCode
await _fileUploadRecordRepository.BatchUpdateNoTrackingAsync(t => t.TrialId == trialId && t.Path.Contains(newStuty.StudyInstanceUid), u => new FileUploadRecord() { StudyCode = studyCode, SubjectId = newStuty.SubjectId, SubjectVisitId = newStuty.SubjectVisitId });
-
+ await _trialRepository.BatchUpdateNoTrackingAsync(t => t.Id == trialId, u => new Trial() { MaxDicomCode = currentNextCodeInt });
await _scpPatientRepository.BatchUpdateNoTrackingAsync(t => t.Id == find.SCPStudy.PatientId, u => new SCPPatient() { SubjectId = subjectId });
await _scpStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == scpStudyId, u => new SCPStudy() { SubjectVisitId = subjectVisitId });
From caffff259eaecbe2d11c247b430df4cc394aab06 Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Tue, 19 May 2026 10:10:59 +0800
Subject: [PATCH 09/21] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=A3=80=E6=9F=A5?=
=?UTF-8?q?=E4=B8=8D=E5=88=A0=E9=99=A4pacs=E6=8E=A8=E9=80=81=E8=BF=87?=
=?UTF-8?q?=E6=9D=A5=E7=9A=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
IRC.Core.SCP/Service/CStoreSCPService.cs | 5 +++--
.../Service/QC/QCOperationService.cs | 16 ++++++++--------
2 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/IRC.Core.SCP/Service/CStoreSCPService.cs b/IRC.Core.SCP/Service/CStoreSCPService.cs
index 9c1fecab5..e7c4f18f9 100644
--- a/IRC.Core.SCP/Service/CStoreSCPService.cs
+++ b/IRC.Core.SCP/Service/CStoreSCPService.cs
@@ -8,6 +8,7 @@ using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure;
using IRaCIS.Core.Infrastructure.Extention;
using IRaCIS.Core.SCP.Service;
+using MassTransit;
using Medallion.Threading;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal;
using Microsoft.Extensions.DependencyInjection;
@@ -95,7 +96,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 };
+ _upload = new SCPImageUpload() { Id = NewId.NextSequentialGuid(), StartTime = DateTime.Now, CallingAE = association.CallingAE, CalledAE = association.CalledAE, CallingAEIP = association.RemoteHost };
Log.Logger.Warning($"接收到来自{association.CallingAE}的连接");
@@ -644,7 +645,7 @@ namespace IRaCIS.Core.SCP.Service
ms.Position = 0;
//irc 从路径最后一截取Guid
- storeRelativePath = await ossService.UploadToOSSAsync(ms, ossFolderPath, instanceId.ToString(), false, uploadInfo: new FileUploadRecordAddOrEdit() { TrialId = _trialId, BatchDataType = BatchDataType.PACSReceive });
+ storeRelativePath = await ossService.UploadToOSSAsync(ms, ossFolderPath, instanceId.ToString(), false, uploadInfo: new FileUploadRecordAddOrEdit() { TrialId = _trialId, BatchDataType = BatchDataType.PACSReceive, UploadBatchId = _upload.Id.ToString() });
fileSize = ms.Length;
diff --git a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs
index b4c2e1982..023e3f15c 100644
--- a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs
+++ b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs
@@ -1111,12 +1111,12 @@ namespace IRaCIS.Core.Application.Image.QA
var visit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId);
- var isExistStudyClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(t => t.TrialId == visit.TrialId && t.ClinicalDataLevel == ClinicalLevel.Study&&t.IsConfirm&&t.IsApply);
- if(isExistStudyClinicalData)
+ var isExistStudyClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(t => t.TrialId == visit.TrialId && t.ClinicalDataLevel == ClinicalLevel.Study && t.IsConfirm && t.IsApply);
+ if (isExistStudyClinicalData)
{
List modalitieTypes = new List() { "PT、CT", "CT、PT", "PET-CT" };
- var studyList=await _dicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId&& modalitieTypes.Contains(t.Modalities)).ProjectTo(_mapper.ConfigurationProvider).ToListAsync();
+ var studyList = await _dicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId && modalitieTypes.Contains(t.Modalities)).ProjectTo(_mapper.ConfigurationProvider).ToListAsync();
if (studyList.Any(x => x.IsHasEmptyPatientInfo))
{
return ResponseOutput.NotOk(_localizer["QCOperation_IsHasEmptyPatientInfo"]);
@@ -1189,7 +1189,7 @@ namespace IRaCIS.Core.Application.Image.QA
await _scpStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == id, u => new SCPStudy() { SubjectVisitId = null });
- if (fisrtPath.IsNotNullOrEmpty())
+ if (fisrtPath.IsNotNullOrEmpty() && study.IsFromPACS == false)
{
var prefix = fisrtPath.Substring(1, fisrtPath.LastIndexOf('/') - 1);
@@ -1230,7 +1230,7 @@ namespace IRaCIS.Core.Application.Image.QA
string cacheKey = CacheKeys.UserQCSkipTask(_userInfo.UserRoleId);
-
+
await _fusionCache.SetAsync(cacheKey, new List(), TimeSpan.FromMinutes(60));
return ResponseOutput.Ok();
@@ -1393,12 +1393,12 @@ namespace IRaCIS.Core.Application.Image.QA
// 获取当前缓存中的访视Id集合(如果没有则创建空集合)
- var skippedVisits = await _fusionCache.GetOrDefaultAsync>(CacheKeys.UserQCSkipTask(_userInfo.UserRoleId), new List() { });
+ var skippedVisits = await _fusionCache.GetOrDefaultAsync>(CacheKeys.UserQCSkipTask(_userInfo.UserRoleId), new List() { });
//跳过当前访视
if (inDto.IsSkipCurrentVisit)
{
skippedVisits.Add(inDto.SubjectVisitId);
-
+
currentActionList = currentActionList.Where(t => !skippedVisits.Contains(t.SubjectVisitId)).ToList();
}
@@ -1449,7 +1449,7 @@ namespace IRaCIS.Core.Application.Image.QA
//跳过当前访视
if (inDto.IsSkipCurrentVisit)
- {
+ {
visitList = visitList.Where(t => !skippedVisits.Contains(t.SubjectVisitId)).ToList();
}
From 7d7c350df68d61cee575ee3bda105102e966a34e Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Tue, 19 May 2026 13:24:23 +0800
Subject: [PATCH 10/21] =?UTF-8?q?=E4=BF=AE=E6=94=B9scp=E9=BB=98=E8=AE=A4?=
=?UTF-8?q?=E8=AE=BE=E7=BD=AE=E7=9A=84=E5=8C=BA=E5=9F=9F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
IRC.Core.SCP/Service/FileUploadRecordService.cs | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/IRC.Core.SCP/Service/FileUploadRecordService.cs b/IRC.Core.SCP/Service/FileUploadRecordService.cs
index 831d884e7..cc5affc4d 100644
--- a/IRC.Core.SCP/Service/FileUploadRecordService.cs
+++ b/IRC.Core.SCP/Service/FileUploadRecordService.cs
@@ -115,6 +115,19 @@ public class FileUploadRecordService(IRepository _fileUploadRe
}
}
+ //SCP推送过来IP为空,后端归档的,设置区域
+ if (_userInfo.IP.IsNullOrEmpty() && _userInfo.Domain.IsNullOrEmpty())
+ {
+ var apiDefalut = ObjectStoreServiceConfig.SyncConfigList.FirstOrDefault(t => t.UploadRegion == ObjectStoreServiceConfig.ApiDeployRegion);
+
+ if (apiDefalut != null)
+ {
+ addOrEditFileUploadRecord.UploadRegion = apiDefalut.UploadRegion;
+ addOrEditFileUploadRecord.TargetRegion = apiDefalut.TargetRegion;
+
+ }
+ }
+
if (addOrEditFileUploadRecord.TrialId != null)
{
From 12f91c3b999ea254fd4ac16f675e3f8e692b5a92 Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Wed, 20 May 2026 09:23:46 +0800
Subject: [PATCH 11/21] =?UTF-8?q?dicom=E6=B2=A1=E6=9C=89=E7=B1=BB=E5=9E=8B?=
=?UTF-8?q?=E6=97=B6=EF=BC=8C=E7=BB=99=E9=BB=98=E8=AE=A4=E5=80=BCdcm?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
IRC.Core.SCP/Service/OSSService.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/IRC.Core.SCP/Service/OSSService.cs b/IRC.Core.SCP/Service/OSSService.cs
index df4f5cb39..19b51a8a3 100644
--- a/IRC.Core.SCP/Service/OSSService.cs
+++ b/IRC.Core.SCP/Service/OSSService.cs
@@ -967,7 +967,7 @@ public class OSSService(IOptionsMonitor options,
uploadInfo.FileSize = fileSize;
uploadInfo.Path = returnPath;
uploadInfo.FileName = Path.GetFileName(localFilePath);
- uploadInfo.FileType = Path.GetExtension(returnPath);
+ uploadInfo.FileType = Path.GetExtension(returnPath) == "" ? "dcm" : Path.GetExtension(returnPath);
await _fileUploadRecordService.AddOrUpdateFileUploadRecord(uploadInfo);
From 1fbda0327c1dc0ee6e97e26e9bef22d7b75b56f5 Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Wed, 20 May 2026 11:49:25 +0800
Subject: [PATCH 12/21] =?UTF-8?q?=E4=BF=AE=E6=94=B9dcm=E9=BB=98=E8=AE=A4?=
=?UTF-8?q?=E5=80=BC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
IRC.Core.SCP/Service/OSSService.cs | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/IRC.Core.SCP/Service/OSSService.cs b/IRC.Core.SCP/Service/OSSService.cs
index 19b51a8a3..35e58939d 100644
--- a/IRC.Core.SCP/Service/OSSService.cs
+++ b/IRC.Core.SCP/Service/OSSService.cs
@@ -825,10 +825,12 @@ public class OSSService(IOptionsMonitor options,
if (ObjectStoreServiceOptions.IsOpenStoreSync && uploadInfo != null)
{
+ var fileType = Path.GetExtension(returnPath).TrimStart('.');
+
uploadInfo.FileSize = fileStream.CanSeek ? fileStream.Length : 0;
uploadInfo.Path = returnPath;
uploadInfo.FileName = fileRealName;
- uploadInfo.FileType = Path.GetExtension(returnPath).TrimStart('.');
+ uploadInfo.FileType = fileType.IsNullOrEmpty()?"dcm": fileType;
await _fileUploadRecordService.AddOrUpdateFileUploadRecord(uploadInfo);
@@ -964,10 +966,14 @@ public class OSSService(IOptionsMonitor options,
if (ObjectStoreServiceOptions.IsOpenStoreSync && uploadInfo != null)
{
+
+ var fileType = Path.GetExtension(returnPath).TrimStart('.');
+
uploadInfo.FileSize = fileSize;
uploadInfo.Path = returnPath;
uploadInfo.FileName = Path.GetFileName(localFilePath);
- uploadInfo.FileType = Path.GetExtension(returnPath) == "" ? "dcm" : Path.GetExtension(returnPath);
+ uploadInfo.FileType = fileType.IsNullOrEmpty() ? "dcm" : fileType;
+
await _fileUploadRecordService.AddOrUpdateFileUploadRecord(uploadInfo);
From 7c1c45417f64b47e4ed341f5ab85b26f67a0a7f8 Mon Sep 17 00:00:00 2001
From: hang <872297557@qq.com>
Date: Wed, 20 May 2026 14:10:10 +0800
Subject: [PATCH 13/21] =?UTF-8?q?=E4=B8=AD=E5=BF=83=E8=B0=83=E7=A0=94?=
=?UTF-8?q?=E5=88=9D=E6=AD=A5=E8=B0=83=E6=95=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../DTO/TrialSiteEquipmentSurveyViewModel.cs | 42 +-
.../Service/SiteSurvey/_MapConfig.cs | 3 +-
.../TrialSiteUser/DTO/TrialViewModel.cs | 12 +-
.../SiteSurvey/TrialSiteEquipmentSurvey.cs | 40 +
...0641_SiteSurveyEquipmentModify.Designer.cs | 22285 ++++++++++++++++
...0260520060641_SiteSurveyEquipmentModify.cs | 223 +
.../IRaCISDBContextModelSnapshot.cs | 55 +-
7 files changed, 22643 insertions(+), 17 deletions(-)
create mode 100644 IRaCIS.Core.Infra.EFCore/Migrations/20260520060641_SiteSurveyEquipmentModify.Designer.cs
create mode 100644 IRaCIS.Core.Infra.EFCore/Migrations/20260520060641_SiteSurveyEquipmentModify.cs
diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteEquipmentSurveyViewModel.cs b/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteEquipmentSurveyViewModel.cs
index e503d80af..50d40bd2c 100644
--- a/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteEquipmentSurveyViewModel.cs
+++ b/IRaCIS.Core.Application/Service/SiteSurvey/DTO/TrialSiteEquipmentSurveyViewModel.cs
@@ -6,17 +6,9 @@
namespace IRaCIS.Core.Application.Contracts
{
/// TrialSiteEquipmentSurveyView 列表视图模型
- public class TrialSiteEquipmentSurveyView
+ public class TrialSiteEquipmentSurveyView: TrialSiteEquipmentSurveyAddOrEdit
{
- public Guid Id { get; set; }
- public Guid TrialSiteSurveyId { get; set; }
- public string EquipmentType { get; set; } = string.Empty;
- public Guid? EquipmentTypeId { get; set; }
-
- public string Parameters { get; set; } = string.Empty;
- public string ManufacturerName { get; set; } = string.Empty;
- public string ScannerType { get; set; } = string.Empty;
- public string Note { get; set; } = string.Empty;
+
public DateTime CreateTime { get; set; }
public Guid CreateUserId { get; set; }
public DateTime UpdateTime { get; set; }
@@ -56,6 +48,36 @@ namespace IRaCIS.Core.Application.Contracts
public string ManufacturerName { get; set; } = string.Empty;
public string ScannerType { get; set; } = string.Empty;
public string Note { get; set; } = string.Empty;
+
+
+ [Comment("扫描设备-New")]
+ public int EquipmentTypeEnum { get; set; }
+
+ public string OtherEquipmentType { get; set; }
+
+ [Comment("扫描设备厂商")]
+ public int ManufacturerType { get; set; }
+
+ [Comment("磁场强度 (1.5T / 3.0T)")]
+ public int MagneticFieldStrengthType { get; set; }
+
+ [Comment("体部线圈通道数 (≥16 或 <16)")]
+ public int BodyCoilChannelCount { get; set; }
+
+ [Comment("是否具备专用的PDFF脂肪定量序列(CSE-MRI序列)")]
+ public bool HasDedicatedPdfFatQuantificationSequence { get; set; }
+
+ [Comment("专用的PDFF脂肪定量序列类型 (当 HasDedicatedPdfFatQuantificationSequence = true 时有效)")]
+ public int? PdfFatQuantificationSequenceType { get; set; }
+
+ [Comment("其他序列详细说明 (当 PdfFatQuantificationSequenceType = Other 时建议填写)")]
+ public string OtherSequenceSpecification { get; set; }
+
+ [Comment("是否包含 T2/R2 校正(用于铁沉积校正)")]
+ public bool HasT2R2Correction { get; set; }
+
+ [Comment("是否可完整导出 PDFF 参数图及全部原始 DICOM 数据")]
+ public bool CanFullyExportPdfParameterMapsAndRawDicom { get; set; }
}
diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/_MapConfig.cs b/IRaCIS.Core.Application/Service/SiteSurvey/_MapConfig.cs
index b7353328d..abdcde35e 100644
--- a/IRaCIS.Core.Application/Service/SiteSurvey/_MapConfig.cs
+++ b/IRaCIS.Core.Application/Service/SiteSurvey/_MapConfig.cs
@@ -39,8 +39,7 @@ namespace IRaCIS.Core.Application.AutoMapper
//列表
- CreateMap()
- .ForMember(t => t.EquipmentType, u => u.MapFrom(d => isEn_Us ? d.EquipmentType.Value : d.EquipmentType.ValueCN));
+ CreateMap();
diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialViewModel.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialViewModel.cs
index e13584f7f..df120b412 100644
--- a/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialViewModel.cs
+++ b/IRaCIS.Core.Application/Service/TrialSiteUser/DTO/TrialViewModel.cs
@@ -260,6 +260,8 @@ namespace IRaCIS.Application.Contracts
public List ModifyFiledList { get; set; } = new List();
+ public List EquipmentControlFieldList { get; set; } = new List();
+
#endregion
@@ -273,7 +275,7 @@ namespace IRaCIS.Application.Contracts
}
- public class TrialConfigInfo: TrialExtraConfig
+ public class TrialConfigInfo : TrialExtraConfig
{
#region 视图模型返回 项目术语配置 ,实际数据库没有配置
public List TrialObjectNameList { get; set; }
@@ -311,6 +313,14 @@ namespace IRaCIS.Application.Contracts
}
+ public class SiteSurveyEquipmentField
+ {
+ public string FiledName { get; set; }
+ public int ShowOrder { get; set; }
+
+ public bool IsView { get; set; }
+
+ }
}
\ No newline at end of file
diff --git a/IRaCIS.Core.Domain/SiteSurvey/TrialSiteEquipmentSurvey.cs b/IRaCIS.Core.Domain/SiteSurvey/TrialSiteEquipmentSurvey.cs
index 9180d2453..66be543c8 100644
--- a/IRaCIS.Core.Domain/SiteSurvey/TrialSiteEquipmentSurvey.cs
+++ b/IRaCIS.Core.Domain/SiteSurvey/TrialSiteEquipmentSurvey.cs
@@ -14,12 +14,52 @@ public class TrialSiteEquipmentSurvey : BaseFullAuditEntity
#endregion
public Guid TrialSiteSurveyId { get; set; }
+ [Comment("扫描设备-废弃")]
public Guid EquipmentTypeId { get; set; }
+
+ [Comment("扫描设备参数")]
public string Parameters { get; set; } = string.Empty;
+ [Comment("扫描设备厂商其他补充")]
public string ManufacturerName { get; set; } = string.Empty;
+
+ [Comment("扫描设备型号")]
public string ScannerType { get; set; } = string.Empty;
public string Note { get; set; } = string.Empty;
+
+ #region 新增
+
+ [Comment("扫描设备-New")]
+ public int EquipmentTypeEnum { get; set; }
+
+ public string OtherEquipmentType { get; set; }
+
+ [Comment("扫描设备厂商")]
+ public int ManufacturerType { get; set; }
+
+ [Comment("磁场强度 (1.5T / 3.0T)")]
+ public int MagneticFieldStrengthType { get; set; }
+
+ [Comment("体部线圈通道数 (≥16 或 <16)")]
+ public int BodyCoilChannelCount { get; set; }
+
+ [Comment("是否具备专用的PDFF脂肪定量序列(CSE-MRI序列)")]
+ public bool HasDedicatedPdfFatQuantificationSequence { get; set; }
+
+ [Comment("专用的PDFF脂肪定量序列类型 (当 HasDedicatedPdfFatQuantificationSequence = true 时有效)")]
+ public int? PdfFatQuantificationSequenceType { get; set; }
+
+ [Comment("其他序列详细说明 (当 PdfFatQuantificationSequenceType = Other 时建议填写)")]
+ public string OtherSequenceSpecification { get; set; }
+
+ [Comment("是否包含 T2/R2 校正(用于铁沉积校正)")]
+ public bool HasT2R2Correction { get; set; }
+
+ [Comment("是否可完整导出 PDFF 参数图及全部原始 DICOM 数据")]
+ public bool CanFullyExportPdfParameterMapsAndRawDicom { get; set; }
+
+ #endregion
+
}
diff --git a/IRaCIS.Core.Infra.EFCore/Migrations/20260520060641_SiteSurveyEquipmentModify.Designer.cs b/IRaCIS.Core.Infra.EFCore/Migrations/20260520060641_SiteSurveyEquipmentModify.Designer.cs
new file mode 100644
index 000000000..4c184124e
--- /dev/null
+++ b/IRaCIS.Core.Infra.EFCore/Migrations/20260520060641_SiteSurveyEquipmentModify.Designer.cs
@@ -0,0 +1,22285 @@
+//
+using System;
+using IRaCIS.Core.Infra.EFCore;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace IRaCIS.Core.Infra.EFCore.Migrations
+{
+ [DbContext(typeof(IRaCISDBContext))]
+ [Migration("20260520060641_SiteSurveyEquipmentModify")]
+ partial class SiteSurveyEquipmentModify
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.19")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.Attachment", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Code")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)")
+ .HasComment("编码");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("DoctorId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ExpiryDate")
+ .HasColumnType("datetime2")
+ .HasComment("过期时间");
+
+ b.Property("FileName")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("IsAuthorizedView")
+ .HasColumnType("bit");
+
+ b.Property("IsOfficial")
+ .HasColumnType("bit")
+ .HasComment("是否正式简历");
+
+ b.Property("Language")
+ .HasColumnType("int")
+ .HasComment("1 中文 2为英文");
+
+ b.Property("Path")
+ .IsRequired()
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("TrialId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)")
+ .HasComment("文件类型名");
+
+ b.Property("UpdateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("UpdateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("Attachment", t =>
+ {
+ t.HasComment("医生 - 简历|证书 文档表");
+ });
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.AuditDocument", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AuditDocumentTypeEnum")
+ .HasColumnType("int");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("FileFormat")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("FilePath")
+ .IsRequired()
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("FileSize")
+ .HasPrecision(18, 2)
+ .HasColumnType("decimal(18,2)");
+
+ b.Property("IsAuthorization")
+ .HasColumnType("bit");
+
+ b.Property("MainFileId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("ParentId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("UpdateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("UpdateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Version")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("AuditDocument", t =>
+ {
+ t.HasComment("稽查文档管理");
+ });
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.AuditDocumentClosure", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AncestorId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("祖先");
+
+ b.Property("Depth")
+ .HasColumnType("int");
+
+ b.Property("DescendantId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("后代");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.ToTable("AuditDocumentClosure");
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.AuditRecord", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AuditContent")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("AuditState")
+ .HasColumnType("int")
+ .HasComment("稽查状态");
+
+ b.Property("AuditTime")
+ .HasColumnType("date")
+ .HasComment("稽查日期");
+
+ b.Property("AuditType")
+ .HasColumnType("int")
+ .HasComment("稽查形式");
+
+ b.Property("BeginTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CompanyName")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("EndTime")
+ .HasColumnType("datetime2");
+
+ b.Property("IsViewTrainingRecord")
+ .HasColumnType("bit");
+
+ b.Property("UpdateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("UpdateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("AuditRecord");
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.AuditRecordIdentityUser", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AuditRecordId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("IdentityUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("AuditRecordIdentityUser");
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.AuditRecordPermission", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AuditDocumentId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("AuditRecordId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("AuditRecordPermission");
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.CRO", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CROCode")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("CROName")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("CRONameCN")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("IsTrialLevel")
+ .HasColumnType("bit")
+ .HasComment("是否是项目级别");
+
+ b.Property("TrialId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("UpdateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("UpdateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("CROCompany", t =>
+ {
+ t.HasComment("机构 - CRO");
+ });
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.CheckChallengeDialog", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("IsCRCNeedReply")
+ .HasColumnType("bit")
+ .HasComment("CRC是否需要回复 前端使用");
+
+ b.Property("ParamInfo")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)")
+ .HasComment("核查的检查信息Json");
+
+ b.Property("SubjectVisitId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TalkContent")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("UserTypeEnum")
+ .HasColumnType("int")
+ .HasComment("核查过程中的操作用户类型");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("CheckChallengeDialog", t =>
+ {
+ t.HasComment("一致性核查 - 对话记录表");
+ });
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.ClinicalAnswerRowInfo", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClinicalFormId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("表单Id");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("QuestionId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("问题Id");
+
+ b.Property("RowIndex")
+ .HasColumnType("int");
+
+ b.Property("SubjectId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("受试者Id");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("ClinicalAnswerRowInfo", t =>
+ {
+ t.HasComment("受试者 - 临床表单表格问题行记录");
+ });
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.ClinicalDataSystemSet", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClinicalDataLevel")
+ .HasColumnType("int");
+
+ b.Property("ClinicalDataSetEnName")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("ClinicalDataSetEnum")
+ .HasColumnType("int")
+ .HasComment("枚举(字典里面取的)");
+
+ b.Property("ClinicalDataSetName")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("ClinicalUploadType")
+ .HasColumnType("int")
+ .HasComment("上传方式");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CriterionEnumListStr")
+ .IsRequired()
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("EnFileName")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("EnPath")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("FileName")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("IsApply")
+ .HasColumnType("bit")
+ .HasComment("是否应用");
+
+ b.Property("IsEnable")
+ .HasColumnType("bit");
+
+ b.Property("Path")
+ .IsRequired()
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("UploadRole")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("ClinicalDataSystemSet", t =>
+ {
+ t.HasComment("系统 - 临床数据配置");
+ });
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.ClinicalDataTrialSet", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClinicalDataLevel")
+ .HasColumnType("int")
+ .HasComment("临床级别");
+
+ b.Property("ClinicalDataSetEnName")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("ClinicalDataSetName")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("ClinicalUploadType")
+ .HasColumnType("int")
+ .HasComment("上传方式");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CriterionEnumListStr")
+ .IsRequired()
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("EnFileName")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("EnPath")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("FileName")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("IsApply")
+ .HasColumnType("bit")
+ .HasComment("是否应用");
+
+ b.Property("IsConfirm")
+ .HasColumnType("bit");
+
+ b.Property("Path")
+ .IsRequired()
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("SystemClinicalDataSetId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TrialId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("UploadRole")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("ClinicalDataTrialSet", t =>
+ {
+ t.HasComment("项目 - 临床数据适应标准配置");
+ });
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.ClinicalForm", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CheckDate")
+ .HasColumnType("datetime2")
+ .HasComment("检查日期");
+
+ b.Property("ClinicalDataTrialSetId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("PicturePath")
+ .IsRequired()
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)")
+ .HasComment("截图地址");
+
+ b.Property("ReadingId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("SubjectId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("受试者Id");
+
+ b.Property("TrialId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("VisitId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("ClinicalForm", t =>
+ {
+ t.HasComment("受试者 - 临床表单");
+ });
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.ClinicalQuestionAnswer", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Answer")
+ .IsRequired()
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)");
+
+ b.Property("ClinicalDataTrialSetId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ClinicalFormId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("表单Id");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("QuestionId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("问题Id");
+
+ b.Property("SubjectId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("受试者Id");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("ClinicalQuestionAnswer", t =>
+ {
+ t.HasComment("受试者 - 临床表单问题答案");
+ });
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.ClinicalTableAnswer", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Answer")
+ .IsRequired()
+ .HasMaxLength(1000)
+ .HasColumnType("nvarchar(1000)")
+ .HasComment("答案");
+
+ b.Property("ClinicalFormId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("表单Id");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("QuestionId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("问题Id");
+
+ b.Property("RowId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("答案行的Id");
+
+ b.Property("SubjectId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("受试者Id");
+
+ b.Property("TableQuestionId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("ClinicalTableAnswer", t =>
+ {
+ t.HasComment("受试者 - 临床表单表格问题答案");
+ });
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.CommonDocument", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("BusinessScenarioEnum")
+ .HasColumnType("int")
+ .HasComment("业务场景");
+
+ b.Property("Code")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CriterionTypeEnum")
+ .HasColumnType("int")
+ .HasComment("系统标准枚举");
+
+ b.Property("DeleteUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("DeletedTime")
+ .HasColumnType("datetime2");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("FileTypeEnum")
+ .HasColumnType("int")
+ .HasComment("类型-上传|导出|邮件附件");
+
+ b.Property("IsDeleted")
+ .HasColumnType("bit");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("NameCN")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("Path")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("UpdateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("UpdateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("CommonDocument", t =>
+ {
+ t.HasComment("数据上传 | 数据导出 | 邮件附件 文件记录表 (需要同步)");
+ });
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.CriterionKeyFileRead", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("IdentityUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TrialCriterionId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("CriterionKeyFileRead", t =>
+ {
+ t.HasComment("标准阅读关键点");
+ });
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.CriterionNidusSystem", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CriterionId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("IsSystemCriterion")
+ .HasColumnType("bit");
+
+ b.Property("LesionType")
+ .HasColumnType("int")
+ .HasComment("病灶类型");
+
+ b.Property("OrganType")
+ .HasColumnType("int")
+ .HasComment("器官类型");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("CriterionNidusSystem", t =>
+ {
+ t.HasComment("系统标准 - 病灶器官表 (需要同步)");
+ });
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.CriterionNidusTrial", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CriterionId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("LesionType")
+ .HasColumnType("int");
+
+ b.Property("OrganType")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("CriterionNidusTrial", t =>
+ {
+ t.HasComment("项目标准 - 病灶器官表");
+ });
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.DataInspection", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("BatchId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("批次Id");
+
+ b.Property("ChildrenTypeId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("子类");
+
+ b.Property("CreateTime")
+ .HasColumnType("datetime2");
+
+ b.Property("CreateUserId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("CreateUserName")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)")
+ .HasComment("创建人姓名");
+
+ b.Property("CreateUserRealName")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("DoctorUserId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("阅片医生");
+
+ b.Property("EntityName")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)")
+ .HasComment("被稽查实体名");
+
+ b.Property("GeneralId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("要稽查对象Id");
+
+ b.Property("IP")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("Identification")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)")
+ .HasComment("标识");
+
+ b.Property("IsFrontAdd")
+ .HasColumnType("bit")
+ .HasComment("是否是前端添加");
+
+ b.Property("IsSign")
+ .HasColumnType("bit");
+
+ b.Property("JsonDetail")
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("LastJsonDetail")
+ .HasColumnType("nvarchar(max)")
+ .HasComment("上一条json");
+
+ b.Property("ModuleTypeId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ObjectRelationParentId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("被稽查对象外键1");
+
+ b.Property("ObjectRelationParentId2")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ObjectRelationParentId3")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ObjectTypeId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("OptTypeId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("ParentId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("父ID");
+
+ b.Property("RealUrlAndEntity")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("Reason")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)");
+
+ b.Property("RoleName")
+ .IsRequired()
+ .HasMaxLength(400)
+ .HasColumnType("nvarchar(400)")
+ .HasComment("角色名称");
+
+ b.Property("SignId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("SubjectId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("SubjectVisitId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TrialId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TrialReadingCriterionId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("TrialSiteId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("VisitStageId")
+ .HasColumnType("uniqueidentifier")
+ .HasComment("访视计划ID");
+
+ b.Property("VisitTaskId")
+ .HasColumnType("uniqueidentifier");
+
+ b.HasKey("Id");
+
+ SqlServerKeyBuilderExtensions.IsClustered(b.HasKey("Id"), false);
+
+ b.HasIndex("CreateTime");
+
+ SqlServerIndexBuilderExtensions.IsClustered(b.HasIndex("CreateTime"));
+
+ b.ToTable("DataInspection", t =>
+ {
+ t.HasComment("稽查 - 记录表");
+ });
+ });
+
+ modelBuilder.Entity("IRaCIS.Core.Domain.Models.DicomInstance", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Anonymize")
+ .HasColumnType("bit");
+
+ b.Property