1623 lines
		
	
	
		
			75 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			1623 lines
		
	
	
		
			75 KiB
		
	
	
	
		
			C#
		
	
	
| using DocumentFormat.OpenXml.EMMA;
 | ||
| using FellowOakDicom;
 | ||
| using IRaCIS.Core.Application.Contracts;
 | ||
| using IRaCIS.Core.Application.Contracts.Dicom.DTO;
 | ||
| using IRaCIS.Core.Application.Filter;
 | ||
| using IRaCIS.Core.Application.Helper;
 | ||
| using IRaCIS.Core.Application.Service.ImageAndDoc.DTO;
 | ||
| using IRaCIS.Core.Domain.Models;
 | ||
| using IRaCIS.Core.Domain.Share;
 | ||
| using IRaCIS.Core.Infrastructure;
 | ||
| using MassTransit;
 | ||
| using MassTransit.Initializers;
 | ||
| using Medallion.Threading;
 | ||
| using Microsoft.AspNetCore.Mvc;
 | ||
| using Newtonsoft.Json;
 | ||
| using System.Data;
 | ||
| using System.IO.Compression;
 | ||
| using System.Text;
 | ||
| using System.Web;
 | ||
| using ZiggyCreatures.Caching.Fusion;
 | ||
| 
 | ||
| namespace IRaCIS.Core.Application.Service.ImageAndDoc
 | ||
| {
 | ||
|     public interface IDownloadAndUploadService
 | ||
|     {
 | ||
|         Task PackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isDicom, bool isAnonymize = true);
 | ||
| 
 | ||
|         Task<IResponseOutput> SubejctRandomReadingTaskNameDeal(Guid subjectId, Guid trialReadingCriterionId);
 | ||
|     }
 | ||
| 
 | ||
|     [ApiExplorerSettings(GroupName = "Trial")]
 | ||
|     public class DownloadAndUploadService(IRepository<SystemAnonymization> _systemAnonymizationRepository,
 | ||
|         IRepository<VisitTask> _visitTaskRepository,
 | ||
|         IRepository<SubjectVisit> _subjectVisitRepository,
 | ||
|         IOSSService _oSSService,
 | ||
|         IRepository<Dictionary> _dictionaryRepository,
 | ||
|         IRepository<Trial> _trialRepository,
 | ||
|         IRepository<StudyMonitor> _studyMonitorRepository,
 | ||
|         IRepository<TaskStudy> _taskStudyRepository,
 | ||
|         IRepository<TaskSeries> _taskSeriesRepository,
 | ||
|         IRepository<TaskInstance> _taskInstanceRepository,
 | ||
|         IRepository<ReadingQuestionCriterionTrial> _readingQuestionCriterionTrialRepository,
 | ||
|         IRepository<NoneDicomStudy> _noneDicomStudyReposiotry,
 | ||
|         IRepository<NoneDicomStudyFile> _noneDicomStudyFileReposiotry,
 | ||
|         IDistributedLockProvider _distributedLockProvider,
 | ||
|         IRepository<TrialImageDownload> _trialImageDownloadRepository,
 | ||
|         IRepository<Subject> _subjectRepository, 
 | ||
|         IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer, IFusionCache _fusionCache) : BaseService, IDownloadAndUploadService
 | ||
|     {
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 受试者随机阅片,任务进行随机编号
 | ||
|         /// 进入阅片任务前,随机挑选出该受试者的一个任务,然后给该任务一个编号,编号给的逻辑是:TimePoint Ran+ 已阅任务数量+1
 | ||
|         /// 根据当前受试者该标准已阅任务数量(生效失效的任务都算,考虑重阅,最后编号不重复)  第一个就是TimePoint Ran1,后面依次随机挑选出来的阅片序号依次递增
 | ||
|         /// </summary>
 | ||
|         /// <param name="subjectId"></param>
 | ||
|         /// <param name="trialReadingCriterionId"></param>
 | ||
|         /// <returns></returns>
 | ||
|         public async Task<IResponseOutput> SubejctRandomReadingTaskNameDeal(Guid subjectId, Guid trialReadingCriterionId)
 | ||
|         {
 | ||
|             //subject 随机阅片  或者无序 有上传 才处理任务编号
 | ||
|             if (_visitTaskRepository.Any(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId &&
 | ||
|            (t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.SubjectRandom ||
 | ||
|            (t.TrialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.Random && t.TrialReadingCriterion.ImageUploadEnum != ReadingImageUpload.None))))
 | ||
|             {
 | ||
|                 //找到 非一致性分析,未签名,状态正常的 并且任务名称是TimePoint的 任务
 | ||
|                 var needDealTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.UserRoleId
 | ||
|                    && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.TaskBlindName == "Timepoint" && t.ReadingCategory == ReadingCategory.Visit
 | ||
|                    && (t.TaskState == TaskState.Effect || t.TaskState == TaskState.Freeze), true).ToListAsync();
 | ||
| 
 | ||
|                 if (needDealTaskList.Count > 0)
 | ||
|                 {
 | ||
|                     //已完成的访视任务数量(包含重阅的)
 | ||
|                     var haveFinishedTaskCount = await _visitTaskRepository.CountAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.UserRoleId
 | ||
|                     && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit);
 | ||
| 
 | ||
|                     //已经处理过的任务名称的数量
 | ||
| 
 | ||
|                     var haveDealedTaskList = await _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.DoctorUserId == _userInfo.UserRoleId
 | ||
|                     && t.ReadingTaskState != ReadingTaskState.HaveSigned && t.ReadingCategory == ReadingCategory.Visit && t.TaskBlindName != "Timepoint").Select(t => new { t.TaskBlindName, t.SourceSubjectVisitId, t.SouceReadModuleId }).ToListAsync();
 | ||
| 
 | ||
| 
 | ||
|                     //随机赋值编号  比如要处理5个任务,实例化一个包含1-5的数组,每次随机取出一个
 | ||
|                     List<int> availableNumbers = Enumerable.Range(haveDealedTaskList.Count + haveFinishedTaskCount + 1, needDealTaskList.Count).ToList();
 | ||
|                     Random rng = new Random();
 | ||
|                     foreach (var visitTask in needDealTaskList)
 | ||
|                     {
 | ||
|                         int randomIndex = rng.Next(availableNumbers.Count);
 | ||
| 
 | ||
|                         var findOldTask = haveDealedTaskList.Where(t => t.SourceSubjectVisitId == visitTask.SourceSubjectVisitId && t.SouceReadModuleId == visitTask.SouceReadModuleId).FirstOrDefault();
 | ||
| 
 | ||
|                         if (findOldTask != null)
 | ||
|                         {
 | ||
|                             visitTask.TaskBlindName = findOldTask.TaskBlindName;
 | ||
|                         }
 | ||
|                         else
 | ||
|                         {
 | ||
|                             visitTask.TaskBlindName = $"Timepoint Ran {availableNumbers[randomIndex]}";
 | ||
|                         }
 | ||
| 
 | ||
|                         availableNumbers.RemoveAt(randomIndex);
 | ||
|                     }
 | ||
|                     await _visitTaskRepository.SaveChangesAsync();
 | ||
|                 }
 | ||
|             }
 | ||
|             return ResponseOutput.Ok();
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 获取该受试者任务上传列表(展示已上传情况)
 | ||
|         /// </summary>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<IResponseOutput<List<SubjectImageUploadDTO>>> GetSubjectImageUploadList(IRUploadStudyQuery inQuery)
 | ||
|         {
 | ||
| 
 | ||
|             //要根据标准阅片顺序,确定是否查询单个任务的,还是查询所有的
 | ||
|             var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
 | ||
|                  .Select(t => new { t.IsReadingTaskViewInOrder, t.Trial.Modalitys }).FirstNotNullAsync();
 | ||
| 
 | ||
|             var subjectCode = string.Empty;
 | ||
|             var subjectId = inQuery.SubjectId;
 | ||
| 
 | ||
|             if (criterionInfo.IsReadingTaskViewInOrder == ReadingOrder.Random)
 | ||
|             {
 | ||
|                 if (inQuery.VisitTaskId == null)
 | ||
|                 {
 | ||
|                     throw new Exception("无序阅片,前端参数传递错误");
 | ||
|                 }
 | ||
|                 //考虑到一致性分析,必须要这个编号进行过滤
 | ||
|                 var taskInfo = _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId).Select(t => new
 | ||
|                 {
 | ||
|                     SubjectCode = t.IsAnalysisCreate ? t.BlindSubjectCode : t.Subject.Code,
 | ||
|                     SubjectId = t.SubjectId,
 | ||
|                 }).FirstOrDefault();
 | ||
|                 subjectId = taskInfo.SubjectId;
 | ||
|                 subjectCode = taskInfo.SubjectCode;
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 if (inQuery.SubjectId == null || inQuery.SubjectCode == null)
 | ||
|                 {
 | ||
|                     throw new Exception("有序阅片,前端参数传递错误");
 | ||
|                 }
 | ||
| 
 | ||
|                 //考虑到一致性分析,必须要这个编号进行过滤
 | ||
|                 subjectCode = inQuery.SubjectCode;
 | ||
|             }
 | ||
| 
 | ||
|             await SubejctRandomReadingTaskNameDeal((Guid)subjectId, inQuery.TrialReadingCriterionId);
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|             var query = _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId && t.SourceSubjectVisitId != null
 | ||
|             && t.DoctorUserId == _userInfo.UserRoleId && t.TaskState == TaskState.Effect)
 | ||
|                 //满足 有序,或者随机只看到当前任务的dicom 非dicom检查
 | ||
|                 .WhereIf(criterionInfo.IsReadingTaskViewInOrder != ReadingOrder.SubjectRandom && inQuery.VisitTaskId != null, t => t.Id == inQuery.VisitTaskId)
 | ||
