优化上传代码
parent
ae70c7f69b
commit
5d96df5d00
|
@ -1,94 +0,0 @@
|
|||
using AutoMapper;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IRaCIS.Core.API.Controllers
|
||||
{
|
||||
[ApiExplorerSettings(GroupName = "Trial")]
|
||||
[ApiController]
|
||||
public class CommonController : ControllerBase
|
||||
{
|
||||
public IMapper _mapper { get; set; }
|
||||
public IUserInfo _userInfo { get; set; }
|
||||
|
||||
private readonly IWebHostEnvironment _hostEnvironment;
|
||||
|
||||
|
||||
|
||||
public CommonController(IMapper mapper, IUserInfo userInfo, IMediator mediator, IWebHostEnvironment hostEnvironment)
|
||||
{
|
||||
_hostEnvironment = hostEnvironment;
|
||||
_mapper = mapper;
|
||||
_userInfo = userInfo;
|
||||
}
|
||||
|
||||
|
||||
[AllowAnonymous]
|
||||
[HttpGet("Common/LocalFilePreview")]
|
||||
public async Task<FileContentResult> LocalFilePreview(string relativePath)
|
||||
{
|
||||
var rootPath = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).IfNullThrowException().FullName;
|
||||
|
||||
var _fileStorePath = Path.Combine(rootPath, relativePath.Replace('/', '\\').Trim('\\'));
|
||||
|
||||
|
||||
var storePreviewPath = _fileStorePath + ".preview.jpeg";
|
||||
|
||||
//if (!System.IO.File.Exists(storePreviewPath))
|
||||
//{
|
||||
ImageResizeHelper.ResizeSave(_fileStorePath, storePreviewPath);
|
||||
//}
|
||||
|
||||
return new FileContentResult(await System.IO.File.ReadAllBytesAsync(storePreviewPath), "image/jpeg");
|
||||
|
||||
//_logger.LogError(rootPath);
|
||||
|
||||
//_logger.LogError(_fileStorePath);
|
||||
|
||||
|
||||
//if (!File.Exists(storePreviewPath))
|
||||
//{
|
||||
|
||||
//Bitmap sourceImage = new Bitmap(File.OpenRead(_fileStorePath));
|
||||
|
||||
//System.Drawing.Image destinationImage = new Bitmap(500, 500);
|
||||
//Graphics g = Graphics.FromImage(destinationImage);
|
||||
|
||||
//g.DrawImage(
|
||||
// sourceImage,
|
||||
// new Rectangle(0, 0, 500, 500),
|
||||
// new Rectangle(0, 0, sourceImage.Width, sourceImage.Height),
|
||||
// GraphicsUnit.Pixel
|
||||
//);
|
||||
|
||||
//destinationImage.Save(storePreviewPath);
|
||||
|
||||
//var image = SKBitmap.Decode(_fileStorePath);
|
||||
////设置图片新的size
|
||||
//var newImg = image.Resize(new SKSizeI(50, 50), SKFilterQuality.Medium);
|
||||
//using var fs = new FileStream(storePreviewPath, FileMode.Create);
|
||||
//newImg.Encode(fs, SKEncodedImageFormat.Png, 100);
|
||||
//fs.Flush();
|
||||
|
||||
|
||||
//var image = NetVips.Image.NewFromFile(_fileStorePath);
|
||||
//var newImg = image.Resize(0.5);
|
||||
//newImg.WriteToFile(storePreviewPath);
|
||||
|
||||
|
||||
//var image = NetVips.Image.NewFromFile(_fileStorePath);
|
||||
//var newImg = image.ThumbnailImage(500);
|
||||
//newImg.WriteToFile(_fileStorePath);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
using AutoMapper;
|
||||
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.StaticFiles;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
|
||||
namespace IRaCIS.Core.API.Controllers
|
||||
{
|
||||
[ApiExplorerSettings(GroupName = "Trial")]
|
||||
[ApiController]
|
||||
public class DownLoadController : ControllerBase
|
||||
{
|
||||
public IMapper _mapper { get; set; }
|
||||
public IUserInfo _userInfo { get; set; }
|
||||
|
||||
private readonly IWebHostEnvironment _hostEnvironment;
|
||||
|
||||
|
||||
|
||||
public DownLoadController(IMapper mapper, IUserInfo userInfo, IMediator mediator, IWebHostEnvironment hostEnvironment)
|
||||
{
|
||||
_hostEnvironment = hostEnvironment;
|
||||
_mapper = mapper;
|
||||
_userInfo = userInfo;
|
||||
}
|
||||
|
||||
//[HttpGet("VisitPlan/DownloadInflunceStudyList{trialId:guid}/{createTime:dateTime}")]
|
||||
//public async Task<IActionResult> DownloadInflunceStudyList(Guid trialId, DateTime createTime, [FromServices] IRepository<VisitPlanInfluenceSubjectVisit> _influnceRepository)
|
||||
//{
|
||||
// var list = _influnceRepository.Where(t => t.TrialId == trialId && t.CreateTime == createTime)
|
||||
// .ProjectTo<VisitPlanInfluenceSubjectVisitDTO>(_mapper.ConfigurationProvider).ToList();
|
||||
|
||||
// if (list.Count == 0)
|
||||
// {
|
||||
// list.Add(new VisitPlanInfluenceSubjectVisitDTO() { CreateTime = DateTime.Now, SubjectCode = "test", StudyTime = DateTime.Now, IsDicomStudy = false, HistoryWindow = "test" });
|
||||
// }
|
||||
|
||||
// IExporter exporter = new ExcelExporter();
|
||||
|
||||
// var result = await exporter.ExportAsByteArray(list);
|
||||
|
||||
|
||||
// return new XlsxFileResult(bytes: bytes);
|
||||
|
||||
// //return File(result, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"检查导出_{DateTime.Now}.xlsx");
|
||||
|
||||
//}
|
||||
|
||||
|
||||
[AllowAnonymous]
|
||||
[HttpGet("CommonDocument/DownloadCommonDoc")]
|
||||
public async Task<IActionResult> DownloadCommonFile(string code, [FromServices] IRepository<CommonDocument> _commonDocumentRepository)
|
||||
{
|
||||
var doc = await _commonDocumentRepository.AsQueryable(true).FirstOrDefaultAsync(t => t.Code == code);
|
||||
|
||||
if (doc == null)
|
||||
{
|
||||
throw new Exception("当前code 没要找到对应的文件");
|
||||
}
|
||||
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
|
||||
var filePath = Path.Combine(rootPath, doc.Path.Trim('/'));
|
||||
|
||||
if (!System.IO.File.Exists(filePath))
|
||||
{
|
||||
throw new Exception("服务器本地不存在该路径文件");
|
||||
}
|
||||
|
||||
new FileExtensionContentTypeProvider().Mappings.TryGetValue(Path.GetExtension(filePath), out var contentType);
|
||||
|
||||
|
||||
return File(System.IO.File.OpenRead(filePath), contentType ?? "application/octet-stream", doc.Name);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -79,18 +79,6 @@ namespace IRaCIS.Api.Controllers
|
|||
|
||||
|
||||
|
||||
[HttpPost, Route("enroll/downloadResume/{trialId:guid}/{language}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter))]
|
||||
[AllowAnonymous]
|
||||
public async Task<IResponseOutput<string>> DownloadResume([FromServices] IFileService _fileService, int language, Guid trialId, Guid[] doctorIdArray)
|
||||
{
|
||||
var userId = Guid.Parse(User.FindFirst("id").Value);
|
||||
var zipPath = await _fileService.CreateOfficialResumeZip(language, doctorIdArray);
|
||||
|
||||
return ResponseOutput.Ok(zipPath);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary> 系统用户登录接口[New] </summary>
|
||||
|
|
|
@ -1,532 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Application.Contracts;
|
||||
using IRaCIS.Core.API.Utility;
|
||||
using IRaCIS.Core.Application.Contracts.Image;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
|
||||
namespace IRaCIS.Api.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// 文件上传
|
||||
/// </summary>
|
||||
[Route("file")]
|
||||
[ApiController, Authorize, ApiExplorerSettings(GroupName = "Common")]
|
||||
public class FileController : ControllerBase
|
||||
{
|
||||
private readonly IFileService _fileService;
|
||||
private readonly IWebHostEnvironment _webHostEnvironment;
|
||||
private readonly IHostEnvironment _hostEnvironment;
|
||||
private ILogger<FileController> _logger;
|
||||
|
||||
private string _targetFilePath;
|
||||
private readonly long _fileSizeLimit;
|
||||
private readonly string[] _permittedExtensions = { ".pdf", ".doc", ".docx" };
|
||||
|
||||
public string trustedFileNameForFileStorage = "";
|
||||
|
||||
// Get the default form options so that we can use them to set the default
|
||||
// limits for request body data.
|
||||
private static readonly FormOptions _defaultFormOptions = new FormOptions();
|
||||
private string defaultUploadFilePath = string.Empty;
|
||||
public FileController(IFileService fileService, Microsoft.Extensions.Configuration.IConfiguration config,
|
||||
IHostEnvironment hostEnvironment, ILogger<FileController> logger,
|
||||
IWebHostEnvironment webHostEnvironment)
|
||||
{
|
||||
_fileService = fileService;
|
||||
_hostEnvironment = hostEnvironment;
|
||||
_webHostEnvironment = webHostEnvironment;
|
||||
_fileSizeLimit = config.GetValue<long>("FileSizeLimit");
|
||||
defaultUploadFilePath = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).FullName;
|
||||
|
||||
_logger = logger;
|
||||
|
||||
_logger.LogWarning("File Path:" + defaultUploadFilePath);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 上传文件[FileUpload]
|
||||
/// </summary>
|
||||
/// <param name="attachmentType">附件类型</param>
|
||||
/// <param name="doctorId">医生Id</param>
|
||||
/// <returns>返回文件信息</returns>
|
||||
[HttpPost, Route("uploadFile/{attachmentType}/{doctorId}")]
|
||||
[DisableFormValueModelBinding]
|
||||
public async Task<IActionResult> UploadOrdinaryFile(string attachmentType, Guid doctorId)
|
||||
{
|
||||
#region 官方文档方式
|
||||
|
||||
|
||||
if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
|
||||
{
|
||||
ModelState.AddModelError("File",
|
||||
$"The request couldn't be processed (Error 1).");
|
||||
// Log error
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
var boundary = MultipartRequestHelper.GetBoundary(
|
||||
MediaTypeHeaderValue.Parse(Request.ContentType),
|
||||
_defaultFormOptions.MultipartBoundaryLengthLimit);
|
||||
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)
|
||||
{
|
||||
// This check assumes that there's a file
|
||||
// present without form data. If form data
|
||||
// is present, this method immediately fails
|
||||
// and returns the model error.
|
||||
if (!MultipartRequestHelper
|
||||
.HasFileContentDisposition(contentDisposition))
|
||||
{
|
||||
ModelState.AddModelError("File",
|
||||
$"The request couldn't be processed (Error 2).");
|
||||
// Log error
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't trust the file name sent by the client. To display
|
||||
// the file name, HTML-encode the value.
|
||||
var trustedFileNameForDisplay = WebUtility.HtmlEncode(
|
||||
contentDisposition.FileName.Value);
|
||||
|
||||
//var trustedFileNameForFileStorage = Path.GetRandomFileName();
|
||||
trustedFileNameForFileStorage = contentDisposition.FileName.Value;
|
||||
|
||||
// **WARNING!**
|
||||
// In the following example, the file is saved without
|
||||
// scanning the file's contents. In most production
|
||||
// scenarios, an anti-virus/anti-malware scanner API
|
||||
// is used on the file before making the file available
|
||||
// for download or for use by other systems.
|
||||
// For more information, see the topic that accompanies
|
||||
// this sample.
|
||||
|
||||
var streamedFileContent = await FileHelpers.ProcessStreamedFile(
|
||||
section, contentDisposition, ModelState,
|
||||
_permittedExtensions, _fileSizeLimit);
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BadRequest(ModelState);
|
||||
}
|
||||
|
||||
|
||||
//实际文件处理
|
||||
string uploadFolderPath = Path.Combine(defaultUploadFilePath, "UploadFile/" + doctorId + "/");
|
||||
|
||||
var doctorAttachmentUploadFolder = Path.Combine(uploadFolderPath, attachmentType);
|
||||
|
||||
_targetFilePath = doctorAttachmentUploadFolder;
|
||||
|
||||
if (!Directory.Exists(doctorAttachmentUploadFolder)) Directory.CreateDirectory(doctorAttachmentUploadFolder);
|
||||
|
||||
using (var targetStream = System.IO.File.Create(
|
||||
Path.Combine(_targetFilePath, trustedFileNameForFileStorage)))
|
||||
{
|
||||
await targetStream.WriteAsync(streamedFileContent);
|
||||
|
||||
var attachmentPath = $"/UploadFile/{doctorId}/{attachmentType}/{trustedFileNameForFileStorage}";
|
||||
|
||||
return new JsonResult(ResponseOutput.Ok(new UploadFileInfoDTO() { FilePath = attachmentPath, FullFilePath = attachmentPath + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7) }));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Drain any remaining section body that hasn't been consumed and
|
||||
// read the headers for the next section.
|
||||
section = await reader.ReadNextSectionAsync();
|
||||
}
|
||||
|
||||
|
||||
return Created(nameof(FileController), null);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 上传文件( 不是医生个人的文件)[FileUpload]
|
||||
/// 例如:阅片章程等
|
||||
/// </summary>
|
||||
/// <param name="type">文件类型</param>
|
||||
/// <returns></returns>
|
||||
|
||||
[HttpPost, Route("uploadNonDoctorFile/{type}")]
|
||||
[DisableFormValueModelBinding]
|
||||
public async Task<IActionResult> UploadNonDoctorFile(string type)
|
||||
{
|
||||
#region New Test 实测OK
|
||||
|
||||
//上传根路径
|
||||
string uploadFolderPath = Path.Combine(defaultUploadFilePath, "UploadFile");
|
||||
|
||||
|
||||
if (uploadFolderPath != null)
|
||||
{
|
||||
//文件类型路径处理
|
||||
var uploadTypePath = Path.Combine(uploadFolderPath, type);
|
||||
if (!Directory.Exists(uploadTypePath)) Directory.CreateDirectory(uploadTypePath);
|
||||
|
||||
|
||||
////实际文件处理
|
||||
|
||||
_targetFilePath = uploadTypePath;
|
||||
|
||||
//获取boundary
|
||||
|
||||
#region 方式二
|
||||
|
||||
var boundary = MultipartRequestHelper.GetBoundary(
|
||||
MediaTypeHeaderValue.Parse(Request.ContentType),
|
||||
_defaultFormOptions.MultipartBoundaryLengthLimit);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 方式一
|
||||
//var boundary = HeaderUtilities.RemoveQuotes(MediaTypeHeaderValue.Parse(Request.ContentType).Boundary).Value;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
//得到reader
|
||||
var reader = new MultipartReader(boundary, HttpContext.Request.Body);
|
||||
//{ BodyLengthLimit = 2000 };//
|
||||
var section = await reader.ReadNextSectionAsync();
|
||||
|
||||
//读取section
|
||||
while (section != null)
|
||||
{
|
||||
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
|
||||
if (hasContentDispositionHeader)
|
||||
{
|
||||
trustedFileNameForFileStorage = contentDisposition.FileName.Value;
|
||||
|
||||
|
||||
await WriteFileAsync(section.Body, Path.Combine(_targetFilePath, trustedFileNameForFileStorage));
|
||||
|
||||
#region 方式二
|
||||
|
||||
//using (var targetStream = System.IO.File.Create(
|
||||
// Path.Combine(_targetFilePath, trustedFileNameForFileStorage)))
|
||||
//{
|
||||
|
||||
// using (var memoryStream = new MemoryStream())
|
||||
// {
|
||||
// await section.Body.CopyToAsync(memoryStream);
|
||||
|
||||
// await targetStream.WriteAsync(memoryStream.ToArray());
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
var attachmentPath = $"/UploadFile/{type}/{trustedFileNameForFileStorage}";
|
||||
|
||||
return new JsonResult(ResponseOutput.Ok(new UploadFileInfoDTO() { FilePath = attachmentPath, FullFilePath = attachmentPath + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7) }));
|
||||
}
|
||||
|
||||
section = await reader.ReadNextSectionAsync();
|
||||
}
|
||||
return Created(nameof(FileController), null);
|
||||
|
||||
|
||||
}
|
||||
return new JsonResult(ResponseOutput.NotOk("服务器端映射路径操作失败"));
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 写文件导到磁盘
|
||||
/// </summary>
|
||||
/// <param name="stream">流</param>
|
||||
/// <param name="path">文件保存路径</param>
|
||||
/// <returns></returns>
|
||||
public 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;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#region 上传无影响部分
|
||||
|
||||
/// <summary>
|
||||
/// 下载多个医生的所有附件
|
||||
/// </summary>
|
||||
/// <param name="doctorIds"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
[HttpPost, Route("downloadDoctorAttachments")]
|
||||
public async Task<IResponseOutput<UploadFileInfoDTO>> DownloadAttachment(Guid[] doctorIds)
|
||||
{
|
||||
|
||||
var path = await _fileService.CreateDoctorsAllAttachmentZip(doctorIds);
|
||||
|
||||
return ResponseOutput.Ok(new UploadFileInfoDTO
|
||||
{
|
||||
FilePath = path,
|
||||
FullFilePath = path + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7)
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载医生官方简历
|
||||
/// </summary>
|
||||
/// <param name="language"></param>
|
||||
/// <param name="doctorIds"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost, Route("downloadOfficialCV/{language}")]
|
||||
public async Task<IResponseOutput<UploadFileInfoDTO>> DownloadOfficialResume(int language, Guid[] doctorIds)
|
||||
{
|
||||
|
||||
var path = _fileService.CreateDoctorsAllAttachmentZip(doctorIds);
|
||||
return ResponseOutput.Ok(new UploadFileInfoDTO
|
||||
{
|
||||
FilePath = await _fileService.CreateOfficialResumeZip(language, doctorIds),
|
||||
FullFilePath = path + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7)
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载指定医生的指定附件
|
||||
/// </summary>
|
||||
/// <param name="doctorId">医生Id</param>
|
||||
/// <param name="attachmentIds">要下载的附件Id</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost, Route("downloadByAttachmentId/{doctorId}")]
|
||||
public async Task<IResponseOutput<UploadFileInfoDTO>> DownloadAttachmentById(Guid doctorId, Guid[] attachmentIds)
|
||||
{
|
||||
var path = await _fileService.CreateZipPackageByAttachment(doctorId, attachmentIds);
|
||||
return ResponseOutput.Ok(new UploadFileInfoDTO
|
||||
{
|
||||
FilePath = await _fileService.CreateZipPackageByAttachment(doctorId, attachmentIds),
|
||||
FullFilePath = path + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7)
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 废弃
|
||||
|
||||
public class UploadDTFCommand
|
||||
{
|
||||
public Guid TrialId { get; set; }
|
||||
public Guid SiteId { get; set; }
|
||||
public Guid SubjectId { get; set; }
|
||||
public Guid SubjectVisitId { get; set; }
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 流式上传 临时文件
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("UploadDTF/{trialId:guid}/{siteId:guid}/{subjectId:guid}/{subjectVisitId:guid}/{studyId:guid}")]
|
||||
[DisableFormValueModelBinding]
|
||||
[DisableRequestSizeLimit]
|
||||
[Obsolete]
|
||||
public async Task<IResponseOutput> UploadingStream(Guid trialId, Guid siteId, Guid subjectId, Guid subjectVisitId, Guid studyId, [FromServices] IStudyDTFService studyDTFService)
|
||||
{
|
||||
|
||||
//上传根路径
|
||||
string uploadFolderPath = Path.Combine(defaultUploadFilePath, "Dicom");
|
||||
|
||||
|
||||
var dtfPath = Path.Combine(uploadFolderPath, DateTime.Now.Year.ToString(), trialId.ToString(),
|
||||
siteId.ToString(), subjectId.ToString(), subjectVisitId.ToString());
|
||||
|
||||
if (!Directory.Exists(dtfPath))
|
||||
{
|
||||
Directory.CreateDirectory(dtfPath);
|
||||
}
|
||||
|
||||
|
||||
#region 之前DTF 先上传临时文件,再拷贝
|
||||
////上传根路径
|
||||
//string uploadFolderPath = Path.Combine(defaultUploadFilePath, "UploadFile");
|
||||
////文件类型路径处理
|
||||
//var uploadTempFilePath = Path.Combine(uploadFolderPath, "TempFile");
|
||||
//if (!Directory.Exists(uploadTempFilePath)) Directory.CreateDirectory(uploadTempFilePath);
|
||||
|
||||
|
||||
//var trustedFileNameForFileStorage = Guid.NewGuid().ToString() + fileNameEX;
|
||||
|
||||
//await WriteFileAsync(section.Body, Path.Combine(uploadTempFilePath, trustedFileNameForFileStorage));
|
||||
|
||||
//var attachmentPath = $"{uploadTempFilePath}/{trustedFileNameForFileStorage}";
|
||||
|
||||
////多个文件上传,在这里返回就不合适,需要在外层,返回所有的文件路径,实际需要时再更改
|
||||
//return ResponseOutput.Ok(new UploadFileInfoDTO() { FilePath = attachmentPath });
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
//获取boundary
|
||||
var boundary = HeaderUtilities.RemoveQuotes(MediaTypeHeaderValue.Parse(Request.ContentType).Boundary).Value;
|
||||
//得到reader
|
||||
var reader = new MultipartReader(boundary, HttpContext.Request.Body);
|
||||
|
||||
var section = await reader.ReadNextSectionAsync();
|
||||
|
||||
//读取section
|
||||
while (section != null)
|
||||
{
|
||||
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
|
||||
if (hasContentDispositionHeader)
|
||||
{
|
||||
var realName = contentDisposition.FileName.Value;
|
||||
|
||||
var fileNameEX = Path.GetExtension(contentDisposition.FileName.Value);
|
||||
var trustedFileNameForFileStorage = Guid.NewGuid().ToString() + fileNameEX;
|
||||
|
||||
|
||||
var relativePath = $"/Dicom/{DateTime.Now.Year.ToString()}/{trialId}/{siteId}/{subjectId}/{subjectVisitId}/{trustedFileNameForFileStorage}";
|
||||
studyDTFService.AddStudyDTF(new Core.Application.Contracts.Dicom.DTO.StudyDTFAddOrUpdateCommand()
|
||||
{
|
||||
StudyId = studyId,
|
||||
|
||||
FileName = realName,
|
||||
|
||||
Path = relativePath
|
||||
});
|
||||
|
||||
await WriteFileAsync(section.Body, Path.Combine(dtfPath, trustedFileNameForFileStorage));
|
||||
|
||||
//仅仅返回一个文件,如果多文件上传 在最后返回多个路径
|
||||
return ResponseOutput.Ok(new UploadFileInfoDTO() { FilePath = relativePath, FullFilePath = relativePath + "?access_token=" + HttpContext.Request.Headers["Authorization"].ToString().Substring(7) });
|
||||
}
|
||||
section = await reader.ReadNextSectionAsync();
|
||||
}
|
||||
return ResponseOutput.NotOk("Upload error");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 流式上传 非Dicom文件
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("UploadNoneDICOM")]
|
||||
[DisableFormValueModelBinding]
|
||||
[DisableRequestSizeLimit]
|
||||
[Obsolete]
|
||||
public async Task<IResponseOutput> UploadingNoneDicomStream([FromForm] ArchiveStudyCommand archiveStudyCommand, [FromServices] IStudyService studyService)
|
||||
{
|
||||
//上传根路径
|
||||
string uploadFolderPath = Path.Combine(defaultUploadFilePath, "Dicom");
|
||||
|
||||
//文件类型路径处理
|
||||
//var noneDicomPath = Path.Combine(uploadFolderPath, DateTime.Now.Year.ToString(), archiveStudyCommand.TrialId.ToString(),
|
||||
// archiveStudyCommand.SiteId.ToString(), archiveStudyCommand.SubjectId.ToString(), archiveStudyCommand.SubjectVisitId.ToString(), "Data");
|
||||
|
||||
//var dtfPath = Path.Combine(uploadFolderPath, DateTime.Now.Year.ToString(), archiveStudyCommand.TrialId.ToString(),
|
||||
// archiveStudyCommand.SiteId.ToString(), archiveStudyCommand.SubjectId.ToString(), archiveStudyCommand.SubjectVisitId.ToString());
|
||||
|
||||
var noneDicomPath = string.Empty;
|
||||
|
||||
var dtfPath = string.Empty;
|
||||
|
||||
var tempDtfPath = Path.Combine(defaultUploadFilePath/*, archiveStudyCommand.DTFPath*/);
|
||||
|
||||
|
||||
if (!Directory.Exists(noneDicomPath))
|
||||
{
|
||||
Directory.CreateDirectory(noneDicomPath);
|
||||
}
|
||||
if (!System.IO.File.Exists(tempDtfPath))
|
||||
{
|
||||
return ResponseOutput.NotOk("DTF file can not found");
|
||||
}
|
||||
|
||||
System.IO.File.Move(tempDtfPath, dtfPath);
|
||||
|
||||
var saveFileDic = new Dictionary<string, string>();
|
||||
|
||||
//获取boundary
|
||||
var boundary = HeaderUtilities.RemoveQuotes(MediaTypeHeaderValue.Parse(Request.ContentType).Boundary).Value;
|
||||
//得到reader
|
||||
var reader = new MultipartReader(boundary, HttpContext.Request.Body);
|
||||
|
||||
var section = await reader.ReadNextSectionAsync();
|
||||
|
||||
//读取section
|
||||
while (section != null)
|
||||
{
|
||||
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
|
||||
if (hasContentDispositionHeader)
|
||||
{
|
||||
var fileName = contentDisposition.FileName.Value;
|
||||
var fileNameEX = Path.GetExtension(contentDisposition.FileName.Value);
|
||||
var trustedFileNameForFileStorage = Guid.NewGuid() + fileNameEX;
|
||||
|
||||
|
||||
|
||||
await WriteFileAsync(section.Body, Path.Combine(noneDicomPath, trustedFileNameForFileStorage));
|
||||
|
||||
var attachmentPath = $"{noneDicomPath}/{trustedFileNameForFileStorage}";
|
||||
|
||||
saveFileDic.Add(attachmentPath, fileName);
|
||||
|
||||
|
||||
}
|
||||
section = await reader.ReadNextSectionAsync();
|
||||
}
|
||||
|
||||
//处理数据库操作
|
||||
|
||||
//studyService.DealNonDicomFile(saveFileDic, archiveStudyCommand);
|
||||
return ResponseOutput.Ok(saveFileDic);
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
|
@ -10,7 +10,6 @@ using System.Threading.Tasks;
|
|||
using IRaCIS.Application.Services;
|
||||
using IRaCIS.Core.Application.Service.Inspection.DTO;
|
||||
using IRaCIS.Core.Infra.EFCore;
|
||||
using IRaCIS.Core.Application.Service.Inspection.Interface;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Application.Auth;
|
||||
|
||||
|
@ -23,15 +22,12 @@ namespace IRaCIS.Core.API.Controllers.Special
|
|||
{
|
||||
private readonly ITrialService _trialService;
|
||||
private readonly ICalculateService _calculateService;
|
||||
private readonly IInspectionService _inspectionService;
|
||||
|
||||
public FinancialChangeController(ITrialService trialService, ICalculateService calculateService,
|
||||
IInspectionService inspectionService
|
||||
public FinancialChangeController(ITrialService trialService, ICalculateService calculateService
|
||||
)
|
||||
{
|
||||
_trialService = trialService;
|
||||
_calculateService = calculateService;
|
||||
this._inspectionService = inspectionService;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using AutoMapper;
|
||||
using Castle.Core.Internal;
|
||||
using IRaCIS.Application.Contracts;
|
||||
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Contracts.DTO;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
|
||||
using IRaCIS.Core.Application.Image.QA;
|
||||
using IRaCIS.Core.Application.Interfaces;
|
||||
using IRaCIS.Core.Application.Service.Inspection.DTO;
|
||||
|
|
|
@ -1,432 +0,0 @@
|
|||
using IRaCIS.Application.Interfaces;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using IRaCIS.Core.Application.Contracts.Dicom.DTO;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using System.Threading.Tasks;
|
||||
using IRaCIS.Core.Application.Contracts.Dicom;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Infrastructure.Extention;
|
||||
using EasyCaching.Core;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Domain.Models;
|
||||
using IRaCIS.Core.Application.Service.Inspection.Interface;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
|
||||
namespace IRaCIS.Api.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// Study
|
||||
/// </summary>
|
||||
[Route("study")]
|
||||
[ApiController, Authorize, ApiExplorerSettings(GroupName = "Image")]
|
||||
public class StudyController : ControllerBase
|
||||
{
|
||||
private readonly IStudyService _studyService;
|
||||
private readonly IDicomArchiveService _dicomArchiveService;
|
||||
private readonly ILogger<StudyController> _logger;
|
||||
private readonly IDictionaryService _dictionaryService;
|
||||
private readonly IInspectionService _inspectionService;
|
||||
private IEasyCachingProvider _provider;
|
||||
private IUserInfo _userInfo;
|
||||
private static object _locker = new object();
|
||||
|
||||
|
||||
public StudyController(IStudyService studyService,
|
||||
IDicomArchiveService dicomArchiveService,
|
||||
ILogger<StudyController> logger,
|
||||
IDictionaryService dictionaryService,
|
||||
IInspectionService inspectionService,
|
||||
IEasyCachingProvider provider, IUserInfo userInfo
|
||||
)
|
||||
{
|
||||
_userInfo = userInfo;
|
||||
_provider = provider;
|
||||
_studyService = studyService;
|
||||
_dicomArchiveService = dicomArchiveService;
|
||||
_logger = logger;
|
||||
this._dictionaryService = dictionaryService;
|
||||
this._inspectionService = inspectionService;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary> 归档</summary>
|
||||
[HttpPost, Route("archiveStudy/{trialId:guid}")]
|
||||
[DisableFormValueModelBinding]
|
||||
[DisableRequestSizeLimit]
|
||||
[TypeFilter(typeof(TrialResourceFilter))]
|
||||
public async Task<IResponseOutput> ArchiveStudy([FromForm] ArchiveStudyCommand archiveStudyCommand)
|
||||
{
|
||||
|
||||
string studycode = string.Empty;
|
||||
var startTime = DateTime.Now;
|
||||
|
||||
if (_provider.Exists("StudyUid_" + archiveStudyCommand.StudyInstanceUid))
|
||||
{
|
||||
return ResponseOutput.NotOk("当前已有人正在上传和归档该检查!");
|
||||
}
|
||||
else
|
||||
{
|
||||
_provider.Set("StudyUid_" + archiveStudyCommand.StudyInstanceUid, _userInfo.Id, TimeSpan.FromMinutes(30));
|
||||
}
|
||||
|
||||
var archiveResult = new DicomArchiveResult();
|
||||
var archivedStudyIds = new List<Guid>();
|
||||
var seriesInstanceUidList = new List<string>();
|
||||
var instanceUidList = new List<string>();
|
||||
|
||||
//重传的时候,找出当前检查已经上传的series instance
|
||||
if (archiveStudyCommand.AbandonStudyId != null)
|
||||
{
|
||||
_studyService.GetHasUploadSeriesAndInstance(archiveStudyCommand.AbandonStudyId.Value, ref seriesInstanceUidList, ref instanceUidList);
|
||||
}
|
||||
|
||||
var savedInfo = _studyService.GetSaveToDicomInfo(archiveStudyCommand.SubjectVisitId);
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
//采用post方式 这里多加一个判断 过滤其他参数
|
||||
if (string.IsNullOrEmpty(section.ContentType))
|
||||
{
|
||||
section = await reader.ReadNextSectionAsync();
|
||||
continue;
|
||||
}
|
||||
|
||||
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
|
||||
if (hasContentDispositionHeader)
|
||||
{
|
||||
string fileName = contentDisposition.FileName.Value;
|
||||
try
|
||||
{
|
||||
|
||||
string mediaType = section.ContentType;
|
||||
|
||||
if (mediaType.Contains("zip"))
|
||||
{
|
||||
var partStream = section.Body;
|
||||
using (var zipArchive = new ZipArchive(partStream, ZipArchiveMode.Read))
|
||||
{
|
||||
foreach (var entry in zipArchive.Entries)
|
||||
{
|
||||
if (entry.FullName.EndsWith("/")) continue;
|
||||
try
|
||||
{
|
||||
++archiveResult.ReceivedFileCount;
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
await section.Body.CopyToAsync(memoryStream);
|
||||
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
var archiveStudyId = await _dicomArchiveService.ArchiveDicomStreamAsync(memoryStream, savedInfo, seriesInstanceUidList, instanceUidList);
|
||||
studycode = archiveStudyId.Item2;
|
||||
if (!archivedStudyIds.Contains(archiveStudyId.Item1))
|
||||
archivedStudyIds.Add(archiveStudyId.Item1);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
archiveResult.ErrorFiles.Add($"{fileName}/{entry.FullName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++archiveResult.ReceivedFileCount;
|
||||
|
||||
|
||||
if (mediaType.Contains("octet-stream"))
|
||||
{
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
await section.Body.CopyToAsync(memoryStream);
|
||||
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
var archiveStudyId = await _dicomArchiveService.ArchiveDicomStreamAsync(memoryStream, savedInfo, seriesInstanceUidList, instanceUidList);
|
||||
studycode = archiveStudyId.Item2;
|
||||
|
||||
|
||||
if (!archivedStudyIds.Contains(archiveStudyId.Item1))
|
||||
archivedStudyIds.Add(archiveStudyId.Item1);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.LogError(e.Message + e.StackTrace);
|
||||
|
||||
archiveResult.ErrorFiles.Add(fileName);
|
||||
|
||||
_provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid);
|
||||
|
||||
}
|
||||
}
|
||||
section = await reader.ReadNextSectionAsync();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (archivedStudyIds.Count > 0) // 上传成功,处理逻辑
|
||||
{
|
||||
|
||||
|
||||
// 同一个访视 多个线程上传处理 批量保存 可能造成死锁 https://www.cnblogs.com/johnblogs/p/9945767.html
|
||||
|
||||
await _dicomArchiveService.DicomDBDataSaveChange();
|
||||
|
||||
//sw.Stop();
|
||||
_studyService.UploadOrReUploadNeedTodo(archiveStudyCommand, archivedStudyIds, ref archiveResult, new StudyMonitor()
|
||||
{
|
||||
TrialId = savedInfo.TrialId,
|
||||
SiteId = savedInfo.SiteId,
|
||||
SubjectId = savedInfo.SubjectId,
|
||||
SubjectVisitId = savedInfo.SubjectVisitId,
|
||||
StudyId = archivedStudyIds[0],
|
||||
|
||||
StudyCode= studycode,
|
||||
UploadStartTime = startTime,
|
||||
UploadFinishedTime = DateTime.Now,
|
||||
//TotalMillisecondsInterval = (DateTime.Now- startTime).TotalMilliseconds,
|
||||
FileSize = (decimal)HttpContext.Request.ContentLength,
|
||||
FileCount = archiveResult.ReceivedFileCount,
|
||||
IsDicom = true,
|
||||
IsDicomReUpload = archiveStudyCommand.AbandonStudyId != null,
|
||||
IP = _userInfo.IP
|
||||
});
|
||||
|
||||
_provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return ResponseOutput.NotOk("未完成该检查的归档");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
_logger.LogError(e.Message + e.StackTrace);
|
||||
|
||||
_provider.Remove("StudyUid_" + archiveStudyCommand.StudyInstanceUid);
|
||||
|
||||
return ResponseOutput.NotOk(e.Message, ApiResponseCodeEnum.ProgramException);
|
||||
|
||||
}
|
||||
|
||||
return ResponseOutput.Ok(archiveResult);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#region 2021.12.14 整理废弃
|
||||
|
||||
//[Obsolete]
|
||||
//[HttpGet, Route("forwardStudy/{studyId:guid}/{trialId:guid}")]
|
||||
//[TrialAudit(AuditType.StudyAudit, AuditOptType.Forwarded)]
|
||||
//[TypeFilter(typeof(TrialResourceFilter))]
|
||||
|
||||
//public IResponseOutput ForwardStudy(Guid studyId)
|
||||
//{
|
||||
// return _studyService.ForwardStudy(studyId);
|
||||
//}
|
||||
|
||||
///// <summary> 指定资源Id,获取Dicom检查信息 </summary>
|
||||
///// <param name="studyId"> Dicom检查的Id </param>
|
||||
//[HttpGet, Route("item/{studyId:guid}")]
|
||||
//[Obsolete]
|
||||
//public IResponseOutput<DicomStudyDTO> GetStudyItem(Guid studyId)
|
||||
//{
|
||||
// return ResponseOutput.Ok(_studyService.GetStudyItem(studyId));
|
||||
//}
|
||||
|
||||
//[Obsolete]
|
||||
//[HttpDelete, Route("deleteStudy/{id:guid}/{trialId:guid}")]
|
||||
//public IResponseOutput DeleteStudy(Guid id)
|
||||
//{
|
||||
// return _studyService.DeleteStudy(id);
|
||||
//}
|
||||
|
||||
//[Obsolete]
|
||||
//[HttpPost, Route("getStudyList")]
|
||||
//public IResponseOutput<PageOutput<StudyDTO>> GetStudyList(StudyQueryDTO queryDto)
|
||||
//{
|
||||
// return ResponseOutput.Ok(_studyService.GetStudyList(queryDto));
|
||||
//}
|
||||
|
||||
|
||||
/////// <summary> 指定资源Id,渲染Dicom检查的Jpeg预览图像 </summary>
|
||||
/////// <param name="studyId"> Dicom检查的Id </param>
|
||||
////[HttpGet, Route("preview/{studyId:guid}")]
|
||||
////[AllowAnonymous]
|
||||
////public FileContentResult GetStudyPreview(Guid studyId)
|
||||
////{
|
||||
//// string path = _studyService.GetStudyPreview(studyId);
|
||||
//// using (var sw = DicomRenderingHelper.RenderPreviewJpeg(path))
|
||||
//// {
|
||||
//// var bytes = new byte[sw.Length];
|
||||
//// sw.Read(bytes, 0, bytes.Length);
|
||||
//// sw.Close();
|
||||
//// return new FileContentResult(bytes, "image/jpeg");
|
||||
//// }
|
||||
////}
|
||||
|
||||
///// <summary>
|
||||
///// Dicom匿名化
|
||||
///// </summary>
|
||||
///// <param name="studyId">需要匿名化的检查Id</param>
|
||||
///// <returns></returns>
|
||||
//[HttpPost, Route("dicomAnonymize/{studyId:guid}/{trialId:guid}")]
|
||||
//[TrialAudit(AuditType.StudyAudit, AuditOptType.Anonymized)]
|
||||
//[Obsolete]
|
||||
//[TypeFilter(typeof(TrialResourceFilter))]
|
||||
//public async Task<IResponseOutput> DicomAnonymize(Guid studyId)
|
||||
//{
|
||||
// string userName = User.FindFirst("realName").Value; ;
|
||||
// return await _studyService.DicomAnonymize(studyId, userName);
|
||||
//}
|
||||
|
||||
|
||||
///// <summary>
|
||||
///// 获取受试者 这次访视 对应的study modality 列表
|
||||
///// </summary>
|
||||
///// <param name="trialId"></param>
|
||||
///// <param name="siteId"></param>
|
||||
///// <param name="subjectId"></param>
|
||||
///// <param name="subjectVisitId"></param>
|
||||
///// <returns></returns>
|
||||
//[HttpPost, Route("getSubjectVisitStudyList/{trialId:guid}/{siteId:guid}/{subjectId:guid}/{subjectVisitId:guid}")]
|
||||
//[Obsolete]
|
||||
//[AllowAnonymous]
|
||||
//public IResponseOutput<List<SubjectVisitStudyDTO>> GetSubjectVisitStudyList(Guid trialId, Guid siteId, Guid subjectId,
|
||||
// Guid subjectVisitId)
|
||||
//{
|
||||
// return ResponseOutput.Ok(_studyService.GetSubjectVisitStudyList(trialId, siteId, subjectId, subjectVisitId));
|
||||
//}
|
||||
|
||||
//[HttpPost, Route("getDistributeStudyList")]
|
||||
//[Obsolete]
|
||||
//public IResponseOutput<PageOutput<DistributeReviewerStudyStatusDTO>> GetDistributeStudyList(StudyStatusQueryDTO studyStatusQueryDto)
|
||||
//{
|
||||
// return ResponseOutput.Ok(_studyService.GetDistributeStudyList(studyStatusQueryDto));
|
||||
//}
|
||||
|
||||
/////// <summary> 删除检查</summary>
|
||||
////[HttpDelete, Route("deleteStudy/{id:guid}/{trialId:guid}")]
|
||||
////
|
||||
////[TypeFilter(typeof(TrialResourceFilter))]
|
||||
////public IResponseOutput DeleteStudy(Guid id)
|
||||
////{
|
||||
//// return _studyService.DeleteStudy(id);
|
||||
////}
|
||||
|
||||
///// <summary> 更新Study状态,并保存状态变更信息 </summary>
|
||||
///// <param name="studyStatusDetailCommand"></param>
|
||||
|
||||
//[HttpPost, Route("updateStudyStatus/{trialId:guid}")]
|
||||
|
||||
//[TrialAudit(AuditType.StudyAudit, AuditOptType.ChangeStudyStatus)]
|
||||
//[Obsolete]
|
||||
//[TypeFilter(typeof(TrialResourceFilter))]
|
||||
//public IResponseOutput UpdateStudyStatus(StudyStatusDetailCommand studyStatusDetailCommand)
|
||||
//{
|
||||
// return _studyService.UpdateStudyStatus(studyStatusDetailCommand);
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// 根据项目Id 获取可选医生列表
|
||||
///// </summary>
|
||||
///// <param name="trialId"></param>
|
||||
///// <returns></returns>
|
||||
//[HttpGet, Route("GetReviewerList/{trialId:guid}")]
|
||||
//[Obsolete]
|
||||
//public IResponseOutput<List<ReviewerDistributionDTO>> GetReviewerListByTrialId(Guid trialId)
|
||||
//{
|
||||
// var result = _studyService.GetReviewerListByTrialId(trialId);
|
||||
// return ResponseOutput.Ok(result);
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// 根据StudyId获取该Study的操作记录,时间倒序
|
||||
///// </summary>
|
||||
///// <param name="studyId"></param>
|
||||
///// <returns></returns>
|
||||
//[HttpGet, Route("getStudyStatusDetailList/{studyId:guid}")]
|
||||
//[Obsolete]
|
||||
//public IResponseOutput<List<StudyStatusDetailDTO>> GetStudyStatusDetailList(Guid studyId)
|
||||
//{
|
||||
// var result = _studyService.GetStudyStatusDetailList(studyId);
|
||||
// return ResponseOutput.Ok(result);
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// 获取某个访视的关联访视
|
||||
///// 用于获取关联影像(调用之前的接口:/series/list/,根据StudyId,获取访视的序列列表)
|
||||
///// </summary>
|
||||
///// <param name="visitNum"></param>
|
||||
///// <param name="tpCode"></param>
|
||||
///// <returns></returns>
|
||||
//[HttpGet, Route("getRelationVisitList/{visitNum}/{tpCode}")]
|
||||
//[Obsolete]
|
||||
//[AllowAnonymous]
|
||||
//public IResponseOutput<IEnumerable<RelationVisitDTO>> GetRelationVisitList(decimal visitNum, string tpCode)
|
||||
//{
|
||||
// return ResponseOutput.Ok(_studyService.GetRelationVisitList(visitNum, tpCode));
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// 保存标记(跟删除合并,每次保存最新的标记),会删除替换之前的标记
|
||||
///// 外层的TPcode 必须传,里面的标记数组可为空数组,表示删除该Study的所有标记
|
||||
///// </summary>
|
||||
///// <param name="imageLabelCommand"></param>
|
||||
///// <returns></returns>
|
||||
//[HttpPost, Route("saveImageLabelList")]
|
||||
//[AllowAnonymous]
|
||||
//[Obsolete]
|
||||
|
||||
//public IResponseOutput SaveImageLabelList(ImageLabelCommand imageLabelCommand)
|
||||
//{
|
||||
// return ResponseOutput.Result(_studyService.SaveImageLabelList(imageLabelCommand));
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// 根据TPCode 获取所有的标记
|
||||
///// </summary>
|
||||
///// <param name="tpCode"></param>
|
||||
///// <returns></returns>
|
||||
//[HttpGet, Route("getImageLabelList/{tpCode}")]
|
||||
//[Obsolete]
|
||||
//[AllowAnonymous]
|
||||
//public IResponseOutput<IEnumerable<ImageLabelDTO>> GetImageLabelList(string tpCode)
|
||||
//{
|
||||
// return ResponseOutput.Ok(_studyService.GetImageLabel(tpCode));
|
||||
//}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,405 +0,0 @@
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -4,6 +4,34 @@
|
|||
<name>IRaCIS.Core.API</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="M:EasyCaching.Demo.Interceptors.Controllers.ErrorController.Error(System.Int32)">
|
||||
<summary>
|
||||
主要处理 前端404等错误 全局业务异常已统一处理了,非业务错误会来到这里
|
||||
</summary>
|
||||
<param name="code"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:IRaCIS.Api.Controllers.ExtraController">
|
||||
<summary>
|
||||
医生基本信息 、工作信息 专业信息、审核状态
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Api.Controllers.ExtraController.GetDoctorDetail(IRaCIS.Application.Interfaces.IAttachmentService,IRaCIS.Application.Interfaces.IDoctorService,IRaCIS.Application.Interfaces.IEducationService,IRaCIS.Application.Interfaces.ITrialExperienceService,IRaCIS.Application.Interfaces.IResearchPublicationService,IRaCIS.Application.Interfaces.IVacationService,System.Guid)">
|
||||
<summary>
|
||||
获取医生详情
|
||||
</summary>
|
||||
<param name="attachmentService"></param>
|
||||
<param name="_doctorService"></param>
|
||||
<param name="_educationService"></param>
|
||||
<param name="_trialExperienceService"></param>
|
||||
<param name="_researchPublicationService"></param>
|
||||
<param name="_vacationService"></param>
|
||||
<param name="doctorId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Api.Controllers.ExtraController.Login(IRaCIS.Application.Contracts.UserLoginDTO,EasyCaching.Core.IEasyCachingProvider,IRaCIS.Application.Services.IUserService,IRaCIS.Core.Application.Auth.ITokenService,Microsoft.Extensions.Configuration.IConfiguration)">
|
||||
<summary> 系统用户登录接口[New] </summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.Special.FinancialChangeController.AddOrUpdateTrialInspection(IRaCIS.Core.Application.Service.Inspection.DTO.DataInspectionDto{IRaCIS.Application.Contracts.TrialCommand})">
|
||||
<summary> 添加实验项目-返回新增Id[AUTH]</summary>
|
||||
<returns>新记录Id</returns>
|
||||
|
@ -124,35 +152,117 @@
|
|||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.UploadController.UploadCommonDoc">
|
||||
<member name="M:IRaCIS.Core.API.Controllers.UploadBaseController.SingleFileUploadAsync(System.Func{System.String,System.ValueTuple{System.String,System.String}})">
|
||||
<summary> 流式上传 直接返回</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.UploadBaseController.FileUploadAsync(System.Func{System.String,System.Threading.Tasks.Task{System.String}})">
|
||||
<summary> 流式上传 通用封装 不返回任何数据,后续还有事情处理 </summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.UploadBaseController.DicomFileUploadAsync(System.Func{System.String,System.IO.Stream,System.Threading.Tasks.Task})">
|
||||
<summary> 流式上传 Dicom上传 需要返回文件数量 </summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.StudyController.ArchiveStudy(IRaCIS.Core.Application.Contracts.ArchiveStudyCommand,Microsoft.Extensions.Logging.ILogger{IRaCIS.Core.API.Controllers.UploadDownLoadController},EasyCaching.Core.IEasyCachingProvider,IRaCIS.Application.Interfaces.IStudyService,IRaCIS.Core.Application.Contracts.Dicom.IDicomArchiveService)">
|
||||
<summary>Dicom 归档</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.StudyController.ArchiveStudyNew(IRaCIS.Core.Application.Contracts.ArchiveStudyCommand,Microsoft.Extensions.Logging.ILogger{IRaCIS.Core.API.Controllers.UploadDownLoadController},EasyCaching.Core.IEasyCachingProvider,IRaCIS.Application.Interfaces.IStudyService,IRaCIS.Core.Application.Contracts.Dicom.IDicomArchiveService)">
|
||||
<summary>Dicom 归档</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadVisitClinicalData(System.Guid,IRaCIS.Core.Infra.EFCore.IRepository)">
|
||||
<summary>
|
||||
上传临床数据 多文件
|
||||
</summary>
|
||||
<param name="subjectVisitId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadNoneDicomFile(Microsoft.AspNetCore.Http.IFormCollection,System.Guid,System.Guid,IRaCIS.Core.Infra.EFCore.IRepository)">
|
||||
<summary>
|
||||
上传非Dicom 文件 支持压缩包 多文件上传
|
||||
</summary>
|
||||
<param name="formCollection"></param>
|
||||
<param name="subjectVisitId"></param>
|
||||
<param name="noneDicomStudyId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.StudyController.UploadVisitCheckExcel(System.Guid,MediatR.IMediator,IRaCIS.Core.Infra.EFCore.IRepository)">
|
||||
<summary>
|
||||
一致性核查 excel上传 支持三种格式
|
||||
</summary>
|
||||
<param name="trialId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:IRaCIS.Core.API.Controllers.FileController">
|
||||
<summary>医生文件上传下载</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.FileController.UploadOrdinaryFile(System.String,System.Guid)">
|
||||
<summary>
|
||||
上传文件[FileUpload]
|
||||
</summary>
|
||||
<param name="attachmentType">附件类型</param>
|
||||
<param name="doctorId">医生Id</param>
|
||||
<returns>返回文件信息</returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.FileController.UploadNonDoctorFile(System.String)">
|
||||
<summary>
|
||||
上传文件( 不是医生个人的文件)[FileUpload]
|
||||
例如:阅片章程等
|
||||
</summary>
|
||||
<param name="type">文件类型</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadAttachment(System.Guid[],IRaCIS.Application.Interfaces.IFileService)">
|
||||
<summary>
|
||||
下载多个医生的所有附件
|
||||
</summary>
|
||||
<param name="doctorIds"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadOfficialResume(System.Int32,System.Guid[],IRaCIS.Application.Interfaces.IFileService)">
|
||||
<summary>
|
||||
下载医生官方简历
|
||||
</summary>
|
||||
<param name="language"></param>
|
||||
<param name="doctorIds"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.FileController.DownloadAttachmentById(System.Guid,System.Guid[],IRaCIS.Application.Interfaces.IFileService)">
|
||||
<summary>
|
||||
下载指定医生的指定附件
|
||||
</summary>
|
||||
<param name="doctorId">医生Id</param>
|
||||
<param name="attachmentIds">要下载的附件Id</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.LocalFilePreview(System.String)">
|
||||
<summary> 缩略图 </summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.DownloadCommonFile(System.String,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.CommonDocument})">
|
||||
<summary> 通用文件下载 </summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.UploadTrialDoc(System.Guid)">
|
||||
<summary>
|
||||
上传项目签名文档
|
||||
</summary>
|
||||
<param name="trialId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.UploadSysTemDoc">
|
||||
<summary>
|
||||
上传系统签名文档
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.UploadCommonDoc">
|
||||
<summary>
|
||||
上传通用文档 比如一致性核查的 比如导出的excel 模板
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.UploadController.UploadSystemNoticeDoc">
|
||||
<member name="M:IRaCIS.Core.API.Controllers.UploadDownLoadController.UploadSystemNoticeDoc">
|
||||
<summary>
|
||||
上传系统通知文档
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.UploadController.UploadVisitData(System.Guid,IRaCIS.Core.API.Controllers.UploadController.UploadFileTypeEnum,IRaCIS.Core.Infra.EFCore.IRepository{IRaCIS.Core.Domain.Models.SubjectVisit})">
|
||||
<summary>
|
||||
上传临床数据
|
||||
</summary>
|
||||
<param name="subjectVisitId"></param>
|
||||
<param name="uploadType"> 1:DICOM DTF 2:非DIOM DTF 3: 受试者临床数据</param>
|
||||
<param name="_subjectVisitRepository"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.API.Controllers.UploadController.WriteFileAsync(System.IO.Stream,System.String)">
|
||||
<summary>
|
||||
写文件导到磁盘
|
||||
</summary>
|
||||
<param name="stream">流</param>
|
||||
<param name="path">文件保存路径</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:IRaCIS.Core.API.IpPolicyRateLimitSetup">
|
||||
<summary>
|
||||
IPLimit限流 启动服务
|
||||
|
@ -166,99 +276,6 @@
|
|||
<param name="memberSerialization">序列化成员</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:IRaCIS.Api.Controllers.ExtraController">
|
||||
<summary>
|
||||
医生基本信息 、工作信息 专业信息、审核状态
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Api.Controllers.ExtraController.GetDoctorDetail(IRaCIS.Application.Interfaces.IAttachmentService,IRaCIS.Application.Interfaces.IDoctorService,IRaCIS.Application.Interfaces.IEducationService,IRaCIS.Application.Interfaces.ITrialExperienceService,IRaCIS.Application.Interfaces.IResearchPublicationService,IRaCIS.Application.Interfaces.IVacationService,System.Guid)">
|
||||
<summary>
|
||||
获取医生详情
|
||||
</summary>
|
||||
<param name="attachmentService"></param>
|
||||
<param name="_doctorService"></param>
|
||||
<param name="_educationService"></param>
|
||||
<param name="_trialExperienceService"></param>
|
||||
<param name="_researchPublicationService"></param>
|
||||
<param name="_vacationService"></param>
|
||||
<param name="doctorId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Api.Controllers.ExtraController.Login(IRaCIS.Application.Contracts.UserLoginDTO,EasyCaching.Core.IEasyCachingProvider,IRaCIS.Application.Services.IUserService,IRaCIS.Core.Application.Auth.ITokenService,Microsoft.Extensions.Configuration.IConfiguration)">
|
||||
<summary> 系统用户登录接口[New] </summary>
|
||||
</member>
|
||||
<member name="T:IRaCIS.Api.Controllers.FileController">
|
||||
<summary>
|
||||
文件上传
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Api.Controllers.FileController.UploadOrdinaryFile(System.String,System.Guid)">
|
||||
<summary>
|
||||
上传文件[FileUpload]
|
||||
</summary>
|
||||
<param name="attachmentType">附件类型</param>
|
||||
<param name="doctorId">医生Id</param>
|
||||
<returns>返回文件信息</returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Api.Controllers.FileController.UploadNonDoctorFile(System.String)">
|
||||
<summary>
|
||||
上传文件( 不是医生个人的文件)[FileUpload]
|
||||
例如:阅片章程等
|
||||
</summary>
|
||||
<param name="type">文件类型</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Api.Controllers.FileController.WriteFileAsync(System.IO.Stream,System.String)">
|
||||
<summary>
|
||||
写文件导到磁盘
|
||||
</summary>
|
||||
<param name="stream">流</param>
|
||||
<param name="path">文件保存路径</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Api.Controllers.FileController.DownloadAttachment(System.Guid[])">
|
||||
<summary>
|
||||
下载多个医生的所有附件
|
||||
</summary>
|
||||
<param name="doctorIds"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Api.Controllers.FileController.DownloadOfficialResume(System.Int32,System.Guid[])">
|
||||
<summary>
|
||||
下载医生官方简历
|
||||
</summary>
|
||||
<param name="language"></param>
|
||||
<param name="doctorIds"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Api.Controllers.FileController.DownloadAttachmentById(System.Guid,System.Guid[])">
|
||||
<summary>
|
||||
下载指定医生的指定附件
|
||||
</summary>
|
||||
<param name="doctorId">医生Id</param>
|
||||
<param name="attachmentIds">要下载的附件Id</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Api.Controllers.FileController.UploadingStream(System.Guid,System.Guid,System.Guid,System.Guid,System.Guid,IRaCIS.Core.Application.Contracts.Image.IStudyDTFService)">
|
||||
<summary>
|
||||
流式上传 临时文件
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Api.Controllers.FileController.UploadingNoneDicomStream(IRaCIS.Core.Application.Contracts.ArchiveStudyCommand,IRaCIS.Application.Interfaces.IStudyService)">
|
||||
<summary>
|
||||
流式上传 非Dicom文件
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:IRaCIS.Api.Controllers.StudyController">
|
||||
<summary>
|
||||
Study
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Api.Controllers.StudyController.ArchiveStudy(IRaCIS.Core.Application.Contracts.ArchiveStudyCommand)">
|
||||
<summary> 归档</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.WX.CoreApi.Auth.AuthMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext)">
|
||||
<summary>
|
||||
为了前端 一段时间无操作,需要重新登陆
|
||||
|
@ -266,13 +283,6 @@
|
|||
<param name="httpContext"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:EasyCaching.Demo.Interceptors.Controllers.ErrorController.Error(System.Int32)">
|
||||
<summary>
|
||||
主要处理 前端404等错误 全局业务异常已统一处理了,非业务错误会来到这里
|
||||
</summary>
|
||||
<param name="code"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:ZhaoXi._001.NET5Demo.Practice.WebApi.Utility.Jwt.CustomHSJWTService">
|
||||
<summary>
|
||||
对称可逆加密
|
||||
|
|
|
@ -32,9 +32,6 @@ namespace IRaCIS.Core.API
|
|||
|
||||
|
||||
var uploadPath = Path.Combine(Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).FullName, StaticData.UploadFileFolder);
|
||||
//var dicomPath = Path.Combine(Directory.GetParent(env.ContentRootPath.TrimEnd('\\')).FullName, StaticData.TrialDataFolder);
|
||||
|
||||
//var systemDataFolder = Path.Combine(Directory.GetParent(env.ContentRootPath.TrimEnd('\\')).FullName, StaticData.SystemDataFolder);
|
||||
|
||||
|
||||
if (!Directory.Exists(uploadPath))
|
||||
|
@ -48,49 +45,9 @@ namespace IRaCIS.Core.API
|
|||
RequestPath = $"/{StaticData.UploadFileFolder}"
|
||||
});
|
||||
|
||||
//if (!Directory.Exists(dicomPath))
|
||||
//{
|
||||
// Directory.CreateDirectory(dicomPath);
|
||||
//}
|
||||
|
||||
//if (!Directory.Exists(systemDataFolder))
|
||||
//{
|
||||
// Directory.CreateDirectory(systemDataFolder);
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
//app.UseStaticFiles(new StaticFileOptions
|
||||
//{
|
||||
// FileProvider = new PhysicalFileProvider(dicomPath),
|
||||
// RequestPath = $"/{StaticData.TrialDataFolder}"
|
||||
//});
|
||||
|
||||
//app.UseStaticFiles(new StaticFileOptions
|
||||
//{
|
||||
// FileProvider = new PhysicalFileProvider(systemDataFolder),
|
||||
// RequestPath = $"/{StaticData.SystemDataFolder}"
|
||||
//});
|
||||
|
||||
|
||||
#region 兼容之前的文档能查看
|
||||
|
||||
//var comonPathPath = Path.Combine(Directory.GetParent(env.ContentRootPath.TrimEnd('\\')).FullName, StaticData.CommonFileFolder);
|
||||
|
||||
//var systemNoticePath = Path.Combine(Directory.GetParent(env.ContentRootPath.TrimEnd('\\')).FullName, StaticData.SystemNoticeFolder);
|
||||
|
||||
//if (!Directory.Exists(comonPathPath))
|
||||
//{
|
||||
// Directory.CreateDirectory(comonPathPath);
|
||||
//}
|
||||
//app.UseStaticFiles(new StaticFileOptions
|
||||
//{
|
||||
// FileProvider = new PhysicalFileProvider(comonPathPath),
|
||||
// RequestPath = $"/{StaticData.CommonFileFolder}"
|
||||
//});
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Microsoft.AspNetCore.Hosting;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using MiniExcelLibs;
|
||||
|
||||
|
@ -9,24 +10,12 @@ public static class ExcelExportHelper
|
|||
//MiniExcel_Export
|
||||
public static async Task<IActionResult> DataExportAsync(string code, object data, string exportFileNamePrefix, IRepository<CommonDocument> _commonDocumentRepository, IWebHostEnvironment _hostEnvironment)
|
||||
{
|
||||
var doc = _commonDocumentRepository.AsQueryable(true).FirstOrDefault(t => t.Code == code);
|
||||
|
||||
if (doc == null)
|
||||
{
|
||||
throw new Exception("程序没有找到对应的数据模板文件,请联系系统运维人员。");
|
||||
}
|
||||
var (physicalPath, fileNmae) = await FileStoreHelper.GetCommonDocPhysicalFilePathAsync(_hostEnvironment, _commonDocumentRepository, code);
|
||||
|
||||
var rootPath = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\'))?.FullName;
|
||||
|
||||
var filePath = Path.Combine(rootPath, doc.Path.Trim('/'));
|
||||
|
||||
if (!System.IO.File.Exists(filePath))
|
||||
{
|
||||
throw new Exception("数据模板文件存储路径上未找对应文件,请联系系统运维人员。");
|
||||
}
|
||||
|
||||
//模板路径
|
||||
var tplPath = filePath;
|
||||
var tplPath = physicalPath;
|
||||
|
||||
#region MiniExcel
|
||||
|
||||
|
@ -38,7 +27,7 @@ public static class ExcelExportHelper
|
|||
|
||||
return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
{
|
||||
FileDownloadName = $"{exportFileNamePrefix}_{doc.Name.Substring(0,doc.Name.LastIndexOf('.'))}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"
|
||||
FileDownloadName = $"{exportFileNamePrefix}_{fileNmae.Substring(0, fileNmae.LastIndexOf('.'))}_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
||||
namespace IRaCIS.Core.Application.Helper;
|
||||
|
@ -9,7 +10,7 @@ public static class FileStoreHelper
|
|||
{
|
||||
|
||||
|
||||
|
||||
//处理文件名 压缩包,或者目录类的 会带上相对路径
|
||||
public static (string TrustedFileNameForFileStorage, string RealName) GetStoreFileName(string fileName)
|
||||
{
|
||||
|
||||
|
@ -29,17 +30,273 @@ public static class FileStoreHelper
|
|||
return (trustedFileNameForFileStorage, fileName);
|
||||
}
|
||||
|
||||
//API vue 部署目录
|
||||
public static string GetIRaCISRootPath(IWebHostEnvironment _hostEnvironment)
|
||||
{
|
||||
var rootPath = (Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\'))).IfNullThrowException().FullName;
|
||||
return rootPath;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//获取环境存储根目录
|
||||
public static string GetIRaCISRootDataFolder(IWebHostEnvironment _hostEnvironment)
|
||||
{
|
||||
var root = (Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\'))).IfNullThrowException().FullName;
|
||||
|
||||
|
||||
var rootFolder =Path.Combine(root, StaticData.IRaCISDataFolder) ;
|
||||
var rootPath = GetIRaCISRootPath(_hostEnvironment);
|
||||
|
||||
var rootFolder = Path.Combine(rootPath, StaticData.IRaCISDataFolder);
|
||||
|
||||
return rootFolder;
|
||||
}
|
||||
|
||||
//根据相对路径 获取具体文件物理地址
|
||||
public static string GetPhysicalFilePath(IWebHostEnvironment _hostEnvironment, string relativePath)
|
||||
{
|
||||
var rootPath = GetIRaCISRootPath(_hostEnvironment);
|
||||
|
||||
var physicalFilePath = Path.Combine(rootPath, relativePath.Trim('/'));
|
||||
|
||||
return physicalFilePath;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//通过编码获取通用文档具体物理路径
|
||||
|
||||
public static async Task<(string PhysicalPath, string FileName)> GetCommonDocPhysicalFilePathAsync(IWebHostEnvironment _hostEnvironment, IRepository<CommonDocument> _commonDocumentRepository, string code)
|
||||
{
|
||||
var doc = await _commonDocumentRepository.FirstOrDefaultAsync(t => t.Code == code);
|
||||
|
||||
if (doc == null)
|
||||
{
|
||||
throw new BusinessValidationFailedException("数据库没有找到对应的数据模板文件,请联系系统运维人员。");
|
||||
}
|
||||
|
||||
var filePath = FileStoreHelper.GetPhysicalFilePath(_hostEnvironment, doc.Path);
|
||||
|
||||
if (!System.IO.File.Exists(filePath))
|
||||
{
|
||||
throw new BusinessValidationFailedException("数据模板文件存储路径上未找对应文件,请联系系统运维人员。");
|
||||
}
|
||||
|
||||
return (filePath, doc.Name.Trim('/'));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 写文件导到磁盘
|
||||
/// </summary>
|
||||
/// <param name="stream">流</param>
|
||||
/// <param name="path">文件保存路径</param>
|
||||
/// <returns></returns>
|
||||
public 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;
|
||||
}
|
||||
|
||||
// 获取项目签名文档存放路径
|
||||
|
||||
public static (string PhysicalPath, string RelativePath) GetTrialSignDocPath(IWebHostEnvironment _hostEnvironment, Guid trialId, string fileName)
|
||||
{
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
//文件类型路径处理
|
||||
var uploadFolderPath = Path.Combine(rootPath, StaticData.TrialDataFolder, trialId.ToString(), StaticData.SignDocumentFolder);
|
||||
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
||||
|
||||
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
|
||||
|
||||
var relativePath = $"/{StaticData.IRaCISDataFolder}/{StaticData.TrialDataFolder}/{trialId}/{StaticData.SignDocumentFolder}/{trustedFileNameForFileStorage}";
|
||||
|
||||
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||
|
||||
return (serverFilePath, relativePath);
|
||||
}
|
||||
|
||||
// 获取系统签名文档存放路径
|
||||
public static (string PhysicalPath, string RelativePath) GetSystemSignDocPath(IWebHostEnvironment _hostEnvironment, string fileName)
|
||||
{
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
|
||||
//文件类型路径处理
|
||||
var uploadFolderPath = Path.Combine(rootPath, StaticData.SystemDataFolder, StaticData.SignDocumentFolder);
|
||||
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
||||
|
||||
|
||||
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
|
||||
|
||||
var relativePath = $"/{StaticData.IRaCISDataFolder}/{StaticData.SystemDataFolder}/{ StaticData.SignDocumentFolder}/{trustedFileNameForFileStorage}";
|
||||
|
||||
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||
|
||||
return (serverFilePath, relativePath);
|
||||
}
|
||||
|
||||
// 获取通用文档存放路径(excel模板 )
|
||||
|
||||
public static (string PhysicalPath, string RelativePath) GetCommonDocPath(IWebHostEnvironment _hostEnvironment, string fileName)
|
||||
{
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
//文件类型路径处理
|
||||
var uploadFolderPath = Path.Combine(rootPath, StaticData.SystemDataFolder, StaticData.DataTemplate);
|
||||
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
||||
|
||||
|
||||
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
|
||||
|
||||
|
||||
var relativePath = $"/{StaticData.IRaCISDataFolder}/{StaticData.SystemDataFolder}/{StaticData.DataTemplate}/{trustedFileNameForFileStorage}";
|
||||
|
||||
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||
|
||||
return (serverFilePath, relativePath);
|
||||
}
|
||||
|
||||
//获取系统通知文档存放路径
|
||||
|
||||
public static (string PhysicalPath, string RelativePath) GetSystemNoticePath(IWebHostEnvironment _hostEnvironment, string fileName)
|
||||
{
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
//文件类型路径处理
|
||||
var uploadFolderPath = Path.Combine(rootPath, StaticData.SystemDataFolder, StaticData.NoticeAttachment);
|
||||
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
||||
|
||||
|
||||
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
|
||||
|
||||
|
||||
|
||||
var relativePath = $"/{StaticData.IRaCISDataFolder}/{StaticData.SystemDataFolder}/{StaticData.NoticeAttachment}/{trustedFileNameForFileStorage}";
|
||||
|
||||
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||
|
||||
return (serverFilePath, relativePath);
|
||||
}
|
||||
|
||||
// 获取一致性核查路径
|
||||
public static (string PhysicalPath, string RelativePath) GetTrialCheckFilePath(IWebHostEnvironment _hostEnvironment, string fileName,Guid trialId)
|
||||
{
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
//上传根路径
|
||||
string uploadFolderPath = Path.Combine(rootPath, StaticData.TrialDataFolder, trialId.ToString(), "CheckExcel");
|
||||
|
||||
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
||||
|
||||
|
||||
//存放核对表
|
||||
var (trustedFileNameForFileStorage, realFileName) = FileStoreHelper.GetStoreFileName(fileName);
|
||||
|
||||
|
||||
var relativePath = $"/{StaticData.IRaCISDataFolder}/{StaticData.TrialDataFolder}/{trialId}/CheckExcel/{trustedFileNameForFileStorage}";
|
||||
|
||||
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||
|
||||
return (serverFilePath, relativePath);
|
||||
}
|
||||
|
||||
//获取临床数据存放路径
|
||||
public static (string PhysicalPath, string RelativePath,string FileRealName) GetClinicalDataPath(IWebHostEnvironment _hostEnvironment, string fileName,Guid trialId,Guid siteId,Guid subjectId,Guid subjectVisitId)
|
||||
{
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
string uploadFolderPath = Path.Combine(rootPath, StaticData.TrialDataFolder, trialId.ToString(),siteId.ToString(), subjectId.ToString(), subjectVisitId.ToString(), StaticData.TreatmenthistoryFolder);
|
||||
|
||||
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
||||
|
||||
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
|
||||
|
||||
|
||||
var relativePath = $"/{StaticData.IRaCISDataFolder}/{StaticData.TrialDataFolder}/{trialId}/{siteId}/{subjectId}/{subjectVisitId}/{StaticData.TreatmenthistoryFolder}/{trustedFileNameForFileStorage}";
|
||||
|
||||
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||
|
||||
return (serverFilePath, relativePath, fileRealName);
|
||||
|
||||
}
|
||||
|
||||
//获取非dicom文件存放路径
|
||||
public static (string PhysicalPath, string RelativePath, string FileRealName) GetNoneDicomFilePath(IWebHostEnvironment _hostEnvironment, string fileName, Guid trialId, Guid siteId, Guid subjectId, Guid subjectVisitId)
|
||||
{
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
string uploadFolderPath = Path.Combine(rootPath, StaticData.TrialDataFolder, trialId.ToString(), siteId.ToString(), subjectId.ToString(), subjectVisitId.ToString(), StaticData.NoneDicomFolder);
|
||||
|
||||
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
||||
|
||||
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
|
||||
|
||||
|
||||
var relativePath = $"/{StaticData.IRaCISDataFolder}/{StaticData.TrialDataFolder}/{trialId}/{siteId}/{subjectId}/{subjectVisitId}/{StaticData.NoneDicomFolder}/{trustedFileNameForFileStorage}";
|
||||
|
||||
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||
|
||||
return (serverFilePath, relativePath, fileRealName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 获取医生通用文件存放路径
|
||||
|
||||
public static (string PhysicalPath, string RelativePath) GetDoctorOrdinaryFilePath(IWebHostEnvironment _hostEnvironment, string fileName,Guid doctorId,string attachmentType)
|
||||
{
|
||||
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
//文件类型路径处理
|
||||
var uploadFolderPath = Path.Combine(rootPath, "UploadFile", doctorId.ToString(), attachmentType);
|
||||
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
||||
|
||||
|
||||
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
|
||||
|
||||
|
||||
|
||||
var relativePath = $"/{StaticData.IRaCISDataFolder}/UploadFile/{doctorId}/{attachmentType}/{trustedFileNameForFileStorage}";
|
||||
|
||||
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||
|
||||
return (serverFilePath, relativePath);
|
||||
}
|
||||
|
||||
public static (string PhysicalPath, string RelativePath) GetNonDoctorFilePath(IWebHostEnvironment _hostEnvironment, string fileName, string attachmentType)
|
||||
{
|
||||
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
//文件类型路径处理
|
||||
var uploadFolderPath = Path.Combine(rootPath, "UploadFile", attachmentType);
|
||||
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
||||
|
||||
|
||||
var (trustedFileNameForFileStorage, fileRealName) = FileStoreHelper.GetStoreFileName(fileName);
|
||||
|
||||
|
||||
|
||||
var relativePath = $"/{StaticData.IRaCISDataFolder}/UploadFile/{attachmentType}/{trustedFileNameForFileStorage}";
|
||||
|
||||
var serverFilePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||
|
||||
return (serverFilePath, relativePath);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ namespace IRaCIS.Core.Application.Helper;
|
|||
public static class SendEmailHelper
|
||||
{
|
||||
|
||||
|
||||
public static async Task SendEmailAsync(MimeMessage messageToSend, EventHandler<MessageSentEventArgs>? messageSentSuccess = null)
|
||||
{
|
||||
using (var smtp = new MailKit.Net.Smtp.SmtpClient())
|
||||
|
|
|
@ -422,6 +422,14 @@
|
|||
<param name="trialExternalUserId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Helper.FileStoreHelper.WriteFileAsync(System.IO.Stream,System.String)">
|
||||
<summary>
|
||||
写文件导到磁盘
|
||||
</summary>
|
||||
<param name="stream">流</param>
|
||||
<param name="path">文件保存路径</param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:IRaCIS.Core.Application.ViewModel.CommonDocumentView">
|
||||
<summary> CommonDocumentView 列表视图模型 </summary>
|
||||
</member>
|
||||
|
@ -678,15 +686,6 @@
|
|||
受试者临床信息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Contracts.ClinicalDataService.UploadVisitClinicalData(Microsoft.AspNetCore.Http.IFormCollection,System.Guid,Microsoft.AspNetCore.Hosting.IWebHostEnvironment)">
|
||||
<summary>
|
||||
上传临床数据
|
||||
</summary>
|
||||
<param name="formCollection"></param>
|
||||
<param name="subjectVisitId"></param>
|
||||
<param name="_hostEnvironment"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Contracts.ClinicalDataService.GetSubjectVisitClinicalData(System.Guid)">
|
||||
<summary>
|
||||
获取访视+受试者级别的数据
|
||||
|
@ -830,15 +829,6 @@
|
|||
<param name="noneDicomStudyId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Contracts.NoneDicomStudyService.UploadNoneDicomFile(Microsoft.AspNetCore.Http.IFormCollection,System.Guid,System.Guid)">
|
||||
<summary>
|
||||
上传非Dicom 文件 支持压缩包
|
||||
</summary>
|
||||
<param name="formCollection"></param>
|
||||
<param name="subjectVisitId"></param>
|
||||
<param name="noneDicomStudyId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:IRaCIS.Core.Application.Contracts.QCQuestionConfigureService">
|
||||
<summary>
|
||||
系统QC 问题管理
|
||||
|
@ -1556,14 +1546,6 @@
|
|||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Image.QA.QCOperationService.UploadVisitCheckExcel(Microsoft.AspNetCore.Http.IFormFile,System.Guid)">
|
||||
<summary>
|
||||
一致性核查 excel上传 支持三种格式
|
||||
</summary>
|
||||
<param name="file"></param>
|
||||
<param name="trialId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.Image.QA.QCOperationService.AddOrUpdateQCQuestionAnswerList(IRaCIS.Core.Application.Contracts.DTO.QCQuestionAnswerCommand[],System.Guid,System.Guid,IRaCIS.Core.Domain.Share.TrialQCProcess,IRaCIS.Core.Domain.Share.CurrentQC)">
|
||||
<summary>
|
||||
添加或者更新 QC核对问题列表 两个人不能同时操作,就算意外进去了,提交数据,也不会覆盖前一个人数据, 后台已经做好判断
|
||||
|
@ -1751,19 +1733,6 @@
|
|||
<param name="trialConfig"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.TrialConfigService.VerifySignature(IRaCIS.Core.Application.Contracts.SignDTO)">
|
||||
<summary>
|
||||
签名认证 +
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:IRaCIS.Core.Application.TrialConfigService.MakeSignEffective(System.Guid)">
|
||||
<summary>
|
||||
业务接口操作成功后, 让签署数据生效
|
||||
</summary>
|
||||
<param name="signId"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:IRaCIS.Core.Application.Triggers.AddVisitPlanTrigger">
|
||||
<summary>
|
||||
添加访视计划 要给改项目下的所有Subject 添加该访视
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace IRaCIS.Application.Interfaces
|
|||
|
||||
DicomTrialSiteSubjectInfo GetSaveToDicomInfo(Guid subjctVisitId);
|
||||
|
||||
void GetHasUploadSeriesAndInstance(Guid studyId, ref List<string> seriesInstanceUidList, ref List<string> instanceUidList);
|
||||
(List<string> SeriesInstanceUid, List<string> SopInstanceUid) GetHasUploadSeriesAndInstance(Guid studyId);
|
||||
|
||||
|
||||
void UploadOrReUploadNeedTodo(ArchiveStudyCommand archiveStudyCommand, List<Guid> archiveStudyIds, ref DicomArchiveResult reusult, StudyMonitor monitor);
|
||||
|
|
|
@ -72,11 +72,13 @@ namespace IRaCIS.Application.Services
|
|||
return info;
|
||||
}
|
||||
|
||||
public void GetHasUploadSeriesAndInstance(Guid studyId, ref List<string> seriesInstanceUidList, ref List<string> sopInstanceUidList)
|
||||
public (List<string> SeriesInstanceUid, List<string> SopInstanceUid) GetHasUploadSeriesAndInstance(Guid studyId)
|
||||
{
|
||||
seriesInstanceUidList = _dicomSeriesRepository.Where(t => t.StudyId == studyId).Select(t => t.SeriesInstanceUid).ToList();
|
||||
var seriesInstanceUidList = _dicomSeriesRepository.Where(t => t.StudyId == studyId).Select(t => t.SeriesInstanceUid).ToList();
|
||||
|
||||
sopInstanceUidList = _dicomInstanceRepository.Where(t => t.StudyId == studyId).Select(t => t.SopInstanceUid).ToList();
|
||||
var sopInstanceUidList = _dicomInstanceRepository.Where(t => t.StudyId == studyId).Select(t => t.SopInstanceUid).ToList();
|
||||
|
||||
return (seriesInstanceUidList, sopInstanceUidList);
|
||||
}
|
||||
|
||||
public void UploadOrReUploadNeedTodo(ArchiveStudyCommand archiveStudyCommand, List<Guid> archiveStudyIds, ref DicomArchiveResult result, StudyMonitor monitor)
|
||||
|
|
|
@ -4,15 +4,8 @@ using IRaCIS.Core.Application.Service.Inspection.DTO;
|
|||
using IRaCIS.Core.Application.Service.Inspection.Interface;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Panda.DynamicWebApi.Attributes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
namespace IRaCIS.Core.Application.Service.Inspection
|
||||
{
|
||||
|
|
|
@ -4,14 +4,8 @@
|
|||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using IRaCIS.Core.Application.Service.Verify;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using IRaCIS.Core.Application.Auth;
|
||||
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
|
@ -44,63 +38,6 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 上传临床数据
|
||||
/// </summary>
|
||||
/// <param name="formCollection"></param>
|
||||
/// <param name="subjectVisitId"></param>
|
||||
/// <param name="_hostEnvironment"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{trialId:guid}/{subjectVisitId:guid}")]
|
||||
[DisableRequestSizeLimit]
|
||||
[Authorize(Policy = IRaCISPolicy.CRC)]
|
||||
public async Task<IResponseOutput> UploadVisitClinicalData(IFormCollection formCollection, Guid subjectVisitId, [FromServices] IWebHostEnvironment _hostEnvironment)
|
||||
{
|
||||
await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
|
||||
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
//上传根路径
|
||||
var _fileStorePath = Path.Combine(rootPath, StaticData.TrialDataFolder);
|
||||
|
||||
var sv = _repository.Where<SubjectVisit>(t => t.Id == subjectVisitId).Select(t => new { t.TrialId, t.SiteId, t.SubjectId }).FirstOrDefault().IfNullThrowException();
|
||||
|
||||
string uploadFolderPath = Path.Combine(_fileStorePath, sv.TrialId.ToString(),
|
||||
sv.SiteId.ToString(), sv.SubjectId.ToString(), subjectVisitId.ToString(), StaticData.TreatmenthistoryFolder);
|
||||
|
||||
if (!Directory.Exists(uploadFolderPath))
|
||||
{
|
||||
Directory.CreateDirectory(uploadFolderPath);
|
||||
}
|
||||
|
||||
foreach (IFormFile file in formCollection.Files)
|
||||
{
|
||||
|
||||
var (trustedFileNameForFileStorage, fileName) = FileStoreHelper.GetStoreFileName(file.FileName);
|
||||
|
||||
var relativePath = $"/{StaticData.IRaCISDataFolder}/{StaticData.TrialDataFolder}/{sv.TrialId}/{sv.SiteId}/{sv.SubjectId}/{subjectVisitId}/{StaticData.TreatmenthistoryFolder}/{trustedFileNameForFileStorage}";
|
||||
|
||||
var filePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||
|
||||
using (FileStream fs = System.IO.File.Create(filePath))
|
||||
{
|
||||
await file.CopyToAsync(fs);
|
||||
await fs.FlushAsync();
|
||||
}
|
||||
|
||||
//插入临床pdf 路径
|
||||
await _previousPdfRepository.AddAsync(new PreviousPDF() { SubjectVisitId = subjectVisitId, Path = relativePath, FileName = fileName });
|
||||
}
|
||||
|
||||
|
||||
await _repository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取访视+受试者级别的数据
|
||||
|
|
|
@ -25,6 +25,6 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
Task<List<PreviousPDFView>> GetPreviousPDFList(Guid subjectVisitId);
|
||||
Task<List<PreviousSurgeryView>> GetPreviousSurgeryList(PreviousSurgeryQuery queryPreviousSurgery);
|
||||
Task<SubjectClinicalDataDto> GetSubjectVisitClinicalData(Guid subjectVisitId);
|
||||
Task<IResponseOutput> UploadVisitClinicalData(IFormCollection formCollection, Guid subjectVisitId, [FromServices] IWebHostEnvironment _hostEnvironment);
|
||||
//Task<IResponseOutput> UploadVisitClinicalData(IFormCollection formCollection, Guid subjectVisitId, [FromServices] IWebHostEnvironment _hostEnvironment);
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
Task<List<NoneDicomStudyFileView>> GetNoneDicomStudyFileList(Guid noneDicomStudyId);
|
||||
Task<List<NoneDicomStudyView>> GetNoneDicomStudyList(Guid subjectVisitId, Guid? sujectVisitId = null);
|
||||
Task<List<NoneDicomStudyFileView>> GetVisitNoneDicomStudyFileList(Guid subjectVisitId);
|
||||
Task<IResponseOutput> UploadNoneDicomFile(IFormCollection formCollection, Guid subjectVisitId, Guid noneDicomStudyId);
|
||||
//Task<IResponseOutput> UploadNoneDicomFile(IFormCollection formCollection, Guid subjectVisitId, Guid noneDicomStudyId);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||
Task<IResponseOutput> SetVisitUrgent(Guid trialId, Guid subjectVisitId, bool setOrCancel);
|
||||
Task<IResponseOutput> UpdateModality(UpdateModalityCommand updateModalityCommand);
|
||||
Task<IResponseOutput> UpdateSubjectAndSVInfo(UploadSubjectAndVisitCommand command);
|
||||
Task<IResponseOutput> UploadVisitCheckExcel(IFormFile file, Guid trialId);
|
||||
//Task<IResponseOutput> UploadVisitCheckExcel(IFormFile file, Guid trialId);
|
||||
Task<IResponseOutput> VerifyCanQCPassedOrFailed(Guid subjectVisitId);
|
||||
|
||||
|
||||
|
|
|
@ -4,20 +4,10 @@
|
|||
// 对此文件的更改可能会导致不正确的行为,并且如果重新生成代码,这些更改将会丢失。
|
||||
//--------------------------------------------------------------------
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using SharpCompress.Archives;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Application.Service.Inspection.Interface;
|
||||
using Nito.AsyncEx;
|
||||
using IRaCIS.Application.Interfaces;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
using IRaCIS.Core.Application.Service.Verify;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using IRaCIS.Core.Application.Auth;
|
||||
|
||||
namespace IRaCIS.Core.Application.Contracts
|
||||
{
|
||||
|
@ -28,39 +18,21 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
public class NoneDicomStudyService : BaseService, INoneDicomStudyService
|
||||
{
|
||||
private readonly IRepository<NoneDicomStudy> _noneDicomStudyRepository;
|
||||
private readonly IHttpContextAccessor _httpContext;
|
||||
private readonly IDictionaryService _dictionaryService;
|
||||
private readonly IInspectionService _inspectionService;
|
||||
private readonly IRepository<StudyMonitor> _studyMonitorRepository;
|
||||
private readonly IRepository<NoneDicomStudyFile> _noneDicomStudyFileRepository;
|
||||
private readonly IRepository<SubjectVisit> _subjectVisitRepository;
|
||||
private readonly AsyncLock _mutex = new AsyncLock();
|
||||
|
||||
private readonly ILogger<NoneDicomStudyService> _logger;
|
||||
|
||||
|
||||
public NoneDicomStudyService(IRepository<NoneDicomStudy> noneDicomStudyRepository,
|
||||
IHttpContextAccessor httpContext,
|
||||
IDictionaryService dictionaryService,
|
||||
IInspectionService inspectionService,
|
||||
IRepository<StudyMonitor> studyMonitorRepository,
|
||||
IRepository<NoneDicomStudyFile> noneDicomStudyFileRepository, IRepository<SubjectVisit> subjectVisitRepository, ILogger<NoneDicomStudyService> logger)
|
||||
|
||||
IRepository<NoneDicomStudyFile> noneDicomStudyFileRepository)
|
||||
{
|
||||
_noneDicomStudyRepository = noneDicomStudyRepository;
|
||||
|
||||
this._httpContext = httpContext;
|
||||
this._dictionaryService = dictionaryService;
|
||||
this._inspectionService = inspectionService;
|
||||
this._studyMonitorRepository = studyMonitorRepository;
|
||||
_noneDicomStudyFileRepository = noneDicomStudyFileRepository;
|
||||
this._subjectVisitRepository = subjectVisitRepository;
|
||||
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public async Task<List<NoneDicomStudyView>> GetNoneDicomStudyList( [FromQuery,NotDefault] Guid subjectVisitId,Guid? nonedicomStudyId)
|
||||
{
|
||||
|
@ -171,116 +143,5 @@ namespace IRaCIS.Core.Application.Contracts
|
|||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 上传非Dicom 文件 支持压缩包
|
||||
/// </summary>
|
||||
/// <param name="formCollection"></param>
|
||||
/// <param name="subjectVisitId"></param>
|
||||
/// <param name="noneDicomStudyId"></param>
|
||||
/// <returns></returns>
|
||||
//[DisableRequestSizeLimit]
|
||||
[RequestSizeLimit(1_073_741_824)]
|
||||
[HttpPost("{trialId:guid}/{subjectVisitId:guid}/{noneDicomStudyId:guid}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter))]
|
||||
[Authorize(Policy = IRaCISPolicy.CRC)]
|
||||
public async Task<IResponseOutput> UploadNoneDicomFile(IFormCollection formCollection, Guid subjectVisitId, Guid noneDicomStudyId)
|
||||
{
|
||||
await QCCommonVerify.VerifyIsCRCSubmmitAsync(_repository, _userInfo, subjectVisitId);
|
||||
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
//上传根路径
|
||||
var _fileStorePath = Path.Combine(rootPath, StaticData.TrialDataFolder);
|
||||
|
||||
var sv = (await _repository.Where<SubjectVisit>(t => t.Id == subjectVisitId).Select(t => new { t.TrialId, t.SiteId, t.SubjectId }).FirstOrDefaultAsync()).IfNullThrowConvertException();
|
||||
|
||||
string uploadFolderPath = Path.Combine(_fileStorePath, sv.TrialId.ToString(), sv.SiteId.ToString(), sv.SubjectId.ToString(), subjectVisitId.ToString(), StaticData.NoneDicomFolder);
|
||||
|
||||
if (!Directory.Exists(uploadFolderPath))
|
||||
{
|
||||
Directory.CreateDirectory(uploadFolderPath);
|
||||
}
|
||||
|
||||
var startTime = DateTime.Now;
|
||||
|
||||
foreach (IFormFile file in formCollection.Files)
|
||||
{
|
||||
if (file.FileName.Contains(".Zip", StringComparison.OrdinalIgnoreCase) || file.FileName.Contains(".rar", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var archive = ArchiveFactory.Open(file.OpenReadStream());
|
||||
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
if (!entry.IsDirectory)
|
||||
{
|
||||
DealCompressFile(entry, sv, subjectVisitId, noneDicomStudyId, uploadFolderPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
var (trustedFileNameForFileStorage, fileName) = FileStoreHelper.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 = fileName, Path = relativePath, NoneDicomStudyId = noneDicomStudyId });
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 上传非Dicom 后 将状态改为待提交 分为普通上传 和QC后重传 普通上传时才改为待提交
|
||||
await _subjectVisitRepository.UpdatePartialFromQueryAsync(t => t.Id == subjectVisitId && t.SubmitState == SubmitStateEnum.None, u => new SubjectVisit() { SubmitState = SubmitStateEnum.ToSubmit });
|
||||
|
||||
var studyCode = await _noneDicomStudyRepository.Where(t => t.Id == noneDicomStudyId).Select(t => t.StudyCode).FirstOrDefaultAsync();
|
||||
|
||||
await _studyMonitorRepository.AddAsync(new StudyMonitor()
|
||||
{
|
||||
FileCount = formCollection.Files.Count,
|
||||
FileSize = formCollection.Files.Sum(t => t.Length),
|
||||
IsDicom = false,
|
||||
IsDicomReUpload = false,
|
||||
StudyId = noneDicomStudyId,
|
||||
StudyCode = studyCode,
|
||||
UploadStartTime = startTime,
|
||||
UploadFinishedTime = DateTime.Now,
|
||||
IP = _userInfo.IP,
|
||||
TrialId = sv.TrialId,
|
||||
SiteId = sv.SiteId,
|
||||
SubjectId = sv.SubjectId,
|
||||
SubjectVisitId = subjectVisitId,
|
||||
});
|
||||
|
||||
await _noneDicomStudyFileRepository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Ok(/*list*/);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private async void DealCompressFile(IArchiveEntry entry, dynamic sv, Guid subjectVisitId, Guid noneDicomStudyId, string uploadFolderPath)
|
||||
{
|
||||
var (trustedFileNameForFileStorage, fileName) = FileStoreHelper.GetStoreFileName(entry.Key);
|
||||
|
||||
var relativePath = $"/{StaticData.IRaCISDataFolder}/{StaticData.TrialDataFolder}/{sv.TrialId}/{sv.SiteId}/{sv.SubjectId}/{subjectVisitId}/{StaticData.NoneDicomFolder}/{trustedFileNameForFileStorage}";
|
||||
|
||||
var filePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||
|
||||
entry.WriteToFile(filePath);
|
||||
|
||||
await _noneDicomStudyFileRepository.AddAsync(new NoneDicomStudyFile() { FileName = fileName, Path = relativePath, NoneDicomStudyId = noneDicomStudyId });
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,18 @@
|
|||
using Hangfire;
|
||||
using IRaCIS.Core.Application.MediatR.CommandAndQueries;
|
||||
using IRaCIS.Core.Application.BackGroundJob;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Contracts;
|
||||
using IRaCIS.Core.Application.Contracts.DTO;
|
||||
using IRaCIS.Core.Application.Filter;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using MediatR;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Net.Http.Headers;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using MiniExcelLibs;
|
||||
using ExcelDataReader;
|
||||
using System.Text;
|
||||
using System.Data;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using WinSCP;
|
||||
using Magicodes.ExporterAndImporter.Excel;
|
||||
using Newtonsoft.Json;
|
||||
using IRaCIS.Core.Infrastructure;
|
||||
using IRaCIS.Core.Application.Service.Inspection.DTO;
|
||||
using Nito.AsyncEx;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using IRaCIS.Core.Application.Auth;
|
||||
using IRaCIS.Core.Application.Helper;
|
||||
|
||||
namespace IRaCIS.Core.Application.Image.QA
|
||||
{
|
||||
|
@ -39,16 +29,12 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||
private readonly IRepository<QCChallengeDialog> _qCChallengeDialogrepository;
|
||||
private readonly IRepository<CheckChallengeDialog> _checkChallengeDialogrepository;
|
||||
private readonly IRepository<Trial> _trialRepository;
|
||||
private readonly IRepository<ConsistencyCheckFile> _consistencyCheckFileRepository;
|
||||
private readonly IMediator _mediator;
|
||||
|
||||
private readonly AsyncLock _mutex = new AsyncLock();
|
||||
|
||||
public QCOperationService(DicomFileStoreHelper dicomFileStoreHelper, IRepository<SubjectVisit> subjectVisitRepository,
|
||||
IRepository<QCChallenge> qcChallengeRepository,
|
||||
IRepository<Trial> trialRepository,
|
||||
IRepository<ConsistencyCheckFile> consistencyCheckFileRepository,
|
||||
IMediator mediator,
|
||||
IRepository<DicomStudy> dicomStudyRepository,
|
||||
IRepository<DicomSeries> dicomSeriesrepository,
|
||||
IRepository<Subject> subjectRepository,
|
||||
|
@ -64,9 +50,7 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||
this._subjectRepository = subjectRepository;
|
||||
this._qCChallengeDialogrepository = qCChallengeDialogrepository;
|
||||
this._checkChallengeDialogrepository = checkChallengeDialogrepository;
|
||||
_mediator = mediator;
|
||||
_trialRepository = trialRepository;
|
||||
this._consistencyCheckFileRepository = consistencyCheckFileRepository;
|
||||
}
|
||||
|
||||
#region QC质疑 以及回复 关闭
|
||||
|
@ -519,229 +503,6 @@ namespace IRaCIS.Core.Application.Image.QA
|
|||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 一致性核查 excel上传 支持三种格式
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <param name="trialId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{trialId:guid}")]
|
||||
[TypeFilter(typeof(TrialResourceFilter))]
|
||||
[Authorize(Policy = IRaCISPolicy.PM_APM)]
|
||||
public async Task<IResponseOutput> UploadVisitCheckExcel(IFormFile file, Guid trialId)
|
||||
{
|
||||
//if (_userInfo.UserTypeEnumInt != (int)UserTypeEnum.ProjectManager && _userInfo.UserTypeEnumInt != (int)UserTypeEnum.APM)
|
||||
//{
|
||||
// return ResponseOutput.NotOk("只有PM/APM具有操作权限!");
|
||||
//}
|
||||
|
||||
var rootPath = FileStoreHelper.GetIRaCISRootDataFolder(_hostEnvironment);
|
||||
|
||||
var fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.ToString().Trim('"').ToLower();
|
||||
if (!fileName.EndsWith(".xlsx") && !fileName.EndsWith(".csv") && !fileName.EndsWith(".xls"))
|
||||
{
|
||||
return ResponseOutput.NotOk("支持.xlsx、.xls、.csv格式的文件上传。");
|
||||
}
|
||||
|
||||
//上传根路径
|
||||
string uploadFolderPath = Path.Combine(rootPath,StaticData.TrialDataFolder, trialId.ToString(), "CheckExcel");
|
||||
|
||||
if (!Directory.Exists(uploadFolderPath))
|
||||
{
|
||||
Directory.CreateDirectory(uploadFolderPath);
|
||||
}
|
||||
|
||||
//存放核对表
|
||||
var (trustedFileNameForFileStorage, realFileName) = FileStoreHelper.GetStoreFileName(fileName);
|
||||
|
||||
var filePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||
|
||||
|
||||
|
||||
using (FileStream fs = System.IO.File.Create(filePath))
|
||||
{
|
||||
await file.CopyToAsync(fs);
|
||||
await fs.FlushAsync();
|
||||
}
|
||||
|
||||
//获取Excel表内容
|
||||
var config = new MiniExcelLibs.Csv.CsvConfiguration()
|
||||
{
|
||||
StreamReaderFunc = (stream) => new StreamReader(stream, Encoding.GetEncoding("gb2312"))
|
||||
};
|
||||
|
||||
var etcCheckList = new List<CheckViewModel>();
|
||||
|
||||
|
||||
|
||||
#region MiniExcel 需要自己验证数据格式规范
|
||||
|
||||
//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
|
||||
|
||||
//Magicodes 支持自定义特性验证
|
||||
if (fileName.EndsWith(".xlsx"))
|
||||
{
|
||||
var Importer = new ExcelImporter();
|
||||
|
||||
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();
|
||||
}
|
||||
else if (fileName.EndsWith(".csv"))
|
||||
{
|
||||
#region 临时方案 MiniExcel读取 然后保存为xlsx 再用 Magicodes验证数据
|
||||
|
||||
//因为csv 需要加配置文件 不然都是null
|
||||
etcCheckList = MiniExcel.Query<CheckViewModel>(filePath, null, configuration: config).ToList();
|
||||
|
||||
var csVToXlsxPath = Path.Combine(uploadFolderPath, DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss") + Path.GetFileNameWithoutExtension(fileName) + ".xlsx");
|
||||
|
||||
await MiniExcel.SaveAsAsync(csVToXlsxPath, etcCheckList, excelType: ExcelType.XLSX);
|
||||
|
||||
|
||||
var Importer = new ExcelImporter();
|
||||
|
||||
var import = await Importer.Import<CheckViewModel>(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
|
||||
|
||||
}
|
||||
//ExcelReaderFactory 需要自己验证数据 并且从固定列取数据
|
||||
else
|
||||
{
|
||||
//为了支持 xls 引入新的组件库
|
||||
using (var stream = System.IO.File.Open(filePath, 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(stream))
|
||||
{
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//etcCheckList = etcCheckList.Where(t=>)
|
||||
|
||||
if (etcCheckList == null || etcCheckList.Count == 0)
|
||||
{
|
||||
return ResponseOutput.NotOk("请保证上传数据符合模板文件中的样式,且存在有效数据。");
|
||||
}
|
||||
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("请保证上传数据符合模板文件中的样式,且存在有效数据。");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
await _consistencyCheckFileRepository.AddAsync(new ConsistencyCheckFile()
|
||||
{
|
||||
TrialId = trialId,
|
||||
CreateTime = DateTime.Now,
|
||||
FileName = fileName,
|
||||
FilePath = filePath,
|
||||
RelativePaths = filePath.Replace(rootPath, ""),
|
||||
CreateUserId = _userInfo.Id
|
||||
});
|
||||
|
||||
//new()
|
||||
//{
|
||||
// TrialId = trialId,
|
||||
// CreateTime = DateTime.Now,
|
||||
// FileName = fileName,
|
||||
// FilePath = filePath,
|
||||
// CreateUser =
|
||||
// RelativePaths = filePath.Replace(rootPath, "");
|
||||
//};
|
||||
|
||||
|
||||
|
||||
await _mediator.Send(new ConsistencyVerificationRequest() { ETCList = etcCheckList, TrialId = trialId });
|
||||
|
||||
return ResponseOutput.Ok();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
|
|
@ -349,94 +349,5 @@ namespace IRaCIS.Core.Application
|
|||
|
||||
|
||||
|
||||
#region 调整废弃
|
||||
[Obsolete]
|
||||
[HttpPost("{trialId:guid}/{type}")]
|
||||
public async Task<IResponseOutput> UploadTrialFile(IFormFile file, string type, Guid trialId, [FromServices] IWebHostEnvironment _hostEnvironment)
|
||||
{
|
||||
|
||||
var rootPath = Directory.GetParent(_hostEnvironment.ContentRootPath.TrimEnd('\\')).IfNullThrowException().FullName;
|
||||
//上传根路径
|
||||
var _fileStorePath = Path.Combine(rootPath, StaticData.TrialDataFolder);
|
||||
|
||||
//文件类型路径处理
|
||||
var uploadFolderPath = Path.Combine(_fileStorePath, trialId.ToString(), type);
|
||||
if (!Directory.Exists(uploadFolderPath)) Directory.CreateDirectory(uploadFolderPath);
|
||||
|
||||
|
||||
var realName = file.FileName;
|
||||
var fileNameEX = Path.GetExtension(realName);
|
||||
var trustedFileNameForFileStorage = Guid.NewGuid().ToString() + fileNameEX;
|
||||
|
||||
var relativePath = $"/{StaticData.TrialDataFolder}/{trialId}/{type}/{trustedFileNameForFileStorage}";
|
||||
|
||||
var filePath = Path.Combine(uploadFolderPath, trustedFileNameForFileStorage);
|
||||
using (FileStream fs = System.IO.File.Create(filePath))
|
||||
{
|
||||
await file.CopyToAsync(fs);
|
||||
fs.Flush();
|
||||
}
|
||||
|
||||
return ResponseOutput.Ok(new
|
||||
{
|
||||
FilePath = relativePath,
|
||||
FullFilePath = relativePath + "?access_token=" + _userInfo.UserToken
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 签名认证 +
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[Obsolete]
|
||||
public async Task<IResponseOutput> VerifySignature(SignDTO signDTO)
|
||||
{
|
||||
|
||||
var user = await _repository.FirstOrDefaultAsync<User>(u => u.UserName == signDTO.UserName && u.Password == signDTO.PassWord);
|
||||
if (user == null)
|
||||
{
|
||||
return ResponseOutput.NotOk("密码错误。");
|
||||
}
|
||||
else if (user.Status == UserStateEnum.Disable)
|
||||
{
|
||||
return ResponseOutput.NotOk("该用户已被禁止使用。");
|
||||
}
|
||||
|
||||
//if (signDTO.IsAddSignData)
|
||||
//{
|
||||
// 记录签名信息
|
||||
var add = await _repository.AddAsync(_mapper.Map<TrialSign>(signDTO));
|
||||
|
||||
await _repository.SaveChangesAsync();
|
||||
|
||||
return ResponseOutput.Ok(add.Id);
|
||||
//}
|
||||
|
||||
//return ResponseOutput.Ok();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 业务接口操作成功后, 让签署数据生效
|
||||
/// </summary>
|
||||
/// <param name="signId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPut("{signId:guid}")]
|
||||
[Obsolete]
|
||||
public async Task<IResponseOutput> MakeSignEffective(Guid signId)
|
||||
{
|
||||
var success = await _repository.BatchUpdateAsync<TrialSign>(t => t.Id == signId, u => new TrialSign() { IsCompleted = true });
|
||||
|
||||
return ResponseOutput.Result(success);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ using System.Threading.Tasks;
|
|||
using EFCore.BulkExtensions;
|
||||
using IRaCIS.Core.Domain.Share;
|
||||
using IRaCIS.Core.Infra.EFCore.Common.Dto;
|
||||
using System.Reflection;
|
||||
|
||||
namespace IRaCIS.Core.Infra.EFCore
|
||||
{
|
||||
|
@ -88,6 +89,10 @@ namespace IRaCIS.Core.Infra.EFCore
|
|||
Task<bool> BatchDeleteAsync<T>(Expression<Func<T, bool>> deleteFilter) where T : Entity;
|
||||
|
||||
Task<bool> BatchUpdateAsync<T>(Expression<Func<T, bool>> where, Expression<Func<T, T>> updateFactory) where T : Entity;
|
||||
|
||||
Task UpdatePartialFromQueryAsync<T>(Expression<Func<T, bool>> updateFilter,
|
||||
Expression<Func<T, T>> updateFactory,
|
||||
bool autoSave = false, bool ignoreQueryFilter = false) where T : Entity;
|
||||
}
|
||||
|
||||
public class Repository : IRepository
|
||||
|
@ -493,6 +498,62 @@ namespace IRaCIS.Core.Infra.EFCore
|
|||
|
||||
return await _dbContext.Set<T>().AsNoTracking().IgnoreQueryFilters().Where(whereFilter).BatchUpdateAsync(updateFactory).ConfigureAwait(false) > 0;
|
||||
}
|
||||
|
||||
|
||||
public async Task UpdatePartialFromQueryAsync<T>(Expression<Func<T, bool>> updateFilter,
|
||||
Expression<Func<T, T>> updateFactory,
|
||||
bool autoSave = false, bool ignoreQueryFilter = false) where T : Entity
|
||||
{
|
||||
if (updateFilter == null)
|
||||
{
|
||||
throw new ArgumentException("更新过滤条件不允许为空", nameof(updateFilter));
|
||||
}
|
||||
var query = ignoreQueryFilter ? _dbContext.Set<T>().AsNoTracking().IgnoreQueryFilters() : _dbContext.Set<T>().AsNoTracking();
|
||||
|
||||
var searchEntityList = await query.Where(updateFilter).ToListAsync();
|
||||
|
||||
foreach (var needUpdateEntity in searchEntityList)
|
||||
{
|
||||
await UpdateAsync(needUpdateEntity, updateFactory, autoSave);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateAsync<T>(T waitModifyEntity, Expression<Func<T, T>> updateFactory, bool autoSave = false) where T : Entity
|
||||
{
|
||||
var entityEntry = _dbContext.Entry(waitModifyEntity);
|
||||
entityEntry.State = EntityState.Detached;
|
||||
|
||||
|
||||
ModifyPartialFiled(waitModifyEntity, updateFactory);
|
||||
|
||||
return await SaveChangesAsync(autoSave);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>更新后拥有完整的实体信息,便于稽查</summary>
|
||||
private void ModifyPartialFiled<T>(T waitModifyEntity, Expression<Func<T, T>> updateFactory)
|
||||
{
|
||||
List<PropertyInfo> list = ((MemberInitExpression)updateFactory.Body).Bindings.Select(mb => mb.Member.Name)
|
||||
.Select(propName => typeof(T).GetProperty(propName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)).ToList();
|
||||
|
||||
Func<T, T> func = updateFactory.Compile();
|
||||
|
||||
T applyObj = func(waitModifyEntity);
|
||||
|
||||
//深拷贝更新之前实体信息
|
||||
//var copyObj = waitModifyEntity.Clone();
|
||||
|
||||
foreach (PropertyInfo prop in list)
|
||||
{
|
||||
object value = prop.GetValue(applyObj);
|
||||
prop.SetValue(waitModifyEntity, value);
|
||||
|
||||
_dbContext.Entry(waitModifyEntity).Property(prop.Name).IsModified = true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
Loading…
Reference in New Issue