index.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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 url1 = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1601012352754&di=d33308119328f5ed987bd90031f98cfa&imgtype=0&src=http%3A%2F%2Fa2.att.hudong.com%2F27%2F81%2F01200000194677136358818023076.jpg';
  8. // const url2 = 'https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1601001245&di=60b5e1a42beb791524b46d7e3677f1f4&src=http://a2.att.hudong.com/13/86/01300001285722131043860050752.jpg';
  9. const uploadButton = (
  10. <div>
  11. <Icon type="plus" />
  12. <div className="ant-upload-text">点击上传</div>
  13. </div>
  14. );
  15. class ImgList extends Component{
  16. constructor(props) {
  17. super(props);
  18. this.state={
  19. seeMore: false,
  20. gallery: null,
  21. loading: true,
  22. imgLoadNum: 0,
  23. uploadLoading: false,
  24. uploadsuccessNum: 0,
  25. percent: 0,
  26. }
  27. this.imgLoading = this.imgLoading.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 === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/jpg';
  64. if (!isJPG) {
  65. message.error('只能上传图片文件!');
  66. }
  67. const isLt2M = file.size / 1024 / 1024 < 10;
  68. if (!isLt2M) {
  69. message.error('图片大小不能超过 10MB!');
  70. }
  71. return isJPG && isLt2M;
  72. }
  73. componentWillUnmount() {
  74. this.setTimeOutObj && clearTimeout(this.setTimeOutObj);
  75. }
  76. render() {
  77. const {fileList} = this.props;
  78. if(!fileList || !Array.isArray(fileList)){
  79. return null;
  80. }
  81. return (
  82. <div className='ImgListComponent'>
  83. <div className='ImgList'>
  84. <Spin spinning={Object.keys(this.props.uploadConfig).length !== 0 ? false : (fileList.length === 0 ? false : this.state.loading)} tip="图片加载中...">
  85. <Upload
  86. {...this.props.uploadConfig}
  87. className={Object.keys(this.props.uploadConfig).length !== 0 ? "" : "demandDetailShow-upload" }
  88. listType="picture-card"
  89. fileList={
  90. Object.keys(this.props.uploadConfig).length !== 0 ?
  91. (
  92. fileList.map((v,i)=>{
  93. v.index = i;
  94. // v.url = i%2 ? url1 : url2;
  95. return v
  96. })
  97. ) : (
  98. this.state.seeMore?
  99. fileList.map((v,i)=>{
  100. v.index = i;
  101. // v.url = i%2 ? url1 : url2;
  102. return v
  103. }) :
  104. fileList.map((v,i)=>{
  105. v.index = i;
  106. // v.url = i%2 ? url1 : url2;
  107. return v
  108. }).slice(0,10)
  109. )
  110. }
  111. onPreview={(file) => {
  112. if(Object.keys(this.props.uploadConfig).length !== 0){
  113. //TODO 上传组件,查看图片临时解决方法,无法查看下一张
  114. let image = new Image();
  115. image.src = file.url || file.thumbUrl;
  116. let viewer = new Viewer(image, {
  117. hidden: function () {
  118. viewer.destroy();
  119. },
  120. });
  121. viewer.show();
  122. }else{
  123. this.state.gallery.view(file.index).show();
  124. }
  125. }}
  126. beforeUpload={this.beforeUpload}
  127. onChange={(infor)=>{
  128. if(infor.file.status){
  129. this.state.gallery && this.state.gallery.destroy();
  130. this.props.onChange(infor);
  131. //-----------------------------
  132. if(infor.file && infor.file.status !== 'removed'){
  133. let arr = infor.fileList.filter((v)=>{return isNaN(parseInt(v.uid))});
  134. if(infor.event && infor.event.percent === 100){
  135. this.setState({
  136. uploadsuccessNum: this.state.uploadsuccessNum + 1,
  137. percent: (this.state.uploadsuccessNum + 1) / arr.length
  138. })
  139. }else{
  140. this.setState({
  141. uploadLoading: true,
  142. })
  143. }
  144. if(this.state.uploadsuccessNum === arr.length){
  145. this.setState({
  146. uploadLoading: false,
  147. },()=>{
  148. this.setState({
  149. percent: 0,
  150. })
  151. })
  152. }
  153. }else{
  154. let arr = infor.fileList.filter((v)=>{return isNaN(parseInt(v.uid))});
  155. this.setState({
  156. uploadsuccessNum: arr.length,
  157. })
  158. }
  159. //-----------------------------------
  160. if(infor.file && infor.file.status === 'error'){
  161. message.error('图片上传失败,请重新上传!');
  162. }
  163. }
  164. }}
  165. >
  166. {Object.keys(this.props.uploadConfig).length === 0 ? "" : uploadButton}
  167. </Upload>
  168. </Spin>
  169. </div>
  170. {fileList.length > 10 && Object.keys(this.props.uploadConfig).length === 0 ? <div className='seeMore' onClick={()=>{this.setState({seeMore:!this.state.seeMore})}}>
  171. {this.state.seeMore ? '收起' : '查看更多'}
  172. </div> : <div/>}
  173. <ul id={this.props.domId} style={{display:'none',zIndex:-1,}}>
  174. {
  175. fileList.map((value,index)=>(
  176. <li key={index}>
  177. <img src={value.url || value.thumbUrl} onLoad={()=>{
  178. this.imgLoading();
  179. }}/>
  180. </li>
  181. ))
  182. }
  183. </ul>
  184. {this.state.uploadLoading ? <div style={{
  185. position:"fixed",
  186. top: 0,
  187. bottom: 0,
  188. left: 0,
  189. right: 0,
  190. zIndex: 9999999999,
  191. background: 'rgba(0,0,0,.8)',
  192. display:"flex",
  193. flexFlow:'column',
  194. alignItems:'center',
  195. justifyContent:'center',
  196. }}>
  197. <Progress style={{color:'#FFF'}} type="circle" status="active" percent={parseFloat(this.state.percent * 100).toFixed(0)} />
  198. <div style={{color:'#FFF',paddingTop:'15px'}}>图片上传中...</div>
  199. </div> : <div/>}
  200. </div>
  201. )
  202. }
  203. }
  204. ImgList.propTypes = {
  205. domId : PropTypes.string, //如果一个界面有多个该组件,需要传入自定义id名称,用于图片列表显示
  206. fileList: PropTypes.array.isRequired, //图片文件列表
  207. uploadConfig: PropTypes.object, //上传图片配置参数(需要上传图片时需要,存在与否,用于区分是否为上传或者为查看)
  208. onChange: PropTypes.func, //选择图片
  209. }
  210. ImgList.defaultProps = {
  211. domId: 'images',
  212. fileList: [],
  213. uploadConfig: {},
  214. onChange:()=>{}
  215. }
  216. export default ImgList;