| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- 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<string> => {
- 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<UploadPartResponse> => {
- 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;
- }
- }
|