1+ import React , { Component } from 'react'
2+ import PropTypes from 'prop-types'
3+ import { Upload , Icon , Modal , Button , Input , notification } from 'antd'
4+ import styles from './UploadFile.less'
5+
6+ const getFileList = ( files ) => {
7+ if ( Array . isArray ( files ) ) {
8+ return files . map ( ( item , key ) => {
9+ const urlArr = item . url . split ( '/' )
10+ return { url : item . url , id : item . id , uid : key , key :item . key , name : urlArr [ urlArr . length - 1 ] , status : 'done' }
11+ } )
12+ }
13+ if ( files && ! ! files . length ) {
14+ const filesArr = files . split ( '/' )
15+ return [ { uid : - 1 , url : files , name : filesArr [ filesArr . length - 1 ] , status : 'done' } ]
16+ }
17+ return ''
18+ }
19+
20+ function renderAccecpt ( accept ) {
21+ if ( ! accept ) {
22+ return null
23+ }
24+ if ( [ 'image' , 'video' , 'audio' ] . find ( ext => ext === accept ) ) {
25+ return `${ accept } /*`
26+ }
27+ if ( accept === 'zip' ) {
28+ return 'application/zip,application/x-zip,application/x-zip-compressed'
29+ }
30+ return `.${ accept } `
31+ }
32+
33+ class UploadFiles extends Component {
34+ static propTypes = {
35+ files : PropTypes . oneOfType ( [ PropTypes . array , PropTypes . string ] ) ,
36+ onUpload : PropTypes . func . isRequired ,
37+ multiple : PropTypes . oneOfType ( [ PropTypes . bool , PropTypes . number ] ) ,
38+ disabled : PropTypes . bool ,
39+ path : PropTypes . string ,
40+ accept : PropTypes . string ,
41+ }
42+ constructor ( props ) {
43+ super ( props )
44+ this . state = {
45+ previewVisible : false ,
46+ previewImage : '' ,
47+ files : getFileList ( props . files ) ,
48+ webpicVisible :false ,
49+ weburl :''
50+ }
51+ }
52+
53+ componentWillReceiveProps ( nextProps ) {
54+ if ( Array . isArray ( this . props . files ) && ! this . props . files . length && ! ! nextProps . files . length ) {
55+ this . setState ( { files : getFileList ( nextProps . files ) } )
56+ }
57+ }
58+ showWebPic = ( ) => {
59+ this . setState ( { webpicVisible :true } )
60+ }
61+ picInputChange = ( e ) => {
62+ this . setState ( { weburl :e . target . value } )
63+ }
64+ useWebPic = ( ) => {
65+ const { weburl, files} = this . state ;
66+ const ishttp = weburl . indexOf ( 'http' ) > - 1 ;
67+ const isimg = weburl . indexOf ( '.jpg' ) > - 1 || weburl . indexOf ( '.png' ) || weburl . indexOf ( '.jepg' ) > - 1 ;
68+ if ( ! ishttp || ! isimg ) {
69+ return notification . error ( { message : '添加失败' , description :"非法链接" } ) ;
70+ }
71+ let newFiles = [ ] ;
72+ const obj = { uid :files . length + 1 , id :files . length + 1 , url :weburl , key :weburl . split ( '.com' ) [ 1 ] , status :'done' } ;
73+ newFiles . push ( obj ) ;
74+ this . props . onUpload ( obj ) ;
75+ this . setState ( { files :newFiles , webpicVisible :false } )
76+ }
77+ render ( ) {
78+ const { previewVisible, webpicVisible, previewImage, files} = this . state
79+ const { multiple = 1 , showWeb, onUpload, onRemove, disabled, data, path, accept } = this . props
80+ const renderFiles = ( fileList ) => {
81+ const newFiles = fileList . map ( ( file ) => {
82+ return file . response ? { id :file . response . data . id , url :file . response . data . url , key :file . response . data . key } : file
83+ } )
84+ if ( multiple === 1 ) {
85+ return newFiles [ 0 ]
86+ }
87+ return newFiles
88+ }
89+ //post url
90+ let actionUrl = `${ API_URL } /file`
91+ if ( path ) {
92+ actionUrl += `&path=${ path } `
93+ }
94+ const uploadProps = {
95+ accept : renderAccecpt ( accept ) ,
96+ action : actionUrl ,
97+ headers : {
98+ 'X-Requested-With' : null ,
99+ } ,
100+ data :data ,
101+ disabled,
102+ listType : 'picture-card' ,
103+ fileList : files ,
104+ multiple : multiple === true ,
105+ onPreview : ( file ) => {
106+ this . setState ( {
107+ previewImage : file . url || file . thumbUrl ,
108+ previewVisible : true ,
109+ } )
110+ } ,
111+ beforeUpload : ( ) => {
112+ return true
113+ } ,
114+ onChange : ( { file, fileList } ) => {
115+ this . setState ( { files : fileList } )
116+ if ( file . percent === 100 && file . status === 'done' ) {
117+ onUpload ( renderFiles ( fileList , 1 ) )
118+ }
119+ } ,
120+ onRemove : ( file ) => {
121+ let fileKey ;
122+ const { response, key} = file ;
123+ fileKey = key ;
124+ if ( response ) {
125+ fileKey = response . data . key ;
126+ }
127+ if ( disabled ) {
128+ return false
129+ }
130+ const fileList = this . state . files . filter ( item => item . uid !== file . uid )
131+ onUpload ( renderFiles ( fileList , 0 ) )
132+ onRemove ( fileKey ) ;
133+ return true
134+ } ,
135+ }
136+ const modalProps = {
137+ visible : previewVisible ,
138+ footer : null ,
139+ onCancel : ( ) => this . setState ( { previewVisible : false } ) ,
140+ }
141+ const modalPropsPic = {
142+ title :'添加网络图片' ,
143+ visible : true ,
144+ onCancel : ( ) => this . setState ( { webpicVisible :false } ) ,
145+ onOk :( ) => this . useWebPic ( )
146+ }
147+ const uploadButton = (
148+ < div >
149+ < Icon type = "plus" />
150+ < div className = "ant-upload-text" > 本地上传</ div >
151+ </ div >
152+ )
153+ return (
154+ < div className = "clearfix" >
155+ < Upload { ...uploadProps } >
156+ { multiple === true ? uploadButton : ( files . length < multiple && uploadButton ) }
157+ </ Upload >
158+ { showWeb && < Button icon = "plus" onClick = { this . showWebPic } > 网络图片</ Button > }
159+ < Modal { ...modalProps } >
160+ < img className = { styles . previewImage } src = { previewImage } />
161+ </ Modal >
162+ { webpicVisible && < Modal { ...modalPropsPic } >
163+ < Input placeholder = "输入图片链接..." onChange = { this . picInputChange } style = { { width :'100%' } } />
164+ </ Modal > }
165+ </ div >
166+ )
167+ }
168+ }
169+
170+ export default UploadFiles
0 commit comments