1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        「免費(fèi)開(kāi)源」基于Vue和Quasar的前端SPA項(xiàng)目crudapi后臺(tái)管理系統(tǒng)實(shí)戰(zhàn)之文件上傳(十)

        共 4331字,需瀏覽 9分鐘

         ·

        2021-06-22 16:08

        基于Vue和Quasar的前端SPA項(xiàng)目實(shí)戰(zhàn)之文件上傳(十)


        回顧


        通過(guò)之前一篇文章?基于Vue和Quasar的前端SPA項(xiàng)目實(shí)戰(zhàn)之?dāng)?shù)據(jù)導(dǎo)入的介紹,實(shí)現(xiàn)了業(yè)務(wù)數(shù)據(jù)批量導(dǎo)入功能,本文主要介紹文件上傳相關(guān)內(nèi)容。


        簡(jiǎn)介


        crudapi支持附件字段,表字段里面保存的是文件url字符串。附件可以通過(guò)其它文件管理系統(tǒng)比如阿里云的OSS進(jìn)行上傳,或者使用系統(tǒng)自帶的文件管理API進(jìn)行上傳,包括普通文件上傳和大文件切片上傳兩種方式。


        UI界面


        文件上傳?文件上傳

        大文件上傳?大文件上傳


        API


        文件上傳API

        文件上傳API,包括普通文件上傳和大文件切片兩個(gè)功能,具體的通過(guò)swagger文檔可以查看。通過(guò)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="開(kāi)啟大文件上傳模式" />
        
          <div v-show="!enableBigFile" class="q-py-md">
            <q-file v-model="normalFile" label="請(qǐng)選擇文件(普通上傳)">
              <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="請(qǐng)選擇文件(大文件上傳)">
              <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>
        

        通過(guò)toggle切換上傳模式,如果是小文件采用普通的方式即可。


        普通上傳


        async onSubmitClick() {
          console.info("CFile->onSubmitClick");
        
          if (!this.normalFile) {
            this.$q.notify({
              message: '請(qǐng)選擇文件!',
              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: "文件準(zhǔn)備中"
          });
        
          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: '請(qǐng)選擇文件!',
              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);
          }
        }
        

        大文件如果采用普通的上傳方式,可能由于網(wǎng)絡(luò)的原因速度比較慢,而且不穩(wěn)定,所以采用切片的方式進(jìn)行多線程上傳。具體原理如下:首先計(jì)算文件MD5,后臺(tái)會(huì)根據(jù)MD5唯一確定是同一個(gè)文件,同一個(gè)文件的不同block根據(jù)大小和偏移量會(huì)寫(xiě)在相同文件對(duì)應(yīng)的位置,當(dāng)最后一個(gè)block上傳成功后,表示上傳結(jié)束。分片大小默認(rèn)為20MB,可以配置為需要的值,前端通過(guò)Promise.all的ajax調(diào)用方式可以實(shí)現(xiàn)多線程同時(shí)上傳。


        文件表為例


        文件表

        文件表的“鏈接”字段設(shè)置類型為“附件ATTACHMENT”,添加業(yè)務(wù)數(shù)據(jù)頁(yè)面會(huì)自動(dòng)采用CFile組件。

        大文件上傳demo

        選擇大文件之后,點(diǎn)擊上傳圖標(biāo),通過(guò)chrome網(wǎng)絡(luò)請(qǐng)求發(fā)現(xiàn),多線程分片上傳模式已經(jīng)啟動(dòng),上傳結(jié)束之后可以查看下載。


        小結(jié)


        本文主要介紹了文件上傳功能,包括普通上傳模式和大文件切片上傳模式,大文件切片上傳模式通過(guò)優(yōu)化后很容易支持?jǐn)帱c(diǎn)續(xù)傳和秒傳,后續(xù)會(huì)根據(jù)需求優(yōu)化文件上傳功能。


        demo演示


        官網(wǎng)地址:https://crudapi.cn(opens new window)


        測(cè)試地址:https://demo.crudapi.cn/crudapi/login(opens new window)


        附源碼地址


        GitHub地址


        https://github.com/crudapi/crudapi-admin-web(opens new window)


        Gitee地址


        https://gitee.com/crudapi/crudapi-admin-web(opens new window)

        由于網(wǎng)絡(luò)原因,GitHub可能速度慢,改成訪問(wèn)Gitee即可,代碼同步更新。

        瀏覽 59
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            99r | BBB操BBB | 免费看美女被操网站 | 少妇人妻AV | 三级影片在线播放 | avwww 污片在线免费观看 | 欧美逼逼 | 久久窝窝视频 | 国产成在线观看免费视频 | 男女做爰猛烈叫床高潮的书 |