287 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			287 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
| //--------------------------------------------------------------------
 | |
| //     此代码由T4模板自动生成  byzhouhang 20210918
 | |
| //	   生成时间 2021-12-06 10:54:55 
 | |
| //     对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
 | |
| //--------------------------------------------------------------------
 | |
| using Microsoft.AspNetCore.Mvc;
 | |
| using Microsoft.AspNetCore.Http;
 | |
| using IRaCIS.Core.Domain.Share;
 | |
| using SharpCompress.Archives;
 | |
| using IRaCIS.Core.Application.Filter;
 | |
| using IRaCIS.Core.Application.Service.Inspection.Interface;
 | |
| using Nito.AsyncEx;
 | |
| using IRaCIS.Application.Interfaces;
 | |
| using IRaCIS.Core.Infrastructure;
 | |
| using Microsoft.Extensions.Logging;
 | |
| using System.ComponentModel.DataAnnotations;
 | |
| using IRaCIS.Core.Application.Helper;
 | |
| using IRaCIS.Core.Application.Service.Verify;
 | |
| using Microsoft.AspNetCore.Authorization;
 | |
| using IRaCIS.Core.Application.Auth;
 | |
| 
 | |
| namespace IRaCIS.Core.Application.Contracts
 | |
| {
 | |
|     /// <summary>
 | |
|     /// NoneDicomStudyService
 | |
|     /// </summary>	
 | |
|     [ApiExplorerSettings(GroupName = "Image")]
 | |
|     public class NoneDicomStudyService : BaseService, INoneDicomStudyService
 | |
|     {
 | |
|         private readonly IRepository<NoneDicomStudy> _noneDicomStudyRepository;
 | |
|         private readonly IHttpContextAccessor _httpContext;
 | |
|         private readonly IDictionaryService _dictionaryService;
 | |
|         private readonly IInspectionService _inspectionService;
 | |
|         private readonly IRepository<StudyMonitor> _studyMonitorRepository;
 | |
|         private readonly IRepository<NoneDicomStudyFile> _noneDicomStudyFileRepository;
 | |
|         private readonly IRepository<SubjectVisit> _subjectVisitRepository;
 | |
|         private readonly AsyncLock _mutex = new AsyncLock();
 | |
| 
 | |
|         private readonly ILogger<NoneDicomStudyService> _logger;
 | |
| 
 | |
| 
 | |
|         public NoneDicomStudyService(IRepository<NoneDicomStudy> noneDicomStudyRepository,
 | |
|             IHttpContextAccessor httpContext,
 | |
|             IDictionaryService dictionaryService,
 | |
|             IInspectionService inspectionService,
 | |
|             IRepository<StudyMonitor> studyMonitorRepository,
 | |
|             IRepository<NoneDicomStudyFile> noneDicomStudyFileRepository, IRepository<SubjectVisit> subjectVisitRepository, ILogger<NoneDicomStudyService> logger)
 | |
|         {
 | |
|             _noneDicomStudyRepository = noneDicomStudyRepository;
 | |
| 
 | |
|             this._httpContext = httpContext;
 | |
|             this._dictionaryService = dictionaryService;
 | |
|             this._inspectionService = inspectionService;
 | |
|             this._studyMonitorRepository = studyMonitorRepository;
 | |
|             _noneDicomStudyFileRepository = noneDicomStudyFileRepository;
 | |
|             this._subjectVisitRepository = subjectVisitRepository;
 | |
| 
 | |
|             _logger = logger;
 | |
|         }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         [HttpGet]
 | |
|         public async Task<List<NoneDicomStudyView>> GetNoneDicomStudyList( [FromQuery,NotDefault] Guid subjectVisitId,Guid? nonedicomStudyId)
 | |
|         {
 | |
| 
 | |
|             var noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId).WhereIf(nonedicomStudyId!=null , t => t.Id== nonedicomStudyId)
 | |
| 
 | |
|                 .ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken });
 | |
| 
 | |
|             return await noneDicomStudyQueryable.ToListAsync();
 | |