|                 .Select(u => new SubjectImageUploadDTO()
 | ||
|                 {
 | ||
|                     VisitTaskId = u.Id,
 | ||
| 
 | ||
|                     SubejctId = u.SubjectId,
 | ||
| 
 | ||
|                     TrialSiteId = u.Subject.TrialSiteId,
 | ||
| 
 | ||
|                     IsImageFilter = u.TrialReadingCriterion.IsImageFilter,
 | ||
| 
 | ||
|                     CriterionModalitys = u.TrialReadingCriterion.CriterionModalitys,
 | ||
| 
 | ||
|                     SubjectCode = u.IsAnalysisCreate == true ? u.BlindSubjectCode : u.Subject.Code,
 | ||
|                     TaskBlindName = u.TaskBlindName,
 | ||
|                     TaskName = u.TaskName,
 | ||
|                     ReadingTaskState = u.ReadingTaskState,
 | ||
| 
 | ||
|                     SourceSubjectVisitId = u.SourceSubjectVisitId,
 | ||
| 
 | ||
|                     OrginalStudyList = u.SourceSubjectVisit.StudyList
 | ||
|                     .Where(t => u.TrialReadingCriterion.IsImageFilter ? ("|" + u.TrialReadingCriterion.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true)
 | ||
|                     .Select(t => new StudyBasicInfo()
 | ||
|                     {
 | ||
|                         Id = t.Id,
 | ||
|                         StudyInstanceUid = t.StudyInstanceUid,
 | ||
|                         ModalityForEdit = t.ModalityForEdit,
 | ||
|                         BodyPartExamined = t.BodyPartExamined,
 | ||
|                         BodyPartForEdit = t.BodyPartForEdit,
 | ||
| 
 | ||
|                         StudyCode = t.StudyCode,
 | ||
|                         StudyTime = t.StudyTime,
 | ||
|                         Description = t.Description,
 | ||
|                         InstanceCount = t.InstanceCount,
 | ||
|                         Modalities = t.Modalities,
 | ||
|                         SeriesCount = t.SeriesCount,
 | ||
|                     }).ToList(),
 | ||
| 
 | ||
|                     UploadStudyList = u.TaskStudyList.Select(t => new StudyBasicInfo()
 | ||
|                     {
 | ||
|                         Id = t.Id,
 | ||
|                         StudyInstanceUid = t.StudyInstanceUid,
 | ||
|                         ModalityForEdit = t.ModalityForEdit,
 | ||
|                         BodyPartExamined = t.BodyPartExamined,
 | ||
|                         BodyPartForEdit = t.BodyPartForEdit,
 | ||
| 
 | ||
|                         StudyCode = t.StudyCode,
 | ||
|                         StudyTime = t.StudyTime,
 | ||
|                         Description = t.Description,
 | ||
|                         InstanceCount = t.InstanceCount,
 | ||
|                         Modalities = t.Modalities,
 | ||
|                         SeriesCount = t.SeriesCount,
 | ||
| 
 | ||
|                         SopInstanceUidList = t.InstanceList.Select(t => t.SopInstanceUid).ToList(),
 | ||
| 
 | ||
|                     }).ToList()
 | ||
|                 })
 | ||
|                 ;
 | ||
|             //var test = await query.ToListAsync();
 | ||
| 
 | ||
|             var list = await query.Where(t => t.SubjectCode == subjectCode).ToListAsync();
 | ||
| 
 | ||
| 
 | ||
|             return ResponseOutput.Ok(list, new { TrialModality = criterionInfo.Modalitys });
 | ||
|         }
 | ||
| 
 | ||
|         private void SpecialArchiveStudyDeal(TaskStudy study)
 | ||
