| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { Upload, message, Button, Icon, Progress, notification } from 'antd' |
| | | import md5 from 'md5' |
| | | import { fromJS } from 'immutable' |
| | | import { Upload, Button, Icon, Progress, notification } from 'antd' |
| | | import SparkMD5 from 'spark-md5' |
| | | import Api from '@/api' |
| | | import './index.scss' |
| | | |
| | | let Url = '/Upload' |
| | | if (process.env.NODE_ENV === 'production') { |
| | | Url = document.location.origin + '/' + window.GLOB.service + 'zh-CN/Home/Upload' |
| | | } |
| | | |
| | | let service = '' |
| | | if (process.env.NODE_ENV === 'production') { |
| | | service = document.location.origin + '/' + window.GLOB.service |
| | | } else { |
| | | service = window.GLOB.location + window.GLOB.service |
| | | } |
| | | |
| | | class FileUpload extends Component { |
| | |
| | | baseUrl: Url, |
| | | percent: 0, |
| | | showprogress: false |
| | | } |
| | | |
| | | init = async () => { |
| | | try { |
| | | const OSSData = await this.mockGetOSSData() |
| | | |
| | | this.setState({ |
| | | OSSData |
| | | }) |
| | | } catch (error) { |
| | | message.error(error) |
| | | } |
| | | } |
| | | |
| | | onChange = ({ fileList }) => { |
| | |
| | | } |
| | | } |
| | | |
| | | onUpdate = (url) => { |
| | | const { value, onChange } = this.props |
| | | |
| | | let filelist = fromJS(value).toJS() |
| | | filelist[filelist.length -1].status = 'done' |
| | | filelist[filelist.length -1].response = url |
| | | filelist[filelist.length -1].origin = false |
| | | |
| | | if (onChange) { |
| | | onChange([...filelist]) |
| | | } |
| | | } |
| | | |
| | | onDelete = (msg) => { |
| | | const { value, onChange } = this.props |
| | | let filelist = value.filter(v => !v.url && !v.response) |
| | | |
| | | if (onChange) { |
| | | onChange([...filelist]) |
| | | } |
| | | |
| | | this.setState({ |
| | | showprogress: false |
| | | }) |
| | | |
| | | notification.warning({ |
| | | top: 92, |
| | | message: msg || '文件上传失败!', |
| | | duration: 5 |
| | | }) |
| | | } |
| | | |
| | | getExtraData = () => { |
| | | return { |
| | | RootPath: 'Content/images/upload/' |
| | | } |
| | | } |
| | | |
| | | shardupload = (file, shardSize, shardCount, i, fileList) => { |
| | | let start = i * shardSize |
| | | let end = Math.min(file.size, start + shardSize) |
| | | // let param = { |
| | | // file: file.slice(start, end), |
| | | // fileMd5: md5(''), |
| | | // shardingMd5: md5(''), |
| | | // baseDomain: '', |
| | | // rootPath: 'Content/images/upload/', |
| | | // fileName: file.name, |
| | | // fileExt: file.type.replace('image/', ''), |
| | | // shardingCnt: shardCount, |
| | | // shardingNo: i + 1 |
| | | // } |
| | | |
| | | shardupload = (params) => { |
| | | let param = params.chunks.shift() |
| | | let form = new FormData() |
| | | let pice = file.slice(start, end) |
| | | |
| | | form.append('file', pice) //slice方法用于切出文件的一部分 |
| | | form.append('fileMd5', md5(file)) |
| | | form.append('shardingMd5', md5(pice)) |
| | | form.append('baseDomain', '') |
| | | form.append('file', param.binary) |
| | | form.append('fileMd5', params.file.fileMd5) |
| | | form.append('shardingMd5', param.chunkMd5) |
| | | form.append('baseDomain', service) |
| | | form.append('rootPath', 'Content/images/upload/') |
| | | form.append('fileName', file.name) |
| | | form.append('fileExt', file.type.replace('image/', '')) |
| | | form.append('shardingCnt', shardCount) |
| | | form.append('shardingNo', i + 1) |
| | | form.append('fileName', params.file.fileName) |
| | | form.append('fileExt', params.file.fileType) |
| | | form.append('shardingCnt', param.chunks) |
| | | form.append('shardingNo', param.chunk) |
| | | |
| | | Api.getLargeFileUpload(form).then(res => { |
| | | if (res.status) { |
| | | if (i < shardCount) { |
| | | i++ |
| | | |
| | | if (params.chunks.length > 0) { |
| | | this.setState({ |
| | | percent: Math.floor(100 * (i / shardCount)) |
| | | percent: Math.floor(100 * (param.chunk / param.chunks)) |
| | | }) |
| | | this.shardupload(file, shardSize, shardCount, i, fileList) |
| | | this.shardupload(params) |
| | | } else { |
| | | if (res.urlPath) { |
| | | this.onUpdate(res.urlPath) |
| | | } else { |
| | | this.onDelete() |
| | | } |
| | | this.setState({ |
| | | percent: 100 |
| | | }, () => { |
| | | setTimeout(() => { |
| | | this.setState({ |
| | | showprogress: false, |
| | | percent: 0 |
| | | }) |
| | | }, 200) |
| | | }) |
| | | } |
| | | } else { |
| | | fileList = fileList.filter(item => !!item.url) |
| | | notification.warning({ |
| | | top: 92, |
| | | message: res.message, |
| | | duration: 5 |
| | | }) |
| | | this.onDelete(res.message) |
| | | } |
| | | }) |
| | | // } else { |
| | | // this.setState({ |
| | | // percent: 100 |
| | | // }, () => { |
| | | // setTimeout(() => { |
| | | // this.setState({ |
| | | // showprogress: false, |
| | | // percent: 0 |
| | | // }) |
| | | // }, 200) |
| | | // }) |
| | | // } |
| | | } |
| | | |
| | | beforeUpload = (file, fileList) => { |
| | | let shardSize = 2 * 1024 * 1024 |
| | | beforeUpload = (file) => { |
| | | this.setState({ |
| | | showprogress: true, |
| | | percent: 0 |
| | | }) |
| | | |
| | | if (file.size > shardSize) { |
| | | // this.setState({ |
| | | // showprogress: true, |
| | | // percent: 0 |
| | | // }) |
| | | // let shardCount = Math.ceil(file.size / shardSize) |
| | | // 兼容性的处理 |
| | | let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice |
| | | let chunkSize = 1024 * 1024 * 2 // 切片每次2M |
| | | let chunks = Math.ceil(file.size / chunkSize) // 切片总数 |
| | | let currentChunk = 0 // 当前上传的chunk |
| | | let spark = new SparkMD5.ArrayBuffer() // 对arrayBuffer数据进行md5加密,产生一个md5字符串 |
| | | let chunkFileReader = new FileReader() // 用于计算出每个chunkMd5 |
| | | let totalFileReader = new FileReader() // 用于计算出总文件的fileMd5 |
| | | let params = {chunks: [], file: {}} // 用于上传所有分片的md5信息 |
| | | |
| | | // this.shardupload(file, shardSize, shardCount, 0, fileList) |
| | | // return false |
| | | return true |
| | | } else { |
| | | return true |
| | | params.file.fileName = file.name.replace(/\.{1}[^.]*$/ig, '') // 文件名(去除后缀名) |
| | | params.file.fileType = file.name.replace(/^.*\.{1}/ig, '') // 文件类型 |
| | | params.file.fileSize = file.size // 文件大小 |
| | | params.file.fileChunks = chunks // 记录所有chunks的长度 |
| | | |
| | | totalFileReader.readAsArrayBuffer(file) |
| | | totalFileReader.onload = (e) => { // 对整个totalFile生成md5 |
| | | spark.append(e.target.result) |
| | | params.file.fileMd5 = spark.end() // 计算整个文件的fileMd5 |
| | | |
| | | Api.getFilePreUpload({fileMd5: params.file.fileMd5}).then(res => { |
| | | if (res.status && res.urlPath) { |
| | | this.onUpdate(res.urlPath) |
| | | this.setState({ |
| | | percent: 100 |
| | | }, () => { |
| | | setTimeout(() => { |
| | | this.setState({ |
| | | showprogress: false, |
| | | percent: 0 |
| | | }) |
| | | }, 200) |
| | | }) |
| | | } else if (res.shardings && res.shardings.length > 0) { |
| | | res.shardings.forEach(shard => { |
| | | if (shard.shardingNo && parseInt(shard.shardingNo) > currentChunk) { |
| | | currentChunk = parseInt(shard.shardingNo) |
| | | } |
| | | }) |
| | | loadNext() |
| | | } else { |
| | | loadNext() |
| | | } |
| | | }) |
| | | } |
| | | |
| | | chunkFileReader.onload = (e) => { |
| | | spark.append(e.target.result) // 对每一片分片进行md5加密 |
| | | |
| | | params.chunks[params.chunks.length - 1].chunkMd5 = spark.end() // 添加切片md5 |
| | | |
| | | currentChunk++ // 每一次分片onload,currentChunk都需要增加,以便来计算分片的次数 |
| | | |
| | | if (currentChunk < chunks) { // 当前切片总数没有达到总数时 |
| | | loadNext() |
| | | } else { |
| | | this.shardupload(params) |
| | | } |
| | | } |
| | | |
| | | chunkFileReader.onerror = () => { |
| | | this.onDelete() |
| | | console.warn('File reading failed.') |
| | | } |
| | | totalFileReader.onerror = () => { |
| | | this.onDelete() |
| | | } |
| | | |
| | | let loadNext = () => { |
| | | let start = currentChunk * chunkSize // 计算分片的起始位置 |
| | | let end = Math.min(file.size, start + chunkSize) // 计算分片的结束位置 |
| | | |
| | | let obj = { // 每一个分片需要包含的信息 |
| | | chunk: currentChunk + 1, |
| | | binary: file.slice(start, end), |
| | | start: start, |
| | | end: end, |
| | | chunks |
| | | } |
| | | |
| | | params.chunks.push(obj) |
| | | chunkFileReader.readAsArrayBuffer(blobSlice.call(file, start, end)) |
| | | } |
| | | |
| | | // loadNext() |
| | | return false |
| | | } |
| | | |
| | | /** |
| | |
| | | fileList: value, |
| | | action: baseUrl, |
| | | method: 'post', |
| | | multiple: true, |
| | | multiple: false, |
| | | onChange: this.onChange, |
| | | onRemove: this.onRemove, |
| | | data: this.getExtraData, |