qm-bus
Version:
千米公有云业务组件库
175 lines (159 loc) • 5.13 kB
JavaScript
import React, { Component } from 'react'
import { Form, Upload, Icon, message, Modal } from 'antd'
import { QMImg } from 'qm-ui'
import { QMConst } from 'qm-ux'
import assign from 'object-assign'
const FormItem = Form.Item
/**
* 视频上传
*/
class MediaUpload extends Component {
static defaultProps = {
limit: 10,
rule: {
limit: 5, // 视频数量限制
size: 200, // 文件大小限制
filetype: 'mp4,avi,rmvb', // 支持的文件类型
msg: ({ limit, size, filetype }) =>
`视频格式仅支持:${filetype},且一次最多上传 ${limit}个,每个不能超过 ${size}MB!`,
},
}
constructor(props) {
super(props)
this.errorSet = new Set()
this.errorMsg = {
limit: ({ limit }) => `视频文件最多只能上传 ${limit}个!`,
type: ({ filetype }) => `视频文件格式仅支持:${filetype}!`,
size: ({ size }) => `视频文件大小不得超过 ${size}MB!`,
}
this.state = {
preview: false,
previewImage: '',
files: [],
}
}
_onImageDel = file => {
this.state.files.splice(this.state.files.indexOf(file), 1)
this.setState({ files: this.state.files })
}
_onPreview = file => {
if (file.response) {
this.setState({ preview: true, previewImage: file.response.data[0].url })
} else {
this.setState({ preview: true, previewImage: file.url })
}
}
_onPreviewCancel = () => {
this.setState({ preview: false })
}
_onChange = ({ file, fileList }) => {
if (file.response && file.response.success && file.status == 'done') {
let url = file.response.data[0].url
if (fileList.filter(i => i.hash == url && i.response).length > 0) {
message.warning('视频已经上传过了!')
fileList.splice(fileList.indexOf(file), 1)
} else {
file.hash = url
file.url = '//pic.qianmi.com/qmui/v0.2/img/video-img.png'
}
} else if (file.response && file.status == 'done') {
let _index = fileList.findIndex(f => f.uid == file.uid)
fileList.splice(_index, 1)
if (file.response.message) {
message.error(file.response.message)
} else {
message.error('视频上传失败!')
}
}
this.setState({ files: fileList })
this.props.setVideo(this.state.files)
}
/**
* 上传前校验
*/
onValidBeforeUpload = (file, files) => {
let { limit, rule } = this.props
let { size, filetype, limit: vedio_limit } = rule
limit = vedio_limit || limit
let index = files.indexOf(file)
let name = file.name.toLowerCase()
try {
// 1.数量校验
if (this.state.files.length + index > limit - 1) {
this.errorSet.add('limit')
throw new Error(limit)
}
// 2.文件类型校验
if (!(new RegExp(filetype.split(',').join('|')).test(name) || /^video/gi.test(file.type))) {
this.errorSet.add('type')
throw new Error(limit)
}
// 3.文件大小校验
if (file.size > 1024 * 1024 * size) {
this.errorSet.add('size')
throw new Error(limit)
}
return true
} catch (e) {
return false
} finally {
if (index === files.length - 1) {
let i = 0
for (let s of this.errorSet) {
message.config({
top: 20 + 40 * i++,
duration: 5,
})
message.error(this.errorMsg[s]({ limit, filetype, size }))
}
this.errorSet.clear()
}
}
}
render() {
let { formLayout, limit, headers, rule } = this.props
let { msg, size, filetype, limit: video_limit } = rule
limit = video_limit || limit
if (msg && typeof msg === 'function') {
msg = msg({ limit, size, filetype })
}
return (
<Form>
<FormItem
{...formLayout}
label="本地视频"
help={<span dangerouslySetInnerHTML={{ __html: msg }}></span>}>
<div className="local-img-preview clearfix">
<Upload
action={QMConst.HOST['v_upload_api'] + '/api/upload/video'}
headers={headers}
multiple
onPreview={this._onPreview}
fileList={this.state.files.map(i =>
assign({}, i, { url: QMImg.src({ src: i.url }) })
)}
onChange={this._onChange}
listType="picture-card"
beforeUpload={this.onValidBeforeUpload}
withCredentials={true}
onRemove={this._onImageDel}>
{this.state.files.length < limit ? (
<div>
<Icon type="plus" />
</div>
) : null}
</Upload>
</div>
<Modal visible={this.state.preview} footer={null} onCancel={this._onPreviewCancel}>
<video
src={QMImg.src({ src: this.state.previewImage })}
style={{ maxWidth: '480px', maxHeight: '480px' }}
controls="controls"
/>
</Modal>
</FormItem>
</Form>
)
}
}
export default MediaUpload