import { chunkUploadApi, mergeChunksApi } from '@/apis/upload'; import calculateMD5 from './calculateMD5'; interface Chunk { file: Blob; index: number; } interface UploadPartResponse { code?: number; message?: string; data?: any; } const CHUNK_SIZE = 5 * 1024 * 1024; export const chunkUpload = async ( file: File, // 这里是 File 类型,包含文件名和类型信息 onProgress?: (progress: number) => void ): Promise => { const chunks: Chunk[] = []; const totalChunks = Math.ceil(file.size / CHUNK_SIZE); const fileKey = await calculateMD5(file); // 创建分片 for (let i = 0; i < totalChunks; i++) { const start = i * CHUNK_SIZE; const end = Math.min(start + CHUNK_SIZE, file.size); const chunk = file.slice(start, end); chunks.push({ file: chunk, index: i + 1 }); } // 上传进度跟踪 let uploadedChunks = 0; const uploadPromises = chunks.map(chunk => { return uploadChunk( chunk.file, fileKey, chunk.index, totalChunks, onProgress ? () => { uploadedChunks++; const progress = Math.round((uploadedChunks / totalChunks) * 100); console.log(`上传进度: ${progress}%`); onProgress(progress); } : undefined ) }) // 等待所有分片上传完成 await Promise.all(uploadPromises) // 所有分片上传完成后,请求合并,传递文件名和类型 await mergeChunksApi( fileKey, totalChunks, file.name, file.type ); return fileKey; }; const uploadChunk = async ( chunk: Blob, fileKey: string, chunkNumber: number, totalChunks: number, onProgress?: () => void ): Promise => { const formData = new FormData(); formData.append('file', chunk); formData.append('fileKey', fileKey); formData.append('chunkNumber', chunkNumber.toString()); formData.append('totalChunks', totalChunks.toString()); try { const response = await chunkUploadApi(formData) if (onProgress) { onProgress(); } return { message: response.data.message || '上传成功' }; } catch (error: any) { console.error(`分片 ${chunkNumber} 上传失败:`, error); throw error; } }