import React, { Component } from 'react'; import { Icon, message, Spin, Upload, Progress, Modal } from 'antd'; import $ from 'jquery/src/ajax'; import './index.less'; import Viewer from 'viewerjs'; import 'viewerjs/dist/viewer.css'; import PropTypes from 'prop-types'; import pdfimg from '../../../../image/pdf_logo.png'; const uploadButton = ( <div> <Icon type="plus" /> <div className="ant-upload-text" style={{ cursor: 'pointer' }}>点击上传</div> </div> ); class ImgList extends Component { constructor(props) { super(props); this.state = { seeMore: false, gallery: null, loading: true, imgLoadNum: 0, uploadLoading: false, percent: 0, newUploadArr: [], newUploadInforArr: {}, isPDF: false, file: {}, } this.imgLoading = this.imgLoading.bind(this); this.beforeUpload = this.beforeUpload.bind(this); this.onRemove = this.onRemove.bind(this); this.setTimeOutObj = null; } componentDidMount() { this.setTimeOutObj = setTimeout(() => { this.setState({ gallery: new Viewer(document.getElementById(this.props.domId)) }, () => { this.setState({ loading: false }) }) }, 10000) } imgLoading() { if (Object.keys(this.props.uploadConfig).length !== 0) { this.setTimeOutObj && clearTimeout(this.setTimeOutObj); } else { let num = this.state.imgLoadNum + 1; if (num >= this.props.fileList.length) { this.state.gallery && this.state.gallery.destroy(); this.setState({ gallery: new Viewer(document.getElementById(this.props.domId)) }, () => { this.setTimeOutObj && clearTimeout(this.setTimeOutObj); this.setState({ loading: false }) }) } this.setState({ imgLoadNum: num }) } } beforeUpload(file) { const { isSupportPDF = false } = this.props const isLt2M = file.size / 1024 / 1024 < 20; if (!isLt2M) { message.error('文件大小不能超过 20MB!'); return isLt2M; } if (this.props.accept) { if (isLt2M) { this.state.newUploadArr.push(file) this.setState({ newUploadArr: this.state.newUploadArr }) } return isLt2M; } else { const isJPG = file.type.split('/'); if (isSupportPDF) { if (isJPG[0] !== 'image' && isJPG[0] !== "application") { message.error('只能上传图片或pdf文件!'); return false; } } else { if (isJPG[0] !== 'image') { message.error('只能上传图片!'); return false; } } if (isJPG && isLt2M) { // 用于计算当次选择的图片数量 this.state.newUploadArr.push(file) this.setState({ newUploadArr: this.state.newUploadArr }) } return isJPG && isLt2M; } } // 删除绑定的图片 async onRemove(info) { const { orderNo, bindId, sign, deleteApi } = this.props if (!deleteApi) { return } let name = info.response.data let remove = new Promise(function (resolve, reject) { Modal.confirm({ title: '操作确认', content: '是否确认删除?', okText: '确定', cancelText: '取消', onOk() { $.ajax({ method: "post", dataType: "json", crossDomain: false, url: globalConfig.context + deleteApi, data: { id: bindId, // 编号 (没有不用传) orderNo, // 绑定的订单号 sign, fileName: name } }).done(function (data) { if (!data.error.length) { resolve(true); } else { }; }.bind(this)); }, onCancel() { resolve(false) }, }) }); return await remove; } componentWillUnmount() { this.setTimeOutObj && clearTimeout(this.setTimeOutObj); } render() { const { fileList } = this.props; if (!fileList || !Array.isArray(fileList)) { return null; } return ( <div className='ImgListComponent'> <div className='ImgList'> <Spin spinning={Object.keys(this.props.uploadConfig).length !== 0 ? false : (fileList.length === 0 ? false : this.state.loading)} tip="文件加载中..."> <Upload {...this.props.uploadConfig} accept={this.props.accept || "image/*,application/pdf"} className={Object.keys(this.props.uploadConfig).length !== 0 ? "" : "demandDetailShow-upload"} listType={this.props.accept ? this.props.uploadConfig.listType : "picture-card"} fileList={ Object.keys(this.props.uploadConfig).length !== 0 ? ( fileList.map((v, i) => { v.index = i; v.url = v.url; v.thumbUrl = v.name.substr(v.name.lastIndexOf(".") + 1) == "pdf" ? pdfimg : v.url return v }) ) : ( this.state.seeMore ? fileList.map((v, i) => { v.index = i; v.url = v.url; v.thumbUrl = v.name.substr(v.name.lastIndexOf(".") + 1) == "pdf" ? pdfimg : v.url return v }) : fileList.map((v, i) => { v.index = i; v.url = v.url; v.thumbUrl = v.name.substr(v.name.lastIndexOf(".") + 1) == "pdf" ? pdfimg : v.url return v }).slice(0, 10) ) } onPreview={(file) => { let types = file.name.substr(file.name.lastIndexOf(".") + 1) if (!!file.type && file.type.split('/')[0] == "application" || types == "pdf") { let url = file.response.data.indexOf("/upload") == -1 ? globalConfig.avatarHost + "/upload" + file.response.data : file.response.data // this.setState({ // isPDF: true, // file: url, // }) window.open(url) } else { if (Object.keys(this.props.uploadConfig).length !== 0) { //TODO 上传组件,查看图片临时解决方法,无法查看下一张 let image = new Image(); image.src = file.url || file.thumbUrl; let viewer = new Viewer(image, { hidden: function () { viewer.destroy(); }, }); viewer.show(); } else { this.state.gallery.view(file.index).show(); } } }} beforeUpload={this.beforeUpload} onChange={(infor) => { if (infor.file.status) { let newUploadNum = this.state.newUploadArr.length this.state.gallery && this.state.gallery.destroy(); this.props.onChange(infor); if (infor.file && infor.file.status === 'error') { message.error('上传失败,请重新上传!'); } //用于控制进度条 if (infor.file && infor.file.status !== 'removed' && infor.event) { let percent = 0; this.state.newUploadInforArr[infor.file.uid] = infor.event.percent; this.setState({ newUploadInforArr: this.state.newUploadInforArr }) for (let i of Object.values(this.state.newUploadInforArr)) { percent += i } let percentNum = percent / newUploadNum / 100; this.setState({ percent: percentNum }) if (percentNum <= 1) { this.setState({ uploadLoading: true, }) } if (percentNum >= 1) { this.setState({ percent: 1, }, () => { setTimeout(() => { this.setState({ uploadLoading: false, }, () => { this.setState({ percent: 0, newUploadArr: [], newUploadInforArr: {} }) }) }, 1500) }) } } else if (infor.file && infor.file.status === 'removed') { this.setState({ percent: 0, newUploadArr: [], newUploadInforArr: {} }) } } }} onRemove={this.onRemove} > {Object.keys(this.props.uploadConfig).length === 0 ? "" : uploadButton} </Upload> </Spin> </div> {fileList.length > 10 && Object.keys(this.props.uploadConfig).length === 0 ? <div className='seeMore' onClick={() => { this.setState({ seeMore: !this.state.seeMore }) }}> {this.state.seeMore ? '收起' : '查看更多'} </div> : <div />} <ul id={this.props.domId} style={{ display: 'none', zIndex: -1, }}> { fileList.map((value, index) => ( <li key={index}> <img src={value.name.substr(value.name.lastIndexOf(".") + 1) == "pdf" ? pdfimg : (value.url || value.thumbUrl)} onLoad={() => { this.imgLoading(); }} /> </li> )) } </ul> {this.state.uploadLoading ? <div className='mask'> <Progress className='progress' type="circle" status="active" percent={parseFloat(this.state.percent * 100).toFixed(0)} /> <div className='promptText'>文件上传中...</div> </div> : <div />} { // PDF文件预览弹窗 this.state.isPDF && <Modal // maskClosable={false} wrapClassName={"pdfmodal"} visible={this.state.isPDF} className="admin-desc-content" footer="" title="" width="1200px" onCancel={() => { this.setState({ isPDF: false, file: "", }) }} > <embed src={this.state.file} type="application/pdf" style={{ width: "100%", height: 700 }} /> <div className='no'></div> </Modal> } </div> ) } } ImgList.propTypes = { domId: PropTypes.string, //如果一个界面有多个该组件,需要传入自定义id名称,用于图片列表显示 fileList: PropTypes.array.isRequired, //图片文件列表 uploadConfig: PropTypes.object, //上传图片配置参数(需要上传图片时需要,存在与否,用于区分是否为上传或者为查看) onChange: PropTypes.func, //选择图片 } ImgList.defaultProps = { domId: 'images', fileList: [], uploadConfig: {}, onChange: () => { } } export default ImgList;