1004 lines
		
	
	
		
			39 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			1004 lines
		
	
	
		
			39 KiB
		
	
	
	
		
			C#
		
	
	
using AutoMapper;
 | 
						||
using ExcelDataReader;
 | 
						||
using IRaCIS.Application.Interfaces;
 | 
						||
using IRaCIS.Core.Application.BusinessFilter;
 | 
						||
using IRaCIS.Core.Application.Contracts;
 | 
						||
using IRaCIS.Core.Application.Contracts.Dicom;
 | 
						||
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
 | 
						||
using IRaCIS.Core.Application.Filter;
 | 
						||
using IRaCIS.Core.Application.Helper;
 | 
						||
using IRaCIS.Core.Application.MassTransit.Command;
 | 
						||
using IRaCIS.Core.Application.Service;
 | 
						||
using IRaCIS.Core.Domain.Models;
 | 
						||
using IRaCIS.Core.Domain.Share;
 | 
						||
using IRaCIS.Core.Infra.EFCore;
 | 
						||
using IRaCIS.Core.Infrastructure;
 | 
						||
using IRaCIS.Core.Infrastructure.Extention;
 | 
						||
using MassTransit.Mediator;
 | 
						||
using Microsoft.AspNetCore.Authorization;
 | 
						||
using Microsoft.AspNetCore.Hosting;
 | 
						||
using Microsoft.AspNetCore.Http;
 | 
						||
using Microsoft.AspNetCore.Mvc;
 | 
						||
using Microsoft.AspNetCore.Mvc.Filters;
 | 
						||
using Microsoft.AspNetCore.Mvc.ModelBinding;
 | 
						||
using Microsoft.AspNetCore.SignalR;
 | 
						||
using Microsoft.AspNetCore.StaticFiles;
 | 
						||
using Microsoft.AspNetCore.WebUtilities;
 | 
						||
using Microsoft.EntityFrameworkCore;
 | 
						||
using Microsoft.Extensions.Localization;
 | 
						||
using Microsoft.Extensions.Logging;
 | 
						||
using Microsoft.Net.Http.Headers;
 | 
						||
using MiniExcelLibs;
 | 
						||
using Newtonsoft.Json;
 | 
						||
using SharpCompress.Archives;
 | 
						||
using System;
 | 
						||
using System.Collections.Generic;
 | 
						||
using System.ComponentModel.DataAnnotations;
 | 
						||
using System.Data;
 | 
						||
using System.IO;
 | 
						||
using System.Linq;
 | 
						||
using System.Text;
 | 
						||
using System.Threading.Tasks;
 | 
						||
using Path = System.IO.Path;
 | 
						||
 | 
						||
namespace IRaCIS.Core.API.Controllers
 | 
						||
{
 | 
						||
 | 
						||
    #region 上传基类封装
 | 
						||
 | 
						||
 | 
						||
 | 
						||
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
 | 
						||
    public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter
 | 
						||
    {
 | 
						||
        public void OnResourceExecuting(ResourceExecutingContext context)
 | 
						||
        {
 | 
						||
 | 
						||
 | 
						||
            var factories = context.ValueProviderFactories;
 | 
						||
            //factories.RemoveType<FormValueProviderFactory>();
 | 
						||
            factories.RemoveType<FormFileValueProviderFactory>();
 | 
						||
            factories.RemoveType<JQueryFormValueProviderFactory>();
 | 
						||
            context.HttpContext.Request.EnableBuffering();
 | 
						||
        }
 | 
						||
 | 
						||
        public void OnResourceExecuted(ResourceExecutedContext context)
 | 
						||
        {
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    [DisableFormValueModelBinding]
 | 
						||
    public abstract class UploadBaseController : ControllerBase
 | 
						||
    {
 | 
						||
        /// <summary>  流式上传  直接返回</summary>
 | 
						||
        [Route("SingleFileUpload")]
 | 
						||
        [ApiExplorerSettings(IgnoreApi = true)]
 | 
						||
 | 
						||
        public virtual async Task<IResponseOutput> SingleFileUploadAsync(Func<string, (string, string)> filePathFunc)
 | 
						||
        {
 | 
						||
            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)
 | 
						||
                {
 | 
						||
 | 
						||
                    var (serverFilePath, relativePath) = filePathFunc(contentDisposition.FileName.Value);
 | 
						||
 | 
						||
                    await FileStoreHelper.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>
 | 
						||
        [Route("FileUpload")]
 | 
						||
        [ApiExplorerSettings(IgnoreApi = true)]
 | 
						||
 | 
						||
        public virtual async Task FileUploadAsync(Func<string, Task<string>> filePathFunc)
 | 
						||
        {
 | 
						||
            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)
 | 
						||
                {
 | 
						||
                    var fileName = contentDisposition.FileName.Value;
 | 
						||
                    //处理压缩文件
 | 
						||
                    if (fileName.Contains(".Zip", StringComparison.OrdinalIgnoreCase) || fileName.Contains(".rar", StringComparison.OrdinalIgnoreCase))
 | 
						||
                    {
 | 
						||
                        var archive = ArchiveFactory.Open(section.Body);
 | 
						||
 | 
						||
                        foreach (var entry in archive.Entries)
 | 
						||
                        {
 | 
						||
                            if (!entry.IsDirectory)
 | 
						||
                            {
 | 
						||
                                var serverFilePath = await filePathFunc(entry.Key);
 | 
						||
                                entry.WriteToFile(serverFilePath);
 | 
						||
 | 
						||
                            }
 | 
						||
                        }
 | 
						||
                    }
 | 
						||
                    //普通单个文件
 | 
						||
                    else
 | 
						||
                    {
 | 
						||
                        var serverFilePath = await filePathFunc(fileName);
 | 
						||
 | 
						||
                        await FileStoreHelper.WriteFileAsync(section.Body, serverFilePath);
 | 
						||
                    }
 | 
						||
 | 
						||
                }
 | 
						||
                section = await reader.ReadNextSectionAsync();
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        [Route("FileUploadToOSS")]
 | 
						||
        [ApiExplorerSettings(IgnoreApi = true)]
 | 
						||
 | 
						||
        public virtual async Task FileUploadToOSSAsync(Func<string, Stream, Task<string>> toMemoryStreamFunc)
 | 
						||
        {
 | 
						||
            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)
 | 
						||
                {
 | 
						||
                    var fileName = contentDisposition.FileName.Value;
 | 
						||
 | 
						||
                    await toMemoryStreamFunc(fileName, section.Body);
 | 
						||
 | 
						||
                }
 | 
						||
 | 
						||
                section = await reader.ReadNextSectionAsync();
 | 
						||
 | 
						||
            }
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
        /// <summary>  流式上传   Dicom上传  </summary>
 | 
						||
        [Route("DicomFileUpload")]
 | 
						||
        [ApiExplorerSettings(IgnoreApi = true)]
 | 
						||
 | 
						||
        public virtual async Task DicomFileUploadAsync(Func<string, Stream, int, Task> filePathFunc, string boundary)
 | 
						||
        {
 | 
						||
 | 
						||
            var fileCount = 0;
 | 
						||
 | 
						||
            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)
 | 
						||
                {
 | 
						||
 | 
						||
                    var fileName = contentDisposition.FileName.Value ?? String.Empty;
 | 
						||
 | 
						||
                    string mediaType = section.ContentType ?? String.Empty;
 | 
						||
 | 
						||
 | 
						||
                    //处理压缩文件
 | 
						||
                    if (fileName.Contains(".Zip", StringComparison.OrdinalIgnoreCase) || fileName.Contains(".rar", StringComparison.OrdinalIgnoreCase))
 | 
						||
                    {
 | 
						||
                        var archive = ArchiveFactory.Open(section.Body);
 | 
						||
 | 
						||
                        foreach (var entry in archive.Entries)
 | 
						||
                        {
 | 
						||
                            if (!entry.IsDirectory)
 | 
						||
                            {
 | 
						||
                                ++fileCount;
 | 
						||
 | 
						||
                                await filePathFunc(entry.Key, entry.OpenEntryStream(), fileCount);
 | 
						||
                            }
 | 
						||
                        }
 | 
						||
                    }
 | 
						||
                    //普通单个文件
 | 
						||
                    else
 | 
						||
                    {
 | 
						||
                        if (mediaType.Contains("octet-stream") || mediaType.Contains("dicom"))
 | 
						||
                        {
 | 
						||
                            ++fileCount;
 | 
						||
 | 
						||
                            await filePathFunc(fileName, section.Body, fileCount);
 | 
						||
                        }
 | 
						||
 | 
						||
                    }
 | 
						||
                }
 | 
						||
                section = await reader.ReadNextSectionAsync();
 | 
						||
            }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
    }
 | 
						||
 | 
						||
    #endregion
 | 
						||
 | 
						||
    #region Dicom 影像上传  临床数据  非diocm 
 | 
						||
    public class UploadNoneDicomFileCommand
 | 
						||
    {
 | 
						||
        [NotDefault]
 | 
						||
        public Guid SubjectVisitId { get; set; }
 | 
						||
 | 
						||
 | 
						||
        [NotDefault]
 | 
						||
        public Guid StudyMonitorId { get; set; }
 | 
						||
 | 
						||
 | 
						||
        public Guid? NoneDicomStudyId { get; set; }
 | 
						||
 | 
						||
        //IR 上传的时候跟任务绑定
 | 
						||
        public Guid? VisitTaskId { get; set; }
 | 
						||
 | 
						||
        public string RecordPath { get; set; }
 | 
						||
 | 
						||
        public int FailedFileCount { get; set; }
 | 
						||
 | 
						||
        public long FileSize { get; set; }
 | 
						||
 | 
						||
 | 
						||
        public List<OSSFileDTO> UploadedFileList { get; set; } = new List<OSSFileDTO>();
 | 
						||
 | 
						||
 | 
						||
        public class OSSFileDTO
 | 
						||
        {
 | 
						||
            public string FilePath { get; set; }
 | 
						||
            public string FileName { get; set; }
 | 
						||
            public int FileFize { get; set; }
 | 
						||
 | 
						||
            public string FileType { get; set; }
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    [ApiController, ApiExplorerSettings(GroupName = "Image")]
 | 
						||
    public class StudyController(
 | 
						||
        IMediator _mediator,
 | 
						||
        QCCommon _qCCommon,
 | 
						||
        IUserInfo _userInfo,
 | 
						||
        IRepository<SubjectVisit> _subjectVisitRepository,
 | 
						||
        IStringLocalizer _localizer) : UploadBaseController
 | 
						||
    {
 | 
						||
 | 
						||
 | 
						||
 | 
						||
        /// <summary>Dicom 归档</summary>
 | 
						||
        [HttpPost, Route("Study/ArchiveStudy")]
 | 
						||
        [DisableFormValueModelBinding]
 | 
						||
        [DisableRequestSizeLimit]
 | 
						||
        [TrialGlobalLimit("AfterStopCannNotOpt")]
 | 
						||
        public async Task<IResponseOutput> ArchiveStudyNew(Guid trialId, Guid subjectVisitId, string studyInstanceUid, Guid? abandonStudyId, Guid studyMonitorId,
 | 
						||
             [FromServices] ILogger<UploadDownLoadController> _logger,
 | 
						||
             [FromServices] IStudyService _studyService,
 | 
						||
             [FromServices] IHubContext<UploadHub, IUploadClient> _uploadHub,
 | 
						||
             [FromServices] IDicomArchiveService _dicomArchiveService,
 | 
						||
             [FromServices] IRepository<StudyMonitor> _studyMonitorRepository
 | 
						||
            )
 | 
						||
        {
 | 
						||
 | 
						||
 | 
						||
 | 
						||
            if (!HttpContext.Request.HasFormContentType ||
 | 
						||
                !MediaTypeHeaderValue.TryParse(HttpContext.Request.ContentType, out var mediaTypeHeader) ||
 | 
						||
                string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value))
 | 
						||
            {
 | 
						||
                //---不支持的MediaType
 | 
						||
                return ResponseOutput.NotOk(_localizer["UploadDownLoad_UnsupportedMedia"]);
 | 
						||
            }
 | 
						||
 | 
						||
            var archiveStudyCommand = new ArchiveStudyCommand() { AbandonStudyId = abandonStudyId, StudyInstanceUid = studyInstanceUid, SubjectVisitId = subjectVisitId };
 | 
						||
 | 
						||
            string studycode = string.Empty;
 | 
						||
 | 
						||
            var startTime = DateTime.Now;
 | 
						||
 | 
						||
 | 
						||
 | 
						||
            //到了接口,代表上传结束了
 | 
						||
 | 
						||
            var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == studyMonitorId);
 | 
						||
 | 
						||
            studyMonitor.UploadFinishedTime = DateTime.Now;
 | 
						||
 | 
						||
 | 
						||
            var (archiveResult, archivedStudyIds) = (new DicomArchiveResult(), new List<Guid>());
 | 
						||
 | 
						||
 | 
						||
            var (seriesInstanceUidList, sopInstanceUidList) = (new List<string>(), new List<string>());
 | 
						||
 | 
						||
            //重传的时候,找出当前检查已经上传的series instance
 | 
						||
            if (archiveStudyCommand.AbandonStudyId != null)
 | 
						||
            {
 | 
						||
                (seriesInstanceUidList, sopInstanceUidList) = _studyService.GetHasUploadSeriesAndInstance(archiveStudyCommand.AbandonStudyId.Value);
 | 
						||
            }
 | 
						||
 | 
						||
            var savedInfo = _studyService.GetSaveToDicomInfo(archiveStudyCommand.SubjectVisitId);
 | 
						||
 | 
						||
            try
 | 
						||
            {
 | 
						||
 | 
						||
                await DicomFileUploadAsync(async (fileName, fileStream, receivedCount) =>
 | 
						||
                {
 | 
						||
 | 
						||
                    try
 | 
						||
                    {
 | 
						||
                        using (var memoryStream = new MemoryStream())
 | 
						||
                        {
 | 
						||
                            await fileStream.CopyToAsync(memoryStream);
 | 
						||
 | 
						||
                            memoryStream.Seek(0, SeekOrigin.Begin);
 | 
						||
 | 
						||
                            var (studyId, studyCode) = await _dicomArchiveService.ArchiveDicomStreamAsync(memoryStream, savedInfo, seriesInstanceUidList, sopInstanceUidList);
 | 
						||
                            if (!archivedStudyIds.Contains(studyId))
 | 
						||
                            {
 | 
						||
                                archivedStudyIds.Add(studyId);
 | 
						||
                                archiveResult.ArchivedDicomStudies.Add(new DicomStudyBasicDTO() { StudyCode = studyCode, Id = studyId });
 | 
						||
                            }
 | 
						||
                        }
 | 
						||
 | 
						||
                        //await _uploadHub.Clients.All.ReceivProgressAsync(archiveStudyCommand.StudyInstanceUid, receivedCount);
 | 
						||
 | 
						||
 | 
						||
                        await _uploadHub.Clients.User(_userInfo.UserRoleId.ToString()).ReceivProgressAsync(archiveStudyCommand.StudyInstanceUid, receivedCount);
 | 
						||
 | 
						||
                        archiveResult.ReceivedFileCount = receivedCount;
 | 
						||
 | 
						||
                    }
 | 
						||
                    catch (Exception e)
 | 
						||
                    {
 | 
						||
                        _logger.LogError(e.Message + e.StackTrace);
 | 
						||
 | 
						||
                        archiveResult.ErrorFiles.Add(fileName);
 | 
						||
                    }
 | 
						||
 | 
						||
 | 
						||
                }, mediaTypeHeader.Boundary.Value);
 | 
						||
 | 
						||
 | 
						||
            }
 | 
						||
            catch (Exception)
 | 
						||
            {
 | 
						||
 | 
						||
                //---请求异常,请重试!
 | 
						||
                throw new BusinessValidationFailedException(_localizer["UploadDownLoad_RequestError"]);
 | 
						||
            }
 | 
						||
 | 
						||
            studyMonitor.FileSize = (long)HttpContext.Request.ContentLength;
 | 
						||
            studyMonitor.FileCount = archiveResult.ReceivedFileCount;
 | 
						||
            studyMonitor.FailedFileCount = archiveResult.ErrorFiles.Count;
 | 
						||
            studyMonitor.IsDicomReUpload = archiveStudyCommand.AbandonStudyId != null;
 | 
						||
            studyMonitor.Note = JsonConvert.SerializeObject(archiveResult);
 | 
						||
 | 
						||
 | 
						||
            try
 | 
						||
            {
 | 
						||
 | 
						||
                if (archivedStudyIds.Count > 0) // 上传成功,处理逻辑
 | 
						||
                {
 | 
						||
 | 
						||
                    // 同一个访视 多个线程上传处理  批量保存 可能造成死锁 https://www.cnblogs.com/johnblogs/p/9945767.html
 | 
						||
 | 
						||
                    await _dicomArchiveService.DicomDBDataSaveChange();
 | 
						||
 | 
						||
                    archiveResult.ReuploadNewStudyId = archivedStudyIds[0] == archiveStudyCommand.AbandonStudyId ? archivedStudyIds[0] : Guid.Empty;
 | 
						||
 | 
						||
                    studyMonitor.IsSuccess = true;
 | 
						||
 | 
						||
                }
 | 
						||
 | 
						||
            }
 | 
						||
            catch (Exception e)
 | 
						||
            {
 | 
						||
 | 
						||
                studyMonitor.Note = JsonConvert.SerializeObject(new { Message = e.Message, Result = archiveResult });
 | 
						||
                _logger.LogError(e.Message + e.StackTrace);
 | 
						||
 | 
						||
            }
 | 
						||
            finally
 | 
						||
            {
 | 
						||
 | 
						||
                studyMonitor.StudyId = archiveResult.ArchivedDicomStudies.FirstOrDefault()?.Id ?? Guid.Empty;
 | 
						||
                studyMonitor.StudyCode = archiveResult.ArchivedDicomStudies.FirstOrDefault()?.StudyCode;
 | 
						||
                studyMonitor.ArchiveFinishedTime = DateTime.Now;
 | 
						||
 | 
						||
                await _studyMonitorRepository.SaveChangesAsync();
 | 
						||
            }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
            return ResponseOutput.Result(studyMonitor.IsSuccess, archiveResult);
 | 
						||
 | 
						||
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 非dicom 上传预上传接口
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="preArchiveStudyCommand"></param>
 | 
						||
        /// <param name="_studyService"></param>
 | 
						||
        /// <param name="_studyMonitorRepository"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        [HttpPost, Route("Study/PreArchiveStudy")]
 | 
						||
        [TrialGlobalLimit("AfterStopCannNotOpt")]
 | 
						||
        public async Task<IResponseOutput> PreArchiveStudy(PreArchiveStudyCommand preArchiveStudyCommand,
 | 
						||
     [FromServices] IStudyService _studyService,
 | 
						||
     [FromServices] IRepository<StudyMonitor> _studyMonitorRepository)
 | 
						||
        {
 | 
						||
 | 
						||
            var savedInfo = _studyService.GetSaveToDicomInfo(preArchiveStudyCommand.SubjectVisitId);
 | 
						||
 | 
						||
            var studyMonitor = new StudyMonitor()
 | 
						||
            {
 | 
						||
                TrialId = savedInfo.TrialId,
 | 
						||
                SubjectId = savedInfo.SubjectId,
 | 
						||
                SubjectVisitId = savedInfo.SubjectVisitId,
 | 
						||
 | 
						||
                IsSuccess = false,
 | 
						||
                UploadStartTime = DateTime.Now,
 | 
						||
                FileCount = preArchiveStudyCommand.FileCount,
 | 
						||
                IsDicom = preArchiveStudyCommand.IsDicom,
 | 
						||
                IP = _userInfo.IP
 | 
						||
            };
 | 
						||
 | 
						||
 | 
						||
            var addEntity = await _studyMonitorRepository.AddAsync(studyMonitor, true);
 | 
						||
 | 
						||
            return ResponseOutput.Ok(addEntity.Id);
 | 
						||
 | 
						||
        }
 | 
						||
        /// <summary>
 | 
						||
        /// 上传非Dicom 文件 支持压缩包 多文件上传
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="incommand"></param>
 | 
						||
        /// <param name="_noneDicomStudyRepository"></param>
 | 
						||
        /// <param name="_studyMonitorRepository"></param>
 | 
						||
        /// <param name="_noneDicomStudyFileRepository"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        [HttpPost("NoneDicomStudy/UploadNoneDicomFile")]
 | 
						||
        [TrialGlobalLimit("AfterStopCannNotOpt")]
 | 
						||
        public async Task<IResponseOutput> UploadNoneDicomFile(UploadNoneDicomFileCommand incommand,
 | 
						||
            [FromServices] IRepository<NoneDicomStudy> _noneDicomStudyRepository,
 | 
						||
            [FromServices] IRepository<StudyMonitor> _studyMonitorRepository,
 | 
						||
            [FromServices] IRepository<NoneDicomStudyFile> _noneDicomStudyFileRepository)
 | 
						||
        {
 | 
						||
 | 
						||
            var subjectVisitId = incommand.SubjectVisitId;
 | 
						||
            var studyMonitorId = incommand.StudyMonitorId;
 | 
						||
            var noneDicomStudyId = incommand.NoneDicomStudyId;
 | 
						||
 | 
						||
 | 
						||
            await _qCCommon.VerifyIsCRCSubmmitAsync(_subjectVisitRepository, _userInfo, subjectVisitId);
 | 
						||
 | 
						||
            var sv = (await _subjectVisitRepository.Where(t => t.Id == subjectVisitId).Select(t => new { t.TrialId, t.TrialSiteId, t.SubjectId }).FirstOrDefaultAsync()).IfNullThrowConvertException();
 | 
						||
 | 
						||
            var studyMonitor = await _studyMonitorRepository.FirstOrDefaultAsync(t => t.Id == studyMonitorId);
 | 
						||
 | 
						||
            studyMonitor.UploadFinishedTime = DateTime.Now;
 | 
						||
 | 
						||
            foreach (var item in incommand.UploadedFileList)
 | 
						||
            {
 | 
						||
                //如果是跟任务绑,那么NoneDicomStudyId 设置为空,不影响之前的检查,同时设置 OriginNoneDicomStudyId 保证关系
 | 
						||
 | 
						||
                if (incommand.VisitTaskId != null && incommand.VisitTaskId != Guid.Empty)
 | 
						||
                {
 | 
						||
                    await _noneDicomStudyFileRepository.AddAsync(new NoneDicomStudyFile() { FileName = item.FileName, Path = item.FilePath, OriginNoneDicomStudyId = noneDicomStudyId.Value, VisitTaskId = incommand.VisitTaskId, FileType = item.FileType, FileSize = item.FileFize });
 | 
						||
 | 
						||
                }
 | 
						||
                else
 | 
						||
                {
 | 
						||
                    await _noneDicomStudyFileRepository.AddAsync(new NoneDicomStudyFile() { FileName = item.FileName, Path = item.FilePath, NoneDicomStudyId = noneDicomStudyId.Value, FileType = item.FileType, FileSize = item.FileFize });
 | 
						||
 | 
						||
                }
 | 
						||
 | 
						||
 | 
						||
            }
 | 
						||
            var uploadFinishedTime = DateTime.Now;
 | 
						||
 | 
						||
            var noneDicomStudy = await _noneDicomStudyRepository.FirstOrDefaultAsync((t => t.Id == noneDicomStudyId));
 | 
						||
 | 
						||
            noneDicomStudy.FileCount = noneDicomStudy.FileCount + (incommand.VisitTaskId != null ? 0 : incommand.UploadedFileList.Count);
 | 
						||
 | 
						||
            studyMonitor.RecordPath = incommand.RecordPath;
 | 
						||
            studyMonitor.FailedFileCount = incommand.FailedFileCount;
 | 
						||
            studyMonitor.IsSuccess = incommand.FailedFileCount == 0;
 | 
						||
            studyMonitor.FileSize = incommand.UploadedFileList.Sum(t => t.FileFize);
 | 
						||
            studyMonitor.IsDicom = false;
 | 
						||
            studyMonitor.IsDicomReUpload = false;
 | 
						||
            studyMonitor.StudyId = noneDicomStudyId.Value;
 | 
						||
            studyMonitor.StudyCode = noneDicomStudy.StudyCode;
 | 
						||
            studyMonitor.ArchiveFinishedTime = DateTime.Now;
 | 
						||
            studyMonitor.IP = _userInfo.IP;
 | 
						||
 | 
						||
            await _noneDicomStudyRepository.SaveChangesAsync();
 | 
						||
 | 
						||
            return ResponseOutput.Ok();
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 一致性核查 excel上传 支持三种格式
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="trialId"></param>
 | 
						||
        /// <param name="oSSService"></param>
 | 
						||
        /// <param name="_inspectionFileRepository"></param>
 | 
						||
        /// <returns></returns>
 | 
						||
        /// <exception cref="BusinessValidationFailedException"></exception>
 | 
						||
        [HttpPost("QCOperation/UploadVisitCheckExcel/{trialId:guid}")]
 | 
						||
        [TrialGlobalLimit("AfterStopCannNotOpt")]
 | 
						||
 | 
						||
        public async Task<IResponseOutput> UploadVisitCheckExcel(Guid trialId, [FromServices] IOSSService oSSService, [FromServices] IRepository<InspectionFile> _inspectionFileRepository)
 | 
						||
        {
 | 
						||
 | 
						||
            var fileName = string.Empty;
 | 
						||
            var templateFileStream = new MemoryStream();
 | 
						||
 | 
						||
            await FileUploadToOSSAsync(async (realFileName, fileStream) =>
 | 
						||
            {
 | 
						||
                fileName = realFileName;
 | 
						||
 | 
						||
                if (!fileName.EndsWith(".xlsx") && !fileName.EndsWith(".xls"))
 | 
						||
                {
 | 
						||
                    //---支持.xlsx、.xls格式的文件上传。
 | 
						||
                    throw new BusinessValidationFailedException(_localizer["UploadDownLoad_SupportedFormats"]);
 | 
						||
                }
 | 
						||
 | 
						||
                fileStream.CopyTo(templateFileStream);
 | 
						||
                templateFileStream.Seek(0, SeekOrigin.Begin);
 | 
						||
 | 
						||
 | 
						||
                var ossRelativePath = await oSSService.UploadToOSSAsync(fileStream, "InspectionUpload/Check", realFileName);
 | 
						||
 | 
						||
                await _inspectionFileRepository.AddAsync(new InspectionFile() { FileName = realFileName, RelativePath = ossRelativePath, TrialId = trialId });
 | 
						||
 | 
						||
                return ossRelativePath;
 | 
						||
 | 
						||
            });
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
            var etcCheckList = new List<CheckViewModel>();
 | 
						||
 | 
						||
 | 
						||
            #region MiniExcel  需要自己验证数据格式规范
 | 
						||
 | 
						||
 | 
						||
            if (fileName.EndsWith(".xlsx"))
 | 
						||
            {
 | 
						||
                etcCheckList = MiniExcel.Query<CheckViewModel>(templateFileStream, excelType: ExcelType.XLSX).ToList();
 | 
						||
            }
 | 
						||
            else if (fileName.EndsWith(".csv"))
 | 
						||
            {
 | 
						||
                //因为csv 需要加配置文件 不然都是null
 | 
						||
                etcCheckList = MiniExcel.Query<CheckViewModel>(templateFileStream, null, configuration: new MiniExcelLibs.Csv.CsvConfiguration()
 | 
						||
                {
 | 
						||
                    StreamReaderFunc = (stream) => new StreamReader(stream, Encoding.GetEncoding("gb2312"))
 | 
						||
                }).ToList();
 | 
						||
 | 
						||
            }
 | 
						||
            //if (fileName.EndsWith(".csv"))
 | 
						||
            //{
 | 
						||
            //    //因为csv 需要加配置文件 不然都是null
 | 
						||
            //    etcCheckList = MiniExcel.Query<CheckViewModel>(filePath, null, configuration: config).ToList();
 | 
						||
            //}
 | 
						||
            //else if (fileName.EndsWith(".xlsx"))
 | 
						||
            //{
 | 
						||
            //    
 | 
						||
 | 
						||
 | 
						||
            //    etcCheckList = MiniExcel.Query<CheckViewModel>(filePath).ToList();
 | 
						||
            //}
 | 
						||
 | 
						||
            #endregion
 | 
						||
 | 
						||
            #region 升级net8 导入有问题
 | 
						||
 | 
						||
 | 
						||
            //Magicodes 支持自定义特性验证
 | 
						||
            //    if (fileName.EndsWith(".xlsx"))
 | 
						||
            //{
 | 
						||
            //    var Importer = new ExcelImporter();
 | 
						||
 | 
						||
            //    var import = await Importer.Import<CheckViewModel>(templateFileStream);
 | 
						||
 | 
						||
            //    if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString());
 | 
						||
 | 
						||
            //    //if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors));
 | 
						||
 | 
						||
            //    if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(_localizer["UploadDownLoad_TemplateErrors"]);
 | 
						||
 | 
						||
            //    etcCheckList = import.Data.ToList();
 | 
						||
            //}
 | 
						||
            //else if (fileName.EndsWith(".csv"))
 | 
						||
            //{
 | 
						||
            //    #region   临时方案   MiniExcel读取  然后保存为xlsx  再用 Magicodes验证数据
 | 
						||
 | 
						||
            //    //因为csv 需要加配置文件 不然都是null
 | 
						||
            //    etcCheckList = MiniExcel.Query<CheckViewModel>(templateFileStream, null, configuration: new MiniExcelLibs.Csv.CsvConfiguration()
 | 
						||
            //    {
 | 
						||
            //        StreamReaderFunc = (stream) => new StreamReader(stream, Encoding.GetEncoding("gb2312"))
 | 
						||
            //    }).ToList();
 | 
						||
 | 
						||
            //    var (csVToXlsxPath, csVToXlsxRelativePath) = FileStoreHelper.GetTrialCheckFilePath(_hostEnvironment, Path.GetFileNameWithoutExtension(fileName) + ".xlsx", trialId);
 | 
						||
 | 
						||
 | 
						||
            //    await MiniExcel.SaveAsAsync(csVToXlsxPath, etcCheckList, excelType: ExcelType.XLSX);
 | 
						||
 | 
						||
 | 
						||
            //    var Importer = new ExcelImporter();
 | 
						||
 | 
						||
            //    var import = await Importer.Import<CheckViewModel>(System.IO.File.OpenRead(csVToXlsxPath));
 | 
						||
 | 
						||
            //    if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString());
 | 
						||
 | 
						||
            //    //if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors));
 | 
						||
 | 
						||
            //    if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.TemplateErrors));
 | 
						||
 | 
						||
            //    etcCheckList = import.Data.ToList();
 | 
						||
 | 
						||
            //    #endregion
 | 
						||
 | 
						||
 | 
						||
            //    #region 导入组件有问题  excel编码格式
 | 
						||
            //    //var Importer = new CsvImporter();
 | 
						||
 | 
						||
            //    //var import = await Importer.Import<CheckViewModel>(File.OpenRead(filePath));
 | 
						||
 | 
						||
            //    //if (import.Exception != null) return ResponseOutput.NotOk(import.Exception.ToString());
 | 
						||
 | 
						||
            //    //if (import.RowErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.RowErrors));
 | 
						||
 | 
						||
            //    //if (import.TemplateErrors.Count > 0) return ResponseOutput.NotOk(JsonConvert.SerializeObject(import.TemplateErrors));
 | 
						||
 | 
						||
            //    //etcCheckList = import.Data.ToList();
 | 
						||
            //    #endregion
 | 
						||
 | 
						||
            //}
 | 
						||
 | 
						||
            #endregion
 | 
						||
            //ExcelReaderFactory  需要自己验证数据 并且从固定列取数据
 | 
						||
            else
 | 
						||
            {
 | 
						||
                //为了支持 xls  引入新的组件库
 | 
						||
                //using (var stream = System.IO.File.Open(templateFileStream, FileMode.Open, FileAccess.Read))
 | 
						||
                //{
 | 
						||
                // Auto-detect format, supports:
 | 
						||
                //  - Binary Excel files (2.0-2003 format; *.xls)
 | 
						||
                //  - OpenXml Excel files (2007 format; *.xlsx, *.xlsb)
 | 
						||
                using (var reader = ExcelReaderFactory.CreateReader(templateFileStream))
 | 
						||
                {
 | 
						||
 | 
						||
                    // 2. Use the AsDataSet extension method
 | 
						||
                    var dateset = reader.AsDataSet();
 | 
						||
 | 
						||
                    foreach (DataRow col in dateset.Tables[0].Rows)
 | 
						||
                    {
 | 
						||
 | 
						||
                        etcCheckList.Add(new CheckViewModel()
 | 
						||
                        {
 | 
						||
                            SiteCode = col[0].ToString(),
 | 
						||
                            SubjectCode = col[1].ToString(),
 | 
						||
                            VisitName = col[2].ToString(),
 | 
						||
                            StudyDate = col[3].ToString(),
 | 
						||
                            Modality = col[4].ToString(),
 | 
						||
                        });
 | 
						||
                    }
 | 
						||
 | 
						||
                    etcCheckList.Remove(etcCheckList[0]);
 | 
						||
 | 
						||
                    // The result of each spreadsheet is in result.Tables
 | 
						||
                }
 | 
						||
 | 
						||
            }
 | 
						||
 | 
						||
            if (etcCheckList == null || etcCheckList.Count == 0)
 | 
						||
            {
 | 
						||
                //---请保证上传数据符合模板文件中的样式,且存在有效数据。
 | 
						||
                return ResponseOutput.NotOk(_localizer["UploadDownLoad_InvalidData"]);
 | 
						||
            }
 | 
						||
            else
 | 
						||
            {
 | 
						||
                //处理Excel  有时只是清除某些行的数据  读取也会读到数据,只是数据是null   后面处理的时候转为字符串为报错
 | 
						||
                etcCheckList.ForEach(t =>
 | 
						||
                {
 | 
						||
                    t.Modality = t.Modality ?? string.Empty;
 | 
						||
                    t.SiteCode = t.SiteCode ?? string.Empty;
 | 
						||
                    t.SubjectCode = t.SubjectCode ?? string.Empty;
 | 
						||
                    t.VisitName = t.VisitName ?? string.Empty;
 | 
						||
                    t.StudyDate = t.StudyDate ?? string.Empty;
 | 
						||
                });
 | 
						||
 | 
						||
                var dt = DateTime.Now;
 | 
						||
 | 
						||
                etcCheckList = etcCheckList.Where(t => !(t.Modality == string.Empty || t.SiteCode == string.Empty || t.SubjectCode == string.Empty || t.VisitName == string.Empty || t.StudyDate == string.Empty || !DateTime.TryParse(t.StudyDate, out dt))).ToList();
 | 
						||
 | 
						||
                if (etcCheckList.Count == 0)
 | 
						||
                {
 | 
						||
                    //---请保证上传数据符合模板文件中的样式,且存在有效数据。
 | 
						||
                    return ResponseOutput.NotOk(_localizer["UploadDownLoad_InvalidData"]);
 | 
						||
                }
 | 
						||
            }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
            // 适合获取结果的
 | 
						||
            //var client = _mediator.CreateRequestClient<ConsistenCheckCommand>();
 | 
						||
            //await client.GetResponse<ConsistenCheckResult>(new ConsistenCheckCommand() { ETCList = etcCheckList, TrialId = trialId });
 | 
						||
 | 
						||
            //不获取结果,不用定义返回类型
 | 
						||
            await _mediator.Send(new ConsistenCheckCommand() { ETCList = etcCheckList, TrialId = trialId });
 | 
						||
 | 
						||
            return ResponseOutput.Ok();
 | 
						||
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    #endregion
 | 
						||
 | 
						||
 | 
						||
 | 
						||
 | 
						||
    #region 项目 系统  基本文件 上传  下载 预览
 | 
						||
 | 
						||
    [ApiController, ApiExplorerSettings(GroupName = "Common")]
 | 
						||
 | 
						||
    public class UploadDownLoadController : UploadBaseController
 | 
						||
    {
 | 
						||
        public IMapper _mapper { get; set; }
 | 
						||
        public IUserInfo _userInfo { get; set; }
 | 
						||
        private readonly IMediator _mediator;
 | 
						||
        public IStringLocalizer _localizer { get; set; }
 | 
						||
        private readonly IWebHostEnvironment _hostEnvironment;
 | 
						||
 | 
						||
        public UploadDownLoadController(IMapper mapper, IUserInfo userInfo, IStringLocalizer localizer, IMediator mediator, IWebHostEnvironment hostEnvironment)
 | 
						||
        {
 | 
						||
            _hostEnvironment = hostEnvironment;
 | 
						||
            _localizer = localizer;
 | 
						||
            _mediator = mediator;
 | 
						||
            _mapper = mapper;
 | 
						||
            _userInfo = userInfo;
 | 
						||
        }
 | 
						||
 | 
						||
        [HttpPost, Route("TrialSiteSurvey/UploadTrialSiteSurveyUser")]
 | 
						||
        [DisableFormValueModelBinding]
 | 
						||
        [UnitOfWork]
 | 
						||
        public async Task<IResponseOutput> UploadTrialSiteSurveyUser(Guid trialId, string baseUrl, string routeUrl,
 | 
						||
    [FromServices] IRepository<TrialSite> _trialSiteRepository,
 | 
						||
     [FromServices] IRepository<UserType> _usertypeRepository,
 | 
						||
     [FromServices] ITrialSiteSurveyService _trialSiteSurveyService,
 | 
						||
     [FromServices] IOSSService oSSService,
 | 
						||
     [FromServices] IRepository<InspectionFile> _inspectionFileRepository)
 | 
						||
        {
 | 
						||
            var templateFileStream = new MemoryStream();
 | 
						||
 | 
						||
 | 
						||
            await FileUploadToOSSAsync(async (realFileName, fileStream) =>
 | 
						||
            {
 | 
						||
                await fileStream.CopyToAsync(templateFileStream);
 | 
						||
                templateFileStream.Seek(0, SeekOrigin.Begin);
 | 
						||
 | 
						||
                if (!realFileName.EndsWith(".xlsx", StringComparison.OrdinalIgnoreCase))
 | 
						||
                {
 | 
						||
                    //	 请用提供格式的模板excel上传需要处理的数据
 | 
						||
                    throw new BusinessValidationFailedException(_localizer["UploadDownLoad_TemplateUploadData"]);
 | 
						||
                }
 | 
						||
 | 
						||
                var ossRelativePath = await oSSService.UploadToOSSAsync(fileStream, "InspectionUpload/SiteSurvey", realFileName);
 | 
						||
 | 
						||
                await _inspectionFileRepository.AddAsync(new InspectionFile() { FileName = realFileName, RelativePath = ossRelativePath, TrialId = trialId });
 | 
						||
 | 
						||
 | 
						||
 | 
						||
                return ossRelativePath;
 | 
						||
 | 
						||
            });
 | 
						||
 | 
						||
            //去掉空白行
 | 
						||
            var excelList = MiniExcel.Query<SiteSurveyUserImportDto>(templateFileStream, excelType: ExcelType.XLSX).ToList()
 | 
						||
                .Where(t => !(string.IsNullOrWhiteSpace(t.TrialSiteCode) && string.IsNullOrWhiteSpace(t.FirstName) && string.IsNullOrWhiteSpace(t.LastName) && string.IsNullOrWhiteSpace(t.Email)
 | 
						||
                && string.IsNullOrWhiteSpace(t.Phone) && string.IsNullOrWhiteSpace(t.UserTypeStr) && string.IsNullOrWhiteSpace(t.OrganizationName))).ToList();
 | 
						||
 | 
						||
            if (excelList.Any(t => string.IsNullOrWhiteSpace(t.TrialSiteCode) || string.IsNullOrWhiteSpace(t.FirstName) || string.IsNullOrWhiteSpace(t.LastName) || string.IsNullOrWhiteSpace(t.Email) || string.IsNullOrWhiteSpace(t.UserTypeStr)))
 | 
						||
            {
 | 
						||
                //请确保Excel中 每一行的 中心编号,姓名,邮箱,用户类型数据记录完整再进行上传
 | 
						||
                throw new BusinessValidationFailedException(_localizer["UploadDownLoad_EnsureCompleteData"]);
 | 
						||
            }
 | 
						||
 | 
						||
            var siteCodeList = excelList.Select(t => t.TrialSiteCode.Trim().ToUpper()).Distinct().ToList();
 | 
						||
 | 
						||
            if (_trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode.ToUpper())).Count() != siteCodeList.Count)
 | 
						||
            {
 | 
						||
                //在项目中未找到该Excel中部分或全部中心
 | 
						||
                throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidCenters"]);
 | 
						||
            }
 | 
						||
 | 
						||
            foreach (var item in excelList.GroupBy(t => t.Email.Trim()))
 | 
						||
            {
 | 
						||
                var itemList = item.ToList();
 | 
						||
 | 
						||
                var first = item.First();
 | 
						||
 | 
						||
                if (itemList.Any(t => t.Email.Trim() != first.Email.Trim() || t.Phone.Trim() != first.Phone.Trim() || t.OrganizationName.Trim() != first.OrganizationName.Trim() || t.FirstName.Trim() != first.FirstName.Trim() || t.LastName.Trim() != first.LastName.Trim()))
 | 
						||
                {
 | 
						||
                    //同一邮箱,用户信息应该保持一致!
 | 
						||
 | 
						||
                    throw new BusinessValidationFailedException(_localizer["UploadDownLoad_CheckDuplicateAccounts"]);
 | 
						||
                }
 | 
						||
            }
 | 
						||
 | 
						||
            if (excelList.Any(t => !t.Email.Contains("@")))
 | 
						||
            {
 | 
						||
                //有邮箱不符合邮箱格式,请核查Excel数据
 | 
						||
                throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidEmail"]);
 | 
						||
            }
 | 
						||
            var generateUserTypeList = new List<string>() { "CRC", "CRA" };
 | 
						||
 | 
						||
            //if (excelList.Any(t => !generateUserTypeList.Contains(t.UserTypeStr.ToUpper())))
 | 
						||
            //{
 | 
						||
            //    //用户类型仅能为 CRC,SR,CRA 请核查Excel数据
 | 
						||
            //    throw new BusinessValidationFailedException(_localizer["UploadDownLoad_InvalidUserType"]);
 | 
						||
            //}
 | 
						||
            if (excelList.Count == 0)
 | 
						||
            {
 | 
						||
                throw new BusinessValidationFailedException(_localizer["UploadDownLoad_NoValiddata"]);
 | 
						||
            }
 | 
						||
            //处理好 用户类型  和用户类型枚举
 | 
						||
            var sysUserTypeList = _usertypeRepository.Where(t => t.UserTypeEnum == UserTypeEnum.CRA || t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).Select(t => new { UserTypeId = t.Id, t.UserTypeEnum }).ToList();
 | 
						||
            var siteList = _trialSiteRepository.Where(t => t.TrialId == trialId && siteCodeList.Contains(t.TrialSiteCode)).Select(t => new { t.TrialSiteCode, TrialSiteId = t.Id }).ToList();
 | 
						||
 | 
						||
            foreach (var item in excelList)
 | 
						||
            {
 | 
						||
                switch (item.UserTypeStr.Trim().ToUpper())
 | 
						||
                {
 | 
						||
                    case "CRC":
 | 
						||
 | 
						||
                        item.UserTypeId = sysUserTypeList.FirstOrDefault(t => t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator).UserTypeId;
 | 
						||
                        item.UserTypeEnum = UserTypeEnum.ClinicalResearchCoordinator;
 | 
						||
                        break;
 | 
						||
 | 
						||
                    case "CRA":
 | 
						||
                        item.UserTypeId = sysUserTypeList.FirstOrDefault(t => t.UserTypeEnum == UserTypeEnum.CRA).UserTypeId;
 | 
						||
                        item.UserTypeEnum = UserTypeEnum.CRA;
 | 
						||
                        break;
 | 
						||
 | 
						||
 | 
						||
 | 
						||
                }
 | 
						||
 | 
						||
                item.TrialSiteId = siteList.FirstOrDefault(t => t.TrialSiteCode.Trim().ToUpper() == item.TrialSiteCode.Trim().ToUpper()).TrialSiteId;
 | 
						||
            }
 | 
						||
 | 
						||
            var list = excelList.Where(t => t.UserTypeEnum == UserTypeEnum.ClinicalResearchCoordinator || t.UserTypeEnum == UserTypeEnum.CRA).ToList();
 | 
						||
 | 
						||
            await _trialSiteSurveyService.ImportGenerateAccountAndJoinTrialAsync(trialId, baseUrl, routeUrl, list);
 | 
						||
 | 
						||
            return ResponseOutput.Ok();
 | 
						||
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
        /// <summary>  通用文件下载 </summary>
 | 
						||
        [AllowAnonymous]
 | 
						||
        [HttpGet("CommonDocument/DownloadCommonDoc")]
 | 
						||
        public async Task<IActionResult> DownloadCommonFile(string code, [FromServices] IRepository<CommonDocument> _commonDocumentRepository)
 | 
						||
        {
 | 
						||
            var (filePath, fileName) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code);
 | 
						||
 | 
						||
            new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(filePath), out var contentType);
 | 
						||
 | 
						||
            return File(System.IO.File.OpenRead(filePath), contentType ?? "application/octet-stream", fileName);
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 上传通用文档  比如一致性核查的 比如导出的excel 模板
 | 
						||
        /// </summary>
 | 
						||
        /// <returns></returns>
 | 
						||
        [HttpPost("CommonDocument/UploadCommonDoc")]
 | 
						||
        [DisableRequestSizeLimit]
 | 
						||
        [DisableFormValueModelBinding]
 | 
						||
        public async Task<IResponseOutput> UploadCommonDoc()
 | 
						||
        {
 | 
						||
 | 
						||
            return await SingleFileUploadAsync((fileName) => FileStoreHelper.GetCommonDocPath(_hostEnvironment, fileName));
 | 
						||
        }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
        public enum UploadFileType
 | 
						||
        {
 | 
						||
            DataUpload = 1,
 | 
						||
 | 
						||
            DataDownload = 2,
 | 
						||
 | 
						||
            EmailAttachment = 3,
 | 
						||
 | 
						||
            EmailBodyHtml = 4,
 | 
						||
 | 
						||
            Other = 5
 | 
						||
        }
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// 1:数据上传  2:导出、 3:邮件附件  4:邮件Html     通过 ----new
 | 
						||
        /// </summary>
 | 
						||
        /// <returns></returns>
 | 
						||
        [HttpPost("SystemFile/Upload")]
 | 
						||
        [DisableRequestSizeLimit]
 | 
						||
        [DisableFormValueModelBinding]
 | 
						||
        public async Task<IResponseOutput> Upload(UploadFileType fileType)
 | 
						||
        {
 | 
						||
            IResponseOutput result = null;
 | 
						||
 | 
						||
            switch (fileType)
 | 
						||
            {
 | 
						||
                case UploadFileType.DataUpload:
 | 
						||
                    result = await SingleFileUploadAsync((fileName) => FileStoreHelper.GetSystemFileUploadPath(_hostEnvironment, StaticData.Folder.DataTemplate, fileName));
 | 
						||
 | 
						||
                    break;
 | 
						||
                case UploadFileType.DataDownload:
 | 
						||
                    result = await SingleFileUploadAsync((fileName) => FileStoreHelper.GetSystemFileUploadPath(_hostEnvironment, StaticData.Folder.DataTemplate, fileName));
 | 
						||
 | 
						||
                    break;
 | 
						||
                case UploadFileType.EmailAttachment:
 | 
						||
                    result = await SingleFileUploadAsync((fileName) => FileStoreHelper.GetSystemFileUploadPath(_hostEnvironment, StaticData.Folder.EmailTemplate, fileName));
 | 
						||
 | 
						||
                    break;
 | 
						||
 | 
						||
                case UploadFileType.EmailBodyHtml:
 | 
						||
                    result = await SingleFileUploadAsync((fileName) => FileStoreHelper.GetSystemFileUploadPath(_hostEnvironment, StaticData.Folder.EmailTemplate, fileName));
 | 
						||
                    break;
 | 
						||
 | 
						||
                default:
 | 
						||
                    result = await SingleFileUploadAsync((fileName) => FileStoreHelper.GetOtherFileUploadPath(_hostEnvironment, StaticData.Folder.TempFile, fileName));
 | 
						||
 | 
						||
                    break;
 | 
						||
            }
 | 
						||
 | 
						||
            return result;
 | 
						||
 | 
						||
        }
 | 
						||
 | 
						||
    }
 | 
						||
    #endregion
 | 
						||
 | 
						||
}
 |