##变更为手动模式后,我们可以在Upload的beforeUpload里面对上传的文件进行切片和md5加密,吧切片和md5值放到state里面,然后我们在我们自定义的Button里的onClick事件里调用state值进行上传即可
<Upload {...props}> <Button> <UploadOutlined /> Select File </Button> </Upload> <Button type="primary" onClick={this.handleUpload} disabled={fileList.length === 0} loading={uploading} style={{ marginTop: 16 }} > {uploading ? 'Uploading' : 'Start Upload'} </Button> ###自定义上传方法 handleUpload = () => { const { fileList, md5, saveConfig } = this.state; const formData = new FormData(); fileList.forEach(file => { formData.append('file', file); }); this.setState({ isUploading: true, importLoading: true, modalVisible: false, ModalVisible2: true, isUpload: false, }) clearInterval(this.state.timer) this.state.timer = setInterval(() => { if (this.state.percent < 99) { this.setState( { percent: this.state.percent + 1, }, () => { } ); } }, 5000); reqwest({ url: '/api/system/SystemUpgrade', method: 'post', processData: false, headers: { 'saveConfig': saveConfig?1:0, 'md5': md5 }, data: formData, success: (res) => { let message = formatMessage({id: "app.policy.msg.sys.success"}) this.setState({ isUpload: false, isUploading: false, importLoading: false, loading: false, percent: 100, process_status: 'success', uploadMessage: message, fileList: [], uploading: false, }) setTimeout("window.location.href = '#/auth/login'",2000) }, error: () => { this.setState({ uploading: false, }); this.setState({ isUpload: false, isUploading: false, importLoading: false, loading: false, process_status: 'exception', fileList: [], uploading: false, percent: 100, uploadMessage: formatMessage({ id: 'app.policy.msg.sys.fail' }) }) message.error(formatMessage({ 'id': 'app.policy.msg.sys.fail' })); }, }); }; ###定义Upload属性,对file进行处理,我这里只进行md5加密,因为后端采用了流式接受数据,所以前端未分片,分片可以在对文件进行分片md5加密时同时进行 const uploadProps = { accept: '.gz', showUploadList: true, multiple: false, beforeUpload: (file) => { this.setState({ fileMessage: '', }) if (file.type !== 'application/x-gzip') { this.setState({ fileMessage: formatMessage({ 'id': 'app.policy.msg.file.error' }), fileList: [], uploading: false, }) } var fileMd5 = '' var blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice, chunkSize = 2097152, // 每次读取2MB chunks = Math.ceil(file.size / chunkSize), currentChunk = 0, spark = new SparkMD5.ArrayBuffer(), frOnload = (e) => { spark.append(e.target.result); currentChunk++; if (currentChunk < chunks) loadNext(); else { ###最后一个chunk fileMd5 = spark.end() this.setState(state => ({ md5: fileMd5, fileList: [...state.fileList, file], percent: 1, uploadMessage: '', process_status: '', })); } }, frOnerror = function () { }; function loadNext() { var fileReader = new FileReader(); fileReader.onload = frOnload; fileReader.onerror = frOnerror; var start = currentChunk * chunkSize, end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize; fileReader.readAsArrayBuffer(blobSlice.call(file, start, end)); }; loadNext(); return false; }, onRemove: file => { this.setState(state => { const index = state.fileList.indexOf(file); const newFileList = state.fileList.slice(); newFileList.splice(index, 1); return { fileList: newFileList, }; }); }, fileList, }