欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-03-04 09:52:50
本文主要介绍了文件上传功能,包括普通上传模式和大文件切片上传模式,大文件切片上传模式通过优化后很容易支持断点续传和秒传,后续会根据需求优化文件上传功能。 ......

基于vue和quasar的前端spa项目实战之文件上传(十)

回顾

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

简介

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

ui界面

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

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

api

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

文件上传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调用方式可以实现多线程同时上传。

文件表为例

「免费开源」基于Vue和Quasar的前端SPA项目crudapi后台管理系统实战之文件上传(十)
文件表的“链接”字段设置类型为“附件attachment”,添加业务数据页面会自动采用cfile组件。

「免费开源」基于Vue和Quasar的前端SPA项目crudapi后台管理系统实战之文件上传(十)
选择大文件之后,点击上传图标,通过chrome网络请求发现,多线程分片上传模式已经启动,上传结束之后可以查看下载。

小结

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

demo演示

官网地址:
测试地址:

附源码地址

github地址

gitee地址

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