el代码
<el-upload class="upload-demo" ref="upload" drag action="void" :auto-upload="true" multiple :limit="1" :http-request="customUpload" :on-preview="handlePreview" :on-remove="handleRemove" :before-upload="beforeUpload" :before-remove="beforeRemove" :on-exceed="handleExceed" :file-list="fileList" > <i class="el-icon-upload"></i> <div class="el-upload__text"> 将文件拖到此处,或<em>点击上传</em> </div> </el-upload>
export default { data() { return { fileList: [], }; }, created: function() { }, methods: { handleRemove(file, fileList) { console.log(file, fileList); }, handlePreview(file) { console.log(file); }, // eslint-disable-next-line no-unused-vars handleExceed(files, fileList) { this.$message.warning(`請在下方刪除已經有文件再上傳`); }, beforeUpload(file) { if (type == 1) { if ( !/\.(avi|wmv|mpg|mpeg|mov|rm|ram|swf|flv|mp4|wma|rmvb|mkv)$/.test( file.name ) ) { this.$alert( "视频类型必须是.avi,wmv,mpg,mpeg,mov,rm,ram,swf,flv,mp4,wma,rmvb,mkv中的一种", "标题名称", { confirmButtonText: "确定", customClass: "mzindex" } ); // alert( // "视频类型必须是.avi,wmv,mpg,mpeg,mov,rm,ram,swf,flv,mp4,wma,rmvb,mkv中的一种" // ); return false; } } if (type == 2) { if (!/\.(gif|jpg|jpeg|png|GIF|JPG|PNG|BMP)$/.test(file.name)) { alert("图片类型必须是.gif,jpeg,jpg,png,BMP中的一种"); return false; } } }, customUpload(file) { let vm = this; if (vm.formAdd.type == 1) { var urls = URL.createObjectURL(file.file); var audioElement = new Audio(urls); var duration; // eslint-disable-next-line no-unused-vars audioElement.addEventListener("loadedmetadata", function(_event) { duration = audioElement.duration; //时长为秒,小数,182.36 }); } let url = this.baseUrl + "v1/api/File/Upload"; let createGuid = function() { function S4() { return (((1 + Math.random()) * 0x10000) | 0) .toString(16) .substring(1); } return ( S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4() ); }; this.fileUpload(url, file, 0, createGuid()); }, //上传文件 fileUpload(uploadUrl, option, chunk, guid) { let vm = this; let file = option.file; //每次上传文件的大小 let chunkSize = 1024 * 1024; //最大上传大小 默认100M let maxSize = 1024 * 1024 * 100; let maxChunk = Math.ceil(file.size / chunkSize); let formData = new FormData(); //将文件进行分段 let fileSize = file.size; if (fileSize > maxSize) { this.$message.error("文件大小不能超过" + maxSize / 1024 / 1024 + "M"); return; } //当前上传进度 let currentPercent = parseInt((chunk / maxChunk) * 100); option.onProgress({ percent: currentPercent }); //进度条 formData.append( "file", file.slice(chunk * chunkSize, (chunk + 1) * chunkSize) ); formData.append("name", file.name); formData.append("chunk", chunk); formData.append("maxChunk", maxChunk); formData.append("guid", guid); this.$request.postURL(uploadUrl, formData).then(resJson => { if (resJson.success) { if (!resJson.data.completed) { this.fileUpload(uploadUrl, option, ++chunk, guid); } else { console.log("上传成功", resJson); option.onSuccess(); //上传成功(打钩的小图标) vm.formAdd.name = resJson.fileName; vm.formAdd.url = resJson.path; vm.$message.success("文件上传成功"); console.log("文件列表", vm.fileList); } } else { vm.$message.error(resJson.message); } }); }, // eslint-disable-next-line no-unused-vars beforeRemove(file, fileList) { // this.$confirm(`确定移除 ${file.name}?`, "提示", { // distinguishCancelAndClose: true, // lockScroll: false, // modalAppendToBody: true // }); return true; } } };
后台上传代码
[Route("[controller]")] [ApiController] public class FileController : ControllerBase { /// <summary> /// 文件存放的根路径 /// </summary> private readonly string _baseUploadDir; public FileController(IWebHostEnvironment hostingEnvironment) { _baseUploadDir = Path.Combine(_hostingEnvironment.ContentRootPath, "files"); } /// <summary> /// 分片上传文件 /// </summary> [HttpPost] [Route("upload")] public async Task<IActionResult> Upload() { try { FileUpload._baseUploadDir = _baseUploadDir; var fileName = Request.Form["name"]; //当前分块序号 var index = Request.Form["chunk"].ToString().ToInt(); //所有块数 var maxChunk = Request.Form["maxChunk"].ToString().ToInt(); //前端传来的GUID号 var guid = Request.Form["guid"]; //临时保存分块的目录 var dir = Path.Combine(_baseUploadDir, guid); //判断文件夹是否存在 if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } //分块文件名为索引名,更严谨一些可以加上是否存在的判断,防止多线程时并发冲突 var filePath = Path.Combine(dir, index.ToString()); //表单中取得分块文件 var file = Request.Form.Files["file"]; //获取文件扩展名 //var extension = file.FileName.Substring(file.FileName.LastIndexOf(".") + 1, (file.FileName.Length - file.FileName.LastIndexOf(".") - 1)); var filePathWithFileName = string.Concat(filePath, fileName); using (var stream = new FileStream(filePathWithFileName, FileMode.Create)) { await file.CopyToAsync(stream); } bool completed = false; string saveName = string.Empty; string tempPath = string.Empty; //double duration = 0; //如果是最后一个分块, 则合并文件 if (index == maxChunk) { //获取文件格式 var fileFormat = Path.GetExtension(fileName); //获取项目所在路径 string format = ""; if (fileFormat.ToUpper().IsIn(video)) { format = "video"; } if (fileFormat.ToUpper().IsIn(img)) { format = "images"; } var yearMonth = DateTime.Now.ToString("yyyyMMdd"); //最终保存路径 var finalDir = Path.Combine(_baseUploadDir, yearMonth); finalDir = Path.Combine(finalDir, format); tempPath = Path.Combine(yearMonth, format); //判断文件夹是否存在 if (!Directory.Exists(finalDir)) { Directory.CreateDirectory(finalDir); } //随机生成一个文件名 var trustedFileNameForFileStorage = Path.GetRandomFileName(); saveName = yearMonth + "_" + trustedFileNameForFileStorage + fileFormat; var finalPath = Path.Combine(finalDir, saveName); await MergeFileAsync(finalPath, guid); //_logger.LogInformation("准备获取视频详情----" + finalPath); //var mediaInfo = FFProbe.Analyse(finalPath); //_logger.LogInformation("准备获取视频详情参数----" + mediaInfo.Duration.TotalSeconds); //duration = mediaInfo.Duration.TotalSeconds; completed = true; } return Created(nameof(FileController), new { success = true, path = Path.Combine("files", tempPath, saveName), fileName = fileName.ToString(), data = new { completed, name = fileName } }); } catch (Exception ex) { _logger.LogError("上传出错", ex); throw ex; } } static string[] video = new string[] { ".MP4", ".AVI", ".WMV", ".MOV", ".MPEG" }; static string[] img = new string[] { ".JPG", ".BMP", ".PNG" }; /// <summary> /// 合并分片的文件 /// </summary> /// <param name="fileName">文件名称</param> /// <param name="guid">文件guid</param> public static async Task MergeFileAsync(string fileName, string guid) { //临时文件夹 var dir = Path.Combine(_baseUploadDir, guid); //获得下面的所有文件 var files = Directory.GetFiles(dir); var finalPath = fileName;//Path.Combine(finalDir, saveName); using (var fs = new FileStream(finalPath, FileMode.Create)) { //排一下序,保证从0-N Write var fileParts = files.OrderBy(x => x.Length).ThenBy(x => x); foreach (var part in fileParts) { var bytes = await System.IO.File.ReadAllBytesAsync(part); await fs.WriteAsync(bytes, 0, bytes.Length); bytes = null; //删除分块 System.IO.File.Delete(part); } await fs.FlushAsync(); fs.Close(); //删除临时文件夹和分片文件 Directory.Delete(dir); } } }
评论区