|         }
 | |
| 
 | |
| 
 | |
|         [UnitOfWork]
 | |
|         [TypeFilter(typeof(TrialResourceFilter))]
 | |
|         public async Task<IResponseOutput<NoneDicomStudyAddReturnDto>> AddOrUpdateNoneDicomStudy(NoneDicomStudyAddOrEdit addOrEditNoneDicomStudy)
 | |
|         {
 | |
| 
 | |
|             await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, addOrEditNoneDicomStudy.SubjectVisitId);
 | |
| 
 | |
|             await QCCommonVerify.VerifyStudyImageDataAsync(_repository, addOrEditNoneDicomStudy.SubjectId, addOrEditNoneDicomStudy.SubjectVisitId, addOrEditNoneDicomStudy.ImageDate);
 | |
| 
 | |
|       
 | |
|             NoneDicomStudy? optEntity = null;
 | |
|             using (await _mutex.LockAsync())
 | |
|             {
 | |
|                 if (addOrEditNoneDicomStudy.Id == Guid.Empty || addOrEditNoneDicomStudy.Id == null)
 | |
|                 {
 | |
|                     //默认会是0  
 | |
|                     var code = await _noneDicomStudyRepository.Where(t => t.TrialId == addOrEditNoneDicomStudy.TrialId).Select(x => x.Code).DefaultIfEmpty().MaxAsync();
 | |
| 
 | |
|                     addOrEditNoneDicomStudy.Code = code + 1;
 | |
| 
 | |
|                     optEntity = await _noneDicomStudyRepository.InsertFromDTOAsync(addOrEditNoneDicomStudy);
 | |
| 
 | |
|                     optEntity.StudyCode = "NST" + optEntity.Code.ToString("D5");
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|            
 | |
|                     optEntity = await _noneDicomStudyRepository.UpdateFromDTOAsync(addOrEditNoneDicomStudy);
 | |
|                 }
 | |
| 
 | |
|                 await _noneDicomStudyRepository.SaveChangesAsync();
 | |
|             }
 | |
| 
 | |
| 
 | |
|             NoneDicomStudyAddReturnDto noneDicom = new NoneDicomStudyAddReturnDto()
 | |
|             {
 | |
|                 StudyCode = optEntity.StudyCode,
 | |
|                 Id = optEntity.Id
 | |
|             };
 | |
|             return ResponseOutput.Ok(noneDicom);
 | |
| 
 | |
|         }
 | |
| 
 | |
|         [TypeFilter(typeof(TrialResourceFilter))]
 | |
|         [HttpDelete("{trialId:guid}/{subjectVisitId:guid}/{noneDicomStudyId:guid}")]
 | |
|         public async Task<IResponseOutput> DeleteNoneDicomStudy(Guid noneDicomStudyId, Guid subjectVisitId)
 | |
|         {
 | |
|             //提交了 但是IQC同意的时候 是可以删除的 | 普通提交后也不能删除
 | |
| 
 | |
| 
 | |
|             await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository,_userInfo, subjectVisitId);
 | |
| 
 | |
|             await _noneDicomStudyRepository.DeleteFromQueryAsync(noneDicomStudyId);
 | |
| 
 | |
|             await _noneDicomStudyFileRepository.DeleteFromQueryAsync(t => t.NoneDicomStudyId == noneDicomStudyId);
 | |
| 
 | |
|             //确认需求 不删除
 | |
|             //await _studyMonitorRepository.BatchDeleteNoTrackingAsync(t => t.StudyId == noneDicomStudyId);
 | |
| 
 | |
|             await _noneDicomStudyRepository.SaveChangesAsync();
 | |
| 
 | |
|             return ResponseOutput.Ok();
 | |
|         }
 | |
| 
 | |
| 
 | |
|         [HttpDelete("{trialId:guid}/{subjectVisitId:guid}/{noneDicomStudyFileId:guid}")]
 | |
|         [TypeFilter(typeof(TrialResourceFilter))]
 | |
