浏览代码

!831 文件上传进度显示
Merge pull request !831 from huchao/master

芋道源码 2 月之前
父节点
当前提交
66ba42b356
共有 3 个文件被更改,包括 23 次插入7 次删除
  1. 2 2
      src/api/infra/file/index.ts
  2. 12 4
      src/components/UploadFile/src/useUpload.ts
  3. 9 1
      src/views/infra/file/FileForm.vue

+ 2 - 2
src/api/infra/file/index.ts

@@ -41,6 +41,6 @@ export const createFile = (data: any) => {
 }
 
 // 上传文件
-export const updateFile = (data: any) => {
-  return request.upload({ url: '/infra/file/upload', data })
+export const updateFile = (data: any, onUploadProgress?: Function) => {
+  return request.upload({ url: '/infra/file/upload', data, onUploadProgress })
 }

+ 12 - 4
src/components/UploadFile/src/useUpload.ts

@@ -1,6 +1,6 @@
 import * as FileApi from '@/api/infra/file'
-import { UploadRawFile, UploadRequestOptions } from 'element-plus/es/components/upload/src/upload'
-import axios from 'axios'
+import { UploadRawFile, UploadRequestOptions, UploadProgressEvent } from 'element-plus/es/components/upload/src/upload'
+import axios, { AxiosProgressEvent } from 'axios'
 
 /**
  * 获得上传 URL
@@ -16,6 +16,13 @@ export const useUpload = (directory?: string) => {
   const isClientUpload = UPLOAD_TYPE.CLIENT === import.meta.env.VITE_UPLOAD_TYPE
   // 重写ElUpload上传方法
   const httpRequest = async (options: UploadRequestOptions) => {
+    // 文件上传进度监听
+    const uploadProgressHandler = (evt: AxiosProgressEvent) => {
+      const upEvt: UploadProgressEvent = Object.assign(evt.event)
+      upEvt.percent = evt.progress ? (evt.progress * 100) : 0
+      options.onProgress(upEvt) // 触发 el-upload 的 on-progress
+    }
+
     // 模式一:前端上传
     if (isClientUpload) {
       // 1.1 生成文件名称
@@ -27,7 +34,8 @@ export const useUpload = (directory?: string) => {
         .put(presignedInfo.uploadUrl, options.file, {
           headers: {
             'Content-Type': options.file.type
-          }
+          },
+          onUploadProgress: uploadProgressHandler
         })
         .then(() => {
           // 1.4. 记录文件信息到后端(异步)
@@ -39,7 +47,7 @@ export const useUpload = (directory?: string) => {
       // 模式二:后端上传
       // 重写 el-upload httpRequest 文件上传成功会走成功的钩子,失败走失败的钩子
       return new Promise((resolve, reject) => {
-        FileApi.updateFile({ file: options.file, directory })
+        FileApi.updateFile({ file: options.file, directory }, uploadProgressHandler)
           .then((res) => {
             if (res.code === 0) {
               resolve(res)

+ 9 - 1
src/views/infra/file/FileForm.vue

@@ -11,6 +11,7 @@
       :on-change="handleFileChange"
       :on-error="submitFormError"
       :on-exceed="handleExceed"
+      :on-progress="handleProgress"
       :on-success="submitFormSuccess"
       :http-request="httpRequest"
       accept=".jpg, .png, .gif"
@@ -32,6 +33,7 @@
 </template>
 <script lang="ts" setup>
 import { useUpload } from '@/components/UploadFile/src/useUpload'
+import { UploadFile, UploadProgressEvent } from 'element-plus/es/components/upload/src/upload'
 
 defineOptions({ name: 'InfraFileForm' })
 
@@ -54,16 +56,22 @@ const open = async () => {
 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 
 /** 处理上传的文件发生变化 */
-const handleFileChange = (file) => {
+const handleFileChange = (file: UploadFile) => {
   data.value.path = file.name
 }
 
+/** 处理文件上传进度显示 */
+const handleProgress = (upEvt: UploadProgressEvent, file: UploadFile) => {
+  file.percentage = upEvt.percent
+}
+
 /** 提交表单 */
 const submitFileForm = () => {
   if (fileList.value.length == 0) {
     message.error('请上传文件')
     return
   }
+  formLoading.value = true
   unref(uploadRef)?.submit()
 }