UNPKG

qm-bus

Version:

千米公有云业务组件库

264 lines (244 loc) 8.19 kB
import React, { Component } from 'react' import { Form, Upload, Icon, message, Modal, Input, Button } from 'antd' import { QMImg } from 'qm-ui' import { QMConst } from 'qm-ux' import assign from 'object-assign' import { Relax } from 'iflux2' import { checkUrl } from '../webapi' import { netImagesQL, imagesQL, linkAddressQL, scopeQL } from '../ql' const noop = () => undefined const FormItem = Form.Item @Relax 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!`, }, addNetImage: noop, removeNetImage: noop, addImage: noop, removeImage: noop, netImages: netImagesQL, images: imagesQL, linkAddress: linkAddressQL, setLinkAddress: noop, scope: scopeQL, } 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: [], } } componentWillReceiveProps(nextProps) { if (nextProps.images.size == 0) { this.setState({ files: [] }) } } _onPull = () => { var _this = this this.setState({ loading: true }) let url = this.props.linkAddress if (url) { checkUrl(encodeURIComponent(url), this.props.scope).then(res => { setTimeout(() => { _this.setState({ loading: false }) if (res.err) { message.error(res.err.message) } else { _this.props.addNetImage(res.data) _this.props.setLinkAddress('') } }, 500) }) } else { _this.setState({ loading: false }) message.error('请输入图片地址') } } // 网络图片的删除 _onNetImageDel = v => this.props.removeNetImage(v) // 图片删除 _onImageDel = file => this.props.removeImage(file.hash) _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' this.props.addImage(file.response.data[0]) } } 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 }) } /** * 上传前校验 */ 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.props.setLinkAddress(e.target.value) render() { let { formLayout, limit, rule } = this.props let { msg, size, filetype, limit: pic_limit } = rule limit = pic_limit || limit if (msg && typeof msg === 'function') { msg = msg({ limit, filetype, size }) } let { Platform, SystemId } = QMConst.get('project') let headers = { Platform: Platform, systemId: SystemId, } const url = this.props.scope === 'personal' ? '/api/upload/user/image' : '/api/upload/image' return ( <Form> <FormItem {...formLayout} label="网络图片"> <Input ref="picture-link" type="text" value={this.props.linkAddress} placeholder="请输入图片链接地址" disabled={this.props.netImages.length >= 5} onChange={this._onLinkAddressChange} /> <Button className="pushl" size="large" loading={!!this.state.loading} disabled={this.props.netImages.size >= 5} onClick={this._onPull}> 提取 </Button> <div className="network-img-preview"> <div className="ant-upload-list ant-upload-list-picture-card"> {this.props.netImages.map((i, v) => ( <div key={v + '_' + i.url} className="ant-upload-list-item ant-upload-list-item-done"> <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']) + url} 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={'PREVIEW'} style={{ width: '100%' }} src={this.state.previewImage} /> </Modal> </FormItem> </Form> ) } }