407 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			407 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 = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).FullName;
 | 
						|
            //上传根路径
 | 
						|
            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.SystemDataFolder}/{StaticData.DataTemplate}/{trustedFileNameForFileStorage}";
 | 
						|
 | 
						|
            serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        private void DealSystemNoticePath(string fileRealName, out string serverFilePath, out string relativePath)
 | 
						|
        {
 | 
						|
            var rootPath = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).FullName;
 | 
						|
            //上传根路径
 | 
						|
            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.SystemDataFolder}/{StaticData.NoticeAttachment}/{trustedFileNameForFileStorage}";
 | 
						|
 | 
						|
            serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        private void DealSysTemStorePath(  string fileRealName,  out string serverFilePath, out string relativePath)
 | 
						|
        {
 | 
						|
            var rootPath = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).FullName;
 | 
						|
            //上传根路径
 | 
						|
            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.SystemDataFolder}/{ StaticData.SignDocumentFolder}/{trustedFileNameForFileStorage}";
 | 
						|
 | 
						|
            serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        private void DealTrialStorePath(Guid trialId,string fileRealName,  out string serverFilePath, out string relativePath)
 | 
						|
        {
 | 
						|
            var rootPath = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).FullName;
 | 
						|
            //上传根路径
 | 
						|
            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.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 = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).FullName;
 | 
						|
 | 
						|
            //上传根路径
 | 
						|
            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;
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |