joywok-material-components
Version:
<h1 align="center"> Joywok Material Components </h1>
303 lines (288 loc) • 11.1 kB
JavaScript
import React from 'react';
import ReactDOM from 'react-dom';
import AloneTip from '../tips/aloneTip';
import Progress from 'antd/lib/progress/progress';
require('./style/index.css');
class Upload extends React.Component{
constructor(props) {
super(props);
this.state = {
imgFile: props.schema.imgFile ? props.schema.imgFile : [],
fileLength: props.schema.max ? props.schema.max : 4,
access_token: props.access_token,
maxSize: props.schema.maxSize ? (props.schema.maxSize*1024*1024) : null, // 单位:M 兆
};
}
componentWillReceiveProps(newP){
if(this.props.schema.imgFile.length!=newP.schema.imgFile.length){
this.setState({
imgFile: newP.schema.imgFile ? newP.schema.imgFile : [],
})
}
}
getSha1(file, index) {
let self = this;
return new Promise((resl, rej) => {
new jw.FSha1({
file: file,
cb: function (tsha1) {
self.fileExist(file, tsha1, index)
}
})
})
}
fileExist(file, tsha1, index){
let self = this;
let url = "/api/file/fileifexist?tsha1="+tsha1+"&jwfile="+file.name+"&size="+file.size+"&app_type="+(this.props.type||'jw_app_joychat')+"&access_token="+self.state.access_token
let uplpadFileAjax = $.ajax({
url: url,
type: 'get',
dataType: 'json',
processData: false,
contentType: false,
success: function (resp) {
if(resp.JMStatus && resp.JMStatus.code > 0){
AloneTip({ type: 'error', duration: 3000, hasclose: false, autoHideDuration: 3000, message: resp.JMStatus.errmemo })
}else{
if(resp.JMFlag === false){
self.uploadFileSlipt(file, 1, tsha1, index)
}else{
let imgFile = self.state.imgFile;
if(typeof(index) == "number"){
imgFile[index] = resp.JMAttachment
}else{
imgFile.push(resp.JMAttachment)
}
self.setState({
loading: false,
progress: false,
imgFile: imgFile
})
self.props.onChange && self.props.onChange(imgFile)
AloneTip({ type: 'success', duration: 3000, hasclose: false, autoHideDuration: 3000, message: self.props.labels && self.props.labels.success ? self.props.labels.success : "上传成功" })
}
}
},
error: function () {
// AloneTip({ type: 'error', duration: 3000, hasclose: false, autoHideDuration: 3000, message: resp.errmemo })
}
})
}
// 生成参数
createClientFormData(jwfile,app_id, app_type, total_index, cur_index, tsha1, filename){
let self = this;
return
}
uploadFileSlipt(file, num, tsha1, index){
let self = this;
let blockSize = 20 * 1024 * 1024;
let blockNum = Math.ceil(file.size / blockSize);
let nextSize = Math.min(num * blockSize, file.size);
let fileData = file.slice((num - 1) * blockSize, nextSize);
//生成formdata
new jw.FSha1({
file: fileData,
cb: function (sha1) {
let form = new FormData();
form.append("jwfile", fileData, file.name); //slice方法用于切出文件的一部分
form.append("total_index", blockNum); //总片数
form.append("cur_index", num);
form.append("app_id", "");
form.append("type", self.props.type||"jw_app_joychat");
form.append("sha1", sha1);
form.append("tsha1", tsha1);
form.append("access_token", jw_sid)
let uplpadFileAjax = $.ajax({
url: '/api/file/sectionupload?app_type='+(self.props.type||"jw_app_joychat")+'&app_id=&type=loginthumb',
type: 'post',
dataType: 'json',
data: form,
processData: false,
contentType: false,
beforeSend: function() {
// self.setState({
// ps: 0,
// progress: true,
// formName: file.name,
// file-size: parseInt((file.size/1024/1024)*100)/100
// })
},
xhr: function(resp) {
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', function (e) {
// let uploadsi = parseInt(((e.loaded + (num-1)*20*1024*1024)/1024/1024)*100)/100;
let uploadsi = parseInt(((e.loaded + (num-1)*blockSize)/1024/1024)*100)/100;
let ps = Math.ceil( ((num-1)*blockSize + e.loaded)/file.size*100 );
self.changeProgress(ps,index);
})
return xhr;
},
success: function (resp) {
if(resp.JMStatus.code > 0){
AloneTip({ type: 'error', duration: 3000, hasclose: false, autoHideDuration: 3000, message: resp.JMStatus.errmemo })
self.setState({
loading: false
})
}else{
// if (file.size <= nextSize) {
if (num === blockNum) {
let imgFile = self.state.imgFile;
if(typeof(index) == "number"){
imgFile[index] = resp.JMAttachment
}else{
imgFile.push(resp.JMAttachment)
}
self.setState({
loading: false,
imgFile: imgFile
})
self.props.onChange && self.props.onChange(imgFile)
AloneTip({ type: 'success', duration: 3000, hasclose: false, autoHideDuration: 3000, message: self.props.labels && self.props.labels.success ? self.props.labels.success : "上传成功" })
return;
}else{
self.uploadFileSlipt(file, ++num, tsha1);//递归调用
}
}
},
error: function (resp) {
// AloneTip({ type: 'error', duration: 3000, hasclose: false, autoHideDuration: 3000, message: resp.JMStatus.errmemo })
}
})
self.setState({
uplpadFileAjax: uplpadFileAjax
})
}
})
}
changeProgress(s,percent,index){
let self = this;
setTimeout(()=>{
_.each(self.state.imgFile,(item,i)=>{
// console.log('index::',index,i,percent)
if(index===i) item.ps = percent
})
self.setState({
imgFile: self.state.imgFile
})
},s);
}
fileChange(e, index){
let self = this;
let file = e.currentTarget.files[0];
// console.log('fileChange:',index,file,e.currentTarget)
if(this.state.maxSize&&file.size>this.state.maxSize){
AloneTip({ type: 'error', duration: 3000, hasclose: false, autoHideDuration: 3000, message: i18n('label.file-size-limit')});
e.target.value = '';
return;
}
let filedata = {
name: file.name,
file_size: file.size,
file_type: file.type.indexOf('image')!=-1 ? 'jw_n_image' : file.type,
progress: true,
ps: 0
}
let id;
if(index!=undefined){
_.each(self.state.imgFile,(item,i)=>{
if(index===i){
item = _.extend({id: item.id},filedata);
}
})
}else{
index = self.state.imgFile.length
id = 'tmp_'+index;
self.state.imgFile.push(_.extend({id: id},filedata));
}
self.setState({
imgFile: self.state.imgFile
})
// 伪进度条效果
self.changeProgress(2000,30,index);
self.changeProgress(4000,60,index);
self.changeProgress(6000,80,index);
self.getSha1(file, index)
}
fileDel(index){
let self = this;
let arr = [];
_.map(self.state.imgFile, function(item, i){
if(i != index){
arr.push(item)
}
})
self.setState({
imgFile: arr
})
self.props.onChange && self.props.onChange(arr)
}
// fileReplace(index,e){
fileReplace(e,index){
let self = this;
self.fileChange(e, index)
}
getFileSize(size){
if(size < 1024){
return size + "B"
}else if(size < 1024*1024){
return parseInt(size*100/1024)/100 + "KB"
}else{
return parseInt(size*100/1024/1024)/100 + "MB"
}
}
render(){
let self = this;
let accept = self.props.schema.accept ? self.props.schema.accept : "image/*";
return (<div className="jw-upload ">
{
self.state.imgFile.length > 0 ? <div className="form-ele-item">
<ul className="file-list-container">
{
_.map(self.state.imgFile, function(item, index){
return <li className="file-item">
{/* <img src={item.preview && item.preview.url ? item.thumbnail.url+"&access_token="+self.state.access_token : item.icon}/> */}
{/* <img src={item.thumbnail&&item.thumbnail.open_url}/> */}
{
item.progress ?
<div className="file-uploading">
<Progress percent={item.ps} showInfo={false} />
</div> :
<img src={item.file_type=='jw_n_image'?item.thumbnail&&item.thumbnail.open_url:item.icon}/>
}
<div className="file-info">
<span className="name">{item.name}{item.ext_name?('.'+item.ext_name):''}</span>
<span className="size">{self.getFileSize(item.file_size)}</span>
{
item.progress != undefined ?
'' :
<div className="operation">
<span className="del" onClick={self.fileDel.bind(self,index)}>{self.props.labels && self.props.labels.del ? self.props.labels.del : i18n('btn.remove')}</span>·
<div>
<input accept={accept} id={"contained-button-file1"+index} className="contained-button-file" type="file"
// onChange={self.fileReplace.bind(self,index)}/>
onChange={(e)=>self.fileReplace(e,index)}/>
<label htmlFor={"contained-button-file1"+index}>
<span className="replace">{self.props.labels && self.props.labels.replace ? self.props.labels.replace : (i18n('btn.liveshow.replace'))}</span></label>
</div>
</div>
}
</div>
</li>
})
}
</ul>
{
self.state.imgFile.length < self.state.fileLength ? <div><input accept={accept} id="contained-button-file" className="contained-button-file" type="file" onChange={self.fileChange.bind(self)}/><label className="file-upload-btn" htmlFor="contained-button-file"><span>+{self.props.labels && self.props.labels.upload ? self.props.labels.upload : i18n('btn.upload')}</span></label></div> : ""
}
</div> : <div className="form-ele-item">
<input accept={accept} id="contained-button-file" className="contained-button-file" type="file" onChange={self.fileChange.bind(self)}/>
<label htmlFor="contained-button-file">
<div className="upload-file-container"></div>
</label>
</div>
}
</div>
)
}
}
export default Upload;