| | |
| | | import React, {Component} from 'react' |
| | | import PropTypes from 'prop-types' |
| | | import { is, fromJS } from 'immutable' |
| | | import BraftEditor from 'braft-editor' |
| | | import 'braft-editor/dist/index.css' |
| | | import 'braft-extensions/dist/table.css' |
| | | import BraftEditor from 'braft-editor' |
| | | import 'braft-editor/dist/output.css' |
| | | import Table from 'braft-extensions/dist/table' |
| | | import SparkMD5 from 'spark-md5' |
| | | import moment from 'moment' |
| | | |
| | | import Api from '@/api' |
| | | import './index.scss' |
| | | |
| | | BraftEditor.use(Table()) |
| | | |
| | | let service = '' |
| | | if (process.env.NODE_ENV === 'production') { |
| | | service = document.location.origin + '/' + window.GLOB.service |
| | | } else { |
| | | service = window.GLOB.location + '/' + window.GLOB.service |
| | | } |
| | | |
| | | class NormalEditor extends Component { |
| | | static propTpyes = { |
| | |
| | | value: PropTypes.any, // 条码值 |
| | | } |
| | | |
| | | state = { |
| | | editorState: '' |
| | | } |
| | | |
| | | UNSAFE_componentWillMount () { |
| | | let initVal = null |
| | | |
| | | if (this.props['data-__meta']) { |
| | | initVal = this.props['data-__meta'].initialValue || null |
| | | } |
| | | |
| | | this.setState({editorState: BraftEditor.createEditorState(initVal)}) |
| | | } |
| | | shouldComponentUpdate (nextProps, nextState) { |
| | | return !is(fromJS(this.props), fromJS(nextProps)) |
| | | } |
| | | |
| | | handleEditorChange = () => { |
| | | |
| | | handleEditorChange = (editorState) => { |
| | | this.setState({ editorState }) |
| | | if (this.props.onChange) { |
| | | this.props.onChange(editorState.toHTML()) |
| | | } |
| | | } |
| | | |
| | | submitContent = () => { |
| | | shardupload = (params, param) => { |
| | | let _param = params.chunks.shift() |
| | | let form = new FormData() |
| | | |
| | | 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', 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 (params.chunks.length > 0) { |
| | | param.progress(Math.floor(100 * (_param.chunk / _param.chunks))) |
| | | this.shardupload(params, param) |
| | | } else { |
| | | if (res.urlPath) { |
| | | param.success({ |
| | | url: res.urlPath |
| | | }) |
| | | } else { |
| | | param.error({ |
| | | url: '上传失败!' |
| | | }) |
| | | } |
| | | } |
| | | } else { |
| | | param.error({ |
| | | url: '上传失败!' |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | getuuid = () => { |
| | | let uuid = [] |
| | | let _options = '0123456789abcdefghigklmnopqrstuv' |
| | | for (let i = 0; i < 19; i++) { |
| | | uuid.push(_options.substr(Math.floor(Math.random() * 0x20), 1)) |
| | | } |
| | | uuid = uuid.join('') |
| | | return uuid |
| | | } |
| | | |
| | | handleUpload(param) { |
| | | const file = param.file |
| | | |
| | | 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信息 |
| | | |
| | | 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的长度 |
| | | |
| | | if (!/^[A-Za-z0-9]+$/.test(params.file.fileName)) { // 文件名称含有英文及数字之外字符时,名称系统生成 |
| | | params.file.fileName = moment().format('YYYYMMDDHHmmss') + this.getuuid() |
| | | } |
| | | |
| | | totalFileReader.readAsArrayBuffer(file) |
| | | totalFileReader.onload = (e) => { // 对整个totalFile生成md5 |
| | | spark.append(e.target.result) |
| | | params.file.fileMd5 = spark.end() // 计算整个文件的fileMd5 |
| | | |
| | | let _param = new FormData() |
| | | _param.append('fileMd5', params.file.fileMd5) |
| | | |
| | | Api.getFilePreUpload(_param).then(res => { |
| | | if (res.status && res.urlPath) { |
| | | param.success({ |
| | | url: res.urlPath |
| | | }) |
| | | } 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, param) |
| | | } |
| | | } |
| | | |
| | | chunkFileReader.onerror = () => { |
| | | param.error({ |
| | | url: '上传失败!' |
| | | }) |
| | | console.warn('File reading failed.') |
| | | } |
| | | totalFileReader.onerror = () => { |
| | | param.error({ |
| | | url: '上传失败!' |
| | | }) |
| | | } |
| | | |
| | | 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)) |
| | | } |
| | | } |
| | | |
| | | render() { |
| | | const { editorState } = this.state |
| | | |
| | | return ( |
| | | <div className="normal-braft-editor"> |
| | | <BraftEditor value={'<p></p>'} onChange={this.handleEditorChange} onSave={this.submitContent}/> |
| | | <BraftEditor |
| | | value={editorState} |
| | | onChange={this.handleEditorChange} |
| | | media={{ |
| | | uploadFn: (param) => { |
| | | this.handleUpload(param) |
| | | }, |
| | | validate: () => { |
| | | return true |
| | | }, |
| | | onInsert: () => { |
| | | |
| | | } |
| | | }} |
| | | /> |
| | | </div> |
| | | ) |
| | | } |