|         {
 | ||
|             #region 特殊逻辑
 | ||
| 
 | ||
| 
 | ||
|             if (study.PatientBirthDate.Length == 8)
 | ||
|             {
 | ||
|                 study.PatientBirthDate = $"{study.PatientBirthDate[0]}{study.PatientBirthDate[1]}{study.PatientBirthDate[2]}{study.PatientBirthDate[3]}-{study.PatientBirthDate[4]}{study.PatientBirthDate[5]}-{study.PatientBirthDate[6]}{study.PatientBirthDate[7]}";
 | ||
|             }
 | ||
| 
 | ||
|             var dicModalityList = _dictionaryRepository.Where(t => t.Code == "Modality").SelectMany(t => t.ChildList.Select(c => c.Value)).ToList();
 | ||
| 
 | ||
| 
 | ||
|             var modality = study.Modalities;
 | ||
| 
 | ||
|             var modalityForEdit = dicModalityList.Contains(modality) ? modality : String.Empty;
 | ||
| 
 | ||
|             if (modality == "MR")
 | ||
|             {
 | ||
|                 modalityForEdit = "MRI";
 | ||
|             }
 | ||
| 
 | ||
|             if (modality == "PT")
 | ||
|             {
 | ||
|                 modalityForEdit = "PET";
 | ||
|             }
 | ||
|             if (modality == "PT、CT")
 | ||
|             {
 | ||
|                 modalityForEdit = "PET-CT";
 | ||
|             }
 | ||
| 
 | ||
|             study.ModalityForEdit = modalityForEdit;
 | ||
|             #endregion
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         [TrialGlobalLimit( "AfterStopCannNotOpt" )]
 | ||
| 
 | ||
|         public async Task<IResponseOutput> PreArchiveDicomStudy(PriArchiveTaskStudyCommand preArchiveStudyCommand)
 | ||
|         {
 | ||
| 
 | ||
|             var studyMonitor = new StudyMonitor()
 | ||
|             {
 | ||
|                 TrialId = preArchiveStudyCommand.TrialId,
 | ||
|                 SubjectId = preArchiveStudyCommand.SubjectId,
 | ||
|                 SubjectVisitId = preArchiveStudyCommand.SubjectVisitId,
 | ||
|                 IsSuccess = false,
 | ||
|                 UploadStartTime = DateTime.Now,
 | ||
|                 IsDicom = true,
 | ||
|                 IP = _userInfo.IP,
 | ||
|                 FileCount = preArchiveStudyCommand.FileCount,
 | ||
|             };
 | ||
| 
 | ||
| 
 | ||
|             var addEntity = await _studyMonitorRepository.AddAsync(studyMonitor, true);
 | ||
| 
 | ||
|             return ResponseOutput.Ok(addEntity.Id);
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 在调用预归档前验证 这些检查是否可以全新上传还是已存在补充 目前前端允许  IsAllowUpload==true 全新、IsAllowReUpload==true 补充的study   ,全部丢到后端,后端判断存在,就删除之前的检查,全新插入
 | ||
|         /// </summary>
 | ||
|         /// <param name="inCommand"></param>
 | ||
|         /// <param name="_dicomStudyRepository"></param>
 | ||
|         /// <returns></returns>
 | ||
|         public async Task<List<TaskStudyArchiveConfirmResult>> VerifyIRStudyAllowUpload(TaskStudyAchivePreConfirmCommand inCommand, [FromServices] IRepository<DicomStudy> _dicomStudyRepository)
 | ||
|         {
 | ||
| 
 | ||
|             var currentUploadSubjectVisitId = inCommand.VisitTaskId == null ? null : _visitTaskRepository.Where(t => t.Id == inCommand.VisitTaskId).Select(t => t.SourceSubjectVisitId).FirstOrDefault();
 | ||
| 
 | ||
|             //重阅任务排除
 | ||
|             var notAllowedUidList1 = _taskStudyRepository.Where(t => t.TrialId == inCommand.TrialId && t.VisitTask.TaskState == TaskState.Effect && inCommand.StudyInstanceUidList.Contains(t.StudyInstanceUid)).Select(t => new
 | ||
|             {
 | ||
|                 t.StudyInstanceUid,
 | ||
|                 t.SubjectId,
 | ||
|                 SubjectVisitId = t.VisitTask.SourceSubjectVisitId,
 | ||
|                 SubejectCode = t.VisitTask.IsAnalysisCreate ? t.VisitTask.BlindSubjectCode : t.Subject.Code,
 | ||
|                 VisitTaskId = (Guid?)t.VisitTaskId
 | ||
|             }).ToList();
 | ||
| 
 | ||
|             var notAllowedUidList2 = _dicomStudyRepository.Where(t => t.TrialId == inCommand.TrialId && inCommand.StudyInstanceUidList.Contains(t.StudyInstanceUid)).Select(t => new
 | ||
|             {
 | ||
|                 t.StudyInstanceUid,
 | ||
|                 t.SubjectId,
 | ||
|                 SubjectVisitId = (Guid?)t.SubjectVisitId,
 | ||
|                 SubejectCode = t.Subject.Code,
 | ||
|                 VisitTaskId = (Guid?)null
 | ||
|             }).ToList();
 | ||
| 
 | ||
|             var notAllowedUidList = notAllowedUidList1.Union(notAllowedUidList2);
 | ||
| 
 | ||
|             var result = new List<TaskStudyArchiveConfirmResult>();
 | ||
| 
 | ||
|             foreach (var studyUid in inCommand.StudyInstanceUidList)
 | ||
|             {
 | ||
|                 var findStudy = notAllowedUidList.Where(t => t.StudyInstanceUid == studyUid).FirstOrDefault();
 | ||
|                 if (findStudy != null)
 | ||
|                 {
 | ||
| 
 | ||
|                     //同一个subject 同一份影响
 | ||
|                     if (findStudy.SubejectCode == inCommand.SubjectCode && findStudy.SubjectId == inCommand.SubjectId)
 | ||
|                     {
 | ||
|                         //上传给后处理其他访视了
 | ||
|                         if (inCommand.VisitTaskId != null && findStudy.VisitTaskId != null && findStudy.VisitTaskId != inCommand.VisitTaskId && findStudy.SubjectVisitId != currentUploadSubjectVisitId)
 | ||
|                         {
 | ||
|                             result.Add(new TaskStudyArchiveConfirmResult() { StudyInstanceUid = studyUid, IsAllowReUpload = false, IsAllowUpload = false });
 | ||
|                         }
 | ||
|                         //在原始crc 里面上传了,并且不是当前访视
 | ||
|                         else if (inCommand.VisitTaskId != null && findStudy.VisitTaskId == null && findStudy.SubjectVisitId != currentUploadSubjectVisitId)
 | ||
|                         {
 | ||
|                             result.Add(new TaskStudyArchiveConfirmResult() { StudyInstanceUid = studyUid, IsAllowReUpload = false, IsAllowUpload = false });
 | ||
|                         }
 | ||
|                         else
 | ||
|                         {
 | ||
|                             result.Add(new TaskStudyArchiveConfirmResult() { StudyInstanceUid = studyUid, IsAllowReUpload = true });
 | ||
|                         }
 | ||
|                     }
 | ||
|                     else
 | ||
|                     {
 | ||
|                         result.Add(new TaskStudyArchiveConfirmResult() { StudyInstanceUid = studyUid, IsAllowReUpload = false, IsAllowUpload = false });
 | ||
|                     }
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     //说明没上传 不用管
 | ||
|                     result.Add(new TaskStudyArchiveConfirmResult() { StudyInstanceUid = studyUid, IsAllowUpload = true });
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             return result;
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         [TrialGlobalLimit( "AfterStopCannNotOpt" )]
 | ||
|         public async Task<IResponseOutput> AddOrUpdateArchiveTaskStudy(TaskArchiveStudyCommand incommand)
 | ||
|         {
 | ||
|             #region 获取该subject 已生成任务的访视的检查
 | ||
| 
 | ||
|             //var queryStudy = _visitTaskRepository.Where(t => t.SubjectId == incommand.SubjectId && t.SourceSubjectVisitId != null && t.DoctorUserId == _userInfo.Id).Select(u => new
 | ||
|             //{
 | ||
|             //    VisitTaskId = u.Id,
 | ||
|             //    SourceSubjectVisitId = u.SourceSubjectVisitId,
 | ||
|             //    OrginalStudyList = u.SourceSubjectVisit.StudyList.Select(t => new StudyBasicInfo()
 | ||
|             //    {
 | ||
|             //        Id = t.Id,
 | ||
|             //        StudyInstanceUid = t.StudyInstanceUid
 | ||
|             //    }).ToList(),
 | ||
|             //});
 | ||
| 
 | ||
|             //var studyList = await queryStudy.ToListAsync();
 | ||
| 
 | ||
| 
 | ||
|             //var findOriginStudy = studyList.FirstOrDefault(c => c.OrginalStudyList.Any(t => t.StudyInstanceUid == incommand.Study.StudyInstanceUid));
 | ||
| 
 | ||
|             //if (findOriginStudy == null)
 | ||
|             //{
 | ||
|             //    return ResponseOutput.NotOk("该检查不属于该受试者,请核查");
 | ||
|             //}
 | ||
| 
 | ||
|             #endregion
 | ||
| 
 | ||
|             //总数为0的检查不允许提交
 | ||
|             if (incommand.Study.SeriesList.SelectMany(t => t.InstanceList).Count() == 0)
 | ||
|             {
 | ||
|                 return ResponseOutput.NotOk("Study_InstanceCountZero");
 | ||
|             }
 | ||
| 
 | ||
|             var @uploadLock = _distributedLockProvider.CreateLock($"UploadTaskDicom");
 | ||
| 
 | ||
|             using (await @uploadLock.AcquireAsync())
 | ||
|             {
 | ||
|                 if (_fusionCache.GetOrDefault<Guid>(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid)) != Guid.Empty)
 | ||
|                 {
 | ||
|                     //---当前已有人正在上传和归档该检查!
 | ||
|                     return ResponseOutput.NotOk(I18n.T("UploadDownLoad_ArchiveInProgress"));
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     //在事务未完成前 防止前端重复提交
 | ||
|                     await _fusionCache.SetAsync(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid), _userInfo.UserRoleId, TimeSpan.FromMinutes(1));
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             var visiTaskId = incommand.VisitTaskId;
 | ||
| 
 | ||
|             var modalitys = string.Empty;
 | ||
| 
 | ||
|             try
 | ||
|             {
 | ||
|                 var trialId = incommand.TrialId;
 | ||
| 
 | ||
| 
 | ||
|                 var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == incommand.StudyMonitorId);
 | ||
|                 studyMonitor.UploadFinishedTime = DateTime.Now;
 | ||
|                 studyMonitor.ArchiveFinishedTime = DateTime.Now;
 | ||
|                 studyMonitor.FailedFileCount = incommand.FailedFileCount;
 | ||
|                 studyMonitor.IsSuccess = incommand.FailedFileCount == 0;
 | ||
|                 studyMonitor.RecordPath = incommand.RecordPath;
 | ||
|                 studyMonitor.FileSize = incommand.Study.SeriesList.SelectMany(t => t.InstanceList).Sum(t => t.FileSize);
 | ||
| 
 | ||
|                 var studyId = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString());
 | ||
|                 var findStudy = await _taskStudyRepository.FirstOrDefaultAsync(t => t.Id == studyId);
 | ||
| 
 | ||
| 
 | ||
|                 studyMonitor.StudyId = studyId;
 | ||
|                 studyMonitor.StudyCode = findStudy?.StudyCode ?? "";
 | ||
| 
 | ||
|                 studyMonitor.IsDicomReUpload = findStudy != null;
 | ||
| 
 | ||
|                 //上传
 | ||
|                 if (studyMonitor.IsDicomReUpload == false)
 | ||
|                 {
 | ||
| 
 | ||
| 
 | ||
|                     var study = _mapper.Map<TaskStudy>(incommand.Study);
 | ||
| 
 | ||
|                     var @lock = _distributedLockProvider.CreateLock($"StudyCode");
 | ||
| 
 | ||
|                     using (await @lock.AcquireAsync())
 | ||
|                     {
 | ||
|                         //查询数据库获取最大的Code 没有记录则为0
 | ||
|                         var dbStudyCodeIntMax = _taskStudyRepository.Where(s => s.TrialId == trialId).Select(t => t.Code).DefaultIfEmpty().Max();
 | ||
| 
 | ||
|                         //获取缓存中的值 并发的时候,需要记录,已被占用的值 这样其他线程在此占用的最大的值上递增
 | ||
|                         var cacheMaxCodeInt = await _fusionCache.GetOrDefaultAsync<int>(CacheKeys.TrialStudyMaxCode(trialId));
 | ||
| 
 | ||
|                         int currentNextCodeInt = cacheMaxCodeInt > dbStudyCodeIntMax ? cacheMaxCodeInt + 1 : dbStudyCodeIntMax + 1;
 | ||
|                         study.Code = currentNextCodeInt;
 | ||
| 
 | ||
|                         study.StudyCode = AppSettings.GetCodeStr(currentNextCodeInt, nameof(TaskStudy));
 | ||
| 
 | ||
|                         await _fusionCache.SetAsync<int>(CacheKeys.TrialStudyMaxCode(trialId), study.Code, TimeSpan.FromMinutes(30));
 | ||
| 
 | ||
|                     }
 | ||
| 
 | ||
| 
 | ||
|                     study.Id = IdentifierHelper.CreateGuid(incommand.Study.StudyInstanceUid, incommand.TrialId.ToString(), visiTaskId.ToString());
 | ||
|                     study.TrialId = incommand.TrialId;
 | ||
|                     study.SubjectId = incommand.SubjectId;
 | ||
|                     study.VisitTaskId = visiTaskId;
 | ||
|                     //study.SubjectVisitId = incommand.SubjectVisitId;
 | ||
| 
 | ||
| 
 | ||
|                     //特殊处理逻辑
 | ||
|                     study.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Distinct());
 | ||
|                     SpecialArchiveStudyDeal(study);
 | ||
|                     modalitys = study.Modalities;
 | ||
| 
 | ||
|                     await _taskStudyRepository.AddAsync(study);
 | ||
| 
 | ||
| 
 | ||
|                     studyMonitor.StudyCode = study.StudyCode;
 | ||
| 
 | ||
| 
 | ||
|                     foreach (var seriesItem in incommand.Study.SeriesList)
 | ||
|                     {
 | ||
|                         var series = _mapper.Map<TaskSeries>(seriesItem);
 | ||
| 
 | ||
|                         series.Id = IdentifierHelper.CreateGuid(seriesItem.StudyInstanceUid, seriesItem.SeriesInstanceUid, incommand.TrialId.ToString(), visiTaskId.ToString());
 | ||
|                         series.StudyId = study.Id;
 | ||
| 
 | ||
|                         series.TrialId = incommand.TrialId;
 | ||
|                         series.SubjectId = incommand.SubjectId;
 | ||
|                         //series.SubjectVisitId = incommand.SubjectVisitId;
 | ||
|                         series.VisitTaskId = visiTaskId;
 | ||
| 
 | ||
|                         //前端传递的数量不准,上传的时候,把失败的也加进来了,以实际数组的数字为准
 | ||
|                         series.InstanceCount = seriesItem.InstanceList.Count;
 | ||
| 
 | ||
|                         await _taskSeriesRepository.AddAsync(series);
 | ||
| 
 | ||
|                         foreach (var instanceItem in seriesItem.InstanceList)
 | ||
|                         {
 | ||
|                             var isntance = _mapper.Map<TaskInstance>(instanceItem);
 | ||
| 
 | ||
|                             Guid instanceId = IdentifierHelper.CreateGuid(study.StudyInstanceUid, series.SeriesInstanceUid, isntance.SopInstanceUid, study.TrialId.ToString(), visiTaskId.ToString());
 | ||
| 
 | ||
|                             isntance.Id = instanceId;
 | ||
|                             isntance.StudyId = study.Id;
 | ||
|                             isntance.SeriesId = series.Id;
 | ||
| 
 | ||
|                             isntance.TrialId = incommand.TrialId;
 | ||
|                             isntance.SubjectId = incommand.SubjectId;
 | ||
|                             //isntance.SubjectVisitId = incommand.SubjectVisitId;
 | ||
|                             isntance.VisitTaskId = visiTaskId;
 | ||
| 
 | ||
|                             await _taskInstanceRepository.AddAsync(isntance);
 | ||
|                         }
 | ||
|                     }
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|                     //重传的时候也要赋值检查Id
 | ||
|                     studyMonitor.StudyId = findStudy.Id;
 | ||
|                     studyMonitor.StudyCode = findStudy.StudyCode;
 | ||
| 
 | ||
|                     //特殊处理逻辑
 | ||
|                     findStudy.Modalities = string.Join("、", incommand.Study.SeriesList.Select(t => t.Modality).Union(findStudy.Modalities.Split("、", StringSplitOptions.RemoveEmptyEntries)).Distinct());
 | ||
|                     SpecialArchiveStudyDeal(findStudy);
 | ||
|                     modalitys = findStudy.Modalities;
 | ||
| 
 | ||
| 
 | ||
|                     // 少了整个序列
 | ||
| 
 | ||
|                     //某个序列下少了instance
 | ||
|                     foreach (var seriesItem in incommand.Study.SeriesList)
 | ||
|                     {
 | ||
|                         var seriesId = IdentifierHelper.CreateGuid(seriesItem.StudyInstanceUid, seriesItem.SeriesInstanceUid, trialId.ToString(), visiTaskId.ToString());
 | ||
| 
 | ||
|                         TaskSeries dicomSeries = await _taskSeriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId);
 | ||
| 
 | ||
|                         //判断重复
 | ||
|                         if (dicomSeries == null)
 | ||
|                         {
 | ||
|                             var series = _mapper.Map<TaskSeries>(seriesItem);
 | ||
| 
 | ||
|                             series.Id = seriesId;
 | ||
|                             series.StudyId = findStudy.Id;
 | ||
| 
 | ||
|                             series.TrialId = incommand.TrialId;
 | ||
|                             series.SubjectId = incommand.SubjectId;
 | ||
|                             series.VisitTaskId = visiTaskId;
 | ||
|                             //series.SubjectVisitId = incommand.SubjectVisitId;
 | ||
| 
 | ||
| 
 | ||
|                             dicomSeries = await _taskSeriesRepository.AddAsync(series);
 | ||
| 
 | ||
|                             //新的序列 那么  检查的序列数量+1
 | ||
|                             findStudy.SeriesCount += 1;
 | ||
|                         }
 | ||
|                         else
 | ||
|                         {
 | ||
|                             //该序列掉了instance
 | ||
|                             dicomSeries.InstanceCount += seriesItem.InstanceList.Count;
 | ||
|                         }
 | ||
| 
 | ||
|                         foreach (var instanceItem in seriesItem.InstanceList)
 | ||
|                         {
 | ||
|                             var insntance = _mapper.Map<TaskInstance>(instanceItem);
 | ||
|                             insntance.Id = IdentifierHelper.CreateGuid(insntance.StudyInstanceUid, insntance.SeriesInstanceUid, insntance.SopInstanceUid, trialId.ToString(), visiTaskId.ToString());
 | ||
|                             insntance.StudyId = findStudy.Id;
 | ||
|                             insntance.SeriesId = dicomSeries.Id;
 | ||
| 
 | ||
|                             insntance.TrialId = incommand.TrialId;
 | ||
|                             insntance.SubjectId = incommand.SubjectId;
 | ||
|                             insntance.VisitTaskId = visiTaskId;
 | ||
| 
 | ||
|                             await _taskInstanceRepository.AddAsync(insntance);
 | ||
|                         }
 | ||
| 
 | ||
| 
 | ||
|                         //  不管是新的序列  还是 该序列 掉了Instance   重传的时候 检查的instance 数量都会增加
 | ||
|                         findStudy.InstanceCount += seriesItem.InstanceList.Count;
 | ||
| 
 | ||
|                     }
 | ||
| 
 | ||
| 
 | ||
|                 }
 | ||
| 
 | ||
|                 var @lock2 = _distributedLockProvider.CreateLock($"StudyCommit");
 | ||
| 
 | ||
|                 using (await @lock2.AcquireAsync())
 | ||
|                 {
 | ||
|                     await _taskStudyRepository.SaveChangesAsync();
 | ||
|                 }
 | ||
|             }
 | ||
|             catch (Exception ex)
 | ||
|             {
 | ||
| 
 | ||
|                 return ResponseOutput.NotOk(ex.Message);
 | ||
|             }
 | ||
|             finally
 | ||
|             {
 | ||
|                 await _fusionCache.RemoveAsync(CacheKeys.TrialTaskStudyUidDBLock(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid));
 | ||
|                 await _fusionCache.RemoveAsync(CacheKeys.TrialTaskStudyUidUploading(incommand.TrialId, incommand.VisitTaskId, incommand.Study.StudyInstanceUid));
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|             return ResponseOutput.Ok(modalitys);
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         [HttpDelete]
 | ||
|         public async Task<IResponseOutput> DeleteTaskStudy(Guid visitTaskId, bool isDicom, Guid? dicomStudyId, Guid? noneDicomStudyId)
 | ||
|         {
 | ||
|             if (isDicom)
 | ||
|             {
 | ||
|                 if (dicomStudyId == null)
 | ||
|                 {
 | ||
|                     await _taskStudyRepository.DeleteFromQueryAsync(t => t.VisitTaskId == visitTaskId);
 | ||
|                     await _taskSeriesRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId);
 | ||
|                     await _taskInstanceRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId);
 | ||
|                 }
 | ||
|                 else
 | ||
|                 {
 | ||
|                     await _taskStudyRepository.DeleteFromQueryAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId);
 | ||
|                     await _taskSeriesRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId);
 | ||
|                     await _taskInstanceRepository.BatchDeleteNoTrackingAsync(t => t.VisitTaskId == visitTaskId && t.Id == dicomStudyId);
 | ||
|                 }
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 await _noneDicomStudyFileReposiotry.DeleteFromQueryAsync(t => t.VisitTaskId == visitTaskId && t.OriginNoneDicomStudyId == noneDicomStudyId);
 | ||
|             }
 | ||
