分片上传

master
xiaochanghai 11 months ago
parent fa91694469
commit 07114673a2
  1. 11
      Tiobon.Core.Api/Controllers/FileController.cs
  2. 8
      Tiobon.Core.Api/Tiobon.Core.xml
  3. 13
      Tiobon.Core.IServices/Ghre/IGhre_AttachmentServices.cs
  4. 13
      Tiobon.Core.Model/ViewModels/Extend/ChunkUpload.cs
  5. 86
      Tiobon.Core.Services/Ghre/Ghre_AttachmentServices.cs
  6. 8
      Tiobon.Core/Tiobon.Core.xml

@ -209,17 +209,12 @@ public class FileController : BaseApiController
/// <summary> /// <summary>
/// 分片上传 /// 分片上传
/// </summary> /// </summary>
/// <param name="file"></param> /// <param name="upload"></param>
/// <param name="fileName"></param>
/// <param name="chunkIndex"></param>
/// <param name="totalChunks"></param>
/// <param name="id"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost("UploadLarge")] [HttpPost("UploadLarge")]
public async Task<IActionResult> UploadLargeAsync(IFormFile file, string fileName, int chunkIndex, int totalChunks, string id) public async Task<ServiceResult<FileUploadResult>> UploadLargeAsync([FromForm] ChunkUpload upload)
{ {
dynamic obj = await _ghre_AttachmentServices.UploadVideoAsync(file, fileName, chunkIndex, totalChunks, id); return await _ghre_AttachmentServices.UploadVideoAsync(upload);
return Ok(obj);
} }
#endregion #endregion

@ -377,15 +377,11 @@
<param name="Id">主键ID</param> <param name="Id">主键ID</param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Tiobon.Core.Controllers.FileController.UploadLargeAsync(Microsoft.AspNetCore.Http.IFormFile,System.String,System.Int32,System.Int32,System.String)"> <member name="M:Tiobon.Core.Controllers.FileController.UploadLargeAsync(Tiobon.Core.Model.ChunkUpload)">
<summary> <summary>
分片上传 分片上传
</summary> </summary>
<param name="file"></param> <param name="upload"></param>
<param name="fileName"></param>
<param name="chunkIndex"></param>
<param name="totalChunks"></param>
<param name="id"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="T:Tiobon.Core.Controllers.LoginController"> <member name="T:Tiobon.Core.Controllers.LoginController">

@ -1,15 +1,16 @@
using Microsoft.AspNetCore.Http; using Tiobon.Core.IServices.BASE;
using Tiobon.Core.IServices.BASE; using Tiobon.Core.Model;
using Tiobon.Core.Model.Models; using Tiobon.Core.Model.Models;
using Tiobon.Core.Model.ViewModels;
namespace Tiobon.Core.IServices namespace Tiobon.Core.IServices
{ {
/// <summary> /// <summary>
/// 附件(自定义服务接口) /// 附件(自定义服务接口)
/// </summary> /// </summary>
public interface IGhre_AttachmentServices :IBaseServices<Ghre_Attachment, Ghre_AttachmentDto, InsertGhre_AttachmentInput, EditGhre_AttachmentInput> public interface IGhre_AttachmentServices :IBaseServices<Ghre_Attachment, Ghre_AttachmentDto, InsertGhre_AttachmentInput, EditGhre_AttachmentInput>
{ {
Task<dynamic> UploadVideoAsync(IFormFile file, string fileName, int chunkIndex, int totalChunks, string id); Task<ServiceResult<FileUploadResult>> UploadVideoAsync(ChunkUpload upload);
} }
} }

@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Http;
namespace Tiobon.Core.Model;
public class ChunkUpload
{
public IFormFile file { get; set; }
public string fileName { get; set; } = null;
public int chunkIndex { get; set; }
public int totalChunks { get; set; }
public string id { get; set; } = null;
}

