index.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. import React,{Component} from 'react';
  2. import {Icon, message, Spin, Upload,Progress} from 'antd';
  3. import './index.less';
  4. import Viewer from 'viewerjs';
  5. import 'viewerjs/dist/viewer.css';
  6. import PropTypes from 'prop-types';
  7. const uploadButton = (
  8. <div>
  9. <Icon type="plus" />
  10. <div className="ant-upload-text">点击上传</div>
  11. </div>
  12. );
  13. class ImgList extends Component{
  14. constructor(props) {
  15. super(props);
  16. this.state={
  17. seeMore: false,
  18. gallery: null,
  19. loading: true,
  20. imgLoadNum: 0,
  21. uploadLoading: false,
  22. percent: 0,
  23. newUploadArr: [],
  24. newUploadInforArr: {},
  25. }
  26. this.imgLoading = this.imgLoading.bind(this);
  27. this.beforeUpload = this.beforeUpload.bind(this);
  28. this.setTimeOutObj = null;
  29. }
  30. componentDidMount() {
  31. this.setTimeOutObj = setTimeout(()=>{
  32. this.setState({
  33. gallery: new Viewer(document.getElementById(this.props.domId))
  34. },()=>{
  35. this.setState({
  36. loading: false
  37. })
  38. })
  39. },10000)
  40. }
  41. imgLoading(){
  42. if(Object.keys(this.props.uploadConfig).length !== 0){
  43. this.setTimeOutObj && clearTimeout(this.setTimeOutObj);
  44. }else{
  45. let num = this.state.imgLoadNum + 1;
  46. if(num >= this.props.fileList.length){
  47. this.state.gallery && this.state.gallery.destroy();
  48. this.setState({
  49. gallery: new Viewer(document.getElementById(this.props.domId))
  50. },()=>{
  51. this.setTimeOutObj && clearTimeout(this.setTimeOutObj);
  52. this.setState({
  53. loading: false
  54. })
  55. })
  56. }
  57. this.setState({
  58. imgLoadNum: num
  59. })
  60. }
  61. }
  62. beforeUpload(file) {
  63. const isJPG = file.type.split('/');
  64. if (isJPG[0] !== 'image') {
  65. message.error('只能上传图片文件!');
  66. return false;
  67. }
  68. const isLt2M = file.size / 1024 / 1024 < 10;
  69. if (!isLt2M) {
  70. message.error('图片大小不能超过 10MB!');
  71. return isLt2M;
  72. }
  73. if(isJPG && isLt2M){
  74. //用于计算当次选择的图片数量
  75. this.state.newUploadArr.push(file)
  76. this.setState({
  77. newUploadArr:this.state.newUploadArr
  78. })
  79. }
  80. return isJPG && isLt2M;
  81. }
  82. componentWillUnmount() {
  83. this.setTimeOutObj && clearTimeout(this.setTimeOutObj);
  84. }
  85. render() {
  86. const {fileList} = this.props;
  87. if(!fileList || !Array.isArray(fileList)){
  88. return null;
  89. }
  90. return (
  91. <div className='ImgListComponent'>
  92. <div className='ImgList'>
  93. <Spin spinning={Object.keys(this.props.uploadConfig).length !== 0 ? false : (fileList.length === 0 ? false : this.state.loading)} tip="图片加载中...">
  94. <Upload
  95. {...this.props.uploadConfig}
  96. accept="image/*"
  97. className={Object.keys(this.props.uploadConfig).length !== 0 ? "" : "demandDetailShow-upload" }
  98. listType="picture-card"
  99. fileList={
  100. Object.keys(this.props.uploadConfig).length !== 0 ?
  101. (
  102. fileList.map((v,i)=>{
  103. v.index = i;
  104. return v
  105. })
  106. ) : (
  107. this.state.seeMore?
  108. fileList.map((v,i)=>{
  109. v.index = i;
  110. return v
  111. }) :
  112. fileList.map((v,i)=>{
  113. v.index = i;
  114. return v
  115. }).slice(0,10)
  116. )
  117. }
  118. onPreview={(file) => {
  119. if(Object.keys(this.props.uploadConfig).length !== 0){
  120. //TODO 上传组件,查看图片临时解决方法,无法查看下一张
  121. let image = new Image();
  122. image.src = file.url || file.thumbUrl;
  123. let viewer = new Viewer(image, {
  124. hidden: function () {
  125. viewer.destroy();
  126. },
  127. });
  128. viewer.show();
  129. }else{
  130. this.state.gallery.view(file.index).show();
  131. }
  132. }}
  133. beforeUpload={this.beforeUpload}
  134. onChange={(infor)=>{
  135. if(infor.file.status){
  136. let newUploadNum = this.state.newUploadArr.length
  137. this.state.gallery && this.state.gallery.destroy();
  138. this.props.onChange(infor);
  139. if(infor.file && infor.file.status === 'error'){
  140. message.error('图片上传失败,请重新上传!');
  141. }
  142. //用于控制进度条
  143. if(infor.file && infor.file.status !== 'removed' && infor.event){
  144. let percent = 0;
  145. this.state.newUploadInforArr[infor.file.uid] = infor.event.percent;
  146. this.setState({
  147. newUploadInforArr:this.state.newUploadInforArr
  148. })
  149. for(let i of Object.values(this.state.newUploadInforArr)){
  150. percent+= i
  151. }
  152. let percentNum = percent/newUploadNum/100;
  153. this.setState({
  154. percent:percentNum
  155. })
  156. if(percentNum <= 1) {
  157. this.setState({
  158. uploadLoading: true,
  159. })
  160. }
  161. if(percentNum >= 1){
  162. this.setState({
  163. percent: 1,
  164. },()=>{
  165. setTimeout(()=>{
  166. this.setState({
  167. uploadLoading: false,
  168. },()=>{
  169. this.setState({
  170. percent: 0,
  171. newUploadArr: [],
  172. newUploadInforArr: {}
  173. })
  174. })
  175. },1500)
  176. })
  177. }
  178. }else if(infor.file && infor.file.status === 'removed'){
  179. this.setState({
  180. percent: 0,
  181. newUploadArr: [],
  182. newUploadInforArr: {}
  183. })
  184. }
  185. }
  186. }}
  187. >
  188. {Object.keys(this.props.uploadConfig).length === 0 ? "" : uploadButton}
  189. </Upload>
  190. </Spin>
  191. </div>
  192. {fileList.length > 10 && Object.keys(this.props.uploadConfig).length === 0 ? <div className='seeMore' onClick={()=>{this.setState({seeMore:!this.state.seeMore})}}>
  193. {this.state.seeMore ? '收起' : '查看更多'}
  194. </div> : <div/>}
  195. <ul id={this.props.domId} style={{display:'none',zIndex:-1,}}>
  196. {
  197. fileList.map((value,index)=>(
  198. <li key={index}>
  199. <img src={value.url || value.thumbUrl} onLoad={()=>{
  200. this.imgLoading();
  201. }}/>
  202. </li>
  203. ))
  204. }
  205. </ul>
  206. {this.state.uploadLoading ? <div className='mask'>
  207. <Progress
  208. className='progress'
  209. type="circle"
  210. status="active"
  211. percent={parseFloat(this.state.percent * 100).toFixed(0)}
  212. />
  213. <div className='promptText'>图片上传中...</div>
  214. </div> : <div/>}
  215. </div>
  216. )
  217. }
  218. }
  219. ImgList.propTypes = {
  220. domId : PropTypes.string, //如果一个界面有多个该组件,需要传入自定义id名称,用于图片列表显示
  221. fileList: PropTypes.array.isRequired, //图片文件列表
  222. uploadConfig: PropTypes.object, //上传图片配置参数(需要上传图片时需要,存在与否,用于区分是否为上传或者为查看)
  223. onChange: PropTypes.func, //选择图片
  224. }
  225. ImgList.defaultProps = {
  226. domId: 'images',
  227. fileList: [],
  228. uploadConfig: {},
  229. onChange:()=>{}
  230. }
  231. export default ImgList;