diff --git a/frontend/src/api/upload.ts b/frontend/src/api/upload.ts index 52598a4..1add1dc 100644 --- a/frontend/src/api/upload.ts +++ b/frontend/src/api/upload.ts @@ -1,26 +1,22 @@ -import { getToken } from '@/utils/token' +import request from './request' import type { ApiResponse } from '@/types/api' -/** XMLHttpRequest 上传(带进度回调)—— 保留旧版 api.js 的核心实现 */ -function postFormWithProgress(path: string, formData: FormData, onProgress?: (pct: number) => void): Promise { - return new Promise((resolve, reject) => { - const xhr = new XMLHttpRequest() - xhr.open('POST', path) - const token = getToken() - if (token) xhr.setRequestHeader('Authorization', 'Bearer ' + token) - xhr.upload.addEventListener('progress', (e) => { - if (e.lengthComputable && onProgress) { +/** + * 表单上传(带进度回调)—— 基于 axios request 实例, + * 复用请求拦截器(自动附加 Bearer Token)与响应拦截器(401 自动刷新后重试)。 + * 进度通过 axios onUploadProgress 获取。 + */ +function postFormWithProgress(path: string, formData: FormData, onProgress?: (pct: number) => void): Promise { + return request.post(path, formData, { + // 必须显式指定 multipart/form-data:request 实例默认 Content-Type 为 application/json, + // 若不覆盖,后端会将请求视为非 multipart 而抛 MultipartException(边界由浏览器自动补充)。 + headers: { 'Content-Type': 'multipart/form-data' }, + onUploadProgress: (e) => { + if (e.total && onProgress) { onProgress(Math.round((e.loaded / e.total) * 100)) } - }) - xhr.addEventListener('load', () => { - if (xhr.status === 401) { localStorage.removeItem('sb_token'); localStorage.removeItem('sb_user'); window.dispatchEvent(new Event('auth:unauthorized')); reject(new Error('401')); return } - try { resolve(JSON.parse(xhr.responseText)) } catch { reject(new Error('响应解析失败')) } - }) - xhr.addEventListener('error', () => reject(new Error('网络错误'))) - xhr.addEventListener('abort', () => reject(new Error('上传已取消'))) - xhr.send(formData) - }) + }, + }).then(r => r.data) } /** 上传文件(带进度) */ diff --git a/frontend/src/views/DocUpload.vue b/frontend/src/views/DocUpload.vue index 498b485..085e2b1 100644 --- a/frontend/src/views/DocUpload.vue +++ b/frontend/src/views/DocUpload.vue @@ -15,7 +15,7 @@ - @@ -36,9 +36,10 @@