| 
 | ||
|             await _noneDicomStudyFileReposiotry.SaveChangesAsync();
 | ||
| 
 | ||
|             return ResponseOutput.Ok();
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// IR 上传任务  nonedicom 列表  后处理的数据UploadedFileCount不能排序  --new
 | ||
|         /// </summary>
 | ||
|         /// <param name="inQuery"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<List<TaskNoneDicomStudyDTO>> GetIRUploadTaskNoneDicomStudyList(IRUploadStudyQuery inQuery)
 | ||
|         {
 | ||
|             var subjectCode = inQuery.SubjectCode;
 | ||
|             var subjectId = inQuery.SubjectId;
 | ||
|             var doctorUserId = _userInfo.UserRoleId;
 | ||
| 
 | ||
|             if (inQuery.VisitTaskId != null)
 | ||
|             {
 | ||
|                 //考虑到一致性分析,必须要这个编号进行过滤
 | ||
|                 //医学审核查看下载按钮,这个时候需要知道医生
 | ||
| 
 | ||
|                 var taskInfo = await _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId).Select(t => new
 | ||
|                 {
 | ||
|                     SubjectCode = t.IsAnalysisCreate ? t.BlindSubjectCode : t.Subject.Code,
 | ||
|                     SubjectId = t.SubjectId,
 | ||
|                     t.DoctorUserId,
 | ||
|                     t.IsAnalysisCreate
 | ||
|                 }).FirstNotNullAsync();
 | ||
| 
 | ||
|                 subjectId = taskInfo.SubjectId;
 | ||
|                 subjectCode = taskInfo.SubjectCode;
 | ||
|                 doctorUserId = (Guid)taskInfo.DoctorUserId!;
 | ||
|             }
 | ||
| 
 | ||
|             var info = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
 | ||
|                  .Select(t => new { t.IsImageFilter, t.CriterionModalitys, t.IsReadingTaskViewInOrder }).FirstNotNullAsync();
 | ||
| 
 | ||
|             var query = from u in _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId
 | ||
|                                                    && t.SourceSubjectVisitId != null && t.DoctorUserId == doctorUserId && t.TaskState == TaskState.Effect)
 | ||
|                          //满足 有序,或者随机只看到当前任务的dicom 非dicom检查
 | ||
|                          .WhereIf(info.IsReadingTaskViewInOrder != ReadingOrder.SubjectRandom && inQuery.VisitTaskId != null, t => t.Id == inQuery.VisitTaskId)
 | ||
|                         join ns in _noneDicomStudyReposiotry.Where(t => t.SubjectId == subjectId).WhereIf(info.IsImageFilter, t => ("|" + info.CriterionModalitys + "|").Contains("|" + t.Modality + "|"))
 | ||
|                         on u.SourceSubjectVisitId equals ns.SubjectVisitId
 | ||
| 
 | ||
|                         select new TaskNoneDicomStudyDTO()
 | ||
|                         {
 | ||
|                             SubjectId = u.SubjectId,
 | ||
|                             SubjectCode = u.IsSelfAnalysis == true ? u.BlindSubjectCode : u.Subject.Code,
 | ||
|                             TaskBlindName = u.TaskBlindName,
 | ||
|                             TaskName = u.TaskName,
 | ||
|                             ReadingTaskState=u.ReadingTaskState,
 | ||
|                             SourceSubjectVisitId = u.SourceSubjectVisitId,
 | ||
|                             VisitTaskId = u.Id,
 | ||
| 
 | ||
|                             Id = ns.Id,
 | ||
|                             Description = ns.Description,
 | ||
|                             ImageDate = ns.ImageDate,
 | ||
|                             BodyPart = ns.BodyPart,
 | ||
|                             FileCount = ns.FileCount,
 | ||
|                             Modality = ns.Modality,
 | ||
|                             StudyCode = ns.StudyCode,
 | ||
| 
 | ||
|                             FileList = ns.NoneDicomFileList.Select(t => new NoneDicomFileInfo()
 | ||
|                             {
 | ||
|                                 FileType = t.FileType,
 | ||
|                                 FileName = t.FileName,
 | ||
|                                 FileSize = t.FileSize,
 | ||
|                                 Path = t.Path
 | ||
|                             }).ToList()
 | ||
| 
 | ||
|                         };
 | ||
