import React, {Component} from 'react'
|
import PropTypes from 'prop-types'
|
import { is, fromJS } from 'immutable'
|
import { Upload, Button, Progress, notification } from 'antd'
|
import { UploadOutlined } from '@ant-design/icons'
|
|
import Api from '@/api'
|
import './index.scss'
|
|
class FileUpload extends Component {
|
static propTpyes = {
|
config: PropTypes.object, // 表单信息
|
onChange: PropTypes.func, // 表单变化
|
}
|
|
state = {
|
percent: 0,
|
accept: '',
|
accepts: null,
|
maxFile: null,
|
showprogress: false,
|
maxSize: 0,
|
filelist: []
|
}
|
|
UNSAFE_componentWillMount () {
|
const { config } = this.props
|
|
let filelist = []
|
let accept = ''
|
let accepts = null
|
|
this.setState({
|
accept,
|
accepts,
|
filelist,
|
maxSize: config.maxSize || 0,
|
maxFile: config.maxfile
|
})
|
}
|
|
shouldComponentUpdate (nextProps, nextState) {
|
return !is(fromJS(this.state), fromJS(nextState))
|
}
|
|
onChange = ({ fileList }) => {
|
fileList = fileList.map(item => {
|
if (item.status === 'error' && /^<!DOCTYPE html>/.test(item.response)) {
|
item.response = ''
|
}
|
return item
|
})
|
|
this.setState({filelist: fileList})
|
}
|
|
onRemove = file => {
|
this.setState({filelist: []})
|
|
this.props.onChange('')
|
}
|
|
onUpdate = (url, name) => {
|
let filelist = fromJS(this.state.filelist).toJS()
|
|
if (filelist[0] && url) {
|
filelist[0].status = 'done'
|
filelist[0].response = url
|
}
|
|
this.setState({filelist})
|
this.props.onChange(url, name)
|
}
|
|
onFail = (msg) => {
|
let filelist = this.state.filelist.map(item => {
|
if (!item.url && !item.response && !item.status) {
|
item.status = 'error'
|
}
|
return item
|
})
|
|
this.setState({filelist, showprogress: false, percent: 0})
|
|
notification.warning({
|
top: 92,
|
message: msg || '文件上传失败!',
|
duration: 5
|
})
|
}
|
|
beforeUpload = (file) => {
|
const { accepts, maxSize } = this.state
|
|
if (accepts && file.name) {
|
let pass = false
|
accepts.forEach(type => {
|
if (new RegExp(type + '$', 'ig').test(file.name)) {
|
pass = true
|
}
|
})
|
|
if (!pass) {
|
setTimeout(() => {
|
this.onFail('文件格式错误!')
|
}, 10)
|
return false
|
}
|
}
|
if (maxSize) {
|
let fileSize = file.size / 1024 / 1024
|
|
if (fileSize > maxSize) {
|
setTimeout(() => {
|
this.onFail(`文件大小不可超过${maxSize}M`)
|
}, 10)
|
return false
|
}
|
}
|
|
this.setState({
|
showprogress: true,
|
percent: 0
|
})
|
|
let form = new FormData()
|
|
form.append('file', file)
|
|
Api.getFileUpload(form).then(res => {
|
if (res.status) {
|
if (res.urlPath) {
|
this.onUpdate(res.urlPath, file.name)
|
} else {
|
this.onFail()
|
}
|
this.setState({
|
percent: 100
|
}, () => {
|
setTimeout(() => {
|
this.setState({
|
showprogress: false,
|
percent: 0
|
})
|
}, 200)
|
})
|
} else {
|
this.onFail(res.message)
|
}
|
})
|
|
return false
|
}
|
|
/**
|
* @description 组件销毁,清除state更新
|
*/
|
componentWillUnmount () {
|
this.setState = () => {
|
return
|
}
|
}
|
|
render() {
|
const { showprogress, percent, filelist, accept } = this.state
|
|
let uploadable = 'attach-form-container '
|
|
if (filelist.length >= 1) {
|
uploadable += 'limit-fileupload'
|
}
|
|
const props = {
|
name: 'file',
|
disabled: showprogress,
|
listType: 'text',
|
fileList: filelist,
|
action: null,
|
accept: accept,
|
method: 'post',
|
multiple: false,
|
onChange: this.onChange,
|
onRemove: this.onRemove,
|
beforeUpload: this.beforeUpload,
|
className: uploadable
|
}
|
|
return (
|
<Upload {...props}>
|
<Button>
|
<UploadOutlined /> 点击上传
|
</Button>
|
{showprogress ? <Progress percent={percent} size="small" /> : null}
|
</Upload>
|
)
|
}
|
}
|
|
export default FileUpload
|