define(['jquery', 'bootstrap', 'webupload'], function ($, undefined, WebUploader) { var Upload = { config: { image: { title: 'Images', extensions: 'gif,jpg,jpeg,bmp,png', mimeTypes: 'image/*' }, file: { title: 'Files', extensions: '*', mimeTypes: '*' }, upList: [], }, index: function(){ var query = sent.parseUrl(window.location.href); $wrap = $('#uploader'), // 图片容器 $queue = $('') .appendTo( $wrap.find('.queueList') ), // 状态栏,包括进度和控制按钮 $statusBar = $wrap.find('.statusBar'), // 文件总体选择信息。 $info = $statusBar.find('.info'), // 上传按钮 $upload = $wrap.find('.uploadBtn'), // 没选择文件之前的内容。 $placeHolder = $wrap.find('.placeholder'), // 总体进度条 $progress = $statusBar.find('.progress').hide(), // 添加的文件数量 fileCount = 0, // 添加的文件总大小 fileSize = 0, // 优化retina, 在retina下这个值是2 ratio = window.devicePixelRatio || 1, // 缩略图大小 thumbnailWidth = 110 * ratio, thumbnailHeight = 110 * ratio, // 可能有pedding, ready, uploading, confirm, done. state = 'pedding', // 所有文件的进度信息,key为file id percentages = {}, supportTransition = (function(){ var s = document.createElement('p').style, r = 'transition' in s || 'WebkitTransition' in s || 'MozTransition' in s || 'msTransition' in s || 'OTransition' in s; s = null; return r; })(), // WebUploader实例 uploader; if ( !WebUploader.Uploader.support() ) { alert( 'Web Uploader 不支持您的浏览器!如果你使用的是IE浏览器,请尝试升级 flash 播放器'); throw new Error( 'WebUploader does not support the browser you are using.' ); } // 实例化 uploader = WebUploader.create({ pick: { id: '#filePicker', label: '点击选择'+(query.type == 'image' ? '图片' : '文件') }, dnd: '#uploader .queueList', paste: document.body, accept: Upload.config[query.type], // swf文件路径 // swf: baseRoot + 'plugins/webuploader/Uploader.swf', disableGlobalDnd: true, chunked: true, // server: 'http://webuploader.duapp.com/server/fileupload.php', server: '/'+Config.module+'/upload/upload', fileNumLimit: 300, fileSizeLimit: 5 * 1024 * 1024, // 200 M fileSingleSizeLimit: 1 * 1024 * 1024 // 50 M }); // 添加“添加文件”的按钮, uploader.addButton({ id: '#filePicker2', label: '继续添加' }); uploader.onUploadProgress = function( file, percentage ) { var $li = $('#'+file.id), $percent = $li.find('.progress span'); $percent.css( 'width', percentage * 100 + '%' ); percentages[ file.id ][ 1 ] = percentage; Upload.updateTotalProgress(); }; uploader.onFileQueued = function( file ) { fileCount++; fileSize += file.size; if ( fileCount === 1 ) { $placeHolder.addClass( 'element-invisible' ); $statusBar.show(); } Upload.addFile( file ); Upload.setState( 'ready' ); Upload.updateTotalProgress(); }; uploader.onFileDequeued = function( file ) { fileCount--; fileSize -= file.size; if ( !fileCount ) { Upload.setState( 'pedding' ); } Upload.removeFile( file ); Upload.updateTotalProgress(); }; uploader.on( 'all', function( type, file, response ) { var stats; switch( type ) { case 'uploadFinished': Upload.setState( 'confirm' ); Upload.uploadFinished(); break; case 'uploadSuccess': Upload.uploadSuccess(response, file); break; case 'startUpload': Upload.setState( 'uploading' ); break; case 'stopUpload': Upload.setState( 'paused' ); break; } }); uploader.onError = function( code ) { sent.msg( 'Eroor: ' + code, 'error' ); }; $upload.on('click', function() { if ( $(this).hasClass( 'disabled' ) ) { return false; } if ( state === 'ready' ) { uploader.upload(); } else if ( state === 'paused' ) { uploader.upload(); } else if ( state === 'uploading' ) { uploader.stop(); } }); $info.on( 'click', '.retry', function() { uploader.retry(); } ); $info.on( 'click', '.ignore', function() { alert( 'todo' ); } ); $upload.addClass( 'state-' + state ); Upload.updateTotalProgress(); }, // 当有文件添加进来时执行,负责view的创建 addFile: function ( file ) { var $li = $( '
  • ' + '

    ' + file.name + '

    ' + '

    '+ '

    ' + '
  • ' ), $btns = $('
    ' + '删除' + '向右旋转' + '向左旋转
    ').appendTo( $li ), $prgress = $li.find('p.progress span'), $wrap = $li.find( 'p.imgWrap' ), $info = $('

    '), showError = function( code ) { switch( code ) { case 'exceed_size': text = '文件大小超出'; break; case 'interrupt': text = '上传暂停'; break; default: text = '上传失败,请重试'; break; } $info.text( text ).appendTo( $li ); }; if ( file.getStatus() === 'invalid' ) { showError( file.statusText ); } else { // @todo lazyload $wrap.text( '预览中' ); uploader.makeThumb( file, function( error, src ) { if ( error ) { $wrap.text( '不能预览' ); return; } var img = $(''); $wrap.empty().append( img ); }, thumbnailWidth, thumbnailHeight ); percentages[ file.id ] = [ file.size, 0 ]; file.rotation = 0; } file.on('statuschange', function( cur, prev ) { if ( prev === 'progress' ) { $prgress.hide().width(0); } else if ( prev === 'queued' ) { $li.off( 'mouseenter mouseleave' ); $btns.remove(); } // 成功 if ( cur === 'error' || cur === 'invalid' ) { console.log( file.statusText ); showError( file.statusText ); percentages[ file.id ][ 1 ] = 1; } else if ( cur === 'interrupt' ) { showError( 'interrupt' ); } else if ( cur === 'queued' ) { percentages[ file.id ][ 1 ] = 0; } else if ( cur === 'progress' ) { $info.remove(); $prgress.css('display', 'block'); } else if ( cur === 'complete' ) { $li.append( '' ); } $li.removeClass( 'state-' + prev ).addClass( 'state-' + cur ); }); $li.on( 'mouseenter', function() { $btns.stop().animate({height: 30}); }); $li.on( 'mouseleave', function() { $btns.stop().animate({height: 0}); }); $btns.on( 'click', 'span', function() { var index = $(this).index(), deg; switch ( index ) { case 0: uploader.removeFile( file ); return; case 1: file.rotation += 90; break; case 2: file.rotation -= 90; break; } if ( supportTransition ) { deg = 'rotate(' + file.rotation + 'deg)'; $wrap.css({ '-webkit-transform': deg, '-mos-transform': deg, '-o-transform': deg, 'transform': deg }); } else { $wrap.css( 'filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+ (~~((file.rotation/90)%4 + 4)%4) +')'); } }); $li.appendTo( $queue ); }, // 负责view的销毁 removeFile: function ( file ) { var $li = $('#'+file.id); delete percentages[ file.id ]; Upload.updateTotalProgress(); $li.off().find('.file-panel').off().end().remove(); }, updateTotalProgress: function() { var loaded = 0, total = 0, spans = $progress.children(), percent; $.each( percentages, function( k, v ) { total += v[ 0 ]; loaded += v[ 0 ] * v[ 1 ]; } ); percent = total ? loaded / total : 0; spans.eq( 0 ).text( Math.round( percent * 100 ) + '%' ); spans.eq( 1 ).css( 'width', Math.round( percent * 100 ) + '%' ); Upload.updateStatus(); }, updateStatus: function () { var text = '', stats; if ( state === 'ready' ) { text = '选中' + fileCount + '张图片,共' + WebUploader.formatSize( fileSize ) + '。'; } else if ( state === 'confirm' ) { stats = uploader.getStats(); if ( stats.uploadFailNum ) { text = '已成功上传' + stats.successNum+ '张照片至XX相册,'+ stats.uploadFailNum + '张照片上传失败,重新上传失败图片或忽略' } } else { stats = uploader.getStats(); text = '共' + fileCount + '张(' + WebUploader.formatSize( fileSize ) + '),已上传' + stats.successNum + '张'; if ( stats.uploadFailNum ) { text += ',失败' + stats.uploadFailNum + '张'; } } $info.html( text ); }, setState: function ( val ) { var file, stats; if ( val === state ) { return; } $upload.removeClass( 'state-' + state ); $upload.addClass( 'state-' + val ); state = val; switch ( state ) { case 'pedding': $placeHolder.removeClass( 'element-invisible' ); $queue.parent().removeClass('filled'); $queue.hide(); $statusBar.addClass( 'element-invisible' ); uploader.refresh(); break; case 'ready': $placeHolder.addClass( 'element-invisible' ); $( '#filePicker2' ).removeClass( 'element-invisible'); $queue.parent().addClass('filled'); $queue.show(); $statusBar.removeClass('element-invisible'); uploader.refresh(); break; case 'uploading': $( '#filePicker2' ).addClass( 'element-invisible' ); $progress.show(); $upload.text( '暂停上传' ); break; case 'paused': $progress.show(); $upload.text( '继续上传' ); break; case 'confirm': $progress.hide(); $upload.text( '开始上传' ).addClass( 'disabled' ); stats = uploader.getStats(); if ( stats.successNum && !stats.uploadFailNum ) { Upload.setState( 'finish' ); return; } break; case 'finish': stats = uploader.getStats(); if ( stats.successNum ) { sent.msg( '上传成功', 'success' ); } else { // 没有成功的图片,重设 state = 'done'; location.reload(); } break; } Upload.updateStatus(); }, uploadSuccess: function(res, file){ if (res.code == 1) { Upload.config.upList.push(res.info); } }, uploadFinished: function(){ var query = sent.parseUrl(window.location.href); if(Upload.config.upList.length > 0){ if(query.limit == 1 && Upload.config.upList.length > 1){ sent.msg('请单选图片或文件', 'error'); return false; } parent.Form.api.setFile(Upload.config.upList, query); }else{ sent.msg('未选择数据!', 'error') } }, server: function(){ var query = sent.parseUrl(window.location.href); if($('.img-list .item .thumb').length > 0){ $('.img-list .item .thumb').on('click', function(){ if($(this).hasClass('selected')){ Upload.config.upList = Upload.config.upList.filter(item => !sent.utils.isObjEqual(item, $(this).data())); $(this).removeClass('selected'); }else{ Upload.config.upList.push($(this).data()); $(this).addClass('selected'); } }) } $('button.btn-select').click(function(){ if(Upload.config.upList.length > 0){ if(query.limit == 1 && Upload.config.upList.length > 1){ sent.msg('请单选图片或文件', 'error'); return false; } parent.Form.api.setFile(Upload.config.upList, query); }else{ sent.msg('未选择数据!', 'error') } }) } } return Upload; })