webuploader.extends.js 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060
  1. (function( $ ){
  2. platform = new Platform();
  3. $.fn.webuploader=function(options){
  4. return new widget.webuploader(options,$(this));
  5. };
  6. var requestAuth = 'Bearer ' + sessionStorage.getItem('Authorization')
  7. var widget = widget||{}; // 用户会话信息
  8. widget.webuploader = function(options,container){
  9. var uploaderOptions = $.extend(true,widget.webuploader.defaults,options);
  10. $.extend(true,this,{
  11. 'container':container,
  12. 'uploaderOptions':uploaderOptions,
  13. // 图片容器
  14. $queue : $( '<ul class="ace-thumbnails clearfix"></ul>' )
  15. .appendTo( container.find( '.queueList' ) ),
  16. /*
  17. * $queue : $( '<ul class="filelist"></ul>' ) .appendTo(
  18. * container.find( '.queueList' ) ),
  19. */
  20. // 状态栏,包括进度和控制按钮
  21. $statusBar : container.find( '.statusBar' ),
  22. // 文件总体选择信息。
  23. $info : container.find( '.statusBar' ).find( '.info' ),
  24. // 上传按钮
  25. $upload : $( '.uploadBtn',container.closest('.wrapper_wu') ),
  26. // 没选择文件之前的内容。
  27. $placeHolder : container.find( '.placeholder' ),
  28. $progress : container.find( '.statusBar' ).find( '.progress' ).hide(),
  29. // 添加的文件数量
  30. fileCount : 0,
  31. // 添加的文件总大小
  32. fileSize : 0,
  33. // 优化retina, 在retina下这个值是2
  34. // ratio : window.devicePixelRatio || 1,
  35. // 缩略图大小
  36. thumbnailWidth : 100 * (window.devicePixelRatio || 1),
  37. thumbnailHeight : 100 * (window.devicePixelRatio || 1),
  38. // 可能有pedding, ready, uploading, confirm, done.
  39. state : 'pedding',
  40. // 所有文件的进度信息,key为file id
  41. percentages : {},
  42. $itemLi : $('<li id="">\
  43. <a href="" data-rel="colorbox">\
  44. <img src="" onerror="this.src=\'/common-assets/plugins/webuploader-ext/profile-pic.jpg\'"/>\
  45. <div class="text">\
  46. <div class="inner"></div>\
  47. </div>\
  48. </a>\
  49. <div class="tools tools-bottom">\
  50. <a href="javascript:void(0);" title="下载">\
  51. <i class="ace-icon fa fa-download"></i>\
  52. </a>\
  53. <a href="javascript:void(0);" title="向左转">\
  54. <i class="ace-icon fa fa-rotate-left"></i>\
  55. </a>\
  56. <a href="javascript:void(0);" title="向右转" style="display:none">\
  57. <i class="ace-icon fa fa-rotate-right"></i>\
  58. </a>\
  59. <a href="javascript:void(0);" title="确定" style="display:none">\
  60. <i class="ace-icon fa fa fa-check"></i>\
  61. </a>\
  62. \
  63. </div>\
  64. <div class="progress progress-striped pos-rel" data-percent="0%">\
  65. <div class="progress-bar progress-bar-success"></div>\
  66. </div>\
  67. </li>'),
  68. // 图片上进度条类型,取值有[small_process:附属在缩略图底部小进度条模式,适合图片上传,
  69. // pull_curtain:拉幕模式,上传进度从缩略图底部出现一个遮罩层]
  70. processType:''
  71. });
  72. this.init();
  73. };
  74. // 图片上进度条类型
  75. widget.webuploader.processType={
  76. SMALL_PROCESS:'small_process',
  77. PULL_CURTAIN:'pull_curtain'
  78. };
  79. widget.webuploader.prototype={
  80. /**
  81. * 初始化webuploader控件
  82. */
  83. init:function(){
  84. var self = this;
  85. // 检测浏览器是否支持flash
  86. self.checkFlashSupport();
  87. // 设置上传进度条类型
  88. self.processTypeEvent();
  89. // 选择上传模式
  90. self.uploadModeTypeEvent();
  91. // 注册上传事件
  92. self.webuploaderRegister();
  93. // WebUploader实例
  94. self.uploader = WebUploader.create(self.uploaderOptions);
  95. // 绑定各种事件
  96. self.bindEvent();
  97. self.$upload.addClass( 'state-' + self.state );
  98. self.updateTotalProgress();
  99. var delNode;
  100. if(self.uploaderOptions.viewDel=="true"){
  101. delNode=$('<a href="javascript:void(0);" title="删除" style="display:none">\
  102. <i class="ace-icon fa fa-times red"></i>\
  103. </a>');
  104. }else{
  105. delNode=$('<a href="javascript:void(0);" title="删除">\
  106. <i class="ace-icon fa fa-times red"></i>\
  107. </a>');
  108. }
  109. self.$itemLi.find(".tools-bottom").append(delNode);
  110. },
  111. /**
  112. * 处理上传进度条展示类型
  113. */
  114. processTypeEvent:function(){
  115. var self=this,processTypeEventObj=[];
  116. processTypeEventObj[widget.webuploader.processType.SMALL_PROCESS]=function(){
  117. $('.progress',self.$itemLi).height(18);
  118. };
  119. processTypeEventObj[widget.webuploader.processType.PULL_CURTAIN]=function(){
  120. $('.progress-bar',self.$itemLi).css({
  121. width:'100%'
  122. });
  123. $('.progress',self.$itemLi).css({
  124. position: 'absolute',
  125. bottom: 0,
  126. width: '100%',
  127. opacity: 0.5,
  128. height:'0px',
  129. 'margin-bottom': '0px'
  130. });
  131. };
  132. // 设置默认小进度条模式
  133. self.processType=self.uploaderOptions.processType||widget.webuploader.processType.SMALL_PROCESS;
  134. processTypeEventObj[self.processType]&&processTypeEventObj[self.processType]();
  135. },
  136. /**
  137. * 设置模式
  138. */
  139. uploadModeTypeEvent:function(){
  140. var self = this,modeTypeProcess=[];
  141. // 定义类型处理事件
  142. modeTypeProcess['thumbnails']=function(){
  143. self.$itemLi.css({
  144. 'max-width':'150px',
  145. 'max-height':'100px'
  146. });
  147. };
  148. // 头像模式
  149. modeTypeProcess['single_pic']=function(){
  150. $( '.btn_p',self.container.closest('.wrapper_wu') ).hide();
  151. self.$statusBar.remove();
  152. self.$itemLi.find('.tools-bottom').css({
  153. 'padding-top':'0px'
  154. }).find('a').eq(2).show();
  155. self.container.closest('.wrapper_wu').css({'width':'180px'});
  156. self.$placeHolder.css({
  157. 'background-position-y':'20px',
  158. 'min-height':'0px',
  159. 'padding-top':'100px'
  160. });
  161. $.extend(self.uploaderOptions,{pick:{
  162. id:'#'+self.uploaderOptions.dataField+'filePicker',
  163. button:$('#'+self.uploaderOptions.dataField+'single_pic_btn').show()
  164. }});
  165. self.thumbnailWidth=160;
  166. self.thumbnailHeight=180;
  167. };
  168. modeTypeProcess['process']=function(){
  169. var processContainer = $('<div class="col-xs-10"></div>'),
  170. toolContainer = $('<div class="col-xs-1"></div>'),
  171. liContainer = $('<div class="row"></div>');
  172. $('a[data-rel="colorbox"]',self.$itemLi).wrap('<div class="col-xs-1"></div>');
  173. $('div.text',self.$itemLi).insertAfter(
  174. $('.progress',self.$itemLi).css({
  175. position:'relative'
  176. }).wrap(processContainer)
  177. );
  178. $('div.tools',self.$itemLi)
  179. .remove().appendTo(self.$itemLi)
  180. .wrap(toolContainer)
  181. .find('a').hide().eq(3).show();
  182. self.$itemLi.css({
  183. width:'100%',
  184. border:'0px',
  185. 'border-bottom':'1px solid #838383'
  186. }).children().wrapAll(liContainer.css({
  187. 'z-index':2
  188. })
  189. );
  190. self.$placeHolder.css({
  191. border:'0px',
  192. 'min-height':'0px',
  193. 'padding-top':'0px'
  194. });
  195. self.container.find( '.queueList' ).css({'margin':'0px'});
  196. };
  197. // 执行模式选择
  198. modeTypeProcess[self.uploaderOptions.modeType]&&modeTypeProcess[self.uploaderOptions.modeType]();
  199. },
  200. /**
  201. * 加载初始化文件列表
  202. */
  203. loadingItems:function(items){
  204. var webUploaderFile,self = this,files=[];
  205. // 增加文件加载状态
  206. WebUploader.File.Status.LOADING='loading';
  207. if(items.length>0){
  208. for(var i = 0 ; i < items.length ; i++){
  209. // items[i].lastModifiedDate = new
  210. // Date(items[i].lastModifiedDate.time);
  211. webUploaderFile = new WebUploader.File(items[i]);
  212. webUploaderFile.id = items[i]['id'];
  213. webUploaderFile.setStatus(WebUploader.File.Status.LOADING);
  214. files.push(webUploaderFile);
  215. }
  216. self.uploader.addFiles(files);
  217. }
  218. },
  219. /**
  220. * 增加文件方法
  221. */
  222. addFile:function(file){
  223. var self = this,
  224. $li = this.$itemLi.clone();
  225. $li.find("a[data-rel]").attr("href","javascript:void(0)");
  226. $li.find("a[data-rel]").on("click",function(){
  227. var imgid=$(this).closest('li').attr('id');
  228. if(!imgid||imgid.startsWith('WU_FILE')){
  229. top.layer.msg("已上传文件才可预览或下载!");
  230. return
  231. }
  232. if (file.type.startsWith("image") || file.ext == "png"
  233. || file.ext == "jpg") {
  234. var imgUrl=WEB_ROOT+'/sys/attachment/readImageStreamId?id='+imgid;
  235. top.layer.open({
  236. type : 2,
  237. title : "查看图片",
  238. shadeClose : true,
  239. maxmin:true,
  240. shade : 0.3,
  241. area : [ '480px', '380px' ],
  242. content : imgUrl
  243. });
  244. }else{
  245. window.location=WEB_ROOT+'/sys/attachment/download?id='+$(this).closest('li').attr('id');
  246. }
  247. });
  248. $li.attr('id',file.id);
  249. var $imgA=$('<a href="javascript:void(0)" class="downloada">'+file.name+'</a>');
  250. $li.find('div.inner').append($imgA);
  251. self.processFile(file,$li);
  252. file.rotation = 0;
  253. $li.find('.tools-bottom a').on( 'click', 'i', function() {
  254. var index = $(this).parent().index(),
  255. deg;
  256. switch ( index ) {
  257. case 4:
  258. self.uploader.removeFile( file );
  259. return;
  260. case 2:
  261. self.uploader.upload();
  262. return;
  263. case 1:
  264. file.rotation += 90;
  265. break;
  266. case 0:
  267. // file.rotation -= 90;
  268. var fileId=$(this).closest('li').attr('id');
  269. if(fileId.indexOf("WU_FILE")>-1){
  270. top.layer.msg("该文件还没有上传,不能从服务器下载");
  271. break;
  272. }
  273. window.location=WEB_ROOT+'/sys/attachment/download?id='+$(this).closest('li').attr('id');
  274. break;
  275. }
  276. if ( self.supportTransition() ) {
  277. deg = 'rotate(' + file.rotation + 'deg)';
  278. $li.find('img').css({
  279. '-webkit-transform': deg,
  280. '-mos-transform': deg,
  281. '-o-transform': deg,
  282. 'transform': deg
  283. });
  284. } else {
  285. $li.find('img').css( 'filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+ (~~((file.rotation/90)%4 + 4)%4) +')');
  286. }
  287. });
  288. $li.appendTo( self.$queue );
  289. },
  290. /**
  291. * 增加文件时处理文件信息
  292. */
  293. processFile:function(file,$li){
  294. var self = this;
  295. file.on('statuschange', function( cur, prev ) {
  296. if ( prev === 'progress' ) {
  297. // self.updateProgress($('.progress',$li),0);
  298. }
  299. // 成功
  300. if ( cur === 'error' || cur === 'invalid' ) {
  301. self.showError( file.statusText,$li.find('.info'));
  302. self.percentages[ file.id ][ 1 ] = 1;
  303. } else if ( cur === 'interrupt' ) {
  304. self.showError( 'interrupt',$li.find('.info'));
  305. } else if ( cur === 'queued' ) {
  306. self.percentages[ file.id ][ 1 ] = 0;
  307. } else if ( cur === 'progress' ) {
  308. $li.find('.info').remove();
  309. } else if ( cur === 'complete' ) {
  310. $li.append( '<span class="success"></span>' );
  311. }
  312. });
  313. // 如果是初始化已上传文件列表时
  314. if ( !(file.getStatus() === WebUploader.File.Status.LOADING) ) {
  315. self.percentages[ file.id ] = [ file.size, 0 ];
  316. self.setState( 'ready' );
  317. if ( file.getStatus() === 'invalid' ) {
  318. self.showError( file.statusText,$info);
  319. } else {
  320. self.uploader.makeThumb( file, function( error, src ) {
  321. if ( error ) {
  322. $('img',$li).attr('src',platform.getImgMapingImg({ext:file.ext}));
  323. return;
  324. }
  325. if( self.isSupportBase64() ) {
  326. $('img',$li).attr('src',src);
  327. }
  328. }, self.thumbnailWidth, self.thumbnailHeight );
  329. }
  330. }else{
  331. platform.generateThumbnails(file,self.thumbnailWidth,self.thumbnailHeight,function(thum){
  332. $('img',$li).attr('src',thum);
  333. })
  334. self.percentages[ file.id ] = [ file.size, file.size ];
  335. self.uploader.skipFile(file);
  336. self.setState( 'confirm' );
  337. self.updateProgress($('.progress',$li), 100);
  338. self.setAttachmentId(file.id);
  339. }
  340. },
  341. /**
  342. * 设置上传成功的文件ID
  343. */
  344. setAttachmentId:function(fileId){
  345. var self = this;
  346. // 初始化已上传的id值
  347. var fileIds = $(self.uploaderOptions.fileIdContainer).val();
  348. if(!!!fileIds||fileIds.indexOf(fileId)==-1)
  349. $(self.uploaderOptions.fileIdContainer).val(fileIds===''?fileId:(fileIds+','+fileId));
  350. },
  351. /**
  352. * 上传成功回调函数
  353. */
  354. uploadSuccessEvent:function(file,response){
  355. if(!!!response)return false;
  356. var self = this;
  357. file.path = response.path;
  358. $('li#'+file.id).attr('id',response.id);
  359. file.updateFileId(response.id);
  360. },
  361. /**
  362. * 绑定各种事件
  363. */
  364. bindEvent:function(){
  365. var self = this;
  366. // 拖拽时不接受 js, txt 文件。
  367. self.uploader.on( 'dndAccept', function( items ) {
  368. var denied = false,
  369. len = items.length,
  370. i = 0,
  371. // 修改js类型
  372. unAllowed = 'text/plain;application/javascript ';
  373. for ( ; i < len; i++ ) {
  374. // 如果在列表里面
  375. if ( ~unAllowed.indexOf( items[ i ].type ) ) {
  376. denied = true;
  377. break;
  378. }
  379. }
  380. return !denied;
  381. });
  382. self.uploader.on('ready', function() {
  383. window.uploader = self.uploader;
  384. });
  385. self.uploader.onUploadProgress = function( file, percentage ) {
  386. var $li = $('#'+file.id),
  387. $percent = $li.find('.progress');
  388. self.updateProgress($percent,Math.round( percentage * 100 ));
  389. self.percentages[ file.id ][ 1 ] = percentage;
  390. self.updateTotalProgress();
  391. };
  392. self.uploader.onFileQueued = function( file ) {
  393. self.fileCount++;
  394. self.fileSize += parseInt(file.size);
  395. if ( self.fileCount === 1 ) {
  396. self.$placeHolder.addClass( 'element-invisible' );
  397. self.$statusBar.show();
  398. }
  399. self.addFile( file );
  400. self.updateTotalProgress();
  401. };
  402. self.uploader.onUploadBeforeSend = function(object,data,headers) {
  403. $.extend(true,data,self.uploaderOptions.overFormData);
  404. };
  405. self.uploader.onUploadSuccess = function(file,response) {
  406. self.uploadSuccessEvent(file,response);
  407. };
  408. self.uploader.onUploadFinished = function() {
  409. var completeFils = self.uploader.getFiles(WebUploader.File.Status.COMPLETE),fileIdArray=[];
  410. for(var i=0; i<completeFils.length; i++){
  411. if(fileIdArray.indexOf(completeFils[i]['id'])==-1)
  412. fileIdArray.push(completeFils[i]['id']);
  413. }
  414. $(self.uploaderOptions.fileIdContainer).val(fileIdArray.join(','));
  415. };
  416. self.uploader.onFileDequeued = function( file ) {
  417. self.fileCount--;
  418. self.fileSize -= parseInt(file.size);
  419. if ( !self.fileCount ) {
  420. self.setState( 'pedding' );
  421. }
  422. self.removeFile( file );
  423. self.updateTotalProgress();
  424. };
  425. self.uploader.on( 'all', function( type ) {
  426. var stats;
  427. switch( type ) {
  428. case 'uploadFinished':
  429. self.setState( 'confirm' );
  430. break;
  431. case 'startUpload':
  432. self.setState( 'uploading' );
  433. break;
  434. case 'stopUpload':
  435. self.setState( 'paused' );
  436. break;
  437. }
  438. });
  439. self.uploader.onError = function( code ) {
  440. switch(code){
  441. case 'F_DUPLICATE':
  442. alert( 'Error:不能选择重复的文件!');
  443. break;
  444. case 'F_EXCEED_SIZE':
  445. alert('Error:上传的单个文件大小超过限制');
  446. break;
  447. case 'Q_EXCEED_SIZE_LIMIT':
  448. alert('Error:上传的总文件大小超过限制');
  449. break;
  450. default:
  451. alert('未知错误!');
  452. }
  453. };
  454. self.$upload.on('click', function() {
  455. if ( $(this).hasClass( 'disabled' ) ) {
  456. return false;
  457. }
  458. if ( self.state === 'ready' ) {
  459. self.uploader.upload();
  460. } else if ( self.state === 'paused' ) {
  461. self.uploader.upload();
  462. } else if ( self.state === 'uploading' ) {
  463. self.uploader.stop(true);
  464. }
  465. });
  466. self.$info.on( 'click', '.retry', function() {
  467. self.uploader.retry();
  468. } );
  469. self.$info.on( 'click', '.ignore', function() {
  470. alert( 'todo' );
  471. } );
  472. // $(document).on('click','.downloada',function(e){
  473. // if(!$(e.target).text()==$(this).text()){
  474. // return;
  475. // }
  476. // window.location=WEB_ROOT+'/sys/attachment/download?id='+$(this).closest('li').attr('id');
  477. //
  478. // });
  479. },
  480. /**
  481. * 按照上传状态控制样式的展示
  482. */
  483. setState:function(val){
  484. var file, stats,self=this;
  485. if ( val === self.state ) {
  486. return;
  487. }
  488. self.$upload.removeClass( 'state-' + self.state );
  489. self.$upload.addClass( 'state-' + val );
  490. self.state = val;
  491. switch ( self.state ) {
  492. case 'pedding':
  493. self.$placeHolder.removeClass( 'element-invisible' );
  494. self.$queue.hide();
  495. self.$statusBar.addClass( 'element-invisible' );
  496. self.uploader.refresh();
  497. break;
  498. case 'ready':
  499. self.$placeHolder.addClass( 'element-invisible' );
  500. $( '#input-upload' ).removeClass( 'element-invisible');
  501. self.$queue.show();
  502. self.$statusBar.removeClass('element-invisible');
  503. self.uploader.refresh();
  504. break;
  505. case 'uploading':
  506. $( '#input-upload' ).addClass( 'element-invisible' );
  507. self.$progress.show();
  508. $('#upload-type',self.$upload).text( '暂停上传' );
  509. break;
  510. case 'paused':
  511. self.$progress.show();
  512. $('#upload-type',self.$upload).text( '继续上传' );
  513. break;
  514. case 'confirm':
  515. self.$progress.hide();
  516. $( '#input-upload' ).removeClass( 'element-invisible' );
  517. $('#upload-type',self.$upload).text( '开始上传' );
  518. stats = self.uploader.getStats();
  519. if ( stats.successNum && !stats.uploadFailNum ) {
  520. self.setState( 'finish' );
  521. return;
  522. }
  523. break;
  524. case 'finish':
  525. if ( self.fileCount>0 ) {
  526. }
  527. break;
  528. }
  529. self.updateStatus();
  530. },
  531. /**
  532. * 修改上传之后的提示信息
  533. */
  534. updateStatus:function(){
  535. var text = '', stats;
  536. if ( this.state === 'ready' ) {
  537. text = '选中' + this.fileCount + '个文件,共' +
  538. WebUploader.formatSize( this.fileSize ) + '。';
  539. } else if ( this.state === 'confirm' ) {
  540. stats = this.uploader.getStats();
  541. if ( stats.uploadFailNum ) {
  542. text = '已成功上传' + stats.successNum+ '个文件到服务器,'+
  543. stats.uploadFailNum + '个文件上传失败,<a class="retry" href="#">重新上传</a>失败文件或<a class="ignore" href="#">忽略</a>'
  544. }
  545. } else {
  546. stats = this.uploader.getStats();
  547. text = '共' + this.fileCount + '个(' +
  548. WebUploader.formatSize( this.fileSize ) +
  549. '),已上传' + stats.successNum + '个';
  550. if ( stats.uploadFailNum ) {
  551. text += ',失败' + stats.uploadFailNum + '个';
  552. }
  553. }
  554. this.$info.html( text );
  555. },
  556. /**
  557. * 修改上传文件总大小,修改进度条展示上传进度
  558. */
  559. updateTotalProgress:function(){
  560. var loaded = 0,
  561. total = 0,
  562. percent;
  563. $.each( this.percentages, function( k, v ) {
  564. total += v[ 0 ];
  565. loaded += v[ 0 ] * v[ 1 ];
  566. } );
  567. percent = total ? loaded / total : 0;
  568. this.updateProgress(this.$progress,Math.round( percent * 100 ),true);
  569. this.updateStatus();
  570. },
  571. /**
  572. * 修改上传进度展示 processType进度条类型,默认是小进度条
  573. */
  574. updateProgress:function(progress,num,total){
  575. if(this.processType===widget.webuploader.processType.SMALL_PROCESS||total){
  576. $('.progress-bar',progress).css('width',num+'%');
  577. }else if(this.processType===widget.webuploader.processType.PULL_CURTAIN){
  578. progress.height(num+'%');
  579. if(num===100){
  580. progress.css({
  581. opacity:0
  582. });
  583. }
  584. }
  585. progress.attr('data-percent',num+'%');
  586. return progress;
  587. },
  588. /**
  589. * 删除上传文件
  590. */
  591. removeFile:function(file){
  592. var self = this;
  593. if(!!file.id&&file.id.indexOf('WU_FILE')==-1)
  594. $.ajax({
  595. type: "POST"
  596. , url: self.uploaderOptions.deleteServer
  597. , data: {
  598. id: file.id
  599. },
  600. headers: { Authorization: requestAuth},
  601. async:false
  602. }).done(function(data){
  603. });
  604. var $li = $('#'+file.id);
  605. // 上传字段处减少删除的fild id
  606. var fileIds=$(self.uploaderOptions.fileIdContainer).val().split(",");
  607. $(self.uploaderOptions.fileIdContainer).val(fileIds.filter(function(elem, pos){
  608. return elem!=file.id;
  609. }).join(","));
  610. delete self.percentages[ file.id ];
  611. self.updateTotalProgress();
  612. $li.off().find('.tools-bottom a').off().end().remove();
  613. },
  614. /**
  615. * 队列数据重置
  616. */
  617. queueReset:function(){
  618. this.$queue.html('');
  619. this.setState('pedding');
  620. this.uploader.reset();
  621. },
  622. /**
  623. * 展现错误信息
  624. */
  625. showError:function(code,$info){
  626. switch( code ) {
  627. case 'exceed_size':
  628. text = '文件大小超出';
  629. break;
  630. case 'interrupt':
  631. text = '上传暂停';
  632. break;
  633. default:
  634. text = '上传失败,请重试';
  635. break;
  636. }
  637. $info.text( text ).appendTo( this.$li );
  638. },
  639. /**
  640. * 预处理webuploader的设置选项
  641. */
  642. pretreatmentOptions:function(file){
  643. // 如果开启了智能上传和分片上传并且上传文件大小已满足分片条件则选择分片上传
  644. if(this.uploaderOptions.autoSelectServer
  645. &&this.uploaderOptions.chunked
  646. &&(file.size>=this.uploaderOptions.chunkedMaximumSize)){
  647. this.uploader['options']['chunked']=true;
  648. }else{
  649. this.uploader['options']['chunked']=false;
  650. }
  651. },
  652. webuploaderRegister:function(){
  653. var self = this,startDate;
  654. WebUploader.Uploader.register({
  655. "before-send-file": "beforeSendFile"
  656. , "before-send": "beforeSend"
  657. , "after-send-file": "afterSendFile"
  658. }, {
  659. beforeSendFile: function(file){
  660. startDate = new Date().getTime();
  661. // 秒传验证
  662. var task = new $.Deferred();
  663. (new WebUploader.Uploader()).md5File(file, 0, 10*1024*1024).progress(function(percentage){
  664. // console.log(percentage);
  665. }).then(function(val){
  666. self.uploader['options']['formData']['md5'] = file['md5Mark'] = val;
  667. $.ajax({
  668. type: "POST"
  669. , url: WEB_ROOT+'/sys/attachment/md5Check'
  670. , data: {
  671. md5: val,
  672. chunked:self.uploader['options']['chunked']||false
  673. },
  674. headers: { Authorization: requestAuth},
  675. cache: false
  676. , timeout: 1000 // todo 超时的话,只能认为该文件不曾上传过
  677. , dataType: "json"
  678. }).then(function(data, textStatus, jqXHR){
  679. if(!!data){ // 若存在,这返回失败给WebUploader,表明该文件不需要上传
  680. task.resolve();
  681. self.uploader.skipFile(file);
  682. file.path = data.path;
  683. self.updateProgress($('.progress',$('li#'+file.id)), 100);
  684. self.uploadSuccessEvent(file,data);
  685. // UploadComlate(file);
  686. }else{
  687. task.resolve();
  688. self.pretreatmentOptions(file);
  689. }
  690. }, function(jqXHR, textStatus, errorThrown){ // 任何形式的验证失败,都触发重新上传
  691. task.resolve();
  692. });
  693. });
  694. return $.when(task);
  695. }
  696. , beforeSend: function(block){
  697. if(self.uploader['options']['chunked']){
  698. // 分片验证是否已传过,用于断点续传
  699. var task = new $.Deferred();
  700. $.ajax({
  701. type: "POST"
  702. , url: WEB_ROOT+'/sys/attachment/chunkCheck'
  703. , data: {
  704. chunkIndex: block.chunk
  705. , chunkSize: block.end - block.start
  706. , name: block.file.name
  707. , lastModifiedDate:block.file.lastModifiedDate
  708. , type:block.file.type
  709. , size:block.file.size
  710. }
  711. , cache: false
  712. ,
  713. headers: { Authorization: requestAuth}, timeout: 1000 // todo 超时的话,只能认为该分片未上传过
  714. , dataType: "json"
  715. }).then(function(data, textStatus, jqXHR){
  716. if(data){ // 若存在,返回失败给WebUploader,表明该分块不需要上传
  717. task.reject();
  718. }else{
  719. task.resolve();
  720. }
  721. }, function(jqXHR, textStatus, errorThrown){ // 任何形式的验证失败,都触发重新上传
  722. task.resolve();
  723. });
  724. return $.when(task);
  725. }
  726. }
  727. , afterSendFile: function(file){
  728. if(self.uploader['options']['chunked']){
  729. var chunksTotal = 0;
  730. if((chunksTotal = Math.ceil(file.size/self.uploader['options']['chunkSize'])) > 1){
  731. // 合并请求
  732. var task = new $.Deferred();
  733. $.ajax({
  734. type: "POST"
  735. , url: WEB_ROOT+'/sys/attachment/chunksMerge'
  736. , data: {
  737. name:file.name
  738. , chunks: chunksTotal
  739. , ext: file.ext
  740. , md5: file['md5Mark']
  741. , type:file.type
  742. , superId:self.uploaderOptions.superId
  743. , lastModifiedDate:file.lastModifiedDate
  744. , size:file.size
  745. }
  746. ,
  747. headers: { Authorization: requestAuth}, cache: false
  748. , dataType: "json"
  749. }).then(function(data, textStatus, jqXHR){
  750. // todo 检查响应是否正常
  751. task.resolve();
  752. // console.log("上传文件'"+file.name+"'总耗时: "+((new
  753. // Date().getTime()) - startDate)/1000+'秒');
  754. // UploadComlate(file);
  755. }, function(jqXHR, textStatus, errorThrown){
  756. task.reject();
  757. });
  758. return $.when(task);
  759. }else{
  760. // UploadComlate(file);
  761. }
  762. }
  763. }
  764. });
  765. },
  766. isSupportBase64:function(){
  767. // 判断浏览器是否支持图片的base64
  768. var data = new Image();
  769. var support = true;
  770. data.onload = data.onerror = function() {
  771. if( this.width != 1 || this.height != 1 ) {
  772. support = false;
  773. }
  774. }
  775. data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
  776. return support;
  777. },
  778. flashVersion:function(){
  779. // 检测是否已经安装flash,检测flash的版本
  780. var version;
  781. try {
  782. version = navigator.plugins[ 'Shockwave Flash' ];
  783. version = version.description;
  784. } catch ( ex ) {
  785. try {
  786. version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash')
  787. .GetVariable('$version');
  788. } catch ( ex2 ) {
  789. version = '0.0';
  790. }
  791. }
  792. version = version.match( /\d+/g );
  793. return parseFloat( version[ 0 ] + '.' + version[ 1 ], 10 );
  794. },
  795. supportTransition:function(){
  796. var s = document.createElement('p').style,
  797. r = 'transition' in s ||
  798. 'WebkitTransition' in s ||
  799. 'MozTransition' in s ||
  800. 'msTransition' in s ||
  801. 'OTransition' in s;
  802. s = null;
  803. return r;
  804. },
  805. checkFlashSupport:function(){
  806. if ( !WebUploader.Uploader.support('flash') && WebUploader.browser.ie ) {
  807. var $wrap=$().wrap;
  808. // flash 安装了但是版本过低。
  809. // if (flashVersion) {
  810. if (this.flashVersion()) {
  811. (function(container) {
  812. window['expressinstallcallback'] = function( state ) {
  813. switch(state) {
  814. case 'Download.Cancelled':
  815. alert('您取消了更新!')
  816. break;
  817. case 'Download.Failed':
  818. alert('安装失败')
  819. break;
  820. default:
  821. alert('安装已成功,请刷新!');
  822. break;
  823. }
  824. delete window['expressinstallcallback'];
  825. };
  826. var swf = WEB_ROOT+'/static/webuploader/webuploader-0.1.5/examples/image-upload/expressInstall.swf';
  827. // insert flash object
  828. var html = '<object type="application/' +
  829. 'x-shockwave-flash" data="' + swf + '" ';
  830. if (WebUploader.browser.ie) {
  831. html += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" ';
  832. }
  833. html += 'width="100%" height="100%" style="outline:0">' +
  834. '<param name="movie" value="' + swf + '" />' +
  835. '<param name="wmode" value="transparent" />' +
  836. '<param name="allowscriptaccess" value="always" />' +
  837. '</object>';
  838. $(container).html(html);
  839. })($wrap);
  840. // 压根就没有安转。
  841. } else {
  842. $wrap.html('<a href="http://www.adobe.com/go/getflashplayer" target="_blank" border="0"><img alt="get flash player" src="http://www.adobe.com/macromedia/style_guide/images/160x41_Get_Flash_Player.jpg" /></a>');
  843. }
  844. return false;
  845. } else if (!WebUploader.Uploader.support()) {
  846. alert( 'Web Uploader 不支持您的浏览器!');
  847. return false;
  848. }
  849. },
  850. getImgMapingImg:function(attach){
  851. if(this.imgArray.join(' ').indexOf(attach.ext)!=-1){
  852. return WEB_ROOT+"/sys/attachment/readImageStreamId?id="+attach.id;
  853. }else if(!!this.mappingArray[attach.ext]){
  854. return this.mappingArray[attach.ext];
  855. }else{
  856. return this.mappingArray['default'];
  857. }
  858. }
  859. };
  860. widget.webuploader.defaults={
  861. swf: '/common-assets/plugins/webuploader-0.1.5/Uploader.swf',
  862. pick: {
  863. id: '#input-upload',
  864. label: '点击选择文件'
  865. },
  866. fileIdContainer:''
  867. };
  868. })( jQuery );
  869. function initWebUploader() {
  870. $(".uploader-container").each(function(){
  871. var $container=$(this);
  872. var field=$container.attr("data-field");
  873. var config = $.extend({
  874. // 展现方式(类型有['thumbnails:缩略图模式','single_pic:单图片模式','process:进度条模式'])
  875. // 当设置single_pic模式时,auto属性设置为true,否则无法自动触发上传操作
  876. modeType:'thumbnails',
  877. dataField:field,
  878. // 进度条类型,详细参数见js
  879. processType:'',
  880. // 初始化或者上传完之后文件id隐藏容器(自定义)
  881. fileIdContainer:$("#"+field),
  882. method:'post',
  883. // 设置的formData值都要覆盖默认的上传自带值
  884. overFormData:{
  885. workspace:$("#"+field+"-workspace").val(),
  886. storeType:$("#"+field+"-storeType").val(),
  887. path:$("#"+field+"-path").val()
  888. },
  889. // 文件上传过程中每次都提交的数据
  890. formData:{},
  891. // 文件上传过程中文件所属ID(自定义)
  892. superId:'',
  893. auto:false,
  894. fileVal:'fileInput',
  895. dnd: '#'+field+'dndArea',
  896. paste: $('#'+field+'-input-upload'),
  897. chunked: false,
  898. // 默认分片大小
  899. chunkSize:5 * 1024 * 1024,
  900. // 智能选择server上传(如果是上传文件有可能小于指定分片大小的话必须开启智能上传)(自定义)
  901. autoSelectServer:'true',
  902. // 大于指定文件大小之后才用分片进行上传(默认5M)(自定义)
  903. chunkedMaximumSize:5 * 1024 * 1024,
  904. // 上传服务
  905. server:WEB_ROOT+"/sys/attachment/uploadFile",
  906. // 删除服务(自定义)
  907. deleteServer:WEB_ROOT+"/sys/attachment/deleteAttachment",
  908. // 禁掉全局的拖拽功能。这样不会出现图片拖进页面的时候,把图片打开。
  909. disableGlobalDnd: false,
  910. fileNumLimit: 50,
  911. fileSizeLimit: 2*1024 * 1024 * 1024,
  912. fileSingleSizeLimit: 1*1024 * 1024 * 1024,
  913. prepareNextFile: true,
  914. threads:6,
  915. duplicate: false,
  916. thumb:{
  917. // 是否允许放大,如果想要生成小图的时候不失真,此选项应该设置为false.
  918. allowMagnify: false,
  919. // 是否允许裁剪。
  920. crop: true
  921. },
  922. compress:false,
  923. pick: {
  924. id:'#'+field+'-input-upload',
  925. innerHTML: '<i class="el-icon-plus"></i><span>选择文件</span>'
  926. }
  927. }, $container.data());
  928. var webuploader =$container.webuploader(config);
  929. $('#'+field+'-cancle-upload').on('click',function(){
  930. // webuploader.queueReset();
  931. // 移除所有缩略图并将上传文件移出上传序列
  932. for (var i = 0; i < uploader.getFiles().length; i++) {
  933. // 将图片从上传序列移除
  934. // uploader.removeFile(uploader.getFiles()[i]); // 发送删除图片请求到后台
  935. // uploader.removeFile(uploader.getFiles()[i], true);
  936. // delete uploader.getFiles()[i];
  937. // 将图片从缩略图容器移除
  938. var $li = $('#' + uploader.getFiles()[i].id);
  939. $li.off().remove();
  940. }
  941. webuploader.setState('pedding');
  942. // 重置uploader,目前只重置了文件队列
  943. uploader.reset();
  944. // 更新状态等,重新计算文件总个数和总大小
  945. webuploader.updateStatus();
  946. // 重置文件总个数和总大小
  947. webuploader.fileCount = 0;
  948. webuploader.fileSize = 0;
  949. });
  950. // 初始化上传文件信息列表
  951. var ids=$("#"+field).val();
  952. if(!!ids){
  953. $.ajax({
  954. url: WEB_ROOT+"/sys/attachment/findByIds?ids="+ids,
  955. headers: { Authorization: requestAuth},
  956. method: 'get',
  957. success: function (data) {
  958. if(!!data) {webuploader.loadingItems(data);}
  959. }
  960. })
  961. // $.get(WEB_ROOT+"/sys/attachment/findByIds?ids="+ids,function(data){
  962. // if(!!data) {webuploader.loadingItems(data);}
  963. // });
  964. }
  965. }) ;
  966. }
  967. $(function() {
  968. /** ****webuploader 初始化****** */
  969. initWebUploader()
  970. })