//--------------------------------------------------------------------
// 此代码由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 IRaCIS.Core.Infra.EFCore;
using Newtonsoft.Json;
using IRaCIS.Core.Application.Service.Inspection.Interface;
using IRaCIS.Core.Application.Service.Inspection.DTO;
namespace IRaCIS.Core.Application.Contracts
{
///
/// NoneDicomStudyService
///
[ApiExplorerSettings(GroupName = "Image")]
public class NoneDicomStudyService : BaseService, INoneDicomStudyService
{
private readonly IRepository _noneDicomStudyRepository;
private readonly IHttpContextAccessor _httpContext;
private readonly IWebHostEnvironment _hostEnvironment;
private readonly IInspectionService _inspectionService;
private readonly IRepository _noneDicomStudyFileRepository;
public NoneDicomStudyService(IRepository noneDicomStudyRepository,
IHttpContextAccessor httpContext,
IWebHostEnvironment hostEnvironment,
IInspectionService inspectionService,
IRepository noneDicomStudyFileRepository)
{
_noneDicomStudyRepository = noneDicomStudyRepository;
this._httpContext = httpContext;
this._hostEnvironment = hostEnvironment;
this._inspectionService = inspectionService;
_noneDicomStudyFileRepository = noneDicomStudyFileRepository;
}
[HttpGet("{subjectVisitId:guid}")]
public async Task> GetNoneDicomStudyList(Guid subjectVisitId)
{
var noneDicomStudyQueryable = _noneDicomStudyRepository.Where(t => t.SubjectVisitId == subjectVisitId)
.ProjectTo(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken });
return await noneDicomStudyQueryable.ToListAsync();
}
[UnitOfWork]
[TypeFilter(typeof(TrialResourceFilter))]
public async Task> AddOrUpdateNoneDicomStudy(NoneDicomStudyAddOrEdit addOrEditNoneDicomStudy)
{
var entity = await _noneDicomStudyRepository.InsertOrUpdateAsync(addOrEditNoneDicomStudy, false);
if (_repository.Entry(entity).State == Microsoft.EntityFrameworkCore.EntityState.Added)
{
entity.Code = _noneDicomStudyRepository.Where(t => t.TrialId == addOrEditNoneDicomStudy.TrialId).Select(t => t.Code).DefaultIfEmpty().Max() + 1;
}
entity.StudyCode = "NST" + entity.Code.ToString("D5");
await _repository.SaveChangesAsync();
var svTime = _repository.Where(t => t.Id == addOrEditNoneDicomStudy.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().IfNullThrowException();
var minArray = new DateTime?[] { svTime.DicomStudyMinStudyTime, svTime.NoneDicomStudyMinStudyTime, addOrEditNoneDicomStudy.ImageDate };
var maxArray = new DateTime?[] { svTime.DicomStudyMaxStudyTime, svTime.NoneDicomStudyMaxStudyTime, addOrEditNoneDicomStudy.ImageDate };
await _repository.BatchUpdateAsync(t => t.Id == addOrEditNoneDicomStudy.SubjectVisitId, u => new SubjectVisit()
{
VisitExecuted = VisitExecutedEnum.Executed,
EarliestScanDate = minArray.Min(),
LatestScanDate = maxArray.Max()
});
await _repository.SaveChangesAsync();
NoneDicomStudyAddReturnDto noneDicom = new NoneDicomStudyAddReturnDto()
{
StudyCode= entity.StudyCode,
Id= entity.Id
};
return ResponseOutput.Ok(noneDicom);
}
[TypeFilter(typeof(TrialResourceFilter))]
[HttpDelete("{noneDicomStudyId:guid}/{trialId:guid}")]
public async Task DeleteNoneDicomStudy(Guid noneDicomStudyId)
{
if (_noneDicomStudyRepository.Where(t => t.Id == noneDicomStudyId)
.Any(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.BatchDeleteAsync(t => t.Id == noneDicomStudyId);
await _noneDicomStudyFileRepository.BatchDeleteAsync(t => t.NoneDicomStudyId == noneDicomStudyId);
var svTime = await _repository.Where(t => t.Id == noneDicomStudy.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)
}).FirstOrDefaultAsync().IfNullThrowException();
var minArray = new DateTime?[] { svTime.DicomStudyMinStudyTime, svTime.NoneDicomStudyMinStudyTime };
var maxArray = new DateTime?[] { svTime.DicomStudyMaxStudyTime, svTime.NoneDicomStudyMaxStudyTime };
await _repository.BatchUpdateAsync(t => t.Id == noneDicomStudy.SubjectVisitId, u => new SubjectVisit()
{
EarliestScanDate = minArray.Min(),
LatestScanDate = maxArray.Max()
});
//如果既没有 dicom数据 也没有非dicom 文件 那么提交状态变更回去
if (await _repository.CountAsync(t => t.SubjectVisitId == noneDicomStudy.SubjectVisitId) == 0 && await _repository.CountAsync(t => t.NoneDicomStudy.SubjectVisitId == noneDicomStudy.SubjectVisitId) == 0)
{
await _repository.BatchUpdateAsync(t => t.Id == noneDicomStudy.SubjectVisitId && t.SubmitState == SubmitStateEnum.ToSubmit, u => new SubjectVisit() { VisitExecuted = 0, SubmitState = SubmitStateEnum.None });
}
return ResponseOutput.Ok();
}
[HttpDelete("{noneDicomStudyFileId:guid}")]
public async Task 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);
//如果既没有 dicom数据 也没有非dicom 文件 那么提交状态变更回去
if (await _repository.CountAsync(t => t.SubjectVisitId == subjectVisitId) == 0 && await _repository.CountAsync(t => t.NoneDicomStudy.SubjectVisitId == subjectVisitId) == 0)
{
await _repository.BatchUpdateAsync(t => t.Id == subjectVisitId && t.SubmitState == SubmitStateEnum.ToSubmit, u => new SubjectVisit() { VisitExecuted = 0, SubmitState = SubmitStateEnum.None });
}
var subvisit = await _repository.GetQueryable().FirstOrDefaultAsync(x => x.Id == subjectVisitId);
List datas = new List();
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(new
{
SubmitState = "待提交",
})
});
await _inspectionService.AddListInspectionRecordAsync(datas);
return ResponseOutput.Ok();
}
///
/// 非Dicom检查 文件列表
///
///
///
[HttpGet("{noneDicomStudyId:guid}")]
public async Task> GetNoneDicomStudyFileList(Guid noneDicomStudyId)
{
return await _noneDicomStudyFileRepository.Where(t => t.NoneDicomStudyId == noneDicomStudyId)
.ProjectTo(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken }).ToListAsync();
}
[HttpGet("{subjectVisitId:guid}")]
public async Task> GetVisitNoneDicomStudyFileList(Guid subjectVisitId)
{
return await _repository.Where(t => t.NoneDicomStudy.SubjectVisitId == subjectVisitId).ProjectTo(_mapper.ConfigurationProvider, new { token = _userInfo.UserToken }).ToListAsync();
}
///
/// 上传非Dicom 文件 支持压缩包
///
[HttpPost]
public async Task 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(fileDto.AuditInfo);
data.GeneralId = fileDto.noneDicomStudyId;
await _inspectionService.AddInspectionRecordAsync(data);
var subvisit =await _repository.GetQueryable().FirstOrDefaultAsync(x => x.Id == fileDto.subjectVisitId);
List datas = new List();
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(new
{
SubmitState = "待提交",
})
});
await _inspectionService.AddListInspectionRecordAsync(datas);
}
return result;
}
///
/// 上传非Dicom 文件 支持压缩包
///
///
///
///
///
///
//[DisableRequestSizeLimit]
[RequestSizeLimit(1_073_741_824)]
[HttpPost("{noneDicomStudyId:guid}/{subjectVisitId:guid}")]
public async Task 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(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(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 });
}
}
}