using FellowOakDicom; using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Service.ImageAndDoc.DTO; using MassTransit; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.IO.Compression; using System.Linq; using System.Text; using System.Threading.Tasks; namespace IRaCIS.Core.Application.Service.ImageAndDoc { public interface IDownloadAndUploadService { Task PackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isAnonymize = true); } [ApiExplorerSettings(GroupName = "Trial")] public class DownloadAndUploadService : BaseService, IDownloadAndUploadService { private readonly IRepository _systemAnonymizationRepository; private readonly IRepository _subjectVisitRepository; private readonly IOSSService _oSSService; public DownloadAndUploadService(IRepository systemAnonymizationRepository, IRepository subjectVisitRepository, IOSSService oSSService) { _systemAnonymizationRepository = systemAnonymizationRepository; _subjectVisitRepository = subjectVisitRepository; _oSSService = oSSService; } /// /// 获取该受试者任务上传列表(展示已上传情况) /// /// /// public async Task>> GetSubjectImageUploadList(Guid subjectId) { var query = _repository.Where(t => t.Id == subjectId && t.SourceSubjectVisitId != null) .Select(u => new SubjectImageUploadDTO() { SubejctId = u.SubjectId, SubjectCode = u.IsSelfAnalysis == true ? u.Subject.Code : u.BlindSubjectCode, TaskBlindName = u.TaskBlindName, TaskName = u.TaskName, SourceSubjectVisitId = u.SourceSubjectVisitId, PackState = u.SourceSubjectVisit.PackState, OrginalStudyList = u.SourceSubjectVisit.StudyList.Select(t => new StudyBasicInfo() { Id = t.Id, Description = t.Description, InstanceCount = t.InstanceCount, Modalities = t.Modalities, SeriesCount = t.SeriesCount, }).ToList(), UploadStudyList = u.TaskStudyList.Select(t => new StudyBasicInfo() { Id = t.Id, Description = t.Description, InstanceCount = t.InstanceCount, Modalities = t.Modalities, SeriesCount = t.SeriesCount, }).ToList() }) ; var list = await query.ToListAsync(); return ResponseOutput.Ok(list); } /// /// 打包和匿名化影像 默认是匿名化打包,也可以不匿名化打包 /// /// /// /// /// public async Task RequestPackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isAnonymize = true) { var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId); if (subjectVisit.PackState == PackState.WaitPack) { HangfireJobHelper.NotImmediatelyOnceOnlyJob(t => t.PackageAndAnonymizImage(trialId, subjectVisitId, isAnonymize), TimeSpan.FromSeconds(1)); subjectVisit.PackState = PackState.Packing; await _subjectVisitRepository.SaveChangesAsync(); } return ResponseOutput.Ok(subjectVisit.VisitImageZipPath); } /// /// 后台任务调用,前端忽略该接口 /// /// /// /// /// public async Task PackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isAnonymize = true) { var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId); try { var addOrUpdateFixedFieldList = new List(); var ircFieldList = new List(); if (isAnonymize) { var systemAnonymizationList = _systemAnonymizationRepository.Where(t => t.IsEnable).ToList(); addOrUpdateFixedFieldList = systemAnonymizationList.Where(t => t.IsFixed).ToList(); ircFieldList = systemAnonymizationList.Where(t => t.IsFixed == false).ToList(); } var subjectAndVisitInfo = _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => new { SubjectCode = t.Subject.Code, t.Trial.TrialCode, t.VisitNum }).FirstOrDefault(); var query = from sv in _subjectVisitRepository.Where(t => t.Id == subjectVisitId) select new { SubjectCode = sv.Subject.Code, VisitName = sv.VisitName, StudyList = sv.StudyList.Select(u => new { u.PatientId, u.StudyTime, u.StudyCode, SeriesList = u.SeriesList.Select(z => new { z.Modality, InstancePathList = z.DicomInstanceList.Select(k => new { k.Path }) }) }) }; var info = query.FirstOrDefault(); if (info != null) { // 创建一个临时文件夹来存放文件 string tempFolderPath = Path.Combine(Directory.GetCurrentDirectory(), $"DownloadTemp_{NewId.NextGuid()}"); Directory.CreateDirectory(tempFolderPath); // 遍历查询结果 foreach (var studyInfo in info.StudyList) { // 遍历 Series foreach (var seriesInfo in studyInfo.SeriesList) { string studyFolderPath = Path.Combine(tempFolderPath, $"{info.SubjectCode}_{info.VisitName}", $"{studyInfo.StudyCode}_{studyInfo.StudyTime?.ToString("yyyy-MM-dd")}_{seriesInfo.Modality}"); // 创建 影像 文件夹 Directory.CreateDirectory(studyFolderPath); // 遍历 InstancePathList foreach (var instanceInfo in seriesInfo.InstancePathList) { // 复制文件到相应的文件夹 string destinationPath = Path.Combine(studyFolderPath, Path.GetFileName(instanceInfo.Path)); //下载到当前目录 await _oSSService.DownLoadFromOSSAsync(instanceInfo.Path, destinationPath); #region 匿名化逻辑 if (isAnonymize) { DicomFile dicomFile = await DicomFile.OpenAsync(destinationPath, Encoding.Default); DicomDataset dataset = dicomFile.Dataset; foreach (var item in addOrUpdateFixedFieldList) { var dicomTag = new DicomTag(Convert.ToUInt16(item.Group, 16), Convert.ToUInt16(item.Element, 16)); dataset.AddOrUpdate(dicomTag, item.ReplaceValue); } foreach (var item in ircFieldList) { var dicomTag = new DicomTag(Convert.ToUInt16(item.Group, 16), Convert.ToUInt16(item.Element, 16)); if (dicomTag == DicomTag.ClinicalTrialProtocolID) { dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.TrialCode); } if (dicomTag == DicomTag.ClinicalTrialSiteID) { //dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.TrialSiteCode); } if (dicomTag == DicomTag.ClinicalTrialSubjectID) { dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.SubjectCode); } if (dicomTag == DicomTag.ClinicalTrialTimePointID) { dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.VisitNum.ToString()); } if (dicomTag == DicomTag.PatientID) { dataset.AddOrUpdate(dicomTag, subjectAndVisitInfo.TrialCode + "_" + subjectAndVisitInfo.SubjectCode); } } } #endregion } } } var zipPath = Path.Combine(Directory.GetCurrentDirectory(), $"{info.SubjectCode}_{info.VisitName}_ImageStudy.zip"); ZipFile.CreateFromDirectory(tempFolderPath, zipPath); //上传到Oss var relativePath = await _oSSService.UploadToOSSAsync(zipPath, $"download_zip", false); //subjectVisit.PackState = PackState.Packed; //subjectVisit.VisitImageZipPath = relativePath; //await _subjectVisitRepository.SaveChangesAsync(); await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.Packed, VisitImageZipPath = relativePath }); //清理文件夹 Directory.Delete(tempFolderPath, true); File.Delete(zipPath); } } catch (Exception ex) { await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.WaitPack }); } } } }