UNPKG

qm-bus

Version:

千米公有云业务组件库

259 lines (242 loc) 8.18 kB
import React, { Component } from 'react' import { Form, Upload, Button, Icon, Input, message, Modal } from 'antd' import { QMImg } from 'qm-ui' import { QMConst, QMValidator } from 'qm-ux' const FormItem = Form.Item import { checkUrl } from '../webapi' import assign from 'object-assign' export default class Uploader extends Component { static defaultProps = { limit: 10, // 图片数量限制 rule: { limit: 10, // 文件数量限制 size: 2, // 文件大小限制 filetype: 'jpeg,jpg,gif,png', // 支持的文件类型 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 = { loading: false, preview: false, previewImage: '', files: [], linkAddress: '', netImages: [], videos: [], } } _onPull = () => { var _this = this this.setState({ loading: true }) let url = this.state.linkAddress if (url) { if (QMValidator.protocolHead(url)) { // 这里只校验协议头,防止有使用短连接的情况 checkUrl(encodeURIComponent(url)).then( res => { setTimeout(() => { if (res.err) { message.error(res.err.message) _this.setState({ loading: false }) } else { this.setState({ linkAddress: '', loading: false, netImages: this.state.netImages.concat([res.data]), }) this.props.setNetImg(res.data) } }, 500) }, res => { _this.setState({ loading: false }) } ) } else { _this.setState({ loading: false }) message.error('请输入正确的图片地址') } } else { _this.setState({ loading: false }) message.error('请输入图片地址') } } _onNetImageDel = v => { this.state.netImages.splice(v, 1) this.setState({ netImages: this.state.netImages }) } _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 = url + '@100w_100h' file.thumbUrl = url + '@100w_100h' } } 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.setImg(this.state.files) } /** * 上传前校验 */ onValidBeforeUpload = (file, files) => { let { limit, rule } = this.props let { size, filetype, limit: pic_limit } = rule limit = pic_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) || /^image/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() } } } _onLinkAddressChange = e => this.setState({ linkAddress: e.target.value }) render() { let { formLayout, headers, limit, rule } = this.props let { msg, filetype, size, limit: pic_limit } = rule limit = pic_limit || limit if (msg && typeof msg === 'function') { msg = msg({ limit, filetype, size }) } return ( <Form> <FormItem {...formLayout} label="网络图片"> <Input ref="picture-link" type="text" value={this.state.linkAddress} placeholder="请输入图片链接地址" disabled={this.state.netImages.length >= 5} onChange={this._onLinkAddressChange} /> <Button className="pushl" size="large" loading={!!this.state.loading} disabled={this.state.netImages.size >= 5} onClick={this._onPull}> 提取 </Button> <div className="network-img-preview"> <div className="ant-upload-list ant-upload-list-picture-card"> {this.state.netImages.map((i, v) => ( <div className="ant-upload-list-item ant-upload-list-item-done" key={v + '_' + i.url}> <div className="ant-upload-list-item-info"> <a className="ant-upload-list-item-thumbnail" href={QMImg.src({ src: i.url })} target="_blank"> <img src={QMImg.src({ src: i.url })} alt={i.name} title={i.name} /> </a> <span> <Icon type="eye-o" onClick={this._onPreview.bind(this, i)} /> <Icon title="Remove file" type="delete" onClick={this._onNetImageDel.bind(this, v)} /> </span> </div> </div> ))} </div> </div> </FormItem> <FormItem {...formLayout} label="本地图片" help={<span dangerouslySetInnerHTML={{ __html: msg }}></span>}> <div className="local-img-preview clearfix"> <Upload action={QMConst.HOST['v_upload_api'] + '/api/upload/image'} 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}> <QMImg alt="example" style={{ width: '100%' }} src={this.state.previewImage} /> </Modal> </FormItem> </Form> ) } }