622 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			622 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C#
		
	
	
| using FellowOakDicom;
 | |
| using IRaCIS.Application.Contracts;
 | |
| using IRaCIS.Core.Application.Contracts;
 | |
| using IRaCIS.Core.Application.Contracts.Dicom.DTO;
 | |
| using IRaCIS.Core.Application.Filter;
 | |
| using IRaCIS.Core.Domain.Share;
 | |
| using IRaCIS.Core.Infrastructure;
 | |
| using Microsoft.AspNetCore.Mvc;
 | |
| using Pipelines.Sockets.Unofficial.Arenas;
 | |
| using System.Linq.Dynamic.Core;
 | |
| using IDistributedLockProvider = Medallion.Threading.IDistributedLockProvider;
 | |
| using Subject = IRaCIS.Core.Domain.Models.Subject;
 | |
| 
 | |
| namespace IRaCIS.Core.Application.Service
 | |
| {
 | |
|     [ApiExplorerSettings(GroupName = "Trial")]
 | |
|     public class PatientService(IRepository<Trial> _trialRepository,
 | |
|         IRepository<SCPPatient> _patientRepository,
 | |
|         IRepository<SCPStudy> _scpStudyRepository,
 | |
|         IRepository<Subject> _subjectRepository,
 | |
|         IRepository<SubjectVisit> _subjectVisitRepository,
 | |
|         IRepository<Dictionary> _dictionaryRepository,
 | |
|         IRepository<DicomStudy> _dicomStudyRepository,
 | |
|         IRepository<SCPPatient> _scpPatientRepository,
 | |
|         IRepository<SCPImageUpload> _scpImageUploadRepository,
 | |
|         IDistributedLockProvider _distributedLockProvider, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService
 | |
|     {
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         [HttpGet]
 | |
|         public async Task<IResponseOutput<List<DicomSeriesDTO>>> GetPatientSeriesList(Guid scpStudyId,
 | |
|             [FromServices] IRepository<SCPSeries> _seriesRepository,
 | |
|             [FromServices] IRepository<SCPInstance> _instanceRepository
 | |
|             )
 | |
|         {
 | |
| 
 | |
|             var seriesList = await _seriesRepository.Where(s => s.StudyId == scpStudyId).OrderBy(s => s.SeriesNumber).
 | |
|              ThenBy(s => s.SeriesTime).ThenBy(s => s.CreateTime)
 | |
|              .ProjectTo<DicomSeriesDTO>(_mapper.ConfigurationProvider).ToListAsync();
 | |
| 
 | |
|             var instanceList = await _instanceRepository.Where(s => s.StudyId == scpStudyId).OrderBy(t => t.SeriesId).ThenBy(t => t.InstanceNumber)
 | |
|                         .ThenBy(s => s.InstanceTime).ThenBy(s => s.CreateTime)
 | |
|                 .Select(t => new { t.SeriesId, t.Id, t.Path, t.NumberOfFrames, t.InstanceNumber }).ToListAsync();//.GroupBy(u => u.SeriesId);
 | |
| 
 | |
|             foreach (var series in seriesList)
 | |
|             {
 | |
| 
 | |
|                 series.InstanceInfoList = instanceList.Where(t => t.SeriesId == series.Id).OrderBy(t => t.InstanceNumber).Select(k =>
 | |
|                    new InstanceBasicInfo()
 | |
|                    {
 | |
|                        Id = k.Id,
 | |
|                        NumberOfFrames = k.NumberOfFrames,
 | |
|                        //HtmlPath = string.Empty,
 | |
|                        Path = k.Path,
 | |
|                        InstanceNumber = k.InstanceNumber,
 | |
| 
 | |
|                    }).ToList();
 | |
|             }
 | |
| 
 | |
|             var study = await _scpStudyRepository.FindAsync(scpStudyId);
 | |
| 
 | |
|             return ResponseOutput.Ok(seriesList, study);
 | |
|         }
 | |
| 
 | |
| 
 | |
| 
 | |
|         /// <summary>
 | |
|         /// scp 影像推送记录表
 | |
|         /// </summary>
 | |
|         /// <param name="inQuery"></param>
 | |
|         /// <returns></returns>
 | |
|         [HttpPost]
 | |
|         public async Task<IResponseOutput<PageOutput<SCPImageUploadView>>> GetSCPImageUploadList(SCPImageUploadQuery inQuery)
 | |
|         {
 | |
|             var query = _scpImageUploadRepository.Where(t => t.TrialId == inQuery.TrialId)
 | |
|               .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CalledAE), t => t.CalledAE.Contains(inQuery.CalledAE))
 | |
|               .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAEIP), t => t.CallingAEIP.Contains(inQuery.CallingAEIP))
 | |