@ -3,9 +3,14 @@ using Tiobon.Core.IServices;
using Tiobon.Core.Model.Models; using Tiobon.Core.Model.Models;
using Tiobon.Core.Services.BASE; using Tiobon.Core.Services.BASE;
using Tiobon.Core.IRepository.Base; using Tiobon.Core.IRepository.Base;
using Microsoft.AspNetCore.Http;
using System.Dynamic; using System.Dynamic;
using SqlSugar; using SqlSugar;
using Tiobon.Core.Model;
using Tiobon.Core.DataAccess;
using NPOI.HPSF;
using SharpCompress.Common;
using Tiobon.Core.Common;
using Tiobon.Core.Model.ViewModels;
namespace Tiobon.Core.Services namespace Tiobon.Core.Services
{ {
@ -21,37 +26,62 @@ namespace Tiobon.Core.Services
base.BaseDal = dal; base.BaseDal = dal;
} }
public async Task<dynamic> UploadVideoAsync(IFormFile file, string fileName, int chunkIndex, int totalChunks, string id) public async Task<ServiceResult<FileUploadResult>> UploadVideoAsync(ChunkUpload upload)
{ {
dynamic obj = new ExpandoObject(); var file = upload.file;
string status = "error"; var path = $"{$"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}wwwroot{Path.DirectorySeparatorChar}files{Path.DirectorySeparatorChar}upload{Path.DirectorySeparatorChar}{upload.id}{Path.DirectorySeparatorChar}"}";
string message = string.Empty; if (!Directory.Exists(path))
string pathHeader = string.Empty; Directory.CreateDirectory(path);
string url = string.Empty; using (var stream = File.Create(path + $"{upload.chunkIndex}"))
{
await file.CopyToAsync(stream);
}
try if (upload.chunkIndex == upload.totalChunks - 1)
{ {
var path = $"{$"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}wwwroot{Path.DirectorySeparatorChar}files{Path.DirectorySeparatorChar}upload{Path.DirectorySeparatorChar}{id}{Path.DirectorySeparatorChar}"}"; var id = SnowFlakeSingle.Instance.NextId();
if (!Directory.Exists(path)) await FileMerge(upload.id, ".mp4", id);
Directory.CreateDirectory(path); using var _context = ContextFactory.CreateContext();
using (var stream = File.Create(path + $"{chunkIndex}"))
var ext = string.Empty;
if (string.IsNullOrEmpty(file.FileName) == false)
{ {
await file.CopyToAsync(stream); var dotPos = upload.fileName.LastIndexOf('.');
ext = upload.fileName.Substring(dotPos + 1);
} }
var filePath = $"/files/upload/{id}.{ext}";
if (chunkIndex == totalChunks - 1) var fileAttachment = new Ghre_Attachment();
await FileMerge(id, ".mp4", SnowFlakeSingle.Instance.NextId()); fileAttachment.Id = SnowFlakeSingle.Instance.NextId();
fileAttachment.AttachmentNo = upload.file.FileName;
status = "ok"; fileAttachment.AttachFileName = upload.file.FileName;
} fileAttachment.CreateBy = App.User.ID;
catch (Exception E) fileAttachment.CreateTime = DateTime.Now;
{ fileAttachment.AttachmentName = upload.fileName;
message = E.Message; fileAttachment.AttachFileExtension = ext;
fileAttachment.AttachFileSize = upload.file.Length;
fileAttachment.PhysicsPath = filePath;
fileAttachment.RelativePath = filePath;
fileAttachment.FileURL = filePath;
fileAttachment.ThumbnailPath = filePath;
fileAttachment.AttachmentType = upload.file.ContentType;
//url = fileName + "." + ext;
_context.Add(fileAttachment);
_context.SaveChanges();
return ServiceResult<FileUploadResult>.OprateSuccess("", new FileUploadResult()
{
Id = fileAttachment.Id,
AttachFileExtension = fileAttachment.AttachFileExtension,
AttachFileName = fileAttachment.AttachFileName,
AttachmentName = fileAttachment.AttachmentName,
AttachmentNo = fileAttachment.AttachmentNo,
FileURL = fileAttachment.FileURL,
PhysicsPath = fileAttachment.PhysicsPath,
RelativePath = fileAttachment.RelativePath,
ThumbnailPath = fileAttachment.ThumbnailPath,
AttachFileSize = fileAttachment.AttachFileSize,
});
} }
obj.url = url; return ServiceResult<FileUploadResult>.OprateSuccess("", null);
obj.status = status;
obj.message = message;
return obj;
} }
public static async Task<object> FileMerge(string lastModified, string fileExts, long NewfileName) public static async Task<object> FileMerge(string lastModified, string fileExts, long NewfileName)
@ -60,7 +90,7 @@ namespace Tiobon.Core.Services
bool ok = false; bool ok = false;
try try
{ {
string wwwroot = $"{Directory.GetCurrentDirectory()}/wwwroot/"; string wwwroot = $"{Directory.GetCurrentDirectory()}/wwwroot/files/upload/";
var temporary = Path.Combine(wwwroot, lastModified);//临时文件夹 var temporary = Path.Combine(wwwroot, lastModified);//临时文件夹
//fileName = Request.Form["fileName"];//文件名 //fileName = Request.Form["fileName"];//文件名
string fileExt = fileExts;//获取文件后缀 string fileExt = fileExts;//获取文件后缀
@ -69,7 +99,7 @@ namespace Tiobon.Core.Services
if (!di.Exists) if (!di.Exists)
di.Create(); di.Create();
var finalPath = Path.Combine(wwwroot + lastModified + "/", NewfileName + fileExt);//最终的文件名(demo中保存的是它上传时候的文件名,实际操作肯定不能这样) var finalPath = Path.Combine(wwwroot, NewfileName + fileExt);//最终的文件名(demo中保存的是它上传时候的文件名,实际操作肯定不能这样)
var fs = new FileStream(finalPath, FileMode.Create); var fs = new FileStream(finalPath, FileMode.Create);
foreach (var part in files.OrderBy(x => x.Length).ThenBy(x => x))//排一下序,保证从0-N Write foreach (var part in files.OrderBy(x => x.Length).ThenBy(x => x))//排一下序,保证从0-N Write
{ {

@ -377,15 +377,11 @@
<param name="Id">主键ID</param> <param name="Id">主键ID</param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Tiobon.Core.Controllers.FileController.UploadLargeAsync(Microsoft.AspNetCore.Http.IFormFile,System.String,System.Int32,System.Int32,System.String)"> <member name="M:Tiobon.Core.Controllers.FileController.UploadLargeAsync(Tiobon.Core.Model.ChunkUpload)">
<summary> <summary>
分片上传 分片上传
</summary> </summary>
<param name="file"></param> <param name="upload"></param>
<param name="fileName"></param>
<param name="chunkIndex"></param>
<param name="totalChunks"></param>
<param name="id"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="T:Tiobon.Core.Controllers.LoginController"> <member name="T:Tiobon.Core.Controllers.LoginController">

Loading…
Cancel
Save