/** * 文件上传封装 */ import { getAccessToken, clearAll } from './storage' import type { ApiResponse } from '../types/user' import type { UploadResponse, UploadFileInfo } from '../types/workbench' // 基础 URL const BASE_URL = "http://192.168.108.77:8092" /** * 处理 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 `${BASE_URL}/file/view/${fileId}` } /** * 上传文件(多文件上传接口) * @param filePath 文件路径 * @param businessType 业务类型模块 */ export const uploadFile = (filePath: string, businessType: string): Promise => { return new Promise((resolve, reject) => { const token = getAccessToken() uni.uploadFile({ url: BASE_URL + `/file/uploads?businessType=${businessType}`, filePath: filePath, name: 'files', header: { 'accesstoken': 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 success = result['success'] as boolean | null const code = result['code'] as number | null const msg = result['msg'] as string | null const data = result['data'] as any[] | null // 判断是否成功 if (success == true || code == 0) { if (data != null && data.length > 0) { // 获取第一个文件信息 const fileInfo = data[0] as UTSJSONObject const fileId = fileInfo['fileId'] as string const fileName = fileInfo['fileName'] as string const filePath = fileInfo['filePath'] as string const fileSize = fileInfo['fileSize'] as number const fileExt = fileInfo['fileExt'] as string const businessType = fileInfo['businessType'] as string // 构建完整的 URL const url = getFileViewUrl(fileId) // 返回 UploadResponse const uploadResult: UploadResponse = { url: url, fileId: fileId, fileName: fileName, filePath: filePath, fileSize: fileSize, fileExt: fileExt, businessType: businessType } resolve(uploadResult) } else { reject(new Error('上传成功但未返回文件信息')) } } else { reject(new Error(msg ?? '上传失败')) } } 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) }