joywok-material-components
Version:
<h1 align="center"> Joywok Material Components </h1>
251 lines (249 loc) • 11.8 kB
JavaScript
import React from 'react';
import AloneTip from '../tips/aloneTip';
class Jwfuploader extends React.Component{
constructor(props) {
super(props);
let tmp = {
accept: this.props.accept || '*',
multiple: this.props.multiple!==true?false:true,
inputId: this.props.id || 'jwfu-'+ this.guid(),
action: this.props.action || '/api/file/sectionupload',
splitSize: 1024 * 1024 * 10,
maxSize: this.props.maxSize || 0
}
if( this.props.responseAll!==undefined ){
tmp.splitSize = 1024 * 1024 * 1024 * 10;
}
if( this.props.appType ){
if( tmp.action.indexOf('app_type')===-1 ){
if(tmp.action.indexOf('?')===-1){
tmp.action = tmp.action + '?' + 'app_type=' + this.props.appType;
}else{
tmp.action = tmp.action + '&' + 'app_type=' + this.props.appType;
}
}
}
if( this.props.appId ){
if( tmp.action.indexOf('app_id')===-1 ){
if(tmp.action.indexOf('?')===-1){
tmp.action = tmp.action + '?' + 'app_id=' + this.props.appId;
}else{
tmp.action = tmp.action + '&' + 'app_id=' + this.props.appId;
}
}
}
this.state = tmp;
}
guid(){
function S4(){
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
return (S4()+S4()+S4()+S4()+S4()+S4()+S4()+S4());
}
simpleFilter(data) {
if(typeof data==='string'){
data = data.replace(/\</ig, '<');
data = data.replace(/\>/ig, '>');
data = data.replace(/\"/ig, '"');
data = data.replace(/\'/ig, ''');
}
return data;
}
uploadingFile(file){
if(file.removeFlag===1) return;
if(file.stopFlag===1){
return;
}
let that = this;
let splitSize = this.state.splitSize;
let splitCount = Math.ceil(file.size / splitSize);
let startSize = (file.upindex - 1) * splitSize;
let endSize = Math.min(file.size, file.upindex * splitSize);
let postData = file.slice(startSize, endSize);
let fname = this.simpleFilter( file.name + '');
let action = this.state.action;
if( splitCount>1 ){
action = '/api/file/sectionupload';
}
if( file.status === 'cancel' ){
this.props.onChange({file: file});
return;
}
new jwFSha1({
file: postData,
cb: splitSha1=>{
if( file.status === 'cancel' ){
that.props.onChange({file: file});
return;
}
let formdata = new FormData();
formdata.append("jwfile", postData, encodeURIComponent(encodeURIComponent(fname) )); // 一次encodeURIComponent会被星巴克waf拦截,所以需要两次才行
if( this.props.responseAll===undefined ){
formdata.append('total_index', splitCount);
formdata.append("cur_index", file.upindex);
formdata.append('app_id', '');
formdata.append('type', 'jw_app_subscribe');
formdata.append('sha1', splitSha1);
formdata.append("tsha1", file.sha1);
}
// formdata.append("access_token", jw_sid);
file.ajax = $.ajax({
url: action,
type: 'POST',
data: formdata,
processData: false,
contentType: false,
headers:{
"Access-Token": Base64.encode(jw_sid)
},
beforeSend: ()=>{},
xhr: ()=>{
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', function (event) {
let ps = Math.ceil( ((file.upindex-1)*splitSize + event.loaded)/file.size*100 );
if(ps>100) ps = 100;
file.status = 'uploading';
file.loaded = (file.upindex-1)*splitSize + event.loaded;
if( file.loaded>file.size ){
file.loaded = file.size;
}
file.percent = Math.max(ps, file.percent);
that.props.onChange({file: file});
})
return xhr;
},
success: resp=>{
if( resp.error_code ){
file.status = 'error';
file.errmemo = resp.error;
that.props.onChange({file: file});
}else if(resp.errcode && resp.error_list===undefined){
file.status = 'done';
file.response = resp;
that.props.onChange({file: file});
}else{
if( resp.id && resp.ext_name ){
file.status = 'done';
file.percent = 100;
file.response = resp;
that.props.onChange({file: file});
}else if( resp.JMStatus && resp.JMStatus.code > 0 ){
AloneTip({ type: 'error', duration: 3000, hasclose: false, autoHideDuration: 3000, message: resp.JMStatus.errmemo });
}else{
if(file.upindex===splitCount){
file.status = 'done';
file.percent = 100;
if( this.props.responseAll!==undefined ){
file.response = resp;
}else{
file.response = resp.JMAttachment;
}
that.props.onChange({file: file});
}else{
++file.upindex;
that.uploadingFile(file);
}
}
}
},
error: err=>{
file.status = 'cancel';
that.props.onChange({file: file});
// console.log(err,'err');
if( err.statusText !== 'abort' ){
AloneTip({ type: 'error', duration: 3000, hasclose: false, autoHideDuration: 3000, message: i18n('label.fileupload.uploaderror') });
}
}
})
}
});
}
startUploadFile(file){
if(file.removeFlag!=undefined) return;
let self = this;
file.status = 'uploading';
file.percent = 0;
this.props.onChange({file: file});
new jwFSha1({
file: file,
cb: sha1=>{
file.sha1 = sha1;
file.upindex = 1;
self.uploadingFile(file);
}
});
}
onChange = e=>{
let that = this;
for(let i=0; i<e.target.files.length; i++){
let file = e.target.files[i];
file.uid = this.guid();
file.removeHandle = ()=>{
file.removeFlag = 1;
file.originFileObj.value = '';
}
file.stopHandle = ()=>{
file.stopFlag = 1;
if( file.ajax ) file.ajax.abort();
}
file.continueHandle = ()=>{
delete file.stopFlag;
that.uploadingFile(file);
}
// console.log(file.size, this.state.maxSize, 'xxxxx');
if( file.size > this.state.maxSize && this.state.maxSize !== 0 ){
AloneTip({ type: 'error', duration: 3000, hasclose: false, autoHideDuration: 3000, message: i18n('label.file-size-limit') });
continue;
}
// break;
if( _.isArray( this.state.accept ) && this.state.accept.length>0 ){
let ext = '.' + file.name.replace(/.*\./g, '');
if( this.state.accept.indexOf( ext.toLowerCase() )===-1 ){
file.status = 'cancel';
that.props.onChange({file: file});
let errMsg = i18n('label.file-formaterror');
if( this.state.accept.join().indexOf('.mp3')!==-1 ){
errMsg = i18n('label.filetype-error-mp3');
}
AloneTip({ type: 'error', duration: 3000, hasclose: false, autoHideDuration: 3000, message: errMsg });
continue;
}
}
if(typeof this.props.beforeUpload==='function'){
this.props.beforeUpload( file ).then(()=>{
file.status = 'start';
file.percent = 0;
file.originFileObj = document.getElementById(this.state.inputId);
file.dataURL = 'data:image/png;base64,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';
that.props.onChange({file: file});
if( ['image/jpeg', 'image/jpg', 'image/png', 'image/bmp', 'image/gif', 'image/webp'].indexOf(file.type)>-1 ){
let reader = new FileReader();
reader.addEventListener('load', (e)=>{
file.dataURL = e.target.result;
that.startUploadFile( file );
});
reader.readAsDataURL(file);
}else{
that.startUploadFile( file );
}
}).catch(error=>{
file.status = 'error';
if( error.file ){
file.status = 'done';
file.percent = 100;
file.response = error.file;
that.props.onChange({file: file});
}
console.log(error);
})
}
}
}
componentDidMount(){}
render(){
return (
<input className={this.props.className} id={this.state.inputId} onClick={e=>e.target.value=''} onChange={this.onChange} type="file" accept={this.state.accept} multiple={this.state.multiple} ></input>
)
}
}
export default Jwfuploader;