| 
 | ||
|             var list = await query.Where(t => t.SubjectCode == subjectCode).SortToListAsync(inQuery);
 | ||
| 
 | ||
|             var noneDicomStudyTaskIdList = list.Select(t => t.VisitTaskId).ToList();
 | ||
| 
 | ||
| 
 | ||
|             var taskNoneDicomStudyList = _visitTaskRepository.Where(t => noneDicomStudyTaskIdList.Contains(t.Id))
 | ||
|                   .SelectMany(t => t.TaskNoneDicomStudyFileList).Where(t => noneDicomStudyTaskIdList.Contains((Guid)t.VisitTaskId))
 | ||
|                   .Select(u => new NoneDicomFileInfo
 | ||
|                   {
 | ||
|                       OriginNoneDicomStudyId = u.OriginNoneDicomStudyId,
 | ||
| 
 | ||
|                       FileType = u.FileType,
 | ||
|                       FileName = u.FileName,
 | ||
|                       FileSize = u.FileSize,
 | ||
|                       Path = u.Path
 | ||
|                   })
 | ||
|                  .ToList();
 | ||
| 
 | ||
|             foreach (var item in list)
 | ||
|             {
 | ||
|                 item.UploadedFileCount = taskNoneDicomStudyList.Where(t => t.OriginNoneDicomStudyId == item.Id).Count();
 | ||
|                 item.UploadedFileList = taskNoneDicomStudyList.Where(t => t.OriginNoneDicomStudyId == item.Id).ToList();
 | ||
|             }
 | ||
| 
 | ||
|             return list;
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// IQC  获取CRC 上传到某一个访视的的检查信息 (原始影像信息  包含dicom  非dicom)
 | ||
|         /// </summary>
 | ||
|         /// <param name="inQuery"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<IResponseOutput> GetCRCUploadedStudyInfo(CRCUploadedStudyQuqry inQuery)
 | ||
