UNPKG

@beisen/form-uploader

Version:

form file image uploader

1,120 lines (1,063 loc) 38.6 kB
/* eslint-disable */ import React, {Component} from 'react' import ToolTip from "@beisen/tool-tip" import CommonLabel from '@beisen/common-label' import { decode, transFormat } from '@beisen/common-func' import '../src/index.scss'; function getBody(xhr) { const text = xhr.responseText || xhr.response; if (!text) { return text; } try { return JSON.parse(text); } catch (e) { return text; } } var fileiconName = { aac: 'asc', ape: 'ape', asf: 'asf', avi: 'avi', doc: 'doc', docx: 'docx', exe: 'exe', file: 'file', flac: 'flac', flv: 'flv', folder: 'folder', folder2: 'folder2', gif: 'gif', image: 'image', jpeg: 'jpeg', jpg: 'jpg', m4a: 'm4a', m4v: 'm4v', mkv: 'mkv', mmap: 'mmap', mov: 'mov', mp3: 'mp3', mp4: 'mp4', mpeg: 'mpeg', mpg: 'mpg', music: 'music', none: 'none', ogg: 'ogg', pdf: 'pdf', pic: 'pic', png: 'png', ppt: 'ppt', pptx: 'pptx', rar: 'rar', rm: 'rm', rmvb: 'rmvb', tif: 'tif', ts: 'ts', txt: 'txt', video: 'video', wav: 'wav', wma: 'wma', wmv: 'wmv', xls: 'xls', xlsx: 'xlsx', zip: 'zip' }; const defaultTranslation = { fileSizeZeroError: '文件大小不许为0字节!', previewDownloadText: '下载', reUploadText: '重新上传', uploadOnceLimit: '单次上传文件数不能超过{0}个', fileNameContainsCommaError: '文件名不允许包含符号","', allFilesCountLimit: '总文件数不能超过{0}个', emptyText: '- 空 -', fileTypeError: '文件格式错误!!!', fileSizeBigError: '上传文件大小不得超过{0}!', uploadText: '上传' }; class FormUploader extends Component { static defaultProps = { hiddenTip: false, sideTip: false } constructor(props) { super(props); // const defaults = { // labelText: '', // 左侧文字` // labelTip: '', // 右侧提示信息 // status: 'show', // show状态 和 edit 状态 // url: '', // 上传地址 // multiple: true, // fileInputName: '', // fileSize: '2mb',// mb kb b // fileType: [], // 提供文件验证类型 // onceUploadCount: 3, // multiple时 // allUploadConut: 6, // hasLoadFile: [], // 已经上传的文件 // extendData: {}, // key-value // isDrag: true, // formItem 拖拽默认有 粘贴没有 // isPaste: true, // 只有功能性组件 默认有 // hasLoadFile: [], // 已经上传文件 // previewText: '' || '预览', // maxLength:false, // onSuccess: () => {}, // 发送数据成功回调 // onFailure: () => {}, // 请求失败回调 // onProgress: () => {}, // 请求过程回调 // onDragOver: () => {}, // 文件拖至区域 // onDragLeave: () => {}, // 文件离开区域 // onDrop: () => {} // 拖至区域 // }; this.translation = Object.assign({}, defaultTranslation, props.translation); this.previewUrl = {}; for (var i = 0; i < props.hasLoadFile.length; i++) { if (props.hasLoadFile[i].Name == "") { props.hasLoadFile.splice(i,1); } } this.tempRank = null; this.state = { hasUploadCount: props.hasLoadFile && props.hasLoadFile.length || 0, isDrag: props.isDrag || true, // isPaste: props.isPaste || true, // fileList: [], // 通过input添加的文件 response: props.hasLoadFile || [], // 上传成功返回的结果 isSuccess: false, currentFileList: [], // 单次通过input添加的文件 currentFile: [], //总的input添加的文件 errorMessage: props.errorMessage, //必填验证 errorShow: {type: false, messages: ''}, disappearTime: 2, //自动消失时间,默认为1.5s,可选值有1.5,3,5,10 isRenderInput: true, //重新渲染上传按钮,刷新上传按钮的值 uid: this.getUid(), isRequest: false,//wangyongning 请求过程中 isDel: 0 //删除的个数 } this.changeFiles = this.changeFiles.bind(this); this.deleteFile = this.deleteFile.bind(this); this.renderShow = this.renderShow.bind(this); this.renderCurrentFile = this.renderCurrentFile.bind(this); this.disButton = this.disButton.bind(this); this.clickPreview = this.clickPreview.bind(this); this.getPreviewUrl = this.getPreviewUrl.bind(this); this.handleKeyDown = this.handleKeyDown.bind(this); } // zhongjiahao getUid() { const now = +(new Date()); let index = 0; return `upload-${now}-${++index}`; } reset() { let _id = 'uploader-input-' + this.tempRank; let btn = document.getElementById(_id); btn.setAttribute('value', ''); } // input type file change 事件 changeFiles(event) { const {multiple, onceUploadCount, allUploadConut,onceUploadFiles} = this.props; const { response } = this.state; let _hasUploadCount = response.length || 0; const files = event.target.files || event.dataTransfer.files; let self = this; /* 多选时 单次上传数量验证 */ try { if (multiple && onceUploadCount < files.length) { // self.refs.formUploader.value = ""; if (onceUploadFiles) { onceUploadFiles(0); } throw { name: "TypeError", message: transFormat(this.translation.uploadOnceLimit, onceUploadCount) +'!' } } for (var i = files.length - 1; i >= 0; i--) { var temp = files[i]; var name = temp.name; if (name.indexOf(",")!=-1) { throw { name: "TypeError", message: this.translation.fileNameContainsCommaError } break; } }; if (multiple && (_hasUploadCount + files.length) > allUploadConut) { // self.refs.formUploader.value = ""; if (onceUploadFiles) { onceUploadFiles(0); } throw { name: "TypeError", message: transFormat(this.translation.allFilesCountLimit, allUploadConut) +'!' } } } catch(err) { // for (let i = 0; i < files.length; i++) { // currentFile.pop(); // } this.state.errorShow.messages = err.message; this.state.errorShow.type = true; this.setState(this.state); setTimeout(function() { self.state.errorShow.type = false; self.state.maxLength = false; self.setState(self.state); },self.state.disappearTime*1000); return; } if ((_hasUploadCount + files.length) == allUploadConut) { // this.setState({maxLength: true}) this.state.maxLength = true; } this.fileThen(files); this.reset(); } fileThen(files) { let {currentFileList} = this.state; const {onceUploadFiles} = this.props; let self = this; for (let i = 0;i < files.length; i++) { if (files[i].size == 0) { this.state.errorShow.messages = this.translation.fileSizeZeroError; this.state.errorShow.type = true; this.setState({ maxLength: false }); setTimeout(function() { self.state.errorShow.type = false; self.setState(self.state); },self.state.disappearTime*1000); if (onceUploadFiles) { onceUploadFiles(0); } // return; //注释掉该return, 在这return会造成后续正常文件无法上传的情况,且删除报错等问题 } if (files[i].size!=0) { currentFileList.push(files[i]); } } this.state.isSuccess = false; // this.setState(this.state); this.fileValidCheck(); if (currentFileList.length == 0) return; // this.refs.formUploader.value = ''; this.fileReader(); // xuqian // 文件多个上传 this.count = 0 this.allCount = currentFileList.length this.uploadDone = false; for (let i = 0; i < currentFileList.length; i++) { this.uploadFile(this.formData(currentFileList[i])); } //this.uploadFile(this.formData()); } // 图片 预览 HTML5 fileReader() { let self = this; const {currentFileList} = this.state; for (let i = 0; i < currentFileList.length; i++) { if (currentFileList[i].type.indexOf('image') != 0) continue; let readers = new FileReader(); readers.addEventListener('load', event => { if(self.state.currentFileList[i]) self.state.currentFileList[i].dataUrl = event.target.result; self.setState(this.state); }, false); readers.readAsDataURL(currentFileList[i]); } } translateImage(fileUrl, size) { // var tempFileSum = fileUrl.split(".") // var fileType = tempFileSum[tempFileSum.length-1] // var translateSrc = fileUrl // if (tempFileSum.length > 2) { // var index = fileUrl.indexOf(fileType) - 1 // translateSrc = fileUrl.substring(0, index) + '_' + size + '.' + fileType // } else { // translateSrc = tempFileSum[0] + '_' + size + '.' + fileType // } //修改为在地址后面加resize20作为压缩参数,之前为在末尾 xxx_20.png 这种格式 var tempFileSum = fileUrl.split("/") var url = tempFileSum[2] var index = fileUrl.indexOf(url) var translateSrc = '//' + url + '/resize' + size + fileUrl.substring(index+url.length, fileUrl.length) return BSGlobal.supportPicCompression ? translateSrc : fileUrl } // 文件格式正则 fileRegExp() { const {fileType} = this.props; let temp; // 文件格式验证 if (!fileType) { // const fileType = ['jpeg','JPEG','pdf','PDF','docx','DOCX','xlsx','XLSX','ppt','PPT','rar','RAR','txt','TXT','xls','XLS','doc','zip','ZIP','jpg','JPG','gif','GIF','png','PNG','pptx','PPTX','mmap','MMAP']; // temp = fileType.join('|'); temp = 'alltype' } else { temp = fileType.join('|'); } return new RegExp('(' + temp + ')$', 'i'); } fileMaxSize() { const {fileSize} = this.props; // 文件限制大小 let sizeLabel = { 'b': 1, 'B': 1, 'kb': 1024, 'Kb': 1024, 'KB': 1024, 'M': 1024 * 1024, 'mb': 1024 * 1024, 'Mb': 1024 * 1024, 'MB': 1024 * 1024 }; return fileSize && sizeLabel[fileSize.match(/\D+/i)[0]] * fileSize.match(/\d+/i)[0] || 2 * 1024 * 1024; } valiFileTypeIfPass = (name, suportArr) => { let ifsuport = false; let lastIndex = name.lastIndexOf('.'); let fileType = name.slice(lastIndex + 1,name.length); suportArr.map((cmp, index) => { if(cmp.toLowerCase() == fileType.toLowerCase()){ ifsuport = true; } }) return ifsuport; } // 文件 格式、大小验证 fileValidCheck() { let reg_image = this.fileRegExp(); // 返回文件正则 let maxSize = this.fileMaxSize(); // 返回文件大小 const {currentFileList} = this.state; const {onceUploadFiles, cutsomFileTypeErrorTip = this.translation.fileTypeError, fileSizeMessage, fileTypeMessage} = this.props; let self = this; for (let i = 0; i < currentFileList.length; i++) { try { // 这里进行大小写模糊匹对 let fileTypeVali = this.valiFileTypeIfPass(currentFileList[i].name, this.props.fileType); if (reg_image.test('alltype') ? true : fileTypeVali) { // 格式 if (currentFileList[i].size > maxSize) { // 大小 if (onceUploadFiles) onceUploadFiles(0);// throw { name: 'TypeError', message: fileSizeMessage ? fileSizeMessage : transFormat(this.translation.fileSizeBigError, this.props.fileSize) }; } } else { if (onceUploadFiles) onceUploadFiles(0); throw { name: 'TypeError', message: fileTypeMessage ? fileTypeMessage :cutsomFileTypeErrorTip }; } } catch (err) { //xuqian //提示信息的显示隐藏 this.state.errorShow.messages = err.message; this.state.errorShow.type = true; this.state.maxLength = false; this.state.currentFileList.splice(i, 1); i--; this.setState(this.state); setTimeout(function() { self.state.errorShow.type = false; self.state.maxLength = false; self.setState(self.state); },self.state.disappearTime*1000); } } } // ajax or form 上传 uploadFile(formData) { if (window.XMLHttpRequest && window.FormData) { this.uploadAjax(formData); } else { this.uploadForm(); } } // ajax formData formData(currentFile) { const {fileInputName} = this.props; //const {currentFileList} = this.state; let formData = new FormData(); // xuqian // 文件多个上传 // for (let i = 0; i < currentFileList.length; i++) { // formData.append(fileInputName, currentFileList[i]); // } formData.append(fileInputName, currentFile); // 额外数据 const {extendData} = this.props; if (extendData) { for (let i in extendData) { formData.append(i, extendData[i]); } } return formData; } // ajax上传文件 uploadAjax(formData) { const {onSuccess,multiple, onFailure, onProgress, url, withCredentials,onceUploadFiles} = this.props; //修改了currentFileList 用currentFile代替 const {currentFileList} = this.state; if (onceUploadFiles) { onceUploadFiles(currentFileList.length) } const self = this; let xhr = new XMLHttpRequest(); xhr.upload.addEventListener('progress', event => { if (!self.props.children && event.lengthComputable) { let value = (event.loaded / event.total) * 100; let progress = self.refs.progressCon.querySelectorAll('progress'); for (var dom of progress) { //回调里没有唯一标示,简易判断时哪个进度条 if (dom.id && dom.id == event.total.toString()) { dom.value = value; } else { if (!dom.id) { dom.id = event.total break; } } } onProgress && onProgress(event); } }); xhr.onreadystatechange = event => { self.state.isRequest = true; //请求中 // 当 state 为 0 即开始上传时,先暂时将错误信息隐藏 if (xhr.readyState == 0) { self.state.errorShow.type = false; self.setState(self.state); } if(!multiple){ self.setState({ response: [] ,currentFileList: [] }); } if (xhr.readyState == 4) { if (xhr.status == 200) { self.state.isRequest = false; //请求完毕 self.state.response.push(getBody(xhr)); //多文件一起传当第一个文件传完进度条都得会消失,判断Bug,现改成如下 let responseData = JSON.parse(xhr.response) let index = self.state.currentFileList.findIndex((item) => item.name == responseData.Name) self.state.currentFileList.splice(index,1); if (self.state.currentFileList.length==0) { self.state.isSuccess = true; } self.setState(self.state); self.count ++; //当所有文件上传完后,将标志位置为true if(self.count == self.allCount){ self.uploadDone = true } onSuccess && onSuccess(event, getBody(xhr), self.state.response, self.uploadDone); } else { self.state.isRequest = false; //请求完毕 self.state.currentFileList = []; self.state.isSuccess = true; self.state.maxLength = false; self.setState(self.state); onFailure && onFailure(event, getBody(xhr),self.state.response); } } } xhr.open('post', url, true); if (withCredentials && 'withCredentials' in xhr) { xhr.withCredentials = true; }; xhr.send(formData); // function finishxhr() { // xhr.abort(); // }; } // 原生 form提交 uploadForm(files) { const {fileInputName} = this.props; let iframe = document.createElement('iframe'); iframe.name = "uploadTarget"; iframe.style.display = 'none'; document.body.appendChild(iframe); let form = document.createElement('form'), input = document.createElement('input'); form.action = fileInputName || "uploadfile"; form.method = "post"; form.target = iframe.name; form.enctype = "multipart/form-data"; input.type = 'file'; input.name = 'files'; input.value = files; form.appendChild(input); form.submit(); } // 拖拽文件 dragFile(refValue) { const {onDragOver, onDragLeave, onDrop} = this.props; const self = this; const node = this.refs[refValue]; if (node) { node.addEventListener('dragover', event => { event.stopPropagation(); event.preventDefault(); onDragOver && onDragOver(event); }, false); node.addEventListener('dragleave', event => { event.stopPropagation(); event.preventDefault(); onDragLeave && onDragLeave(event); }, false); node.addEventListener('drop', event => { event.stopPropagation(); event.preventDefault(); onDrop && onDrop(event); const files = event.dataTransfer.files; self.fileThen(files); }, false); } } // 粘贴文件 pasteFile(refValue) { let self = this; const node = this.refs[refValue]; node.addEventListener('paste', event => { // safari 木有 if (!(event.clipboardData && event.clipboardData.items)) return; const items = (event.clipboardData || event.originalEvent.clipboardData).items; if (!items.length) return; var blobs = []; // let reg_image = this.fileRegExp(); // 返回文件正则 // let maxSize = this.fileMaxSize(); // 返回文件限制大小 for (let i = 0; i < items.length; i++) { if (items[i].kind === 'file') { let blobItem = items[i].getAsFile(); if (blobItem.size === 0) return; if (!self.fileValidCheck(blobItem)) return; blobs.push(blobItem); } } self.fileThen(blobs); }, false); } // 删除文件 deleteFile(event) { if (this.state.isRequest) return; //如果在上传过程中 不能删除 const node = event.target; let index = node.getAttribute('data-index'); let tempFile = this.state.response.splice(parseInt(index), 1); if (this.state.currentFileList.length) { tempFile = this.state.currentFileList.splice(parseInt(index), 1); tempFile = []; } if (this.props.onDelete) { this.props.onDelete(tempFile) // wangyongning add: this.props.onDelete()方法成功后会返回true // 先删除数据 数据删除成功后再删除DOM 更新state this.state.maxLength=false; //this.setState(this.state); } } // 渲染 编辑下 上传按钮 renderEditBtn() { const {disabled, multiple, labelTip, acceptData = '',hasLoadFile, allUploadConut, uploadText = this.translation.uploadText} = this.props; const {maxLength, isRequest} = this.state; let bool = multiple && (maxLength || hasLoadFile.length == allUploadConut) || isRequest ?"uploader_is-max":""; let tempRank = parseInt(Math.random() * 1000); this.tempRank = tempRank; return ( <div className={"uploader-edit clearfix " +bool} ref="uploadEdit"> <a className="focusable-upload-btn" tabIndex={disabled ? -1 : 0} onClick={this.disButton} ref="focusableUploadBtn"> <input type="file" id={"uploader-input-" + this.tempRank} data-key={this.state.uid} className='lala' ref="formUploader" disabled={(disabled || (bool=="uploader_is-max"))} onChange={this.changeFiles} multiple={multiple || false} style={bool ? {display: 'none'} : {display: 'block'}} tabIndex="-1" accept={acceptData} title='' /> { !multiple&& (maxLength || hasLoadFile.length == allUploadConut) ? this.translation.reUploadText : decode(uploadText) } </a> <p>{labelTip}</p> </div> ) } //让上传按钮在窗口出现期间不可点 disButton(event) { let self = this; setTimeout(() => { self.refs.formUploader.disabled = true; },1); setTimeout(() => { self.refs.formUploader.disabled = false; },1000); event.target.blur(); } /* 渲染 编辑态下 文件列表 */ renderCurrentFile() { const {currentFileList, isSuccess, isRequest} = this.state; let tempIcon; let processIcon; if (currentFileList.length == 0) return; return currentFileList && currentFileList.map((item, index) => { let name = item.name.split('.'); if (item.dataUrl) { tempIcon = <span className="file-icon file-picture"></span> // tempIcon = <img src={item.dataUrl} /> } else { let file_icon = fileiconName[name[name.length - 1]] != undefined ? name[name.length - 1] : 'none'; tempIcon = <span className={"file-icon " + 'file-' + file_icon}></span> } if (!isSuccess) { processIcon = <progress value="" max="100" ></progress> } else { let _fileType = name.pop(); processIcon = <div className="filenameBox"> <p className="file-info">{name.join('')}</p> <p className="file-typename">{"." + _fileType}</p> </div> } return ( <li key={index} data-index={index}> <div className='file-left'>{tempIcon}</div> <div className='file-center'>{processIcon}</div> <div className='file-right'> </div> <div className='upload-mask'> <div className='actions-view-file'> {isRequest ? '' : <div className='delete-view-file' data-index={index} onClick={this.deleteFile}></div>} </div> </div> </li> ) }) } getPreviewUrlNode(n) { if (n.nodeName=="LI") { return n; } else { return this.getPreviewUrlNode(n.parentNode) } } trimUrl(x) { return x && x.replace(/^\s+|\s+$/gm,''); } /*** li hover上去之后请求另外地址 拿到预览的地址 **/ getPreviewUrl(path, isdoc, clientUrl) { var url = this.props.previewUrl; let returnUrl = ""; if (!isdoc) { returnUrl = clientUrl; } else { if (url && path) { // const index = path.indexOf('//') + 2; // const keyspace = path.substring(index, path.indexOf('/', index)); // let paths = path.split("\/"); // let name = paths[paths.length - 1]; // returnUrl = url + window.BSGlobal.tenantInfo.Id + '/preview/' + keyspace + '/' + name; returnUrl = url + window.BSGlobal.tenantInfo.Id + '/preview?path=' + path ; } } return returnUrl; } /*** 点击预览 */ clickPreview(e) { const node = this.getPreviewUrlNode(e.target); let url = node.getAttribute('data-preview'); let downloadUrl = node.getAttribute('data-downloadurl'); let canPreview = node.getAttribute('data-canPreView'); var type = ['jpeg','jpg','gif','png','bmp']; if (this.props.onPreviewImg && this.checkImageType(url, type)) { this.props.onPreviewImg(url) } else if(this.props.uploadType == 'BC_PictureUploader' || canPreview == 'true') { // 这里进行判断 其他的文件格式支不支持新页面打开 如果新页面打开不了 则走下载的链接进行下载 window.open(url,"_blank"); } else { window.location.href = downloadUrl; } // let url = this.previewUrl[index]; } // 判断方法是在预览格式支持之内的方法 checkIsPreviewType = (url, supportData) => { if(!supportData) return false; // 这里拿链接地址进行判断 是不是包含在支持预览的地址里面的 let index = url.lastIndexOf('.'); let type = url.slice(index+1, url.length); if(supportData.indexOf(type) >= 0) { return 'true'; } else { return 'false'; } } checkImageType(url,type){ let isImage = false for(var i of type){ if(url.indexOf(i)>=0){ isImage = true break; } } return isImage; } /* 渲染 show状态下 */ renderShow() { const {hasLoadFile = [], status , readOnly = false, hiddenTip, sideTip} = this.props; let previewText = ''; let _hasLoadFile = hasLoadFile; const { response } = this.state; let tempList; if (status == 'edit') { tempList = response || []; } else { tempList = _hasLoadFile && _hasLoadFile.length != 0 ? _hasLoadFile : response || []; } if (tempList.length == 1) { let temp = tempList[0]; if (!temp.ClientUrl&&!temp.DownLoadUrl&&!temp.Name&&!temp.Path) { return; } } let imagesType = ['jpeg','JPEG','jpg','JPG','gif','GIF','png','PNG', 'bmp', 'BMP']; let docType = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'txt'] let temp = imagesType.join('|'); let doctemp = docType.join('|'); let reg = new RegExp('(' + temp + ')$', 'i'); let docreg = new RegExp('(' + doctemp + ')$', 'i'); let tempIcon; const deleteIcon = ((status == 'edit') && !readOnly) ? <span className="sys-icon-close"></span> : undefined; if (tempList.length == 0) return; let self = this; if (this.props.status == 'show' && this.props.hasLoadFile.length == 0) tempList = []; return tempList && tempList.map((item, index) => { let fileName = item.Name; let name = item.Name.split('.'); let isImg = false; let isdoc = false; if (reg.test(name[name.length - 1])) { previewText = ''; isImg = true; if (fileName.indexOf('txt')!=-1) { let file_icon = fileiconName[name[name.length - 1]] != undefined ? name[name.length - 1] : 'none'; tempIcon = <span className={"file-icon " + 'file-' + file_icon}></span> } else { tempIcon = <span className="file-icon file-picture"></span> // tempIcon = <img src={self.translateImage(item.ClientUrl,30)} />; //未做压缩处理,暂时已图标代替图片 } } else if (docreg.test(name[name.length - 1])) { previewText = ''; isImg = true; isdoc = true; let file_icon = fileiconName[name[name.length - 1]] != undefined ? name[name.length - 1] : 'none'; tempIcon = <span className={"file-icon " + 'file-' + file_icon}></span> } else { previewText = this.translation.previewDownloadText; let file_icon = fileiconName[name[name.length - 1]] != undefined ? name[name.length - 1] : 'none'; tempIcon = <span className={"file-icon " + 'file-' + file_icon}></span> } // let previewUrl = previewText == '下载' ? item.DownLoadUrl : item.ClientUrl; let previewUrl = item.ClientUrl; let imgDownloadUrl = item.DownLoadUrl; let ifPreview = this.checkIsPreviewType(fileName, this.props.supportPreviewData); let path = item.Path; name.pop(); let preurl = self.getPreviewUrl(path, isdoc ,previewUrl); if (status == 'edit') { let serachview = ""; if (isImg) { serachview = ( <div className='search-view-file' data-preurl={previewUrl} data-index={index} onClick={self.clickPreview} data-downloadurl={imgDownloadUrl} data-canPreView={ifPreview}> </div> ); } let deletview = ""; if (deleteIcon) { deletview = (<div className='sys-icon-cus-shanchu' data-index={index} onClick={self.deleteFile}></div>); } return ( <li key={index} data-index={index} data-isdoc={isdoc} data-clienturl={previewUrl} data-preview={preurl} data-downloadurl={imgDownloadUrl} data-canPreView={ifPreview}> <div> <div className='file-left'> {tempIcon} </div> <div className='file-center pic-type'> <div className="filenameBox"> <ToolTip title={item.Name} hidden={hiddenTip} side={sideTip} > <p className="file-info" data-preurl={previewUrl} data-index={index} onClick={self.clickPreview} data-downloadurl={imgDownloadUrl} data-canPreView={ifPreview}>{fileName}</p> </ToolTip> <span className="file-line"></span> <a tabIndex="-1" href={imgDownloadUrl} className="file-preview sys-icon-fujian-xiazai" target={'_self'}> </a> {deletview} </div> </div> </div> {/* <div className='upload-mask'> <div className='actions-view-file'> {serachview} </div> </div> */} </li> ) } if (!isImg) { let deletview = ""; if (deleteIcon) { deletview = (<div className='delete-view-file' data-index={index} onClick={self.deleteFile}></div>); } return ( <li className='show-status' key={index} data-isdoc={isdoc} data-isdoc={isdoc} data-clienturl={previewUrl} data-index={index} data-preview={preurl} data-downloadurl={imgDownloadUrl} data-canPreView={ifPreview}> <div className='file-left'> {tempIcon} </div> <div className='file-center'> <span> <div className='filenameBox'> <ToolTip title={item.Name} hidden={hiddenTip} side={sideTip} > <p className="file-info" data-preurl={previewUrl} data-index={index} onClick={self.clickPreview} data-downloadurl={imgDownloadUrl} data-canPreView={ifPreview}>{fileName}</p> </ToolTip> <a tabIndex="-1" href={imgDownloadUrl} className="file-preview sys-icon-fujian-xiazai" target={'_self'}> </a> </div> </span> </div> </li> ) } if (!isImg) { let deletview = ""; if (deleteIcon) { deletview = (<div className='delete-view-file' data-index={index} onClick={self.deleteFile}></div>); } return ( <li className='show-status' key={index} data-isdoc={isdoc} data-clienturl={previewUrl} data-index={index} data-preview={preurl} data-downloadurl={imgDownloadUrl} data-canPreView={ifPreview}> <div className='file-left'> {tempIcon} </div> <div className='file-center'> <ToolTip title={item.Name} hidden={hiddenTip} side={sideTip} > <span> <div className='filenameBox'> <p className="file-info">{fileName}</p> </div> </span> </ToolTip> </div> <div className='upload-mask'> <div className='actions-view-file'> <a tabIndex="-1" href={imgDownloadUrl} className="file-preview download-view-file" target={'_self'}> </a> {deletview} </div> </div> </li> ) } if (deleteIcon == undefined) { let serachview = ""; if (isImg) { serachview = ( <div className='search-view-file' data-index={index} data-preurl={previewUrl} onClick={self.clickPreview} data-downloadurl={imgDownloadUrl} data-canPreView={ifPreview}> </div> ); } return ( <li className='show-status' key={index} data-isdoc={isdoc} data-clienturl={previewUrl} data-index={index} data-preview={preurl} data-downloadurl={imgDownloadUrl} data-canPreView={ifPreview}> <div className='file-left'> {tempIcon} </div> <div className='file-center'> <span> <div className='filenameBox'> <ToolTip title={item.Name} hidden={hiddenTip} side={sideTip} > <p className="file-info" data-preurl={previewUrl} data-index={index} onClick={self.clickPreview} data-downloadurl={imgDownloadUrl} data-canPreView={ifPreview}>{fileName}</p> </ToolTip> <a tabIndex="-1" href={imgDownloadUrl} className="file-preview sys-icon-fujian-xiazai" target={'_self'}> </a> </div> <p className="file-downIcon">{previewText}</p> </span> </div> </li> ) } let serachview = ""; if (isImg) { serachview = ( <div className='search-view-file' data-index={index} onClick={self.clickPreview} data-downloadurl={imgDownloadUrl} data-canPreView={ifPreview}></div> ); } return ( <li className='show-status' key={index} data-isdoc={isdoc} data-clienturl={previewUrl} data-index={index} data-preview={preurl} data-downloadurl={imgDownloadUrl} data-canPreView={ifPreview}> <div className='file-left'> {tempIcon} </div> <div className='file-center'> <ToolTip title={item.Name} hidden={hiddenTip} side={sideTip} > <span> <p className="file-info">{fileName}</p> {previewText} </span> </ToolTip> </div> <div className='upload-mask'> <div className='actions-view-file'> {serachview} <a tabIndex="-1" href={imgDownloadUrl} className="file-preview download-view-file" target={'_self'}> </a> </div> </div> </li> ) }); } componentWillMount() { if (this.props.hasLoadFile && this.props.hasLoadFile.length != 0) { this.state.response = Object.assign([], this.props.hasLoadFile); this.setState(this.state); } } componentDidMount() { if (this.state.isDrag && this.props.status == 'edit') { this.dragFile('uploadEdit'); } if (this.props.status == 'edit') { let _id = 'uploader-input-' + this.tempRank; let btn = document.getElementById(_id); if (btn) { btn.addEventListener('click', function() { this.value = ''; }, false); } } document.addEventListener('keydown', this.handleKeyDown); } componentWillUnmount() { document.removeEventListener('keydown', this.handleKeyDown); } componentWillReceiveProps(nextProps) { if (nextProps.status != this.props.status && nextProps.hasLoadFile && nextProps.hasLoadFile.length != 0 || nextProps.hasLoadFile && nextProps.hasLoadFile.length != 0 && nextProps.hasLoadFile.length > this.state.response.length || JSON.stringify(nextProps.hasLoadFile) != JSON.stringify(this.props.hasLoadFile)) { this.state.response = Object.assign([], nextProps.hasLoadFile); } if (nextProps.isDrag != this.props.isDrag) this.state.isDrag = nextProps.isDrag console.log(this.state.response) this.setState(this.state); } /*xuqian 弹窗组件的显示隐藏状态设置 */ renderErrorMessage() { return ( <p className="error-message">{this.state.errorShow.messages}</p> ) } renderMessage() { if (this.state.currentFileList.length != 0 || this.props.hasLoadFile.length != 0) return; if (this.props.uploadType == 'BC_PictureUploader') { return( <p className="error-message">{this.props.errorMessage.message}</p> ) } else { return( <p className="error-message">{this.props.errorMessage.message}</p> ) } } renderHelpText = () => { const { hiddenTip, sideTip, briefDescription} = this.props if(!briefDescription) return; return ( <ToolTip title={briefDescription} hidden={hiddenTip} side={sideTip} > <div className="form-uploader-help"> {briefDescription} </div> </ToolTip> ) } render() { const {hidden, status, readOnly = false, lablePos, hasLoadFile} = this.props; let rightStyle = {}; if (lablePos && status !== 'show') { rightStyle = {'float': 'left', 'width': 'calc(100% - 118px)'} } if (!hidden) { let fileAdd = (status == 'edit' && !readOnly) ? this.renderEditBtn() : undefined; let filesUlClass = status == 'edit' ? 'form-uploader-edit' : 'form-uploader-show'; return ( <div className={"form-item formUploader "+ (status=='show'?' form-item_is-static':'') + (!lablePos ? ' form-uploader__title-up-and-down ' : '')}> <CommonLabel {...this.props} /> <div id="field-right" className="field-right" style={rightStyle}> {status == 'show' && (hasLoadFile.length == 0 || hasLoadFile[0].Name == '') ? <div className="empty-style">{this.translation.emptyText}</div> : ''} {fileAdd} {this.renderHelpText()} <div className="uploader-files"> <ul className={filesUlClass + ' clearfix'} ref="progressCon"> {this.renderShow()} {this.renderCurrentFile()} </ul> </div> {status == 'edit' && !this.state.errorShow.type && this.props.errorMessage.error ? this.renderMessage() : ''} {status == 'edit' && this.state.errorShow.type ? this.renderErrorMessage() : ''} </div> </div> ) } else { return <div></div> } } handleKeyDown(e) { const focusableUploadBtn = this.refs.focusableUploadBtn, formUploader = this.refs.formUploader; switch (e.keyCode) { case 13: // 回车 if (e.target == focusableUploadBtn) { formUploader.click(); } break; case 9: // tab break; case 38: // 上 break; case 40: // 下 break; case 37: // 左 break; case 39: // 右 break; case 27: // esc break; default: // console.info(e); break; } } } module.exports = FormUploader;