|               .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.CallingAE.Contains(inQuery.CallingAE))
 | |
|              .WhereIf(inQuery.StartTime != null, t => t.StartTime >= inQuery.StartTime)
 | |
|              .WhereIf(inQuery.EndTime != null, t => t.EndTime <= inQuery.EndTime)
 | |
|               .WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteKeyInfo), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteKeyInfo)
 | |
|                || t.TrialSite.TrialSiteAliasName.Contains(inQuery.TrialSiteKeyInfo) || t.TrialSite.TrialSiteName.Contains(inQuery.TrialSiteKeyInfo))
 | |
|               .ProjectTo<SCPImageUploadView>(_mapper.ConfigurationProvider);
 | |
| 
 | |
| 
 | |
|             var pageList = await query.ToPagedListAsync(inQuery);
 | |
| 
 | |
| 
 | |
|             return ResponseOutput.Ok(pageList);
 | |
|         }
 | |
| 
 | |
| 
 | |
|         #region 患者检查管理
 | |
| 
 | |
|         /// <summary>
 | |
|         ///影像检查列表-患者为维度组织
 | |
|         /// </summary>
 | |
|         /// <param name="inQuery"></param>
 | |
|         /// <returns></returns>
 | |
|         [HttpPost]
 | |
|         public async Task<IResponseOutput<PageOutput<PatientSubjectView>>> GetPatientList(PatientTrialQuery inQuery)
 | |
|         {
 | |
| 
 | |
| 
 | |
|             #region new ok
 | |
|             var query = _patientRepository.Where(t => t.TrialId == inQuery.TrialId)
 | |
|              .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientIdStr), t => t.PatientIdStr.Contains(inQuery.PatientIdStr))
 | |
|              .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientName), t => t.PatientName.Contains(inQuery.PatientName))
 | |
|              .WhereIf(!string.IsNullOrWhiteSpace(inQuery.SubejctCode), t => t.Subject.Code.Contains(inQuery.SubejctCode))
 | |
|              .WhereIf(!string.IsNullOrWhiteSpace(inQuery.TrialSiteKeyInfo), t => t.TrialSite.TrialSiteCode.Contains(inQuery.TrialSiteKeyInfo)
 | |
|                || t.TrialSite.TrialSiteAliasName.Contains(inQuery.TrialSiteKeyInfo) || t.TrialSite.TrialSiteName.Contains(inQuery.TrialSiteKeyInfo))
 | |
|              .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CallingAE), t => t.SCPStudyList.Any(t => t.CallingAE == inQuery.CallingAE))
 | |
|              .WhereIf(!string.IsNullOrWhiteSpace(inQuery.CalledAE), t => t.SCPStudyList.Any(t => t.CalledAE == inQuery.CalledAE))
 | |
|              .WhereIf(inQuery.BeginPushTime != null, t => t.LatestPushTime >= inQuery.BeginPushTime)
 | |
|              .WhereIf(inQuery.EndPushTime != null, t => t.LatestPushTime <= inQuery.EndPushTime);
 | |
| 
 | |
|             //foreach (var calledAE in inQuery.CalledAEList)
 | |
|             //{
 | |
|             //    query = query.Where(t => t.SCPStudyList.Select(c => c.CalledAE).Contains(calledAE));
 | |
|             //}
 | |
| 
 | |
| 
 | |
|             var resultQuery = from patient in query
 | |
| 
 | |
|                               select new PatientSubjectView()
 | |
