import { uploadImage } from '@/services/users'; type UploadOptions = { key: string; // React Native COS SDK 推荐使用本地文件路径(file:// 或 content://) srcUri?: string; // 为兼容旧实现(Web/Blob)。在 RN SDK 下会忽略 body body?: any; contentType?: string; onProgress?: (progress: { percent: number }) => void; signal?: AbortSignal; }; export async function uploadToCos(options: UploadOptions): Promise<{ key: string; etag?: string; headers?: Record; publicUrl?: string }> { const { key, srcUri, contentType, signal } = options; if (!srcUri || typeof srcUri !== 'string') { throw new Error('请提供本地文件路径 srcUri(形如 file:/// 或 content://)'); } if (signal?.aborted) { throw new DOMException('Aborted', 'AbortError'); } try { // 创建 FormData 用于文件上传 const formData = new FormData(); // 从 srcUri 创建文件对象 let fileBlob; if (srcUri.startsWith('file://') || srcUri.startsWith('content://')) { // React Native 环境,使用 fetch 读取本地文件 const response = await fetch(srcUri); fileBlob = await response.blob(); } else { throw new Error('不支持的文件路径格式,请使用 file:// 或 content:// 格式'); } formData.append('file', { uri: srcUri, type: "image/jpeg", name: "upload.jpg", } as any); console.log('formData', formData) // 使用新的上传接口 const result = await uploadImage(formData); console.log('result', result); return { key: result.fileKey, publicUrl: result.fileUrl, }; } catch (error: any) { if (signal?.aborted) { throw new DOMException('Aborted', 'AbortError'); } console.log('uploadToCos error:', error); throw error; } } export async function uploadWithRetry(options: UploadOptions & { maxRetries?: number; backoffMs?: number }): Promise<{ key: string; etag?: string }> { const { maxRetries = 2, backoffMs = 800, ...rest } = options; let attempt = 0; // 简单指数退避 while (true) { try { return await uploadToCos(rest); } catch (e: any) { if (rest.signal?.aborted) throw e; if (attempt >= maxRetries) throw e; const wait = backoffMs * Math.pow(2, attempt); await new Promise(r => setTimeout(r, wait)); attempt++; } } }