import { CHUNK_SIZE } from './config'; import Worker from './hash.worker'; // 切片 export class FileChunk { constructor(chunk, fileName, start, end, total, folder) { this.chunk = chunk; this.fileName = fileName; // 如果是文件夹,文件夹路径 this.folder = folder; // 切片起始位置 this.start = start; // 切片结束位置 this.end = end; // 文件总大小 this.total = total; // 切片 Hash 值 this.chunkName = ''; this.fileHash = ''; // 索引 this.index = 0; // 文件切片数 this.chunkNum = 0; // 文件状态 'READY', 'UPLOADING', 'SUCCESS', 'ERROR' this.status = 'READY'; } toFormData(excessData) { const formData = new FormData(); formData.append('zone', this.chunk); formData.append('zoneTotalMd5', this.fileHash); formData.append('zoneName', this.chunkName); formData.append('zoneTotalCount', this.chunkNum); formData.append('zoneStartSize', this.start); formData.append('zoneEndSize', this.end); formData.append('zoneTotalSize', this.total); formData.append('zoneNowIndex', this.index); formData.append('fileName', this.fileName); formData.append('folder', this.folder); // 文件路径 if(excessData){ Object.keys(excessData).forEach((key)=>{ formData.append(key, excessData[key]) }) } return formData; } } // 生成文件 hash(web-worker) export function calculateFileHash(fileChunkList) { return new Promise(resolve => { const worker = new Worker(); worker.postMessage({ type: 'HASH', fileChunkList }); worker.onmessage = e => { const { hash } = e.data; if (hash) { resolve(hash); } }; }); } // 生成文件切片 export function createFileChunk(file, blockSize = CHUNK_SIZE) { const fileChunkList = []; const { name, size, folder } = file; let cur = 0; while (cur < size) { let end = cur + blockSize; if (end > size) { end = size; } fileChunkList.push( new FileChunk(file.slice(cur, end), name, cur, end, size, folder), ); cur += blockSize; } const chunkNum = fileChunkList.length; fileChunkList.forEach((chunkFile, index) => { // 这里不生成 Hash 值,会严重阻塞进程 chunkFile.index = index; chunkFile.chunkNum = chunkNum; chunkFile.chunkName = chunkFile.fileName + '_' + index; }); return fileChunkList; }