irc-netcore-api/IRaCIS.Core.Application/Service/QC/NoneDicomStudyService.cs

321 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//--------------------------------------------------------------------
// 此代码由T4模板自动生成 byzhouhang 20210918
// 生成时间 2021-12-06 10:54:55
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
//--------------------------------------------------------------------
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using IRaCIS.Core.Domain.Share;
using SharpCompress.Archives;
using IRaCIS.Core.Application.Filter;
using Newtonsoft.Json;
using IRaCIS.Core.Application.Service.Inspection.Interface;
using IRaCIS.Core.Application.Service.Inspection.DTO;
using Nito.AsyncEx;
using IRaCIS.Application.Interfaces;
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<NoneDicomStudyFile> _noneDicomStudyFileRepository;
private readonly AsyncLock _mutex = new AsyncLock();
public NoneDicomStudyService(IRepository<NoneDicomStudy> noneDicomStudyRepository,
IHttpContextAccessor httpContext,
IDictionaryService dictionaryService,
IInspectionService inspectionService,
IRepository<NoneDicomStudyFile> noneDicomStudyFileRepository)
{
_noneDicomStudyRepository = noneDicomStudyRepository;
this._httpContext = httpContext;
this._dictionaryService = dictionaryService;
this._inspectionService = inspectionService;
_noneDicomStudyFileRepository = noneDicomStudyFileRepository;
}
[HttpGet("{subjectVisitId:guid}")]
public async Task<List<NoneDicomStudyView>> GetNoneDicomStudyList(Guid subjectVisitId)
{
var noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId)
.ProjectTo<NoneDicomStudyView>(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken });
return await noneDicomStudyQueryable.ToListAsync();
}
[UnitOfWork]
[TypeFilter(typeof(TrialResourceFilter))]
public async Task<IResponseOutput<NoneDicomStudyAddReturnDto>> AddOrUpdateNoneDicomStudy(NoneDicomStudyAddOrEdit addOrEditNoneDicomStudy)
{
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("{noneDicomStudyId:guid}/{trialId:guid}")]
public async Task<IResponseOutput> DeleteNoneDicomStudy(Guid noneDicomStudyId)
{
if (_noneDicomStudyRepository.Where(t => t.Id == noneDicomStudyId).SelectMany(t => t.NoneDicomFileList).Count() > 0)
{
return ResponseOutput.NotOk("先移除文件才允许删除非Dicom");
}
var noneDicomStudy = await _noneDicomStudyRepository.FirstOrDefaultAsync(t => t.Id == noneDicomStudyId);
if (noneDicomStudy == null) return Null404NotFound(noneDicomStudy);
await _noneDicomStudyRepository.DeleteAsync(noneDicomStudy);
await _noneDicomStudyFileRepository.BatchDeleteAsync(t => t.NoneDicomStudyId == noneDicomStudyId);
await _repository.BatchDeleteAsync<StudyMonitor>(t => t.StudyId == noneDicomStudyId);
return ResponseOutput.Ok();
}
[HttpDelete("{noneDicomStudyFileId:guid}")]
public async Task<IResponseOutput> DeleteNoneDicomStudyFile(Guid noneDicomStudyFileId)
{
var subjectVisitId = await _noneDicomStudyFileRepository.Where(t => t.Id == noneDicomStudyFileId).Select(t => t.NoneDicomStudy.SubjectVisitId).FirstOrDefaultAsync();
var success = await _noneDicomStudyFileRepository.BatchDeleteAsync(t => t.Id == noneDicomStudyFileId);
var subvisit = await _repository.GetQueryable<SubjectVisit>().FirstOrDefaultAsync(x => x.Id == subjectVisitId);
List<DataInspection> datas = new List<DataInspection>();
datas.Add(new DataInspection()
{
SiteId = subvisit.SiteId,
SubjectId = subvisit.SubjectId,
TrialId = subvisit.TrialId,
SubjectVisitId = subvisit.Id,
Identification = "Edit|Visit|Status|Visit-Image Upload|Add Image",
JsonDetail = JsonConvert.SerializeObject(subvisit)
});
await _inspectionService.AddListInspectionRecordAsync(datas);
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>
[HttpPost]
public async Task<IResponseOutput> NewUploadNoneDicomFile([FromForm] UploadNoneDicomFileDto fileDto)
{
var file = this._httpContext.HttpContext?.Request.Form;
var result = await UploadNoneDicomFile(file, fileDto.subjectVisitId, fileDto.noneDicomStudyId);
if (result.IsSuccess)
{
var data = JsonConvert.DeserializeObject<DataInspectionAddDTO>(fileDto.AuditInfo);
data.GeneralId = fileDto.noneDicomStudyId;
await _inspectionService.AddInspectionRecordAsync(data);
var subvisit = await _repository.GetQueryable<SubjectVisit>().FirstOrDefaultAsync(x => x.Id == fileDto.subjectVisitId);
List<DataInspection> datas = new List<DataInspection>();
datas.Add(new DataInspection()
{
SiteId = subvisit.SiteId,
SubjectId = subvisit.SubjectId,
TrialId = subvisit.TrialId,
SubjectVisitId = subvisit.Id,
Identification = "Edit|Visit|Status|Visit-Image Upload|Add Image",
JsonDetail = JsonConvert.SerializeObject(subvisit)
});
await _inspectionService.AddListInspectionRecordAsync(datas);
}
return result;
}
/// <summary>
/// 上传非Dicom 文件 支持压缩包
/// </summary>
/// <param name="formCollection"></param>
/// <param name="subjectVisitId"></param>
/// <param name="noneDicomStudyId"></param>
/// <returns></returns>
//[DisableRequestSizeLimit]
[RequestSizeLimit(1_073_741_824)]
[HttpPost("{noneDicomStudyId:guid}/{subjectVisitId:guid}")]
public async Task<IResponseOutput> UploadNoneDicomFile(IFormCollection formCollection, Guid subjectVisitId, Guid noneDicomStudyId)
{
var rootPath = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).IfNullThrowException().FullName;
//上传根路径
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 = 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 = file.FileName, Path = relativePath, NoneDicomStudyId = noneDicomStudyId });
}
}
// 上传非Dicom 后 将状态改为待提交 分为普通上传 和QC后重传 普通上传时才改为待提交
await _repository.BatchUpdateAsync<SubjectVisit>(t => t.Id == subjectVisitId && t.SubmitState == SubmitStateEnum.None, u => new SubjectVisit() { SubmitState = SubmitStateEnum.ToSubmit });
await _repository.AddAsync(new StudyMonitor()
{
FileCount = formCollection.Files.Count,
FileSize = formCollection.Files.Sum(t => t.Length),
IsDicom = false,
IsDicomReUpload = false,
StudyId = noneDicomStudyId,
UploadStartTime = startTime,
UploadFinishedTime = DateTime.Now,
IP = _userInfo.IP,
TrialId = sv.TrialId,
SiteId = sv.SiteId,
SubjectId = sv.SubjectId,
SubjectVisitId = subjectVisitId,
});
await _repository.SaveChangesAsync();
return ResponseOutput.Ok(/*list*/);
}
private string GetStoreFileName(string fileName)
{
var realName = fileName;
var fileNameEX = Path.GetExtension(realName);
var trustedFileNameForFileStorage = Guid.NewGuid().ToString() + fileNameEX;
return trustedFileNameForFileStorage;
}
private async void DealCompressFile(IArchiveEntry entry, dynamic sv, Guid subjectVisitId, Guid noneDicomStudyId, string uploadFolderPath)
{
var trustedFileNameForFileStorage = 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);
var fileName = string.Empty;
if (entry.Key.Contains("\\"))
{
fileName = entry.Key.Split("\\").Last();
}
await _repository.AddAsync(new NoneDicomStudyFile() { FileName = fileName, Path = relativePath, NoneDicomStudyId = noneDicomStudyId });
}
}
}