|                               {
 | |
|                                   PatientId = patient.Id,
 | |
|                                   PatientBirthDate = patient.PatientBirthDate,
 | |
|                                   CreateTime = patient.CreateTime,
 | |
|                                   CalledAEList = patient.SCPStudyList.Select(t => t.CalledAE).Distinct().ToList(),
 | |
|                                   CallingAEList = patient.SCPStudyList.Select(t => t.CallingAE).Distinct().ToList(),
 | |
|                                   CreateUserId = patient.CreateUserId,
 | |
|                                   UpdateTime = patient.UpdateTime,
 | |
|                                   UpdateUserId = patient.UpdateUserId,
 | |
| 
 | |
|                                   EarliestStudyTime = patient.EarliestStudyTime,
 | |
|                                   LatestStudyTime = patient.LatestStudyTime,
 | |
|                                   LatestPushTime = patient.LatestPushTime,
 | |
|                                   PatientAge = patient.PatientAge,
 | |
|                                   PatientName = patient.PatientName,
 | |
|                                   PatientIdStr = patient.PatientIdStr,
 | |
|                                   PatientSex = patient.PatientSex,
 | |
| 
 | |
|                                   StudyCount = patient.SCPStudyList.Count(),
 | |
| 
 | |
|                                   TrialId = patient.TrialId,
 | |
|                                   SubejctId = patient.SubjectId,
 | |
|                                   SubjectCode = patient.Subject.Code,
 | |
|                                   TrialSiteAliasName = patient.TrialSite.TrialSiteAliasName,
 | |
|                                   TrialSiteCode = patient.TrialSite.TrialSiteCode,
 | |
|                                   TrialSiteName = patient.TrialSite.TrialSiteName
 | |
| 
 | |
|                               };
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|             var pageList = await resultQuery.ToPagedListAsync(inQuery);
 | |
|             #endregion
 | |
| 
 | |
| 
 | |
|             return ResponseOutput.Ok(pageList);
 | |
|         }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 影像检查列表-> 获取患者的检查列表
 | |
|         /// </summary>
 | |
|         /// <param name="inQuery"></param>
 | |
|         /// <returns></returns>
 | |
|         [HttpPost]
 | |
|         public async Task<PageOutput<PatientStudySimpleView>> GetPatientStudyList(PatientStudyInfoQuery inQuery)
 | |
|         {
 | |
|             var query = from scpStudy in _scpStudyRepository.Where(t => t.PatientId == inQuery.PatientId)
 | |
|                         .WhereIf(inQuery.EarliestStudyTime != null, t => t.StudyTime >= inQuery.EarliestStudyTime)
 | |
|                         .WhereIf(inQuery.LatestStudyTime != null, t => t.StudyTime <= inQuery.LatestStudyTime)
 | |
|                         .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Modalities), t => t.Modalities.Contains(inQuery.Modalities))
 | |
|                         select new PatientStudySimpleView()
 | |
|                         {
 | |
|                             Description = scpStudy.Description,
 | |
|                             CalledAE = scpStudy.CalledAE,
 | |
|                             CallingAE = scpStudy.CallingAE,
 | |
|                             InstanceCount = scpStudy.InstanceCount,
 | |
|                             Modalities = scpStudy.Modalities,
 | |
|                             PatientId = scpStudy.PatientId,
 | |
|                             SCPStudyId = scpStudy.Id,
 | |
|                             SeriesCount = scpStudy.SeriesCount,
 | |
|                             StudyTime = scpStudy.StudyTime,
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|                             SubjectVisitId = scpStudy.SubjectVisitId,
 | |
|                             VisitName = scpStudy.SubjectVisit.VisitName,
 | |
|                             BlindName = scpStudy.SubjectVisit.BlindName
 | |
|                         };
 | |
| 
 | |
| 
 | |
|             //var sortField = string.IsNullOrWhiteSpace(inQuery.SortField) ? nameof(PatientStudySimpleView.StudyTime) : inQuery.SortField;
 | |
|             //var orderQuery = inQuery.Asc ? query.OrderBy(sortField) : query.OrderBy(sortField + " desc");
 | |
| 
 | |
|             //var list = await orderQuery.ToListAsync();
 | |
| 
 | |
|             var pageList = await query.ToPagedListAsync(inQuery, nameof(PatientStudySimpleView.StudyTime));
 | |
| 
 | |
|             return pageList;
 | |
|         }
 | |
| 
 | |
| 
 | |
|         public async Task<List<string>> GetDicomCalledAEList(Guid trialId)
 | |
|         {
 | |
|             var list = await _scpStudyRepository.Where(t => t.TrialId == trialId).Select(t => t.CalledAE).Distinct().ToListAsync();
 | |
| 
 | |
|             return list;
 | |
|         }
 | |
