dicom dir处理返回处理后的路径
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
44156a2e34
commit
eafceeb5d1
|
@ -49,8 +49,9 @@ namespace IRaCIS.Core.Application.Helper
|
||||||
public static class DicomDIRHelper
|
public static class DicomDIRHelper
|
||||||
{
|
{
|
||||||
|
|
||||||
public static async Task GenerateStudyDIRAndUploadAsync(List<StudyDIRInfo> list, string ossFolder, IOSSService _oSSService)
|
public static async Task<Dictionary<string, string>> GenerateStudyDIRAndUploadAsync(List<StudyDIRInfo> list, string ossFolder, IOSSService _oSSService)
|
||||||
{
|
{
|
||||||
|
var dic = new Dictionary<string, string>();
|
||||||
var mappings = new List<string>();
|
var mappings = new List<string>();
|
||||||
int index = 1;
|
int index = 1;
|
||||||
|
|
||||||
|
@ -98,6 +99,8 @@ namespace IRaCIS.Core.Application.Helper
|
||||||
|
|
||||||
mappings.Add($"{filename} => {item.InstanceId}");
|
mappings.Add($"{filename} => {item.InstanceId}");
|
||||||
|
|
||||||
|
dic.Add(item.InstanceId.ToString(), filename);
|
||||||
|
|
||||||
dicomDir.AddFile(dicomFile, filename);
|
dicomDir.AddFile(dicomFile, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,6 +133,45 @@ namespace IRaCIS.Core.Application.Helper
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
return dic;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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 = dataset.GetSingleValueOrDefault(DicomTag.MediaStorageSOPClassUID, string.Empty),
|
||||||
|
MediaStorageSOPInstanceUID = dataset.GetSingleValueOrDefault(DicomTag.MediaStorageSOPInstanceUID, string.Empty),
|
||||||
|
TransferSytaxUID = dicomFile.FileMetaInfo.GetSingleValueOrDefault(DicomTag.TransferSyntaxUID, string.Empty)
|
||||||
|
};
|
||||||
|
|
||||||
|
return info;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,6 +145,8 @@ public interface IOSSService
|
||||||
|
|
||||||
public Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath);
|
public Task DownLoadFromOSSAsync(string ossRelativePath, string localFilePath);
|
||||||
|
|
||||||
|
public Task<Stream> GetStreamFromOSSAsync(string ossRelativePath);
|
||||||
|
|
||||||
public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
|
public ObjectStoreServiceOptions ObjectStoreServiceOptions { get; set; }
|
||||||
|
|
||||||
public Task<string> GetSignedUrl(string ossRelativePath);
|
public Task<string> GetSignedUrl(string ossRelativePath);
|
||||||
|
@ -285,7 +287,7 @@ public class OSSService : IOSSService
|
||||||
{
|
{
|
||||||
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
|
if (ObjectStoreServiceOptions.ObjectStoreUse == "AliyunOSS")
|
||||||
{
|
{
|
||||||
if(AliyunOSSTempToken == null)
|
if (AliyunOSSTempToken == null)
|
||||||
{
|
{
|
||||||
GetObjectStoreTempToken();
|
GetObjectStoreTempToken();
|
||||||
}
|
}
|
||||||
|
@ -295,8 +297,8 @@ public class OSSService : IOSSService
|
||||||
GetObjectStoreTempToken();
|
GetObjectStoreTempToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
else if (ObjectStoreServiceOptions.ObjectStoreUse == "AWS")
|
||||||
{
|
{
|
||||||
if (AWSTempToken == null)
|
if (AWSTempToken == null)
|
||||||
|
@ -474,6 +476,96 @@ 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)
|
public async Task<string> GetSignedUrl(string ossRelativePath)
|
||||||
{
|
{
|
||||||
GetObjectStoreTempToken();
|
GetObjectStoreTempToken();
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
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,6 +1111,13 @@
|
||||||
<param name="trialId"></param>
|
<param name="trialId"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</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">
|
<member name="T:IRaCIS.Core.Application.Service.AttachmentService">
|
||||||
<summary>
|
<summary>
|
||||||
医生文档关联关系维护
|
医生文档关联关系维护
|
||||||
|
|
|
@ -5,6 +5,7 @@ using MassTransit;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using SharpCompress.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -232,25 +233,32 @@ namespace IRaCIS.Core.Application.Service
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///// <summary>
|
/// <summary>
|
||||||
///// 下载影像 维护dir信息 并回传到OSS
|
/// 下载影像 维护dir信息 并回传到OSS
|
||||||
///// </summary>
|
/// </summary>
|
||||||
///// <param name="trialId"></param>
|
/// <param name="trialId"></param>
|
||||||
///// <returns></returns>
|
/// <returns></returns>
|
||||||
//[HttpGet]
|
[HttpGet]
|
||||||
//[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
//public async Task<IResponseOutput> DownloadAndUploadTrialData(Guid trialId, [FromServices] IRepository<DicomInstance> _instanceRepository,
|
public async Task<IResponseOutput> DownloadAndUploadTrialData(Guid trialId, [FromServices] IRepository<DicomInstance> _instanceRepository,
|
||||||
// [FromServices] IRepository<DicomStudy> _studyRepository,
|
[FromServices] IRepository<DicomStudy> _studyRepository,
|
||||||
// [FromServices] IRepository<DicomSeries> _seriesRepository)
|
[FromServices] IRepository<DicomSeries> _seriesRepository)
|
||||||
//{
|
{
|
||||||
// var list = await _instanceRepository.Where(t => t.TrialId == trialId)
|
var list = await _instanceRepository.Where(t => t.TrialId == trialId)
|
||||||
// .Select(t => new { t.SeriesId, t.StudyId, t.Id, t.Path }).ToListAsync();
|
.Select(t => new { t.SeriesId, t.StudyId, t.Id, t.Path }).ToListAsync();
|
||||||
|
|
||||||
// foreach (var item in list)
|
foreach (var item in list)
|
||||||
// {
|
{
|
||||||
|
var stream = await _oSSService.GetStreamFromOSSAsync(item.Path);
|
||||||
|
|
||||||
// }
|
var dicomFile = DicomFile.Open(stream);
|
||||||
//}
|
|
||||||
|
var dirInfo = DicomDIRHelper.ReadDicomDIRInfo(dicomFile);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResponseOutput.Ok();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -520,7 +520,68 @@ 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 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
|
public class CRCUploadedStudyQuqry
|
||||||
{
|
{
|
||||||
|
|
|
@ -782,6 +782,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
|
|
||||||
var imageType = (isQueryDicom && isQueryNoneDicom) ? ImageType.DicomAndNoneDicom : (isQueryDicom ? ImageType.Dicom : ImageType.NoneDicom);
|
var imageType = (isQueryDicom && isQueryNoneDicom) ? ImageType.DicomAndNoneDicom : (isQueryDicom ? ImageType.Dicom : ImageType.NoneDicom);
|
||||||
|
|
||||||
|
var dirDic = new Dictionary<string, string>();
|
||||||
#region DIR处理导出文件名,并将对应关系上传到OSS里面存储
|
#region DIR处理导出文件名,并将对应关系上传到OSS里面存储
|
||||||
|
|
||||||
//有传输语法值的导出 才生成DIR
|
//有传输语法值的导出 才生成DIR
|
||||||
|
@ -831,9 +832,15 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
{
|
{
|
||||||
var ossFolder = $"{pathInfo.TrialId}/Image/{pathInfo.SubjectId}/{pathInfo.VisitId}/{item.Key.StudyInstanceUid}";
|
var ossFolder = $"{pathInfo.TrialId}/Image/{pathInfo.SubjectId}/{pathInfo.VisitId}/{item.Key.StudyInstanceUid}";
|
||||||
|
|
||||||
await DicomDIRHelper.GenerateStudyDIRAndUploadAsync(item.ToList(), ossFolder, _oSSService);
|
var (isSucess, dic) = await SafeBussinessHelper.RunAsync(async () => await DicomDIRHelper.GenerateStudyDIRAndUploadAsync(item.ToList(), ossFolder, _oSSService));
|
||||||
|
|
||||||
|
dirDic = dic;
|
||||||
|
|
||||||
|
if (isSucess)
|
||||||
|
{
|
||||||
|
await _dicomStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new DicomStudy() { StudyDIRPath = $"/{ossFolder}/DICOMDIR" });
|
||||||
|
}
|
||||||
|
|
||||||
await _dicomStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new DicomStudy() { StudyDIRPath = $"/{ossFolder}/DICOMDIR" });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -843,7 +850,7 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
var query = from sv in _subjectVisitRepository.Where(t => t.Id == inQuery.SubjectVisitId)
|
var query = from sv in _subjectVisitRepository.Where(t => t.Id == inQuery.SubjectVisitId)
|
||||||
|
|
||||||
|
|
||||||
select new
|
select new ImageDownloadDto()
|
||||||
{
|
{
|
||||||
TrialId = sv.TrialId,
|
TrialId = sv.TrialId,
|
||||||
SubjectId = sv.SubjectId,
|
SubjectId = sv.SubjectId,
|
||||||
|
@ -854,48 +861,57 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
|
|
||||||
StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
|
StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
|
||||||
|
|
||||||
.Select(u => new
|
.Select(u => new DownloadDicomStudyDto()
|
||||||
{
|
{
|
||||||
u.PatientId,
|
PatientId = u.PatientId,
|
||||||
u.StudyTime,
|
StudyTime = u.StudyTime,
|
||||||
u.StudyCode,
|
StudyCode = u.StudyCode,
|
||||||
u.StudyInstanceUid,
|
StudyInstanceUid = u.StudyInstanceUid,
|
||||||
u.StudyDIRPath,
|
StudyDIRPath = u.StudyDIRPath,
|
||||||
|
|
||||||
SeriesList = u.SeriesList.Select(z => new
|
SeriesList = u.SeriesList.Select(z => new DownloadDicomSeriesDto()
|
||||||
{
|
{
|
||||||
z.Modality,
|
Modality = z.Modality,
|
||||||
|
|
||||||
InstanceList = z.DicomInstanceList.Select(k => new
|
InstanceList = z.DicomInstanceList.Select(k => new DownloadDicomInstanceDto()
|
||||||
{
|
{
|
||||||
k.Path,
|
InstanceId = k.Id,
|
||||||
k.FileSize
|
FileName = string.Empty,
|
||||||
})
|
Path = k.Path,
|
||||||
})
|
FileSize = k.FileSize
|
||||||
|
}).ToList()
|
||||||
|
}).ToList()
|
||||||
|
|
||||||
}).ToList(),
|
}).ToList(),
|
||||||
|
|
||||||
NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => isQueryNoneDicom ? inQuery.NoneDicomStudyIdList.Contains(t.Id) : false)
|
NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => isQueryNoneDicom ? inQuery.NoneDicomStudyIdList.Contains(t.Id) : false)
|
||||||
|
|
||||||
.Select(nd => new
|
.Select(nd => new DownloadNoneDicomStudyDto()
|
||||||
{
|
{
|
||||||
nd.Modality,
|
Modality = nd.Modality,
|
||||||
nd.StudyCode,
|
StudyCode = nd.StudyCode,
|
||||||
nd.ImageDate,
|
ImageDate = nd.ImageDate,
|
||||||
|
|
||||||
FileList = nd.NoneDicomFileList.Select(file => new
|
FileList = nd.NoneDicomFileList.Select(file => new DownloadNoneDicomFileDto()
|
||||||
{
|
{
|
||||||
file.FileName,
|
FileName = file.FileName,
|
||||||
file.Path,
|
Path = file.Path,
|
||||||
file.FileType,
|
FileType = file.FileType,
|
||||||
file.FileSize,
|
FileSize = file.FileSize
|
||||||
})
|
}).ToList()
|
||||||
}).ToList()
|
}).ToList()
|
||||||
};
|
};
|
||||||
|
|
||||||
var result = query.FirstOrDefault();
|
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()
|
var preDownloadInfo = new TrialImageDownload()
|
||||||
{
|
{
|
||||||
|
@ -1070,12 +1086,13 @@ 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 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文件
|
#region 在下载前先处理DIR文件
|
||||||
|
|
||||||
//有传输语法值的导出 才生成DIR
|
//有传输语法值的导出 才生成DIR
|
||||||
if (_subjectVisitRepository.Any(t => t.SubjectId == inQuery.SubjectId && t.StudyList.SelectMany(t => t.InstanceList).Any(c => c.TransferSytaxUID != string.Empty)))
|
if (_subjectVisitRepository.Any(t => t.SubjectId == inQuery.SubjectId && t.StudyList.SelectMany(t => t.InstanceList).Any(c => c.TransferSytaxUID != string.Empty)))
|
||||||
{
|
{
|
||||||
var list = _subjectRepository.Where(t => t.Id == inQuery.SubjectId).SelectMany(t => t.SubjectVisitList.Where(t => subjectVisitIdList.Contains(t.Id))).SelectMany(t => t.StudyList)
|
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 => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
|
||||||
.Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true)
|
.Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true)
|
||||||
.SelectMany(t => t.InstanceList.Where(t => t.IsReading && t.DicomSerie.IsReading))
|
.SelectMany(t => t.InstanceList.Where(t => t.IsReading && t.DicomSerie.IsReading))
|
||||||
|
@ -1117,15 +1134,21 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
|
|
||||||
var pathInfo = await _subjectRepository.Where(t => t.Id == inQuery.SubjectId).Select(t => new { t.TrialId, SubjectId = t.Id }).FirstNotNullAsync();
|
var pathInfo = await _subjectRepository.Where(t => t.Id == inQuery.SubjectId).Select(t => new { t.TrialId, SubjectId = t.Id }).FirstNotNullAsync();
|
||||||
|
|
||||||
foreach (var item in list.GroupBy(t => new { t.StudyInstanceUid, t.DicomStudyId }))
|
foreach (var item in dirInfolist.GroupBy(t => new { t.StudyInstanceUid, t.DicomStudyId }))
|
||||||
{
|
{
|
||||||
var visitId = item.First().SubjectVisitId;
|
var visitId = item.First().SubjectVisitId;
|
||||||
|
|
||||||
var ossFolder = $"{pathInfo.TrialId}/Image/{pathInfo.SubjectId}/{visitId}/{item.Key.StudyInstanceUid}";
|
var ossFolder = $"{pathInfo.TrialId}/Image/{pathInfo.SubjectId}/{visitId}/{item.Key.StudyInstanceUid}";
|
||||||
|
|
||||||
await DicomDIRHelper.GenerateStudyDIRAndUploadAsync(item.ToList(), ossFolder, _oSSService);
|
var (isSucess, dic) = await SafeBussinessHelper.RunAsync(async () => await DicomDIRHelper.GenerateStudyDIRAndUploadAsync(item.ToList(), ossFolder, _oSSService));
|
||||||
|
|
||||||
await _dicomStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new DicomStudy() { StudyDIRPath = $"/{ossFolder}/DICOMDIR" });
|
dirDic = dic;
|
||||||
|
|
||||||
|
if (isSucess)
|
||||||
|
{
|
||||||
|
await _dicomStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == item.Key.DicomStudyId, u => new DicomStudy() { StudyDIRPath = $"/{ossFolder}/DICOMDIR" });
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1136,55 +1159,70 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
join visitTask in _visitTaskRepository.Where(t => taskIdList.Contains(t.Id))
|
join visitTask in _visitTaskRepository.Where(t => taskIdList.Contains(t.Id))
|
||||||
|
|
||||||
on sv.Id equals visitTask.SourceSubjectVisitId
|
on sv.Id equals visitTask.SourceSubjectVisitId
|
||||||
select new
|
select new ImageDownloadDto()
|
||||||
{
|
{
|
||||||
SubjectCode = inQuery.SubjectCode,
|
SubjectCode = inQuery.SubjectCode,
|
||||||
VisitName = sv.VisitName,
|
VisitName = sv.VisitName,
|
||||||
TaskBlindName = visitTask.TaskBlindName,
|
TaskBlindName = visitTask.TaskBlindName,
|
||||||
StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
|
StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
|
||||||
.Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true)
|
.Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true)
|
||||||
.Select(u => new
|
.Select(u => new DownloadDicomStudyDto()
|
||||||
{
|
{
|
||||||
u.PatientId,
|
PatientId = u.PatientId,
|
||||||
u.StudyTime,
|
StudyTime = u.StudyTime,
|
||||||
u.StudyCode,
|
StudyCode = u.StudyCode,
|
||||||
u.StudyDIRPath,
|
StudyInstanceUid = u.StudyInstanceUid,
|
||||||
|
StudyDIRPath = u.StudyDIRPath,
|
||||||
|
|
||||||
SeriesList = u.SeriesList.Where(t => t.IsReading).Select(z => new
|
SeriesList = u.SeriesList.Where(t => t.IsReading).Select(z => new DownloadDicomSeriesDto()
|
||||||
{
|
{
|
||||||
z.Modality,
|
Modality = z.Modality,
|
||||||
|
|
||||||
InstancePathList = z.DicomInstanceList.Where(t => t.IsReading).Select(k => new
|
InstanceList = z.DicomInstanceList.Where(t => t.IsReading).Select(k => new DownloadDicomInstanceDto()
|
||||||
{
|
{
|
||||||
k.Path,
|
InstanceId = k.Id,
|
||||||
k.FileSize
|
FileName = string.Empty,
|
||||||
})
|
Path = k.Path,
|
||||||
})
|
FileSize = k.FileSize
|
||||||
|
}).ToList()
|
||||||
}),
|
}).ToList()
|
||||||
|
}).ToList(),
|
||||||
|
|
||||||
NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => isQueryNoneDicom ? inQuery.NoneDicomStudyIdList.Contains(t.Id) : false)
|
NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => isQueryNoneDicom ? inQuery.NoneDicomStudyIdList.Contains(t.Id) : false)
|
||||||
.Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.Modality + "|") : true)
|
.Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.Modality + "|") : true)
|
||||||
.Where(t => t.IsReading)
|
.Where(t => t.IsReading)
|
||||||
.Select(nd => new
|
.Select(nd => new DownloadNoneDicomStudyDto()
|
||||||
{
|
{
|
||||||
nd.Modality,
|
Modality = nd.Modality,
|
||||||
nd.StudyCode,
|
StudyCode = nd.StudyCode,
|
||||||
nd.ImageDate,
|
ImageDate = nd.ImageDate,
|
||||||
|
|
||||||
FileList = nd.NoneDicomFileList.Where(t => t.IsReading).Select(file => new
|
FileList = nd.NoneDicomFileList.Where(t => t.IsReading).Select(file => new DownloadNoneDicomFileDto()
|
||||||
{
|
{
|
||||||
file.FileName,
|
FileName = file.FileName,
|
||||||
file.Path,
|
Path = file.Path,
|
||||||
file.FileType,
|
FileType = file.FileType,
|
||||||
file.FileSize
|
FileSize = file.FileSize
|
||||||
})
|
}).ToList()
|
||||||
})
|
}).ToList()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var result = await query.ToListAsync();
|
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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1199,17 +1237,17 @@ namespace IRaCIS.Core.Application.Service.ImageAndDoc
|
||||||
DownloadStartTime = DateTime.Now,
|
DownloadStartTime = DateTime.Now,
|
||||||
IsSuccess = false,
|
IsSuccess = false,
|
||||||
ImageType = imageType,
|
ImageType = imageType,
|
||||||
VisitName = string.Join(" | ", result.Select(t => t.VisitName).OrderBy(t => t).ToList()),
|
VisitName = string.Join(" | ", list.Select(t => t.VisitName).OrderBy(t => t).ToList()),
|
||||||
NoneDicomStudyCount = result.Sum(t => t.NoneDicomStudyList.Count()),
|
NoneDicomStudyCount = list.Sum(t => t.NoneDicomStudyList.Count()),
|
||||||
DicomStudyCount = result.Sum(t => t.StudyList.Count()),
|
DicomStudyCount = list.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())),
|
ImageCount = list.Sum(t => t.StudyList.Sum(s => s.SeriesList.Sum(s => s.InstanceList.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))
|
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))
|
||||||
) ?? 0
|
) ?? 0
|
||||||
};
|
};
|
||||||
|
|
||||||
await _trialImageDownloadRepository.AddAsync(preDownloadInfo, true);
|
await _trialImageDownloadRepository.AddAsync(preDownloadInfo, true);
|
||||||
|
|
||||||
return ResponseOutput.Ok(result, new { PreDownloadId = preDownloadInfo.Id, info.IsReadingTaskViewInOrder });
|
return ResponseOutput.Ok(list, new { PreDownloadId = preDownloadInfo.Id, info.IsReadingTaskViewInOrder });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
Loading…
Reference in New Issue