|         public async Task<IResponseOutput> DeleteNoneDicomStudyFile(Guid noneDicomStudyFileId, Guid subjectVisitId)
 | |
|         {
 | |
|             //提交了 但是IQC同意的时候 是可以删除的 | 普通提交后也不能删除
 | |
|             await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
 | |
| 
 | |
|             var success = await _noneDicomStudyFileRepository.DeleteFromQueryAsync(t => t.Id == noneDicomStudyFileId, true);
 | |
| 
 | |
|             return ResponseOutput.Ok();
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 非Dicom检查 文件列表
 | |
|         /// </summary>
 | |
|         /// <param name="noneDicomStudyId"></param>
 | |
|         /// <returns></returns>
 | |
|         [HttpGet("{noneDicomStudyId:guid}")]
 | |
|         public async Task<List<NoneDicomStudyFileView>> GetNoneDicomStudyFileList(Guid noneDicomStudyId)
 | |
|         {
 | |
|             return await _noneDicomStudyFileRepository.Where(t => t.NoneDicomStudyId == noneDicomStudyId)
 | |
|                 .ProjectTo<NoneDicomStudyFileView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken }).ToListAsync();
 | |
|         }
 | |
| 
 | |
|         [HttpGet("{subjectVisitId:guid}")]
 | |
|         public async Task<List<NoneDicomStudyFileView>> GetVisitNoneDicomStudyFileList(Guid subjectVisitId)
 | |
|         {
 | |
|             return await _repository.Where<NoneDicomStudyFile>(t => t.NoneDicomStudy.SubjectVisitId == subjectVisitId)
 | |
|                 .ProjectTo<NoneDicomStudyFileView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken }).ToListAsync();
 | |
|         }
 | |
| 
 | |
| 
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 上传非Dicom 文件 支持压缩包
 | |
|         /// </summary>
 | |
|         /// <param name="formCollection"></param>
 | |
|         /// <param name="subjectVisitId"></param>
 | |
|         /// <param name="noneDicomStudyId"></param>
 | |
|         /// <returns></returns>
 | |
|         //[DisableRequestSizeLimit]
 | |
|         [RequestSizeLimit(1_073_741_824)]
 | |
|         [HttpPost("{trialId:guid}/{subjectVisitId:guid}/{noneDicomStudyId:guid}")]
 | |
|         [TypeFilter(typeof(TrialResourceFilter))]
 | |
|         [Authorize(Policy = IRaCISPolicy.CRC)]
 | |
|         public async Task<IResponseOutput> UploadNoneDicomFile(IFormCollection formCollection, Guid subjectVisitId, Guid noneDicomStudyId)
 | |