| 
 | |
|         public async Task<List<string>> GetDicomCallingAEList(Guid trialId)
 | |
|         {
 | |
|             var list = await _scpStudyRepository.Where(t => t.TrialId == trialId).Select(t => t.CallingAE).Distinct().ToListAsync();
 | |
| 
 | |
|             return list;
 | |
|         }
 | |
| 
 | |
|         public async Task<List<string>> GetDicomModalityList(Guid trialId)
 | |
|         {
 | |
|             var list = await _scpStudyRepository.Where(t => t.TrialId == trialId).SelectMany(t => t.SeriesList).Select(t => t.Modality).Distinct().ToListAsync();
 | |
| 
 | |
|             return list;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 影像访视上传 检查列表
 | |
|         /// </summary>
 | |
|         /// <param name="inQuery"></param>
 | |
|         /// <returns></returns>
 | |
|         [HttpPost]
 | |
|         public async Task<PageOutput<VisitPatientStudyFilterView>> GetVisitPatientStudyFilterList(VisitPatientStudyFilterQuery inQuery)
 | |
|         {
 | |
| 
 | |
|             var trialSiteId = _subjectRepository.Where(t => t.Id == inQuery.SubjectId).Select(t => t.TrialSiteId).FirstOrDefault();
 | |
| 
 | |
|             var query = from scpStudy in _scpStudyRepository
 | |
|                         //未绑定的患者,或者自己已绑定但是未绑定访视的
 | |
|                         .Where(t => t.Patient.SubjectId == null || (t.Patient.SubjectId == inQuery.SubjectId && t.SubjectVisitId == null))
 | |
|                         //中心
 | |
|                         .Where(t => t.TrialSiteId == trialSiteId)
 | |
|                         .WhereIf(inQuery.EarliestStudyTime != null, t => t.StudyTime >= inQuery.EarliestStudyTime)
 | |
|                         .WhereIf(inQuery.LatestStudyTime != null, t => t.StudyTime <= inQuery.LatestStudyTime)
 | |
|                         .WhereIf(!string.IsNullOrWhiteSpace(inQuery.Modalities), t => t.Modalities.Contains(inQuery.Modalities))
 | |
|                         .WhereIf(!string.IsNullOrWhiteSpace(inQuery.PatientInfo), t => t.PatientIdStr.Contains(inQuery.PatientInfo) || t.PatientName.Contains(inQuery.PatientInfo) || t.PatientSex.Contains(inQuery.PatientInfo))
 | |
|                         select new VisitPatientStudyFilterView()
 | |
|                         {
 | |
|                             Description = scpStudy.Description,
 | |
|                             CalledAE = scpStudy.CalledAE,
 | |
|                             CallingAE = scpStudy.CallingAE,
 | |
|                             InstanceCount = scpStudy.InstanceCount,
 | |
|                             Modalities = scpStudy.Modalities,
 | |
|                             PatientId = scpStudy.PatientId,
 | |
|                             SCPStudyId = scpStudy.Id,
 | |
|                             SeriesCount = scpStudy.SeriesCount,
 | |
|                             StudyTime = scpStudy.StudyTime,
 | |
|                             BodyPartExamined = scpStudy.BodyPartExamined,
 | |
|                             AccessionNumber = scpStudy.AccessionNumber,
 | |
| 
 | |
|                             PatientBirthDate = scpStudy.PatientBirthDate,
 | |
|                             PatientAge = scpStudy.PatientAge,
 | |
|                             PatientIdStr = scpStudy.PatientIdStr,
 | |
|                             PatientName = scpStudy.PatientName,
 | |
|                             PatientSex = scpStudy.PatientSex,
 | |
|                         };
 | |
| 
 | |
| 
 | |
|             var pageList = await query.ToPagedListAsync(inQuery, nameof(PatientStudySimpleView.StudyTime));
 | |
| 
 | |
|             return pageList;
 | |
|         }
 | |
| 
 | |
| 
 | |
| 
 | |
|         public async Task<List<VerifySCPStudyUploadResult>> VerifyPacsImage(VerifyPacsImageCommand inCommand)
 | |
|         {
 | |
|             var trialId = inCommand.TrialId;
 | |
| 
 | |
|             var subjectId = inCommand.SubjectId;
 | |
| 
 | |
|             var isVerifyVisitImageDate = await _trialRepository.Where(t => t.Id == inCommand.TrialId).Select(t => t.IsVerifyVisitImageDate).FirstNotNullAsync();
 | |
| 
 | |
|             var result = new List<VerifySCPStudyUploadResult>();
 | |
| 
 | |
|             var visitList = _subjectVisitRepository.Where(t => t.SubjectId == inCommand.SubjectId).Select(t => new { t.VisitNum, t.EarliestScanDate, t.LatestScanDate, t.Id }).ToList();
 | |
| 
 | |
|             var currentVisitNum = visitList.First(t => t.Id == inCommand.SubjectVisitId).VisitNum;
 | |
| 
 | |
|             var scpStudyList = _scpStudyRepository.Where(t => inCommand.SCPStudyIdList.Contains(t.Id)).Select(t => new { StudyDate = t.StudyTime, t.Id }).ToList();
 | |
| 
 | |
|             foreach (var waitUploadItem in scpStudyList)
 | |
|             {
 | |
| 
 | |
|                 if (isVerifyVisitImageDate)
 | |
|                 {
 | |
|                     //小于当前访视 最近的最晚拍片
 | |
|                     var before = visitList.Where(u => u.VisitNum < currentVisitNum).Max(k => k.LatestScanDate);
 | |
| 
 | |
|                     if (before != null && waitUploadItem.StudyDate != null && before > waitUploadItem.StudyDate)
 | |
|                     {
 | |
| 
 | |
|                         // $"当前访视检查时间{waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")}不能早于前序访视检查时间{before?.ToString("yyyy-MM-dd")},请核对检查数据是否有误",
 | |
|                         result.Add(new VerifySCPStudyUploadResult() { SCPStudyId = waitUploadItem.Id, ErrorMesseage = _localizer["Study_VisitBeforePrevError", waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")!, before?.ToString("yyyy-MM-dd")!] });
 | |
|                         continue; // 跳过当前迭代
 | |
|                     }
 | |
| 
 | |
|                     //大于当前访视 最近的最早拍片日期  
 | |
|                     var after = visitList.Where(u => u.VisitNum > currentVisitNum).Min(k => k.EarliestScanDate);
 | |
| 
 | |
|                     if (after != null && waitUploadItem.StudyDate != null && after < waitUploadItem.StudyDate)
 | |
|                     {
 | |
|                         // $"当前访视检查时间{waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")}不能晚于该访视之后的检查时间{after?.ToString("yyyy-MM-dd")},请核对检查数据是否有误"
 | |
|                         result.Add(new VerifySCPStudyUploadResult() { SCPStudyId = waitUploadItem.Id, ErrorMesseage = _localizer["Study_VisitAfterSubseqError", waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")!, after?.ToString("yyyy-MM-dd")!] });
 | |
|                         continue; // 跳过当前迭代
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 var verifyStudyInfo = _dicomStudyRepository.Where(t => t.TrialId == trialId && t.Id == waitUploadItem.Id).ProjectTo<VerifyStudyDto>(_mapper.ConfigurationProvider).FirstOrDefault();
 | |
| 
 | |
|                 var currentStudyResult = new VerifySCPStudyUploadResult() { SCPStudyId = waitUploadItem.Id };
 | |
| 
 | |
| 
 | |
|                 //数据库不存在该检查  允许上传
 | |
|                 if (verifyStudyInfo == null)
 | |
|                 {
 | |
|                     currentStudyResult.AllowUpload = true;
 | |
|                 }
 | |
|                 //数据库该项目有该检查  看是否支持重传
 | |
|                 else
 | |
|                 {
 | |
|                     //是同一个受试者  支持重传
 | |
|                     if (verifyStudyInfo.SubjectId == subjectId && verifyStudyInfo.SubjectVisitId == inCommand.SubjectVisitId)
 | |
|                     {
 | |
|                         currentStudyResult.AllowReUpload = true;
 | |
|                     }
 | |
|                     //不是同一个受试者
 | |
|                     else
 | |
|                     {
 | |
|                         //有默认值,其实不用写,这里为了好理解
 | |
|                         currentStudyResult.AllowUpload = false;
 | |
| 
 | |
|                         currentStudyResult.AllowReUpload = false;
 | |
| 
 | |
|                         //$"此处不可以上传。当前影像检查已经上传给受试者{verifyStudyInfo.SubjectCode}的{verifyStudyInfo.VisitName}"
 | |
|                         currentStudyResult.ErrorMesseage = _localizer["Study_ImgAlreadyUploaded", verifyStudyInfo.SubjectCode, verifyStudyInfo.VisitName];
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 result.Add(currentStudyResult);
 | |
|             }
 | |
| 
 | |
| 
 | |
|             return result;
 | |
| 
 | |
| 
 | |
|         }
 | |
| 
 | |
| 
 | |
| 
 | |
|         /// <summary>
 | |
|         ///   提交 患者检查和访视的绑定
 | |
|         /// </summary>
 | |
|         /// <param name="inCommand"></param>
 | |
|         /// <param name="_dicomstudyRepository"></param>
 | |
|         /// <param name="_dicomSeriesRepository"></param>
 | |
|         /// <param name="_dicomInstanceRepository"></param>
 | |
|         /// <returns></returns>
 | |
|         [HttpPost]
 | |
|         [UnitOfWork]
 | |
|         [TrialGlobalLimit( "AfterStopCannNotOpt" )]
 | |
|         public async Task<IResponseOutput> SubmitVisitStudyBinding(SubmitVisitStudyBindingCommand inCommand,
 | |
|             [FromServices] IRepository<DicomStudy> _dicomstudyRepository,
 | |
|             [FromServices] IRepository<DicomSeries> _dicomSeriesRepository,
 | |
|              [FromServices] IRepository<DicomInstance> _dicomInstanceRepository)
 | |
|         {
 | |
| 
 | |
|             //这里要做校验 + 同时验证本地系统里面的影像是否存在pacs推过来的
 | |
| 
 | |
|             var copyCommand = inCommand.Clone();
 | |
|             copyCommand.SCPStudyIdList = inCommand.SCPStudyIdList.Union(inCommand.ReUploadSCPStudyIdList).ToList();
 | |
|             var verifyResult = await VerifyPacsImage(copyCommand);
 | |
| 
 | |
|             var allowUploadList = verifyResult.Where(u => u.AllowUpload == true).Select(t => t.SCPStudyId).ToList();
 | |
|             var allowReUploadList = verifyResult.Where(u => u.AllowReUpload == true).Select(t => t.SCPStudyId).ToList();
 | |
| 
 | |
|             if (!(inCommand.SCPStudyIdList.All(t => allowUploadList.Contains(t)) && inCommand.ReUploadSCPStudyIdList.All(t => allowReUploadList.Contains(t))))
 | |
|             {
 | |
|                 throw new BusinessValidationFailedException("对接提示:  前端提交的检查有不能上传的,请刷新页面调用验证接口重试!");
 | |
|             }
 | |
| 
 | |
|             var subjectId = inCommand.SubjectId;
 | |
|             var subjectVisitId = inCommand.SubjectVisitId;
 | |
|             var trialId = inCommand.TrialId;
 | |
| 
 | |
|             var @lock = _distributedLockProvider.CreateLock($"StudyCode");
 | |
| 
 | |
|             using (await @lock.AcquireAsync())
 | |
|             {
 | |
|                 var dbStudyCodeIntMax = _dicomStudyRepository.Where(s => s.TrialId == inCommand.TrialId).Select(t => t.Code).DefaultIfEmpty().Max();
 | |
| 
 | |
|                 int currentNextCodeInt = dbStudyCodeIntMax + 1;
 | |
| 
 | |
|                 //新增的,上传的
 | |
|                 foreach (var scpStudyId in inCommand.SCPStudyIdList)
 | |
|                 {
 | |
| 
 | |
|                     var find = _scpStudyRepository.Where(t => t.Id == scpStudyId).Select(t => new { SCPStudy = t, t.SeriesList, t.InstanceList }).FirstOrDefault();
 | |
| 
 | |
|                     if (find != null)
 | |
|                     {
 | |
|                         var newStuty = _mapper.Map<DicomStudy>(find.SCPStudy);
 | |
| 
 | |
|                         await _dicomStudyRepository.AddAsync(newStuty);
 | |
| 
 | |
|                         newStuty.SeqId = Guid.Empty;
 | |
|                         newStuty.Code = currentNextCodeInt;
 | |
|                         newStuty.StudyCode = AppSettings.GetCodeStr(currentNextCodeInt, nameof(DicomStudy));
 | |
|                         newStuty.IsFromPACS = true;
 | |
|                         newStuty.TrialId = trialId;
 | |
|                         newStuty.SubjectId = subjectId;
 | |
|                         newStuty.SubjectVisitId = subjectVisitId;
 | |
| 
 | |
|                         var newSeriesList = _mapper.Map<List<DicomSeries>>(find.SeriesList);
 | |
| 
 | |
|                         foreach (var series in newSeriesList)
 | |
|                         {
 | |
| 
 | |
|                             series.SeqId = Guid.Empty;
 | |
|                             series.TrialId = trialId;
 | |
|                             series.SubjectId = subjectId;
 | |
|                             series.SubjectVisitId = subjectVisitId;
 | |
|                         }
 | |
| 
 | |
|                         await _dicomSeriesRepository.AddRangeAsync(newSeriesList);
 | |
| 
 | |
|                         var newInstanceList = _mapper.Map<List<DicomInstance>>(find.InstanceList);
 | |
| 
 | |
|                         foreach (var instance in newInstanceList)
 | |
|                         {
 | |
|                             instance.SeqId = Guid.Empty;
 | |
|                             instance.TrialId = trialId;
 | |
|                             instance.SubjectId = subjectId;
 | |
|                             instance.SubjectVisitId = subjectVisitId;
 | |
| 
 | |
|                         }
 | |
|                         await _dicomInstanceRepository.AddRangeAsync(newInstanceList);
 | |
|                     }
 | |
| 
 | |
|                     currentNextCodeInt++;
 | |
| 
 | |
|                     await _scpPatientRepository.BatchUpdateNoTrackingAsync(t => t.Id == find.SCPStudy.PatientId, u => new SCPPatient() { SubjectId = subjectId });
 | |
|                     await _scpStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == scpStudyId, u => new SCPStudy() { SubjectVisitId = subjectVisitId });
 | |
| 
 | |
| 
 | |
|                 }
 | |
| 
 | |
|                 foreach (var scpStudyId in inCommand.ReUploadSCPStudyIdList)
 | |
|                 {
 | |
| 
 | |
|                     var study = await _dicomstudyRepository.FirstOrDefaultAsync(t => t.Id == scpStudyId);
 | |
| 
 | |
|                     var instanceIdList = _dicomInstanceRepository.Where(t => t.Id == scpStudyId).Select(t => t.Id).ToList();
 | |
| 
 | |
|                     var scpStudy = _scpStudyRepository.Where(t => t.Id == scpStudyId).Include(t => t.SeriesList).ThenInclude(t => t.SCPInstanceList).FirstOrDefault();
 | |
| 
 | |
|                     //以最后一次为准
 | |
|                     study.IsFromPACS = true;
 | |
|                     //特殊处理逻辑
 | |
|                     study.Modalities = string.Join("、", scpStudy.SeriesList.Select(t => t.Modality).Union(study.Modalities.Split("、", StringSplitOptions.RemoveEmptyEntries)).Distinct());
 | |
| 
 | |
|                     SpecialArchiveStudyDeal(study);
 | |
| 
 | |
| 
 | |
|                     // 少了整个序列
 | |
| 
 | |
|                     //某个序列下少了instance
 | |
|                     foreach (var seriesItem in scpStudy.SeriesList)
 | |
|                     {
 | |
|                         var seriesId = IdentifierHelper.CreateGuid(seriesItem.StudyInstanceUid, seriesItem.SeriesInstanceUid, trialId.ToString());
 | |
| 
 | |
|                         DicomSeries dicomSeries = await _dicomSeriesRepository.FirstOrDefaultAsync(t => t.Id == seriesId);
 | |
| 
 | |
|                         //判断重复
 | |
|                         if (dicomSeries == null)
 | |
|                         {
 | |
|                             var series = _mapper.Map<DicomSeries>(seriesItem);
 | |
| 
 | |
|                             series.SeqId = Guid.Empty;
 | |
|                             series.TrialId = trialId;
 | |
|                             series.SubjectId = subjectId;
 | |
|                             series.SubjectVisitId = subjectVisitId;
 | |
| 
 | |
| 
 | |
|                             dicomSeries = await _dicomSeriesRepository.AddAsync(series);
 | |
| 
 | |
| 
 | |
| 
 | |
|                             foreach (var instanceItem in seriesItem.SCPInstanceList)
 | |
|                             {
 | |
|                                 var instance = _mapper.Map<DicomInstance>(instanceItem);
 | |
| 
 | |
|                                 instance.SeqId = Guid.Empty;
 | |
|                                 instance.TrialId = trialId;
 | |
|                                 instance.SubjectId = subjectId;
 | |
|                                 instance.SubjectVisitId = subjectVisitId;
 | |
| 
 | |
|                                 await _dicomInstanceRepository.AddAsync(instance);
 | |
|                             }
 | |
| 
 | |
|                             //新的序列 那么  检查的序列数量+1
 | |
|                             study.SeriesCount += 1;
 | |
| 
 | |
|                             study.InstanceCount += seriesItem.SCPInstanceList.Count;
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             //该序列掉了instance
 | |
|                             dicomSeries.InstanceCount += seriesItem.SCPInstanceList.Count;
 | |
| 
 | |
|                             var newInstanceList = seriesItem.SCPInstanceList.Where(t => !instanceIdList.Contains(t.Id));
 | |
| 
 | |
|                             foreach (var instanceItem in newInstanceList)
 | |
|                             {
 | |
|                                 var instance = _mapper.Map<DicomInstance>(instanceItem);
 | |
| 
 | |
|                                 instance.SeqId = Guid.Empty;
 | |
|                                 instance.TrialId = trialId;
 | |
|                                 instance.SubjectId = subjectId;
 | |
|                                 instance.SubjectVisitId = subjectVisitId;
 | |
| 
 | |
|                                 await _dicomInstanceRepository.AddAsync(instance);
 | |
|                             }
 | |
| 
 | |
|                             study.InstanceCount += newInstanceList.Count();
 | |
| 
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     await _scpPatientRepository.BatchUpdateNoTrackingAsync(t => t.Id == scpStudy.PatientId, u => new SCPPatient() { SubjectId = subjectId });
 | |
|                     await _scpStudyRepository.BatchUpdateNoTrackingAsync(t => t.Id == scpStudyId, u => new SCPStudy() { SubjectVisitId = subjectVisitId });
 | |
|                 }
 | |
| 
 | |
| 
 | |
|             }
 | |
| 
 | |
| 
 | |
| 
 | |
|             await _scpStudyRepository.SaveChangesAsync();
 | |
| 
 | |
| 
 | |
|             return ResponseOutput.Ok();
 | |
|         }
 | |
| 
 | |
| 
 | |
|         private void SpecialArchiveStudyDeal(DicomStudy study)
 | |
|         {
 | |
|             #region 特殊逻辑
 | |
| 
 | |
| 
 | |
|             if (study.PatientBirthDate.Length == 8)
 | |
|             {
 | |
|                 study.PatientBirthDate = $"{study.PatientBirthDate[0]}{study.PatientBirthDate[1]}{study.PatientBirthDate[2]}{study.PatientBirthDate[3]}-{study.PatientBirthDate[4]}{study.PatientBirthDate[5]}-{study.PatientBirthDate[6]}{study.PatientBirthDate[7]}";
 | |
|             }
 | |
| 
 | |
|             var dicModalityList = _dictionaryRepository.Where(t => t.Code == "Modality").SelectMany(t => t.ChildList.Select(c => c.Value)).ToList();
 | |
| 
 | |
| 
 | |
|             var modality = study.Modalities;
 | |
| 
 | |
|             var modalityForEdit = dicModalityList.Contains(modality) ? modality : String.Empty;
 | |
| 
 | |
|             if (modality == "MR")
 | |
|             {
 | |
|                 modalityForEdit = "MRI";
 | |
|             }
 | |
| 
 | |
|             if (modality == "PT")
 | |
|             {
 | |
|                 modalityForEdit = "PET";
 | |
|             }
 | |
|             if (modality == "PT、CT")
 | |
|             {
 | |
|                 modalityForEdit = "PET-CT";
 | |
|             }
 | |
| 
 | |
|             study.ModalityForEdit = modalityForEdit;
 | |
|             #endregion
 | |
|         }
 | |
| 
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|     }
 | |
| 
 | |
| 
 | |
| 
 | |
| }
 |