写点什么

「免费开源」基于 Vue 和 Quasar 的前端 SPA 项目 crudapi 后台管理系统实战之文件上传(十)

用户头像
crudapi
关注
发布于: 2021 年 06 月 22 日
「免费开源」基于Vue和Quasar的前端SPA项目crudapi后台管理系统实战之文件上传(十)

基于 Vue 和 Quasar 的前端 SPA 项目实战之文件上传(十)

回顾

通过之前一篇文章基于Vue和Quasar的前端SPA项目实战之数据导入(九)的介绍,实现了业务数据批量导入功能,本文主要介绍文件上传相关内容。

简介

crudapi 支持附件字段,表字段里面保存的是文件 url 字符串。附件可以通过其它文件管理系统比如阿里云的 OSS 进行上传,或者使用系统自带的文件管理 API 进行上传,包括普通文件上传和大文件切片上传两种方式。

UI 界面


文件上传



大文件上传

API


文件上传 API,包括普通文件上传和大文件切片两个功能,具体的通过 swagger 文档可以查看。通过 axios 封装 api,名称为 file


import { axiosInstance } from "boot/axios";
const HEADERS = { "Content-Type": "multipart/form-data"};
const file = { upload: async function(data, progressCallback) { console.log("file->upload") return axiosInstance.post(`/api/file` , data, { headers: HEADERS, onUploadProgress: (progressEvent) => { if (progressCallback) { progressCallback(progressEvent) } } }); }, bigUpload: async function(data, progressCallback) { console.log("file->bigUpload") return axiosInstance.post(`/api/file/big` , data, { headers: HEADERS, onUploadProgress: (progressEvent) => { if (progressCallback) { progressCallback(progressEvent) } } }); }};
export { file };
复制代码

核心代码

CFile 组件

 <q-toggle v-model="enableBigFile" label="开启大文件上传模式" />
<div v-show="!enableBigFile" class="q-py-md"> <q-file v-model="normalFile" label="请选择文件(普通上传)"> <template v-slot:prepend> <q-icon name="attach_file" /> </template> <template v-slot:after> <q-btn round dense flat icon="send" @click="onSubmitClick" /> </template> </q-file> </div>
<div v-show="enableBigFile" class="q-py-md"> <q-file v-model="bigFile" @input="bigFileAdded" label="请选择文件(大文件上传)"> <template v-slot:prepend> <q-icon name="attach_file" /> </template> <template v-slot:after> <q-btn round dense flat icon="flight_land" @click="onBigSubmitClick" /> </template> </q-file> </div>
复制代码


通过 toggle 切换上传模式,如果是小文件采用普通的方式即可。

普通上传

async onSubmitClick() {  console.info("CFile->onSubmitClick");
if (!this.normalFile) { this.$q.notify({ message: '请选择文件!', type: 'warning' }); return; }
this.$q.loading.show({ message: "上传中" });
try { let form = new FormData() form.append('file', this.normalFile);
this.fileInfo = await fileService.upload(form, (e)=> { console.info(e); }); this.$q.loading.hide(); this.$emit("input", this.fileInfo); } catch (error) { this.$q.loading.hide(); console.error(error); }}
复制代码

大文件切片上传

bigFileAdded(f) {  console.info("CFile->fileAdded");
if (!f) { console.info("CFile->cancel"); return; }
this.$q.loading.show({ message: "文件准备中" });
FileMd5(f, this.chunkSize, (e, md5) => { this.md5 = md5; console.info(e); console.info(md5); this.$q.loading.hide(); });},
async onBigSubmitClick() { console.info("CFile->onBigSubmitClick");
if (!this.bigFile) { this.$q.notify({ message: '请选择文件!', type: 'warning' }); return; }

this.$q.loading.show({ message: "上传中" });
try { let chunks = this.getChunks();
let reqs = []; for (let i = 0; i < chunks; ++i) { reqs.push(this.uploadWithBlock(i)); }
await Promise.all(reqs) .then((datas) => { console.info(datas); this.checkFinished(datas); }); } catch (error) { this.$q.loading.hide(); console.error(error); }}
复制代码


大文件如果采用普通的上传方式,可能由于网络的原因速度比较慢,而且不稳定,所以采用切片的方式进行多线程上传。具体原理如下:首先计算文件 MD5,后台会根据 MD5 唯一确定是同一个文件,同一个文件的不同 block 根据大小和偏移量会写在相同文件对应的位置,当最后一个 block 上传成功后,表示上传结束。分片大小默认为 20MB,可以配置为需要的值,前端通过 Promise.all 的 ajax 调用方式可以实现多线程同时上传。

文件表为例


文件表的“链接”字段设置类型为“附件 ATTACHMENT”,添加业务数据页面会自动采用 CFile 组件。



选择大文件之后,点击上传图标,通过 chrome 网络请求发现,多线程分片上传模式已经启动,上传结束之后可以查看下载。

小结

本文主要介绍了文件上传功能,包括普通上传模式和大文件切片上传模式,大文件切片上传模式通过优化后很容易支持断点续传和秒传,后续会根据需求优化文件上传功能。

demo 演示

官网地址:https://crudapi.cn


测试地址:https://demo.crudapi.cn/crudapi/login

附源码地址

GitHub 地址

https://github.com/crudapi/crudapi-admin-web

Gitee 地址

https://gitee.com/crudapi/crudapi-admin-web


由于网络原因,GitHub 可能速度慢,改成访问 Gitee 即可,代码同步更新。

发布于: 2021 年 06 月 22 日阅读数: 5
用户头像

crudapi

关注

crudapi是crud+api组合,表示增删改查接口 2019.06.19 加入

使用crudapi可以告别枯燥无味的增删改查代码,让您更加专注业务,节约大量成本,从而提高工作效率。crudapi的目标是让处理数据变得更简单!官网:https://crudapi.cn 演示:https://demo.crudapi.cn/crudapi/login

评论

发布
暂无评论
「免费开源」基于Vue和Quasar的前端SPA项目crudapi后台管理系统实战之文件上传(十)