main.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908
  1. function chunk_file ( name , accept , disk , driver ) {
  2. var initVal = $ ( '#' + name + '-savedpath' ).val ();
  3. initVal = initVal ? true : false;
  4. var $wrap = $ ( '#uploader' + name ) ,
  5. // 图片容器
  6. $queue = $ ( '<ul class="filelist"></ul>' )
  7. .appendTo ( $wrap.find ( '#queueList' + name ) ) ,
  8. // 状态栏,包括进度和控制按钮
  9. $statusBar = $wrap.find ( '.statusBar' ) ,
  10. // 文件总体选择信息。
  11. $info = $statusBar.find ( '.info' ) ,
  12. // 上传按钮
  13. $upload = $wrap.find ( '.uploadBtn' ) ,
  14. // 没选择文件之前的内容。
  15. $placeHolder = $wrap.find ( '.placeholder' ) ,
  16. $progress = $statusBar.find ( '.progress' ).hide () ,
  17. // 添加的文件数量
  18. fileCount = 0 ,
  19. // 添加的文件总大小
  20. fileSize = 0 ,
  21. // 优化retina, 在retina下这个值是2
  22. ratio = window.devicePixelRatio || 1 ,
  23. // 缩略图大小
  24. thumbnailWidth = 110 * ratio ,
  25. thumbnailHeight = 110 * ratio ,
  26. // 可能有pedding, ready, uploading, confirm, done.
  27. state = 'pedding' ,
  28. // 所有文件的进度信息,key为file id
  29. percentages = {} ,
  30. // 判断浏览器是否支持图片的base64
  31. isSupportBase64 = (function () {
  32. var data = new Image ();
  33. var support = true;
  34. data.onload = data.onerror = function () {
  35. if ( this.width != 1 || this.height != 1 ) {
  36. support = false;
  37. }
  38. }
  39. data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
  40. return support;
  41. }) () ,
  42. // 检测是否已经安装flash,检测flash的版本
  43. flashVersion = (function () {
  44. var version;
  45. try {
  46. version = navigator.plugins['Shockwave Flash'];
  47. version = version.description;
  48. } catch ( ex ) {
  49. try {
  50. version = new ActiveXObject ( 'ShockwaveFlash.ShockwaveFlash' )
  51. .GetVariable ( '$version' );
  52. } catch ( ex2 ) {
  53. version = '0.0';
  54. }
  55. }
  56. version = version.match ( /\d+/g );
  57. return parseFloat ( version[0] + '.' + version[1] , 10 );
  58. }) () ,
  59. supportTransition = (function () {
  60. var s = document.createElement ( 'p' ).style ,
  61. r = 'transition' in s ||
  62. 'WebkitTransition' in s ||
  63. 'MozTransition' in s ||
  64. 'msTransition' in s ||
  65. 'OTransition' in s;
  66. s = null;
  67. return r;
  68. }) () ,
  69. // WebUploader实例
  70. uploader;
  71. if ( !WebUploader.Uploader.support ( 'flash' ) && WebUploader.browser.ie ) {
  72. // flash 安装了但是版本过低。
  73. if ( flashVersion ) {
  74. (function ( container ) {
  75. window['expressinstallcallback'] = function ( state ) {
  76. switch ( state ) {
  77. case 'Download.Cancelled':
  78. swal ( '您取消了更新!' , '' , 'error' ).then ( function () {
  79. } );
  80. break;
  81. case 'Download.Failed':
  82. swal ( '安装失败!' , '' , 'error' ).then ( function () {
  83. } );
  84. break;
  85. default:
  86. swal ( '安装已成功,请刷新页面!' , '' , 'error' ).then ( function () {
  87. } );
  88. break;
  89. }
  90. delete window['expressinstallcallback'];
  91. };
  92. var swf = './expressInstall.swf';
  93. // insert flash object
  94. var html = '<object type="application/' +
  95. 'x-shockwave-flash" data="' + swf + '" ';
  96. if ( WebUploader.browser.ie ) {
  97. html += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" ';
  98. }
  99. html += 'width="100%" height="100%" style="outline:0">' +
  100. '<param name="movie" value="' + swf + '" />' +
  101. '<param name="wmode" value="transparent" />' +
  102. '<param name="allowscriptaccess" value="always" />' +
  103. '</object>';
  104. container.html ( html );
  105. }) ( $wrap );
  106. // 压根就没有安转。
  107. } else {
  108. $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>' );
  109. }
  110. return;
  111. } else if ( !WebUploader.Uploader.support () ) {
  112. swal ( 'Web Uploader 不支持您的浏览器!' , '' , 'error' ).then ( function () {
  113. } );
  114. return;
  115. }
  116. var options = {
  117. tokenUrl: window.chunk_file.prefix + '/' + "chunk-file-upload/get_qiniu_token" ,
  118. mockToken: false ,
  119. hash: false ,
  120. disk: disk
  121. };
  122. if ( driver == 'local' ) {//本地
  123. options.host = window.chunk_file.prefix + '/' + 'chunk-file-upload/upload';
  124. } else if ( driver = 'qiniu' ) {
  125. options.host = window.chunk_file.area;
  126. }
  127. var uploader = WebUploader.create ( {
  128. swf: "Uploader.swf" ,
  129. server: options.host ,
  130. pick: {
  131. id: '#filePicker' + name ,
  132. label: '点击选择文件'
  133. } ,
  134. duplicate: true ,
  135. resize: false ,
  136. dnd: "#dndArea" + name ,
  137. paste: document.body ,
  138. disableGlobalDnd: true ,
  139. thumb: {
  140. width: 100
  141. , height: 100
  142. , quality: 70
  143. , allowMagnify: true
  144. , crop: true
  145. } ,
  146. accept: accept ,
  147. compress: false ,
  148. prepareNextFile: true ,
  149. chunked: true ,
  150. chunkSize: 4 * 1024 * 1024 ,
  151. threads: 5 ,
  152. fileNumLimit: window.chunk_file.fileNumLimit ,
  153. fileSizeLimit: window.chunk_file.fileSizeLimit ,
  154. // duplicate: false
  155. } );
  156. var token;
  157. var m = new Map ();
  158. // 添加“添加文件”的按钮,
  159. if ( window.chunk_file.fileNumLimit <= 1 ) {
  160. uploader.addButton ( {
  161. id: '#filePicker2' + name ,
  162. label: '重新选择'
  163. } );
  164. } else {
  165. uploader.addButton ( {
  166. id: '#filePicker2' + name ,
  167. label: '继续选择'
  168. } );
  169. }
  170. //只能单传图片
  171. uploader.on ( "beforeFileQueued" , function ( file ) {
  172. if ( window.chunk_file.fileNumLimit <= 1 ) {//单传
  173. if ( $ ( 'ul.filelist li' ).length ) {
  174. var file_id = $ ( 'ul.filelist' ).children ( 'li' ).attr ( 'id' );
  175. uploader.removeFile ( file_id );
  176. }
  177. }
  178. } );
  179. //错误提示
  180. uploader.on ( "error" , function ( type , handler ) {
  181. switch ( type ) {
  182. case 'Q_EXCEED_NUM_LIMIT':
  183. swal ( '上传文件总数量不能超过' + uploader.options.fileNumLimit + '个' , '' , 'error' ).then ( function () {
  184. } );
  185. break;
  186. case 'Q_EXCEED_SIZE_LIMIT':
  187. swal ( '上传文件大小不能超过' + uploader.options.fileSizeLimit + "KB" , '' , 'error' ).then ( function () {
  188. } );
  189. break;
  190. case 'Q_TYPE_DENIED':
  191. swal ( '上传文件类型不被允许' , '' , 'error' ).then ( function () {
  192. } );
  193. break;
  194. }
  195. } );
  196. //当文件被加入队列以后触发。
  197. uploader.on ( "fileQueued" , function ( file ) {
  198. fileCount++;
  199. fileSize += file.size;
  200. var ctx = new Array ();
  201. m.set ( file.name , ctx );
  202. if ( fileCount === 1 ) {
  203. $placeHolder.addClass ( 'element-invisible' );
  204. $statusBar.show ();
  205. }
  206. addFile ( file );
  207. setState ( 'ready' );
  208. updateTotalProgress ();
  209. } );
  210. uploader.on ( "uploadStart" , function ( file ) {
  211. if ( driver == 'qiniu' ) {//七牛,传递七牛key
  212. if ( !options.mockToken ) {
  213. GetToken ( options.tokenUrl , file );
  214. } else {
  215. uploader.options.formData = {
  216. token: options.mockTokenValue
  217. };
  218. token = options.mockTokenValue;
  219. }
  220. } else {//laravel传递laravelkey
  221. uploader.options.formData._token = $ ( 'meta[name="csrf-token"]' ).attr ( 'content' );
  222. }
  223. var name = Date.parse ( new Date () ) + Math.random ().toString ( 36 ).substr ( 2 ) + '.' + file.source.ext;
  224. uploader.options.formData.key = name;
  225. uploader.options.formData.disk = options.disk;
  226. } );
  227. uploader.on ( "uploadBeforeSend" , function ( block , data , headers ) {
  228. if ( parseInt ( block.file.size ) <= parseInt ( uploader.options.chunkSize ) ) {
  229. uploader.options.chunked = false;
  230. } else {
  231. uploader.options.chunked = true;
  232. headers['Authorization'] = 'UpToken ' + token;
  233. headers['Content-Type'] = 'application/octet-stream';
  234. block.transport.options.server = options.host + "/mkblk/" + (block.end - block.start);
  235. block.transport.options.sendAsBinary = true;
  236. block.transport.options.formData = false;
  237. }
  238. } );
  239. uploader.onUploadProgress = function ( file , percentage ) {
  240. var $li = $ ( '#' + file.id ) ,
  241. $percent = $li.find ( '.progress span' );
  242. $percent.css ( 'width' , percentage * 100 + '%' );
  243. percentages[file.id][1] = percentage;
  244. updateTotalProgress ();
  245. };
  246. uploader.on ( "uploadAccept" , function ( block , ret ) {
  247. //ctx[block.chunk] = ret.ctx;
  248. m.get ( block.file.name )[block.chunk] = ret.ctx;
  249. } );
  250. uploader.on ( "uploadSuccess" , function ( file , res ) {
  251. //成功之后,给li加上key值
  252. $ ( '#' + file.id ).attr ( 'dataSrc' , res.key );
  253. if ( parseInt ( file.size ) <= parseInt ( uploader.options.chunkSize ) ) {//大于就分片,小于就完毕
  254. UploadComplete ( file , res );
  255. } else {
  256. MakeFile ( m.get ( file.name ) , file , options.hash );
  257. }
  258. } );
  259. uploader.on ( 'all' , function ( type ) {
  260. var stats;
  261. switch ( type ) {
  262. case 'uploadFinished'://都结束了
  263. $ ( '.form-horizontal button[type="submit"]' ).attr ( 'disabled' , false ).css ( { "cursor": "pointer" } ).attr ( 'title' , '' );
  264. setState ( 'confirm' );
  265. break;
  266. case 'startUpload'://开始上传
  267. $ ( '.form-horizontal button[type="submit"]' ).attr ( 'disabled' , true ).css ( { "cursor": " no-drop" } ).attr ( 'title' , '上传文件中...' );
  268. setState ( 'uploading' );
  269. break;
  270. case 'stopUpload'://暂停上传
  271. $ ( '.form-horizontal button[type="submit"]' ).attr ( 'disabled' , true ).css ( { "cursor": " no-drop" } ).attr ( 'title' , '上传文件暂停...' );
  272. setState ( 'paused' );
  273. break;
  274. }
  275. } );
  276. uploader.on ( "fileDequeued" , function ( file , res ) {
  277. fileCount--;
  278. fileSize -= file.size;
  279. if ( !fileCount ) {
  280. setState ( 'pedding' );
  281. }
  282. removeFile ( file );
  283. updateTotalProgress ();
  284. } );
  285. $upload.on ( 'click' , function () {
  286. if ( $ ( this ).hasClass ( 'disabled' ) ) {
  287. return false;
  288. }
  289. if ( state === 'ready' ) {
  290. uploader.upload ();
  291. } else if ( state === 'paused' ) {
  292. uploader.upload ();
  293. } else if ( state === 'uploading' ) {
  294. uploader.stop ( true );
  295. }
  296. } );
  297. $info.on ( 'click' , '.retry' , function () {
  298. uploader.retry ();
  299. } );
  300. $info.on ( 'click' , '.ignore' , function () {
  301. swal ( '已忽略' , '' , 'error' ).then ( function () {
  302. } );
  303. } );
  304. $upload.addClass ( 'state-' + state );
  305. function GetToken ( tokenUrl , file ) {
  306. $.ajax ( {
  307. async: false ,
  308. type: 'get' ,
  309. url: tokenUrl ,
  310. dataType: 'json' ,
  311. data: {
  312. disk: disk
  313. } ,
  314. success: function ( res ) {
  315. if ( res.code ) {
  316. token = res.uptoken;
  317. if ( options.hash ) {
  318. uploader.options.formData = {
  319. token: token ,
  320. }
  321. } else {
  322. uploader.options.formData = {
  323. token: token ,
  324. key: file.name
  325. }
  326. }
  327. } else {
  328. swal ( res.msg , '' , 'error' ).then ( function () {
  329. } );
  330. throw '获取token错误';
  331. }
  332. }
  333. } );
  334. }
  335. function MakeFile ( ctx , file , hash ) {
  336. var b = ctx.join ( "," );
  337. if ( hash ) {//key固定
  338. $.ajax ( {
  339. headers: {
  340. 'X-CSRF-TOKEN': $ ( 'meta[name="csrf-token"]' ).attr ( 'content' ) ,
  341. 'file-id': file.id ,
  342. 'file-ext': file.source.ext ,
  343. 'disk': disk
  344. } ,
  345. type: 'POST' ,
  346. url: options.host + '/mkfile/' + file.size ,
  347. data: b ,
  348. contentType: "text/plain" ,
  349. contentLength: b.length ,
  350. beforeSend: function ( XMLHttpRequest ) {
  351. XMLHttpRequest.setRequestHeader ( "Authorization" , 'UpToken ' + token );
  352. } ,
  353. success: function ( res ) {
  354. UploadComplete ( file , res );
  355. }
  356. } );
  357. } else {//key不固定
  358. $.ajax ( {
  359. headers: {
  360. 'X-CSRF-TOKEN': $ ( 'meta[name="csrf-token"]' ).attr ( 'content' ) ,
  361. 'file-id': file.id ,
  362. 'file-ext': file.source.ext ,
  363. 'disk': disk
  364. } ,
  365. type: 'POST' ,
  366. url: options.host + '/mkfile/' + file.size + '/key/' + URLSafeBase64Encode ( uploader.options.formData.key ) ,
  367. data: b ,
  368. contentType: "text/plain" ,
  369. contentLength: b.length ,
  370. beforeSend: function ( XMLHttpRequest ) {
  371. XMLHttpRequest.setRequestHeader ( "Authorization" , 'UpToken ' + token );
  372. } ,
  373. success: function ( res ) {
  374. UploadComplete ( file , res );
  375. }
  376. } );
  377. }
  378. }
  379. function UploadComplete ( file , res ) {
  380. if ( window.chunk_file.fileNumLimit <= 1 ) {
  381. $ ( '#' + name + '-savedpath' ).val ( window.chunk_file.url + '/' + res.key );
  382. } else {
  383. if ( window.chunk_file.saveType == 'json' ) {//为json类型
  384. if ( initVal ) {//如果初始有数据
  385. $ ( '#' + name + '-savedpath' ).val ( '' );
  386. initVal = false;//然后置false
  387. }
  388. //先拿出来
  389. var data = $ ( '#' + name + '-savedpath' ).val ();
  390. if ( !data ) {//为空
  391. data = new Array ();
  392. data.push ( res.key );
  393. } else {
  394. try {
  395. data = JSON.parse ( data );
  396. } catch ( e ) {
  397. data = new Array ();
  398. }
  399. data.push ( res.key );
  400. }
  401. $ ( '#' + name + '-savedpath' ).val ( JSON.stringify ( data ) );
  402. }
  403. }
  404. ctx = new Array ();
  405. uploader.options.chunked = true;
  406. }
  407. function URLSafeBase64Decode ( data ) {
  408. data = data.replace ( /_/g , '/' ).replace ( /-/g , '+' );
  409. var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  410. var o1 , o2 , o3 , h1 , h2 , h3 , h4 , bits , i = 0 ,
  411. ac = 0 ,
  412. dec = "" ,
  413. tmp_arr = [];
  414. if ( !data ) {
  415. return data;
  416. }
  417. data += '';
  418. do { // unpack four hexets into three octets using index points in b64
  419. h1 = b64.indexOf ( data.charAt ( i++ ) );
  420. h2 = b64.indexOf ( data.charAt ( i++ ) );
  421. h3 = b64.indexOf ( data.charAt ( i++ ) );
  422. h4 = b64.indexOf ( data.charAt ( i++ ) );
  423. bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
  424. o1 = bits >> 16 & 0xff;
  425. o2 = bits >> 8 & 0xff;
  426. o3 = bits & 0xff;
  427. if ( h3 === 64 ) {
  428. tmp_arr[ac++] = String.fromCharCode ( o1 );
  429. } else if ( h4 === 64 ) {
  430. tmp_arr[ac++] = String.fromCharCode ( o1 , o2 );
  431. } else {
  432. tmp_arr[ac++] = String.fromCharCode ( o1 , o2 , o3 );
  433. }
  434. } while ( i < data.length );
  435. dec = tmp_arr.join ( '' );
  436. return dec;
  437. }
  438. function utf8_encode ( argString ) {
  439. if ( argString === null || typeof argString === 'undefined' ) {
  440. return '';
  441. }
  442. var string = (argString + ''); // .replace(/\r\n/g, '\n').replace(/\r/g, '\n');
  443. var utftext = '' ,
  444. start , end , stringl = 0;
  445. start = end = 0;
  446. stringl = string.length;
  447. for ( var n = 0 ; n < stringl ; n++ ) {
  448. var c1 = string.charCodeAt ( n );
  449. var enc = null;
  450. if ( c1 < 128 ) {
  451. end++;
  452. } else if ( c1 > 127 && c1 < 2048 ) {
  453. enc = String.fromCharCode (
  454. (c1 >> 6) | 192 , (c1 & 63) | 128
  455. );
  456. } else if ( c1 & 0xF800 ^ 0xD800 > 0 ) {
  457. enc = String.fromCharCode (
  458. (c1 >> 12) | 224 , ((c1 >> 6) & 63) | 128 , (c1 & 63) | 128
  459. );
  460. } else { // surrogate pairs
  461. if ( c1 & 0xFC00 ^ 0xD800 > 0 ) {
  462. throw new RangeError ( 'Unmatched trail surrogate at ' + n );
  463. }
  464. var c2 = string.charCodeAt ( ++n );
  465. if ( c2 & 0xFC00 ^ 0xDC00 > 0 ) {
  466. throw new RangeError ( 'Unmatched lead surrogate at ' + (n - 1) );
  467. }
  468. c1 = ((c1 & 0x3FF) << 10) + (c2 & 0x3FF) + 0x10000;
  469. enc = String.fromCharCode (
  470. (c1 >> 18) | 240 , ((c1 >> 12) & 63) | 128 , ((c1 >> 6) & 63) | 128 , (c1 & 63) | 128
  471. );
  472. }
  473. if ( enc !== null ) {
  474. if ( end > start ) {
  475. utftext += string.slice ( start , end );
  476. }
  477. utftext += enc;
  478. start = end = n + 1;
  479. }
  480. }
  481. if ( end > start ) {
  482. utftext += string.slice ( start , stringl );
  483. }
  484. return utftext;
  485. }
  486. function URLSafeBase64Encode ( data ) {
  487. var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
  488. var o1 , o2 , o3 , h1 , h2 , h3 , h4 , bits , i = 0 ,
  489. ac = 0 ,
  490. enc = '' ,
  491. tmp_arr = [];
  492. if ( !data ) {
  493. return data;
  494. }
  495. data = utf8_encode ( data + '' );
  496. do { // pack three octets into four hexets
  497. o1 = data.charCodeAt ( i++ );
  498. o2 = data.charCodeAt ( i++ );
  499. o3 = data.charCodeAt ( i++ );
  500. bits = o1 << 16 | o2 << 8 | o3;
  501. h1 = bits >> 18 & 0x3f;
  502. h2 = bits >> 12 & 0x3f;
  503. h3 = bits >> 6 & 0x3f;
  504. h4 = bits & 0x3f;
  505. // use hexets to index into b64, and append result to encoded string
  506. tmp_arr[ac++] = b64.charAt ( h1 ) + b64.charAt ( h2 ) + b64.charAt ( h3 ) + b64.charAt ( h4 );
  507. } while ( i < data.length );
  508. enc = tmp_arr.join ( '' );
  509. switch ( data.length % 3 ) {
  510. case 1:
  511. enc = enc.slice ( 0 , -2 ) + '==';
  512. break;
  513. case 2:
  514. enc = enc.slice ( 0 , -1 ) + '=';
  515. break;
  516. }
  517. return enc.replace ( /\//g , '_' ).replace ( /\+/g , '-' );
  518. }
  519. // 当有文件添加进来时执行,负责view的创建
  520. function addFile ( file ) {
  521. var $li = $ ( '<li id="' + file.id + '">' +
  522. '<p class="title">' + file.name + '</p>' +
  523. '<p class="imgWrap"></p>' +
  524. '<p class="progress"><span></span></p>' +
  525. '</li>' ) ,
  526. $btns = $ ( '<div class="file-panel">' +
  527. '<span class="cancel">删除</span>' +
  528. '<span class="rotateRight">向右旋转</span>' +
  529. '<span class="rotateLeft">向左旋转</span></div>' ).appendTo ( $li ) ,
  530. $prgress = $li.find ( 'p.progress span' ) ,
  531. $wrap = $li.find ( 'p.imgWrap' ) ,
  532. $info = $ ( '<p class="error"></p>' ) ,
  533. showError = function ( code ) {
  534. switch ( code ) {
  535. case 'exceed_size':
  536. text = '文件大小超出';
  537. break;
  538. case 'interrupt':
  539. text = '上传暂停';
  540. break;
  541. default:
  542. text = '上传失败,请重试';
  543. break;
  544. }
  545. $info.text ( text ).appendTo ( $li );
  546. };
  547. if ( file.getStatus () === 'invalid' ) {
  548. showError ( file.statusText );
  549. } else {
  550. // @todo lazyload
  551. $wrap.text ( '预览中' );
  552. uploader.makeThumb ( file , function ( error , src ) {
  553. var img;
  554. if ( error ) {
  555. $wrap.text ( '不能预览' );
  556. return;
  557. }
  558. if ( isSupportBase64 ) {
  559. img = $ ( '<img src="' + src + '">' );
  560. $wrap.empty ().append ( img );
  561. } else {
  562. $wrap.text ( "预览出错" );
  563. }
  564. } , thumbnailWidth , thumbnailHeight );
  565. percentages[file.id] = [file.size , 0];
  566. file.rotation = 0;
  567. }
  568. file.on ( 'statuschange' , function ( cur , prev ) {
  569. if ( prev === 'progress' ) {
  570. $prgress.hide ().width ( 0 );
  571. } else if ( prev === 'queued' ) {
  572. // $li.off ( 'mouseenter mouseleave' );
  573. // $btns.remove ();//暂时不删除
  574. }
  575. // 成功
  576. if ( cur === 'error' || cur === 'invalid' ) {
  577. showError ( file.statusText );
  578. percentages[file.id][1] = 1;
  579. } else if ( cur === 'interrupt' ) {
  580. showError ( 'interrupt' );
  581. } else if ( cur === 'queued' ) {
  582. percentages[file.id][1] = 0;
  583. } else if ( cur === 'progress' ) {
  584. $info.remove ();
  585. $prgress.css ( 'display' , 'block' );
  586. } else if ( cur === 'complete' ) {
  587. //这是成功了
  588. $li.append ( '<span class="success"></span>' );
  589. }
  590. $li.removeClass ( 'state-' + prev ).addClass ( 'state-' + cur );
  591. } );
  592. $li.on ( 'mouseenter' , function () {
  593. $btns.stop ().animate ( { height: 30 } );
  594. } );
  595. $li.on ( 'mouseleave' , function () {
  596. $btns.stop ().animate ( { height: 0 } );
  597. } );
  598. $btns.on ( 'click' , 'span' , function () {
  599. var index = $ ( this ).index () ,
  600. deg;
  601. switch ( index ) {
  602. case 0:
  603. uploader.removeFile ( file );
  604. return;
  605. case 1:
  606. file.rotation += 90;
  607. break;
  608. case 2:
  609. file.rotation -= 90;
  610. break;
  611. }
  612. if ( supportTransition ) {
  613. deg = 'rotate(' + file.rotation + 'deg)';
  614. $wrap.css ( {
  615. '-webkit-transform': deg ,
  616. '-mos-transform': deg ,
  617. '-o-transform': deg ,
  618. 'transform': deg
  619. } );
  620. } else {
  621. $wrap.css ( 'filter' , 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + (~~((file.rotation / 90) % 4 + 4) % 4) + ')' );
  622. }
  623. } );
  624. $li.appendTo ( $queue );
  625. }
  626. // 负责view的销毁
  627. function removeFile ( file ) {
  628. var $li = $ ( '#' + file.id );
  629. delete percentages[file.id];
  630. updateTotalProgress ();
  631. $li.off ().find ( '.file-panel' ).off ().end ().remove ();
  632. //然后删除数组文件
  633. var dataSrc = $li.attr ( 'dataSrc' );
  634. var data = $ ( '#' + name + '-savedpath' ).val ();
  635. if ( data ) {//不为空
  636. try {
  637. data = JSON.parse ( data );
  638. } catch ( e ) {
  639. data = new Array ();
  640. }
  641. for ( var i = 0 ; i < data.length ; i++ ) {
  642. if ( dataSrc == data[i] ) {
  643. data.splice ( i , 1 );
  644. }
  645. }
  646. if ( !data.length ) {
  647. data = '';
  648. } else {
  649. data = JSON.stringify ( data );
  650. }
  651. $ ( '#' + name + '-savedpath' ).val ( data );
  652. }
  653. }
  654. function setState ( val ) {
  655. var file , stats;
  656. if ( val === state ) {
  657. return;
  658. }
  659. $upload.removeClass ( 'state-' + state );
  660. $upload.addClass ( 'state-' + val );
  661. state = val;
  662. switch ( state ) {
  663. case 'pedding':
  664. $placeHolder.removeClass ( 'element-invisible' );
  665. $queue.hide ();
  666. $statusBar.addClass ( 'element-invisible' );
  667. uploader.refresh ();
  668. break;
  669. case 'ready':
  670. $placeHolder.addClass ( 'element-invisible' );
  671. $ ( '#filePicker2' + name ).removeClass ( 'element-invisible' );
  672. $queue.show ();
  673. $statusBar.removeClass ( 'element-invisible' );
  674. uploader.refresh ();
  675. break;
  676. case 'uploading':
  677. $ ( '#filePicker2' + name ).addClass ( 'element-invisible' );
  678. $progress.show ();
  679. $upload.text ( '暂停上传' );
  680. break;
  681. case 'paused':
  682. $progress.show ();
  683. $upload.text ( '继续上传' );
  684. break;
  685. case 'confirm':
  686. $progress.hide ();
  687. $ ( '#filePicker2' + name ).removeClass ( 'element-invisible' );
  688. $upload.text ( '开始上传' );
  689. stats = uploader.getStats ();
  690. if ( stats.successNum && !stats.uploadFailNum ) {
  691. setState ( 'finish' );
  692. return;
  693. }
  694. break;
  695. case 'finish':
  696. stats = uploader.getStats ();
  697. if ( stats.successNum ) {
  698. swal ( '上传成功' , '' , 'success' ).then ( function () {
  699. } );
  700. } else {
  701. // 没有成功的图片,重设
  702. state = 'done';
  703. location.reload ();
  704. }
  705. break;
  706. }
  707. updateStatus ();
  708. }
  709. function updateStatus () {
  710. var text = '' , stats;
  711. if ( state === 'ready' ) {
  712. text = '选中' + fileCount + '张图片,共' +
  713. WebUploader.formatSize ( fileSize ) + '。';
  714. } else if ( state === 'confirm' ) {
  715. stats = uploader.getStats ();
  716. if ( stats.uploadFailNum ) {
  717. text = '已成功上传' + stats.successNum + '张照片至XX相册,' +
  718. stats.uploadFailNum + '张照片上传失败,<a class="retry" href="#">重新上传</a>失败图片或<a class="ignore" href="#">忽略</a>'
  719. }
  720. } else {
  721. stats = uploader.getStats ();
  722. text = '共' + fileCount + '张(' +
  723. WebUploader.formatSize ( fileSize ) +
  724. '),已上传' + stats.successNum + '张';
  725. if ( stats.uploadFailNum ) {
  726. text += ',失败' + stats.uploadFailNum + '张';
  727. }
  728. }
  729. $info.html ( text );
  730. }
  731. function updateTotalProgress () {
  732. var loaded = 0 ,
  733. total = 0 ,
  734. spans = $progress.children () ,
  735. percent;
  736. $.each ( percentages , function ( k , v ) {
  737. total += v[0];
  738. loaded += v[0] * v[1];
  739. } );
  740. percent = total ? loaded / total : 0;
  741. spans.eq ( 0 ).text ( Math.round ( percent * 100 ) + '%' );
  742. spans.eq ( 1 ).css ( 'width' , Math.round ( percent * 100 ) + '%' );
  743. updateStatus ();
  744. }
  745. $ ( '#' + name + '-savedpath' ).css ( 'cursor' , 'pointer' )
  746. $ ( document ).on ( 'click' , '#' + name + '-savedpath' , function () {
  747. window.open ( $ ( this ).val () );
  748. } );
  749. return uploader;
  750. }