|         {
 | ||
|             var isQueryDicom = inQuery.DicomStudyIdList.Count > 0;
 | ||
|             var isQueryNoneDicom = inQuery.NoneDicomStudyIdList.Count > 0;
 | ||
| 
 | ||
|             var imageType = (isQueryDicom && isQueryNoneDicom) ? ImageType.DicomAndNoneDicom : (isQueryDicom ? ImageType.Dicom : ImageType.NoneDicom);
 | ||
| 
 | ||
|             var query = from sv in _subjectVisitRepository.Where(t => t.Id == inQuery.SubjectVisitId)
 | ||
| 
 | ||
| 
 | ||
|                         select new
 | ||
|                         {
 | ||
|                             TrialId = sv.TrialId,
 | ||
|                             SubjectId=sv.SubjectId,
 | ||
|                             SubjectCode = sv.Subject.Code,
 | ||
|                             TrialSiteCode=sv.TrialSite.TrialSiteCode,
 | ||
|                             VisitName = sv.VisitName,
 | ||
| 
 | ||
|                             StudyList = sv.StudyList.Where(t => isQueryDicom ? inQuery.DicomStudyIdList.Contains(t.Id) : false)
 | ||
| 
 | ||
|                             .Select(u => new
 | ||
|                             {
 | ||
|                                 u.PatientId,
 | ||
|                                 u.StudyTime,
 | ||
|                                 u.StudyCode,
 | ||
| 
 | ||
|                                 SeriesList = u.SeriesList.Select(z => new
 | ||
|                                 {
 | ||
|                                     z.Modality,
 | ||
| 
 | ||
|                                     InstanceList = z.DicomInstanceList.Select(k => new
 | ||
|                                     {
 | ||
|                                         k.Path,
 | ||
|                                         k.FileSize
 | ||
|                                     })
 | ||
|                                 })
 | ||
| 
 | ||
|                             }).ToList(),
 | ||
| 
 | ||
|                             NoneDicomStudyList = sv.NoneDicomStudyList.Where(t => isQueryNoneDicom ? inQuery.NoneDicomStudyIdList.Contains(t.Id) : false)
 | ||
| 
 | ||
|                             .Select(nd => new
 | ||
|                             {
 | ||
|                                 nd.Modality,
 | ||
|                                 nd.StudyCode,
 | ||
|                                 nd.ImageDate,
 | ||
| 
 | ||
|                                 FileList = nd.NoneDicomFileList.Select(file => new
 | ||
|                                 {
 | ||
|                                     file.FileName,
 | ||
|                                     file.Path,
 | ||
|                                     file.FileType,
 | ||
|                                     file.FileSize,
 | ||
|                                 })
 | ||
|                             }).ToList()
 | ||
|                         };
 | ||
| 
 | ||
|             var result = query.FirstOrDefault();
 | ||
| 
 | ||
|             var preDownloadInfo = new TrialImageDownload()
 | ||
|             {
 | ||
|                 Id = NewId.NextSequentialGuid(),
 | ||
|                 TrialId = result.TrialId,
 | ||
|                 SubjectId = result.SubjectId,
 | ||
|                 SubjectCode = result.SubjectCode,
 | ||
|                 TrialSiteCode = result.TrialSiteCode,
 | ||
|                 IP = _userInfo.IP,
 | ||
|                 DownloadStartTime = DateTime.Now,
 | ||
|                 IsSuccess = false,
 | ||
|                 ImageType = imageType,
 | ||
|                 VisitName = string.Join(" | ", result.VisitName),
 | ||
|                 NoneDicomStudyCount = result.NoneDicomStudyList.Count(),
 | ||
|                 DicomStudyCount = result.StudyList.Count(),
 | ||
|                 ImageCount = result.StudyList.Sum(s => s.SeriesList.Sum(s => s.InstanceList.Count())) + result.NoneDicomStudyList.Sum(s => s.FileList.Count()),
 | ||
|                 ImageSize = result.StudyList.Sum(t => t.SeriesList.Sum(s => s.InstanceList.Sum(i => i.FileSize))) + result.NoneDicomStudyList.Sum(t => t.FileList.Sum(s => s.FileSize))
 | ||
|               ?? 0
 | ||
|             };
 | ||
|             await _trialImageDownloadRepository.AddAsync(preDownloadInfo, true);
 | ||
|             return ResponseOutput.Ok(result, preDownloadInfo.Id);
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// IR 阅片页面 和IR 任务列表页面下载  勾选下载列表(后端要考虑到一致性分析 subjectCode的问题)
 | ||
|         /// </summary>
 | ||
|         /// <param name="inQuery"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<List<SubjectCRCImageUploadedStudyDto>> GetSubjectImageDownloadSelectList(IRReadingDownloadQuery inQuery)
 | ||
|         {
 | ||
| 
 | ||
|             var doctorUserId = _userInfo.UserRoleId;
 | ||
|             var isAnalysisCreate = false;
 | ||
| 
 | ||
|             //要根据标准阅片顺序,确定是否查询单个任务的,还是查询所有的
 | ||
|             var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
 | ||
|                  .Select(t => new { t.IsReadingTaskViewInOrder }).FirstNotNullAsync();
 | ||
| 
 | ||
|             var subjectCode = string.Empty;
 | ||
|             var subjectId = inQuery.SubjectId;
 | ||
| 
 | ||
|             if (criterionInfo.IsReadingTaskViewInOrder == ReadingOrder.Random)
 | ||
|             {
 | ||
|                 if (inQuery.VisitTaskId == null)
 | ||
|                 {
 | ||
|                     throw new Exception("无序阅片,前端参数传递错误");
 | ||
|                 }
 | ||
| 
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 if (inQuery.SubjectId == null || inQuery.SubjectCode == null)
 | ||
|                 {
 | ||
|                     throw new Exception("有序阅片,前端参数传递错误");
 | ||
|                 }
 | ||
| 
 | ||
|                 //考虑到一致性分析,必须要这个编号进行过滤
 | ||
|                 subjectCode = inQuery.SubjectCode;
 | ||
|             }
 | ||
| 
 | ||
|             if (inQuery.VisitTaskId != null)
 | ||
|             {
 | ||
|                 //考虑到一致性分析,必须要这个编号进行过滤
 | ||
|                 //医学审核查看下载按钮,这个时候需要知道医生
 | ||
| 
 | ||
|                 var taskInfo = await _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId).Select(t => new
 | ||
|                 {
 | ||
|                     SubjectCode = t.IsAnalysisCreate ? t.BlindSubjectCode : t.Subject.Code,
 | ||
|                     SubjectId = t.SubjectId,
 | ||
|                     t.DoctorUserId,
 | ||
|                     t.IsAnalysisCreate
 | ||
|                 }).FirstNotNullAsync();
 | ||
| 
 | ||
|                 subjectId = taskInfo.SubjectId;
 | ||
|                 subjectCode = taskInfo.SubjectCode;
 | ||
|                 doctorUserId = (Guid)taskInfo.DoctorUserId!;
 | ||
|                 isAnalysisCreate = taskInfo.IsAnalysisCreate;
 | ||
|             }
 | ||
| 
 | ||
|             var query = _visitTaskRepository.Where(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId
 | ||
|                                                     && t.SourceSubjectVisitId != null && t.DoctorUserId == doctorUserId && t.TaskState == TaskState.Effect)
 | ||
|                 //满足 有序,或者随机只看到当前任务的dicom 非dicom检查
 | ||
|                 .WhereIf(criterionInfo.IsReadingTaskViewInOrder != ReadingOrder.SubjectRandom && inQuery.VisitTaskId != null, t => t.Id == inQuery.VisitTaskId)
 | ||
|                 .ProjectTo<SubjectCRCImageUploadedDto>(_mapper.ConfigurationProvider);
 | ||
| 
 | ||
|             //这里过滤是否是一致性分析的
 | ||
|             var list = await query.Where(t => t.SubjectCode == subjectCode).ToListAsync();
 | ||
| 
 | ||
|             foreach (var item in list)
 | ||
|             {
 | ||
|                 if (item.IsImageFilter)
 | ||
|                 {
 | ||
|                     item.DicomStudyList = item.DicomStudyList.Where(t => ("|" + item.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|")).ToList();
 | ||
|                     item.NoneDicomStudyList = item.NoneDicomStudyList.Where(t => ("|" + item.CriterionModalitys + "|").Contains("|" + t.Modality + "|")).ToList();
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|             #region 将任务级别转为检查级别
 | ||
| 
 | ||
|             var result = new List<SubjectCRCImageUploadedStudyDto>();
 | ||
| 
 | ||
|             var dicomStudyList = list.Where(item => item.DicomStudyList.Count > 0)
 | ||
|               .Select(item => new SubjectCRCImageUploadedStudyDto
 | ||
|               {
 | ||
|                   VisitTaskId = item.VisitTaskId,
 | ||
|                   SubjectId = item.SubjectId,
 | ||
|                   SubjectCode = item.SubjectCode,
 | ||
|                   TaskBlindName = item.TaskBlindName,
 | ||
|                   TaskName = item.TaskName,
 | ||
|                   IsImageFilter = item.IsImageFilter,
 | ||
|                   CriterionModalitys = item.CriterionModalitys,
 | ||
|                   SourceSubjectVisitId = item.SourceSubjectVisitId,
 | ||
|                   //取dicom
 | ||
|                   DicomStudyList = item.DicomStudyList,
 | ||
|               }).ToList();
 | ||
| 
 | ||
|             var noneStudyList = list.Where(item => item.NoneDicomStudyList.Count > 0)
 | ||
|            .Select(item => new SubjectCRCImageUploadedStudyDto
 | ||
|            {
 | ||
|                VisitTaskId = item.VisitTaskId,
 | ||
|                SubjectId = item.SubjectId,
 | ||
|                SubjectCode = item.SubjectCode,
 | ||
|                TaskBlindName = item.TaskBlindName,
 | ||
|                TaskName = item.TaskName,
 | ||
|                IsImageFilter = item.IsImageFilter,
 | ||
|                CriterionModalitys = item.CriterionModalitys,
 | ||
|                SourceSubjectVisitId = item.SourceSubjectVisitId,
 | ||
|                //非dicom
 | ||
|                NoneDicomStudyList = item.NoneDicomStudyList,
 | ||
|            }).ToList();
 | ||
| 
 | ||
| 
 | ||
|             result.AddRange(dicomStudyList);
 | ||
|             result.AddRange(noneStudyList);
 | ||
|             #endregion
 | ||
| 
 | ||
| 
 | ||
|             return result;
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// IR 阅片页面获取下载检查的信息  会根据标准进行过滤检查,(后端要考虑到一致性分析 subjectCode的问题)
 | ||
|         /// 检查在访视下面,所以需要传递下载的访视Id,另外下载访视下面那些检查,就把访视下的对应的检查Id 丢到数组里就好
 | ||
|         /// </summary>
 | ||
|         /// <param name="inQuery"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<IResponseOutput> GetIRReadingDownloadStudyInfo(IRDownloadQuery inQuery)
 | ||
|         {
 | ||
|             var info = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId)
 | ||
|                   .Select(t => new { t.IsImageFilter, t.CriterionModalitys, t.TrialId, t.IsReadingTaskViewInOrder }).FirstNotNullAsync();
 | ||
| 
 | ||
|             var isQueryDicom = inQuery.DicomStudyIdList.Count > 0;
 | ||
|             var isQueryNoneDicom = inQuery.NoneDicomStudyIdList.Count > 0;
 | ||
| 
 | ||
|             var imageType = (isQueryDicom && isQueryNoneDicom) ? ImageType.DicomAndNoneDicom : (isQueryDicom ? ImageType.Dicom : ImageType.NoneDicom);
 | ||
| 
 | ||
|             var taskIdList = inQuery.SubjectVisitTaskList.Select(t => t.TaskId).ToList();
 | ||
| 
 | ||
|             var subjectVisitIdList = inQuery.SubjectVisitTaskList.Select(t => t.SubjectVisitId).ToList();
 | ||
| 
 | ||
|             var trialSiteCode = _visitTaskRepository.Where(t => t.Id == taskIdList.FirstOrDefault()).Select(t => t.IsAnalysisCreate ? t.BlindTrialSiteCode : t.Subject.TrialSite.TrialSiteCode).FirstOrDefault()??string.Empty;
 | ||
| 
 | ||
|             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
 | ||
|                         {
 | ||
|                             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
 | ||
|                             {
 | ||
|                                 u.PatientId,
 | ||
|                                 u.StudyTime,
 | ||
|                                 u.StudyCode,
 | ||
| 
 | ||
|                                 SeriesList = u.SeriesList.Select(z => new
 | ||
|                                 {
 | ||
|                                     z.Modality,
 | ||
| 
 | ||
|                                     InstancePathList = z.DicomInstanceList.Select(k => new
 | ||
|                                     {
 | ||
|                                         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)
 | ||
|                             .Select(nd => new
 | ||
|                             {
 | ||
|                                 nd.Modality,
 | ||
|                                 nd.StudyCode,
 | ||
|                                 nd.ImageDate,
 | ||
| 
 | ||
|                                 FileList = nd.NoneDicomFileList.Select(file => new
 | ||
|                                 {
 | ||
|                                     file.FileName,
 | ||
|                                     file.Path,
 | ||
|                                     file.FileType,
 | ||
|                                     file.FileSize
 | ||
|                                 })
 | ||
|                             })
 | ||
|                         };
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|             var result = await query.ToListAsync();
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|             var preDownloadInfo = new TrialImageDownload()
 | ||
|             {
 | ||
|                 Id = NewId.NextSequentialGuid(),
 | ||
|                 TrialId = info.TrialId,
 | ||
|                 SubjectId=inQuery.SubjectId,
 | ||
|                 SubjectCode = inQuery.SubjectCode,
 | ||
|                 TrialSiteCode= trialSiteCode,
 | ||
|                 IP = _userInfo.IP,
 | ||
|                 DownloadStartTime = DateTime.Now,
 | ||
|                 IsSuccess = false,
 | ||
|                 ImageType = imageType,
 | ||
|                 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(result, new { PreDownloadId = preDownloadInfo.Id, info.IsReadingTaskViewInOrder });
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// dicom 影像后处理预览接口
 | ||
|         /// </summary>
 | ||
|         /// <param name="inQuery"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<IResponseOutput> GetTaskUploadedDicomStudyList(IRTaskUploadedDicomStudyQuery inQuery)
 | ||
|         {
 | ||
|             var info = await _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId)
 | ||
|                  .Select(t => new { t.TrialReadingCriterion.IsImageFilter, t.TrialReadingCriterion.CriterionModalitys }).FirstNotNullAsync();
 | ||
| 
 | ||
|             var query = _taskStudyRepository.Where(t => t.VisitTaskId == inQuery.VisitTaskId)
 | ||
|                 .Where(t => info.IsImageFilter ? ("|" + info.CriterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|") : true)
 | ||
|                 .Select(t => new
 | ||
|                 {
 | ||
|                     StudyId = t.Id,
 | ||
|                     t.Modalities,
 | ||
|                     t.InstanceCount,
 | ||
|                     t.SeriesCount,
 | ||
|                     t.StudyCode,
 | ||
|                     SeriesList = t.SeriesList.OrderBy(s => s.SeriesNumber).ThenBy(s => s.SeriesTime).Select(u => new
 | ||
|                     {
 | ||
|                         u.SeriesTime,
 | ||
|                         u.InstanceCount,
 | ||
|                         u.ImageResizePath,
 | ||
|                         u.Modality,
 | ||
|                         u.Description,
 | ||
|                         u.SeriesInstanceUid,
 | ||
|                         u.SeriesNumber,
 | ||
|                         u.SliceThickness,
 | ||
|                         u.StudyInstanceUid,
 | ||
| 
 | ||
|                         IsExistMutiFrames = u.InstanceList.Any(t => t.NumberOfFrames > 1),
 | ||
| 
 | ||
|                         InstanceInfoList = u.InstanceList.OrderBy(t => t.InstanceNumber).Select(k =>
 | ||
|                         new InstanceBasicInfo()
 | ||
|                         {
 | ||
|                             Id = k.Id,
 | ||
|                             NumberOfFrames = k.NumberOfFrames,
 | ||
|                             HtmlPath = k.HtmlPath,
 | ||
|                             Path = k.Path,
 | ||
|                             InstanceNumber = k.InstanceNumber,
 | ||
| 
 | ||
|                         }).ToList()
 | ||
|                     })
 | ||
|                 });
 | ||
|             var list = await query.ToListAsync();
 | ||
| 
 | ||
|             return ResponseOutput.Ok(list);
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 影像下载成功回调
 | ||
|         /// </summary>
 | ||
|         /// <param name="trialImageDownloadId"></param>
 | ||
|         /// <returns></returns>
 | ||
|         public async Task<IResponseOutput> DownloadImageSuccess(Guid trialImageDownloadId)
 | ||
|         {
 | ||
|             await _trialImageDownloadRepository.UpdatePartialFromQueryAsync(t => t.Id == trialImageDownloadId, u => new TrialImageDownload()
 | ||
|             { DownloadEndTime = DateTime.Now, IsSuccess = true }, true);
 | ||
|             return ResponseOutput.Ok();
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 项目影像下载监控列表
 | ||
|         /// </summary>
 | ||
|         /// <param name="inQuery"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         public async Task<PageOutput<TrialImageDownloadView>> GetTrialDownloadList(TrialIamgeDownQuery inQuery)
 | ||
|         {
 | ||
|             var query = _trialImageDownloadRepository.Where(t => t.TrialId == inQuery.TrialId)
 | ||
|                   .WhereIf(inQuery.SubjectCode.IsNotNullOrEmpty(), t => t.SubjectCode.Contains(inQuery.SubjectCode))
 | ||
|                   .WhereIf(inQuery.IP.IsNotNullOrEmpty(), t => t.IP.Contains(inQuery.IP))
 | ||
|                    .WhereIf(inQuery.Name.IsNotNullOrEmpty(), t => t.CreateUserRole.IdentityUser.UserName.Contains(inQuery.Name) || t.CreateUserRole.FullName.Contains(inQuery.Name))
 | ||
|                   .WhereIf(inQuery.ImageType != null, t => t.ImageType == inQuery.ImageType)
 | ||
|                   .WhereIf(inQuery.UserType != null, t => t.CreateUserRole.UserTypeEnum == inQuery.UserType)
 | ||
|                   .WhereIf(inQuery.IsSuccess != null, t => t.IsSuccess == inQuery.IsSuccess)
 | ||
|                   .WhereIf(inQuery.DownloadStartTime != null, t => t.DownloadStartTime >= inQuery.DownloadStartTime)
 | ||
|                   .WhereIf(inQuery.DownloadEndTime != null, t => t.DownloadEndTime <= inQuery.DownloadEndTime)
 | ||
| 
 | ||
|                   .ProjectTo<TrialImageDownloadView>(_mapper.ConfigurationProvider);
 | ||
| 
 | ||
|             return await query.ToPagedListAsync(inQuery);
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 更新后处理上传的检查modality
 | ||
|         /// </summary>
 | ||
|         /// <param name="taskStudyId"></param>
 | ||
|         /// <param name="modality"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPut]
 | ||
|         public async Task<IResponseOutput> UpdateTaskStudyModality(Guid taskStudyId, string modality)
 | ||
|         {
 | ||
|             await _taskStudyRepository.UpdatePartialFromQueryAsync(t => t.Id == taskStudyId, u => new TaskStudy() { ModalityForEdit = modality }, true);
 | ||
|             return ResponseOutput.Ok();
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         #region 之前后端下载废弃
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 受试者级别所有的影像
 | ||
|         /// 访视级别的影响 传递subjectVisitId
 | ||
|         /// 标准Id是可选的  不同标准有些检查可能有过滤
 | ||
|         /// </summary>
 | ||
|         /// <param name="_subjectRepository"></param>
 | ||
|         /// <param name="inQuery"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [Obsolete]
 | ||
|         public async Task<IResponseOutput> GetSubejectOrVisitZipInfo([FromServices] IRepository<Subject> _subjectRepository, SubejctZipInfoQuery inQuery)
 | ||
|         {
 | ||
|             var isImageFilter = false;
 | ||
| 
 | ||
|             var criterionModalitys = string.Empty;
 | ||
| 
 | ||
|             if (inQuery.TrialReadingCriterionId != null)
 | ||
|             {
 | ||
|                 var criterionInfo = await _readingQuestionCriterionTrialRepository.Where(t => t.Id == inQuery.TrialReadingCriterionId).Select(t => new { t.IsImageFilter, t.CriterionModalitys }).FirstOrDefaultAsync();
 | ||
| 
 | ||
|                 if (criterionInfo != null)
 | ||
|                 {
 | ||
|                     isImageFilter = criterionInfo.IsImageFilter;
 | ||
|                     criterionModalitys = criterionInfo.CriterionModalitys;
 | ||
|                 }
 | ||
| 
 | ||
|             }
 | ||
| 
 | ||
|             if (inQuery.SubejectVisitId != null)
 | ||
|             {
 | ||
|                 var query = from sv in _subjectVisitRepository.Where(t => t.Id == inQuery.SubejectVisitId)
 | ||
| 
 | ||
| 
 | ||
|                             select new
 | ||
|                             {
 | ||
|                                 SubjectCode = sv.Subject.Code,
 | ||
|                                 VisitName = sv.VisitName,
 | ||
|                                 StudyList = sv.StudyList.AsQueryable().WhereIf(isImageFilter, t => ("|" + criterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|"))
 | ||
|                                 .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
 | ||
|                                         })
 | ||
|                                     })
 | ||
| 
 | ||
|                                 }),
 | ||
| 
 | ||
|                                 NoneDicomStudyList = sv.NoneDicomStudyList.AsQueryable().WhereIf(isImageFilter, t => ("|" + criterionModalitys + "|").Contains("|" + t.Modality + "|"))
 | ||
|                                 .Select(nd => new
 | ||
|                                 {
 | ||
|                                     nd.Modality,
 | ||
|                                     nd.StudyCode,
 | ||
|                                     nd.ImageDate,
 | ||
| 
 | ||
|                                     FileList = nd.NoneDicomFileList.Select(file => new
 | ||
|                                     {
 | ||
|                                         file.FileName,
 | ||
|                                         file.Path,
 | ||
|                                         file.FileType
 | ||
|                                     })
 | ||
|                                 })
 | ||
|                             };
 | ||
| 
 | ||
|                 var result = query.ToList();
 | ||
| 
 | ||
|                 return ResponseOutput.Ok(result);
 | ||
|             }
 | ||
|             else if (inQuery.SubejctId != null)
 | ||
|             {
 | ||
|                 var query = from sv in _subjectRepository.Where(t => t.Id == inQuery.SubejctId).SelectMany(t => t.SubjectVisitList)
 | ||
| 
 | ||
| 
 | ||
|                             select new
 | ||
|                             {
 | ||
|                                 SubjectCode = sv.Subject.Code,
 | ||
|                                 VisitName = sv.VisitName,
 | ||
|                                 StudyList = sv.StudyList.AsQueryable().WhereIf(isImageFilter, t => ("|" + criterionModalitys + "|").Contains("|" + t.ModalityForEdit + "|"))
 | ||
|                                 .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
 | ||
|                                         })
 | ||
|                                     })
 | ||
| 
 | ||
|                                 }),
 | ||
| 
 | ||
|                                 NoneDicomStudyList = sv.NoneDicomStudyList.AsQueryable().WhereIf(isImageFilter, t => ("|" + criterionModalitys + "|").Contains("|" + t.Modality + "|"))
 | ||
|                                 .Select(nd => new
 | ||
|                                 {
 | ||
|                                     nd.Modality,
 | ||
|                                     nd.StudyCode,
 | ||
|                                     nd.ImageDate,
 | ||
| 
 | ||
|                                     FileList = nd.NoneDicomFileList.Select(file => new
 | ||
|                                     {
 | ||
|                                         file.FileName,
 | ||
|                                         file.Path,
 | ||
|                                         file.FileType
 | ||
|                                     })
 | ||
|                                 })
 | ||
|                             };
 | ||
| 
 | ||
|                 var result = query.ToList();
 | ||
| 
 | ||
|                 return ResponseOutput.Ok(result);
 | ||
|             }
 | ||
|             else
 | ||
|             {
 | ||
|                 return ResponseOutput.NotOk("不允许 subjectId  SubejectVisitId 都不传递");
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// 后台任务调用,前端忽略该接口
 | ||
|         /// </summary>
 | ||
|         /// <param name="trialId"></param>
 | ||
|         /// <param name="subjectVisitId"></param>
 | ||
|         /// <param name="isDicom"></param>
 | ||
|         /// <param name="isAnonymize"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         [Obsolete]
 | ||
|         public async Task PackageAndAnonymizImage(Guid trialId, Guid subjectVisitId, bool isDicom, bool isAnonymize = true)
 | ||
|         {
 | ||
| 
 | ||
|             var subjectVisit = await _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == subjectVisitId);
 | ||
| 
 | ||
|             try
 | ||
|             {
 | ||
|                 var addOrUpdateFixedFieldList = new List<SystemAnonymization>();
 | ||
| 
 | ||
|                 var ircFieldList = new List<SystemAnonymization>();
 | ||
| 
 | ||
|                 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
 | ||
|                                         })
 | ||
|                                     })
 | ||
| 
 | ||
|                                 }),
 | ||
| 
 | ||
|                                 NoneDicomStudyList = sv.NoneDicomStudyList.Select(nd => new
 | ||
|                                 {
 | ||
|                                     nd.Modality,
 | ||
|                                     nd.StudyCode,
 | ||
|                                     nd.ImageDate,
 | ||
| 
 | ||
|                                     FileList = nd.NoneDicomFileList.Select(file => new
 | ||
|                                     {
 | ||
|                                         file.FileName,
 | ||
|                                         file.Path,
 | ||
|                                         file.FileType
 | ||
|                                     })
 | ||
|                                 })
 | ||
|                             };
 | ||
| 
 | ||
|                 var info = query.FirstOrDefault();
 | ||
| 
 | ||
|                 if (info != null)
 | ||
|                 {
 | ||
|                     // 创建一个临时文件夹来存放文件
 | ||
|                     string tempFolderPath = Path.Combine(Directory.GetCurrentDirectory(), $"DownloadTemp_{NewId.NextGuid()}");
 | ||
|                     Directory.CreateDirectory(tempFolderPath);
 | ||
| 
 | ||
|                     //dicom  处理
 | ||
| 
 | ||
|                     if (isDicom)
 | ||
|                     {
 | ||
|                         // 遍历查询结果
 | ||
|                         foreach (var studyInfo in info.StudyList)
 | ||
|                         {
 | ||
|                             // 遍历 Series
 | ||
|                             foreach (var seriesInfo in studyInfo.SeriesList)
 | ||
|                             {
 | ||
|                                 string studyDicomFolderPath = Path.Combine(tempFolderPath, "Dicom",/* $"{info.SubjectCode}_{info.VisitName}",*/ $"{studyInfo.StudyCode}_{studyInfo.StudyTime?.ToString("yyyy-MM-dd")}_{seriesInfo.Modality}");
 | ||
| 
 | ||
|                                 // 创建 影像 文件夹
 | ||
|                                 Directory.CreateDirectory(studyDicomFolderPath);
 | ||
| 
 | ||
|                                 // 遍历 InstancePathList
 | ||
|                                 foreach (var instanceInfo in seriesInfo.InstancePathList)
 | ||
|                                 {
 | ||
|                                     // 复制文件到相应的文件夹
 | ||
|                                     string destinationPath = Path.Combine(studyDicomFolderPath, 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;
 | ||
|                                         dataset.AddOrUpdate(DicomTag.StudyDate, string.Empty);
 | ||
|                                         dataset.AddOrUpdate(DicomTag.StudyTime, string.Empty);
 | ||
| 
 | ||
|                                         #region 前端已经匿名化,不需要做相关tag匿名化
 | ||
|                                         //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
 | ||
| 
 | ||
|                                     }
 | ||
|                                     #endregion
 | ||
|                                 }
 | ||
|                             }
 | ||
|                         }
 | ||
| 
 | ||
| 
 | ||
|                         var zipDicomPath = Path.Combine(Directory.GetCurrentDirectory(), $"{info.SubjectCode}_{info.VisitName}_ImageStudy_Dicom.zip");
 | ||
|                         ZipFile.CreateFromDirectory(Path.Combine(tempFolderPath, "Dicom"), zipDicomPath);
 | ||
|                         //上传到Oss
 | ||
|                         var relativeDicomPath = await _oSSService.UploadToOSSAsync(zipDicomPath, $"download_zip", false);
 | ||
| 
 | ||
|                         //await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.Packed, VisitImageZipPath = relativeDicomPath });
 | ||
| 
 | ||
| 
 | ||
|                         File.Delete(zipDicomPath);
 | ||
|                     }
 | ||
|                     else
 | ||
|                     {
 | ||
|                         var relativeNoneDicomPath = string.Empty;
 | ||
| 
 | ||
|                         if (info.NoneDicomStudyList.Count() == 1 && info.NoneDicomStudyList.SelectMany(t => t.FileList).Count() == 1)
 | ||
|                         {
 | ||
|                             relativeNoneDicomPath = info.NoneDicomStudyList.First().FileList.First().Path;
 | ||
|                         }
 | ||
|                         else
 | ||
|                         {
 | ||
|                             //非dicom 处理
 | ||
| 
 | ||
|                             foreach (var noneDicomStudy in info.NoneDicomStudyList)
 | ||
|                             {
 | ||
|                                 string studyNoneDicomFolderPath = Path.Combine(tempFolderPath, "NoneDicom", /*$"{info.SubjectCode}_{info.VisitName}",*/ $"{noneDicomStudy.StudyCode}_{noneDicomStudy.ImageDate.ToString("yyyy-MM-dd")}_{noneDicomStudy.Modality}");
 | ||
| 
 | ||
|                                 Directory.CreateDirectory(studyNoneDicomFolderPath);
 | ||
| 
 | ||
|                                 foreach (var file in noneDicomStudy.FileList)
 | ||
|                                 {
 | ||
|                                     string destinationPath = Path.Combine(studyNoneDicomFolderPath, Path.GetFileName(file.FileName));
 | ||
| 
 | ||
|                                     //下载到当前目录
 | ||
|                                     await _oSSService.DownLoadFromOSSAsync(HttpUtility.UrlDecode(file.Path), destinationPath);
 | ||
|                                 }
 | ||
|                             }
 | ||
| 
 | ||
|                             var zipNoneDicomPath = Path.Combine(Directory.GetCurrentDirectory(), $"{info.SubjectCode}_{info.VisitName}_ImageStudy_NoneDicom.zip");
 | ||
|                             ZipFile.CreateFromDirectory(Path.Combine(tempFolderPath, "NoneDicom"), zipNoneDicomPath);
 | ||
|                             relativeNoneDicomPath = await _oSSService.UploadToOSSAsync(zipNoneDicomPath, $"download_zip", false);
 | ||
| 
 | ||
|                             File.Delete(zipNoneDicomPath);
 | ||
|                         }
 | ||
| 
 | ||
|                         //await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.Packed, VisitNoDicomImageZipPath = relativeNoneDicomPath });
 | ||
| 
 | ||
| 
 | ||
|                     }
 | ||
| 
 | ||
|                     //清理文件夹
 | ||
|                     Directory.Delete(tempFolderPath, true);
 | ||
| 
 | ||
|                 }
 | ||
|             }
 | ||