|         {
 | |
|             await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
 | |
| 
 | |
|             var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
 | |
| 
 | |
|             //上传根路径
 | |
|             var _fileStorePath = Path.Combine(rootPath, StaticData.TrialDataFolder);
 | |
| 
 | |
|             var sv = (await _repository.Where<SubjectVisit>(t => t.Id == subjectVisitId).Select(t => new { t.TrialId, t.SiteId, t.SubjectId }).FirstOrDefaultAsync()).IfNullThrowConvertException();
 | |
| 
 | |
|             string uploadFolderPath = Path.Combine(_fileStorePath, sv.TrialId.ToString(), sv.SiteId.ToString(), sv.SubjectId.ToString(), subjectVisitId.ToString(), StaticData.NoneDicomFolder);
 | |
| 
 | |
|             if (!Directory.Exists(uploadFolderPath))
 | |
|             {
 | |
|                 Directory.CreateDirectory(uploadFolderPath);
 | |
|             }
 | |
| 
 | |
|             var startTime = DateTime.Now;
 | |
| 
 | |
|             foreach (IFormFile file in formCollection.Files)
 | |
|             {
 | |
|                 if (file.FileName.Contains(".Zip", StringComparison.OrdinalIgnoreCase) || file.FileName.Contains(".rar", StringComparison.OrdinalIgnoreCase))
 | |
|                 {
 | |
|                     var archive = ArchiveFactory.Open(file.OpenReadStream());
 | |
| 
 | |
|                     foreach (var entry in archive.Entries)
 | |
|                     {
 | |
|                         if (!entry.IsDirectory)
 | |
|                         {
 | |
|                             DealCompressFile(entry, sv, subjectVisitId, noneDicomStudyId, uploadFolderPath);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
| 
 | |
|                    
 | |
| 
 | |
| 
 | |
|                     var (trustedFileNameForFileStorage, fileName) = FileStoreHelper.GetStoreFileName(file.FileName);
 | |
| 
 | |
|                     var relativePath = $"/{StaticData.TrialDataFolder}/{sv.TrialId}/{sv.SiteId}/{sv.SubjectId}/{subjectVisitId}/{StaticData.NoneDicomFolder}/{trustedFileNameForFileStorage}";
 | |
| 
 | |
|                     var filePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
 | |
| 
 | |
|                     using (FileStream fs = System.IO.File.Create(filePath))
 | |
|                     {
 | |
|                         await file.CopyToAsync(fs);
 | |
|                         await fs.FlushAsync();
 | |
|                     }
 | |
| 
 | |
|                     await _noneDicomStudyFileRepository.AddAsync(new NoneDicomStudyFile() { FileName = fileName, Path = relativePath, NoneDicomStudyId = noneDicomStudyId });
 | |
| 
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             // 上传非Dicom 后  将状态改为待提交 分为普通上传 和QC后重传  普通上传时才改为待提交
 | |
|             await _subjectVisitRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectVisitId && t.SubmitState == SubmitStateEnum.None, u => new SubjectVisit() { SubmitState = SubmitStateEnum.ToSubmit });
 | |
| 
 | |
|             var studyCode = await _noneDicomStudyRepository.Where(t => t.Id == noneDicomStudyId).Select(t => t.StudyCode).FirstOrDefaultAsync();
 | |
| 
 | |
|             await _studyMonitorRepository.AddAsync(new StudyMonitor()
 | |
|             {
 | |
|                 FileCount = formCollection.Files.Count,
 | |
|                 FileSize = formCollection.Files.Sum(t => t.Length),
 | |
|                 IsDicom = false,
 | |
|                 IsDicomReUpload = false,
 | |
|                 StudyId = noneDicomStudyId,
 | |
|                 StudyCode = studyCode,
 | |
|                 UploadStartTime = startTime,
 | |
|                 UploadFinishedTime = DateTime.Now,
 | |
|                 IP = _userInfo.IP,
 | |
|                 TrialId = sv.TrialId,
 | |
|                 SiteId = sv.SiteId,
 | |
|                 SubjectId = sv.SubjectId,
 | |
|                 SubjectVisitId = subjectVisitId,
 | |
|             });
 | |
| 
 | |
|             await _noneDicomStudyFileRepository.SaveChangesAsync();
 | |
| 
 | |
|             return ResponseOutput.Ok(/*list*/);
 | |
|         }
 | |
| 
 | |
| 
 | |
| 
 | |
|         private async void DealCompressFile(IArchiveEntry entry, dynamic sv, Guid subjectVisitId, Guid noneDicomStudyId, string uploadFolderPath)
 | |
|         {
 | |
|             var (trustedFileNameForFileStorage, fileName)   = FileStoreHelper.GetStoreFileName(entry.Key); 
 | |
| 
 | |
|             var relativePath = $"/{StaticData.TrialDataFolder}/{sv.TrialId}/{sv.SiteId}/{sv.SubjectId}/{subjectVisitId}/{StaticData.NoneDicomFolder}/{trustedFileNameForFileStorage}";
 | |
| 
 | |
|             var filePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
 | |
| 
 | |
|             entry.WriteToFile(filePath);
 | |
|          
 | |
|             await _noneDicomStudyFileRepository.AddAsync(new NoneDicomStudyFile() { FileName = fileName, Path = relativePath, NoneDicomStudyId = noneDicomStudyId });
 | |
|         }
 | |
| 
 | |
|     }
 | |
| }
 |