增加访视下载接口
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
6dcdfe4d23
commit
345189995e
|
|
@ -944,12 +944,12 @@ namespace IRaCIS.Core.API.Controllers
|
||||||
var progress = new
|
var progress = new
|
||||||
{
|
{
|
||||||
CountPercent = totalCount > 0
|
CountPercent = totalCount > 0
|
||||||
? Math.Round(receivedCount * 100m / totalCount, 2).ToString() + "%"
|
? Math.Round(receivedCount * 100m / totalCount, 2).ToString()
|
||||||
: "0%",
|
: "0",
|
||||||
|
|
||||||
SizePercent = totalSize > 0
|
SizePercent = totalSize > 0
|
||||||
? Math.Round(receivedSize * 100m / totalSize, 2).ToString() + "%"
|
? Math.Round(receivedSize * 100m / totalSize, 2).ToString()
|
||||||
: "0%",
|
: "0",
|
||||||
|
|
||||||
Speed = (speedBps / 1024 >= 1024
|
Speed = (speedBps / 1024 >= 1024
|
||||||
? (speedBps / 1024 / 1024).ToString("0.00") + " MB/s"
|
? (speedBps / 1024 / 1024).ToString("0.00") + " MB/s"
|
||||||
|
|
@ -1077,8 +1077,191 @@ namespace IRaCIS.Core.API.Controllers
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost("download/VisitImageDownload")]
|
||||||
|
public async Task<IActionResult> VisitImageDownload([FromServices] IPatientService _patientService, [FromServices] IOSSService _oSSService,
|
||||||
|
[FromServices] IHubContext<DownloadHub, IDownloadClient> _downLoadHub,
|
||||||
|
[FromServices] IRepository<Trial> _trialRepository,
|
||||||
|
VisitImageDownloadCommand inCommand)
|
||||||
|
{
|
||||||
|
var rusult = await _patientService.GetDownloadSubjectVisitStudyInfo(inCommand);
|
||||||
|
|
||||||
|
var visitList = rusult.Data;
|
||||||
|
var downloadInfo = (SubejctVisitDownload)rusult.OtherData;
|
||||||
|
|
||||||
|
var trialInfo = _trialRepository.Where(t => t.Id == inCommand.TrialId).Select(t => new { t.TrialCode, t.ResearchProgramNo }).FirstOrDefault();
|
||||||
|
|
||||||
|
var trialZipName = $"{trialInfo.TrialCode}_{trialInfo.ResearchProgramNo}_Image_";
|
||||||
|
|
||||||
|
long receivedSize = 0;
|
||||||
|
long receivedCount = 0;
|
||||||
|
long totalSize = downloadInfo.ImageSize;
|
||||||
|
long totalCount = downloadInfo.ImageCount;
|
||||||
|
|
||||||
|
var abortToken = HttpContext.RequestAborted;
|
||||||
|
|
||||||
|
// -------- SignalR 节流参数 --------
|
||||||
|
var notifyInterval = TimeSpan.FromSeconds(1);
|
||||||
|
var lastNotify = DateTime.UtcNow;
|
||||||
|
|
||||||
|
// 用于计算下载速度
|
||||||
|
long lastReceivedSize = 0;
|
||||||
|
DateTime lastSpeedCheck = DateTime.UtcNow;
|
||||||
|
|
||||||
|
async Task NotifyProgressAsync(bool force = false)
|
||||||
|
{
|
||||||
|
|
||||||
|
var now = DateTime.UtcNow;
|
||||||
|
var elapsedSeconds = (now - lastSpeedCheck).TotalSeconds;
|
||||||
|
|
||||||
|
// 如果没有强制推送,并且未到推送间隔,则返回
|
||||||
|
if (!force && elapsedSeconds < notifyInterval.TotalSeconds)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 计算下载速度(字节/秒)
|
||||||
|
double speedBps = 0;
|
||||||
|
if (elapsedSeconds > 0)
|
||||||
|
{
|
||||||
|
speedBps = (receivedSize - lastReceivedSize) / elapsedSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastSpeedCheck = now;
|
||||||
|
lastReceivedSize = receivedSize;
|
||||||
|
lastNotify = DateTime.UtcNow;
|
||||||
|
|
||||||
|
var progress = new
|
||||||
|
{
|
||||||
|
CountPercent = totalCount > 0
|
||||||
|
? Math.Round(receivedCount * 100m / totalCount, 2).ToString()
|
||||||
|
: "0",
|
||||||
|
|
||||||
|
SizePercent = totalSize > 0
|
||||||
|
? Math.Round(receivedSize * 100m / totalSize, 2).ToString()
|
||||||
|
: "0",
|
||||||
|
|
||||||
|
Speed = (speedBps / 1024 >= 1024
|
||||||
|
? (speedBps / 1024 / 1024).ToString("0.00") + " MB/s"
|
||||||
|
: (speedBps / 1024).ToString("0.00") + " KB/s")
|
||||||
|
};
|
||||||
|
|
||||||
|
// 不阻塞下载流程
|
||||||
|
_ = _downLoadHub.Clients
|
||||||
|
.User(_userInfo.IdentityUserId.ToString())
|
||||||
|
.ReceivProgressAsync(
|
||||||
|
inCommand.CurrentNoticeId,
|
||||||
|
progress
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Response.ContentType = "application/zip";
|
||||||
|
Response.Headers["Content-Disposition"] = $"attachment; filename={trialZipName}{ExportExcelConverterDate.DateTimeInternationalToString(DateTime.Now, _userInfo.TimeZoneId)}.zip";
|
||||||
|
Response.Headers["Cache-Control"] = "no-store";
|
||||||
|
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await using var responseStream = Response.BodyWriter.AsStream();
|
||||||
|
using var zip = new ZipArchive(responseStream, ZipArchiveMode.Create, leaveOpen: true);
|
||||||
|
|
||||||
|
foreach (var visit in visitList)
|
||||||
|
{
|
||||||
|
foreach (var study in visit.StudyList)
|
||||||
|
{
|
||||||
|
abortToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
var studyTime = study.StudyTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "UnknownTime";
|
||||||
|
var modalitysStr = string.Join('_', study.SeriesList.Select(t => t.Modality).Distinct());
|
||||||
|
|
||||||
|
// ---------- DICOMDIR ----------
|
||||||
|
var dicomDirPath = $"{visit.SubjectCode}_{visit.VisitName}/{studyTime}_{modalitysStr}/DICOMDIR";
|
||||||
|
var dicomDirEntry = zip.CreateEntry(dicomDirPath, CompressionLevel.Fastest);
|
||||||
|
|
||||||
|
await using (var entryStream = dicomDirEntry.Open())
|
||||||
|
await using (var dirStream = await _oSSService.GetStreamFromOSSAsync(study.StudyDIRPath))
|
||||||
|
{
|
||||||
|
await dirStream.CopyToAsync(entryStream, 32 * 1024, abortToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- IMAGE FILES ----------
|
||||||
|
foreach (var series in study.SeriesList)
|
||||||
|
{
|
||||||
|
foreach (var instance in series.InstanceList)
|
||||||
|
{
|
||||||
|
//当前完成大小
|
||||||
|
receivedSize = receivedSize + instance.FileSize ?? 0;
|
||||||
|
receivedCount++;
|
||||||
|
|
||||||
|
abortToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
var entryPath =
|
||||||
|
$"{visit.SubjectCode}_{visit.VisitName}/{studyTime}_{modalitysStr}/IMAGE/{instance.FileName}";
|
||||||
|
|
||||||
|
var entry = zip.CreateEntry(entryPath, CompressionLevel.Fastest);
|
||||||
|
|
||||||
|
await using var entryStream = entry.Open();
|
||||||
|
await using var source = await _oSSService.GetStreamFromOSSAsync(instance.Path);
|
||||||
|
|
||||||
|
#region 将多帧合并为一帧
|
||||||
|
|
||||||
|
// 如果你是从 stream 打开
|
||||||
|
var dicomFile = await DicomFile.OpenAsync(source);
|
||||||
|
|
||||||
|
// 获取 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
await dicomFile.SaveAsync(entryStream);
|
||||||
|
//await source.CopyToAsync(entryStream, 32 * 1024, abortToken);
|
||||||
|
|
||||||
|
|
||||||
|
await NotifyProgressAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 正常完成
|
||||||
|
await NotifyProgressAsync(true);
|
||||||
|
await _patientService.DownloadImageSuccess(downloadInfo.Id);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
// ✅ 客户端取消 / 断开 —— 正常情况
|
||||||
|
Log.Logger.Warning("Download canceled by client");
|
||||||
|
}
|
||||||
|
catch (IOException ex) when (abortToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
// ✅ HttpClient 流在中断时的常见异常
|
||||||
|
Log.Logger.Warning($"Client disconnected: {ex.Message}");
|
||||||
|
}
|
||||||
|
catch (NullReferenceException ex) when (abortToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
// ✅ HttpConnection.ContentLengthReadStream 已知问题
|
||||||
|
Log.Logger.Warning($"Stream aborted: {ex.Message}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new EmptyResult();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ namespace IRaCIS.Core.Application.Helper
|
||||||
|
|
||||||
public class StudyDIRInfo
|
public class StudyDIRInfo
|
||||||
{
|
{
|
||||||
|
public Guid SubjectId { get; set; }
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
public Guid SubjectVisitId { get; set; }
|
public Guid SubjectVisitId { get; set; }
|
||||||
// Study
|
// Study
|
||||||
public Guid DicomStudyId { get; set; }
|
public Guid DicomStudyId { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -18834,12 +18834,10 @@
|
||||||
<param name="inCommand"></param>
|
<param name="inCommand"></param>
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Application.Services.PatientService.GetDownloadSubjectVisitStudyInfo(System.Guid,System.Guid,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.DicomStudy},IRaCIS.Core.Application.Helper.IOSSService)">
|
<member name="M:IRaCIS.Application.Services.PatientService.GetDownloadSubjectVisitStudyInfo(IRaCIS.Application.Contracts.VisitImageDownloadCommand)">
|
||||||
<summary>
|
<summary>
|
||||||
获取下载的访视检查信息
|
获取下载的访视检查信息
|
||||||
</summary>
|
</summary>
|
||||||
<param name="trialId"></param>
|
|
||||||
<param name="subjectVisitId"></param>
|
|
||||||
<returns></returns>
|
<returns></returns>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:IRaCIS.Application.Services.PatientService.DownloadImageSuccess(System.Guid)">
|
<member name="M:IRaCIS.Application.Services.PatientService.DownloadImageSuccess(System.Guid)">
|
||||||
|
|
|
||||||
|
|
@ -965,6 +965,16 @@ namespace IRaCIS.Application.Contracts
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class VisitImageDownloadCommand
|
||||||
|
{
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
|
|
||||||
|
public List<Guid> SubjectVisitIdList { get; set; }
|
||||||
|
|
||||||
|
[NotDefault]
|
||||||
|
public string CurrentNoticeId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class PatientImageDownloadCommand
|
public class PatientImageDownloadCommand
|
||||||
{
|
{
|
||||||
public List<Guid> PatientIdList { get; set; }
|
public List<Guid> PatientIdList { get; set; }
|
||||||
|
|
@ -1211,6 +1221,19 @@ namespace IRaCIS.Application.Contracts
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class DownloadVisitDto
|
||||||
|
{
|
||||||
|
public Guid TrialId { get; set; }
|
||||||
|
|
||||||
|
public Guid SubjectId { get; set; }
|
||||||
|
|
||||||
|
public string SubjectCode { get; set; }
|
||||||
|
|
||||||
|
public string VisitName { get; set; }
|
||||||
|
|
||||||
|
public List<DownloadDicomStudyDto> StudyList { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class DownloadPatientDto
|
public class DownloadPatientDto
|
||||||
{
|
{
|
||||||
public string PatientName { get; set; }
|
public string PatientName { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -10,5 +10,8 @@ namespace IRaCIS.Application.Interfaces
|
||||||
|
|
||||||
public Task<IResponseOutput> DownloadImageSuccess(Guid trialImageDownloadId);
|
public Task<IResponseOutput> DownloadImageSuccess(Guid trialImageDownloadId);
|
||||||
|
|
||||||
|
|
||||||
|
public Task<IResponseOutput<List<DownloadVisitDto>>> GetDownloadSubjectVisitStudyInfo(VisitImageDownloadCommand inCommand);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ namespace IRaCIS.Application.Services
|
||||||
public class PatientService(IRepository<SCPStudySubjectVisit> _studySubjectVisitRepository,
|
public class PatientService(IRepository<SCPStudySubjectVisit> _studySubjectVisitRepository,
|
||||||
IRepository<TrialIdentityUser> _trialIdentityUserRepository,
|
IRepository<TrialIdentityUser> _trialIdentityUserRepository,
|
||||||
IRepository<SCPStudy> _SCPStudyRepository, IOSSService _oSSService,
|
IRepository<SCPStudy> _SCPStudyRepository, IOSSService _oSSService,
|
||||||
|
IRepository<DicomStudy> _dicomStudyRepository,
|
||||||
IRepository<IdentityUser> _identityUserRepository,
|
IRepository<IdentityUser> _identityUserRepository,
|
||||||
IRepository<SubjectPatient> _subjectPatientRepository, IRepository<SCPStudyHospitalGroup> _SCPStudyHospitalGroupRepository,
|
IRepository<SubjectPatient> _subjectPatientRepository, IRepository<SCPStudyHospitalGroup> _SCPStudyHospitalGroupRepository,
|
||||||
IRepository<Trial> _trialRepository,
|
IRepository<Trial> _trialRepository,
|
||||||
|
|
@ -3458,11 +3459,8 @@ namespace IRaCIS.Application.Services
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取下载的访视检查信息
|
/// 获取下载的访视检查信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="trialId"></param>
|
|
||||||
/// <param name="subjectVisitId"></param>
|
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<IResponseOutput> GetDownloadSubjectVisitStudyInfo(Guid trialId, Guid subjectVisitId,
|
public async Task<IResponseOutput<List<DownloadVisitDto> >> GetDownloadSubjectVisitStudyInfo(VisitImageDownloadCommand inCommand)
|
||||||
[FromServices] IRepository<DicomStudy> _dicomStudyRepository, [FromServices] IOSSService _oSSService)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
var dirDic = new Dictionary<string, string>();
|
var dirDic = new Dictionary<string, string>();
|
||||||
|
|
@ -3470,13 +3468,15 @@ namespace IRaCIS.Application.Services
|
||||||
#region DIR处理导出文件名,并将对应关系上传到OSS里面存储
|
#region DIR处理导出文件名,并将对应关系上传到OSS里面存储
|
||||||
|
|
||||||
//有传输语法值的导出 才生成DIR
|
//有传输语法值的导出 才生成DIR
|
||||||
if (_subjectVisitRepository.Where(t => t.Id == subjectVisitId).SelectMany(t => t.StudyList.SelectMany(t => t.InstanceList)).All(c => c.TransferSyntaxUID != string.Empty))
|
if (_subjectVisitRepository.Where(t => inCommand.SubjectVisitIdList.Contains(t.Id) ).SelectMany(t => t.StudyList.SelectMany(t => t.InstanceList)).All(c => c.TransferSyntaxUID != string.Empty))
|
||||||
{
|
{
|
||||||
var list = _subjectVisitRepository.Where(t => t.Id == subjectVisitId).SelectMany(t => t.StudyList)
|
var list = _subjectVisitRepository.Where(t => inCommand.SubjectVisitIdList.Contains(t.Id)).SelectMany(t => t.StudyList)
|
||||||
.SelectMany(t => t.InstanceList)
|
.SelectMany(t => t.InstanceList)
|
||||||
.Select(t => new StudyDIRInfo()
|
.Select(t => new StudyDIRInfo()
|
||||||
{
|
{
|
||||||
|
SubjectId=t.SubjectId,
|
||||||
|
TrialId=t.TrialId,
|
||||||
|
SubjectVisitId=t.SubjectVisitId,
|
||||||
DicomStudyId = t.DicomStudy.Id,
|
DicomStudyId = t.DicomStudy.Id,
|
||||||
|
|
||||||
PatientId = t.DicomStudy.PatientId,
|
PatientId = t.DicomStudy.PatientId,
|
||||||
|
|
@ -3509,11 +3509,11 @@ namespace IRaCIS.Application.Services
|
||||||
|
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
var pathInfo = await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => new { t.TrialId, t.SubjectId, VisitId = t.Id }).FirstNotNullAsync();
|
//var pathInfoList = await _subjectVisitRepository.Where(t => inCommand.SubjectVisitIdList.Contains(t.Id)).Select(t => new { t.TrialId, t.SubjectId, VisitId = t.Id }).ToListAsync();
|
||||||
|
|
||||||
foreach (var item in list.GroupBy(t => new { t.StudyInstanceUid, t.DicomStudyId }))
|
foreach (var item in list.GroupBy(t => new { t.StudyInstanceUid, t.DicomStudyId,t.SubjectVisitId,t.TrialId,t.SubjectId }))
|
||||||
{
|
{
|
||||||
var ossFolder = $"{pathInfo.TrialId}/Image/{pathInfo.SubjectId}/{pathInfo.VisitId}/{item.Key.StudyInstanceUid}";
|
var ossFolder = $"{item.Key.TrialId}/Image/{item.Key.SubjectId}/{item.Key.SubjectVisitId}/{item.Key.StudyInstanceUid}";
|
||||||
|
|
||||||
var isSucess = await SafeBussinessHelper.RunAsync(async () => await DicomDIRHelper.GenerateStudyDIRAndUploadAsync(item.ToList(), dirDic, ossFolder, _oSSService));
|
var isSucess = await SafeBussinessHelper.RunAsync(async () => await DicomDIRHelper.GenerateStudyDIRAndUploadAsync(item.ToList(), dirDic, ossFolder, _oSSService));
|
||||||
|
|
||||||
|
|
@ -3529,9 +3529,9 @@ namespace IRaCIS.Application.Services
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
var query = from sv in _subjectVisitRepository.Where(t => t.Id == subjectVisitId)
|
var query = from sv in _subjectVisitRepository.Where(t => inCommand.SubjectVisitIdList.Contains(t.Id))
|
||||||
|
|
||||||
select new
|
select new DownloadVisitDto()
|
||||||
{
|
{
|
||||||
TrialId = sv.TrialId,
|
TrialId = sv.TrialId,
|
||||||
SubjectId = sv.SubjectId,
|
SubjectId = sv.SubjectId,
|
||||||
|
|
@ -3567,9 +3567,9 @@ namespace IRaCIS.Application.Services
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var result = query.FirstOrDefault();
|
var visitList = await query.ToListAsync();
|
||||||
|
|
||||||
foreach (var item in result.StudyList.SelectMany(t => t.SeriesList).SelectMany(t => t.InstanceList))
|
foreach (var item in visitList.SelectMany(t=>t.StudyList).SelectMany(t => t.SeriesList).SelectMany(t => t.InstanceList))
|
||||||
{
|
{
|
||||||
var key = item.InstanceId.ToString();
|
var key = item.InstanceId.ToString();
|
||||||
if (dirDic.ContainsKey(key))
|
if (dirDic.ContainsKey(key))
|
||||||
|
|
@ -3580,7 +3580,7 @@ namespace IRaCIS.Application.Services
|
||||||
|
|
||||||
var downLoadList = new ImageDownloadLog()
|
var downLoadList = new ImageDownloadLog()
|
||||||
{
|
{
|
||||||
DownLoadList = result.StudyList
|
DownLoadList = visitList.SelectMany(t => t.StudyList)
|
||||||
.Select(t => new ImageDownloadInfo()
|
.Select(t => new ImageDownloadInfo()
|
||||||
{ PatientId = t.PatientId, StudyId = t.StudyId, StudyInstanceUid = t.StudyInstanceUid, ImageCount = t.SeriesList.SelectMany(c => c.InstanceList).Count() }).ToList()
|
{ PatientId = t.PatientId, StudyId = t.StudyId, StudyInstanceUid = t.StudyInstanceUid, ImageCount = t.SeriesList.SelectMany(c => c.InstanceList).Count() }).ToList()
|
||||||
};
|
};
|
||||||
|
|
@ -3590,16 +3590,15 @@ namespace IRaCIS.Application.Services
|
||||||
DownLoadListStr = downLoadList.ToJsonStr(),
|
DownLoadListStr = downLoadList.ToJsonStr(),
|
||||||
Id = NewId.NextSequentialGuid(),
|
Id = NewId.NextSequentialGuid(),
|
||||||
IP = _userInfo.IP,
|
IP = _userInfo.IP,
|
||||||
SubjectVisitId = subjectVisitId,
|
|
||||||
DownloadStartTime = DateTime.Now,
|
DownloadStartTime = DateTime.Now,
|
||||||
StudyCount = result.StudyList.Count(),
|
StudyCount = visitList.SelectMany(t => t.StudyList).Count(),
|
||||||
ImageCount = result.StudyList.Sum(s => s.SeriesList.Sum(s => s.InstanceList.Count())),
|
ImageCount = visitList.SelectMany(t => t.StudyList).Sum(s => s.SeriesList.Sum(s => s.InstanceList.Count())),
|
||||||
ImageSize = result.StudyList.Sum(t => t.SeriesList.Sum(s => s.InstanceList.Sum(i => i.FileSize))) ?? 0
|
ImageSize = visitList.SelectMany(t => t.StudyList).Sum(t => t.SeriesList.Sum(s => s.InstanceList.Sum(i => i.FileSize))) ?? 0
|
||||||
};
|
};
|
||||||
|
|
||||||
await _subejctVisitDownloadRepository.AddAsync(preDownloadInfo, true);
|
await _subejctVisitDownloadRepository.AddAsync(preDownloadInfo, true);
|
||||||
|
|
||||||
return ResponseOutput.Ok(result, preDownloadInfo.Id);
|
return ResponseOutput.Ok(visitList, preDownloadInfo.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue