define(['bootstrap', 'webuploader', 'util', 'underscore', 'filestyle'], function($, WebUploader, util, _){ fileUploader = { 'supports' : ['upload', 'browser', 'video'], 'defaultoptions' : { global : false, acid : 0, mode : '', callback : null, // 回调方法 type : 'image', // 上传组件类型 direct : false, // 效果, 是否选择即返回, 单图可用. multi : false, // 返回结果是 object 还是 Array dest_dir : '', // 自定义上传目录 tabs : { // 选项卡, remote 'upload': '', 'browser' : '', 'video' : '' } }, 'options' : {}, // 当前配置项 'flag' : 0, 'mode' : '', 'show' : function(callback, options){ if(options.error) { util.message('公众号没有权限'); return false; } this.mode = ''; this.type = options.type; if(options.mode) { this.mode = options.mode; } if(!options.acid) { this.select_acid(callback, options); } else { this.acid = options.acid; this.init(callback, options); } }, 'reset' : function(){ if(this.modalobj != null){ this.images = []; this.flag = 0; for(i in this.options.tabs){ eval("$this.reset_"+i+"();"); } } }, 'hide' : function(){ if(this.modalobj != null){ this.reset(); this.modalobj.modal('hide'); } }, 'uploader' : {}, 'modalobj' : null, 'images' : [], /*上次上次控件的状态,tabname,active*/ 'historyOptions' : '', //选择子公众号 'select_acid' : function(callback, options) { var $this = this; if ($('#modal-acid').length == 0) { $(document.body).append(''); this.acidobj = $('#modal-acid'); this.acidobj.append( '' ); $.getJSON('./index.php?c=utility&a=wechat_file&do=select_acid', function(data) { if(data == 'error') { util.message('没有可用的公众号', '', 'error'); return false; } else { if(data.total > 1) { var html = ''; $.each(data.item, function(k, v){ html += '
'; }); $('#modal-acid').find('#acid').html(html); } } }); } this.acidobj.modal('show'); this.acidobj.find('#acid-checked').unbind('click').click(function(){ var acid = $('#modal-acid').find(':radio:checked').val(); if(!acid) { util.message('请选择公众号', '', 'error'); return false; } $this.acid = acid; $this.acidobj.modal('hide'); $this.init(callback, options); }); }, 'init' : function(callback, options) { $this = this; this.options = $.extend({}, this.defaultoptions, options); this.options.callback = callback; if(options.tabs){ this.options.tabs = {}; for(i in options.tabs){ if($.inArray(i, $this.supports) > -1){ $this.options.tabs[i] = options.tabs[i]; } } } if ($('#modal-wechat-fileUploader').length == 0) { $(document.body).append(''); this.modalobj = $('#modal-wechat-fileUploader'); this.modalobj.append( '\n' ); } else { this.modalobj = $('#modal-wechat-fileUploader'); } var currentOptions = ''; for(i in this.options.tabs){ eval("this.init_"+i+"();"); currentOptions += i + $this.options.tabs[i]; } if(!this.historyOptions || this.historyOptions != currentOptions){ $this.modalobj.find('.nav-pills').find('li').removeClass('active').hide(); $this.modalobj.find('.tab-pane').removeClass('active'); for(i in $this.options.tabs){ $this.modalobj.find('.nav-pills').find('a[aria-controls="'+i+'"]').parent().show(); if($this.options.tabs[i]){ $this.modalobj.find('.nav-pills').find('a[aria-controls="'+i+'"]:first').parent().addClass('active'); $this.modalobj.find('#'+i).addClass('active'); } } } $($this.modalobj.find('.nav-pills').find('li.active').find('a').attr('href')).addClass('active'); this.reset(); this.historyOptions = currentOptions; this.modalobj.modal({'keyboard': false}); this.modalobj.modal('show'); }, 'init_video' : function() { $this = this; if(this.modalobj.find('#video').length == 0){ this.modalobj.find('.nav-pills').append('
  • 上传文件
  • '); this.modalobj.find('.modal-body').append(this.template().video); this.modalobj.find('#video').find(':file[name="file"]').filestyle({buttonText: '选择文件'}); } this.modalobj.find('#video').find('button.btn-primary').off('click'); this.modalobj.find('#video').find('button.btn-primary').on('click', function(){ var url = "./index.php?c=utility&a=wechat_file&do=upload&types=video"; var acid = $this.acid; var mode = $('#fileUploader_video_form').find(':input[name="mode"]:checked').val(); $('#fileUploader_video_form').attr('action', url + '&acid='+acid+'&mode='+mode); if(!$('#fileUploader_video_form :text[name="title"]').val()) { util.message('视频标题不能为空'); return false; } if(!$('#fileUploader_video_form textarea[name="introduction"]').val()) { util.message('视频描述不能为空'); return false; } $('#fileUploader_video_form').submit(); util.loading(); var interval = setInterval(function(){ var $target = $('#fileUploader_video_target').get(0).contentWindow.document.body.innerText; if($target != ''){ clearInterval(interval); var result = $.parseJSON($target); if(result.message){ alert(result.message); util.loaded(); } else if(result.media_id) { if ($.isFunction($this.options.callback)){ if($this.options.multi){ $this.options.callback([result]); } else { $this.options.callback(result); } util.loaded(); $this.hide(); } } } }, 500); }); }, 'reset_video' : function(){}, 'init_browser' : function() { $this = this; if(this.modalobj.find('#wechat_browser').length == 0){ this.modalobj.find('.nav-pills').append('
  • 浏览附件
  • '); this.modalobj.find('.modal-body').append(this.template().browser); } this.localPage(1); this.modalobj.find('#wechat_browser').find('button.btn-primary').off('click'); this.modalobj.find('#wechat_browser').find('button.btn-primary').on('click', function(){ if ($this.images.length > 0){ if($.isFunction($this.options.callback)){ if($this.options.multi){ $this.options.callback($this.images); } else { $this.options.callback($this.images[0]); } $this.hide(); } } else { alert('未选择任何文件.'); } }); }, 'localPage' : function(page) { var $this = this; var $browser = $this.modalobj.find('#wechat_browser'); var acid = $this.acid; var type = $this.type; var mode = $this.mode; $.getJSON('./index.php?c=utility&a=wechat_file&do=browser', {'page': page, 'acid' : acid, 'type' : type, 'mode' : mode}, function(data){ data = data.message; $browser.find('.browser-content').html(''); if(!_.isEmpty(data.items)) { $browser.data('attachment', data.items); $browser.find('.browser-content').empty(); $browser.find('.browser-content').html(_.template($this.template().localDialogLi, data)); $browser.find('#image-list-pager').html(data.page); window.p = function(url, p, state) { $this.localPage(p); } } else { $browser.find('.browser-content').html('暂无附件'); } $browser.find('.img-item').off('click'); $browser.find('.img-item').on('click', function(){ $(this).toggleClass('img-item-selected'); $this.images = []; $.each($('.img-item-selected'), function(idx, ele){ $this.images.push($this.modalobj.find('#wechat_browser').data('attachment')[$(this).attr('attachid')]); }); $browser.find('.browser-info').text('已选中 '+$this.images.length+' 个文件.'); if(($this.options.direct || !$this.options.multi) && $(this).hasClass('img-item-selected')){ $browser.find('button.btn-primary').click(); } }); $browser.find('.btnClose').off('click'); $browser.find('.btnClose').on('click', function(event){ var $this = this; if (confirm("确定要删除文件吗?")){ var id = $(this).parent().attr('attachid'); $.post('./index.php?c=utility&a=wechat_file&do=delete', {'id' : id, 'acid' : acid}, function(data){ var data = $.parseJSON(data); if(!data.error) { util.message(data.message); return false; } $($this).parent().remove(); }); } event.stopPropagation(); }); }); return false; }, 'reset_browser' : function(){ var $this = this; $this.modalobj.find('#wechat_browser').find('.img-item-selected').removeClass('img-item-selected'); $this.modalobj.find('#wechat_browser').find('.browser-content').html(''); }, 'browserfiles' : {}, 'init_upload' : function(){ $this = this; if(this.modalobj.find('#wechat_upload').length == 0){ this.modalobj.find('.nav-pills').html(''); this.modalobj.find('.nav-pills').append('
  • 上传永久文件
  • '); this.modalobj.find('.nav-pills').append('
  • 上传临时文件
  • '); } this.modalobj.find('#wechat_upload').remove(); if(this.modalobj.find('#wechat_upload').length == 0){ this.modalobj.find('.modal-body').append(this.template().upload); var $wrap = $('#wechat_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; })(), uploader; var options = { //auto: !$this.options.multi, pick: { id: '#wechat_filePicker', label: '点击选择文件', multiple : $this.options.multi }, dnd: '#wechat_dndArea', paste: '#wechat_uploader', // swf文件路径 swf: './resource/componets/webuploader/Uploader.swf', // 文件接收服务端。 server: './index.php?c=utility&a=wechat_file&do=upload&', chunked: false, compress: { quality: 80, preserveHeaders: true, noCompressIfLarger: true, compressSize: 1 * 1024 * 1024 }, duplicate : true, fileNumLimit: $this.options.multi ? 30 : 1, fileSizeLimit: 4 * 1024 * 1024, fileSingleSizeLimit: 30* 4 * 1024 * 1024 } // 实例化 uploader = WebUploader.create(options); if($this.options.multi){ // 添加“添加文件”的按钮, uploader.addButton({ id: '#wechat_filePicker2', label: '继续添加', multiple : $this.options.multi }); } $this.uploader = uploader; // 成功上传 accept = 0; $this.reset_upload = function(){ fileCount = 0; fileSize = 0; accept = 0; $.each($this.uploader.getFiles(), function(index, file){ removeFile(file); }); updateTotalProgress(); $this.uploader.reset(); $this.uploader.refresh(); $('#wechat_dndArea').removeClass('element-invisible'); $('#wechat_uploader').find('.filelist').empty(); if($this.options.multi){ $('#wechat_filePicker2').removeClass('element-invisible'); $('#wechat_filePicker2').next().removeClass('disabled'); $('#wechat_filePicker2').find('.webuploader-pick').next().css({'top': '0px', 'left': '0px','width': '100px','height': '32px'}); } $('#wechat_filePicker').find('.webuploader-pick').next().css({'left':'242px', 'top':'35px'}); var bar = $('#wechat_uploader').find('.statusBar'); bar.find('.info').empty(); bar.find('.accept').empty(); bar.show(); }; // 当有文件添加进来时执行,负责view的创建 function addFile(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') { 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的销毁 function removeFile(file) { var $li = $('#'+file.id); delete percentages[file.id]; updateTotalProgress(); $li.off().find('.file-panel').off().end().remove(); } function updateTotalProgress() { 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) + '%'); updateStatus(); } function updateStatus() { var text = '', stats; if (state === 'ready') { if($this.mode == '') { var mode = $this.modalobj.find('.nav-pills li.active').attr('data-mode'); } else { var mode = $this.mode; } var acid = $this.acid; if(!$this.flag) { uploader.option('server', uploader.option('server') + 'acid=' + acid + '&mode=' + mode + '&types=' + $this.type); $this.flag = 1; } text = '选中' + fileCount + '个文件,共' + WebUploader.formatSize(fileSize) + '。'; } else if (state === 'confirm') { stats = uploader.getStats(); if (stats.uploadFailNum) { text = '已上传'+stats.successNum+'个文件,'+stats.uploadFailNum+'个文件上传失败,重新上传失败文件或忽略' } } else { stats = uploader.getStats(); text = '共'+fileCount+'个('+WebUploader.formatSize(fileSize)+'),已上传' + stats.successNum + '个'; if (stats.uploadFailNum) { text += ',失败' + stats.uploadFailNum + '个'; } } $info.html(text); } function setState(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.hide(); $statusBar.addClass('element-invisible'); uploader.refresh(); break; case 'ready': $placeHolder.addClass('element-invisible'); $('#wechat_filePicker2').removeClass('element-invisible'); $queue.show(); $statusBar.removeClass('element-invisible'); uploader.refresh(); break; case 'uploading': $('#wechat_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) { setState('finish'); return; } break; case 'finish': $( '#wechat_filePicker2' ).removeClass( 'element-invisible' ); $upload.text( '确认使用' ).removeClass( 'disabled' ); stats = uploader.getStats(); if (stats.successNum) { // alert('上传成功'); } else { // 没有成功的文件,重设 state = 'done'; location.reload(); } break; } updateStatus(); } uploader.onUploadProgress = function(file, percentage) { var $li = $('#'+file.id), $percent = $li.find('.progress span'); $percent.css('width', percentage * 100 + '%'); percentages[file.id][1] = percentage; fileid = file.id; updateTotalProgress(); }; uploader.onFileQueued = function(file) { fileCount++; fileSize += file.size; if (fileCount === 1) { $placeHolder.addClass('element-invisible'); $statusBar.show(); } addFile(file); setState('ready'); updateTotalProgress(); }; uploader.onFileDequeued = function(file) { fileCount--; fileSize -= file.size; if (!fileCount) { setState('pedding'); } removeFile(file); updateTotalProgress(); $('#wechat_filePicker2').removeClass('element-invisible'); $('#wechat_filePicker2').next().removeClass('disabled'); }; uploader.on('all', function(type) { var stats; switch(type) { case 'uploadFinished': setState('confirm'); break; case 'startUpload': setState('uploading'); break; case 'stopUpload': setState('paused'); break; } }); uploader.on('uploadSuccess', function(file, result) { if (result.message){ alert(result.message); } if (!result.message){ accept++; $this.images.push(result); if(result.width){ $('#'+file.id).append(''+result.width +'x'+ result.height +''); } else if(result.size) { $('#'+file.id).append(''+result.size+''); } $('.accept').text('成功上传 '+accept+' 个文件'); if(!$this.options.multi){ $this.modalobj.find('#wechat_upload').find('.btn.btn-primary').click(); } } }); uploader.on('uploadFinished', function() { if($this.images.length > 0){ $this.modalobj.find('#wechat_upload').find('.btn.btn-primary').click(); } }); uploader.onError = function(code) { if(code == 'Q_EXCEED_SIZE_LIMIT'){ alert('错误信息: 文件大于 1M 无法上传.'); return } if(code == 'F_DUPLICATE'){ alert('错误信息: 不能重复上传文件.'); return } alert('Eroor: ' + code); }; $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); updateTotalProgress(); } this.modalobj.find('#wechat_upload').find('button.btn-primary').off('click'); this.modalobj.find('#wechat_upload').find('button.btn-primary').on('click', function(){ if ($this.images.length > 0){ if($.isFunction($this.options.callback)){ if($this.options.multi){ $this.options.callback($this.images); } else { $this.options.callback($this.images[0]); } $this.hide(); } } else { alert('未选择任何文件.'); } }); }, 'reset_upload' : function(){}, 'template' : function() { var template = {}; var $this = this; template['upload'] = '
    '+ '
    '+ '
    '+ '
    '+ '
    '+ '

    或将文件拖到这里,单次最多可选 ' + ($this.options.multi ? 5 : 1) + '个文件

    '+ '
    '+ '
    '+ '
    '+ '
    '+ ' 0%'+ ' '+ '
    '+ '
    '+ '
    '+ '
    '+ ( $this.options.multi ? '
    ' : '' )+ '
    确认使用
    '+ ' '+ '
    '+ '
    '+ '
    '+ '
    '; template['browser'] = '
    \n' + '
    \n' + ' \n' + '
    '; template['localDialogLi'] = '
    \n' + '<%_.each(items, function(item) {%> \n' + '
    \n' + '
    '+ '<%if(item.type == "image" || item.type == "thumb"){%>' + '
    \n' + '
    <%=item.width%>*<%=item.height%>
    \n' + '
    \n' + '
    \n' + '<%}%>' + '<%if(item.type == "voice" || item.type == "video"){%>' + '
    \n' + '
    <%=item.filename%>
    \n' + '
    \n' + '
    \n' + '<%}%>' + '
    \n' + '<%});%>\n' + '
    '; template['video'] = '
    '+ '
    '+ ' ' + '
    '+ '
    ' + ' ' + '
    ' + ' ' + ' ' + '
    ' + '
    ' + '
    ' + ' ' + '
    ' + ' '+ '
    ' + '
    ' + '
    ' + ' ' + '
    ' + ' '+ '
    ' + '
    ' + '
    ' + ' ' + '
    ' + ' '+ '
    ' + '
    ' + '
    ' + '
    ' + ' ' + '
    ' + '
    ' + '
    ' + '
    '+ ' '+ '
    '; return template; } }; return fileUploader; });