excel.upload.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803
  1. function timeD(time) {
  2. let t=Date.parse(time)+(43*1000);
  3. console.log(t);
  4. let d = new Date(t);
  5. let data = d.getFullYear()+'-'+timeP(d.getMonth() + 1)+'-'+timeP(d.getDate())+' '+timeP(d.getHours())+':'+timeP(d.getMinutes())+':'+ this.timeP(d.getSeconds());
  6. return data;
  7. }
  8. // 补0
  9. function timeP(s) {
  10. return s < 10 ? '0' + s : s
  11. }
  12. var fileReader = new FileReader();
  13. fileReader.headArray=[];
  14. var headType={
  15. 'String':'文本',
  16. 'Int64':'整数',
  17. 'Float64':'小数',
  18. 'Date':'日期',
  19. }
  20. fileReader.isRight=function (str, type) {
  21. var t = type || 0;
  22. var patn = /^[0-9]+$/;
  23. if (t == 1) {
  24. patn = /^\d+(\.\d+)?$/;
  25. }
  26. else if (t == 2) {
  27. patn = /^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-)) (20|21|22|23|[0-1]?\d):[0-5]?\d:[0-5]?\d$/;
  28. }
  29. if (!patn.test(str)) return false;
  30. return true;
  31. }
  32. fileReader.onload = function(ev) {
  33. try {
  34. var data = ev.target.result
  35. var workbook = XLSX.read(data, {
  36. type: 'binary',
  37. cellDates: true
  38. }) // 以二进制流方式读取得到整份excel表格对象
  39. var persons = []; // 存储获取到的数据
  40. } catch (e) {
  41. console.log('文件类型不正确');
  42. return;
  43. }
  44. // 表格的表格范围,可用于判断表头是否数量是否正确
  45. var fromTo = '';
  46. // 遍历每张表读取
  47. for (var sheet in workbook.Sheets) {
  48. if (workbook.Sheets.hasOwnProperty(sheet)) {
  49. fromTo = workbook.Sheets[sheet]['!ref'];
  50. console.log(fromTo);
  51. const sheet2JSONOpts = {
  52. defval: '-'//给defval赋值为空的字符串
  53. }
  54. persons = persons.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet],sheet2JSONOpts));
  55. // break; // 如果只取第一张表,就取消注释这行
  56. }
  57. }
  58. //在控制台打印出来表格中的数据
  59. var cell=0;
  60. for(var j=0;j<persons.length;j++){
  61. var arr=persons[j];
  62. if(j==0){
  63. $("#tablehead").append("<tr class='exceltitle'></tr>");
  64. }
  65. $("#tablebody").append("<tr class='excelcontent'></tr>");
  66. var k=0;
  67. for (var i in arr) {
  68. if(j==0){
  69. var itemType='未知';
  70. if(fileReader.headArray[cell]){
  71. itemType = headType[fileReader.headArray[cell].type];
  72. }
  73. $(".exceltitle").append("<th>"+i+"<strong>["+itemType+"]</strong></th>");
  74. cell++;
  75. }
  76. var isRight='',errorTips='';
  77. if(fileReader.headArray[k]){
  78. if(fileReader.headArray[k].type=='int'){
  79. isRight = fileReader.isRight(arr[i],0)?'':'error';
  80. errorTips = fileReader.isRight(arr[i],0)?'':'错误的数据';
  81. }
  82. else if(fileReader.headArray[k].type=='float'){
  83. isRight = fileReader.isRight(arr[i],1)?'':'error';
  84. errorTips = fileReader.isRight(arr[i],0)?'':'错误的数据';
  85. }
  86. else if(fileReader.headArray[k].type=='date'){
  87. console.log(arr[i]);
  88. if(arr[i] instanceof Date)
  89. {
  90. arr[i] = timeD(arr[i]);
  91. }else{
  92. isRight ='error';
  93. errorTips = fileReader.isRight(arr[i],0)?'':'错误的数据';
  94. }
  95. }
  96. }
  97. $(".excelcontent").eq(j).append("<td class='"+isRight+"' title='"+errorTips+"'>"+arr[i]+"</td>");
  98. k++;
  99. }
  100. console.log(cell);
  101. if(fileReader.headArray.length!=cell){
  102. $("#tablebody").html('').append("<tr class='excelcontent'><td colspan='"+cell+"' style='padding:20px 0;font-weight:600; color:#EB4336'>EXCEL表格数据与创建的数据表信息不匹配,请编辑EXCEL表格数据或者数据表信息后重新上传</td></tr>");
  103. layer.msg('EXCEL表格数据与创建的数据表信息不匹配');
  104. break;
  105. }
  106. if(j>15){
  107. break;
  108. }
  109. }
  110. };
  111. function uploadExcel(options) {
  112. var settings = {
  113. url:'',
  114. data:{},
  115. choose:function(obj){
  116. console.log('选择完成');
  117. console.log(obj);
  118. },
  119. before:function(obj){
  120. console.log('上传前');
  121. console.log(obj);
  122. },
  123. done: function(res, index, upload){
  124. console.log('上传成功');
  125. console.log(res);
  126. },
  127. allDone: function(obj){
  128. console.log('多文件上传回调');
  129. console.log(obj);
  130. },
  131. error: function (index, upload) {
  132. console.log('上传失败');
  133. console.log(index);
  134. },
  135. progress: function(n, elem){
  136. console.log('上传进度');
  137. var percent = n + '%'
  138. }
  139. };
  140. ops = $.extend({}, settings, options);
  141. var contentHtml = '<div class="upload-file-title" id="readyfile"><div id="uploadTitle"><span id="selectfiles" class="upload-select-btn">选择文件</span>请选择<strong>xls,xlsx</strong>格式的文件上传,<span class="upload-file-tips">注意:您可以上传大小10M以内的文件。</span><span id="postfiles" style="display:none;">上传</span></div></div>\
  142. <div class="upload-file-box"><table class="upload-file-table" width="100%"><thead id="tablehead" class="tablehead"></thead><tbody id="tablebody" class="tablebody"></tbody></table></div>';
  143. var tableHeight=window.innerHeight-60;
  144. layer.open({
  145. title: '<strong>上传数据</strong>',
  146. type: '1',
  147. area: ['1226px', tableHeight+'px'],
  148. content: '<div><div class="box-contact-info">' + contentHtml + '</div></div>',
  149. success: function (obj, layerIndex) {
  150. var demoListView=$('#readyfile'),
  151. uploadListIns = upload.render({
  152. elem: '#selectfiles'
  153. , url: 'http://i.slambase.cn:8081/v1/file'
  154. , accept: 'file'
  155. , acceptMime:'.xls,.xlsx,.csv'
  156. , exts:'xls|xlsx|csv'
  157. , auto: false
  158. , size: 10*1024
  159. , bindAction: '#postfiles'
  160. , file:'fileName'
  161. , data: {'user_id':options.data.user_id,'table_name':options.data.table_name}
  162. , choose: function (obj) {
  163. //读取本地文件
  164. obj.preview(function (index, file, result) {
  165. // 以二进制方式打开文件
  166. $("#tablehead").append("");
  167. $("#tablebody").append("");
  168. fileReader.headArray=ops.data.table_schema;
  169. fileReader.readAsBinaryString(file);
  170. var tr = $(['<div class="file-info" id="upload' + index + '">'
  171. , '<span>文件名称:<i>' + file.name + '</i></span>'
  172. , '<span>进度:<i id="progress_' + index + '">0%</i></span>'
  173. , '<span>大小:<i>' + (file.size / (1024 * 1024)).toFixed(1) + 'MB</i></span>'
  174. , '<span>状态:<i id="status_' + index + '">数据预览</i></span>'
  175. , '<span class="file-delete">重新选择</span>'
  176. ,'<span class="upload-post-btn">开始上传</span>'
  177. , '</div>'].join(''));
  178. //删除
  179. tr.find('.file-delete').on('click', function () {
  180. tr.remove();
  181. $('#uploadTitle').show();
  182. $("#tablehead").html("");
  183. $("#tablebody").html("");
  184. uploadListIns.config.elem.next()[0].value = ''; //清空 input file 值,以免删除后出现同名文件不可选
  185. });
  186. //上传
  187. tr.find('.upload-post-btn').on('click', function () {
  188. // alert('上传的参数为:'+JSON.stringify(ops.data))
  189. $('#postfiles').click();
  190. });
  191. $('#uploadTitle').hide();
  192. demoListView.append(tr);
  193. $("#tablehead").html("");
  194. $("#tablebody").html("");
  195. });
  196. }
  197. , done: function (res, index, upload) {
  198. if (res.code == 1) { //上传成功
  199. layer.msg('上传成功');
  200. }
  201. },
  202. progress: function (index, file, percent) {
  203. $('#progress_' + index).html(percent * 100 + '%');
  204. $('#status_' + index).html('上传中...');
  205. console.log(percent);
  206. }
  207. , error: function (index, upload) {
  208. $('#progress_' + index).html('0%');
  209. $('#status_' + index).html('上传失败,请重试');
  210. }
  211. });
  212. }
  213. });
  214. }
  215. var upload = {
  216. config: {} //全局配置项
  217. //设置全局项
  218. ,set: function(options){
  219. var that = this;
  220. that.config = $.extend({}, that.config, options);
  221. return that;
  222. }
  223. }
  224. ,device = function(key){
  225. var agent = navigator.userAgent.toLowerCase()
  226. //获取版本号
  227. ,getVersion = function(label){
  228. var exp = new RegExp(label + '/([^\\s\\_\\-]+)');
  229. label = (agent.match(exp)||[])[1];
  230. return label || false;
  231. }
  232. //返回结果集
  233. ,result = {
  234. os: function(){ //底层操作系统
  235. if(/windows/.test(agent)){
  236. return 'windows';
  237. } else if(/linux/.test(agent)){
  238. return 'linux';
  239. } else if(/iphone|ipod|ipad|ios/.test(agent)){
  240. return 'ios';
  241. } else if(/mac/.test(agent)){
  242. return 'mac';
  243. }
  244. }()
  245. ,ie: function(){ //ie版本
  246. return (!!win.ActiveXObject || "ActiveXObject" in win) ? (
  247. (agent.match(/msie\s(\d+)/) || [])[1] || '11' //由于ie11并没有msie的标识
  248. ) : false;
  249. }()
  250. ,weixin: getVersion('micromessenger') //是否微信
  251. };
  252. //任意的key
  253. if(key && !result[key]){
  254. result[key] = getVersion(key);
  255. }
  256. //移动设备
  257. result.android = /android/.test(agent);
  258. result.ios = result.os === 'ios';
  259. result.mobile = (result.android || result.ios) ? true : false;
  260. return result;
  261. }
  262. //操作当前实例
  263. ,thisUpload = function(){
  264. var that = this;
  265. return {
  266. upload: function(files){
  267. that.upload.call(that, files);
  268. }
  269. ,reload: function(options){
  270. that.reload.call(that, options);
  271. }
  272. ,config: that.config
  273. }
  274. }
  275. //字符常量
  276. ,MOD_NAME = 'upload', ELEM = '.layui-upload', THIS = 'layui-this', SHOW = 'layui-show', HIDE = 'layui-hide', DISABLED = 'layui-disabled'
  277. ,ELEM_FILE = 'layui-upload-file', ELEM_FORM = 'layui-upload-form', ELEM_IFRAME = 'layui-upload-iframe', ELEM_CHOOSE = 'layui-upload-choose', ELEM_DRAG = 'layui-upload-drag'
  278. //构造器
  279. ,Class = function(options){
  280. var that = this;
  281. that.config = $.extend({}, that.config, upload.config, options);
  282. that.render();
  283. };
  284. //默认配置
  285. Class.prototype.config = {
  286. accept: 'images' //允许上传的文件类型:images/file/video/audio
  287. ,exts: '' //允许上传的文件后缀名
  288. ,auto: false //是否选完文件后自动上传
  289. ,bindAction: '' //手动上传触发的元素
  290. ,url: '' //上传地址
  291. ,field: 'file' //文件字段名
  292. ,acceptMime: '' //筛选出的文件类型,默认为所有文件
  293. ,method: 'post' //请求上传的 http 类型
  294. ,data: {} //请求上传的额外参数
  295. ,drag: true //是否允许拖拽上传
  296. ,size: 0 //文件限制大小,默认不限制
  297. ,number: 0 //允许同时上传的文件数,默认不限制
  298. ,multiple: false //是否允许多文件上传,不支持ie8-9
  299. };
  300. //初始渲染
  301. Class.prototype.render = function(options){
  302. var that = this
  303. ,options = that.config;
  304. options.elem = $(options.elem);
  305. options.bindAction = $(options.bindAction);
  306. that.file();
  307. that.events();
  308. };
  309. //追加文件域
  310. Class.prototype.file = function(){
  311. var that = this
  312. ,options = that.config
  313. ,elemFile = that.elemFile = $([
  314. '<input class="'+ ELEM_FILE +'" type="file" accept="'+ options.acceptMime +'" name="'+ options.field +'"'
  315. ,(options.multiple ? ' multiple' : '')
  316. ,'>'
  317. ].join(''))
  318. ,next = options.elem.next();
  319. if(next.hasClass(ELEM_FILE) || next.hasClass(ELEM_FORM)){
  320. next.remove();
  321. }
  322. //包裹ie8/9容器
  323. if(device.ie && device.ie < 10){
  324. options.elem.wrap('<div class="layui-upload-wrap"></div>');
  325. }
  326. that.isFile() ? (
  327. that.elemFile = options.elem
  328. ,options.field = options.elem[0].name
  329. ) : options.elem.after(elemFile);
  330. //初始化ie8/9的Form域
  331. if(device.ie && device.ie < 10){
  332. that.initIE();
  333. }
  334. };
  335. //ie8-9初始化
  336. Class.prototype.initIE = function(){
  337. var that = this
  338. ,options = that.config
  339. ,iframe = $('<iframe id="'+ ELEM_IFRAME +'" class="'+ ELEM_IFRAME +'" name="'+ ELEM_IFRAME +'" frameborder="0"></iframe>')
  340. ,elemForm = $(['<form target="'+ ELEM_IFRAME +'" class="'+ ELEM_FORM +'" method="post" key="set-mine" enctype="multipart/form-data" action="'+ options.url +'">'
  341. ,'</form>'].join(''));
  342. //插入iframe
  343. $('#'+ ELEM_IFRAME)[0] || $('body').append(iframe);
  344. //包裹文件域
  345. if(!options.elem.next().hasClass(ELEM_FORM)){
  346. that.elemFile.wrap(elemForm);
  347. //追加额外的参数
  348. options.elem.next('.'+ ELEM_FORM).append(function(){
  349. var arr = [];
  350. $.each(options.data, function(key, value){
  351. value = typeof value === 'function' ? value() : value;
  352. arr.push('<input type="hidden" name="'+ key +'" value="'+ value +'">')
  353. });
  354. return arr.join('');
  355. }());
  356. }
  357. };
  358. //异常提示
  359. Class.prototype.msg = function(content){
  360. alert(content);
  361. };
  362. //判断绑定元素是否为文件域本身
  363. Class.prototype.isFile = function(){
  364. var elem = this.config.elem[0];
  365. if(!elem) return;
  366. return elem.tagName.toLocaleLowerCase() === 'input' && elem.type === 'file'
  367. }
  368. //预读图片信息
  369. Class.prototype.preview = function(callback){
  370. var that = this;
  371. if(window.FileReader){
  372. $.each(that.chooseFiles, function(index, file){
  373. var reader = new FileReader();
  374. reader.readAsDataURL(file);
  375. reader.onload = function(){
  376. callback && callback(index, file, this.result);
  377. }
  378. });
  379. }
  380. };
  381. //执行上传
  382. Class.prototype.upload = function(files, type){
  383. var that = this
  384. ,options = that.config
  385. ,elemFile = that.elemFile[0]
  386. //高级浏览器处理方式,支持跨域
  387. ,ajaxSend = function(){
  388. var successful = 0, aborted = 0
  389. ,items = files || that.files || that.chooseFiles || elemFile.files
  390. ,allDone = function(){ //多文件全部上传完毕的回调
  391. if(options.multiple && successful + aborted === that.fileLength){
  392. typeof options.allDone === 'function' && options.allDone({
  393. total: that.fileLength
  394. ,successful: successful
  395. ,aborted: aborted
  396. });
  397. }
  398. };
  399. $.each(items, function(index, file){
  400. var formData = new FormData();
  401. formData.append(options.field, file);
  402. //追加额外的参数
  403. $.each(options.data, function(key, value){
  404. value = typeof value === 'function' ? value() : value;
  405. formData.append(key, value);
  406. });
  407. //提交文件
  408. var opts = {
  409. url: options.url
  410. ,type: 'post' //统一采用 post 上传
  411. ,data: formData
  412. ,contentType: false
  413. ,processData: false
  414. ,dataType: 'json'
  415. ,headers: options.headers || {}
  416. //成功回调
  417. ,success: function(res){
  418. successful++;
  419. done(index, res);
  420. allDone();
  421. }
  422. //异常回调
  423. ,error: function(){
  424. aborted++;
  425. that.msg('请求上传接口出现异常');
  426. error(index);
  427. allDone();
  428. }
  429. };
  430. //监听进度条
  431. if(typeof options.progress === 'function'){
  432. opts.xhr = function(){
  433. var xhr = $.ajaxSettings.xhr();
  434. //监听上传进度
  435. xhr.upload.addEventListener("progress", function (e) {
  436. if(e.lengthComputable) {
  437. var percent = Math.floor((e.loaded/e.total)* 100); //百分比
  438. options.progress(percent, options.item[0], e);
  439. }
  440. });
  441. return xhr;
  442. }
  443. }
  444. $.ajax(opts);
  445. });
  446. }
  447. //低版本IE处理方式,不支持跨域
  448. ,iframeSend = function(){
  449. var iframe = $('#'+ ELEM_IFRAME);
  450. that.elemFile.parent().submit();
  451. //获取响应信息
  452. clearInterval(Class.timer);
  453. Class.timer = setInterval(function() {
  454. var res, iframeBody = iframe.contents().find('body');
  455. try {
  456. res = iframeBody.text();
  457. } catch(e) {
  458. that.msg('获取上传后的响应信息出现异常');
  459. clearInterval(Class.timer);
  460. error();
  461. }
  462. if(res){
  463. clearInterval(Class.timer);
  464. iframeBody.html('');
  465. done(0, res);
  466. }
  467. }, 30);
  468. }
  469. //统一回调
  470. ,done = function(index, res){
  471. that.elemFile.next('.'+ ELEM_CHOOSE).remove();
  472. elemFile.value = '';
  473. if(typeof res !== 'object'){
  474. try {
  475. res = JSON.parse(res);
  476. } catch(e){
  477. res = {};
  478. return that.msg('请对上传接口返回有效JSON');
  479. }
  480. }
  481. typeof options.done === 'function' && options.done(res, index || 0, function(files){
  482. that.upload(files);
  483. });
  484. }
  485. //统一网络异常回调
  486. ,error = function(index){
  487. if(options.auto){
  488. elemFile.value = '';
  489. }
  490. typeof options.error === 'function' && options.error(index || 0, function(files){
  491. that.upload(files);
  492. });
  493. }
  494. ,exts = options.exts
  495. ,check ,value = function(){
  496. var arr = [];
  497. $.each(files || that.chooseFiles, function(i, item){
  498. arr.push(item.name);
  499. });
  500. return arr;
  501. }()
  502. //回调返回的参数
  503. ,args = {
  504. //预览
  505. preview: function(callback){
  506. that.preview(callback);
  507. }
  508. //上传
  509. ,upload: function(index, file){
  510. var thisFile = {};
  511. thisFile[index] = file;
  512. that.upload(thisFile);
  513. }
  514. //追加文件到队列
  515. ,pushFile: function(){
  516. that.files = that.files || {};
  517. $.each(that.chooseFiles, function(index, item){
  518. that.files[index] = item;
  519. });
  520. return that.files;
  521. }
  522. //重置文件
  523. ,resetFile: function(index, file, filename){
  524. var newFile = new File([file], filename);
  525. that.files = that.files || {};
  526. that.files[index] = newFile;
  527. }
  528. }
  529. //提交上传
  530. ,send = function(){
  531. //选择文件的回调
  532. if(type === 'choose' || options.auto){
  533. options.choose && options.choose(args);
  534. if(type === 'choose'){
  535. return;
  536. }
  537. }
  538. //上传前的回调
  539. options.before && options.before(args);
  540. //IE兼容处理
  541. if(device.ie){
  542. return device.ie > 9 ? ajaxSend() : iframeSend();
  543. }
  544. ajaxSend();
  545. }
  546. //校验文件格式
  547. value = value.length === 0
  548. ? ((elemFile.value.match(/[^\/\\]+\..+/g)||[]) || '')
  549. : value;
  550. if(value.length === 0) return;
  551. switch(options.accept){
  552. case 'file': //一般文件
  553. if(exts && !RegExp('\\w\\.('+ exts +')$', 'i').test(escape(value))){
  554. that.msg('选择的文件中包含不支持的格式');
  555. return elemFile.value = '';
  556. }
  557. break;
  558. case 'video': //视频文件
  559. if(!RegExp('\\w\\.('+ (exts || 'avi|mp4|wma|rmvb|rm|flash|3gp|flv') +')$', 'i').test(escape(value))){
  560. that.msg('选择的视频中包含不支持的格式');
  561. return elemFile.value = '';
  562. }
  563. break;
  564. case 'audio': //音频文件
  565. if(!RegExp('\\w\\.('+ (exts || 'mp3|wav|mid') +')$', 'i').test(escape(value))){
  566. that.msg('选择的音频中包含不支持的格式');
  567. return elemFile.value = '';
  568. }
  569. break;
  570. default: //图片文件
  571. $.each(value, function(i, item){
  572. if(!RegExp('\\w\\.('+ (exts || 'jpg|png|gif|bmp|jpeg$') +')', 'i').test(escape(item))){
  573. check = true;
  574. }
  575. });
  576. if(check){
  577. that.msg('选择的图片中包含不支持的格式');
  578. return elemFile.value = '';
  579. }
  580. break;
  581. }
  582. //检验文件数量
  583. that.fileLength = function(){
  584. var length = 0
  585. ,items = files || that.files || that.chooseFiles || elemFile.files;
  586. $.each(items, function(){
  587. length++;
  588. });
  589. return length;
  590. }();
  591. if(options.number && that.fileLength > options.number){
  592. return that.msg('同时最多只能上传的数量为:'+ options.number);
  593. }
  594. //检验文件大小
  595. if(options.size > 0 && !(device.ie && device.ie < 10)){
  596. var limitSize;
  597. $.each(that.chooseFiles, function(index, file){
  598. if(file.size > 1024*options.size){
  599. var size = options.size/1024;
  600. size = size >= 1 ? (size.toFixed(2) + 'MB') : options.size + 'KB'
  601. elemFile.value = '';
  602. limitSize = size;
  603. }
  604. });
  605. if(limitSize) return that.msg('文件不能超过'+ limitSize);
  606. }
  607. send();
  608. };
  609. //重置方法
  610. Class.prototype.reload = function(options){
  611. options = options || {};
  612. delete options.elem;
  613. delete options.bindAction;
  614. var that = this
  615. ,options = that.config = $.extend({}, that.config, upload.config, options)
  616. ,next = options.elem.next();
  617. //更新文件域相关属性
  618. next.attr({
  619. name: options.name
  620. ,accept: options.acceptMime
  621. ,multiple: options.multiple
  622. });
  623. };
  624. //事件处理
  625. Class.prototype.events = function(){
  626. var that = this
  627. ,options = that.config
  628. //设置当前选择的文件队列
  629. ,setChooseFile = function(files){
  630. that.chooseFiles = {};
  631. $.each(files, function(i, item){
  632. var time = new Date().getTime();
  633. that.chooseFiles[time + '-' + i] = item;
  634. });
  635. }
  636. //设置选择的文本
  637. ,setChooseText = function(files, filename){
  638. var elemFile = that.elemFile
  639. ,value = files.length > 1
  640. ? files.length + '个文件'
  641. : ((files[0] || {}).name || (elemFile[0].value.match(/[^\/\\]+\..+/g)||[]) || '');
  642. if(elemFile.next().hasClass(ELEM_CHOOSE)){
  643. elemFile.next().remove();
  644. }
  645. that.upload(null, 'choose');
  646. if(that.isFile() || options.choose) return;
  647. elemFile.after('<span class="layui-inline '+ ELEM_CHOOSE +'">'+ value +'</span>');
  648. };
  649. //点击上传容器
  650. options.elem.off('upload.start').on('upload.start', function(){
  651. var othis = $(this), data = othis.attr('lay-data');
  652. if(data){
  653. try{
  654. data = new Function('return '+ data)();
  655. that.config = $.extend({}, options, data);
  656. } catch(e){
  657. hint.error('Upload element property lay-data configuration item has a syntax error: ' + data)
  658. }
  659. }
  660. that.config.item = othis;
  661. that.elemFile[0].click();
  662. });
  663. //拖拽上传
  664. if(!(device.ie && device.ie < 10)){
  665. options.elem.off('upload.over').on('upload.over', function(){
  666. var othis = $(this)
  667. othis.attr('lay-over', '');
  668. })
  669. .off('upload.leave').on('upload.leave', function(){
  670. var othis = $(this)
  671. othis.removeAttr('lay-over');
  672. })
  673. .off('upload.drop').on('upload.drop', function(e, param){
  674. var othis = $(this), files = param.originalEvent.dataTransfer.files || [];
  675. othis.removeAttr('lay-over');
  676. setChooseFile(files);
  677. if(options.auto){
  678. that.upload(files);
  679. } else {
  680. setChooseText(files);
  681. }
  682. });
  683. }
  684. //文件选择
  685. that.elemFile.off('upload.change').on('upload.change', function(){
  686. var files = this.files || [];
  687. setChooseFile(files);
  688. options.auto ? that.upload() : setChooseText(files); //是否自动触发上传
  689. });
  690. //手动触发上传
  691. options.bindAction.off('upload.action').on('upload.action', function(){
  692. that.upload();
  693. });
  694. //防止事件重复绑定
  695. if(options.elem.data('haveEvents')) return;
  696. that.elemFile.on('change', function(){
  697. $(this).trigger('upload.change');
  698. });
  699. options.elem.on('click', function(){
  700. if(that.isFile()) return;
  701. $(this).trigger('upload.start');
  702. });
  703. if(options.drag){
  704. options.elem.on('dragover', function(e){
  705. e.preventDefault();
  706. $(this).trigger('upload.over');
  707. }).on('dragleave', function(e){
  708. $(this).trigger('upload.leave');
  709. }).on('drop', function(e){
  710. e.preventDefault();
  711. $(this).trigger('upload.drop', e);
  712. });
  713. }
  714. options.bindAction.on('click', function(){
  715. $(this).trigger('upload.action');
  716. });
  717. options.elem.data('haveEvents', true);
  718. };
  719. //核心入口
  720. upload.render = function(options){
  721. var inst = new Class(options);
  722. return thisUpload.call(inst);
  723. };