Compare commits
No commits in common. "Test_IRC_Net8" and "EICS-V1.12.0" have entirely different histories.
Test_IRC_N
...
EICS-V1.12
|
@ -23,16 +23,14 @@ namespace IRaCIS.Core.API
|
|||
.MinimumLevel.Information()
|
||||
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
|
||||
.MinimumLevel.Override("MassTransit", LogEventLevel.Warning)
|
||||
//https://github.com/ZiggyCreatures/FusionCache/blob/main/docs/Logging.md
|
||||
.MinimumLevel.Override("ZiggyCreatures.Caching.Fusion", LogEventLevel.Warning)
|
||||
|
||||
.MinimumLevel.Override("FusionCache", LogEventLevel.Warning)
|
||||
// Filter out ASP.NET Core infrastructre logs that are Information and below 日志太多了 一个请求 记录好几条
|
||||
.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
|
||||
.MinimumLevel.Override("Microsoft.AspNetCore.Hosting", LogEventLevel.Warning)
|
||||
.MinimumLevel.Override("Microsoft.AspNetCore.Mvc", LogEventLevel.Warning)
|
||||
.MinimumLevel.Override("Microsoft.AspNetCore.Routing", LogEventLevel.Warning)
|
||||
.MinimumLevel.Override("Hangfire", LogEventLevel.Warning)
|
||||
.Enrich.FromLogContext()
|
||||
.Enrich.FromLogContext()
|
||||
.Filter.ByExcluding(logEvent => logEvent.Properties.ContainsKey("RequestPath") && logEvent.Properties["RequestPath"].ToString().Contains("/health"))
|
||||
.WriteTo.Console()
|
||||
.WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day,retainedFileCountLimit:60);
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
}
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"RemoteNew": "Server=101.132.193.237,1434;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=101.132.193.237,1434;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
|
||||
//"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
|
||||
//"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
|
||||
//"RemoteNew": "Server=101.132.193.237,1434;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
|
||||
//"Hangfire": "Server=101.132.193.237,1434;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
|
||||
"RemoteNew": "Server=prod_mssql_standard,1433;Database=Prod_IRC;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true",
|
||||
"Hangfire": "Server=prod_mssql_standard,1433;Database=Prod_IRC_Hangfire;User ID=sa;Password=zhanying@2021;TrustServerCertificate=true"
|
||||
},
|
||||
"ObjectStoreService": {
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
|
|
|
@ -1,164 +1,105 @@
|
|||
{
|
||||
// 日志信息
|
||||
"Logging": {
|
||||
// 日志等级
|
||||
"LogLevel": {
|
||||
// 默认日志等级
|
||||
"Default": "Information",
|
||||
// 调试日志等级
|
||||
"Microsoft": "Warning",
|
||||
// ASP.NET Core 日志等级
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
// 数据库链接字符串
|
||||
"ConnectionStrings": {
|
||||
// 本地数据库链接字符串
|
||||
"RemoteNew": "Server=106.14.89.110,1435;Database=Test_IRC;User ID=sa;Password=xc@123456;TrustServerCertificate=true",
|
||||
// Hangfire 定时任务数据库链接字符串
|
||||
"Hangfire": "Server=106.14.89.110,1435;Database=Test_IRC_Hangfire;User ID=sa;Password=xc@123456;TrustServerCertificate=true"
|
||||
},
|
||||
// 对象存储服务配置
|
||||
|
||||
"ObjectStoreService": {
|
||||
// 使用的对象存储服务类型
|
||||
|
||||
"ObjectStoreUse": "AliyunOSS",
|
||||
// 阿里云对象存储服务的配置
|
||||
|
||||
"AliyunOSS": {
|
||||
// 阿里云 OSS 的 Region ID
|
||||
"RegionId": "cn-shanghai",
|
||||
// 阿里云 OSS 的内部访问端点
|
||||
"InternalEndpoint": "https://oss-cn-shanghai-internal.aliyuncs.com",
|
||||
// 阿里云 OSS 的外部访问端点
|
||||
"EndPoint": "https://oss-cn-shanghai.aliyuncs.com",
|
||||
// 阿里云 OSS 的访问密钥 ID
|
||||
"AccessKeyId": "LTAI5tRRZehUp2V9pyTPtAJm",
|
||||
// 阿里云 OSS 的访问密钥 Secret
|
||||
"AccessKeySecret": "FLizxkHsMm4CGYHtkV8E3PNJJZU7oV",
|
||||
// 阿里云 OSS 的角色 ARN
|
||||
"RoleArn": "acs:ram::1899121822495495:role/dev-oss-access",
|
||||
// 阿里云 OSS 的Bucket名称
|
||||
"BucketName": "zy-irc-test-store",
|
||||
// 阿里云 OSS 的访问端点
|
||||
//"ViewEndpoint": "https://zy-irc-test-store.oss-cn-shanghai.aliyuncs.com",
|
||||
"ViewEndpoint": "https://zy-irc-test-dev-cache.oss-cn-shanghai.aliyuncs.com",
|
||||
// 阿里云 OSS 的预览端点
|
||||
"Region": "oss-cn-shanghai",
|
||||
// 阿里云 OSS 的临时访问凭证有效时间(秒)
|
||||
"DurationSeconds": 7200,
|
||||
// 阿里云 OSS 的预览端点
|
||||
"PreviewEndpoint": "https://test-oss.test.extimaging.com"
|
||||
},
|
||||
// MinIO 对象存储服务的配置
|
||||
"MinIO": {
|
||||
// MinIO 的访问端点
|
||||
"EndPoint": "hir-oss.test.extimaging.com",
|
||||
// MinIO 的端口
|
||||
"Port": "443",
|
||||
// 是否使用 SSL
|
||||
"UseSSL": true,
|
||||
// MinIO 的角色 ARN
|
||||
"AccessKey": "fbStsVYCIPKHQneeqMwD",
|
||||
// MinIO 的访问密钥
|
||||
"SecretKey": "TzgvyA3zGXMUnpilJNUlyMYHfosl1hBMl6lxPmjy",
|
||||
// MinIO 的BucketName
|
||||
"BucketName": "irc-test",
|
||||
// MinIO 的访问端点
|
||||
"ViewEndpoint": "https://hir-oss.test.extimaging.com/irc-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
|
||||
}
|
||||
},
|
||||
// 系统配置
|
||||
|
||||
"BasicSystemConfig": {
|
||||
// 打开用户复杂密码
|
||||
|
||||
"OpenUserComplexPassword": false,
|
||||
// 是否在开始工作前强制签署电子知情同意书
|
||||
"OpenSignDocumentBeforeWork": false,
|
||||
// 是否启用登录失败次数限制(防暴力破解)
|
||||
|
||||
"OpenLoginLimit": false,
|
||||
// 连续登录失败多少次后触发锁定
|
||||
"LoginMaxFailCount": 5,
|
||||
// 触发锁定后账号锁定时长(分钟)
|
||||
"LoginFailLockMinutes": 1,
|
||||
// 无操作自动登出的超时时间(分钟)
|
||||
"AutoLoginOutMinutes": 10,
|
||||
// 是否启用多因子登录认证(MFA)
|
||||
|
||||
"OpenLoginMFA": false,
|
||||
// 连续阅片的最长工作时间(分钟),超时后强制休息
|
||||
|
||||
"ContinuousReadingTimeMin": 120,
|
||||
// 强制休息时长(分钟)
|
||||
"ReadingRestTimeMin": 10,
|
||||
// 是否强制用户定期修改密码
|
||||
|
||||
"IsNeedChangePassWord": true,
|
||||
// 密码有效期(天),到期后必须修改
|
||||
"ChangePassWordDays": 90,
|
||||
|
||||
// 模板类型 1 Elevate 2 Extensive
|
||||
"TemplateType": 2,
|
||||
// 是否打开项目关联删除
|
||||
|
||||
"OpenTrialRelationDelete": true,
|
||||
// 转换PDF服务配置
|
||||
|
||||
"ThirdPdfUrl": "http://106.14.89.110:30088/api/v1/convert/file/pdf"
|
||||
},
|
||||
// 邮件服务配置(用于系统通知、找回密码、错误报警等)
|
||||
|
||||
"SystemEmailSendConfig": {
|
||||
// SMTP端口
|
||||
"Port": 465,
|
||||
// 企业邮箱SMTP服务器地址
|
||||
"Host": "smtp.qiye.aliyun.com",
|
||||
// 发件人邮箱地址
|
||||
"FromEmail": "test@extimaging.com",
|
||||
// 发件人显示名称
|
||||
"FromName": "Test IRC Imaging System",
|
||||
// SMTP授权码
|
||||
"AuthorizationCode": "SHzyyl2021",
|
||||
// 系统对外访问地址
|
||||
"SiteUrl": "http://irc.test.extimaging.com/login",
|
||||
// 系统简称
|
||||
|
||||
"SystemShortName": "IRC",
|
||||
// 组织英文名称
|
||||
"OrganizationName": "Extlmaging",
|
||||
// 组织中文名称
|
||||
"OrganizationNameCN": "Extlmaging",
|
||||
// 公司英文全称
|
||||
"CompanyName": "Extensive Imaging",
|
||||
// 公司中文全称
|
||||
"CompanyNameCN": "上海展影医疗科技有限公司",
|
||||
// 公司英文简称
|
||||
"CompanyShortName": "Extensive Imaging",
|
||||
// 公司中文简称
|
||||
"CompanyShortNameCN": "展影医疗",
|
||||
// 是否为国际版环境
|
||||
"IsEnv_US": false,
|
||||
// 是否开启系统异常邮件报警
|
||||
"IsOpenErrorNoticeEmail": false,
|
||||
// 邮箱格式校验正则表达式
|
||||
"EmailRegexStr": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
|
||||
// 接收系统异常报警的邮箱列表
|
||||
"ErrorNoticeEmailList": [ "872297557@qq.com" ]
|
||||
},
|
||||
// PACS 连接配置
|
||||
|
||||
"SystemPacsConfig": {
|
||||
// PACS服务器端口
|
||||
"Port": "11113",
|
||||
// PACS服务器IP地址
|
||||
"IP": "106.14.89.110"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,190 +0,0 @@
|
|||
using FellowOakDicom;
|
||||
using FellowOakDicom.Media;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IRaCIS.Core.Application.Helper
|
||||
{
|
||||
|
||||
public class StudyDIRInfo
|
||||
{
|
||||
public Guid SubjectVisitId { get; set; }
|
||||
// Study
|
||||
public Guid DicomStudyId { get; set; }
|
||||
|
||||
public string PatientId { get; set; }
|
||||
public string PatientName { get; set; }
|
||||
public string PatientBirthDate { get; set; }
|
||||
public string PatientSex { get; set; }
|
||||
|
||||
public string StudyInstanceUid { get; set; }
|
||||
public string StudyId { get; set; }
|
||||
public string DicomStudyDate { get; set; }
|
||||
public string DicomStudyTime { get; set; }
|
||||
public string AccessionNumber { get; set; }
|
||||
public string StudyDescription { get; set; }
|
||||
|
||||
// Series
|
||||
public string SeriesInstanceUid { get; set; }
|
||||
public string Modality { get; set; }
|
||||
public string DicomSeriesDate { get; set; }
|
||||
public string DicomSeriesTime { get; set; }
|
||||
public int SeriesNumber { get; set; }
|
||||
public string SeriesDescription { get; set; }
|
||||
|
||||
// Instance
|
||||
public Guid InstanceId { get; set; }
|
||||
public string SopInstanceUid { get; set; }
|
||||
public string SOPClassUID { get; set; }
|
||||
public int InstanceNumber { get; set; }
|
||||
public string MediaStorageSOPClassUID { get; set; }
|
||||
public string MediaStorageSOPInstanceUID { get; set; }
|
||||
public string TransferSytaxUID { get; set; }
|
||||
}
|
||||
public static class DicomDIRHelper
|
||||
{
|
||||
|
||||
public static async Task GenerateStudyDIRAndUploadAsync(List<StudyDIRInfo> list, Dictionary<string, string> dic, string ossFolder, IOSSService _oSSService)
|
||||
{
|
||||
var mappings = new List<string>();
|
||||
int index = 1;
|
||||
|
||||
|
||||
var dicomDir = new DicomDirectory();
|
||||
|
||||
foreach (var item in list.OrderBy(t => t.SeriesNumber).ThenBy(t => t.InstanceNumber))
|
||||
{
|
||||
var dicomUid = DicomUID.Enumerate().FirstOrDefault(uid => uid.UID == item.TransferSytaxUID);
|
||||
|
||||
if (dicomUid != null)
|
||||
{
|
||||
var ts = DicomTransferSyntax.Query(dicomUid);
|
||||
|
||||
var dataset = new DicomDataset(ts)
|
||||
{
|
||||
{ DicomTag.PatientID, item.PatientId ?? string.Empty },
|
||||
{ DicomTag.PatientName, item.PatientName ?? string.Empty },
|
||||
{ DicomTag.PatientBirthDate, item.PatientBirthDate ?? string.Empty },
|
||||
{ DicomTag.PatientSex, item.PatientSex ?? string.Empty },
|
||||
|
||||
{ DicomTag.StudyInstanceUID, item.StudyInstanceUid ?? string.Empty },
|
||||
{ DicomTag.StudyID, item.StudyId ?? string.Empty },
|
||||
{ DicomTag.StudyDate, item.DicomStudyDate ?? string.Empty },
|
||||
{ DicomTag.StudyTime, item.DicomStudyTime ?? string.Empty },
|
||||
{ DicomTag.AccessionNumber, item.AccessionNumber ?? string.Empty },
|
||||
{ DicomTag.StudyDescription, item.StudyDescription ?? string.Empty },
|
||||
|
||||
{ DicomTag.SeriesInstanceUID, item.SeriesInstanceUid ?? string.Empty },
|
||||
{ DicomTag.Modality, item.Modality ?? string.Empty },
|
||||
{ DicomTag.SeriesDate, item.DicomSeriesDate ?? string.Empty },
|
||||
{ DicomTag.SeriesTime, item.DicomSeriesTime ?? string.Empty },
|
||||
{ DicomTag.SeriesNumber, item.SeriesNumber.ToString() ?? string.Empty },
|
||||
{ DicomTag.SeriesDescription, item.SeriesDescription ?? string.Empty },
|
||||
|
||||
{ DicomTag.SOPInstanceUID, item.SopInstanceUid ?? string.Empty },
|
||||
{ DicomTag.SOPClassUID, item.SOPClassUID ?? string.Empty },
|
||||
{ DicomTag.InstanceNumber, item.InstanceNumber.ToString() ?? string.Empty },
|
||||
{ DicomTag.MediaStorageSOPClassUID, item.MediaStorageSOPClassUID ?? string.Empty },
|
||||
{ DicomTag.MediaStorageSOPInstanceUID, item.MediaStorageSOPInstanceUID ?? string.Empty },
|
||||
{ DicomTag.TransferSyntaxUID, item.TransferSytaxUID ?? string.Empty },
|
||||
};
|
||||
|
||||
var dicomFile = new DicomFile(dataset);
|
||||
|
||||
// 文件名递增格式:IM_00001, IM_00002, ...
|
||||
string filename = $@"IMAGE/IM_{index:D5}"; // :D5 表示补足5位
|
||||
|
||||
mappings.Add($"{filename} => {item.InstanceId}");
|
||||
|
||||
dic.Add(item.InstanceId.ToString(), Path.GetFileName(filename));
|
||||
|
||||
dicomDir.AddFile(dicomFile, filename);
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//有实际的文件
|
||||
if (mappings.Count > 0)
|
||||
{
|
||||
#region 写入临时路径
|
||||
var tempFilePath = Path.GetTempFileName();
|
||||
|
||||
// 保存 DICOMDIR 到临时文件 不能直接写入到流种
|
||||
await dicomDir.SaveAsync(tempFilePath);
|
||||
|
||||
using (var memoryStream = new MemoryStream(File.ReadAllBytes(tempFilePath)))
|
||||
{
|
||||
// 重置流位置
|
||||
memoryStream.Position = 0;
|
||||
|
||||
await _oSSService.UploadToOSSAsync(memoryStream, ossFolder, "DICOMDIR", false);
|
||||
}
|
||||
|
||||
//清理临时文件
|
||||
File.Delete(tempFilePath);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 映射上传
|
||||
|
||||
// 将映射写入内存流
|
||||
var mappingText = string.Join(Environment.NewLine, mappings);
|
||||
await using var mappingStream = new MemoryStream(Encoding.UTF8.GetBytes(mappingText));
|
||||
|
||||
await _oSSService.UploadToOSSAsync(mappingStream, ossFolder, $"Download_{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}", false);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static StudyDIRInfo ReadDicomDIRInfo(DicomFile dicomFile)
|
||||
{
|
||||
var dataset = dicomFile.Dataset;
|
||||
|
||||
|
||||
var info = new StudyDIRInfo
|
||||
{
|
||||
PatientId = dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty),
|
||||
PatientName = dataset.GetSingleValueOrDefault(DicomTag.PatientName, string.Empty),
|
||||
PatientBirthDate = dataset.GetSingleValueOrDefault(DicomTag.PatientBirthDate, string.Empty),
|
||||
PatientSex = dataset.GetSingleValueOrDefault(DicomTag.PatientSex, string.Empty),
|
||||
|
||||
StudyInstanceUid = dataset.GetSingleValueOrDefault(DicomTag.StudyInstanceUID, string.Empty),
|
||||
StudyId = dataset.GetSingleValueOrDefault(DicomTag.StudyID, string.Empty),
|
||||
DicomStudyDate = dataset.GetSingleValueOrDefault(DicomTag.StudyDate, string.Empty),
|
||||
DicomStudyTime = dataset.GetSingleValueOrDefault(DicomTag.StudyTime, string.Empty),
|
||||
AccessionNumber = dataset.GetSingleValueOrDefault(DicomTag.AccessionNumber, string.Empty),
|
||||
StudyDescription = dataset.GetSingleValueOrDefault(DicomTag.StudyDescription, string.Empty),
|
||||
|
||||
SeriesInstanceUid = dataset.GetSingleValueOrDefault(DicomTag.SeriesInstanceUID, string.Empty),
|
||||
Modality = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty),
|
||||
DicomSeriesDate = dataset.GetSingleValueOrDefault(DicomTag.SeriesDate, string.Empty),
|
||||
DicomSeriesTime = dataset.GetSingleValueOrDefault(DicomTag.SeriesTime, string.Empty),
|
||||
SeriesNumber = dataset.GetSingleValueOrDefault(DicomTag.SeriesNumber, 1),
|
||||
SeriesDescription = dataset.GetSingleValueOrDefault(DicomTag.SeriesDescription, string.Empty),
|
||||
|
||||
SopInstanceUid = dataset.GetSingleValueOrDefault(DicomTag.SOPInstanceUID, string.Empty),
|
||||
SOPClassUID = dataset.GetSingleValueOrDefault(DicomTag.SOPClassUID, string.Empty),
|
||||
InstanceNumber = dataset.GetSingleValueOrDefault(DicomTag.InstanceNumber, 1),
|
||||
|
||||
MediaStorageSOPClassUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.MediaStorageSOPClassUID, string.Empty),
|
||||
MediaStorageSOPInstanceUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.MediaStorageSOPInstanceUID, string.Empty),
|
||||
|
||||
TransferSytaxUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.TransferSyntaxUID, string.Empty)
|
||||
};
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -112,8 +112,6 @@ public class AliyunOSSTempToken
|
|||
|
||||
public string PreviewEndpoint { get; set; }
|
||||
|
||||
public string DownloadEndPoint => EndPoint.Insert(EndPoint.IndexOf("//") + 2, BucketName + ".");
|
||||
|
||||
}
|
||||
|
||||
[LowerCamelCaseJson]
|
||||
|
@ -147,8 +145,6 @@ public interface IOSSService
|
|||
|
||||
public Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath);
|
||||
|
||||
public Task<Stream> GetStreamFromOSSAsync(string ossRelativePath);
|
||||
|
||||
public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
|
||||
|
||||
public Task<string> GetSignedUrl(string ossRelativePath);
|
||||
|
@ -194,7 +190,7 @@ public class OSSService : IOSSService
|
|||
/// <returns></returns>
|
||||
public async Task<string> UploadToOSSAsync(Stream fileStream, string oosFolderPath, string fileRealName, bool isFileNameAddGuid = true)
|
||||
{
|
||||
BackBatchGetToken();
|
||||
GetObjectStoreTempToken();
|
||||
|
||||
var ossRelativePath = isFileNameAddGuid ? $"{oosFolderPath}/{Guid.NewGuid()}_{fileRealName}" : $"{oosFolderPath}/{fileRealName}";
|
||||
|
||||
|
@ -284,37 +280,6 @@ public class OSSService : IOSSService
|
|||
}
|
||||
|
||||
|
||||
//后端批量上传 或者下载,不每个文件获取临时token
|
||||
private void BackBatchGetToken()
|
||||
{
|
||||
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
|
||||
{
|
||||
if (AliyunOSSTempToken == null)
|
||||
{
|
||||
GetObjectStoreTempToken();
|
||||
}
|
||||
//token 过期了
|
||||
else if (AliyunOSSTempToken.Expiration.AddSeconds(10) <= DateTime.Now)
|
||||
{
|
||||
GetObjectStoreTempToken();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
||||
{
|
||||
if (AWSTempToken == null)
|
||||
{
|
||||
GetObjectStoreTempToken();
|
||||
}
|
||||
//token 过期了
|
||||
else if (AWSTempToken.Expiration?.AddSeconds(10) <= DateTime.Now)
|
||||
{
|
||||
GetObjectStoreTempToken();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// oosFolderPath 不要 "/ "开头 应该: TempFolder/ChildFolder
|
||||
|
@ -326,7 +291,7 @@ public class OSSService : IOSSService
|
|||
/// <exception cref="BusinessValidationFailedException"></exception>
|
||||
public async Task<string> UploadToOSSAsync(string localFilePath, string oosFolderPath, bool isFileNameAddGuid = true)
|
||||
{
|
||||
BackBatchGetToken();
|
||||
GetObjectStoreTempToken();
|
||||
|
||||
var localFileName = Path.GetFileName(localFilePath);
|
||||
|
||||
|
@ -396,7 +361,11 @@ public class OSSService : IOSSService
|
|||
|
||||
public async Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath)
|
||||
{
|
||||
BackBatchGetToken();
|
||||
if (isFirstCall)
|
||||
{
|
||||
GetObjectStoreTempToken();
|
||||
isFirstCall = false;
|
||||
}
|
||||
|
||||
ossRelativePath = ossRelativePath.TrimStart('/');
|
||||
try
|
||||
|
@ -409,12 +378,14 @@ public class OSSService : IOSSService
|
|||
|
||||
var _ossClient = new OssClient(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint, AliyunOSSTempToken.AccessKeyId, AliyunOSSTempToken.AccessKeySecret, AliyunOSSTempToken.SecurityToken);
|
||||
|
||||
// 上传文件
|
||||
var result = _ossClient.GetObject(aliConfig.BucketName, ossRelativePath);
|
||||
|
||||
// 将下载的文件流保存到本地文件
|
||||
using (var fs = File.OpenWrite(localFilePath))
|
||||
{
|
||||
await result.Content.CopyToAsync(fs);
|
||||
result.Content.CopyTo(fs);
|
||||
fs.Close();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -478,96 +449,6 @@ public class OSSService : IOSSService
|
|||
|
||||
}
|
||||
|
||||
public async Task<Stream> GetStreamFromOSSAsync(string ossRelativePath)
|
||||
{
|
||||
BackBatchGetToken();
|
||||
ossRelativePath = ossRelativePath.TrimStart('/');
|
||||
|
||||
try
|
||||
{
|
||||
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
|
||||
{
|
||||
var aliConfig = ObjectStoreServiceOptions.AliyunOSS;
|
||||
|
||||
var _ossClient = new OssClient(
|
||||
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? aliConfig.EndPoint : aliConfig.InternalEndpoint,
|
||||
AliyunOSSTempToken.AccessKeyId,
|
||||
AliyunOSSTempToken.AccessKeySecret,
|
||||
AliyunOSSTempToken.SecurityToken
|
||||
);
|
||||
|
||||
var result = _ossClient.GetObject(aliConfig.BucketName, ossRelativePath);
|
||||
|
||||
// 将OSS返回的流复制到内存流中并返回
|
||||
var memoryStream = new MemoryStream();
|
||||
await result.Content.CopyToAsync(memoryStream);
|
||||
memoryStream.Position = 0; // 重置位置以便读取
|
||||
return memoryStream;
|
||||
}
|
||||
else if (ObjectStoreServiceOptions.ObjectStoreUse == "MinIO")
|
||||
{
|
||||
var minIOConfig = ObjectStoreServiceOptions.MinIO;
|
||||
|
||||
var minioClient = new MinioClient()
|
||||
.WithEndpoint($"{minIOConfig.EndPoint}:{minIOConfig.Port}")
|
||||
.WithCredentials(minIOConfig.AccessKeyId, minIOConfig.SecretAccessKey)
|
||||
.WithSSL(minIOConfig.UseSSL)
|
||||
.Build();
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
|
||||
var getObjectArgs = new GetObjectArgs()
|
||||
.WithBucket(minIOConfig.BucketName)
|
||||
.WithObject(ossRelativePath)
|
||||
.WithCallbackStream(stream => stream.CopyToAsync(memoryStream));
|
||||
|
||||
await minioClient.GetObjectAsync(getObjectArgs);
|
||||
memoryStream.Position = 0;
|
||||
return memoryStream;
|
||||
}
|
||||
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
||||
{
|
||||
var awsConfig = ObjectStoreServiceOptions.AWS;
|
||||
|
||||
var credentials = new SessionAWSCredentials(
|
||||
AWSTempToken.AccessKeyId,
|
||||
AWSTempToken.SecretAccessKey,
|
||||
AWSTempToken.SessionToken
|
||||
);
|
||||
|
||||
var clientConfig = new AmazonS3Config
|
||||
{
|
||||
RegionEndpoint = RegionEndpoint.USEast1,
|
||||
UseHttp = true,
|
||||
};
|
||||
|
||||
var amazonS3Client = new AmazonS3Client(credentials, clientConfig);
|
||||
|
||||
var getObjectRequest = new Amazon.S3.Model.GetObjectRequest
|
||||
{
|
||||
BucketName = awsConfig.BucketName,
|
||||
Key = ossRelativePath
|
||||
};
|
||||
|
||||
var response = await amazonS3Client.GetObjectAsync(getObjectRequest);
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
await response.ResponseStream.CopyToAsync(memoryStream);
|
||||
memoryStream.Position = 0;
|
||||
return memoryStream;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new BusinessValidationFailedException("未定义的存储介质类型");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new BusinessValidationFailedException("oss流获取失败! " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task<string> GetSignedUrl(string ossRelativePath)
|
||||
{
|
||||
GetObjectStoreTempToken();
|
||||
|
@ -1124,9 +1005,14 @@ public class OSSService : IOSSService
|
|||
}
|
||||
}
|
||||
|
||||
private bool isFirstCall = true;
|
||||
public async Task<long> GetObjectSizeAsync(string sourcePath)
|
||||
{
|
||||
BackBatchGetToken();
|
||||
if (isFirstCall)
|
||||
{
|
||||
GetObjectStoreTempToken();
|
||||
isFirstCall = false;
|
||||
}
|
||||
|
||||
|
||||
var objectkey = sourcePath.Trim('/');
|
||||
|
@ -1140,7 +1026,7 @@ public class OSSService : IOSSService
|
|||
var key = HttpUtility.UrlDecode(objectkey);
|
||||
var metadata = _ossClient.GetObjectMetadata(aliConfig.BucketName, key);
|
||||
|
||||
long fileSize = metadata?.ContentLength ?? 0; // 文件大小(字节)
|
||||
long fileSize = metadata?.ContentLength??0; // 文件大小(字节)
|
||||
|
||||
return fileSize;
|
||||
}
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IRaCIS.Core.Application.Helper
|
||||
{
|
||||
public static class SafeBussinessHelper
|
||||
{
|
||||
public static async Task<bool> RunAsync(Func<Task> func, [CallerMemberName] string caller = "", string errorMsgTitle = "")
|
||||
{
|
||||
try
|
||||
{
|
||||
await func();
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Logger.Error($"【{errorMsgTitle}失败 - {caller}】: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<(bool Success, T? Result)> RunAsync<T>(Func<Task<T>> func, [CallerMemberName] string caller = "", string errorMsgTitle = "")
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await func();
|
||||
return (true, result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Logger.Error($"【{errorMsgTitle}失败 - {caller}】: {ex.Message}");
|
||||
return (false, default);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1111,13 +1111,6 @@
|
|||
<param name="trialId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.TrialImageDownloadService.DownloadAndUploadTrialData(System.Guid,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomInstance},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomStudy},IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomSeries})">
|
||||
<summary>
|
||||
下载影像 维护dir信息 并回传到OSS
|
||||
</summary>
|
||||
<param name="trialId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:IRaCIS.Core.Application.Service.AttachmentService">
|
||||
<summary>
|
||||
医生文档关联关系维护
|
||||
|
@ -10923,11 +10916,6 @@
|
|||
Parent字典code
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingQuestionTrialView.ExcludeShowVisitList">
|
||||
<summary>
|
||||
排除显示的访视名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.ReadingQuestionTrialView.ReadingQuestionCriterionTrialId">
|
||||
<summary>
|
||||
系统标准Id
|
||||
|
@ -11798,11 +11786,6 @@
|
|||
分类显示类型 是否显示
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.AddOrUpdateReadingQuestionTrialInDto.ExcludeShowVisitList">
|
||||
<summary>
|
||||
排除显示的访视名称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:IRaCIS.Core.Application.Service.Reading.Dto.AddOrUpdateReadingQuestionTrialInDto.HighlightAnswer">
|
||||
<summary>
|
||||
高亮问题的答案
|
||||
|
@ -14108,13 +14091,6 @@
|
|||
计划外访视 获取受试者选择下拉框列表
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.VisitPlanService.GetVisitStage(IRaCIS.Application.Contracts.GetVisitStageInDto)">
|
||||
<summary>
|
||||
获取项目访视计划
|
||||
</summary>
|
||||
<param name="inDto"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Service.VisitPlanService.GetTrialVisitStageList(IRaCIS.Application.Contracts.VisitPlanQueryDTO)">
|
||||
暂时不用
|
||||
<summary> 获取项目访视计划</summary>
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace IRaCIS.Core.Application.Service
|
|||
/// 系统模板文档配置表
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(GroupName = "Common")]
|
||||
public class CommonDocumentService(IRepository<CommonDocument> _commonDocumentRepository,
|
||||
public class CommonDocumentService(IRepository<CommonDocument> _commonDocumentRepository,
|
||||
IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IWebHostEnvironment _hostEnvironment) : BaseService, ICommonDocumentService
|
||||
{
|
||||
|
||||
|
@ -36,14 +36,6 @@ namespace IRaCIS.Core.Application.Service
|
|||
return await commonDocumentQueryable.ToPagedListAsync(queryCommonDocument);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<CommonDocument> GetCommonDocument(string code)
|
||||
{
|
||||
var find = await _commonDocumentRepository.Where(t => t.Code == code).FirstOrDefaultAsync();
|
||||
|
||||
return find;
|
||||
}
|
||||
|
||||
|
||||
public async Task<IResponseOutput> AddOrUpdateCommonDocument(CommonDocumentAddOrEdit addOrEditCommonDocument)
|
||||
{
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
using DocumentFormat.OpenXml.EMMA;
|
||||
using FellowOakDicom;
|
||||
using FellowOakDicom.Imaging;
|
||||
using FellowOakDicom.Imaging.Render;
|
||||
using FellowOakDicom.IO.Buffer;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using MassTransit;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SharpCompress.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -45,14 +41,12 @@ namespace IRaCIS.Core.Application.Service
|
|||
[AllowAnonymous]
|
||||
public async Task<IResponseOutput> DownloadTrialImage(Guid trialId)
|
||||
{
|
||||
//var subjectCodeList = new List<string>() { "05002", "07006", "07026" };
|
||||
var subjectCodeList = new List<string>() { "05002", "07006", "07026" };
|
||||
var downloadInfo = _trialRepository.Where(t => t.Id == trialId).Select(t => new
|
||||
{
|
||||
t.ResearchProgramNo,
|
||||
|
||||
VisitList = t.SubjectVisitList
|
||||
//.Where(t=>subjectCodeList.Contains(t.Subject.Code))
|
||||
.Select(sv => new
|
||||
VisitList = t.SubjectVisitList.Where(t=>subjectCodeList.Contains(t.Subject.Code)).Select(sv => new
|
||||
{
|
||||
TrialSiteCode = sv.TrialSite.TrialSiteCode,
|
||||
SubjectCode = sv.Subject.Code,
|
||||
|
@ -63,11 +57,11 @@ namespace IRaCIS.Core.Application.Service
|
|||
u.StudyTime,
|
||||
u.StudyCode,
|
||||
|
||||
SeriesList = u.SeriesList.Where(t => t.IsReading).Select(z => new
|
||||
SeriesList = u.SeriesList.Select(z => new
|
||||
{
|
||||
z.Modality,
|
||||
|
||||
InstancePathList = z.DicomInstanceList.Where(t => t.IsReading).Select(k => new
|
||||
InstancePathList = z.DicomInstanceList.Select(k => new
|
||||
{
|
||||
k.Path
|
||||
}).ToList()
|
||||
|
@ -75,13 +69,13 @@ namespace IRaCIS.Core.Application.Service
|
|||
|
||||
}).ToList(),
|
||||
|
||||
NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => t.IsReading).Select(nd => new
|
||||
NoneDicomStudyList = sv.NoneDicomStudyList.Select(nd => new
|
||||
{
|
||||
nd.Modality,
|
||||
nd.StudyCode,
|
||||
nd.ImageDate,
|
||||
|
||||
FileList = nd.NoneDicomFileList.Where(t => t.IsReading).Select(file => new
|
||||
FileList = nd.NoneDicomFileList.Select(file => new
|
||||
{
|
||||
file.FileName,
|
||||
file.Path,
|
||||
|
@ -94,17 +88,12 @@ namespace IRaCIS.Core.Application.Service
|
|||
|
||||
|
||||
var count = downloadInfo.VisitList.SelectMany(t => t.NoneDicomStudyList).SelectMany(t => t.FileList).Count();
|
||||
var count2 = downloadInfo.VisitList.SelectMany(t => t.StudyList).SelectMany(t => t.SeriesList).SelectMany(t => t.InstancePathList).Count();
|
||||
|
||||
Console.WriteLine($"下载总数量:{count}+{count2}={count + count2}");
|
||||
var count2 = downloadInfo.VisitList.SelectMany(t => t.StudyList).SelectMany(t => t.SeriesList).SelectMany(t=>t.InstancePathList).Count();
|
||||
|
||||
if (downloadInfo != null)
|
||||
{
|
||||
var downloadJobs = new List<Func<Task>>();
|
||||
|
||||
var rootFolder = @"E:\DownloadImage";
|
||||
|
||||
//var rootFolder = FileStoreHelper.GetDonwnloadImageFolder(_hostEnvironment);
|
||||
var rootFolder = FileStoreHelper.GetDonwnloadImageFolder(_hostEnvironment);
|
||||
|
||||
// 获取无效字符(系统定义的)
|
||||
string invalidChars = new string(Path.GetInvalidFileNameChars()) + new string(Path.GetInvalidPathChars());
|
||||
|
@ -152,16 +141,12 @@ namespace IRaCIS.Core.Application.Service
|
|||
// 复制文件到相应的文件夹
|
||||
string destinationPath = Path.Combine(studyDicomFolderPath, Path.GetFileName(instanceInfo.Path));
|
||||
|
||||
|
||||
//加入到下载任务里
|
||||
downloadJobs.Add(() => _oSSService.DownLoadFromOSSAsync(instanceInfo.Path, destinationPath));
|
||||
|
||||
//下载到当前目录
|
||||
//await _oSSService.DownLoadFromOSSAsync(instanceInfo.Path, destinationPath);
|
||||
await _oSSService.DownLoadFromOSSAsync(instanceInfo.Path, destinationPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
foreach (var noneDicomStudy in visitItem.NoneDicomStudyList)
|
||||
|
@ -174,59 +159,15 @@ namespace IRaCIS.Core.Application.Service
|
|||
{
|
||||
string destinationPath = Path.Combine(studyNoneDicomFolderPath, Path.GetFileName(file.FileName));
|
||||
|
||||
//加入到下载任务里
|
||||
downloadJobs.Add(() => _oSSService.DownLoadFromOSSAsync(HttpUtility.UrlDecode(file.Path), destinationPath));
|
||||
//下载到当前目录
|
||||
//await _oSSService.DownLoadFromOSSAsync(HttpUtility.UrlDecode(file.Path), destinationPath);
|
||||
await _oSSService.DownLoadFromOSSAsync(HttpUtility.UrlDecode(file.Path), destinationPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#region 异步方式处理
|
||||
|
||||
int totalCount = downloadJobs.Count;
|
||||
int downloadedCount = 0;
|
||||
|
||||
foreach (var job in downloadJobs)
|
||||
{
|
||||
try
|
||||
{
|
||||
await job();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"下载失败: {ex.Message}");
|
||||
}
|
||||
|
||||
downloadedCount++;
|
||||
|
||||
// 每处理50个,输出一次进度(或最后一个时也输出)
|
||||
if (downloadedCount % 50 == 0 || downloadedCount == totalCount)
|
||||
{
|
||||
Console.WriteLine($"已下载 {downloadedCount} / {totalCount} 个文件,完成 {(downloadedCount * 100.0 / totalCount):F2}%");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 多线程测试
|
||||
|
||||
//const int batchSize = 15;
|
||||
//int totalCount = downloadJobs.Count;
|
||||
//int downloadedCount = 0;
|
||||
|
||||
//for (int i = 0; i < downloadJobs.Count; i += batchSize)
|
||||
//{
|
||||
// var batch = downloadJobs.Skip(i).Take(batchSize).Select(job => job());
|
||||
|
||||
// await Task.WhenAll(batch);
|
||||
|
||||
// downloadedCount += batch.Count();
|
||||
|
||||
// Console.WriteLine($"已下载 {downloadedCount} / {totalCount} 个文件,完成 {(downloadedCount * 100.0 / totalCount):F2}%");
|
||||
//}
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
|
@ -235,105 +176,6 @@ namespace IRaCIS.Core.Application.Service
|
|||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 下载影像 维护dir信息 并回传到OSS
|
||||
/// </summary>
|
||||
/// <param name="trialId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[AllowAnonymous]
|
||||
public async Task<IResponseOutput> DownloadAndUploadTrialData(Guid trialId, [FromServices] IRepository<DicomInstance> _instanceRepository,
|
||||
[FromServices] IRepository<DicomStudy> _studyRepository,
|
||||
[FromServices] IRepository<DicomSeries> _seriesRepository)
|
||||
{
|
||||
var list = await _instanceRepository.Where(t => t.TrialId == trialId && t.SubjectVisitId == Guid.Parse("01000000-0a00-0242-bd20-08dcce543ded" ) && t.DicomStudy.ModalityForEdit == "IVUS")
|
||||
.Select(t => new { t.SeriesId, t.StudyId, t.Id, t.Path }).ToListAsync();
|
||||
|
||||
int totalCount = list.Count;
|
||||
int dealCount = 0;
|
||||
foreach (var item in list)
|
||||
{
|
||||
|
||||
var stream = await _oSSService.GetStreamFromOSSAsync(item.Path);
|
||||
|
||||
var dicomFile = DicomFile.Open(stream);
|
||||
|
||||
// 获取 Pixel Data 标签
|
||||
var pixelData = DicomPixelData.Create(dicomFile.Dataset);
|
||||
|
||||
//获取像素是否为封装形式
|
||||
var syntax = dicomFile.Dataset.InternalTransferSyntax;
|
||||
|
||||
//对于封装像素的文件做转换
|
||||
if (syntax.IsEncapsulated)
|
||||
{
|
||||
// 创建一个新的片段序列
|
||||
var newFragments = new DicomOtherByteFragment(DicomTag.PixelData);
|
||||
// 获取每帧数据并封装为单独的片段
|
||||
for (int n = 0; n < pixelData.NumberOfFrames; n++)
|
||||
{
|
||||
var frameData = pixelData.GetFrame(n);
|
||||
newFragments.Fragments.Add(new MemoryByteBuffer(frameData.Data));
|
||||
}
|
||||
// 替换原有的片段序列
|
||||
dicomFile.Dataset.AddOrUpdate(newFragments);
|
||||
}
|
||||
|
||||
|
||||
#region 获取dir信息 维护数据库三个表数据
|
||||
|
||||
var dirInfo = DicomDIRHelper.ReadDicomDIRInfo(dicomFile);
|
||||
|
||||
await _instanceRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Id,
|
||||
u => new DicomInstance()
|
||||
{
|
||||
IsEncapsulated= syntax.IsEncapsulated,
|
||||
TransferSytaxUID = dirInfo.TransferSytaxUID,
|
||||
SOPClassUID = dirInfo.SOPClassUID,
|
||||
MediaStorageSOPClassUID = dirInfo.MediaStorageSOPClassUID,
|
||||
MediaStorageSOPInstanceUID = dirInfo.MediaStorageSOPInstanceUID
|
||||
}, false);
|
||||
|
||||
await _seriesRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.SeriesId,
|
||||
u => new DicomSeries()
|
||||
{
|
||||
DicomSeriesDate = dirInfo.DicomSeriesDate,
|
||||
DicomSeriesTime = dirInfo.DicomSeriesTime,
|
||||
}, false);
|
||||
|
||||
await _studyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.StudyId,
|
||||
u => new DicomStudy()
|
||||
{
|
||||
DicomStudyDate = dirInfo.DicomStudyDate,
|
||||
DicomStudyTime = dirInfo.DicomStudyTime
|
||||
}, false);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
//保存到内存流
|
||||
using var memoryStream = new MemoryStream();
|
||||
dicomFile.Save(memoryStream);
|
||||
memoryStream.Position = 0;
|
||||
|
||||
//获取原始目录 和文件名
|
||||
var folder = item.Path.Substring(0, item.Path.LastIndexOf('/')).TrimStart('/');
|
||||
var fileName = Path.GetFileName(item.Path);
|
||||
|
||||
//dicomFile.Save($"download_{Guid.NewGuid()}");
|
||||
|
||||
await _oSSService.UploadToOSSAsync(memoryStream, folder, fileName, false);
|
||||
|
||||
dealCount++;
|
||||
|
||||
Console.WriteLine($"{DateTime.Now}已下载 {dealCount} / {totalCount} 个文件,完成 {(dealCount * 100.0 / totalCount):F2}%");
|
||||
}
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -136,7 +136,7 @@ namespace IRaCIS.Core.Application.Services
|
|||
var beforeUserTypeIds = document.NeedConfirmedUserTypeList.Select(x => x.NeedConfirmUserTypeId).ToList();
|
||||
|
||||
_mapper.Map(addOrEditSystemDocument, document);
|
||||
document.UpdateTime = DateTime.Now;
|
||||
|
||||
#region 之前区分路径文件夹 现在不区分废弃
|
||||
|
||||
//if (document.FileTypeId != addOrEditSystemDocument.FileTypeId)
|
||||
|
|
|
@ -1064,7 +1064,7 @@ namespace IRaCIS.Core.Application.Services
|
|||
var beforeUserTypeIds = document.NeedConfirmedUserTypeList.Select(x => x.NeedConfirmUserTypeId).ToList();
|
||||
|
||||
_mapper.Map(addOrEditTrialDocument, document);
|
||||
document.UpdateTime = DateTime.Now;
|
||||
|
||||
#region 不区分路径了
|
||||
|
||||
//if (document.FileTypeId != addOrEditTrialDocument.FileTypeId)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using FellowOakDicom;
|
||||
using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
|
||||
using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using Newtonsoft.Json;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
@ -324,14 +323,9 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
|
||||
public string BodyPartExamined { get; set; } = string.Empty;
|
||||
|
||||
public string DicomStudyDate { get; set; }
|
||||
|
||||
public string DicomStudyTime { get; set; }
|
||||
|
||||
public List<AddOrUpdateSeriesDto> SeriesList { get; set; }
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class AddOrUpdateSeriesDto
|
||||
|
@ -357,12 +351,6 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
public string TriggerTime { get; set; } = string.Empty;
|
||||
|
||||
public string ImageResizePath { get; set; } = string.Empty;
|
||||
|
||||
public string DicomSeriesDate { get; set; }
|
||||
|
||||
public string DicomSeriesTime { get; set; }
|
||||
|
||||
|
||||
public List<AddInstanceDto> InstanceList { get; set; }
|
||||
|
||||
public Guid? VisitTaskId { get; set; }
|
||||
|
@ -397,17 +385,6 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
public string HtmlPath { get; set; } = string.Empty;
|
||||
|
||||
public long FileSize { get; set; }
|
||||
|
||||
public string SOPClassUID { get; set; }
|
||||
|
||||
public string MediaStorageSOPClassUID { get; set; }
|
||||
|
||||
public string TransferSytaxUID { get; set; }
|
||||
|
||||
public string MediaStorageSOPInstanceUID { get; set; }
|
||||
|
||||
public bool IsEncapsulated => DicomTransferSyntax.Lookup(DicomUID.Parse(TransferSytaxUID)).IsEncapsulated;
|
||||
|
||||
}
|
||||
|
||||
public class CRCUploadTaskQuery
|
||||
|
@ -525,69 +502,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
|
||||
}
|
||||
|
||||
#region 下载重新生成名字
|
||||
public class ImageDownloadDto
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
public Guid SubjectId { get; set; }
|
||||
public string SubjectCode { get; set; }
|
||||
public string TrialSiteCode { get; set; }
|
||||
public string VisitName { get; set; }
|
||||
|
||||
public string TaskBlindName { get; set; }
|
||||
|
||||
|
||||
public Guid VisitId { get; set; }
|
||||
|
||||
public List<DownloadDicomStudyDto> StudyList { get; set; }
|
||||
public List<DownloadNoneDicomStudyDto> NoneDicomStudyList { get; set; }
|
||||
}
|
||||
|
||||
public class DownloadDicomStudyDto
|
||||
{
|
||||
public string PatientId { get; set; }
|
||||
public DateTime? StudyTime { get; set; }
|
||||
public string StudyCode { get; set; }
|
||||
public string StudyInstanceUid { get; set; }
|
||||
public string StudyDIRPath { get; set; }
|
||||
|
||||
public List<DownloadDicomSeriesDto> SeriesList { get; set; }
|
||||
}
|
||||
|
||||
public class DownloadDicomSeriesDto
|
||||
{
|
||||
public string Modality { get; set; }
|
||||
|
||||
public List<DownloadDicomInstanceDto> InstanceList { get; set; }
|
||||
}
|
||||
|
||||
public class DownloadDicomInstanceDto
|
||||
{
|
||||
public bool IsEncapsulated { get; set; }
|
||||
public Guid InstanceId { get; set; }
|
||||
public string FileName { get; set; }
|
||||
public string Path { get; set; }
|
||||
public long? FileSize { get; set; }
|
||||
}
|
||||
|
||||
public class DownloadNoneDicomStudyDto
|
||||
{
|
||||
public string Modality { get; set; }
|
||||
public string StudyCode { get; set; }
|
||||
public DateTime? ImageDate { get; set; }
|
||||
|
||||
public List<DownloadNoneDicomFileDto> FileList { get; set; } = new();
|
||||
}
|
||||
|
||||
public class DownloadNoneDicomFileDto
|
||||
{
|
||||
public string FileName { get; set; }
|
||||
public string Path { get; set; }
|
||||
public string FileType { get; set; }
|
||||
public long? FileSize { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public class CRCUploadedStudyQuqry
|
||||
{
|
||||
|
@ -679,9 +594,6 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
|
||||
|
||||
public bool IsKeyImage { get; set; }
|
||||
|
||||
// true 导出阅片,null 就是所有影像
|
||||
public bool? IsExportReading { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
@ -725,16 +637,10 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
|
||||
public long? TotalImageSize { get; set; }
|
||||
|
||||
public long? TotalReadingImageSize { get; set; }
|
||||
|
||||
public string TotalImageSizeStr => TotalImageSize.HasValue
|
||||
? $"{TotalImageSize.Value / 1024d / 1024d:F3} MB"
|
||||
: "0.000 MB";
|
||||
|
||||
public string TotalReadingImageSizeStr => TotalReadingImageSize.HasValue
|
||||
? $"{TotalReadingImageSize.Value / 1024d / 1024d:F3} MB"
|
||||
: "0.000 MB";
|
||||
|
||||
public string ImageTypeStr => $"{(IsHaveDicom ? "DICOM" : "")}{(IsHaveNoneDicom&&IsHaveDicom?" , ":"")}{(IsHaveNoneDicom ? "Non-DICOM" : "")}";
|
||||
|
||||
public bool IsHaveDicom { get; set; }
|
||||
|
@ -786,22 +692,6 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
? $"{TotalImageSize.Value / SubjectVisitCount / 1024d / 1024d:F3} MB"
|
||||
: "0.000 MB";
|
||||
|
||||
public long? TotalReadingImageSize { get; set; }
|
||||
|
||||
|
||||
public string TotalReadingImageSizeStr => TotalReadingImageSize.HasValue
|
||||
? $"{TotalReadingImageSize.Value / 1024d / 1024d:F3} MB"
|
||||
: "0.000 MB";
|
||||
|
||||
|
||||
public string SubjectReadingImageAVGSizeStr => TotalReadingImageSize.HasValue
|
||||
? $"{TotalReadingImageSize.Value / SubjectCount / 1024d / 1024d:F3} MB"
|
||||
: "0.000 MB";
|
||||
|
||||
|
||||
public string SubjectVisitReadingImageAVGSizeStr => TotalReadingImageSize.HasValue
|
||||
? $"{TotalReadingImageSize.Value / SubjectVisitCount / 1024d / 1024d:F3} MB"
|
||||
: "0.000 MB";
|
||||
|
||||
}
|
||||
public class TrialImageDownloadView
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using DocumentFormat.OpenXml.EMMA;
|
||||
using FellowOakDicom;
|
||||
using FellowOakDicom.Media;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
|
@ -15,11 +14,9 @@ using MassTransit;
|
|||
using MassTransit.Initializers;
|
||||
using Medallion.Threading;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NetTopologySuite.Mathematics;
|
||||
using Newtonsoft.Json;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
|
@ -35,7 +32,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
}
|
||||
|
||||
[ApiExplorerSettings(GroupName = "Trial")]
|
||||
public class DownloadAndUploadService(IRepository<SystemAnonymization> _systemAnonymizationRepository, IRepository<DicomStudy> _dicomStudyRepository,
|
||||
public class DownloadAndUploadService(IRepository<SystemAnonymization> _systemAnonymizationRepository,
|
||||
IRepository<VisitTask> _visitTaskRepository,
|
||||
IRepository<SubjectVisit> _subjectVisitRepository,
|
||||
IOSSService _oSSService,
|
||||
|
@ -782,137 +779,58 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
|
||||
var imageType = (isQueryDicom && isQueryNoneDicom) ? ImageType.DicomAndNoneDicom : (isQueryDicom ? ImageType.Dicom : ImageType.NoneDicom);
|
||||
|
||||
var dirDic = new Dictionary<string, string>();
|
||||
#region DIR处理导出文件名,并将对应关系上传到OSS里面存储
|
||||
|
||||
//有传输语法值的导出 才生成DIR
|
||||
if (_subjectVisitRepository.Where(t => t.Id == inQuery.SubjectVisitId).SelectMany(t => t.StudyList.SelectMany(t => t.InstanceList)).All(c => c.TransferSytaxUID != string.Empty))
|
||||
{
|
||||
var list = _subjectVisitRepository.Where(t => t.Id == inQuery.SubjectVisitId).SelectMany(t => t.StudyList)
|
||||
.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
|
||||
.SelectMany(t => t.InstanceList)
|
||||
.Select(t => new StudyDIRInfo()
|
||||
{
|
||||
|
||||
DicomStudyId = t.DicomStudy.Id,
|
||||
|
||||
PatientId = t.DicomStudy.PatientId,
|
||||
PatientName = t.DicomStudy.PatientName,
|
||||
PatientBirthDate = t.DicomStudy.PatientBirthDate,
|
||||
PatientSex = t.DicomStudy.PatientSex,
|
||||
|
||||
StudyInstanceUid = t.StudyInstanceUid,
|
||||
StudyId = t.DicomStudy.StudyId,
|
||||
DicomStudyDate = t.DicomStudy.DicomStudyDate,
|
||||
DicomStudyTime = t.DicomStudy.DicomStudyTime,
|
||||
AccessionNumber = t.DicomStudy.AccessionNumber,
|
||||
|
||||
StudyDescription = t.DicomStudy.Description,
|
||||
|
||||
SeriesInstanceUid = t.DicomSerie.SeriesInstanceUid,
|
||||
Modality = t.DicomSerie.Modality,
|
||||
DicomSeriesDate = t.DicomSerie.DicomSeriesDate,
|
||||
DicomSeriesTime = t.DicomSerie.DicomSeriesTime,
|
||||
SeriesNumber = t.DicomSerie.SeriesNumber,
|
||||
SeriesDescription = t.DicomSerie.Description,
|
||||
|
||||
InstanceId = t.Id,
|
||||
SopInstanceUid = t.SopInstanceUid,
|
||||
SOPClassUID = t.SOPClassUID,
|
||||
InstanceNumber = t.InstanceNumber,
|
||||
MediaStorageSOPClassUID = t.MediaStorageSOPClassUID,
|
||||
MediaStorageSOPInstanceUID = t.MediaStorageSOPInstanceUID,
|
||||
TransferSytaxUID = t.TransferSytaxUID,
|
||||
|
||||
}).ToList();
|
||||
|
||||
var pathInfo = await _subjectVisitRepository.Where(t => t.Id == inQuery.SubjectVisitId).Select(t => new { t.TrialId, t.SubjectId, VisitId = t.Id }).FirstNotNullAsync();
|
||||
|
||||
foreach (var item in list.GroupBy(t => new { t.StudyInstanceUid, t.DicomStudyId }))
|
||||
{
|
||||
var ossFolder = $"{pathInfo.TrialId}/Image/{pathInfo.SubjectId}/{pathInfo.VisitId}/{item.Key.StudyInstanceUid}";
|
||||
|
||||
var isSucess = await SafeBussinessHelper.RunAsync(async () => await DicomDIRHelper.GenerateStudyDIRAndUploadAsync(item.ToList(), dirDic, ossFolder, _oSSService));
|
||||
|
||||
|
||||
if (isSucess)
|
||||
{
|
||||
await _dicomStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new DicomStudy() { StudyDIRPath = $"/{ossFolder}/DICOMDIR" });
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
var query = from sv in _subjectVisitRepository.Where(t => t.Id == inQuery.SubjectVisitId)
|
||||
|
||||
|
||||
select new ImageDownloadDto()
|
||||
select new
|
||||
{
|
||||
TrialId = sv.TrialId,
|
||||
SubjectId = sv.SubjectId,
|
||||
SubjectCode = sv.Subject.Code,
|
||||
TrialSiteCode = sv.TrialSite.TrialSiteCode,
|
||||
VisitName = sv.VisitName,
|
||||
VisitId = sv.Id,
|
||||
|
||||
StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
|
||||
|
||||
.Select(u => new DownloadDicomStudyDto()
|
||||
.Select(u => new
|
||||
{
|
||||
PatientId = u.PatientId,
|
||||
StudyTime = u.StudyTime,
|
||||
StudyCode = u.StudyCode,
|
||||
StudyInstanceUid = u.StudyInstanceUid,
|
||||
StudyDIRPath = u.StudyDIRPath,
|
||||
u.PatientId,
|
||||
u.StudyTime,
|
||||
u.StudyCode,
|
||||
|
||||
SeriesList = u.SeriesList.Select(z => new DownloadDicomSeriesDto()
|
||||
SeriesList = u.SeriesList.Select(z => new
|
||||
{
|
||||
Modality = z.Modality,
|
||||
z.Modality,
|
||||
|
||||
InstanceList = z.DicomInstanceList.Select(k => new DownloadDicomInstanceDto()
|
||||
InstanceList = z.DicomInstanceList.Select(k => new
|
||||
{
|
||||
IsEncapsulated = k.IsEncapsulated,
|
||||
InstanceId = k.Id,
|
||||
FileName = string.Empty,
|
||||
Path = k.Path,
|
||||
FileSize = k.FileSize
|
||||
}).ToList()
|
||||
}).ToList()
|
||||
k.Path,
|
||||
k.FileSize
|
||||
})
|
||||
})
|
||||
|
||||
}).ToList(),
|
||||
|
||||
NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => isQueryNoneDicom ? inQuery.NoneDicomStudyIdList.Contains(t.Id) : false)
|
||||
|
||||
.Select(nd => new DownloadNoneDicomStudyDto()
|
||||
.Select(nd => new
|
||||
{
|
||||
Modality = nd.Modality,
|
||||
StudyCode = nd.StudyCode,
|
||||
ImageDate = nd.ImageDate,
|
||||
nd.Modality,
|
||||
nd.StudyCode,
|
||||
nd.ImageDate,
|
||||
|
||||
FileList = nd.NoneDicomFileList.Select(file => new DownloadNoneDicomFileDto()
|
||||
FileList = nd.NoneDicomFileList.Select(file => new
|
||||
{
|
||||
FileName = file.FileName,
|
||||
Path = file.Path,
|
||||
FileType = file.FileType,
|
||||
FileSize = file.FileSize
|
||||
}).ToList()
|
||||
file.FileName,
|
||||
file.Path,
|
||||
file.FileType,
|
||||
file.FileSize,
|
||||
})
|
||||
}).ToList()
|
||||
};
|
||||
|
||||
var result = query.FirstOrDefault();
|
||||
|
||||
foreach (var item in result.StudyList.SelectMany(t => t.SeriesList).SelectMany(t => t.InstanceList))
|
||||
{
|
||||
var key = item.InstanceId.ToString();
|
||||
if (dirDic.ContainsKey(key))
|
||||
{
|
||||
item.FileName = dirDic[key];
|
||||
}
|
||||
}
|
||||
|
||||
var preDownloadInfo = new TrialImageDownload()
|
||||
{
|
||||
Id = NewId.NextSequentialGuid(),
|
||||
|
@ -1086,143 +1004,59 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
|
||||
var trialSiteCode = _visitTaskRepository.Where(t => t.Id == taskIdList.FirstOrDefault()).Select(t => t.IsAnalysisCreate ? t.BlindTrialSiteCode : t.Subject.TrialSite.TrialSiteCode).FirstOrDefault() ?? string.Empty;
|
||||
|
||||
var dirDic = new Dictionary<string, string>();
|
||||
#region 在下载前先处理DIR文件
|
||||
|
||||
//有传输语法值的导出 才生成DIR
|
||||
if (_subjectVisitRepository.Where(t => t.SubjectId == inQuery.SubjectId).SelectMany(t => t.StudyList.SelectMany(t => t.InstanceList)).All(c => c.TransferSytaxUID != string.Empty))
|
||||
{
|
||||
var dirInfolist = _subjectRepository.Where(t => t.Id == inQuery.SubjectId).SelectMany(t => t.SubjectVisitList.Where(t => subjectVisitIdList.Contains(t.Id))).SelectMany(t => t.StudyList)
|
||||
.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
|
||||
.Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true)
|
||||
.SelectMany(t => t.InstanceList.Where(t => t.IsReading && t.DicomSerie.IsReading))
|
||||
.Select(t => new StudyDIRInfo()
|
||||
{
|
||||
SubjectVisitId = t.SubjectVisitId,
|
||||
|
||||
DicomStudyId = t.DicomStudy.Id,
|
||||
|
||||
PatientId = t.DicomStudy.PatientId,
|
||||
PatientName = t.DicomStudy.PatientName,
|
||||
PatientBirthDate = t.DicomStudy.PatientBirthDate,
|
||||
PatientSex = t.DicomStudy.PatientSex,
|
||||
|
||||
StudyInstanceUid = t.StudyInstanceUid,
|
||||
StudyId = t.DicomStudy.StudyId,
|
||||
DicomStudyDate = t.DicomStudy.DicomStudyDate,
|
||||
DicomStudyTime = t.DicomStudy.DicomStudyTime,
|
||||
AccessionNumber = t.DicomStudy.AccessionNumber,
|
||||
|
||||
StudyDescription = t.DicomStudy.Description,
|
||||
|
||||
SeriesInstanceUid = t.DicomSerie.SeriesInstanceUid,
|
||||
Modality = t.DicomSerie.Modality,
|
||||
DicomSeriesDate = t.DicomSerie.DicomSeriesDate,
|
||||
DicomSeriesTime = t.DicomSerie.DicomSeriesTime,
|
||||
SeriesNumber = t.DicomSerie.SeriesNumber,
|
||||
SeriesDescription = t.DicomSerie.Description,
|
||||
|
||||
InstanceId = t.Id,
|
||||
SopInstanceUid = t.SopInstanceUid,
|
||||
SOPClassUID = t.SOPClassUID,
|
||||
InstanceNumber = t.InstanceNumber,
|
||||
MediaStorageSOPClassUID = t.MediaStorageSOPClassUID,
|
||||
MediaStorageSOPInstanceUID = t.MediaStorageSOPInstanceUID,
|
||||
TransferSytaxUID = t.TransferSytaxUID,
|
||||
|
||||
}).ToList();
|
||||
|
||||
var pathInfo = await _subjectRepository.Where(t => t.Id == inQuery.SubjectId).Select(t => new { t.TrialId, SubjectId = t.Id }).FirstNotNullAsync();
|
||||
|
||||
foreach (var item in dirInfolist.GroupBy(t => new { t.StudyInstanceUid, t.DicomStudyId }))
|
||||
{
|
||||
var visitId = item.First().SubjectVisitId;
|
||||
|
||||
var ossFolder = $"{pathInfo.TrialId}/Image/{pathInfo.SubjectId}/{visitId}/{item.Key.StudyInstanceUid}";
|
||||
|
||||
var isSucess = await SafeBussinessHelper.RunAsync(async () => await DicomDIRHelper.GenerateStudyDIRAndUploadAsync(item.ToList(), dirDic, ossFolder, _oSSService));
|
||||
|
||||
|
||||
if (isSucess)
|
||||
{
|
||||
await _dicomStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new DicomStudy() { StudyDIRPath = $"/{ossFolder}/DICOMDIR" });
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
var query = from sv in _subjectRepository.Where(t => t.Id == inQuery.SubjectId).SelectMany(t => t.SubjectVisitList.Where(t => subjectVisitIdList.Contains(t.Id)))
|
||||
//一致性分析,导致查询出来两条数据
|
||||
join visitTask in _visitTaskRepository.Where(t => taskIdList.Contains(t.Id))
|
||||
|
||||
on sv.Id equals visitTask.SourceSubjectVisitId
|
||||
select new ImageDownloadDto()
|
||||
select new
|
||||
{
|
||||
SubjectCode = inQuery.SubjectCode,
|
||||
VisitName = sv.VisitName,
|
||||
TaskBlindName = visitTask.TaskBlindName,
|
||||
StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
|
||||
.Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true)
|
||||
.Select(u => new DownloadDicomStudyDto()
|
||||
.Select(u => new
|
||||
{
|
||||
PatientId = u.PatientId,
|
||||
StudyTime = u.StudyTime,
|
||||
StudyCode = u.StudyCode,
|
||||
StudyInstanceUid = u.StudyInstanceUid,
|
||||
StudyDIRPath = u.StudyDIRPath,
|
||||
u.PatientId,
|
||||
u.StudyTime,
|
||||
u.StudyCode,
|
||||
|
||||
SeriesList = u.SeriesList.Where(t => t.IsReading).Select(z => new DownloadDicomSeriesDto()
|
||||
SeriesList = u.SeriesList.Where(t => t.IsReading).Select(z => new
|
||||
{
|
||||
Modality = z.Modality,
|
||||
z.Modality,
|
||||
|
||||
InstanceList = z.DicomInstanceList.Where(t => t.IsReading).Select(k => new DownloadDicomInstanceDto()
|
||||
InstancePathList = z.DicomInstanceList.Where(t => t.IsReading).Select(k => new
|
||||
{
|
||||
IsEncapsulated = k.IsEncapsulated,
|
||||
InstanceId = k.Id,
|
||||
FileName = string.Empty,
|
||||
Path = k.Path,
|
||||
FileSize = k.FileSize
|
||||
}).ToList()
|
||||
}).ToList()
|
||||
}).ToList(),
|
||||
k.Path,
|
||||
k.FileSize
|
||||
})
|
||||
})
|
||||
|
||||
}),
|
||||
|
||||
NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => isQueryNoneDicom ? inQuery.NoneDicomStudyIdList.Contains(t.Id) : false)
|
||||
.Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.Modality + "|") : true)
|
||||
.Where(t => t.IsReading)
|
||||
.Select(nd => new DownloadNoneDicomStudyDto()
|
||||
{
|
||||
Modality = nd.Modality,
|
||||
StudyCode = nd.StudyCode,
|
||||
ImageDate = nd.ImageDate,
|
||||
.Select(nd => new
|
||||
{
|
||||
nd.Modality,
|
||||
nd.StudyCode,
|
||||
nd.ImageDate,
|
||||
|
||||
FileList = nd.NoneDicomFileList.Where(t => t.IsReading).Select(file => new DownloadNoneDicomFileDto()
|
||||
{
|
||||
FileName = file.FileName,
|
||||
Path = file.Path,
|
||||
FileType = file.FileType,
|
||||
FileSize = file.FileSize
|
||||
}).ToList()
|
||||
}).ToList()
|
||||
FileList = nd.NoneDicomFileList.Where(t => t.IsReading).Select(file => new
|
||||
{
|
||||
file.FileName,
|
||||
file.Path,
|
||||
file.FileType,
|
||||
file.FileSize
|
||||
})
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
|
||||
var list = await query.ToListAsync();
|
||||
|
||||
foreach (var result in list)
|
||||
{
|
||||
foreach (var item in result.StudyList.SelectMany(t => t.SeriesList).SelectMany(t => t.InstanceList))
|
||||
{
|
||||
var key = item.InstanceId.ToString();
|
||||
if (dirDic.ContainsKey(key))
|
||||
{
|
||||
item.FileName = dirDic[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var result = await query.ToListAsync();
|
||||
|
||||
|
||||
|
||||
|
@ -1237,17 +1071,17 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
DownloadStartTime = DateTime.Now,
|
||||
IsSuccess = false,
|
||||
ImageType = imageType,
|
||||
VisitName = string.Join(" | ", list.Select(t => t.VisitName).OrderBy(t => t).ToList()),
|
||||
NoneDicomStudyCount = list.Sum(t => t.NoneDicomStudyList.Count()),
|
||||
DicomStudyCount = list.Sum(t => t.StudyList.Count()),
|
||||
ImageCount = list.Sum(t => t.StudyList.Sum(s => s.SeriesList.Sum(s => s.InstanceList.Count())) + t.NoneDicomStudyList.Sum(s => s.FileList.Count())),
|
||||
ImageSize = list.Sum(t => t.StudyList.Sum(t => t.SeriesList.Sum(s => s.InstanceList.Sum(i => i.FileSize))) + t.NoneDicomStudyList.Sum(t => t.FileList.Sum(s => s.FileSize))
|
||||
VisitName = string.Join(" | ", result.Select(t => t.VisitName).OrderBy(t => t).ToList()),
|
||||
NoneDicomStudyCount = result.Sum(t => t.NoneDicomStudyList.Count()),
|
||||
DicomStudyCount = result.Sum(t => t.StudyList.Count()),
|
||||
ImageCount = result.Sum(t => t.StudyList.Sum(s => s.SeriesList.Sum(s => s.InstancePathList.Count())) + t.NoneDicomStudyList.Sum(s => s.FileList.Count())),
|
||||
ImageSize = result.Sum(t => t.StudyList.Sum(t => t.SeriesList.Sum(s => s.InstancePathList.Sum(i => i.FileSize))) + t.NoneDicomStudyList.Sum(t => t.FileList.Sum(s => s.FileSize))
|
||||
) ?? 0
|
||||
};
|
||||
|
||||
await _trialImageDownloadRepository.AddAsync(preDownloadInfo, true);
|
||||
|
||||
return ResponseOutput.Ok(list, new { PreDownloadId = preDownloadInfo.Id, info.IsReadingTaskViewInOrder });
|
||||
return ResponseOutput.Ok(result, new { PreDownloadId = preDownloadInfo.Id, info.IsReadingTaskViewInOrder });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1384,9 +1218,6 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
|
||||
TotalImageSize = t.StudyList.SelectMany(t => t.InstanceList).Sum(t => t.FileSize) + t.NoneDicomStudyList.SelectMany(t => t.NoneDicomFileList).Sum(t => t.FileSize),
|
||||
|
||||
TotalReadingImageSize = t.StudyList.SelectMany(t => t.InstanceList.Where(t => t.IsReading && t.DicomSerie.IsReading)).Sum(t => t.FileSize)
|
||||
+ t.NoneDicomStudyList.Where(t => t.IsReading).SelectMany(t => t.NoneDicomFileList.Where(t => t.IsReading)).Sum(t => t.FileSize),
|
||||
|
||||
|
||||
//DicomStudyCount = t.StudyList.Count(),
|
||||
//NoneDicomStudyCount = t.NoneDicomStudyList.Count(),
|
||||
|
@ -1418,10 +1249,6 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
{
|
||||
SubjectId = g.Key,
|
||||
VisitCount = g.Count(),
|
||||
ReadingImageSize = g.SelectMany(t => t.NoneDicomStudyList.Where(t => t.IsReading)).SelectMany(t => t.NoneDicomFileList.Where(t => t.IsReading)).Sum(t => t.FileSize)
|
||||
|
||||
+ g.SelectMany(t => t.StudyList).SelectMany(t => t.InstanceList.Where(t => t.IsReading && t.DicomSerie.IsReading)).Sum(t => t.FileSize),
|
||||
|
||||
ImageSize = g.SelectMany(t => t.NoneDicomStudyList).SelectMany(t => t.NoneDicomFileList).Sum(t => t.FileSize)
|
||||
|
||||
+ g.SelectMany(t => t.StudyList).SelectMany(t => t.InstanceList).Sum(t => t.FileSize)
|
||||
|
@ -1434,9 +1261,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
|
||||
var totalImageSize = subjectImageList.Sum(t => t.ImageSize);
|
||||
|
||||
var totalReadingImageSize = subjectImageList.Sum(t => t.ReadingImageSize);
|
||||
|
||||
return ResponseOutput.Ok(new TrialImageStatInfo { SubjectCount = subjectCount, SubjectVisitCount = subjectVisitCount, TotalImageSize = totalImageSize, TotalReadingImageSize = totalReadingImageSize });
|
||||
return ResponseOutput.Ok(new TrialImageStatInfo { SubjectCount = subjectCount, SubjectVisitCount = subjectVisitCount, TotalImageSize = totalImageSize });
|
||||
|
||||
|
||||
}
|
||||
|
@ -1450,8 +1275,6 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
public async Task<IResponseOutput> GetExportSubjectVisitImageList(TrialExportImageCommand inCommand)
|
||||
{
|
||||
|
||||
var isExportReading = inCommand.IsExportReading == true;
|
||||
|
||||
if (inCommand.IsKeyImage)
|
||||
{
|
||||
var downloadInfoList = _visitTaskRepository.Where(t => t.TrialId == inCommand.TrialId && (t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Global)
|
||||
|
@ -1715,11 +1538,11 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
u.StudyTime,
|
||||
u.StudyCode,
|
||||
|
||||
SeriesList = u.SeriesList.Where(t => isExportReading ? t.IsReading : true).Select(z => new
|
||||
SeriesList = u.SeriesList.Select(z => new
|
||||
{
|
||||
z.Modality,
|
||||
|
||||
InstancePathList = z.DicomInstanceList.Where(t => isExportReading ? t.IsReading : true).Select(k => new
|
||||
InstancePathList = z.DicomInstanceList.Select(k => new
|
||||
{
|
||||
k.Path
|
||||
})
|
||||
|
@ -1727,13 +1550,13 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
|||
|
||||
}),
|
||||
|
||||
NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => isExportReading ? t.IsReading : true).Select(nd => new
|
||||
NoneDicomStudyList = sv.NoneDicomStudyList.Select(nd => new
|
||||
{
|
||||
nd.Modality,
|
||||
nd.StudyCode,
|
||||
nd.ImageDate,
|
||||
|
||||
FileList = nd.NoneDicomFileList.Where(t => isExportReading ? t.IsReading : true).Select(file => new
|
||||
FileList = nd.NoneDicomFileList.Select(file => new
|
||||
{
|
||||
file.FileName,
|
||||
file.Path,
|
||||
|
|
|
@ -1040,10 +1040,7 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
|||
|
||||
public List<string> HighlightAnswerList { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 排除显示的访视名称
|
||||
/// </summary>
|
||||
public List<decimal> ExcludeShowVisitList { get; set; } = new List<decimal>() { };
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 系统标准Id
|
||||
|
@ -2424,13 +2421,9 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto
|
|||
public string ExportResultStr { get; set; } = "[]";
|
||||
|
||||
public List<ExportResult> ExportResult { get; set; } = new List<ExportResult>();
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 排除显示的访视名称
|
||||
/// </summary>
|
||||
public List<decimal> ExcludeShowVisitList { get; set; } = new List<decimal>() { };
|
||||
|
||||
public bool IsAdditional { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -22,7 +22,6 @@ using Newtonsoft.Json.Serialization;
|
|||
using NPOI.POIFS.Properties;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using Panda.DynamicWebApi.Attributes;
|
||||
using System.Linq;
|
||||
using ZiggyCreatures.Caching.Fusion;
|
||||
|
||||
namespace IRaCIS.Core.Application.Service
|
||||
|
@ -35,7 +34,6 @@ namespace IRaCIS.Core.Application.Service
|
|||
IRepository<NoneDicomStudy> _noneDicomStudyRepository,
|
||||
IRepository<VisitTask> _visitTaskRepository,
|
||||
IRepository<Trial> _trialRepository,
|
||||
IRepository<TaskInstance> _taskInstanceRepository,
|
||||
IRepository<NoneDicomStudyFile> _noneDicomStudyFileRepository,
|
||||
IRepository<ReadingNoneDicomMark> _readingNoneDicomMarkRepository,
|
||||
IRepository<UserLog> _userLogRepository,
|
||||
|
@ -1064,17 +1062,16 @@ namespace IRaCIS.Core.Application.Service
|
|||
|
||||
var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
|
||||
|
||||
if (taskInfo.VisitTaskNum == 0)
|
||||
if (taskinfo.VisitTaskNum == 0)
|
||||
{
|
||||
questions = questions.Where(x => (x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.BaseLineShow) || (x.LimitShow == LimitShow.ExcludeSomeVisits && !x.ExcludeShowVisitList.Contains(taskInfo.VisitTaskNum))).ToList();
|
||||
questions = questions.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.BaseLineShow).ToList();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
questions = questions.Where(x => (x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.FollowShow) || (x.LimitShow == LimitShow.ExcludeSomeVisits && !x.ExcludeShowVisitList.Contains(taskInfo.VisitTaskNum))).ToList();
|
||||
questions = questions.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.FollowShow).ToList();
|
||||
}
|
||||
|
||||
|
||||
questions.ForEach(x =>
|
||||
{
|
||||
x.CrterionDictionaryGroup = ReadingCommon.GetCrterionDictionaryGroup(taskinfo.IsConvertedTask);
|
||||
|
@ -1345,12 +1342,12 @@ namespace IRaCIS.Core.Application.Service
|
|||
taskInfo = await _visitTaskRepository.Where(x => x.Id == inDto.TaskId).ProjectTo<VisitTaskDto>(_mapper.ConfigurationProvider).FirstNotNullAsync();
|
||||
if (taskInfo.VisitTaskNum == 0)
|
||||
{
|
||||
qusetionList = qusetionList.Where(x => (x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.BaseLineShow) || (x.LimitShow == LimitShow.ExcludeSomeVisits&&!x.ExcludeShowVisitList.Contains(taskInfo.VisitTaskNum))).ToList();
|
||||
qusetionList = qusetionList.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.BaseLineShow).ToList();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
qusetionList = qusetionList.Where(x => (x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.FollowShow) || (x.LimitShow == LimitShow.ExcludeSomeVisits && !x.ExcludeShowVisitList.Contains(taskInfo.VisitTaskNum))).ToList();
|
||||
qusetionList = qusetionList.Where(x => x.LimitShow == LimitShow.AllShow || x.LimitShow == LimitShow.FollowShow).ToList();
|
||||
}
|
||||
|
||||
|
||||
|
@ -2603,7 +2600,7 @@ namespace IRaCIS.Core.Application.Service
|
|||
await VerifyTaskIsSign(inDto.VisitTaskId);
|
||||
if (inDto.InstanceId != null && inDto.IsDicomReading)
|
||||
{
|
||||
if ((!(await _dicomInstanceRepository.AnyAsync(x => x.Id == inDto.InstanceId && x.SeriesId == inDto.SeriesId))) && (!(await _taskInstanceRepository.AnyAsync(x => x.Id == inDto.InstanceId && x.SeriesId == inDto.SeriesId))))
|
||||
if (!(await _dicomInstanceRepository.AnyAsync(x => x.Id == inDto.InstanceId && x.SeriesId == inDto.SeriesId)))
|
||||
{
|
||||
throw new BusinessValidationFailedException(_localizer["ReadingImage_Idnotcorrespond"]);
|
||||
}
|
||||
|
@ -3133,10 +3130,9 @@ namespace IRaCIS.Core.Application.Service
|
|||
.WhereIf(taskInfo.SourceSubjectVisit.IsBaseLine, x => ((x.IsRequired == IsRequired.Required && x.ShowQuestion == ShowQuestion.Show) && (x.LimitEdit == LimitEdit.None || x.LimitEdit == LimitEdit.OnlyBaseLine)))
|
||||
.WhereIf(!taskInfo.SourceSubjectVisit.IsBaseLine, x => ((x.IsRequired == IsRequired.Required && x.ShowQuestion == ShowQuestion.Show) && (x.LimitEdit == LimitEdit.None || x.LimitEdit == LimitEdit.OnlyVisit)))
|
||||
.WhereIf(taskInfo.TrialReadingCriterion.CriterionType == CriterionType.PCWG3, x => x.QuestionType != QuestionType.SiteVisitForTumorEvaluation)
|
||||
.ToListAsync();
|
||||
|
||||
// 排除访视
|
||||
readingQuestionList = readingQuestionList.Where(x => !(x.LimitShow == LimitShow.ExcludeSomeVisits && x.ExcludeShowVisitList.Contains(taskInfo.VisitTaskNum))).ToList();
|
||||
//.WhereIf(!criterion.IseCRFShowInDicomReading,x=>x.IsShowInDicom)
|
||||
.ToListAsync();
|
||||
|
||||
var answerQuestionIds = await _readingTaskQuestionAnswerRepository.Where(x => x.VisitTaskId == inDto.VisitTaskId && x.Answer != string.Empty).Select(x => x.ReadingQuestionTrialId).ToListAsync();
|
||||
|
||||
|
|
|
@ -924,12 +924,7 @@ namespace IRaCIS.Core.Application.Service
|
|||
var noteEqual = false;
|
||||
foreach (var item in groupTasks)
|
||||
{
|
||||
// 裁判问题可以不必填
|
||||
if(item.TaskAnswerList.Count()==0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (item.TaskAnswerList.Count() != 2)
|
||||
if (item.TaskAnswerList.Count() != 2)
|
||||
{
|
||||
noteEqual = true;
|
||||
break;
|
||||
|
@ -1018,14 +1013,14 @@ namespace IRaCIS.Core.Application.Service
|
|||
}
|
||||
else
|
||||
{
|
||||
var absoluteValue = (Math.Abs(value1 - value2) * 100) / (value1 < value2 ? value1 : value2);
|
||||
var absoluteValue = (Math.Abs(value1 - value2)*100)/(value1<value2?value1:value2) ;
|
||||
if (item.JudgeDifferenceType == JudgeDifferenceType.Greater)
|
||||
{
|
||||
noteEqual = absoluteValue > item.JudgeDifferenceValue;
|
||||
noteEqual= absoluteValue > item.JudgeDifferenceValue;
|
||||
}
|
||||
else if (item.JudgeDifferenceType == JudgeDifferenceType.AboveOrEqual)
|
||||
{
|
||||
noteEqual = absoluteValue >= item.JudgeDifferenceValue;
|
||||
noteEqual= absoluteValue >= item.JudgeDifferenceValue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -88,10 +88,7 @@ namespace IRaCIS.Application.Contracts
|
|||
public bool IsDeleted { get; set; }
|
||||
}
|
||||
|
||||
public class GetVisitStageInDto
|
||||
{
|
||||
public Guid TrialId { get; set; } = Guid.Empty;
|
||||
}
|
||||
|
||||
public class VisitPlanQueryDTO : PageInput
|
||||
{
|
||||
public Guid TrialId { get; set; } = Guid.Empty;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using DocumentFormat.OpenXml.Office2010.ExcelAc;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
|
@ -19,18 +18,7 @@ namespace IRaCIS.Core.Application.Service
|
|||
IRepository<VisitPlanInfluenceStat> _visitPlanInfluenceStatRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, IVisitPlanService
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 获取项目访视计划
|
||||
/// </summary>
|
||||
/// <param name="inDto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<List<VisitStageDTO>> GetVisitStage(GetVisitStageInDto inDto)
|
||||
{
|
||||
var visitStageList = await _visitStageRepository.Where(x => x.TrialId == inDto.TrialId).ProjectTo<VisitStageDTO>(_mapper.ConfigurationProvider).OrderBy(x => x.VisitNum).ToListAsync(); ;
|
||||
|
||||
return visitStageList;
|
||||
}
|
||||
|
||||
|
||||
///暂时不用
|
||||
/// <summary> 获取项目访视计划</summary>
|
||||
|
|
|
@ -136,7 +136,7 @@ namespace IRaCIS.Core.Application.Service
|
|||
{
|
||||
if (!_readingMedicineSystemQuestion.Any(t => t.CriterionTypeEnum == CriterionType.mRECISTHCC))
|
||||
{
|
||||
var list = _readingMedicineSystemQuestion.Where(t => t.CriterionTypeEnum == CriterionType.RECIST1Point1).OrderBy(t=>t.ShowOrder).ToList();
|
||||
var list = _readingMedicineSystemQuestion.Where(t => t.CriterionTypeEnum == CriterionType.RECIST1Point1).ToList();
|
||||
|
||||
var initOrder = 500;
|
||||
foreach (var item in list)
|
||||
|
|
|
@ -3074,14 +3074,7 @@ public enum PET5PSScore
|
|||
/// </summary>
|
||||
FollowShow = 2,
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 排除部分访视
|
||||
/// </summary>
|
||||
|
||||
ExcludeSomeVisits = 3,
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 限制编辑
|
||||
|
|
|
@ -32,7 +32,7 @@ public class DicomInstance : BaseFullDeleteAuditEntity, IEntitySeqId
|
|||
|
||||
public int ImageRows { get; set; }
|
||||
|
||||
|
||||
|
||||
public string ImagerPixelSpacing { get; set; } = null!;
|
||||
|
||||
public int InstanceNumber { get; set; }
|
||||
|
@ -44,7 +44,7 @@ public class DicomInstance : BaseFullDeleteAuditEntity, IEntitySeqId
|
|||
[StringLength(1000)]
|
||||
public string Path { get; set; } = null!;
|
||||
|
||||
|
||||
|
||||
public string PixelSpacing { get; set; } = null!;
|
||||
|
||||
public Guid SeqId { get; set; }
|
||||
|
@ -55,7 +55,7 @@ public class DicomInstance : BaseFullDeleteAuditEntity, IEntitySeqId
|
|||
|
||||
public int SliceLocation { get; set; }
|
||||
|
||||
|
||||
|
||||
public string SliceThickness { get; set; } = null!;
|
||||
|
||||
public string SopInstanceUid { get; set; } = null!;
|
||||
|
@ -70,27 +70,11 @@ public class DicomInstance : BaseFullDeleteAuditEntity, IEntitySeqId
|
|||
|
||||
public Guid TrialId { get; set; }
|
||||
|
||||
|
||||
|
||||
public string WindowCenter { get; set; } = null!;
|
||||
|
||||
|
||||
|
||||
public string WindowWidth { get; set; } = null!;
|
||||
|
||||
public bool IsReading { get; set; } = true;
|
||||
|
||||
|
||||
|
||||
#region DIR 增加
|
||||
|
||||
public string SOPClassUID { get; set; }
|
||||
|
||||
public string MediaStorageSOPClassUID { get; set; }
|
||||
|
||||
public string TransferSytaxUID { get; set; }
|
||||
|
||||
public string MediaStorageSOPInstanceUID { get; set; }
|
||||
|
||||
public bool IsEncapsulated { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -73,12 +73,5 @@ public class DicomSeries : BaseFullDeleteAuditEntity, IEntitySeqId
|
|||
public string TriggerTime { get; set; } = null!;
|
||||
|
||||
public Guid? VisitTaskId { get; set; }
|
||||
|
||||
#region DIR 增加
|
||||
|
||||
public string DicomSeriesDate { get; set; }
|
||||
|
||||
public string DicomSeriesTime { get; set; }
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
|
|
@ -102,14 +102,4 @@ public class DicomStudy : BaseFullDeleteAuditEntity, IEntitySeqId
|
|||
public string Uploader { get; set; } = null!;
|
||||
|
||||
public string ModifyReason { get; set; }
|
||||
|
||||
#region DIR 增加字段
|
||||
|
||||
public string DicomStudyDate { get; set; }
|
||||
|
||||
public string DicomStudyTime { get; set; }
|
||||
|
||||
public string StudyDIRPath { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -226,11 +226,6 @@ public class ReadingQuestionTrial : BaseAddAuditEntity
|
|||
[Comment("限制显示")]
|
||||
public LimitShow LimitShow { get; set; } = LimitShow.AllShow;
|
||||
|
||||
/// <summary>
|
||||
/// 排除显示的访视名称
|
||||
/// </summary>
|
||||
public List<decimal> ExcludeShowVisitList { get; set; } = new List<decimal>() { };
|
||||
|
||||
[MaxLength]
|
||||
[Comment("自定义计算标记")]
|
||||
public string CalculateQuestions { get; set; } = "[]";
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,29 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace IRaCIS.Core.Infra.EFCore.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class ExcludeShowVisitList : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "ExcludeShowVisitList",
|
||||
table: "ReadingQuestionTrial",
|
||||
type: "nvarchar(max)",
|
||||
nullable: false,
|
||||
defaultValue: "[]");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ExcludeShowVisitList",
|
||||
table: "ReadingQuestionTrial");
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,114 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace IRaCIS.Core.Infra.EFCore.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class dir : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "DicomStudyDate",
|
||||
table: "DicomStudy",
|
||||
type: "nvarchar(400)",
|
||||
maxLength: 400,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "DicomStudyTime",
|
||||
table: "DicomStudy",
|
||||
type: "nvarchar(400)",
|
||||
maxLength: 400,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "DicomSeriesDate",
|
||||
table: "DicomSeries",
|
||||
type: "nvarchar(400)",
|
||||
maxLength: 400,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "DicomSeriesTime",
|
||||
table: "DicomSeries",
|
||||
type: "nvarchar(400)",
|
||||
maxLength: 400,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "MediaStorageSOPClassUID",
|
||||
table: "DicomInstance",
|
||||
type: "nvarchar(400)",
|
||||
maxLength: 400,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "MediaStorageSOPInstanceUID",
|
||||
table: "DicomInstance",
|
||||
type: "nvarchar(400)",
|
||||
maxLength: 400,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "SOPClassUID",
|
||||
table: "DicomInstance",
|
||||
type: "nvarchar(400)",
|
||||
maxLength: 400,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "TransferSytaxUID",
|
||||
table: "DicomInstance",
|
||||
type: "nvarchar(400)",
|
||||
maxLength: 400,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "DicomStudyDate",
|
||||
table: "DicomStudy");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "DicomStudyTime",
|
||||
table: "DicomStudy");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "DicomSeriesDate",
|
||||
table: "DicomSeries");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "DicomSeriesTime",
|
||||
table: "DicomSeries");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "MediaStorageSOPClassUID",
|
||||
table: "DicomInstance");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "MediaStorageSOPInstanceUID",
|
||||
table: "DicomInstance");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "SOPClassUID",
|
||||
table: "DicomInstance");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "TransferSytaxUID",
|
||||
table: "DicomInstance");
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,30 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace IRaCIS.Core.Infra.EFCore.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class dir2 : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "StudyDIRPath",
|
||||
table: "DicomStudy",
|
||||
type: "nvarchar(400)",
|
||||
maxLength: 400,
|
||||
nullable: false,
|
||||
defaultValue: "");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "StudyDIRPath",
|
||||
table: "DicomStudy");
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,29 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace IRaCIS.Core.Infra.EFCore.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class addIsEncapsulated : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "IsEncapsulated",
|
||||
table: "DicomInstance",
|
||||
type: "bit",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "IsEncapsulated",
|
||||
table: "DicomInstance");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -930,22 +930,9 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
|||
b.Property<bool>("IsDeleted")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsEncapsulated")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<bool>("IsReading")
|
||||
.HasColumnType("bit");
|
||||
|
||||
b.Property<string>("MediaStorageSOPClassUID")
|
||||
.IsRequired()
|
||||
.HasMaxLength(400)
|
||||
.HasColumnType("nvarchar(400)");
|
||||
|
||||
b.Property<string>("MediaStorageSOPInstanceUID")
|
||||
.IsRequired()
|
||||
.HasMaxLength(400)
|
||||
.HasColumnType("nvarchar(400)");
|
||||
|
||||
b.Property<int>("NumberOfFrames")
|
||||
.HasColumnType("int");
|
||||
|
||||
|
@ -959,11 +946,6 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
|||
.HasMaxLength(400)
|
||||
.HasColumnType("nvarchar(400)");
|
||||
|
||||
b.Property<string>("SOPClassUID")
|
||||
.IsRequired()
|
||||
.HasMaxLength(400)
|
||||
.HasColumnType("nvarchar(400)");
|
||||
|
||||
b.Property<Guid>("SeriesId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
|
@ -999,11 +981,6 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
|||
b.Property<Guid>("SubjectVisitId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
b.Property<string>("TransferSytaxUID")
|
||||
.IsRequired()
|
||||
.HasMaxLength(400)
|
||||
.HasColumnType("nvarchar(400)");
|
||||
|
||||
b.Property<Guid>("TrialId")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
|
@ -1080,16 +1057,6 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
|||
.HasMaxLength(400)
|
||||
.HasColumnType("nvarchar(400)");
|
||||
|
||||
b.Property<string>("DicomSeriesDate")
|
||||
.IsRequired()
|
||||
.HasMaxLength(400)
|
||||
.HasColumnType("nvarchar(400)");
|
||||
|
||||
b.Property<string>("DicomSeriesTime")
|
||||
.IsRequired()
|
||||
.HasMaxLength(400)
|
||||
.HasColumnType("nvarchar(400)");
|
||||
|
||||
b.Property<Guid>("Id")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
|
@ -1250,16 +1217,6 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
|||
.HasMaxLength(400)
|
||||
.HasColumnType("nvarchar(400)");
|
||||
|
||||
b.Property<string>("DicomStudyDate")
|
||||
.IsRequired()
|
||||
.HasMaxLength(400)
|
||||
.HasColumnType("nvarchar(400)");
|
||||
|
||||
b.Property<string>("DicomStudyTime")
|
||||
.IsRequired()
|
||||
.HasMaxLength(400)
|
||||
.HasColumnType("nvarchar(400)");
|
||||
|
||||
b.Property<Guid>("Id")
|
||||
.HasColumnType("uniqueidentifier");
|
||||
|
||||
|
@ -1328,11 +1285,6 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
|||
.HasMaxLength(400)
|
||||
.HasColumnType("nvarchar(400)");
|
||||
|
||||
b.Property<string>("StudyDIRPath")
|
||||
.IsRequired()
|
||||
.HasMaxLength(400)
|
||||
.HasColumnType("nvarchar(400)");
|
||||
|
||||
b.Property<string>("StudyId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(400)
|
||||
|
@ -6322,10 +6274,6 @@ namespace IRaCIS.Core.Infra.EFCore.Migrations
|
|||
.HasColumnType("nvarchar(400)")
|
||||
.HasComment("字典code");
|
||||
|
||||
b.Property<string>("ExcludeShowVisitList")
|
||||
.IsRequired()
|
||||
.HasColumnType("nvarchar(max)");
|
||||
|
||||
b.Property<string>("ExportResultStr")
|
||||
.IsRequired()
|
||||
.HasMaxLength(400)
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace IRaCIS.Core.Infra.EFCore
|
|||
Task<bool> BatchDeleteNoTrackingAsync(Expression<Func<TEntity, bool>> deleteFilter);
|
||||
|
||||
/// <summary>批量更新,相当于原生sql, 没用EF跟踪方式(所有查询出来,再更新 浪费性能)</summary>
|
||||
Task<bool> BatchUpdateNoTrackingAsync(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, TEntity>> updateFactory, bool isAutoIncludeTimeAndUser = true);
|
||||
Task<bool> BatchUpdateNoTrackingAsync(Expression<Func<TEntity, bool>> where, Expression<Func<TEntity, TEntity>> updateFactory);
|
||||
|
||||
Task<bool> ExecuteUpdateAsync(Expression<Func<TEntity, bool>> where, Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setPropertyCalls);
|
||||
|
||||
|
@ -77,7 +77,7 @@ namespace IRaCIS.Core.Infra.EFCore
|
|||
#endregion
|
||||
|
||||
|
||||
void MarkAsModified<TFrom>(TFrom entity, string propertyName);
|
||||
void MarkAsModified<TFrom>(TFrom entity, string propertyName);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ namespace IRaCIS.Core.Infra.EFCore
|
|||
|
||||
|
||||
/// <summary>批量更新,相当于原生sql, 没用EF跟踪方式(所有查询出来,再更新 浪费性能)</summary>
|
||||
public static async Task<bool> BatchUpdateNoTrackingAsync<T>(this IRaCISDBContext _dbContext, Expression<Func<T, bool>> where, Expression<Func<T, T>> updateFactory, Guid updateUserId, bool isAutoIncludeTimeAndUser = true) where T : Entity
|
||||
public static async Task<bool> BatchUpdateNoTrackingAsync<T>(this IRaCISDBContext _dbContext, Expression<Func<T, bool>> where, Expression<Func<T, T>> updateFactory, Guid updateUserId) where T : Entity
|
||||
{
|
||||
if (where == null) throw new ArgumentNullException(nameof(where));
|
||||
|
||||
|
@ -202,17 +202,15 @@ namespace IRaCIS.Core.Infra.EFCore
|
|||
|
||||
if (typeof(IAuditUpdate).IsAssignableFrom(typeof(T)))
|
||||
{
|
||||
if (isAutoIncludeTimeAndUser)
|
||||
{
|
||||
if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateTime)))
|
||||
{
|
||||
fieldValues.Add(nameof(IAuditUpdate.UpdateTime), DateTime.Now);
|
||||
}
|
||||
|
||||
if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateUserId)))
|
||||
{
|
||||
fieldValues.Add(nameof(IAuditUpdate.UpdateUserId), updateUserId);
|
||||
}
|
||||
if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateTime)))
|
||||
{
|
||||
fieldValues.Add(nameof(IAuditUpdate.UpdateTime), DateTime.Now);
|
||||
}
|
||||
|
||||
if (!hasPropNameList.Contains(nameof(IAuditUpdate.UpdateUserId)))
|
||||
{
|
||||
fieldValues.Add(nameof(IAuditUpdate.UpdateUserId), updateUserId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -297,10 +297,10 @@ namespace IRaCIS.Core.Infra.EFCore
|
|||
|
||||
/// <summary>批量更新,相当于原生sql, 没用EF跟踪方式(所有查询出来,再更新 浪费性能)</summary>
|
||||
public async Task<bool> BatchUpdateNoTrackingAsync(Expression<Func<TEntity, bool>> where,
|
||||
Expression<Func<TEntity, TEntity>> updateFactory ,bool isAutoIncludeTimeAndUser = true)
|
||||
Expression<Func<TEntity, TEntity>> updateFactory)
|
||||
{
|
||||
|
||||
return await _dbContext.BatchUpdateNoTrackingAsync(where, updateFactory, _userInfo.UserRoleId, isAutoIncludeTimeAndUser);
|
||||
return await _dbContext.BatchUpdateNoTrackingAsync(where, updateFactory, _userInfo.UserRoleId);
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue