From d8098a948aad02f7d339e251e931ba9b8fbc59b9 Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Sun, 29 May 2022 19:12:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E7=90=86=E6=A3=80=E6=9F=A5=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/UploadDownLoadController.cs | 266 +-- IRaCIS.Core.API/IRaCIS.Core.API.xml | 7 +- .../IRaCIS.Core.Application.xml | 14 +- .../ImageAndDoc/DTO/DicomArchiveResult.cs | 2 + .../ImageAndDoc/DicomArchiveService.cs | 52 +- .../Interface/IDicomArchiveService.cs | 2 +- .../ImageAndDoc/Interface/IStudyService.cs | 104 +- .../Service/ImageAndDoc/StudyListService.cs | 586 ------ .../Service/ImageAndDoc/StudyService.cs | 1604 ++++++----------- .../Service/ImageAndDoc/StudyxxService.cs | 1051 +++++++++++ .../Service/QC/QCOperationService.cs | 2 +- .../Triggers/SubjectVisitTrigger.cs | 14 +- 12 files changed, 1715 insertions(+), 1989 deletions(-) delete mode 100644 IRaCIS.Core.Application/Service/ImageAndDoc/StudyListService.cs create mode 100644 IRaCIS.Core.Application/Service/ImageAndDoc/StudyxxService.cs diff --git a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs index a0c08da75..6bd744e43 100644 --- a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs +++ b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs @@ -136,9 +136,9 @@ namespace IRaCIS.Core.API.Controllers - /// 流式上传 Dicom上传 需要返回文件数量 + /// 流式上传 Dicom上传 [Route("base")] - public virtual async Task DicomFileUploadAsync(Func filePathFunc) + public virtual async Task DicomFileUploadAsync(Func filePathFunc) { var fileCount = 0; @@ -155,7 +155,7 @@ namespace IRaCIS.Core.API.Controllers if (hasContentDispositionHeader) { - var fileName = contentDisposition.FileName.Value??String.Empty; + var fileName = contentDisposition.FileName.Value ?? String.Empty; string mediaType = section.ContentType ?? String.Empty; @@ -172,8 +172,6 @@ namespace IRaCIS.Core.API.Controllers ++fileCount; await filePathFunc(entry.Key, entry.OpenEntryStream()); - - } } } @@ -186,11 +184,8 @@ namespace IRaCIS.Core.API.Controllers await filePathFunc(fileName, section.Body); } - + } - - - } section = await reader.ReadNextSectionAsync(); } @@ -223,186 +218,6 @@ namespace IRaCIS.Core.API.Controllers _userInfo = userInfo; } - /// Dicom 归档 - [HttpPost, Route("Study/ArchiveStudy1/{trialId:guid}")] - [DisableFormValueModelBinding] - [DisableRequestSizeLimit] - [TypeFilter(typeof(TrialResourceFilter))] - public async Task ArchiveStudy([FromForm] ArchiveStudyCommand archiveStudyCommand, - [FromServices] ILogger _logger, - [FromServices] IEasyCachingProvider _provider, - [FromServices] IStudyService _studyService, - [FromServices] IDicomArchiveService _dicomArchiveService - ) - { - - string studycode = string.Empty; - var startTime = DateTime.Now; - - if (_provider.Exists("StudyUid_" + archiveStudyCommand.StudyInstanceUid)) - { - return ResponseOutput.NotOk("当前已有人正在上传和归档该检查!"); - } - else - { - _provider.Set("StudyUid_" + archiveStudyCommand.StudyInstanceUid, _userInfo.Id, TimeSpan.FromMinutes(30)); - } - - var archiveResult = new DicomArchiveResult(); - var archivedStudyIds = new List(); - - var (seriesInstanceUidList, sopInstanceUidList) = (new List(), new List()); - - //重传的时候,找出当前检查已经上传的series instance - if (archiveStudyCommand.AbandonStudyId != null) - { - (seriesInstanceUidList, sopInstanceUidList) = _studyService.GetHasUploadSeriesAndInstance(archiveStudyCommand.AbandonStudyId.Value); - } - - var savedInfo = _studyService.GetSaveToDicomInfo(archiveStudyCommand.SubjectVisitId); - - - var boundary = HeaderUtilities.RemoveQuotes(MediaTypeHeaderValue.Parse(Request.ContentType).Boundary).Value; - var reader = new MultipartReader(boundary, HttpContext.Request.Body); - var section = await reader.ReadNextSectionAsync(); - while (section != null) - { - //采用post方式 这里多加一个判断 过滤其他参数 - if (string.IsNullOrEmpty(section.ContentType)) - { - section = await reader.ReadNextSectionAsync(); - continue; - } - - var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition); - if (hasContentDispositionHeader) - { - string fileName = contentDisposition.FileName.Value; - try - { - - string mediaType = section.ContentType; - - if (mediaType.Contains("zip")) - { - var partStream = section.Body; - using (var zipArchive = new ZipArchive(partStream, ZipArchiveMode.Read)) - { - foreach (var entry in zipArchive.Entries) - { - if (entry.FullName.EndsWith("/")) continue; - try - { - ++archiveResult.ReceivedFileCount; - using (var memoryStream = new MemoryStream()) - { - await section.Body.CopyToAsync(memoryStream); - - memoryStream.Seek(0, SeekOrigin.Begin); - - var archiveStudyId = await _dicomArchiveService.ArchiveDicomStreamAsync(memoryStream, savedInfo, seriesInstanceUidList, sopInstanceUidList); - studycode = archiveStudyId.Item2; - if (!archivedStudyIds.Contains(archiveStudyId.Item1)) - archivedStudyIds.Add(archiveStudyId.Item1); - } - } - catch - { - archiveResult.ErrorFiles.Add($"{fileName}/{entry.FullName}"); - } - } - } - } - - ++archiveResult.ReceivedFileCount; - - - if (mediaType.Contains("octet-stream")) - { - using (var memoryStream = new MemoryStream()) - { - await section.Body.CopyToAsync(memoryStream); - - memoryStream.Seek(0, SeekOrigin.Begin); - - var archiveStudyId = await _dicomArchiveService.ArchiveDicomStreamAsync(memoryStream, savedInfo, seriesInstanceUidList, sopInstanceUidList); - studycode = archiveStudyId.Item2; - - - if (!archivedStudyIds.Contains(archiveStudyId.Item1)) - archivedStudyIds.Add(archiveStudyId.Item1); - } - } - } - catch (Exception e) - { - _logger.LogError(e.Message + e.StackTrace); - - archiveResult.ErrorFiles.Add(fileName); - - _provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid); - - } - } - section = await reader.ReadNextSectionAsync(); - } - - try - { - if (archivedStudyIds.Count > 0) // 上传成功,处理逻辑 - { - - - // 同一个访视 多个线程上传处理 批量保存 可能造成死锁 https://www.cnblogs.com/johnblogs/p/9945767.html - - await _dicomArchiveService.DicomDBDataSaveChange(); - - //sw.Stop(); - _studyService.UploadOrReUploadNeedTodo(archiveStudyCommand, archivedStudyIds, ref archiveResult, new StudyMonitor() - { - TrialId = savedInfo.TrialId, - SiteId = savedInfo.SiteId, - SubjectId = savedInfo.SubjectId, - SubjectVisitId = savedInfo.SubjectVisitId, - StudyId = archivedStudyIds[0], - - StudyCode = studycode, - UploadStartTime = startTime, - UploadFinishedTime = DateTime.Now, - //TotalMillisecondsInterval = (DateTime.Now- startTime).TotalMilliseconds, - FileSize = (decimal)HttpContext.Request.ContentLength, - FileCount = archiveResult.ReceivedFileCount, - IsDicom = true, - IsDicomReUpload = archiveStudyCommand.AbandonStudyId != null, - IP = _userInfo.IP - }); - - _provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid); - - } - else - { - return ResponseOutput.NotOk("未完成该检查的归档"); - } - - - } - catch (Exception e) - { - - _logger.LogError(e.Message + e.StackTrace); - - _provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid); - - return ResponseOutput.NotOk(e.Message, ApiResponseCodeEnum.ProgramException); - - } - - return ResponseOutput.Ok(archiveResult); - } - - - /// Dicom 归档 [HttpPost, Route("Study/ArchiveStudy/{trialId:guid}")] @@ -413,7 +228,8 @@ namespace IRaCIS.Core.API.Controllers [FromServices] ILogger _logger, [FromServices] IEasyCachingProvider _provider, [FromServices] IStudyService _studyService, - [FromServices] IDicomArchiveService _dicomArchiveService + [FromServices] IDicomArchiveService _dicomArchiveService, + [FromServices] IRepository _repository ) { @@ -438,42 +254,48 @@ namespace IRaCIS.Core.API.Controllers //重传的时候,找出当前检查已经上传的series instance if (archiveStudyCommand.AbandonStudyId != null) { - (seriesInstanceUidList, sopInstanceUidList) =_studyService.GetHasUploadSeriesAndInstance(archiveStudyCommand.AbandonStudyId.Value); + (seriesInstanceUidList, sopInstanceUidList) = _studyService.GetHasUploadSeriesAndInstance(archiveStudyCommand.AbandonStudyId.Value); } var savedInfo = _studyService.GetSaveToDicomInfo(archiveStudyCommand.SubjectVisitId); - archiveResult.ReceivedFileCount= await DicomFileUploadAsync(async (fileName, fileStream) => - { + archiveResult.ReceivedFileCount = await DicomFileUploadAsync(async (fileName, fileStream) => + { - try - { - using (var memoryStream = new MemoryStream()) - { - await fileStream.CopyToAsync(memoryStream); + try + { + using (var memoryStream = new MemoryStream()) + { + await fileStream.CopyToAsync(memoryStream); - memoryStream.Seek(0, SeekOrigin.Begin); + memoryStream.Seek(0, SeekOrigin.Begin); - var archiveStudyId = await _dicomArchiveService.ArchiveDicomStreamAsync(memoryStream, savedInfo, seriesInstanceUidList, sopInstanceUidList); - studycode = archiveStudyId.Item2; + var (studyId, studyCode) = await _dicomArchiveService.ArchiveDicomStreamAsync(memoryStream, savedInfo, seriesInstanceUidList, sopInstanceUidList); - if (!archivedStudyIds.Contains(archiveStudyId.Item1)) - archivedStudyIds.Add(archiveStudyId.Item1); - } - } - catch (Exception e) - { - _logger.LogError(e.Message + e.StackTrace); - - archiveResult.ErrorFiles.Add(fileName); - - _provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid); - - } + if (!archivedStudyIds.Contains(studyId)) + { + archivedStudyIds.Add(studyId); + archiveResult.ArchivedDicomStudies.Add(new DicomStudyBasicDTO() { StudyCode = studyCode, Id = studyId }); + } - }); + } + + + } + catch (Exception e) + { + _logger.LogError(e.Message + e.StackTrace); + + archiveResult.ErrorFiles.Add(fileName); + + _provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid); + + } + + + }); try @@ -485,7 +307,9 @@ namespace IRaCIS.Core.API.Controllers await _dicomArchiveService.DicomDBDataSaveChange(); - _studyService.UploadOrReUploadNeedTodo(archiveStudyCommand, archivedStudyIds, ref archiveResult, new StudyMonitor() + archiveResult.ReuploadNewStudyId = archivedStudyIds[0] == archiveStudyCommand.AbandonStudyId ? archivedStudyIds[0] : Guid.Empty; + + await _repository.AddAsync(new StudyMonitor() { TrialId = savedInfo.TrialId, SiteId = savedInfo.SiteId, @@ -496,20 +320,22 @@ namespace IRaCIS.Core.API.Controllers StudyCode = studycode, UploadStartTime = startTime, UploadFinishedTime = DateTime.Now, - //TotalMillisecondsInterval = (DateTime.Now- startTime).TotalMilliseconds, FileSize = (decimal)HttpContext.Request.ContentLength, FileCount = archiveResult.ReceivedFileCount, IsDicom = true, IsDicomReUpload = archiveStudyCommand.AbandonStudyId != null, IP = _userInfo.IP - }); + }, true); + + + //_studyService.UploadOrReUploadNeedTodo(archiveStudyCommand, archivedStudyIds, ref archiveResult, ); _provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid); } else { - return ResponseOutput.NotOk("未完成该检查的归档"); + return ResponseOutput.NotOk(archiveResult); } @@ -543,7 +369,7 @@ namespace IRaCIS.Core.API.Controllers [HttpPost("ClinicalData/UploadVisitClinicalData/{trialId:guid}/{subjectVisitId:guid}")] [DisableRequestSizeLimit] [Authorize(Policy = IRaCISPolicy.CRC)] - public async Task UploadVisitClinicalData( Guid subjectVisitId, [FromServices] IRepository _repository) + public async Task UploadVisitClinicalData(Guid subjectVisitId, [FromServices] IRepository _repository) { await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId); diff --git a/IRaCIS.Core.API/IRaCIS.Core.API.xml b/IRaCIS.Core.API/IRaCIS.Core.API.xml index ab1c3a3f7..a4dec7590 100644 --- a/IRaCIS.Core.API/IRaCIS.Core.API.xml +++ b/IRaCIS.Core.API/IRaCIS.Core.API.xml @@ -159,12 +159,9 @@ 流式上传 通用封装 不返回任何数据,后续还有事情处理 - 流式上传 Dicom上传 需要返回文件数量 + 流式上传 Dicom上传 - - Dicom 归档 - - + Dicom 归档 diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index be2734983..b3aad2ec2 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -160,6 +160,13 @@ 批量验证 检查是否可以上传 并告知原因 + + + 获取保存到Dicom文件中的信息 + + + + SystemAnonymizationService @@ -2223,13 +2230,6 @@ 分页获取奖励单价列表 - - - 获取保存到Dicom文件中的信息 - - - - 分页获取CRO列表 diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomArchiveResult.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomArchiveResult.cs index 1e2089d1a..9eb0b06ba 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomArchiveResult.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DTO/DicomArchiveResult.cs @@ -7,6 +7,7 @@ namespace IRaCIS.Core.Application.Contracts.Dicom.DTO { public int ReceivedFileCount { get; set; } public ICollection ErrorFiles { get; set; } + public ICollection ArchivedDicomStudies { get; set; } public Guid ReuploadNewStudyId { get; set; } = Guid.Empty; @@ -15,6 +16,7 @@ namespace IRaCIS.Core.Application.Contracts.Dicom.DTO { ReceivedFileCount = 0; ErrorFiles = new List(); + ArchivedDicomStudies = new List(); } } diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs index 842c51fe8..1db82cb21 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs @@ -48,7 +48,7 @@ namespace IRaCIS.Core.Application.Services return success; } - public async Task> ArchiveDicomStreamAsync(Stream dicomStream, + public async Task<(Guid StudyId, string StudyCode)> ArchiveDicomStreamAsync(Stream dicomStream, DicomTrialSiteSubjectInfo addtionalInfo, List seriesInstanceUidList, List instanceUidList) { @@ -63,7 +63,7 @@ namespace IRaCIS.Core.Application.Services if (instanceUidList.Any(t => t == sopInstanceUid)) { - return new Tuple(IdentifierHelper.CreateGuid(studyInstanceUid, addtionalInfo.TrialId.ToString()), string.Empty) ; + return (IdentifierHelper.CreateGuid(studyInstanceUid, addtionalInfo.TrialId.ToString()), string.Empty) ; } @@ -116,52 +116,6 @@ namespace IRaCIS.Core.Application.Services } - #region 调整废弃 - ////按照配置文件 匿名化 - //foreach (var anonymizeItem in SystemConfig.AnonymizeTagList) - //{ - // if (anonymizeItem.Enable) - // { - // ushort group = Convert.ToUInt16(anonymizeItem.Group, 16); - // ushort element = Convert.ToUInt16(anonymizeItem.Element, 16); - // dataset.AddOrUpdate(new DicomTag(group, element), anonymizeItem.ReplaceValue); - // } - //} - - - //if (AppSettings.AddClinicalInfo) //是否需要写入临床信息 - //{ - // //Dicom 文件中写入临床信息 - // dataset.AddOrUpdate(DicomTag.ClinicalTrialProtocolID, addtionalInfo.TrialCode); //Trial - // dataset.AddOrUpdate(DicomTag.ClinicalTrialProtocolName, addtionalInfo.TrialIndication); //indication - // dataset.AddOrUpdate(DicomTag.ClinicalTrialSponsorName, addtionalInfo.Sponsor);//sponsor - // dataset.AddOrUpdate(DicomTag.ClinicalTrialSiteID, addtionalInfo.SiteCode); //SiteId - // dataset.AddOrUpdate(DicomTag.ClinicalTrialSiteName, addtionalInfo.SiteName);//SiteName - // dataset.AddOrUpdate(DicomTag.ClinicalTrialSubjectID, addtionalInfo.SubjectCode + " " + addtionalInfo.SubjectSex);//SubjectId - // dataset.AddOrUpdate(DicomTag.ClinicalTrialTimePointID, addtionalInfo.VisitNum.ToString()); // TimePoint - // dataset.AddOrUpdate(DicomTag.ClinicalTrialTimePointDescription, addtionalInfo.VisitName + " " + addtionalInfo.SVUPDES); - //} - - //DicomStudy dicomStudy = null; - //DicomSeries dicomSeries = null; - //DicomInstance dicomInstance = null; - - //lock (lockTest) - //{ - // dicomStudy = CreateDicomStudy(dataset, addtionalInfo, out bool isStudyNeedAdd); - // dicomSeries = CreateDicomSeries(dataset, dicomStudy, out bool isSeriesNeedAdd); - // dicomInstance = CreateDicomInstance(dataset, dicomStudy, dicomSeries); - - // if (isStudyNeedAdd) _studyRepository.Add(dicomStudy); - // if (isSeriesNeedAdd) _seriesRepository.Add(dicomSeries); - // _instanceRepository.Add(dicomInstance); - //} - #endregion - - - - - DicomStudy dicomStudy = CreateDicomStudy(dataset, addtionalInfo, out bool isStudyNeedAdd); DicomSeries dicomSeries = CreateDicomSeries(dataset, dicomStudy, out bool isSeriesNeedAdd); DicomInstance dicomInstance = CreateDicomInstance(dataset, dicomStudy, dicomSeries); @@ -210,7 +164,7 @@ namespace IRaCIS.Core.Application.Services if (dataset.InternalTransferSyntax.IsEncapsulated) await dicomFile.SaveAsync(filePath); else await dicomFile.Clone(DicomTransferSyntax.RLELossless).SaveAsync(filePath); //RLELossless } - return new Tuple(dicomInstance.StudyId, dicomStudy.StudyCode); + return (dicomInstance.StudyId, dicomStudy.StudyCode); } diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/Interface/IDicomArchiveService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/Interface/IDicomArchiveService.cs index 62531e71b..f78222dfc 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/Interface/IDicomArchiveService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/Interface/IDicomArchiveService.cs @@ -2,7 +2,7 @@ { public interface IDicomArchiveService { - Task> ArchiveDicomStreamAsync(Stream dicomStream, DicomTrialSiteSubjectInfo addtionalInfo, List seriesInstanceUidList, List instanceUidList); + Task<(Guid StudyId, string StudyCode)> ArchiveDicomStreamAsync(Stream dicomStream, DicomTrialSiteSubjectInfo addtionalInfo, List seriesInstanceUidList, List instanceUidList); //ICollection GetArchivedStudyList(List archivedStudyIds); Task DicomDBDataSaveChange(); diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/Interface/IStudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/Interface/IStudyService.cs index ffc4dbeae..9d6da479d 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/Interface/IStudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/Interface/IStudyService.cs @@ -1,97 +1,17 @@ -using System; -using System.Collections.Generic; -using IRaCIS.Core.Application.Contracts.Dicom.DTO; -using System.Threading.Tasks; -using IRaCIS.Core.Infrastructure.Extention; -using IRaCIS.Core.Application.Contracts; +using IRaCIS.Core.Application.Contracts; +using Microsoft.AspNetCore.Mvc; -namespace IRaCIS.Application.Interfaces +namespace IRaCIS.Core.Application.Contracts { public interface IStudyService { - - - - - //IResponseOutput ForwardStudy(Guid studyId); - - DicomTrialSiteSubjectInfo GetSaveToDicomInfo(Guid subjctVisitId); - - (List SeriesInstanceUid, List SopInstanceUid) GetHasUploadSeriesAndInstance(Guid studyId); - - - void UploadOrReUploadNeedTodo(ArchiveStudyCommand archiveStudyCommand, List archiveStudyIds, ref DicomArchiveResult reusult, StudyMonitor monitor); - - - - //PageOutput GetStudyList(StudyQueryDTO queryDto); - - - //Task DicomAnonymize(Guid studyId, string optuserName); - - - //List GetStudyStatusDetailList(Guid studyId); - - - //IEnumerable GetRelationVisitList(decimal visitNum, string tpCode); - //List GetSubjectVisitStudyList(Guid trialId, Guid siteId, Guid subjectId, Guid subjectVisitId); - - //PageOutput GetDistributeStudyList(StudyStatusQueryDTO studyStatusQueryDto); - - - //IEnumerable GetAllRelationStudyList(Guid studyId); - - - //IEnumerable GetStudyStatList(Guid trialId, Guid subjectId, Guid siteId); - - - //bool UpdateReUploadNewStudyCode(Guid studyId, Guid newStudyId); - - - //void ReUploadSameStudy(Guid subjectVisitId, Guid studyId); - - - //VerifyStudyUploadResult VerifyStudyAllowUpload(string studyInstanceUid, Guid trialId, Guid? studyId); - - //List< VerifyStudyUploadResult> VerifyStudyAllowUpload(VerifyUploadOrReupload verifyList); - - //void ClearStudyInstanceAndSeriseData(Guid studyId); - - //IResponseOutput DeleteStudy(Guid id); - - - - //Guid AddSubjectVisit(Guid subjectId, Guid siteId, Guid visitStageId, DateTime? SVSTDTC, DateTime? SVENDTC); - //void UpdateSubjectLatestInfo(Guid subjectVisitId); - - //void UpdateSubjectVisit(Guid subjectVisitId, Guid studyId); - - //bool DistributeStudy(StudyReviewerCommand studyReviewer); - - //IResponseOutput EditStudyReviewer(StudyReviewerEditCommand studyReviewerEditCommand); - - - //void UploadStudyDeal(Guid studyId); - - - //List GetReviewerListByTrialId(Guid trialId); - - //IResponseOutput UpdateStudyStatus(StudyStatusDetailCommand studyStatusDetailDTO); - - //string GetStudyPreview(Guid studyId); - //DicomStudyDTO GetStudyItem(Guid studyId); - - ////bool SaveImageLabel(ImageLabelDTO label); - //bool SaveImageLabelList(ImageLabelCommand imageLabelCommand); - //IEnumerable GetImageLabel(string tpCode); - - //IResponseOutput DealNonDicomFile(Dictionary filePathDic, ArchiveStudyCommand archiveStudyCommand); - //bool ReUploadDifferentStudy(Guid subjectVisitId, Guid abandonStudyId, Guid newStudyId); - - - //List GetQANoticeList(Guid studyId); - - - + IResponseOutput> GetAllRelationStudyList(Guid subjectVisitId); + Task> GetDicomAndNoneDicomStudyList(StudyQuery studyQuery); + Task> GetDicomAndNoneDicomStudyMonitorList(StudyQuery studyQuery); + (List SeriesInstanceUid, List SopInstanceUid) GetHasUploadSeriesAndInstance(Guid studyId); + DicomTrialSiteSubjectInfo GetSaveToDicomInfo(Guid subjectVisitId); + IResponseOutput Item(Guid studyId); + Task Preview(Guid studyId); + IResponseOutput> VerifyStudyAllowUpload(VerifyUploadOrReupload verifyInfo); } -} +} \ No newline at end of file diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyListService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyListService.cs deleted file mode 100644 index c2b1f8d4c..000000000 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyListService.cs +++ /dev/null @@ -1,586 +0,0 @@ -using IRaCIS.Core.Application.Contracts; -using IRaCIS.Core.Domain.Share; -using Microsoft.AspNetCore.Mvc; -using IRaCIS.Core.Application.Dicom; -using Microsoft.AspNetCore.Authorization; -using IRaCIS.Core.Application.Services; -using EasyCaching.Core; -using System.Linq.Expressions; - -namespace IRaCIS.Core.Application.Service.ImageAndDoc -{ - [ApiExplorerSettings(GroupName = "Image")] - public class StudyService : BaseService - { - - private readonly DicomFileStoreHelper _dicomFileStoreHelper; - private readonly IEasyCachingProvider _provider; - - public StudyService(DicomFileStoreHelper dicomFileStoreHelper, IEasyCachingProvider provider) - { - _dicomFileStoreHelper = dicomFileStoreHelper; - _provider = provider; - } - - - private Expression> GetDicomStudySubjectVisitFilter(string[]? VisitPlanArray) - { - Expression> svExpression = x => true; - - bool isNeedVisitSearch = VisitPlanArray != null && VisitPlanArray?.Length > 0; - - if (isNeedVisitSearch) - { - var inPlanArray = VisitPlanArray!.Where(t => !t.Contains('.')).Select(t => decimal.Parse(t)).ToArray(); - var isSelectOutPlan = VisitPlanArray!.Any(t => t.Contains('.')); - - - if (inPlanArray.Length > 0) - { - svExpression = svExpression.And(t => inPlanArray.Contains(t.SubjectVisit.VisitNum)); - } - - - if (isSelectOutPlan) - { - svExpression = svExpression.Or(t => t.SubjectVisit.InPlan == false); - - } - - - } - - return svExpression; - } - - - private Expression> GetNoneDicomStudySubjectVisitFilter(string[]? VisitPlanArray) - { - Expression> svExpression = x => true; - - bool isNeedVisitSearch = VisitPlanArray != null && VisitPlanArray?.Length > 0; - - if (isNeedVisitSearch) - { - var inPlanArray = VisitPlanArray!.Where(t => !t.Contains('.')).Select(t => decimal.Parse(t)).ToArray(); - var isSelectOutPlan = VisitPlanArray!.Any(t => t.Contains('.')); - - - if (inPlanArray.Length > 0) - { - svExpression = svExpression.And(t => inPlanArray.Contains(t.SubjectVisit.VisitNum)); - } - - - if (isSelectOutPlan) - { - svExpression = svExpression.Or(t => t.SubjectVisit.InPlan == false); - - } - - - } - - return svExpression; - } - - private Expression> GetStudyMonitorSubjectVisitFilter(string[]? VisitPlanArray) - { - Expression> svExpression = x => true; - - bool isNeedVisitSearch = VisitPlanArray != null && VisitPlanArray?.Length > 0; - - if (isNeedVisitSearch) - { - var inPlanArray = VisitPlanArray!.Where(t => !t.Contains('.')).Select(t => decimal.Parse(t)).ToArray(); - var isSelectOutPlan = VisitPlanArray!.Any(t => t.Contains('.')); - - - if (inPlanArray.Length > 0) - { - svExpression = svExpression.And(t => inPlanArray.Contains(t.SubjectVisit.VisitNum)); - } - - - if (isSelectOutPlan) - { - svExpression = svExpression.Or(t => t.SubjectVisit.InPlan == false); - - } - - - } - - return svExpression; - } - - - - [HttpPost] - public async Task> GetDicomAndNoneDicomStudyList(StudyQuery studyQuery) - { - - var svExpression = GetDicomStudySubjectVisitFilter(studyQuery.VisitPlanArray); - - var dicomStudyQuery = _repository.Where(t => t.TrialId == studyQuery.TrialId) - .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) - //.WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo)) - .WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression) - .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo)) - .Select(t => new UnionStudyViewModel() - { - TrialId = t.TrialId, - SiteId = t.SiteId, - SubjectId = t.SubjectId, - SubjectVisitId = t.SubjectVisitId, - VisitName = t.SubjectVisit.VisitName, - VisitNum = t.SubjectVisit.VisitNum, - - IsDicom = true, - - SubjectCode = t.Subject.Code, - - Id = t.Id, - - Bodypart = t.BodyPartExamined, - - Modalities = t.Modalities, - - Count = t.SeriesCount, - - StudyCode = t.StudyCode, - - //DicomStudyCode = t.StudyCode, - //NoneDicomCode = 0, - - StudyTime = t.StudyTime, - - TrialSiteAliasName = t.TrialSite.TrialSiteAliasName, - - TrialSiteCode = t.TrialSite.TrialSiteCode, - - Uploader = t.Uploader.UserName, - - UploadTime = t.CreateTime - - }); - - - //.ProjectTo(_mapper.ConfigurationProvider); - var svExpression2 = GetNoneDicomStudySubjectVisitFilter(studyQuery.VisitPlanArray); - - - var nodeDicomStudyQuery = _repository.Where(t => t.TrialId == studyQuery.TrialId) - .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) - //.WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo)) - .WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression2) - .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo)) - - .Select(t => new UnionStudyViewModel() - { - TrialId = t.TrialId, - SiteId = t.SiteId, - SubjectId = t.SubjectId, - SubjectVisitId = t.SubjectVisitId, - VisitName = t.SubjectVisit.VisitName, - VisitNum = t.SubjectVisit.VisitNum, - - IsDicom = false, - - SubjectCode = t.Subject.Code, - - Id = t.Id, - - Bodypart = t.BodyPart, - - Modalities = t.Modality, - - Count = t.NoneDicomFileList.Count(), - - StudyCode = t.StudyCode, - - //NoneDicomCode = t.Code, - //DicomStudyCode = string.Empty, - - StudyTime = t.ImageDate, - - TrialSiteAliasName = t.TrialSite.TrialSiteAliasName, - - TrialSiteCode = t.TrialSite.TrialSiteCode, - - Uploader = t.CreateUser.UserName, - - UploadTime = t.CreateTime - - }); - - //.ProjectTo(_mapper.ConfigurationProvider); - - - var unionQuery = dicomStudyQuery.Union(nodeDicomStudyQuery) - .WhereIf(studyQuery.SubjectId != null, t => t.SubjectId == studyQuery.SubjectId) - .WhereIf(studyQuery.SubjectVisitId != null, t => t.SubjectId == studyQuery.SubjectVisitId) - .WhereIf(studyQuery.SiteId != null, t => t.SiteId == studyQuery.SiteId); - - return await unionQuery.ToPagedListAsync(studyQuery.PageIndex, studyQuery.PageSize, studyQuery.SortField, studyQuery.Asc); - } - - - [HttpPost] - public async Task> GetDicomAndNoneDicomStudyMonitorList(StudyQuery studyQuery) - { - var svExpression = GetStudyMonitorSubjectVisitFilter(studyQuery.VisitPlanArray); - var StudyMonitorQuery = _repository.Where(t => t.TrialId == studyQuery.TrialId) - .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) - //.WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo)) - .WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression) - .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo)) - .WhereIf(studyQuery.SubjectId != null, t => t.SubjectId == studyQuery.SubjectId) - .WhereIf(studyQuery.SubjectVisitId != null, t => t.SubjectId == studyQuery.SubjectVisitId) - .WhereIf(studyQuery.SiteId != null, t => t.SiteId == studyQuery.SiteId) - .Select(t => new UnionStudyMonitorModel() - { - TrialId = t.TrialId, - SiteId = t.SiteId, - SubjectId = t.SubjectId, - SubjectVisitId = t.SubjectVisitId, - VisitName = t.SubjectVisit.VisitName, - VisitNum = t.SubjectVisit.VisitNum, - - - - SubjectCode = t.Subject.Code, - - - TrialSiteAliasName = t.TrialSite.TrialSiteAliasName, - - TrialSiteCode = t.TrialSite.TrialSiteCode, - - Uploader = t.Uploader.UserName, - - UploadTime = t.CreateTime, - - - IP = t.IP, - FileCount = t.FileCount, - FileSize = t.FileSize, - UploadFinishedTime = t.UploadFinishedTime, - UploadStartTime = t.UploadStartTime, - - TotalMillisecondsInterval = t.TotalMillisecondsInterval, - - IsDicomReUpload = t.IsDicomReUpload, - StudyId = t.Id, - IsDicom = t.IsDicom, - - StudyCode = t.StudyCode - - - }); - - return await StudyMonitorQuery.ToPagedListAsync(studyQuery.PageIndex, studyQuery.PageSize, string.IsNullOrEmpty(studyQuery.SortField) ? "UploadTime" : studyQuery.SortField, studyQuery.Asc); - - - - #region 冗余查询 - //var dicomStudyQuery = _repository.Where(t => t.TrialId == studyQuery.TrialId && t.IsDicom) - // .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) - // .WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo)) - // .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo)) - // .Select(t => new UnionStudyMonitorModel() - // { - // TrialId = t.TrialId, - // SiteId = t.SiteId, - // SubjectId = t.SubjectId, - // SubjectVisitId = t.SubjectVisitId, - // VisitName = t.SubjectVisit.VisitName, - // VisitNum = t.SubjectVisit.VisitNum, - - - - // SubjectCode = t.Subject.Code, - - - // TrialSiteAliasName = t.TrialSite.TrialSiteAliasName, - - // TrialSiteCode = t.TrialSite.TrialSiteCode, - - // Uploader = t.Uploader.FullName, - - // UploadTime = t.CreateTime, - - - // IP = t.IP, - // FileCount = t.FileCount, - // FileSize = t.FileSize, - // UploadFinishedTime = t.UploadFinishedTime, - // UploadStartTime = t.UploadStartTime, - - // TotalMillisecondsInterval = t.TotalMillisecondsInterval, - - // IsDicomReUpload = t.IsDicomReUpload, - // StudyId = t.Id, - // IsDicom = t.IsDicom, - - // StudyCode = t.DicomStudy.StudyCode - // //DicomStudyCode = t.DicomStudy.StudyCode, - // //NoneDicomCode = 0, - - // }); - - ////.ProjectTo(_mapper.ConfigurationProvider); - - - - //var nodeDicomStudyQuery = _repository.Where(t => t.TrialId == studyQuery.TrialId && t.IsDicom == false) - // .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) - // .WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo)) - // .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo)) - - // .Select(t => new UnionStudyMonitorModel() - // { - - // TrialId = t.TrialId, - // SiteId = t.SiteId, - // SubjectId = t.SubjectId, - // SubjectVisitId = t.SubjectVisitId, - // VisitName = t.SubjectVisit.VisitName, - // VisitNum = t.SubjectVisit.VisitNum, - // SubjectCode = t.Subject.Code, - // TrialSiteAliasName = t.TrialSite.TrialSiteAliasName, - // TrialSiteCode = t.TrialSite.TrialSiteCode, - // Uploader = t.Uploader.FullName, - // UploadTime = t.CreateTime, - - // IP = t.IP, - // FileCount = t.FileCount, - // FileSize = t.FileSize, - // UploadFinishedTime = t.UploadFinishedTime, - // UploadStartTime = t.UploadStartTime, - - // TotalMillisecondsInterval = t.TotalMillisecondsInterval, - - // IsDicomReUpload = t.IsDicomReUpload, - // StudyId = t.Id, - // IsDicom = t.IsDicom, - - // StudyCode = t.NoneDicomStudy.StudyCode - - // //DicomStudyCode = string.Empty, - // //NoneDicomCode = t.NoneDicomStudy.Code, - - // }); - - ////.ProjectTo(_mapper.ConfigurationProvider); - - - //var unionQuery = dicomStudyQuery.Union(nodeDicomStudyQuery) - // .WhereIf(studyQuery.SubjectId != null, t => t.SubjectId == studyQuery.SubjectId) - // .WhereIf(studyQuery.SubjectVisitId != null, t => t.SubjectId == studyQuery.SubjectVisitId) - // .WhereIf(studyQuery.SiteId != null, t => t.SiteId == studyQuery.SiteId); - - //return await unionQuery.ToPagedListAsync(studyQuery.PageIndex, studyQuery.PageSize, string.IsNullOrEmpty(studyQuery.SortField) ? "UploadTime" : studyQuery.SortField, studyQuery.Asc); - - #endregion - - - - } - - - /// 指定资源Id,渲染Dicom检查的Jpeg预览图像 - /// Dicom检查的Id - [HttpGet("{studyId:guid}")] - public async Task Preview(Guid studyId) - { - string path = String.Empty; - - DicomInstance dicomInstance = await _repository.FirstOrDefaultAsync(s => s.StudyId == studyId); - - if (dicomInstance != null) - { - DicomStudy dicomStudy = await _repository.FirstOrDefaultAsync(s => s.Id == dicomInstance.StudyId); - if (dicomStudy != null) - { - path = _dicomFileStoreHelper.GetInstanceFilePath(dicomStudy, dicomInstance.SeriesId, dicomInstance.Id.ToString()); - } - } - - using (var sw = DicomRenderingHelper.RenderPreviewJpeg(path)) - { - var bytes = new byte[sw.Length]; - sw.Read(bytes, 0, bytes.Length); - sw.Close(); - return new FileContentResult(bytes, "image/jpeg"); - } - } - - - /// - /// 获取某个检查的关联检查列表(该受试者在这个想项目下的所有检查) - /// 点击检查检查列表中的一个检查获取对应的序列列表(调用之前的接口:/series/list/,根据StudyId,获取访视的序列列表) - /// - /// - [HttpGet("{subjectVisitId:guid}")] - [AllowAnonymous] - public IResponseOutput> GetAllRelationStudyList(Guid subjectVisitId) - { - #region 废弃 - //var studylist = _studyRepository.Where(u => u.SubjectVisitId == subjectVisitId && u.IsDeleted == false).Select(t => new { StudyId = t.Id, t.SubjectId, t.TrialId }).ToList(); - //var subjectId = studylist.FirstOrDefault().SubjectId; - //var trialId = studylist.FirstOrDefault().TrialId; - //var studyIds = studylist.Select(t => t.StudyId).ToList(); - - - //var query = from studyItem in _studyRepository.Where(u => u.SubjectId == subjectId - // && u.TrialId == trialId && u.IsDeleted == false && - // !studyIds.Contains(u.Id) - // /* && u.Status != (int)StudyStatus.Abandon*/) - // join visitItem in _subjectVisitRepository.AsQueryable() - // on studyItem.SubjectVisitId equals visitItem.Id - // select new RelationStudyDTO - // { - // StudyId = studyItem.Id, - // StudyCode = studyItem.StudyCode, - // VisitName = visitItem.VisitName, - // Modalities = studyItem.Modalities, - // Description = studyItem.Description, - // SeriesCount = studyItem.SeriesCount - // }; - #endregion - - var studyInfo = _repository.Where(u => u.SubjectVisitId == subjectVisitId).Select(t => new { t.SubjectId, t.TrialId }).FirstOrDefault().IfNullThrowException(); - - var query = _repository.Where(t => t.SubjectVisitId != subjectVisitId && t.TrialId == studyInfo.TrialId && t.SubjectId == studyInfo.SubjectId) - .ProjectTo(_mapper.ConfigurationProvider).ToList(); - - var list = query.OrderBy(u => u.VisitName).ThenBy(s => s.StudyCode).ToList(); - - return ResponseOutput.Ok(list); - } - - - /// 指定资源Id,获取Dicom检查信息 - /// Dicom检查的Id - [HttpGet, Route("{studyId:guid}")] - [AllowAnonymous] - public IResponseOutput Item(Guid studyId) - { - return ResponseOutput.Ok(_mapper.Map(_repository.Where().FirstOrDefault(s => s.Id == studyId))); - } - - - - /// - /// 批量验证 检查是否可以上传 并告知原因 - /// - [HttpPost] - public IResponseOutput> VerifyStudyAllowUpload(VerifyUploadOrReupload verifyInfo) - { - var trialInfo = _repository.Where().FirstOrDefault(t => t.Id == verifyInfo.TrialId).IfNullThrowException(); - - var result = new List(); - - var visitList = _repository.Where(t => t.SubjectId == verifyInfo.SubjectId).Select(t => new { t.VisitNum, t.EarliestScanDate, t.LatestScanDate, t.Id }).ToList(); - - - verifyInfo.StudyInstanceUidList.ForEach(waitUploadItem => - { - - if (trialInfo.IsVerifyVisitImageDate) - { - - //小于当前访视 最近的最晚拍片 - var before = visitList.Where(u => u.VisitNum < verifyInfo.VisitNum).Max(k => k.LatestScanDate); - - if (before != null && waitUploadItem.StudyDate !=null && before > waitUploadItem.StudyDate) - { - result.Add(new VerifyStudyUploadResult() { ErrorMesseage = $"当前访视检查时间{waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")}不能早于前序访视检查时间{before?.ToString("yyyy-MM-dd")},请核对检查数据是否有误", StudyInstanceUid = waitUploadItem.StudyInstanceUid }); - return; - } - - //大于当前访视 最近的最早拍片日期 - var after = visitList.Where(u => u.VisitNum > verifyInfo.VisitNum).Min(k => k.EarliestScanDate); - - if (after != null && waitUploadItem.StudyDate != null && after < waitUploadItem.StudyDate) - { - result.Add(new VerifyStudyUploadResult() { ErrorMesseage = $"当前访视检查时间{waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")}不能晚于该访视之后的检查时间{after?.ToString("yyyy-MM-dd")},请核对检查数据是否有误", StudyInstanceUid = waitUploadItem.StudyInstanceUid }); - return; - } - } - - var temp = VerifyStudyUpload(waitUploadItem.StudyInstanceUid, verifyInfo.TrialId, verifyInfo.SubjectVisitId, verifyInfo.SubjectId); - - result.Add(temp); - }); - - return ResponseOutput.Ok(result); - } - - - private VerifyStudyUploadResult VerifyStudyUpload(string studyInstanceUid, Guid trialId, Guid currentSubjectVisitId, Guid SubjectId) - { - - var result = new VerifyStudyUploadResult(); - - if (_provider.Exists("StudyUid_" + studyInstanceUid)) - { - result.AllowUpload = false; - - result.AllowReUpload = false; - result.StudyInstanceUid = studyInstanceUid; - result.ErrorMesseage = "当前有人正在上传归档该检查!"; - - return result; - } - - if (_repository.Where(t => t.Id == SubjectId).Select(t => t.Status).FirstOrDefault() == SubjectStatus.EndOfVisit) - { - result.AllowUpload = false; - - result.AllowReUpload = false; - result.StudyInstanceUid = studyInstanceUid; - result.ErrorMesseage = "受试者访视结束,不允许上传!"; - - return result; - } - - Guid expectStudyId = IdentifierHelper.CreateGuid(studyInstanceUid.Trim(), trialId.ToString()); - - - - var verifyStudyInfo = _repository.Where(t => t.TrialId == trialId && t.Id == expectStudyId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); - result.StudyInfo = verifyStudyInfo; - - - //数据库不存在该检查 允许上传 - if (verifyStudyInfo == null) - { - result.AllowUpload = true; - } - //数据库该项目有该检查 看是否支持重传 - else - { - //是同一个受试者 支持重传 - if (verifyStudyInfo.SubjectId == SubjectId && verifyStudyInfo.SubjectVisitId == currentSubjectVisitId) - { - result.AllowReUpload = true; - } - //不是同一个受试者 - else - { - //有默认值,其实不用写,这里为了好理解 - result.AllowUpload = false; - - result.AllowReUpload = false; - - result.ErrorMesseage = $"此处不可以上传。当前影像检查已经上传给受试者{verifyStudyInfo.SubjectCode}的{verifyStudyInfo.VisitName}"; - } - } - result.StudyInstanceUid = studyInstanceUid; - return result; - } - - - } -} diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs index 2712a99dc..925bc15d7 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyService.cs @@ -1,61 +1,597 @@ -using AutoMapper; -using IRaCIS.Application.Interfaces; -using IRaCIS.Core.Application.Contracts.Dicom.DTO; +using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Domain.Share; +using Microsoft.AspNetCore.Mvc; +using IRaCIS.Core.Application.Dicom; +using Microsoft.AspNetCore.Authorization; +using IRaCIS.Core.Application.Services; +using EasyCaching.Core; +using System.Linq.Expressions; -using IRaCIS.Core.Application.Contracts; -using IRaCIS.Core.Application.Service.Inspection.Interface; - - -namespace IRaCIS.Application.Services +namespace IRaCIS.Core.Application.Service.ImageAndDoc { - //[Intercept(typeof(QANoticeAOP))] - public class StudyService : IStudyService + [ApiExplorerSettings(GroupName = "Image")] + public class StudyService : BaseService, IStudyService { - private readonly IRepository _studyRepository; + + private readonly DicomFileStoreHelper _dicomFileStoreHelper; + private readonly IEasyCachingProvider _provider; + private readonly IRepository _subjectVisitRepository; private readonly IRepository _dicomInstanceRepository; private readonly IRepository _dicomSeriesRepository; - private readonly IInspectionService _inspectionService; - private readonly IUserInfo _userInfo; - private readonly IMapper _mapper; - - - private static string _fileStorePath = string.Empty; - - private readonly IRepository _dicomStudyMonitorRepository; - - - - - - public StudyService(IRepository studyRepository, - IRepository subjectVisitRepository, + public StudyService(DicomFileStoreHelper dicomFileStoreHelper, IEasyCachingProvider provider + , IRepository subjectVisitRepository, IRepository dicomInstanceRepository, - IRepository dicomSeriesRepository, - IInspectionService inspectionService, - IUserInfo userInfo, - - IRepository dicomStudyMonitorRepository, - - IMapper mapper) + IRepository dicomSeriesRepository) { - _dicomStudyMonitorRepository = dicomStudyMonitorRepository; - - - _userInfo = userInfo; - _studyRepository = studyRepository; - + _dicomFileStoreHelper = dicomFileStoreHelper; + _provider = provider; _subjectVisitRepository = subjectVisitRepository; _dicomInstanceRepository = dicomInstanceRepository; _dicomSeriesRepository = dicomSeriesRepository; - this._inspectionService = inspectionService; - _mapper = mapper; } + private Expression> GetDicomStudySubjectVisitFilter(string[]? VisitPlanArray) + { + Expression> svExpression = x => true; + + bool isNeedVisitSearch = VisitPlanArray != null && VisitPlanArray?.Length > 0; + + if (isNeedVisitSearch) + { + var inPlanArray = VisitPlanArray!.Where(t => !t.Contains('.')).Select(t => decimal.Parse(t)).ToArray(); + var isSelectOutPlan = VisitPlanArray!.Any(t => t.Contains('.')); + + + if (inPlanArray.Length > 0) + { + svExpression = svExpression.And(t => inPlanArray.Contains(t.SubjectVisit.VisitNum)); + } + + + if (isSelectOutPlan) + { + svExpression = svExpression.Or(t => t.SubjectVisit.InPlan == false); + + } + + + } + + return svExpression; + } + + + private Expression> GetNoneDicomStudySubjectVisitFilter(string[]? VisitPlanArray) + { + Expression> svExpression = x => true; + + bool isNeedVisitSearch = VisitPlanArray != null && VisitPlanArray?.Length > 0; + + if (isNeedVisitSearch) + { + var inPlanArray = VisitPlanArray!.Where(t => !t.Contains('.')).Select(t => decimal.Parse(t)).ToArray(); + var isSelectOutPlan = VisitPlanArray!.Any(t => t.Contains('.')); + + + if (inPlanArray.Length > 0) + { + svExpression = svExpression.And(t => inPlanArray.Contains(t.SubjectVisit.VisitNum)); + } + + + if (isSelectOutPlan) + { + svExpression = svExpression.Or(t => t.SubjectVisit.InPlan == false); + + } + + + } + + return svExpression; + } + + private Expression> GetStudyMonitorSubjectVisitFilter(string[]? VisitPlanArray) + { + Expression> svExpression = x => true; + + bool isNeedVisitSearch = VisitPlanArray != null && VisitPlanArray?.Length > 0; + + if (isNeedVisitSearch) + { + var inPlanArray = VisitPlanArray!.Where(t => !t.Contains('.')).Select(t => decimal.Parse(t)).ToArray(); + var isSelectOutPlan = VisitPlanArray!.Any(t => t.Contains('.')); + + + if (inPlanArray.Length > 0) + { + svExpression = svExpression.And(t => inPlanArray.Contains(t.SubjectVisit.VisitNum)); + } + + + if (isSelectOutPlan) + { + svExpression = svExpression.Or(t => t.SubjectVisit.InPlan == false); + + } + + + } + + return svExpression; + } + + + + [HttpPost] + public async Task> GetDicomAndNoneDicomStudyList(StudyQuery studyQuery) + { + + var svExpression = GetDicomStudySubjectVisitFilter(studyQuery.VisitPlanArray); + + var dicomStudyQuery = _repository.Where(t => t.TrialId == studyQuery.TrialId) + .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) + //.WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo)) + .WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression) + .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo)) + .Select(t => new UnionStudyViewModel() + { + TrialId = t.TrialId, + SiteId = t.SiteId, + SubjectId = t.SubjectId, + SubjectVisitId = t.SubjectVisitId, + VisitName = t.SubjectVisit.VisitName, + VisitNum = t.SubjectVisit.VisitNum, + + IsDicom = true, + + SubjectCode = t.Subject.Code, + + Id = t.Id, + + Bodypart = t.BodyPartExamined, + + Modalities = t.Modalities, + + Count = t.SeriesCount, + + StudyCode = t.StudyCode, + + //DicomStudyCode = t.StudyCode, + //NoneDicomCode = 0, + + StudyTime = t.StudyTime, + + TrialSiteAliasName = t.TrialSite.TrialSiteAliasName, + + TrialSiteCode = t.TrialSite.TrialSiteCode, + + Uploader = t.Uploader.UserName, + + UploadTime = t.CreateTime + + }); + + + //.ProjectTo(_mapper.ConfigurationProvider); + var svExpression2 = GetNoneDicomStudySubjectVisitFilter(studyQuery.VisitPlanArray); + + + var nodeDicomStudyQuery = _repository.Where(t => t.TrialId == studyQuery.TrialId) + .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) + //.WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo)) + .WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression2) + .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo)) + + .Select(t => new UnionStudyViewModel() + { + TrialId = t.TrialId, + SiteId = t.SiteId, + SubjectId = t.SubjectId, + SubjectVisitId = t.SubjectVisitId, + VisitName = t.SubjectVisit.VisitName, + VisitNum = t.SubjectVisit.VisitNum, + + IsDicom = false, + + SubjectCode = t.Subject.Code, + + Id = t.Id, + + Bodypart = t.BodyPart, + + Modalities = t.Modality, + + Count = t.NoneDicomFileList.Count(), + + StudyCode = t.StudyCode, + + //NoneDicomCode = t.Code, + //DicomStudyCode = string.Empty, + + StudyTime = t.ImageDate, + + TrialSiteAliasName = t.TrialSite.TrialSiteAliasName, + + TrialSiteCode = t.TrialSite.TrialSiteCode, + + Uploader = t.CreateUser.UserName, + + UploadTime = t.CreateTime + + }); + + //.ProjectTo(_mapper.ConfigurationProvider); + + + var unionQuery = dicomStudyQuery.Union(nodeDicomStudyQuery) + .WhereIf(studyQuery.SubjectId != null, t => t.SubjectId == studyQuery.SubjectId) + .WhereIf(studyQuery.SubjectVisitId != null, t => t.SubjectId == studyQuery.SubjectVisitId) + .WhereIf(studyQuery.SiteId != null, t => t.SiteId == studyQuery.SiteId); + + return await unionQuery.ToPagedListAsync(studyQuery.PageIndex, studyQuery.PageSize, studyQuery.SortField, studyQuery.Asc); + } + + + [HttpPost] + public async Task> GetDicomAndNoneDicomStudyMonitorList(StudyQuery studyQuery) + { + var svExpression = GetStudyMonitorSubjectVisitFilter(studyQuery.VisitPlanArray); + var StudyMonitorQuery = _repository.Where(t => t.TrialId == studyQuery.TrialId) + .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator || _userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) + //.WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo)) + .WhereIf(studyQuery.VisitPlanArray != null && studyQuery.VisitPlanArray?.Length > 0, svExpression) + .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo)) + .WhereIf(studyQuery.SubjectId != null, t => t.SubjectId == studyQuery.SubjectId) + .WhereIf(studyQuery.SubjectVisitId != null, t => t.SubjectId == studyQuery.SubjectVisitId) + .WhereIf(studyQuery.SiteId != null, t => t.SiteId == studyQuery.SiteId) + .Select(t => new UnionStudyMonitorModel() + { + TrialId = t.TrialId, + SiteId = t.SiteId, + SubjectId = t.SubjectId, + SubjectVisitId = t.SubjectVisitId, + VisitName = t.SubjectVisit.VisitName, + VisitNum = t.SubjectVisit.VisitNum, + + + + SubjectCode = t.Subject.Code, + + + TrialSiteAliasName = t.TrialSite.TrialSiteAliasName, + + TrialSiteCode = t.TrialSite.TrialSiteCode, + + Uploader = t.Uploader.UserName, + + UploadTime = t.CreateTime, + + + IP = t.IP, + FileCount = t.FileCount, + FileSize = t.FileSize, + UploadFinishedTime = t.UploadFinishedTime, + UploadStartTime = t.UploadStartTime, + + TotalMillisecondsInterval = t.TotalMillisecondsInterval, + + IsDicomReUpload = t.IsDicomReUpload, + StudyId = t.Id, + IsDicom = t.IsDicom, + + StudyCode = t.StudyCode + + + }); + + return await StudyMonitorQuery.ToPagedListAsync(studyQuery.PageIndex, studyQuery.PageSize, string.IsNullOrEmpty(studyQuery.SortField) ? "UploadTime" : studyQuery.SortField, studyQuery.Asc); + + + + #region 冗余查询 + //var dicomStudyQuery = _repository.Where(t => t.TrialId == studyQuery.TrialId && t.IsDicom) + // .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) + // .WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo)) + // .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo)) + // .Select(t => new UnionStudyMonitorModel() + // { + // TrialId = t.TrialId, + // SiteId = t.SiteId, + // SubjectId = t.SubjectId, + // SubjectVisitId = t.SubjectVisitId, + // VisitName = t.SubjectVisit.VisitName, + // VisitNum = t.SubjectVisit.VisitNum, + + + + // SubjectCode = t.Subject.Code, + + + // TrialSiteAliasName = t.TrialSite.TrialSiteAliasName, + + // TrialSiteCode = t.TrialSite.TrialSiteCode, + + // Uploader = t.Uploader.FullName, + + // UploadTime = t.CreateTime, + + + // IP = t.IP, + // FileCount = t.FileCount, + // FileSize = t.FileSize, + // UploadFinishedTime = t.UploadFinishedTime, + // UploadStartTime = t.UploadStartTime, + + // TotalMillisecondsInterval = t.TotalMillisecondsInterval, + + // IsDicomReUpload = t.IsDicomReUpload, + // StudyId = t.Id, + // IsDicom = t.IsDicom, + + // StudyCode = t.DicomStudy.StudyCode + // //DicomStudyCode = t.DicomStudy.StudyCode, + // //NoneDicomCode = 0, + + // }); + + ////.ProjectTo(_mapper.ConfigurationProvider); + + + + //var nodeDicomStudyQuery = _repository.Where(t => t.TrialId == studyQuery.TrialId && t.IsDicom == false) + // .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) + // .WhereIf(!string.IsNullOrEmpty(studyQuery.VisitPlanInfo), studyQuery.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(studyQuery.VisitPlanInfo)) + // .WhereIf(!string.IsNullOrWhiteSpace(studyQuery.SubjectInfo), t => t.Subject.Code.Contains(studyQuery.SubjectInfo)) + + // .Select(t => new UnionStudyMonitorModel() + // { + + // TrialId = t.TrialId, + // SiteId = t.SiteId, + // SubjectId = t.SubjectId, + // SubjectVisitId = t.SubjectVisitId, + // VisitName = t.SubjectVisit.VisitName, + // VisitNum = t.SubjectVisit.VisitNum, + // SubjectCode = t.Subject.Code, + // TrialSiteAliasName = t.TrialSite.TrialSiteAliasName, + // TrialSiteCode = t.TrialSite.TrialSiteCode, + // Uploader = t.Uploader.FullName, + // UploadTime = t.CreateTime, + + // IP = t.IP, + // FileCount = t.FileCount, + // FileSize = t.FileSize, + // UploadFinishedTime = t.UploadFinishedTime, + // UploadStartTime = t.UploadStartTime, + + // TotalMillisecondsInterval = t.TotalMillisecondsInterval, + + // IsDicomReUpload = t.IsDicomReUpload, + // StudyId = t.Id, + // IsDicom = t.IsDicom, + + // StudyCode = t.NoneDicomStudy.StudyCode + + // //DicomStudyCode = string.Empty, + // //NoneDicomCode = t.NoneDicomStudy.Code, + + // }); + + ////.ProjectTo(_mapper.ConfigurationProvider); + + + //var unionQuery = dicomStudyQuery.Union(nodeDicomStudyQuery) + // .WhereIf(studyQuery.SubjectId != null, t => t.SubjectId == studyQuery.SubjectId) + // .WhereIf(studyQuery.SubjectVisitId != null, t => t.SubjectId == studyQuery.SubjectVisitId) + // .WhereIf(studyQuery.SiteId != null, t => t.SiteId == studyQuery.SiteId); + + //return await unionQuery.ToPagedListAsync(studyQuery.PageIndex, studyQuery.PageSize, string.IsNullOrEmpty(studyQuery.SortField) ? "UploadTime" : studyQuery.SortField, studyQuery.Asc); + + #endregion + + + + } + + + /// 指定资源Id,渲染Dicom检查的Jpeg预览图像 + /// Dicom检查的Id + [HttpGet("{studyId:guid}")] + public async Task Preview(Guid studyId) + { + string path = String.Empty; + + DicomInstance dicomInstance = await _repository.FirstOrDefaultAsync(s => s.StudyId == studyId); + + if (dicomInstance != null) + { + DicomStudy dicomStudy = await _repository.FirstOrDefaultAsync(s => s.Id == dicomInstance.StudyId); + if (dicomStudy != null) + { + path = _dicomFileStoreHelper.GetInstanceFilePath(dicomStudy, dicomInstance.SeriesId, dicomInstance.Id.ToString()); + } + } + + using (var sw = DicomRenderingHelper.RenderPreviewJpeg(path)) + { + var bytes = new byte[sw.Length]; + sw.Read(bytes, 0, bytes.Length); + sw.Close(); + return new FileContentResult(bytes, "image/jpeg"); + } + } + + + /// + /// 获取某个检查的关联检查列表(该受试者在这个想项目下的所有检查) + /// 点击检查检查列表中的一个检查获取对应的序列列表(调用之前的接口:/series/list/,根据StudyId,获取访视的序列列表) + /// + /// + [HttpGet("{subjectVisitId:guid}")] + [AllowAnonymous] + public IResponseOutput> GetAllRelationStudyList(Guid subjectVisitId) + { + #region 废弃 + //var studylist = _studyRepository.Where(u => u.SubjectVisitId == subjectVisitId && u.IsDeleted == false).Select(t => new { StudyId = t.Id, t.SubjectId, t.TrialId }).ToList(); + //var subjectId = studylist.FirstOrDefault().SubjectId; + //var trialId = studylist.FirstOrDefault().TrialId; + //var studyIds = studylist.Select(t => t.StudyId).ToList(); + + + //var query = from studyItem in _studyRepository.Where(u => u.SubjectId == subjectId + // && u.TrialId == trialId && u.IsDeleted == false && + // !studyIds.Contains(u.Id) + // /* && u.Status != (int)StudyStatus.Abandon*/) + // join visitItem in _subjectVisitRepository.AsQueryable() + // on studyItem.SubjectVisitId equals visitItem.Id + // select new RelationStudyDTO + // { + // StudyId = studyItem.Id, + // StudyCode = studyItem.StudyCode, + // VisitName = visitItem.VisitName, + // Modalities = studyItem.Modalities, + // Description = studyItem.Description, + // SeriesCount = studyItem.SeriesCount + // }; + #endregion + + var studyInfo = _repository.Where(u => u.SubjectVisitId == subjectVisitId).Select(t => new { t.SubjectId, t.TrialId }).FirstOrDefault().IfNullThrowException(); + + var query = _repository.Where(t => t.SubjectVisitId != subjectVisitId && t.TrialId == studyInfo.TrialId && t.SubjectId == studyInfo.SubjectId) + .ProjectTo(_mapper.ConfigurationProvider).ToList(); + + var list = query.OrderBy(u => u.VisitName).ThenBy(s => s.StudyCode).ToList(); + + return ResponseOutput.Ok(list); + } + + + /// 指定资源Id,获取Dicom检查信息 + /// Dicom检查的Id + [HttpGet, Route("{studyId:guid}")] + [AllowAnonymous] + public IResponseOutput Item(Guid studyId) + { + return ResponseOutput.Ok(_mapper.Map(_repository.Where().FirstOrDefault(s => s.Id == studyId))); + } + + + + /// + /// 批量验证 检查是否可以上传 并告知原因 + /// + [HttpPost] + public IResponseOutput> VerifyStudyAllowUpload(VerifyUploadOrReupload verifyInfo) + { + var trialInfo = _repository.Where().FirstOrDefault(t => t.Id == verifyInfo.TrialId).IfNullThrowException(); + + var result = new List(); + + var visitList = _repository.Where(t => t.SubjectId == verifyInfo.SubjectId).Select(t => new { t.VisitNum, t.EarliestScanDate, t.LatestScanDate, t.Id }).ToList(); + + + verifyInfo.StudyInstanceUidList.ForEach(waitUploadItem => + { + + if (trialInfo.IsVerifyVisitImageDate) + { + + //小于当前访视 最近的最晚拍片 + var before = visitList.Where(u => u.VisitNum < verifyInfo.VisitNum).Max(k => k.LatestScanDate); + + if (before != null && waitUploadItem.StudyDate != null && before > waitUploadItem.StudyDate) + { + result.Add(new VerifyStudyUploadResult() { ErrorMesseage = $"当前访视检查时间{waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")}不能早于前序访视检查时间{before?.ToString("yyyy-MM-dd")},请核对检查数据是否有误", StudyInstanceUid = waitUploadItem.StudyInstanceUid }); + return; + } + + //大于当前访视 最近的最早拍片日期 + var after = visitList.Where(u => u.VisitNum > verifyInfo.VisitNum).Min(k => k.EarliestScanDate); + + if (after != null && waitUploadItem.StudyDate != null && after < waitUploadItem.StudyDate) + { + result.Add(new VerifyStudyUploadResult() { ErrorMesseage = $"当前访视检查时间{waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")}不能晚于该访视之后的检查时间{after?.ToString("yyyy-MM-dd")},请核对检查数据是否有误", StudyInstanceUid = waitUploadItem.StudyInstanceUid }); + return; + } + } + + var temp = VerifyStudyUpload(waitUploadItem.StudyInstanceUid, verifyInfo.TrialId, verifyInfo.SubjectVisitId, verifyInfo.SubjectId); + + result.Add(temp); + }); + + return ResponseOutput.Ok(result); + } + + + private VerifyStudyUploadResult VerifyStudyUpload(string studyInstanceUid, Guid trialId, Guid currentSubjectVisitId, Guid SubjectId) + { + + var result = new VerifyStudyUploadResult(); + + if (_provider.Exists("StudyUid_" + studyInstanceUid)) + { + result.AllowUpload = false; + + result.AllowReUpload = false; + result.StudyInstanceUid = studyInstanceUid; + result.ErrorMesseage = "当前有人正在上传归档该检查!"; + + return result; + } + + if (_repository.Where(t => t.Id == SubjectId).Select(t => t.Status).FirstOrDefault() == SubjectStatus.EndOfVisit) + { + result.AllowUpload = false; + + result.AllowReUpload = false; + result.StudyInstanceUid = studyInstanceUid; + result.ErrorMesseage = "受试者访视结束,不允许上传!"; + + return result; + } + + Guid expectStudyId = IdentifierHelper.CreateGuid(studyInstanceUid.Trim(), trialId.ToString()); + + + + var verifyStudyInfo = _repository.Where(t => t.TrialId == trialId && t.Id == expectStudyId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); + result.StudyInfo = verifyStudyInfo; + + + //数据库不存在该检查 允许上传 + if (verifyStudyInfo == null) + { + result.AllowUpload = true; + } + //数据库该项目有该检查 看是否支持重传 + else + { + //是同一个受试者 支持重传 + if (verifyStudyInfo.SubjectId == SubjectId && verifyStudyInfo.SubjectVisitId == currentSubjectVisitId) + { + result.AllowReUpload = true; + } + //不是同一个受试者 + else + { + //有默认值,其实不用写,这里为了好理解 + result.AllowUpload = false; + + result.AllowReUpload = false; + + result.ErrorMesseage = $"此处不可以上传。当前影像检查已经上传给受试者{verifyStudyInfo.SubjectCode}的{verifyStudyInfo.VisitName}"; + } + } + result.StudyInstanceUid = studyInstanceUid; + return result; + } + @@ -81,991 +617,5 @@ namespace IRaCIS.Application.Services return (seriesInstanceUidList, sopInstanceUidList); } - public void UploadOrReUploadNeedTodo(ArchiveStudyCommand archiveStudyCommand, List archiveStudyIds, ref DicomArchiveResult result, StudyMonitor monitor) - { - - - var archivedStudyId = archiveStudyIds[0]; - - result.ArchivedDicomStudies = _studyRepository.Where(t => t.SubjectVisitId == archiveStudyCommand.SubjectVisitId) - .ProjectTo(_mapper.ConfigurationProvider).ToList(); - - #region 更新受试者访视信息 及访视状态为待提交 最早最晚拍片时间 访视已执行 - - var subjectVisit = _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == archiveStudyCommand.SubjectVisitId).Result; - - //正常情况下 上传或者重传(待提交之前 要改为待提交 ) QA后上传 不能改为待提交 - if (subjectVisit.SubmitState == SubmitStateEnum.None) - { - subjectVisit.SubmitState = SubmitStateEnum.ToSubmit; - } - - subjectVisit.VisitExecuted = VisitExecutedEnum.Executed; - - - - - - - - ////处理拍片日期 - //var svTime = _subjectVisitRepository.Where(t => t.Id == archiveStudyCommand.SubjectVisitId).Select(t => new - //{ - // DicomStudyMinStudyTime = t.StudyList.Min(t => (DateTime?)t.StudyTime), - // DicomStudyMaxStudyTime = t.StudyList.Max(t => (DateTime?)t.StudyTime), - // NoneDicomStudyMinStudyTime = t.NoneDicomStudyList.Min(t => (DateTime?)t.ImageDate), - // NoneDicomStudyMaxStudyTime = t.NoneDicomStudyList.Max(t => (DateTime?)t.ImageDate) - //}).FirstOrDefault(); - - //var minArray = new DateTime?[] { svTime.DicomStudyMinStudyTime, svTime.NoneDicomStudyMinStudyTime }; - //var maxArray = new DateTime?[] { svTime.DicomStudyMaxStudyTime, svTime.NoneDicomStudyMaxStudyTime }; - - //subjectVisit.EarliestScanDate = minArray.Min(); - //subjectVisit.LatestScanDate = maxArray.Max(); - - #endregion - - - //按照访视维度,上传只存在重传同一份,和上传新的(不存在之前检查维度 重传同一份 和重传不同的) - - if (archiveStudyCommand.AbandonStudyId != null && archiveStudyCommand.AbandonStudyId == archivedStudyId) - { - result.ReuploadNewStudyId = archivedStudyId; - - - // 1、普通上传后重传 - // 2、QC后重传 - //_studyService.ReUploadSameStudy(archiveStudyCommand.SubjectVisitId, archivedDicomStudy.Id); - - }//上传 - else - { - //汇总 Series的Modality 更新到检查里面 检查状态 上传人 - var seriesModalityList = _dicomSeriesRepository.Where(t => t.StudyId == archivedStudyId).Select(u => u.Modality).Distinct(); - string ModaliyStr = string.Join('、', seriesModalityList.ToList()); - - var study = _studyRepository.FirstOrDefaultAsync(t => t.Id == archivedStudyId).Result.IfNullThrowException(); - study.Status = (int)StudyStatus.Uploaded; - study.Modalities = ModaliyStr; - - } - _ = _dicomStudyMonitorRepository.AddAsync(monitor).Result; - _ = _studyRepository.SaveChangesAsync().Result; - - - - - - } - - - - - - //public virtual IResponseOutput ForwardStudy(Guid studyId) - //{ - - // var study = _studyRepository.FirstOrDefault(u => u.Id == studyId); - - - - // //数据库状态,其他人已经操作过了,此时提醒 - // if (study.Status != (int)StudyStatus.Anonymized) - // { - // ResponseOutput.NotOk($"当前界面Study:{study.StudyCode} 状态被其他人已变更,不允许该操作,请刷新界面"); - // } - - // _studyRepository.Update(t => t.Id == studyId, u => new DicomStudy() - // { - // Status = (int)StudyStatus.Forwarding - // }); - - // var subject = _subjectRepository.FirstOrDefault(u => u.Id == study.SubjectId); - // var trial = _trialRepository.FirstOrDefault(u => u.Id == study.TrialId); - // var subjectVisit = _subjectVisitRepository.FirstOrDefault(u => u.Id == study.SubjectVisitId); - // var targetPath = Path.Combine("/IMPORT-IMAGES", - // trial.TrialCode + "_" + subject.Code + "_" + subjectVisit.VisitName + "_" + study.StudyCode); - // var path = Path.Combine(_fileStorePath, study.CreateTime.Year.ToString(), study.TrialId.ToString(), - // study.SiteId.ToString(), study.SubjectId.ToString(), study.SubjectVisitId.ToString(), study.Id.ToString(), "Data"); - // try - // { - // // 主机及端口信息后面可以改到 配置文件 - // SessionOptions sessionOptions = new SessionOptions - // { - // Protocol = Protocol.Sftp, - // PortNumber = 8022, - // HostName = "CS-690-sftp.mint-imaging.com", - // UserName = "zdong", - // Password = "Everest@2021", - // //GiveUpSecurityAndAcceptAnySshHostKey = true, - // SshHostKeyFingerprint = @"ecdsa-sha2-nistp384 384 59gkjJ5lMwv3jsB8Wz2B35tBAIor5pSd8PcJYtoamPo=" - // }; - // using (Session session = new Session()) - // { - // session.Open(sessionOptions); - // if (!session.FileExists(targetPath)) - // { - // session.CreateDirectory(targetPath); - // } - - // var files = (new DirectoryInfo(path)).GetFiles(); - // foreach (var file in files) - // { - // if (file.Name.Contains("Anonymize") && file.Extension.Contains("dcm")) - // { - // string remoteFilePath = - // RemotePath.TranslateLocalPathToRemote(file.FullName, path, targetPath); - // var result = session.PutFiles(file.FullName, remoteFilePath, false); - // if (!result.IsSuccess) - // { - // return ResponseOutput.NotOk("Forward Failed"); - // } - // } - // } - - // //_studyStatusDetailRepository.Add(new StudyStatusDetail - // //{ - // // Status = (int)StudyStatus.Forwarded, - // // StudyId = studyId, - // // Note = string.Empty, - // // OptUserName = _userInfo.RealName, - // // OptTime = DateTime.Now - // //}); - - // study.Status = (int)StudyStatus.Forwarded; - // _studyRepository.Update(study); - - // //_workloadTPRepository.Add(new WorkloadTP - // //{ - // // SiteId = study.SiteId, - // // StudyId = study.Id, - // // SubjectId = study.SubjectId, - // // SubjectVisitId = study.SubjectVisitId, - // // Status = 0, - // // ReviewerId = Guid.Empty, - // // TrialId = study.TrialId, - // // UpdateTime = DateTime.Now, - // // TimepointCode = study.StudyCode + "_T01" - // //}); - // //if (study.IsDoubleReview) //双重阅片,则再添加一条,编号变为T02 - // //{ - // // _workloadTPRepository.Add(new WorkloadTP - // // { - // // SiteId = study.SiteId, - // // StudyId = study.Id, - // // SubjectId = study.SubjectId, - // // SubjectVisitId = study.SubjectVisitId, - // // Status = 0, - // // ReviewerId = Guid.Empty, - // // TrialId = study.TrialId, - // // UpdateTime = DateTime.Now, - // // TimepointCode = study.StudyCode + "_T02" - // // }); - // //} - - - // return ResponseOutput.Result(_studyRepository.SaveChanges()); - // } - // } - // catch (Exception e) - // { - // _studyRepository.Update(t => t.Id == studyId, u => new DicomStudy() - // { - // Status = (int)StudyStatus.ForwardFailed - // }); - // return ResponseOutput.NotOk("Forward Failed " + e.Message); - // } - //} - - - - - - - - - #region 暂存 读片 - - //public IEnumerable GetSeriesList(Guid studyId) - //{ - // return _dicomSeriesRepository.Where(s => s.StudyId == studyId).OrderBy(s => s.SeriesNumber). - // ThenBy(s => s.SeriesTime).ThenBy(s => s.CreateTime) - // .ProjectTo(_mapper.ConfigurationProvider); - //} - - - //public IEnumerable GetImageLabel(string tpCode) - //{ - // return _imageLabelRepository.Where(s => s.TpCode == tpCode) - // .ProjectTo(_mapper.ConfigurationProvider); - //} - - //public bool SaveImageLabelList(ImageLabelCommand imageLabelCommand) - //{ - // var success = _imageLabelRepository.Delete(u => u.TpCode == imageLabelCommand.TpCode); - // _keyInstanceRepository.Delete(u => u.TpCode == imageLabelCommand.TpCode); - // if (imageLabelCommand.ImageLabelList.Count == 0) - // { - // return true; - // } - // else - // { - - // foreach (var label in imageLabelCommand.ImageLabelList) - // { - // _imageLabelRepository.Add(new ImageLabel - // { - // TpCode = imageLabelCommand.TpCode, - // StudyId = label.StudyId, - // SeriesId = label.SeriesId, - // InstanceId = label.InstanceId, - // LabelValue = label.LabelValue - // }); - // _keyInstanceRepository.Add(new KeyInstance - // { - // TpCode = imageLabelCommand.TpCode, - // SeriesId = label.SeriesId, - // InstanceId = label.InstanceId, - // }); - // } - // success = _imageLabelRepository.SaveChanges(); - // return success; - // } - //} - - - #endregion - - - - - #region 废弃 - //public DicomStudyDTO GetStudyItem(Guid studyId) - //{ - // return _mapper.Map(_studyRepository.FirstOrDefault(s => s.Id == studyId)); - //} - //public virtual async Task DicomAnonymize(Guid studyId, string optUserName) - //{ - // var study = _studyRepository.FirstOrDefault(t => t.Id == studyId); - - // //数据库状态,其他人已经操作过了,此时提醒 - // if (study.Status != (int)StudyStatus.QAFinish) - // { - // ResponseOutput.NotOk($"当前界面Study:{study.StudyCode} 状态被其他人已变更,不允许该操作,请刷新界面"); - // } - - // var subject = _subjectRepository.Select(t => new { Id = t.Id, Code = t.Code }).FirstOrDefault(u => u.Id == study.SubjectId).IfNullThrowException(); - // var trial = _trialRepository.Select(t => new { Id = t.Id, Code = t.TrialCode }).FirstOrDefault(u => u.Id == study.TrialId).IfNullThrowException(); - - // study.Status = (int)StudyStatus.Anonymizing; - - - // // 查询受试者 信息 - // //string subjectCde = string.Empty; - // //string subjectSex = string.Empty; - - // //读取Dicom 文件,匿名化 - - // //按照配置文件 匿名化 - // var dicomSeries = _dicomSeriesRepository.Where(s => s.StudyId == studyId).ToList(); - // foreach (var seriesItem in dicomSeries) - // { - // var dicomInstances = _dicomInstanceRepository.Where(s => s.SeriesId == seriesItem.Id).ToList(); - - // foreach (var instanceItem in dicomInstances) - // { - // _dicomInstanceRepository.Attach(instanceItem); - - // try - // { - // string filePath = _dicomFileStoreHelper.CreateInstanceFilePath(study, seriesItem.Id, instanceItem.Id); - // DicomFile dicomFile = await DicomFile.OpenAsync(filePath, Encoding.Default); - - // #region 废弃 - - // //if (SystemConfig.AddClinicalInfo) //是否需要写入临床信息 - // //{ - // // dicomFile.Dataset.AddOrUpdate(DicomTag.ClinicalTrialSubjectID, subjectCde + " " + subjectSex);//SubjectId - // //} - // //DicomDataset dataset = dicomFile.Dataset; - - // #endregion - - // foreach (var anonymizeItem in AppSettings.AnonymizeTagList) - // { - // if (anonymizeItem.Enable) - // { - // ushort group = Convert.ToUInt16(anonymizeItem.Group, 16); - // ushort element = Convert.ToUInt16(anonymizeItem.Element, 16); - // dicomFile.Dataset.AddOrUpdate(new DicomTag(group, element), anonymizeItem.ReplaceValue); - // } - // } - - // dicomFile.Dataset.AddOrUpdate(DicomTag.PatientID, trial.Code + "_" + subject.Code); - - // //_dicomFileStoreHelper.CreateInstanceFilePath(study, seriesItem.Id, instanceItem.Id); - - // string path = Path.Combine(_fileStorePath, study.CreateTime.Year.ToString(), - // study.TrialId.ToString(), - // study.SiteId.ToString(), study.SubjectId.ToString(), study.SubjectVisitId.ToString(), study.Id.ToString(), "Data"); - - // //await dicomFile.SaveAsync(Path.Combine(path, instanceItem.Id.ToString() + ".dcm")); - // await dicomFile.SaveAsync( - // Path.Combine(path, instanceItem.Id.ToString() + ".Anonymize" + ".dcm")); - - // instanceItem.Anonymize = true; - - // //_dicomInstanceRepository.Update(instanceItem); - // } - // catch (Exception ex) - // { - - // study.Status = (int)StudyStatus.AnonymizeFailed; - - // _dicomInstanceRepository.SaveChanges(); - - // //这个地方返回没用 - // return ResponseOutput.NotOk(ex.Message); - // } - // } - - // } - - // study.Status = (int)StudyStatus.Anonymized; - - // var success = _dicomInstanceRepository.SaveChanges(); - - // return ResponseOutput.Result(success); - //} - //public string GetStudyPreview(Guid studyId) - //{ - // DicomInstance dicomInstance = _dicomInstanceRepository.FirstOrDefault(s => s.StudyId == studyId); - // if (dicomInstance != null) - // { - // DicomStudy dicomStudy = _studyRepository.FirstOrDefault(s => s.Id == dicomInstance.StudyId); - // if (dicomStudy != null) - // { - // return _dicomFileStoreHelper.GetInstanceFilePath(dicomStudy, dicomInstance.SeriesId, dicomInstance.Id.ToString()); - // } - // } - // return string.Empty; - //} - - //public IEnumerable GetAllRelationStudyList(Guid subjectVisitId) - //{ - // #region 废弃 - // //var studylist = _studyRepository.Where(u => u.SubjectVisitId == subjectVisitId && u.IsDeleted == false).Select(t => new { StudyId = t.Id, t.SubjectId, t.TrialId }).ToList(); - // //var subjectId = studylist.FirstOrDefault().SubjectId; - // //var trialId = studylist.FirstOrDefault().TrialId; - // //var studyIds = studylist.Select(t => t.StudyId).ToList(); - - - // //var query = from studyItem in _studyRepository.Where(u => u.SubjectId == subjectId - // // && u.TrialId == trialId && u.IsDeleted == false && - // // !studyIds.Contains(u.Id) - // // /* && u.Status != (int)StudyStatus.Abandon*/) - // // join visitItem in _subjectVisitRepository.AsQueryable() - // // on studyItem.SubjectVisitId equals visitItem.Id - // // select new RelationStudyDTO - // // { - // // StudyId = studyItem.Id, - // // StudyCode = studyItem.StudyCode, - // // VisitName = visitItem.VisitName, - // // Modalities = studyItem.Modalities, - // // Description = studyItem.Description, - // // SeriesCount = studyItem.SeriesCount - // // }; - // #endregion - - // var studyInfo = _studyRepository.Where(u => u.SubjectVisitId == subjectVisitId).Select(t => new { t.SubjectId, t.TrialId }).FirstOrDefault().IfNullThrowException(); - - // var query = _studyRepository.Where(t => t.SubjectVisitId != subjectVisitId && t.TrialId == studyInfo.TrialId && t.SubjectId == studyInfo.SubjectId) - // .ProjectTo(_mapper.ConfigurationProvider).ToList(); - - // return query.OrderBy(u => u.VisitName).ThenBy(s => s.StudyCode).ToList(); - //} - - - ///// - ///// 检查列表 - ///// - ///// - ///// - //public PageOutput GetStudyList(StudyQueryDTO queryDto) - //{ - // var query = _studyRepository.Where(x => x.TrialId == queryDto.TrialId) - // .WhereIf(queryDto.SubjectId != null, t => t.SubjectId == queryDto.SubjectId) - // .WhereIf(queryDto.SubjectVisitId != null, t => t.SubjectId == queryDto.SubjectVisitId) - // .WhereIf(!string.IsNullOrEmpty(queryDto.VisitPlanInfo), queryDto.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(queryDto.VisitPlanInfo)) - // .WhereIf(queryDto.StudyTimeBegin != null, t => t.StudyTime >= queryDto.StudyTimeBegin) - // .WhereIf(queryDto.StudyTimeEnd != null, t => t.StudyTime <= queryDto.StudyTimeEnd) - // .WhereIf(queryDto.UpdateTimeBegin != null, t => t.StudyTime >= queryDto.UpdateTimeBegin) - // .WhereIf(queryDto.UpdateTimeEnd != null, t => t.StudyTime <= queryDto.UpdateTimeEnd) - // .WhereIf(queryDto.SiteId != null, t => t.SiteId == queryDto.SiteId) - // .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) - // .WhereIf(!string.IsNullOrWhiteSpace(queryDto.SubjectInfo), t => t.Subject.Code.Contains(queryDto.SubjectInfo)) - // .ProjectTo(_mapper.ConfigurationProvider); - - - // var list = query.ToPagedList(queryDto.PageIndex, queryDto.PageSize, queryDto.SortField == string.Empty ? "StudyCode" : queryDto.SortField, queryDto.Asc); - - - // foreach (var item in list.CurrentPageData) - // { - // if (item.PatientBirthDate.Length == 8) - // { - // item.PatientBirthDate = - // $"{item.PatientBirthDate[0]}{item.PatientBirthDate[1]}{item.PatientBirthDate[2]}{item.PatientBirthDate[3]}-{item.PatientBirthDate[4]}{item.PatientBirthDate[5]}-{item.PatientBirthDate[6]}{item.PatientBirthDate[7]}"; - // } - // } - - // return list; - //} - - - - //public IResponseOutput DeleteStudy(Guid id) - //{ - // var needDelete = _studyRepository.FirstOrDefault(t => t.Id == id); - - // if (needDelete == null) - // { - // return ResponseOutput.DBNotExistIfNUll(needDelete); - // } - // else //移除内存中缓存的StudyCode 这样刚上传的,删除 再上传还是用同样的Code - // { - - // if (_provider.Get($"{needDelete.TrialId }_{ StaticData.StudyMaxCode}").Value == needDelete.StudyCode) - // { - // _provider.Remove($"{needDelete.TrialId }_{ StaticData.StudyMaxCode}"); - // } - // } - - - - // //if (study.Status != (int)StudyStatus.Uploaded) - // //{ - // // return ResponseOutput.NotOk("This study has been quality controlled and couldn't be deleted "); - // //} - - // #region 废弃的直接删除了 这里不用处理了 - - // ////处理废弃的Study 如果有的话 - // //var oldStudy = _studyRepository.FirstOrDefault(t => t.StudyCode == study.StudyCode && t.Id != id); - // //if (oldStudy != null) - // //{ - // // _studyRepository.Delete(t => t.Id == oldStudy.Id); - // // _dicomInstanceRepository.Delete(t => t.StudyId == oldStudy.Id); - // // _dicomSeriesRepository.Delete(t => t.StudyId == oldStudy.Id); - // //} - // //处理废弃的Study - // //var success5 = _studyRepository.Delete(t => t.StudyCode == study.StudyCode); - // #endregion - - - // //清除现有Study记录 - // var success1 = _studyRepository.Delete(t => t.Id == id); - // var succeess2 = _dicomInstanceRepository.Delete(t => t.StudyId == id); - // var success3 = _dicomSeriesRepository.Delete(t => t.StudyId == id); - - - // //一个访视下面有多个检查,所以需要检测 没有的时候才清空 - // if (_studyRepository.Count(t => t.SubjectVisitId == needDelete.SubjectVisitId) == 0) - // { - // _subjectVisitRepository.Update(t => t.Id == needDelete.SubjectVisitId, - - // u => new SubjectVisit() { VisitExecuted = VisitExecutedEnum.UnExecuted, SVENDTC = null, SVSTDTC = null }); - - // _qcChallengeRepository.Delete(t => t.SubjectVisitId == needDelete.SubjectVisitId); - - // //_qcChallengeRepository.Delete(t => t.SubjectVisitId == subjectVisitId); - - // //_trialQCQuestionAnswerRepository.Delete(t => t.SubjectVisitId == subjectVisitId); - // } - - - - - - // return ResponseOutput.Result(success1 || succeess2 || success3); - //} - - //public void ClearStudyInstanceAndSeriseData(Guid studyId) - //{ - // //重新开始计数,怕数据库又脏数据,影响数量 - // _studyRepository.Update(t => t.Id == studyId, u => new DicomStudy() - // { - // InstanceCount = 0, - // SeriesCount = 0 - // }); - - // _dicomSeriesRepository.Delete(t => t.StudyId == studyId); - // _dicomInstanceRepository.Delete(t => t.StudyId == studyId); - //} - - - - //public bool ReUploadDifferentStudy(Guid subjectVisitId, Guid abandonStudyId, Guid newStudyId) - //{ - // //_qcChallengeRepository.Update(t => t.SubjectVisitId == subjectVisitId && t.NeedReUpload == true, u => new QCChallenge() { ReUploadedTime = DateTime.Now, ReUploader = _userInfo.RealName }); - - // //注意这里不是用SeqId 主键查询,因为Seq id 是后续加的,为了不改变代码和前端接口参数 - // var study = _studyRepository.FirstOrDefault(t => t.Id == abandonStudyId); - - // var code = study.StudyCode; - - // //清理以前的数据 - // _studyRepository.Delete(t => t.Id == abandonStudyId); - // _dicomInstanceRepository.Delete(t => t.StudyId == abandonStudyId); - // _dicomSeriesRepository.Delete(t => t.StudyId == abandonStudyId); - - // ////将以前的qa记录数据绑定到现在新生成的Study上 - // //_qaNoticeRepository.Update(t => t.SubjectVisitId == abandonStudyId, u => new QANotice() { SubjectVisitId = newStudyId }); - // //_qaNoticeUserRepository.Update(t => t.SubjectVisitId == abandonStudyId, - // // u => new QANoticeUser() { SubjectVisitId = newStudyId }); - // //_qaRecordRepository.Update(t => t.SubjectVisitId == abandonStudyId, u => new QARecord() { SubjectVisitId = newStudyId }); - - - // var success = false; - // if (study.Status == (int)StudyStatus.Uploading) - // { - // success = _studyRepository.Update(t => t.Id == newStudyId, u => new DicomStudy() - // { - // Status = (int)StudyStatus.Uploaded, - // StudyCode = code - // }); - // } - // else - // { - // //新一份的影像状态为旧影像的状态 不改变 - // success = _studyRepository.Update(t => t.Id == newStudyId, u => new DicomStudy() - // { - // Status = study.Status, - // StudyCode = code - // }); - // } - - - - // #region 废弃之前的Study记录 讲新产生的记录的StudyCode 变更为老的 这样可以关联在一起 - - // //var realName = _userInfo.RealName; - // //var code = _studyRepository.GetAll().First(t => t.Id == abandonStudyId).StudyCode; - // //_studyRepository.Update(t => t.Id == abandonStudyId, u => new DicomStudy() - // //{ - // // Status = (int)StudyStatus.Abandon - // //}); - // //_studyRepository.Update(t => t.Id == newStudyId, u => new DicomStudy() - // //{ - // // Status = (int)StudyStatus.Uploaded, - // // StudyCode = code - // //}); - // //_studyStatusDetailRepository.Add(new StudyStatusDetail - // //{ - // // Status = (int)StudyStatus.Abandon, - // // StudyId = abandonStudyId, - // // Note = string.Empty, - // // OptUserName = realName, - // // OptTime = DateTime.Now - // //}); - // //_studyStatusDetailRepository.Add(new StudyStatusDetail - // //{ - // // Status = (int)StudyStatus.Uploaded, - // // StudyId = newStudyId, - // // Note = string.Empty, - // // OptUserName = realName, - // // OptTime = DateTime.Now - // //}); - - // //_studyStatusDetailRepository.SaveChanges(); - - // #endregion - - - // return success; - - //} - - - //public virtual void ReUploadSameStudy(Guid subjectVisitId, Guid studyId) - //{ - // //_qcChallengeRepository.Update(t => t.SubjectVisitId == subjectVisitId && t.NeedReUpload == true, u => new QCChallenge() { ReUploadedTime = DateTime.Now, ReUploader = _userInfo.RealName }); - - // #region 之前整个上传过程操作没有放在一个整体事务 会有脏数据 现在整体一个事务,不会产生,废弃 但是切入AOP 所以保留空方法 - // //var study = _studyRepository.FirstOrDefault(t=>t.Id== studyId); - // //var status = study.Status; - - // //if (status == (int)StudyStatus.Uploading) - // //{ - // // _studyRepository.Update(t => t.Id == studyId, u => new DicomStudy() - // // { - // // Status = (int)StudyStatus.Uploaded - // // }); - // //} - // #endregion - //} - ///// - ///// 上传完检查后,处理检查 汇总 Series的Modality 更新到检查里面 检查状态 上传人 - ///// - ///// - //public void UploadStudyDeal(Guid studyId) - //{ - - // var seriesModalityList = _dicomSeriesRepository.Where(t => t.StudyId == studyId).Select(u => u.Modality).Distinct(); - // string ModaliyStr = string.Join('、', seriesModalityList.ToList()); - - // var study = _studyRepository.FirstOrDefault(t => t.Id == studyId); - // study.Status = (int)StudyStatus.Uploaded; - // study.Modalities = ModaliyStr; - // _studyRepository.SaveChanges(); - //} - - - //public List GetSubjectVisitStudyList(Guid trialId, Guid siteId, Guid subjectId, Guid subjectVisitId) - //{ - // var query = _studyRepository.Where(t => t.TrialId == trialId && t.SiteId == siteId && t.SubjectId == t.SubjectId && t.SubjectVisitId == subjectVisitId) - // .Select(u => new SubjectVisitStudyDTO() { Modalities = u.Modalities, StudyCode = u.StudyCode, StudyId = u.Id, Status = u.Status }); - - // return query.ToList(); - //} - - ////此处有AOP操作,不要更改为动态Api - //public virtual IResponseOutput UpdateStudyStatus(StudyStatusDetailCommand studyStatus) - //{ - - // //注意这里不是用SeqId 主键查询,因为Seq id 是后续加的,为了不改变代码和前端接口参数 - // var study = _studyRepository.FirstOrDefault(t => t.Id == studyStatus.StudyId); - - // //数据库状态,其他人已经操作过了,此时提醒 - // if (study.Status > studyStatus.Status) - // { - // ResponseOutput.NotOk($"当前界面Study:{study.StudyCode} 状态被其他人已变更,不允许该操作,请刷新界面"); - // } - - // ////防止多次调用,更新 没必要 - // //if (study.Status == studyStatus.Status) - // //{ - // // return ResponseOutput.Ok(); - // //} - - // study.Status = studyStatus.Status; - // study.UpdateTime = DateTime.Now; - - // //if (studyStatus.Status == (int)StudyStatus.Uploaded) - // //{ - // // study.UploadedTime = DateTime.Now; - // // study.Uploader = _userInfo.RealName; - - - // //} - // //if (study.Status == (int)StudyStatus.QAing) - // //{ - // // study.DeadlineTime = studyStatus.DeadlineTime; - // //} - - // if (studyStatus.Status == (int)StudyStatus.QAFInishNotPass) - // { - // study.QAComment = studyStatus.QAComment; - // } - - - // return ResponseOutput.Ok(_studyRepository.SaveChanges()); - //} - - //public List GetStudyStatusDetailList(Guid studyId) - //{ - // return _studyStatusDetailRepository.Where(s => s.StudyId == studyId).OrderByDescending(s => s.OptTime) - // .ProjectTo(_mapper.ConfigurationProvider).ToList(); - //} - - - //public bool DistributeStudy(StudyReviewerCommand studyReviewer) - //{ - // //更新Study表中,总的状态 - // // 插入中间表 - // studyReviewer.StudyList.ForEach(study => - // { - // var workloadType = 1; - // StudyStatus studyStatus = StudyStatus.Distributed; - - // if (study.Status >= (int)StudyStatus.NeedAd) - // { - // workloadType = 2; - // studyStatus = StudyStatus.AdDistributed; - // } - - // var tempStudy = _studyRepository.FirstOrDefault(s => s.Id == study.StudyId); - // tempStudy.Status = (int)studyStatus; - // _studyRepository.Update(tempStudy); - - // _studyReviewerRepository.Add(new StudyReviewer() - // { - // ReviewerId = studyReviewer.ReviewerId, - // StudyId = study.StudyId, - // WorkloadType = workloadType, - // TrialId = studyReviewer.TrialId, - // Status = (int)studyStatus - // }); - // }); - - // return _studyReviewerRepository.SaveChanges(); - //} - - - //public IResponseOutput EditStudyReviewer(StudyReviewerEditCommand studyReviewerEditCommand) - //{ - // _studyReviewerRepository.Delete(t => studyReviewerEditCommand.StudyId == t.StudyId); - - // if (studyReviewerEditCommand.IsDoubleReview) - // { - // if (studyReviewerEditCommand.ReviewerId1 != null) - // { - // _studyReviewerRepository.Add( - // new StudyReviewer() - // { - // StudyId = studyReviewerEditCommand.StudyId, - // TrialId = studyReviewerEditCommand.TrialId, - // ReviewerId = studyReviewerEditCommand.ReviewerId1.Value, - // WorkloadType = 1 - // }); - // } - - // if (studyReviewerEditCommand.ReviewerId2 != null) - // { - // _studyReviewerRepository.Add( - // new StudyReviewer() - // { - // StudyId = studyReviewerEditCommand.StudyId, - // TrialId = studyReviewerEditCommand.TrialId, - // ReviewerId = studyReviewerEditCommand.ReviewerId2.Value, - // WorkloadType = 1 - // }); - // } - - // if (studyReviewerEditCommand.ReviewerIdForAD != null) - // { - // _studyReviewerRepository.Add( - // new StudyReviewer() - // { - // StudyId = studyReviewerEditCommand.StudyId, - // TrialId = studyReviewerEditCommand.TrialId, - // ReviewerId = studyReviewerEditCommand.ReviewerIdForAD.Value, - // WorkloadType = 2 - // }); - // } - - // if (studyReviewerEditCommand.ReviewerId2 == null || studyReviewerEditCommand.ReviewerId1 == null) - // { - // _studyRepository.Update(t => t.Id == studyReviewerEditCommand.StudyId, - // u => new DicomStudy() - // { - // Status = (int)StudyStatus.QAFinish - // }); - // } - // } - // else - // { - // if (studyReviewerEditCommand.ReviewerId1 != null) - // { - // _studyReviewerRepository.Add( - // new StudyReviewer() - // { - // StudyId = studyReviewerEditCommand.StudyId, - // TrialId = studyReviewerEditCommand.TrialId, - // ReviewerId = studyReviewerEditCommand.ReviewerId1.Value, - // WorkloadType = 1 - // }); - // } - // else - // { - // _studyRepository.Update(t => t.Id == studyReviewerEditCommand.StudyId, - // u => new DicomStudy() - // { - // Status = (int)StudyStatus.QAFinish - // }); - // } - // } - - // var success = _studyReviewerRepository.SaveChanges(); - // return ResponseOutput.Result(success); - //} - - //public List GetReviewerListByTrialId(Guid trialId) - //{ - // var query = from enrollItem in _enrollRepository - // .Where(t => t.TrialId == trialId && t.EnrollStatus >= 10) - // join doctorItem in _doctorRepository.AsQueryable() - // on enrollItem.DoctorId equals doctorItem.Id into g - // from doctor in g.DefaultIfEmpty() - // select new - // { - // ReviewerCode = doctor.ReviewerCode, - // FirstName = doctor.FirstName, - // LastName = doctor.LastName, - // ReviewerId = enrollItem.DoctorId, - // ActivelyReading = doctor.ActivelyReading, - // }; - - // return query.Where(s => s.ActivelyReading).Select(s => new ReviewerDistributionDTO - // { - // ReviewerCode = s.ReviewerCode, - // FirstName = s.FirstName, - // LastName = s.LastName, - // ReviewerId = s.ReviewerId, - - // }).ToList(); - //} - - - //public PageOutput GetDistributeStudyList( - // StudyStatusQueryDTO studyStatusQueryDto) - //{ - // Expression> studyReviewerLambda = x => x.TrialId == studyStatusQueryDto.TrialId; - - // if (studyStatusQueryDto.ReviewerId != null) - // { - // studyReviewerLambda = studyReviewerLambda.And(t => t.ReviewerId == studyStatusQueryDto.ReviewerId); - // } - - // if (studyStatusQueryDto.StudyStatus != null) - // { - // studyReviewerLambda = studyReviewerLambda.And(t => t.Status == studyStatusQueryDto.StudyStatus); - // } - - // var query = from studyReviewer in _studyReviewerRepository.Where(studyReviewerLambda) - // join doctor in _doctorRepository.AsQueryable() on studyReviewer.ReviewerId equals doctor.Id - // join study in _studyRepository.AsQueryable() on studyReviewer.StudyId equals study.Id - // select new DistributeReviewerStudyStatusDTO() - // { - // Name = doctor.LastName + " / " + doctor.FirstName, - // NameCN = doctor.ChineseName, - // ReviewerCode = doctor.ReviewerCode, - // Status = studyReviewer.Status, - // StudyCode = study.StudyCode - // }; - - // return query.ToPagedList(studyStatusQueryDto.PageIndex, - // studyStatusQueryDto.PageSize, studyStatusQueryDto.SortField == string.Empty - // ? "ReviewerCode" - // : studyStatusQueryDto.SortField, studyStatusQueryDto.Asc); - - - //} - - //public IEnumerable GetRelationVisitList(decimal visitNum, string tpCode) - //{ - // string tpGroup = tpCode.Substring(tpCode.Length - 3, 3); - // var tp = _workloadTPRepository.FirstOrDefault(u => u.TimepointCode == tpCode); - // var query = from workloadTp in _workloadTPRepository.Where(u => u.SubjectId == tp.SubjectId - // && u.TrialId == tp.TrialId && - // u.TimepointCode.Contains(tpGroup)) - // join subjectVisit in _subjectVisitRepository.Where(u => u.VisitNum <= visitNum) - // on workloadTp.SubjectVisitId equals subjectVisit.Id - // select new RelationVisitDTO - // { - // StudyId = workloadTp.StudyId, - // TpCode = workloadTp.TimepointCode, - // VisitName = subjectVisit.VisitName - // }; - // return query.ToList(); - //} - - //public List GetQANoticeList(Guid subjectVisitId) - //{ - - // var query = from noticeUser in _qaNoticeUserRepository.AsQueryable() - // .Where(t => t.ToUserId == _userInfo.Id && t.SubjectVisitId == subjectVisitId) - // join notice in _qaNoticeRepository.Where(u => u.NeedDeal == true && u.SubjectVisitId == subjectVisitId) on - // noticeUser.QANoticeId equals notice.Id - // select notice.Id; - - // var noticeUserList = query.ToList(); - - // //待处理的消息数量 - // var count = noticeUserList.Count; - - - // var list = _qaNoticeRepository.Where(t => t.SubjectVisitId == subjectVisitId) - // .ProjectTo(_mapper.ConfigurationProvider).OrderByDescending(t => t.SendTime).ToList(); - - // list.ForEach(t => t.IsMessageReceiver = count > 0 && noticeUserList.Contains(t.Id) ? t.NeedDeal : false); - - - // return list; - //} - - //public IResponseOutput DealNonDicomFile(Dictionary filePathDic, - // ArchiveStudyCommand archiveStudyCommand) - //{ - - - // var savedInfo = GetSaveToDicomInfo(archiveStudyCommand.SubjectVisitId); - - // var dicomStudy = new DicomStudy - // { - // Id = Guid.NewGuid(), - - // //SiteId = addtionalInfo.SiteId, - // //TrialId = addtionalInfo.TrialId, - // //SubjectId = addtionalInfo.SubjectId, - // //SubjectVisitId = addtionalInfo.SubjectVisitId, - // IsDoubleReview = savedInfo.IsDoubleReview, - // Comment = savedInfo.Comment - // }; - - - - // #region Setting Code - - // //var last = _studyRepository.Where(s => s.TrialId == addtionalInfo.TrialId) - // // .OrderByDescending(c => c.StudyCode).FirstOrDefault(); - // //if (last != null) - // //{ - // // var len = last.StudyCode.Length; - // // if (len > 5 && int.TryParse(last.StudyCode.Substring(len - 5, 5), out var num)) - // // { - // // dicomStudy.StudyCode = "ST" + (++num).ToString().PadLeft(5, '0'); - // // } - // // else - // // { - // // return ResponseOutput.NotOk("Generate StudyCode failed"); - // // } - // //} - // //else - // //{ - // // dicomStudy.StudyCode = "ST" + 1.ToString().PadLeft(5, '0'); - // //} - - // #endregion - - // var study = _studyRepository.Add(dicomStudy); - // var saveFileList = new List(); - - // foreach (var key in filePathDic.Keys) - // { - // saveFileList.Add(new NoneDicomFile() { FileName = filePathDic[key], StudyId = study.Id, Path = key }); - // } - - - // _noneDicomFileRepository.AddRange(saveFileList); - - - - // var success = _noneDicomFileRepository.SaveChanges(); - - // UpdateStudyStatus(new StudyStatusDetailCommand - // { - // StudyId = study.Id, - // Status = (int)StudyStatus.Uploaded, - // Note = string.Empty - // }); - - - // return ResponseOutput.Result(success); - - //} - #endregion - - } } diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/StudyxxService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyxxService.cs new file mode 100644 index 000000000..8675ba83a --- /dev/null +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/StudyxxService.cs @@ -0,0 +1,1051 @@ +//using AutoMapper; +//using IRaCIS.Application.Interfaces; +//using IRaCIS.Core.Application.Contracts.Dicom.DTO; +//using IRaCIS.Core.Domain.Share; + +//using IRaCIS.Core.Application.Contracts; +//using IRaCIS.Core.Application.Service.Inspection.Interface; + + +//namespace IRaCIS.Application.Services +//{ +// //[Intercept(typeof(QANoticeAOP))] +// public class StudyService : IStudyService +// { +// private readonly IRepository _studyRepository; + +// private readonly IRepository _subjectVisitRepository; +// private readonly IRepository _dicomInstanceRepository; +// private readonly IRepository _dicomSeriesRepository; + +// private readonly IMapper _mapper; + + +// private static string _fileStorePath = string.Empty; + +// private readonly IRepository _dicomStudyMonitorRepository; + + + + + +// public StudyService(IRepository studyRepository, +// IRepository subjectVisitRepository, +// IRepository dicomInstanceRepository, +// IRepository dicomSeriesRepository, +// IInspectionService inspectionService, +// IUserInfo userInfo, + +// IRepository dicomStudyMonitorRepository, + +// IMapper mapper) +// { +// _dicomStudyMonitorRepository = dicomStudyMonitorRepository; + + +// _userInfo = userInfo; +// _studyRepository = studyRepository; + +// _subjectVisitRepository = subjectVisitRepository; +// _dicomInstanceRepository = dicomInstanceRepository; +// _dicomSeriesRepository = dicomSeriesRepository; +// this._inspectionService = inspectionService; +// _mapper = mapper; +// } + + + + + +// /// +// /// 获取保存到Dicom文件中的信息 +// /// +// /// +// /// +// public DicomTrialSiteSubjectInfo GetSaveToDicomInfo(Guid subjectVisitId) +// { +// //6表连接 subject trial trialSite sponsor subjectVisit site +// var info = _subjectVisitRepository.Where(t => t.Id == subjectVisitId).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault().IfNullThrowException(); + +// return info; +// } + +// public (List SeriesInstanceUid, List SopInstanceUid) GetHasUploadSeriesAndInstance(Guid studyId) +// { +// var seriesInstanceUidList = _dicomSeriesRepository.Where(t => t.StudyId == studyId).Select(t => t.SeriesInstanceUid).ToList(); + +// var sopInstanceUidList = _dicomInstanceRepository.Where(t => t.StudyId == studyId).Select(t => t.SopInstanceUid).ToList(); + +// return (seriesInstanceUidList, sopInstanceUidList); +// } + + + + +// public void UploadOrReUploadNeedTodo(ArchiveStudyCommand archiveStudyCommand, List archiveStudyIds, ref DicomArchiveResult result, StudyMonitor monitor) +// { + + +// var archivedStudyId = archiveStudyIds[0]; + +// //result.ArchivedDicomStudies = _studyRepository.Where(t => t.SubjectVisitId == archiveStudyCommand.SubjectVisitId) +// // .ProjectTo(_mapper.ConfigurationProvider).ToList(); + +// #region 更新受试者访视信息 及访视状态为待提交 最早最晚拍片时间 访视已执行 + +// var subjectVisit = _subjectVisitRepository.FirstOrDefaultAsync(t => t.Id == archiveStudyCommand.SubjectVisitId).Result; + + + + + + + + + +// #endregion + + +// //按照访视维度,上传只存在重传同一份,和上传新的(不存在之前检查维度 重传同一份 和重传不同的) + +// if (archiveStudyCommand.AbandonStudyId != null && archiveStudyCommand.AbandonStudyId == archivedStudyId) +// { +// result.ReuploadNewStudyId = archivedStudyId; + + +// // 1、普通上传后重传 +// // 2、QC后重传 +// //_studyService.ReUploadSameStudy(archiveStudyCommand.SubjectVisitId, archivedDicomStudy.Id); + +// }//上传 +// else +// { +// //汇总 Series的Modality 更新到检查里面 检查状态 上传人 +// var seriesModalityList = _dicomSeriesRepository.Where(t => t.StudyId == archivedStudyId).Select(u => u.Modality).Distinct(); +// string ModaliyStr = string.Join('、', seriesModalityList.ToList()); + +// var study = _studyRepository.FirstOrDefaultAsync(t => t.Id == archivedStudyId).Result.IfNullThrowException(); +// study.Status = (int)StudyStatus.Uploaded; +// study.Modalities = ModaliyStr; + +// } +// _ = _dicomStudyMonitorRepository.AddAsync(monitor).Result; +// _ = _studyRepository.SaveChangesAsync().Result; + + + + + +// } + + + + + +// //public virtual IResponseOutput ForwardStudy(Guid studyId) +// //{ + +// // var study = _studyRepository.FirstOrDefault(u => u.Id == studyId); + + + +// // //数据库状态,其他人已经操作过了,此时提醒 +// // if (study.Status != (int)StudyStatus.Anonymized) +// // { +// // ResponseOutput.NotOk($"当前界面Study:{study.StudyCode} 状态被其他人已变更,不允许该操作,请刷新界面"); +// // } + +// // _studyRepository.Update(t => t.Id == studyId, u => new DicomStudy() +// // { +// // Status = (int)StudyStatus.Forwarding +// // }); + +// // var subject = _subjectRepository.FirstOrDefault(u => u.Id == study.SubjectId); +// // var trial = _trialRepository.FirstOrDefault(u => u.Id == study.TrialId); +// // var subjectVisit = _subjectVisitRepository.FirstOrDefault(u => u.Id == study.SubjectVisitId); +// // var targetPath = Path.Combine("/IMPORT-IMAGES", +// // trial.TrialCode + "_" + subject.Code + "_" + subjectVisit.VisitName + "_" + study.StudyCode); +// // var path = Path.Combine(_fileStorePath, study.CreateTime.Year.ToString(), study.TrialId.ToString(), +// // study.SiteId.ToString(), study.SubjectId.ToString(), study.SubjectVisitId.ToString(), study.Id.ToString(), "Data"); +// // try +// // { +// // // 主机及端口信息后面可以改到 配置文件 +// // SessionOptions sessionOptions = new SessionOptions +// // { +// // Protocol = Protocol.Sftp, +// // PortNumber = 8022, +// // HostName = "CS-690-sftp.mint-imaging.com", +// // UserName = "zdong", +// // Password = "Everest@2021", +// // //GiveUpSecurityAndAcceptAnySshHostKey = true, +// // SshHostKeyFingerprint = @"ecdsa-sha2-nistp384 384 59gkjJ5lMwv3jsB8Wz2B35tBAIor5pSd8PcJYtoamPo=" +// // }; +// // using (Session session = new Session()) +// // { +// // session.Open(sessionOptions); +// // if (!session.FileExists(targetPath)) +// // { +// // session.CreateDirectory(targetPath); +// // } + +// // var files = (new DirectoryInfo(path)).GetFiles(); +// // foreach (var file in files) +// // { +// // if (file.Name.Contains("Anonymize") && file.Extension.Contains("dcm")) +// // { +// // string remoteFilePath = +// // RemotePath.TranslateLocalPathToRemote(file.FullName, path, targetPath); +// // var result = session.PutFiles(file.FullName, remoteFilePath, false); +// // if (!result.IsSuccess) +// // { +// // return ResponseOutput.NotOk("Forward Failed"); +// // } +// // } +// // } + +// // //_studyStatusDetailRepository.Add(new StudyStatusDetail +// // //{ +// // // Status = (int)StudyStatus.Forwarded, +// // // StudyId = studyId, +// // // Note = string.Empty, +// // // OptUserName = _userInfo.RealName, +// // // OptTime = DateTime.Now +// // //}); + +// // study.Status = (int)StudyStatus.Forwarded; +// // _studyRepository.Update(study); + +// // //_workloadTPRepository.Add(new WorkloadTP +// // //{ +// // // SiteId = study.SiteId, +// // // StudyId = study.Id, +// // // SubjectId = study.SubjectId, +// // // SubjectVisitId = study.SubjectVisitId, +// // // Status = 0, +// // // ReviewerId = Guid.Empty, +// // // TrialId = study.TrialId, +// // // UpdateTime = DateTime.Now, +// // // TimepointCode = study.StudyCode + "_T01" +// // //}); +// // //if (study.IsDoubleReview) //双重阅片,则再添加一条,编号变为T02 +// // //{ +// // // _workloadTPRepository.Add(new WorkloadTP +// // // { +// // // SiteId = study.SiteId, +// // // StudyId = study.Id, +// // // SubjectId = study.SubjectId, +// // // SubjectVisitId = study.SubjectVisitId, +// // // Status = 0, +// // // ReviewerId = Guid.Empty, +// // // TrialId = study.TrialId, +// // // UpdateTime = DateTime.Now, +// // // TimepointCode = study.StudyCode + "_T02" +// // // }); +// // //} + + +// // return ResponseOutput.Result(_studyRepository.SaveChanges()); +// // } +// // } +// // catch (Exception e) +// // { +// // _studyRepository.Update(t => t.Id == studyId, u => new DicomStudy() +// // { +// // Status = (int)StudyStatus.ForwardFailed +// // }); +// // return ResponseOutput.NotOk("Forward Failed " + e.Message); +// // } +// //} + + + + + + + + +// #region 暂存 读片 + +// //public IEnumerable GetSeriesList(Guid studyId) +// //{ +// // return _dicomSeriesRepository.Where(s => s.StudyId == studyId).OrderBy(s => s.SeriesNumber). +// // ThenBy(s => s.SeriesTime).ThenBy(s => s.CreateTime) +// // .ProjectTo(_mapper.ConfigurationProvider); +// //} + + +// //public IEnumerable GetImageLabel(string tpCode) +// //{ +// // return _imageLabelRepository.Where(s => s.TpCode == tpCode) +// // .ProjectTo(_mapper.ConfigurationProvider); +// //} + +// //public bool SaveImageLabelList(ImageLabelCommand imageLabelCommand) +// //{ +// // var success = _imageLabelRepository.Delete(u => u.TpCode == imageLabelCommand.TpCode); +// // _keyInstanceRepository.Delete(u => u.TpCode == imageLabelCommand.TpCode); +// // if (imageLabelCommand.ImageLabelList.Count == 0) +// // { +// // return true; +// // } +// // else +// // { + +// // foreach (var label in imageLabelCommand.ImageLabelList) +// // { +// // _imageLabelRepository.Add(new ImageLabel +// // { +// // TpCode = imageLabelCommand.TpCode, +// // StudyId = label.StudyId, +// // SeriesId = label.SeriesId, +// // InstanceId = label.InstanceId, +// // LabelValue = label.LabelValue +// // }); +// // _keyInstanceRepository.Add(new KeyInstance +// // { +// // TpCode = imageLabelCommand.TpCode, +// // SeriesId = label.SeriesId, +// // InstanceId = label.InstanceId, +// // }); +// // } +// // success = _imageLabelRepository.SaveChanges(); +// // return success; +// // } +// //} + + +// #endregion + + + + +// #region 废弃 +// //public DicomStudyDTO GetStudyItem(Guid studyId) +// //{ +// // return _mapper.Map(_studyRepository.FirstOrDefault(s => s.Id == studyId)); +// //} +// //public virtual async Task DicomAnonymize(Guid studyId, string optUserName) +// //{ +// // var study = _studyRepository.FirstOrDefault(t => t.Id == studyId); + +// // //数据库状态,其他人已经操作过了,此时提醒 +// // if (study.Status != (int)StudyStatus.QAFinish) +// // { +// // ResponseOutput.NotOk($"当前界面Study:{study.StudyCode} 状态被其他人已变更,不允许该操作,请刷新界面"); +// // } + +// // var subject = _subjectRepository.Select(t => new { Id = t.Id, Code = t.Code }).FirstOrDefault(u => u.Id == study.SubjectId).IfNullThrowException(); +// // var trial = _trialRepository.Select(t => new { Id = t.Id, Code = t.TrialCode }).FirstOrDefault(u => u.Id == study.TrialId).IfNullThrowException(); + +// // study.Status = (int)StudyStatus.Anonymizing; + + +// // // 查询受试者 信息 +// // //string subjectCde = string.Empty; +// // //string subjectSex = string.Empty; + +// // //读取Dicom 文件,匿名化 + +// // //按照配置文件 匿名化 +// // var dicomSeries = _dicomSeriesRepository.Where(s => s.StudyId == studyId).ToList(); +// // foreach (var seriesItem in dicomSeries) +// // { +// // var dicomInstances = _dicomInstanceRepository.Where(s => s.SeriesId == seriesItem.Id).ToList(); + +// // foreach (var instanceItem in dicomInstances) +// // { +// // _dicomInstanceRepository.Attach(instanceItem); + +// // try +// // { +// // string filePath = _dicomFileStoreHelper.CreateInstanceFilePath(study, seriesItem.Id, instanceItem.Id); +// // DicomFile dicomFile = await DicomFile.OpenAsync(filePath, Encoding.Default); + +// // #region 废弃 + +// // //if (SystemConfig.AddClinicalInfo) //是否需要写入临床信息 +// // //{ +// // // dicomFile.Dataset.AddOrUpdate(DicomTag.ClinicalTrialSubjectID, subjectCde + " " + subjectSex);//SubjectId +// // //} +// // //DicomDataset dataset = dicomFile.Dataset; + +// // #endregion + +// // foreach (var anonymizeItem in AppSettings.AnonymizeTagList) +// // { +// // if (anonymizeItem.Enable) +// // { +// // ushort group = Convert.ToUInt16(anonymizeItem.Group, 16); +// // ushort element = Convert.ToUInt16(anonymizeItem.Element, 16); +// // dicomFile.Dataset.AddOrUpdate(new DicomTag(group, element), anonymizeItem.ReplaceValue); +// // } +// // } + +// // dicomFile.Dataset.AddOrUpdate(DicomTag.PatientID, trial.Code + "_" + subject.Code); + +// // //_dicomFileStoreHelper.CreateInstanceFilePath(study, seriesItem.Id, instanceItem.Id); + +// // string path = Path.Combine(_fileStorePath, study.CreateTime.Year.ToString(), +// // study.TrialId.ToString(), +// // study.SiteId.ToString(), study.SubjectId.ToString(), study.SubjectVisitId.ToString(), study.Id.ToString(), "Data"); + +// // //await dicomFile.SaveAsync(Path.Combine(path, instanceItem.Id.ToString() + ".dcm")); +// // await dicomFile.SaveAsync( +// // Path.Combine(path, instanceItem.Id.ToString() + ".Anonymize" + ".dcm")); + +// // instanceItem.Anonymize = true; + +// // //_dicomInstanceRepository.Update(instanceItem); +// // } +// // catch (Exception ex) +// // { + +// // study.Status = (int)StudyStatus.AnonymizeFailed; + +// // _dicomInstanceRepository.SaveChanges(); + +// // //这个地方返回没用 +// // return ResponseOutput.NotOk(ex.Message); +// // } +// // } + +// // } + +// // study.Status = (int)StudyStatus.Anonymized; + +// // var success = _dicomInstanceRepository.SaveChanges(); + +// // return ResponseOutput.Result(success); +// //} +// //public string GetStudyPreview(Guid studyId) +// //{ +// // DicomInstance dicomInstance = _dicomInstanceRepository.FirstOrDefault(s => s.StudyId == studyId); +// // if (dicomInstance != null) +// // { +// // DicomStudy dicomStudy = _studyRepository.FirstOrDefault(s => s.Id == dicomInstance.StudyId); +// // if (dicomStudy != null) +// // { +// // return _dicomFileStoreHelper.GetInstanceFilePath(dicomStudy, dicomInstance.SeriesId, dicomInstance.Id.ToString()); +// // } +// // } +// // return string.Empty; +// //} + +// //public IEnumerable GetAllRelationStudyList(Guid subjectVisitId) +// //{ +// // #region 废弃 +// // //var studylist = _studyRepository.Where(u => u.SubjectVisitId == subjectVisitId && u.IsDeleted == false).Select(t => new { StudyId = t.Id, t.SubjectId, t.TrialId }).ToList(); +// // //var subjectId = studylist.FirstOrDefault().SubjectId; +// // //var trialId = studylist.FirstOrDefault().TrialId; +// // //var studyIds = studylist.Select(t => t.StudyId).ToList(); + + +// // //var query = from studyItem in _studyRepository.Where(u => u.SubjectId == subjectId +// // // && u.TrialId == trialId && u.IsDeleted == false && +// // // !studyIds.Contains(u.Id) +// // // /* && u.Status != (int)StudyStatus.Abandon*/) +// // // join visitItem in _subjectVisitRepository.AsQueryable() +// // // on studyItem.SubjectVisitId equals visitItem.Id +// // // select new RelationStudyDTO +// // // { +// // // StudyId = studyItem.Id, +// // // StudyCode = studyItem.StudyCode, +// // // VisitName = visitItem.VisitName, +// // // Modalities = studyItem.Modalities, +// // // Description = studyItem.Description, +// // // SeriesCount = studyItem.SeriesCount +// // // }; +// // #endregion + +// // var studyInfo = _studyRepository.Where(u => u.SubjectVisitId == subjectVisitId).Select(t => new { t.SubjectId, t.TrialId }).FirstOrDefault().IfNullThrowException(); + +// // var query = _studyRepository.Where(t => t.SubjectVisitId != subjectVisitId && t.TrialId == studyInfo.TrialId && t.SubjectId == studyInfo.SubjectId) +// // .ProjectTo(_mapper.ConfigurationProvider).ToList(); + +// // return query.OrderBy(u => u.VisitName).ThenBy(s => s.StudyCode).ToList(); +// //} + + +// ///// +// ///// 检查列表 +// ///// +// ///// +// ///// +// //public PageOutput GetStudyList(StudyQueryDTO queryDto) +// //{ +// // var query = _studyRepository.Where(x => x.TrialId == queryDto.TrialId) +// // .WhereIf(queryDto.SubjectId != null, t => t.SubjectId == queryDto.SubjectId) +// // .WhereIf(queryDto.SubjectVisitId != null, t => t.SubjectId == queryDto.SubjectVisitId) +// // .WhereIf(!string.IsNullOrEmpty(queryDto.VisitPlanInfo), queryDto.VisitPlanInfo.Contains('.') ? t => t.SubjectVisit.VisitNum.ToString().Contains(".") : t => t.SubjectVisit.VisitNum == decimal.Parse(queryDto.VisitPlanInfo)) +// // .WhereIf(queryDto.StudyTimeBegin != null, t => t.StudyTime >= queryDto.StudyTimeBegin) +// // .WhereIf(queryDto.StudyTimeEnd != null, t => t.StudyTime <= queryDto.StudyTimeEnd) +// // .WhereIf(queryDto.UpdateTimeBegin != null, t => t.StudyTime >= queryDto.UpdateTimeBegin) +// // .WhereIf(queryDto.UpdateTimeEnd != null, t => t.StudyTime <= queryDto.UpdateTimeEnd) +// // .WhereIf(queryDto.SiteId != null, t => t.SiteId == queryDto.SiteId) +// // .WhereIf(_userInfo.UserTypeEnumInt == (int)UserTypeEnum.ClinicalResearchCoordinator, t => t.TrialSite.CRCUserList.Any(t => t.UserId == _userInfo.Id)) +// // .WhereIf(!string.IsNullOrWhiteSpace(queryDto.SubjectInfo), t => t.Subject.Code.Contains(queryDto.SubjectInfo)) +// // .ProjectTo(_mapper.ConfigurationProvider); + + +// // var list = query.ToPagedList(queryDto.PageIndex, queryDto.PageSize, queryDto.SortField == string.Empty ? "StudyCode" : queryDto.SortField, queryDto.Asc); + + +// // foreach (var item in list.CurrentPageData) +// // { +// // if (item.PatientBirthDate.Length == 8) +// // { +// // item.PatientBirthDate = +// // $"{item.PatientBirthDate[0]}{item.PatientBirthDate[1]}{item.PatientBirthDate[2]}{item.PatientBirthDate[3]}-{item.PatientBirthDate[4]}{item.PatientBirthDate[5]}-{item.PatientBirthDate[6]}{item.PatientBirthDate[7]}"; +// // } +// // } + +// // return list; +// //} + + + +// //public IResponseOutput DeleteStudy(Guid id) +// //{ +// // var needDelete = _studyRepository.FirstOrDefault(t => t.Id == id); + +// // if (needDelete == null) +// // { +// // return ResponseOutput.DBNotExistIfNUll(needDelete); +// // } +// // else //移除内存中缓存的StudyCode 这样刚上传的,删除 再上传还是用同样的Code +// // { + +// // if (_provider.Get($"{needDelete.TrialId }_{ StaticData.StudyMaxCode}").Value == needDelete.StudyCode) +// // { +// // _provider.Remove($"{needDelete.TrialId }_{ StaticData.StudyMaxCode}"); +// // } +// // } + + + +// // //if (study.Status != (int)StudyStatus.Uploaded) +// // //{ +// // // return ResponseOutput.NotOk("This study has been quality controlled and couldn't be deleted "); +// // //} + +// // #region 废弃的直接删除了 这里不用处理了 + +// // ////处理废弃的Study 如果有的话 +// // //var oldStudy = _studyRepository.FirstOrDefault(t => t.StudyCode == study.StudyCode && t.Id != id); +// // //if (oldStudy != null) +// // //{ +// // // _studyRepository.Delete(t => t.Id == oldStudy.Id); +// // // _dicomInstanceRepository.Delete(t => t.StudyId == oldStudy.Id); +// // // _dicomSeriesRepository.Delete(t => t.StudyId == oldStudy.Id); +// // //} +// // //处理废弃的Study +// // //var success5 = _studyRepository.Delete(t => t.StudyCode == study.StudyCode); +// // #endregion + + +// // //清除现有Study记录 +// // var success1 = _studyRepository.Delete(t => t.Id == id); +// // var succeess2 = _dicomInstanceRepository.Delete(t => t.StudyId == id); +// // var success3 = _dicomSeriesRepository.Delete(t => t.StudyId == id); + + +// // //一个访视下面有多个检查,所以需要检测 没有的时候才清空 +// // if (_studyRepository.Count(t => t.SubjectVisitId == needDelete.SubjectVisitId) == 0) +// // { +// // _subjectVisitRepository.Update(t => t.Id == needDelete.SubjectVisitId, + +// // u => new SubjectVisit() { VisitExecuted = VisitExecutedEnum.UnExecuted, SVENDTC = null, SVSTDTC = null }); + +// // _qcChallengeRepository.Delete(t => t.SubjectVisitId == needDelete.SubjectVisitId); + +// // //_qcChallengeRepository.Delete(t => t.SubjectVisitId == subjectVisitId); + +// // //_trialQCQuestionAnswerRepository.Delete(t => t.SubjectVisitId == subjectVisitId); +// // } + + + + + +// // return ResponseOutput.Result(success1 || succeess2 || success3); +// //} + +// //public void ClearStudyInstanceAndSeriseData(Guid studyId) +// //{ +// // //重新开始计数,怕数据库又脏数据,影响数量 +// // _studyRepository.Update(t => t.Id == studyId, u => new DicomStudy() +// // { +// // InstanceCount = 0, +// // SeriesCount = 0 +// // }); + +// // _dicomSeriesRepository.Delete(t => t.StudyId == studyId); +// // _dicomInstanceRepository.Delete(t => t.StudyId == studyId); +// //} + + + +// //public bool ReUploadDifferentStudy(Guid subjectVisitId, Guid abandonStudyId, Guid newStudyId) +// //{ +// // //_qcChallengeRepository.Update(t => t.SubjectVisitId == subjectVisitId && t.NeedReUpload == true, u => new QCChallenge() { ReUploadedTime = DateTime.Now, ReUploader = _userInfo.RealName }); + +// // //注意这里不是用SeqId 主键查询,因为Seq id 是后续加的,为了不改变代码和前端接口参数 +// // var study = _studyRepository.FirstOrDefault(t => t.Id == abandonStudyId); + +// // var code = study.StudyCode; + +// // //清理以前的数据 +// // _studyRepository.Delete(t => t.Id == abandonStudyId); +// // _dicomInstanceRepository.Delete(t => t.StudyId == abandonStudyId); +// // _dicomSeriesRepository.Delete(t => t.StudyId == abandonStudyId); + +// // ////将以前的qa记录数据绑定到现在新生成的Study上 +// // //_qaNoticeRepository.Update(t => t.SubjectVisitId == abandonStudyId, u => new QANotice() { SubjectVisitId = newStudyId }); +// // //_qaNoticeUserRepository.Update(t => t.SubjectVisitId == abandonStudyId, +// // // u => new QANoticeUser() { SubjectVisitId = newStudyId }); +// // //_qaRecordRepository.Update(t => t.SubjectVisitId == abandonStudyId, u => new QARecord() { SubjectVisitId = newStudyId }); + + +// // var success = false; +// // if (study.Status == (int)StudyStatus.Uploading) +// // { +// // success = _studyRepository.Update(t => t.Id == newStudyId, u => new DicomStudy() +// // { +// // Status = (int)StudyStatus.Uploaded, +// // StudyCode = code +// // }); +// // } +// // else +// // { +// // //新一份的影像状态为旧影像的状态 不改变 +// // success = _studyRepository.Update(t => t.Id == newStudyId, u => new DicomStudy() +// // { +// // Status = study.Status, +// // StudyCode = code +// // }); +// // } + + + +// // #region 废弃之前的Study记录 讲新产生的记录的StudyCode 变更为老的 这样可以关联在一起 + +// // //var realName = _userInfo.RealName; +// // //var code = _studyRepository.GetAll().First(t => t.Id == abandonStudyId).StudyCode; +// // //_studyRepository.Update(t => t.Id == abandonStudyId, u => new DicomStudy() +// // //{ +// // // Status = (int)StudyStatus.Abandon +// // //}); +// // //_studyRepository.Update(t => t.Id == newStudyId, u => new DicomStudy() +// // //{ +// // // Status = (int)StudyStatus.Uploaded, +// // // StudyCode = code +// // //}); +// // //_studyStatusDetailRepository.Add(new StudyStatusDetail +// // //{ +// // // Status = (int)StudyStatus.Abandon, +// // // StudyId = abandonStudyId, +// // // Note = string.Empty, +// // // OptUserName = realName, +// // // OptTime = DateTime.Now +// // //}); +// // //_studyStatusDetailRepository.Add(new StudyStatusDetail +// // //{ +// // // Status = (int)StudyStatus.Uploaded, +// // // StudyId = newStudyId, +// // // Note = string.Empty, +// // // OptUserName = realName, +// // // OptTime = DateTime.Now +// // //}); + +// // //_studyStatusDetailRepository.SaveChanges(); + +// // #endregion + + +// // return success; + +// //} + + +// //public virtual void ReUploadSameStudy(Guid subjectVisitId, Guid studyId) +// //{ +// // //_qcChallengeRepository.Update(t => t.SubjectVisitId == subjectVisitId && t.NeedReUpload == true, u => new QCChallenge() { ReUploadedTime = DateTime.Now, ReUploader = _userInfo.RealName }); + +// // #region 之前整个上传过程操作没有放在一个整体事务 会有脏数据 现在整体一个事务,不会产生,废弃 但是切入AOP 所以保留空方法 +// // //var study = _studyRepository.FirstOrDefault(t=>t.Id== studyId); +// // //var status = study.Status; + +// // //if (status == (int)StudyStatus.Uploading) +// // //{ +// // // _studyRepository.Update(t => t.Id == studyId, u => new DicomStudy() +// // // { +// // // Status = (int)StudyStatus.Uploaded +// // // }); +// // //} +// // #endregion +// //} +// ///// +// ///// 上传完检查后,处理检查 汇总 Series的Modality 更新到检查里面 检查状态 上传人 +// ///// +// ///// +// //public void UploadStudyDeal(Guid studyId) +// //{ + +// // var seriesModalityList = _dicomSeriesRepository.Where(t => t.StudyId == studyId).Select(u => u.Modality).Distinct(); +// // string ModaliyStr = string.Join('、', seriesModalityList.ToList()); + +// // var study = _studyRepository.FirstOrDefault(t => t.Id == studyId); +// // study.Status = (int)StudyStatus.Uploaded; +// // study.Modalities = ModaliyStr; +// // _studyRepository.SaveChanges(); +// //} + + +// //public List GetSubjectVisitStudyList(Guid trialId, Guid siteId, Guid subjectId, Guid subjectVisitId) +// //{ +// // var query = _studyRepository.Where(t => t.TrialId == trialId && t.SiteId == siteId && t.SubjectId == t.SubjectId && t.SubjectVisitId == subjectVisitId) +// // .Select(u => new SubjectVisitStudyDTO() { Modalities = u.Modalities, StudyCode = u.StudyCode, StudyId = u.Id, Status = u.Status }); + +// // return query.ToList(); +// //} + +// ////此处有AOP操作,不要更改为动态Api +// //public virtual IResponseOutput UpdateStudyStatus(StudyStatusDetailCommand studyStatus) +// //{ + +// // //注意这里不是用SeqId 主键查询,因为Seq id 是后续加的,为了不改变代码和前端接口参数 +// // var study = _studyRepository.FirstOrDefault(t => t.Id == studyStatus.StudyId); + +// // //数据库状态,其他人已经操作过了,此时提醒 +// // if (study.Status > studyStatus.Status) +// // { +// // ResponseOutput.NotOk($"当前界面Study:{study.StudyCode} 状态被其他人已变更,不允许该操作,请刷新界面"); +// // } + +// // ////防止多次调用,更新 没必要 +// // //if (study.Status == studyStatus.Status) +// // //{ +// // // return ResponseOutput.Ok(); +// // //} + +// // study.Status = studyStatus.Status; +// // study.UpdateTime = DateTime.Now; + +// // //if (studyStatus.Status == (int)StudyStatus.Uploaded) +// // //{ +// // // study.UploadedTime = DateTime.Now; +// // // study.Uploader = _userInfo.RealName; + + +// // //} +// // //if (study.Status == (int)StudyStatus.QAing) +// // //{ +// // // study.DeadlineTime = studyStatus.DeadlineTime; +// // //} + +// // if (studyStatus.Status == (int)StudyStatus.QAFInishNotPass) +// // { +// // study.QAComment = studyStatus.QAComment; +// // } + + +// // return ResponseOutput.Ok(_studyRepository.SaveChanges()); +// //} + +// //public List GetStudyStatusDetailList(Guid studyId) +// //{ +// // return _studyStatusDetailRepository.Where(s => s.StudyId == studyId).OrderByDescending(s => s.OptTime) +// // .ProjectTo(_mapper.ConfigurationProvider).ToList(); +// //} + + +// //public bool DistributeStudy(StudyReviewerCommand studyReviewer) +// //{ +// // //更新Study表中,总的状态 +// // // 插入中间表 +// // studyReviewer.StudyList.ForEach(study => +// // { +// // var workloadType = 1; +// // StudyStatus studyStatus = StudyStatus.Distributed; + +// // if (study.Status >= (int)StudyStatus.NeedAd) +// // { +// // workloadType = 2; +// // studyStatus = StudyStatus.AdDistributed; +// // } + +// // var tempStudy = _studyRepository.FirstOrDefault(s => s.Id == study.StudyId); +// // tempStudy.Status = (int)studyStatus; +// // _studyRepository.Update(tempStudy); + +// // _studyReviewerRepository.Add(new StudyReviewer() +// // { +// // ReviewerId = studyReviewer.ReviewerId, +// // StudyId = study.StudyId, +// // WorkloadType = workloadType, +// // TrialId = studyReviewer.TrialId, +// // Status = (int)studyStatus +// // }); +// // }); + +// // return _studyReviewerRepository.SaveChanges(); +// //} + + +// //public IResponseOutput EditStudyReviewer(StudyReviewerEditCommand studyReviewerEditCommand) +// //{ +// // _studyReviewerRepository.Delete(t => studyReviewerEditCommand.StudyId == t.StudyId); + +// // if (studyReviewerEditCommand.IsDoubleReview) +// // { +// // if (studyReviewerEditCommand.ReviewerId1 != null) +// // { +// // _studyReviewerRepository.Add( +// // new StudyReviewer() +// // { +// // StudyId = studyReviewerEditCommand.StudyId, +// // TrialId = studyReviewerEditCommand.TrialId, +// // ReviewerId = studyReviewerEditCommand.ReviewerId1.Value, +// // WorkloadType = 1 +// // }); +// // } + +// // if (studyReviewerEditCommand.ReviewerId2 != null) +// // { +// // _studyReviewerRepository.Add( +// // new StudyReviewer() +// // { +// // StudyId = studyReviewerEditCommand.StudyId, +// // TrialId = studyReviewerEditCommand.TrialId, +// // ReviewerId = studyReviewerEditCommand.ReviewerId2.Value, +// // WorkloadType = 1 +// // }); +// // } + +// // if (studyReviewerEditCommand.ReviewerIdForAD != null) +// // { +// // _studyReviewerRepository.Add( +// // new StudyReviewer() +// // { +// // StudyId = studyReviewerEditCommand.StudyId, +// // TrialId = studyReviewerEditCommand.TrialId, +// // ReviewerId = studyReviewerEditCommand.ReviewerIdForAD.Value, +// // WorkloadType = 2 +// // }); +// // } + +// // if (studyReviewerEditCommand.ReviewerId2 == null || studyReviewerEditCommand.ReviewerId1 == null) +// // { +// // _studyRepository.Update(t => t.Id == studyReviewerEditCommand.StudyId, +// // u => new DicomStudy() +// // { +// // Status = (int)StudyStatus.QAFinish +// // }); +// // } +// // } +// // else +// // { +// // if (studyReviewerEditCommand.ReviewerId1 != null) +// // { +// // _studyReviewerRepository.Add( +// // new StudyReviewer() +// // { +// // StudyId = studyReviewerEditCommand.StudyId, +// // TrialId = studyReviewerEditCommand.TrialId, +// // ReviewerId = studyReviewerEditCommand.ReviewerId1.Value, +// // WorkloadType = 1 +// // }); +// // } +// // else +// // { +// // _studyRepository.Update(t => t.Id == studyReviewerEditCommand.StudyId, +// // u => new DicomStudy() +// // { +// // Status = (int)StudyStatus.QAFinish +// // }); +// // } +// // } + +// // var success = _studyReviewerRepository.SaveChanges(); +// // return ResponseOutput.Result(success); +// //} + +// //public List GetReviewerListByTrialId(Guid trialId) +// //{ +// // var query = from enrollItem in _enrollRepository +// // .Where(t => t.TrialId == trialId && t.EnrollStatus >= 10) +// // join doctorItem in _doctorRepository.AsQueryable() +// // on enrollItem.DoctorId equals doctorItem.Id into g +// // from doctor in g.DefaultIfEmpty() +// // select new +// // { +// // ReviewerCode = doctor.ReviewerCode, +// // FirstName = doctor.FirstName, +// // LastName = doctor.LastName, +// // ReviewerId = enrollItem.DoctorId, +// // ActivelyReading = doctor.ActivelyReading, +// // }; + +// // return query.Where(s => s.ActivelyReading).Select(s => new ReviewerDistributionDTO +// // { +// // ReviewerCode = s.ReviewerCode, +// // FirstName = s.FirstName, +// // LastName = s.LastName, +// // ReviewerId = s.ReviewerId, + +// // }).ToList(); +// //} + + +// //public PageOutput GetDistributeStudyList( +// // StudyStatusQueryDTO studyStatusQueryDto) +// //{ +// // Expression> studyReviewerLambda = x => x.TrialId == studyStatusQueryDto.TrialId; + +// // if (studyStatusQueryDto.ReviewerId != null) +// // { +// // studyReviewerLambda = studyReviewerLambda.And(t => t.ReviewerId == studyStatusQueryDto.ReviewerId); +// // } + +// // if (studyStatusQueryDto.StudyStatus != null) +// // { +// // studyReviewerLambda = studyReviewerLambda.And(t => t.Status == studyStatusQueryDto.StudyStatus); +// // } + +// // var query = from studyReviewer in _studyReviewerRepository.Where(studyReviewerLambda) +// // join doctor in _doctorRepository.AsQueryable() on studyReviewer.ReviewerId equals doctor.Id +// // join study in _studyRepository.AsQueryable() on studyReviewer.StudyId equals study.Id +// // select new DistributeReviewerStudyStatusDTO() +// // { +// // Name = doctor.LastName + " / " + doctor.FirstName, +// // NameCN = doctor.ChineseName, +// // ReviewerCode = doctor.ReviewerCode, +// // Status = studyReviewer.Status, +// // StudyCode = study.StudyCode +// // }; + +// // return query.ToPagedList(studyStatusQueryDto.PageIndex, +// // studyStatusQueryDto.PageSize, studyStatusQueryDto.SortField == string.Empty +// // ? "ReviewerCode" +// // : studyStatusQueryDto.SortField, studyStatusQueryDto.Asc); + + +// //} + +// //public IEnumerable GetRelationVisitList(decimal visitNum, string tpCode) +// //{ +// // string tpGroup = tpCode.Substring(tpCode.Length - 3, 3); +// // var tp = _workloadTPRepository.FirstOrDefault(u => u.TimepointCode == tpCode); +// // var query = from workloadTp in _workloadTPRepository.Where(u => u.SubjectId == tp.SubjectId +// // && u.TrialId == tp.TrialId && +// // u.TimepointCode.Contains(tpGroup)) +// // join subjectVisit in _subjectVisitRepository.Where(u => u.VisitNum <= visitNum) +// // on workloadTp.SubjectVisitId equals subjectVisit.Id +// // select new RelationVisitDTO +// // { +// // StudyId = workloadTp.StudyId, +// // TpCode = workloadTp.TimepointCode, +// // VisitName = subjectVisit.VisitName +// // }; +// // return query.ToList(); +// //} + +// //public List GetQANoticeList(Guid subjectVisitId) +// //{ + +// // var query = from noticeUser in _qaNoticeUserRepository.AsQueryable() +// // .Where(t => t.ToUserId == _userInfo.Id && t.SubjectVisitId == subjectVisitId) +// // join notice in _qaNoticeRepository.Where(u => u.NeedDeal == true && u.SubjectVisitId == subjectVisitId) on +// // noticeUser.QANoticeId equals notice.Id +// // select notice.Id; + +// // var noticeUserList = query.ToList(); + +// // //待处理的消息数量 +// // var count = noticeUserList.Count; + + +// // var list = _qaNoticeRepository.Where(t => t.SubjectVisitId == subjectVisitId) +// // .ProjectTo(_mapper.ConfigurationProvider).OrderByDescending(t => t.SendTime).ToList(); + +// // list.ForEach(t => t.IsMessageReceiver = count > 0 && noticeUserList.Contains(t.Id) ? t.NeedDeal : false); + + +// // return list; +// //} + +// //public IResponseOutput DealNonDicomFile(Dictionary filePathDic, +// // ArchiveStudyCommand archiveStudyCommand) +// //{ + + +// // var savedInfo = GetSaveToDicomInfo(archiveStudyCommand.SubjectVisitId); + +// // var dicomStudy = new DicomStudy +// // { +// // Id = Guid.NewGuid(), + +// // //SiteId = addtionalInfo.SiteId, +// // //TrialId = addtionalInfo.TrialId, +// // //SubjectId = addtionalInfo.SubjectId, +// // //SubjectVisitId = addtionalInfo.SubjectVisitId, +// // IsDoubleReview = savedInfo.IsDoubleReview, +// // Comment = savedInfo.Comment +// // }; + + + +// // #region Setting Code + +// // //var last = _studyRepository.Where(s => s.TrialId == addtionalInfo.TrialId) +// // // .OrderByDescending(c => c.StudyCode).FirstOrDefault(); +// // //if (last != null) +// // //{ +// // // var len = last.StudyCode.Length; +// // // if (len > 5 && int.TryParse(last.StudyCode.Substring(len - 5, 5), out var num)) +// // // { +// // // dicomStudy.StudyCode = "ST" + (++num).ToString().PadLeft(5, '0'); +// // // } +// // // else +// // // { +// // // return ResponseOutput.NotOk("Generate StudyCode failed"); +// // // } +// // //} +// // //else +// // //{ +// // // dicomStudy.StudyCode = "ST" + 1.ToString().PadLeft(5, '0'); +// // //} + +// // #endregion + +// // var study = _studyRepository.Add(dicomStudy); +// // var saveFileList = new List(); + +// // foreach (var key in filePathDic.Keys) +// // { +// // saveFileList.Add(new NoneDicomFile() { FileName = filePathDic[key], StudyId = study.Id, Path = key }); +// // } + + +// // _noneDicomFileRepository.AddRange(saveFileList); + + + +// // var success = _noneDicomFileRepository.SaveChanges(); + +// // UpdateStudyStatus(new StudyStatusDetailCommand +// // { +// // StudyId = study.Id, +// // Status = (int)StudyStatus.Uploaded, +// // Note = string.Empty +// // }); + + +// // return ResponseOutput.Result(success); + +// //} +// #endregion + + +// } +//} diff --git a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs index 93f7ce8b1..3a1ad2271 100644 --- a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs @@ -719,7 +719,7 @@ namespace IRaCIS.Core.Application.Image.QA [HttpPost, Route("{trialId:guid}/{subjectVisitId:guid}")] [TypeFilter(typeof(TrialResourceFilter))] [UnitOfWork] - [Authorize(Policy = IRaCISPolicy.IQC)] + [Authorize(Policy = IRaCISPolicy.CRC_IQC)] public async Task DeleteStudyList(Guid[] ids, Guid subjectVisitId, Guid trialId) { diff --git a/IRaCIS.Core.Application/Triggers/SubjectVisitTrigger.cs b/IRaCIS.Core.Application/Triggers/SubjectVisitTrigger.cs index 887a6a9b0..005dbce4a 100644 --- a/IRaCIS.Core.Application/Triggers/SubjectVisitTrigger.cs +++ b/IRaCIS.Core.Application/Triggers/SubjectVisitTrigger.cs @@ -9,10 +9,13 @@ namespace IRaCIS.Core.Application.Triggers public class SubjectVisitTrigger : IAfterSaveTrigger, IAfterSaveTrigger, IAfterSaveTrigger { private readonly IRepository _subjectVisitRepository; + private readonly IRepository _repository; - public SubjectVisitTrigger(IRepository subjectVisitRepository) + public SubjectVisitTrigger(IRepository subjectVisitRepository,IRepository repository) { _subjectVisitRepository = subjectVisitRepository; + + _repository = repository; } //注意删除不能用扩展方法,必须用EF跟踪的实体 否则不能取到 SubjectVisitId @@ -45,6 +48,15 @@ namespace IRaCIS.Core.Application.Triggers if (context.ChangeType == ChangeType.Added ) { await UpdateSubjectVisitImageDateAsync(subjectVisitId); + + var studyId = context.Entity.Id; + //处理Modality + var seriesModalityList = _repository.Where(t => t.StudyId == studyId).Select(u => u.Modality).Distinct(); + string ModaliyStr = string.Join('、', seriesModalityList.ToList()); + + + context.Entity.Modalities = ModaliyStr; + await _subjectVisitRepository.BatchUpdateNoTrackingAsync(t => t.Id == subjectVisitId, u => new SubjectVisit() { VisitExecuted = VisitExecutedEnum.Executed