406 lines
16 KiB
C#
406 lines
16 KiB
C#
using AutoMapper;
|
|
using IRaCIS.Core.Application.Contracts;
|
|
using IRaCIS.Core.Application.Filter;
|
|
using IRaCIS.Core.Application.Helper;
|
|
using IRaCIS.Core.Domain.Models;
|
|
using IRaCIS.Core.Domain.Share;
|
|
using IRaCIS.Core.Infra.EFCore;
|
|
using IRaCIS.Core.Infrastructure.Extention;
|
|
using MediatR;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.WebUtilities;
|
|
using Microsoft.Net.Http.Headers;
|
|
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace IRaCIS.Core.API.Controllers
|
|
{
|
|
[ApiExplorerSettings(GroupName = "Trial")]
|
|
[ApiController]
|
|
public class UploadController : ControllerBase
|
|
{
|
|
public IMapper _mapper { get; set; }
|
|
public IUserInfo _userInfo { get; set; }
|
|
private readonly IMediator _mediator;
|
|
|
|
private readonly IWebHostEnvironment _hostEnvironment;
|
|
|
|
private readonly IServiceProvider _serviceProvider;
|
|
|
|
|
|
public UploadController(IMapper mapper, IUserInfo userInfo, IMediator mediator, IWebHostEnvironment hostEnvironment, IServiceProvider serviceProvider)
|
|
{
|
|
_serviceProvider = serviceProvider;
|
|
_hostEnvironment = hostEnvironment;
|
|
_mediator = mediator;
|
|
_mapper = mapper;
|
|
_userInfo = userInfo;
|
|
}
|
|
|
|
[HttpPost("TrialDocument/UploadTrialDoc/{trialId:guid}")]
|
|
[DisableRequestSizeLimit]
|
|
[DisableFormValueModelBinding]
|
|
public async Task<IResponseOutput> UploadTrialDoc(Guid trialId)
|
|
{
|
|
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)
|
|
{
|
|
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
|
|
|
|
if (hasContentDispositionHeader)
|
|
{
|
|
|
|
DealTrialStorePath(trialId, contentDisposition.FileName.Value, out string serverFilePath, out string relativePath );
|
|
|
|
await WriteFileAsync(section.Body, serverFilePath);
|
|
|
|
//仅仅返回一个文件,如果多文件上传 在最后返回多个路径
|
|
return ResponseOutput.Ok(new
|
|
{
|
|
FilePath = relativePath,
|
|
FullFilePath = relativePath + "?access_token=" + _userInfo.UserToken
|
|
});
|
|
|
|
}
|
|
section = await reader.ReadNextSectionAsync();
|
|
}
|
|
return ResponseOutput.Ok();
|
|
}
|
|
|
|
|
|
[HttpPost("TrialDocument/UploadSystemDoc")]
|
|
[DisableRequestSizeLimit]
|
|
[DisableFormValueModelBinding]
|
|
public async Task<IResponseOutput> UploadSysTemDoc( )
|
|
{
|
|
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)
|
|
{
|
|
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
|
|
|
|
if (hasContentDispositionHeader)
|
|
{
|
|
|
|
DealSysTemStorePath( contentDisposition.FileName.Value, out string serverFilePath, out string relativePath);
|
|
|
|
await WriteFileAsync(section.Body, serverFilePath);
|
|
|
|
//仅仅返回一个文件,如果多文件上传 在最后返回多个路径
|
|
return ResponseOutput.Ok(new
|
|
{
|
|
FilePath = relativePath,
|
|
FullFilePath = relativePath + "?access_token=" + _userInfo.UserToken
|
|
});
|
|
|
|
}
|
|
section = await reader.ReadNextSectionAsync();
|
|
}
|
|
return ResponseOutput.Ok();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 上传通用文档 比如一致性核查的 比如导出的excel 模板
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpPost("CommonDocument/UploadCommonDoc")]
|
|
[DisableRequestSizeLimit]
|
|
[DisableFormValueModelBinding]
|
|
public async Task<IResponseOutput> UploadCommonDoc(/*string fileType, string moduleType*/)
|
|
{
|
|
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)
|
|
{
|
|
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
|
|
|
|
if (hasContentDispositionHeader)
|
|
{
|
|
|
|
DealCommonStorePath(/*fileType, moduleType,*/ contentDisposition.FileName.Value, out string serverFilePath, out string relativePath);
|
|
|
|
await WriteFileAsync(section.Body, serverFilePath);
|
|
|
|
//仅仅返回一个文件,如果多文件上传 在最后返回多个路径
|
|
return ResponseOutput.Ok(new
|
|
{
|
|
FilePath = relativePath,
|
|
FullFilePath = relativePath + "?access_token=" + _userInfo.UserToken
|
|
});
|
|
|
|
}
|
|
section = await reader.ReadNextSectionAsync();
|
|
}
|
|
return ResponseOutput.Ok();
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// 上传系统通知文档
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpPost("SystemNotice/UploadSystemNoticeDoc")]
|
|
[DisableRequestSizeLimit]
|
|
[DisableFormValueModelBinding]
|
|
public async Task<IResponseOutput> UploadSystemNoticeDoc()
|
|
{
|
|
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)
|
|
{
|
|
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
|
|
|
|
if (hasContentDispositionHeader)
|
|
{
|
|
|
|
DealSystemNoticePath( contentDisposition.FileName.Value, out string serverFilePath, out string relativePath);
|
|
|
|
await WriteFileAsync(section.Body, serverFilePath);
|
|
|
|
//仅仅返回一个文件,如果多文件上传 在最后返回多个路径
|
|
return ResponseOutput.Ok(new
|
|
{
|
|
FilePath = relativePath,
|
|
FullFilePath = relativePath + "?access_token=" + _userInfo.UserToken
|
|
});
|
|
|
|
}
|
|
section = await reader.ReadNextSectionAsync();
|
|
}
|
|
return ResponseOutput.Ok();
|
|
}
|
|
|
|
|
|
private void DealCommonStorePath(/*string fileType, string moduleType,*/ string fileRealName, out string serverFilePath, out string relativePath)
|
|
{
|
|
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment) ;
|
|
//上传根路径
|
|
var _fileStorePath = Path.Combine(rootPath, StaticData.SystemDataFolder);
|
|
|
|
//文件类型路径处理
|
|
var uploadFolderPath = Path.Combine(_fileStorePath, StaticData.DataTemplate);
|
|
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
|
|
|
|
|
var (trustedFileNameForFileStorage, fileName) = FileStoreHelper.GetStoreFileName(fileRealName);
|
|
|
|
|
|
relativePath = $"/{StaticData.IRaCISDataFolder}/{StaticData.SystemDataFolder}/{StaticData.DataTemplate}/{trustedFileNameForFileStorage}";
|
|
|
|
serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
|
}
|
|
|
|
|
|
private void DealSystemNoticePath(string fileRealName, out string serverFilePath, out string relativePath)
|
|
{
|
|
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
|
//上传根路径
|
|
var _fileStorePath = Path.Combine(rootPath, StaticData.SystemDataFolder);
|
|
|
|
//文件类型路径处理
|
|
var uploadFolderPath = Path.Combine(_fileStorePath, StaticData.NoticeAttachment);
|
|
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
|
|
|
|
|
var (trustedFileNameForFileStorage, fileName) = FileStoreHelper.GetStoreFileName(fileRealName);
|
|
|
|
|
|
|
|
relativePath = $"/{StaticData.IRaCISDataFolder}/{StaticData.SystemDataFolder}/{StaticData.NoticeAttachment}/{trustedFileNameForFileStorage}";
|
|
|
|
serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
|
}
|
|
|
|
|
|
private void DealSysTemStorePath( string fileRealName, out string serverFilePath, out string relativePath)
|
|
{
|
|
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
|
//上传根路径
|
|
var _fileStorePath = Path.Combine(rootPath, StaticData.SystemDataFolder);
|
|
|
|
//文件类型路径处理
|
|
var uploadFolderPath = Path.Combine(_fileStorePath, StaticData.SignDocumentFolder);
|
|
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
|
|
|
|
|
//var fileNameEX = Path.GetExtension(fileRealName);
|
|
//var trustedFileNameForFileStorage = Guid.NewGuid().ToString() + fileNameEX;
|
|
|
|
var trustedFileNameForFileStorage = Guid.NewGuid().ToString() + fileRealName;
|
|
|
|
relativePath = $"/{StaticData.IRaCISDataFolder}/{StaticData.SystemDataFolder}/{ StaticData.SignDocumentFolder}/{trustedFileNameForFileStorage}";
|
|
|
|
serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
|
}
|
|
|
|
|
|
private void DealTrialStorePath(Guid trialId,string fileRealName, out string serverFilePath, out string relativePath)
|
|
{
|
|
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
|
//上传根路径
|
|
var _fileStorePath = Path.Combine(rootPath, StaticData.TrialDataFolder);
|
|
|
|
//文件类型路径处理
|
|
var uploadFolderPath = Path.Combine(_fileStorePath, trialId.ToString(), StaticData.SignDocumentFolder);
|
|
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
|
|
|
var (trustedFileNameForFileStorage, fileName) = FileStoreHelper.GetStoreFileName(fileRealName);
|
|
|
|
relativePath = $"/{StaticData.IRaCISDataFolder}/{StaticData.TrialDataFolder}/{trialId}/{StaticData.SignDocumentFolder}/{trustedFileNameForFileStorage}";
|
|
|
|
serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// 上传临床数据
|
|
/// </summary>
|
|
/// <param name="subjectVisitId"></param>
|
|
/// <param name="uploadType"> 1:DICOM DTF 2:非DIOM DTF 3: 受试者临床数据</param>
|
|
/// <param name="_subjectVisitRepository"></param>
|
|
/// <returns></returns>
|
|
[HttpPost("ClinicalData/UploadVisitClinicalData/{trialId:guid}/{subjectVisitId:guid}/{type}")]
|
|
[DisableRequestSizeLimit]
|
|
[DisableFormValueModelBinding]
|
|
[Obsolete]
|
|
public async Task<IResponseOutput> UploadVisitData(Guid subjectVisitId, [FromRoute] UploadFileTypeEnum uploadType, [FromServices] IRepository<SubjectVisit> _subjectVisitRepository)
|
|
{
|
|
|
|
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)
|
|
{
|
|
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
|
|
|
|
if (hasContentDispositionHeader)
|
|
{
|
|
|
|
DealStorePath(subjectVisitId, contentDisposition.FileName.Value, uploadType, out string serverFilePath, out string relativePath, _subjectVisitRepository);
|
|
|
|
await WriteFileAsync(section.Body, serverFilePath);
|
|
|
|
//仅仅返回一个文件,如果多文件上传 在最后返回多个路径
|
|
return ResponseOutput.Ok(new
|
|
{
|
|
FilePath = relativePath,
|
|
FullFilePath = relativePath + "?access_token=" + _userInfo.UserToken
|
|
});
|
|
|
|
}
|
|
section = await reader.ReadNextSectionAsync();
|
|
}
|
|
return ResponseOutput.Ok();
|
|
|
|
}
|
|
|
|
public enum UploadFileTypeEnum
|
|
{
|
|
DICOM_DTF = 1,
|
|
|
|
NonDICOM_DTF = 2,
|
|
|
|
SubjectTreatement = 3
|
|
}
|
|
|
|
private void DealStorePath(Guid subjectVisitId, string realName, UploadFileTypeEnum typeEnum, out string serverFilePath, out string relativePath, IRepository<SubjectVisit> _subjectVisitRepository)
|
|
{
|
|
|
|
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
|
|
|
//上传根路径
|
|
var _fileStorePath = Path.Combine(rootPath, StaticData.TrialDataFolder);
|
|
|
|
var sv = _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => new { t.TrialId, t.SiteId, t.SubjectId }).FirstOrDefault();
|
|
|
|
//处理存储的文件夹
|
|
var typeFolder = typeEnum == UploadFileTypeEnum.SubjectTreatement ? StaticData.TreatmenthistoryFolder
|
|
: typeEnum == UploadFileTypeEnum.NonDICOM_DTF ? StaticData.NoneDicomFolder
|
|
: /*typeEnum == UploadFileTypeEnum.DICOM_DTF ?*/ StaticData.DicomFolder;
|
|
|
|
string uploadFolderPath = Path.Combine(_fileStorePath, sv.TrialId.ToString(), sv.SiteId.ToString(), sv.SubjectId.ToString(), subjectVisitId.ToString(), typeFolder);
|
|
|
|
if (!Directory.Exists(uploadFolderPath))
|
|
{
|
|
Directory.CreateDirectory(uploadFolderPath);
|
|
}
|
|
|
|
var fileNameEX = Path.GetExtension(realName);
|
|
|
|
var trustedFileNameForFileStorage = Guid.NewGuid().ToString() + fileNameEX;
|
|
|
|
relativePath = $"/{StaticData.TrialDataFolder}/{sv.TrialId}/{sv.SiteId}/{sv.SubjectId}/{subjectVisitId}/{typeFolder}/{trustedFileNameForFileStorage}";
|
|
|
|
serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
|
|
|
//处理 是上传文件返回路径 还是上传文件后,需要保存数据库
|
|
|
|
|
|
if (typeEnum == UploadFileTypeEnum.SubjectTreatement)
|
|
{
|
|
var repository = _serviceProvider.GetService(typeof(IRepository<PreviousPDF>)) as IRepository<PreviousPDF>;
|
|
|
|
_= repository.InsertOrUpdateAsync(new PreviousPDFAddOrEdit() { FileName = realName, Path = relativePath, SubjectVisitId = subjectVisitId }, true).Result;
|
|
}
|
|
else if (typeEnum == UploadFileTypeEnum.NonDICOM_DTF)
|
|
{
|
|
|
|
}
|
|
else if (typeEnum == UploadFileTypeEnum.NonDICOM_DTF)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 写文件导到磁盘
|
|
/// </summary>
|
|
/// <param name="stream">流</param>
|
|
/// <param name="path">文件保存路径</param>
|
|
/// <returns></returns>
|
|
private static async Task<int> WriteFileAsync(System.IO.Stream stream, string path)
|
|
{
|
|
const int FILE_WRITE_SIZE = 84975;//写出缓冲区大小
|
|
int writeCount = 0;
|
|
using (FileStream fileStream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Write, FILE_WRITE_SIZE, true))
|
|
{
|
|
byte[] byteArr = new byte[FILE_WRITE_SIZE];
|
|
int readCount = 0;
|
|
while ((readCount = await stream.ReadAsync(byteArr, 0, byteArr.Length)) > 0)
|
|
{
|
|
await fileStream.WriteAsync(byteArr, 0, readCount);
|
|
writeCount += readCount;
|
|
}
|
|
}
|
|
return writeCount;
|
|
}
|
|
}
|
|
}
|