|             catch (Exception ex)
 | ||
|             {
 | ||
|                 //await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { PackState = PackState.WaitPack });
 | ||
| 
 | ||
|             }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
|         }
 | ||
|         #endregion
 | ||
| 
 | ||
|         #region 按照任务为维度 展示上传的列表  废弃
 | ||
|         /// <summary>
 | ||
|         /// IR 影像上传任务列表 --old  20240903 界面调整,现在先废弃
 | ||
|         /// </summary>
 | ||
|         /// <param name="inQuery"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         [Obsolete]
 | ||
|         public async Task<List<SubjectUploadTaskInfo>> GetIRUploadTaskList_Old(CRCUploadTaskQuery inQuery)
 | ||
|         {
 | ||
|             var query = _visitTaskRepository.Where(t => t.SubjectId == inQuery.SubjectId && t.TrialReadingCriterionId == inQuery.TrialReadingCriterionId
 | ||
|                                                    && t.SourceSubjectVisitId != null && t.DoctorUserId == _userInfo.UserRoleId && t.TaskState == TaskState.Effect)
 | ||
|                .ProjectTo<SubjectUploadTaskInfo>(_mapper.ConfigurationProvider);
 | ||
| 
 | ||
| 
 | ||
|             var list = await query.Where(t => t.SubjectCode == inQuery.SubjectCode).ToListAsync();
 | ||
| 
 | ||
|             return list;
 | ||
|         }
 | ||
