/** * 文件上传封装 */ import { getAccessToken, clearAll } from './storage' import type { ApiResponse } from '../types/user' import type { UploadResponse, UploadFileInfo } from '../types/workbench' import { getBaseUrl } from './request' /** * 处理 401 未授权错误 */ const handle401Error = (): void => { // 清除所有本地存储 clearAll() // 提示用户 uni.showToast({ title: '登录已过期,请重新登录', icon: 'none', duration: 2000 }) // 延迟跳转到登录页 setTimeout(() => { uni.reLaunch({ url: '/pages/login/index' }) }, 1500) } /** * 获取文件预览地址 */ export const getFileViewUrl = (fileId: string): string => { return getBaseUrl()+`${fileId}` } /** * 上传文件(多文件上传接口) * @param filePath 文件路径 * @param businessType 业务类型模块 */ export const uploadFile = (filePath: string, businessType: string): Promise => { return new Promise((resolve, reject) => { const token = getAccessToken() uni.uploadFile({ url: getBaseUrl() + `/common/upload`, filePath: filePath, name: 'file', header: { 'Authorization': 'Bearer ' + token ?? '' }, success: (res) => { // 提取属性(any 类型不能直接访问属性) const statusCode = res.statusCode as number const resData = res.data as string console.log('上传响应:', res) // 处理 401 未授权 if (statusCode == 401) { try { const errorResult = JSON.parse(resData) as UTSJSONObject const message = errorResult['message'] as string | null const error = errorResult['error'] as string | null // 显示错误信息 const errorMsg = message ?? error ?? '登录已过期' // 处理 401 错误 handle401Error() reject(new Error(errorMsg)) } catch (e: any) { handle401Error() reject(new Error('登录已过期')) } return } // 处理成功响应 if (statusCode == 200) { try { const result = JSON.parse(resData) as UTSJSONObject // 获取第一个文件信息 const fileInfo = result as UTSJSONObject let code = fileInfo["code"] as number | null; let msg = fileInfo["msg"] as string | null; if (code == 200) { const fileName = fileInfo['fileName'] as string // 构建完整的 URL const url = getFileViewUrl(fileName) // 返回 UploadResponse const uploadResult: UploadResponse = { url: url, fileId: fileName, fileName: fileName, filePath: filePath, fileSize: 0, fileExt: '', businessType: businessType } resolve(uploadResult) }else{ const errorMsg = msg != null ? msg : "请求失败"; console.error('响应数据解析失败:', errorMsg) reject(new Error(errorMsg)) } } catch (e: any) { console.error('响应数据解析失败:', e) reject(new Error('响应数据解析失败')) } } else { // 其他错误状态码 try { const errorResult = JSON.parse(resData) as UTSJSONObject const message = errorResult['message'] as string | null const error = errorResult['error'] as string | null const errorMsg = message ?? error ?? `上传失败:${statusCode}` reject(new Error(errorMsg)) } catch (e: any) { reject(new Error(`上传失败:${statusCode}`)) } } }, fail: (err: any) => { reject(new Error('上传失败,请检查网络连接')) } }) }) } /** * 上传图片 * @param filePath 文件路径 * @param businessType 业务类型模块,默认为 'image' */ export const uploadImage = (filePath: string, businessType: string | null): Promise => { const type = businessType ?? 'image' return uploadFile(filePath, type) } /** * 上传视频 * @param filePath 文件路径 * @param businessType 业务类型模块,默认为 'video' */ export const uploadVideo = (filePath: string, businessType: string | null): Promise => { const type = businessType ?? 'video' return uploadFile(filePath, type) }