|         /// <summary>
 | ||
|         /// IR 上传任务  dicom 列表  后处理的数据不能排序  --old  20240903 界面调整,现在先废弃
 | ||
|         /// </summary>
 | ||
|         /// <param name="inQuery"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         [Obsolete]
 | ||
|         public async Task<List<IRUploadTaskDicomStudyDto>> GetIRUploadTaskDicomStudyList_Old(CRCUploadTaskStudyQuery inQuery)
 | ||
|         {
 | ||
|             var list = await _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId)
 | ||
|                   .SelectMany(t => t.SourceSubjectVisit.StudyList)
 | ||
|                  .ProjectTo<IRUploadTaskDicomStudyDto>(_mapper.ConfigurationProvider).SortToListAsync(inQuery);
 | ||
| 
 | ||
|             var taskDicomStudyList = _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId)
 | ||
|                   .SelectMany(t => t.TaskStudyList)
 | ||
|                   .Select(u => new
 | ||
|                   {
 | ||
|                       u.Id,
 | ||
|                       u.SeriesCount,
 | ||
|                       u.InstanceCount,
 | ||
|                       SopInstanceList = u.InstanceList.Select(t => t.SopInstanceUid).ToList()
 | ||
|                   })
 | ||
|                  .ToList();
 | ||
| 
 | ||
|             foreach (var item in list)
 | ||
|             {
 | ||
|                 var find = taskDicomStudyList.FirstOrDefault(t => t.Id == item.Id);
 | ||
| 
 | ||
|                 if (find != null)
 | ||
|                 {
 | ||
|                     item.UploadedInstanceCount = find.InstanceCount;
 | ||
|                     item.UploadedSopInstanceUidList = find.SopInstanceList;
 | ||
|                     item.UploadedSeriesCount = find.SeriesCount;
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             return list;
 | ||
|         }
 | ||
| 
 | ||
|         /// <summary>
 | ||
|         /// IR 上传任务  nonedicom 列表  后处理的数据不能排序  --old  20240903 界面调整,现在先废弃
 | ||
|         /// </summary>
 | ||
|         /// <param name="inQuery"></param>
 | ||
|         /// <returns></returns>
 | ||
|         [HttpPost]
 | ||
|         [Obsolete]
 | ||
|         public async Task<List<IRUploadTaskNoneDicomStudyDto>> GetIRUploadTaskNoneDicomStudyList_Old(CRCUploadTaskStudyQuery inQuery)
 | ||
|         {
 | ||
|             var list = await _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId)
 | ||
|                  .SelectMany(t => t.SourceSubjectVisit.StudyList)
 | ||
|                 .ProjectTo<IRUploadTaskNoneDicomStudyDto>(_mapper.ConfigurationProvider).SortToListAsync(inQuery);
 | ||
| 
 | ||
|             var taskNoneDicomStudyList = _visitTaskRepository.Where(t => t.Id == inQuery.VisitTaskId)
 | ||
|                   .SelectMany(t => t.TaskNoneDicomStudyFileList).Where(t => t.VisitTaskId == inQuery.VisitTaskId)
 | ||
|                   .Select(u => new
 | ||
|                   {
 | ||
|                       u.OriginNoneDicomStudyId,
 | ||
|                   })
 | ||
|                  .ToList();
 | ||
| 
 | ||
|             foreach (var item in list)
 | ||
|             {
 | ||
|                 item.UploadedFileCount = taskNoneDicomStudyList.Where(t => t.OriginNoneDicomStudyId == item.Id).Count();
 | ||
|             }
 | ||
| 
 | ||
|             return list;
 | ||
| 
 | ||
|         }
 | ||
|         #endregion
 | ||
| 
 | ||
|     }
 | ||
| 
 | ||
| 
 | ||
| }
 |