/** @Name:layuiAdmin 视图模块 @Author:贤心 @Site:http://www.layui.com/admin/ @License:LPPL */ layui.define(['laytpl', 'layer'], function(exports){ var $ = layui.jquery ,laytpl = layui.laytpl ,layer = layui.layer ,setter = layui.setter ,device = layui.device() ,hint = layui.hint() //对外接口 ,view = function(id){ return new Class(id); } ,SHOW = 'layui-show', LAY_BODY = 'LAY_app_body' //构造器 ,Class = function(id){ this.id = id; this.container = $('#'+(id || LAY_BODY)); }; //加载中 view.loading = function(elem){ elem.append( this.elemLoad = $('') ); }; //移除加载 view.removeLoad = function(){ this.elemLoad && this.elemLoad.remove(); }; //清除 token,并跳转到登入页 view.exit = function(callback){ //清空本地记录的 token layui.data(setter.tableName, { key: setter.request.tokenName ,remove: true }); //跳转到登入页 parent.location.href = '/admin/login/login.html'; callback && callback(); }; //Ajax请求 view.req = function(options){ var that = this ,success = options.success ,error = options.error ,request = setter.request ,response = setter.response ,debug = function(){ return setter.debug ? '
URL:' + options.url : ''; }; options.data = options.data || {}; options.headers = options.headers || {}; if(request.tokenName){ /* //自动给参数传入默认 token options.data[request.tokenName] = request.tokenName in options.data ? options.data[request.tokenName] : (layui.data(setter.tableName)[request.tokenName] || ''); */ //自动给 Request Headers 传入 token options.headers[request.tokenName] = request.tokenName in options.headers ? options.headers[request.tokenName] : (layui.data(setter.tableName)[request.tokenName] || ''); } delete options.success; delete options.error; return $.ajax($.extend({ type: 'get' ,dataType: 'json' ,success: function(res){ var statusCode = response.statusCode; //只有 response 的 code 一切正常才执行 done if(res[response.statusName] == statusCode.ok) { typeof options.done === 'function' && options.done(res); } //登录状态失效,清除本地 access_token,并强制跳转到登入页 else if(res[response.statusName] == statusCode.logout){ view.exit(); } //其它异常 else { var error = [ 'Error: ' + (res[response.msgName] || '返回状态码异常') ,debug() ].join(''); view.error(error); } //只要 http 状态码正常,无论 response 的 code 是否正常都执行 success typeof success === 'function' && success(res); } ,error: function(e, code){ var error = [ '请求异常,请重试
错误信息:'+ code ,debug() ].join(''); view.error(error); typeof error === 'function' && error(res); } }, options)); }; view.download = function(url){ $('
').appendTo('body').submit().remove(); }; view.admindownload = function(url){ const xhr = new XMLHttpRequest() xhr.open('GET', url) xhr.responseType = 'blob' xhr.onload = function () { const disposition = xhr.getResponseHeader("Content-Disposition"); let fileName = ''; if (disposition && disposition.indexOf('attachment') !== -1) { const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(disposition); if (matches != null && matches[1]) { fileName = matches[1].replace(/['"]/g, '').trim(); fileName = decodeURIComponent(fileName); // 解码文件名 } } const url = window.URL.createObjectURL(xhr.response); const link = document.createElement('a'); link.href = url; link.download = fileName; document.body.appendChild(link); link.click(); document.body.removeChild(link); // 清理下载链接对象 window.URL.revokeObjectURL(url); } // 传递 token xhr.setRequestHeader('Authorization', layui.data(setter.tableName)[setter.request.tokenName] || ''); xhr.send(); // $.ajax({ // url: url, // method: "get", // beforeSend: function (request) { // request.setRequestHeader("Authorization", layui.data(setter.tableName)[setter.request.tokenName] || ''); // }, // xhrFields: { // responseType: 'blob' // }, // success: function (result, state, xhr) { // // let fileName = decodeURIComponent(xhr.getResponseHeader('Content-Disposition').split(';')[1].split('=')[1].replace(/\"/g, '')); // // let type = xhr.getResponseHeader("content-type") // // const url = window.URL.createObjectURL(result); // // const link = document.createElement('a'); // // link.href = url; // // link.setAttribute('download', 'example.docx'); // // document.body.appendChild(link); // // link.click(); // // document.body.removeChild(link); // 清理下载链接对象 // }, // }) }; //弹窗 view.popup = function(options){ var success = options.success ,skin = options.skin; delete options.success; delete options.skin; return layer.open($.extend({ type: 1 ,title: '提示' ,content: '' ,id: 'LAY-system-view-popup' ,skin: 'layui-layer-admin' + (skin ? ' ' + skin : '') ,shadeClose: true ,closeBtn: false ,success: function(layero, index){ var elemClose = $(''); layero.append(elemClose); elemClose.on('click', function(){ layer.close(index); }); typeof success === 'function' && success.apply(this, arguments); } }, options)) }; //异常提示 view.error = function(content, options){ return view.popup($.extend({ content: content ,maxWidth: 300 //,shade: 0.01 //,offset: 't' ,anim: 6 ,id: 'LAY_adminError' }, options)) }; //请求模板文件渲染 Class.prototype.render = function(views, params){ var that = this, router = layui.router(); views = setter.views + views + setter.engine; $('#'+ LAY_BODY).children('.layadmin-loading').remove(); view.loading(that.container); //loading //请求模板 $.ajax({ url: views ,type: 'get' ,dataType: 'html' ,data: { v: layui.cache.version } ,success: function(html){ html = '
' + html + '
'; var elemTitle = $(html).find('title') ,title = elemTitle.text() || (html.match(/\([\s\S]*)\<\/title>/)||[])[1]; var res = { title: title ,body: html }; elemTitle.remove(); that.params = params || {}; //获取参数 if(that.then){ that.then(res); delete that.then; } that.parse(html); view.removeLoad(); if(that.done){ that.done(res); delete that.done; } } ,error: function(e){ view.removeLoad(); if(that.render.isError){ return view.error('请求视图文件异常,状态:'+ e.status); }; if(e.status === 404){ that.render('template/tips/404'); } else { that.render('template/tips/error'); } that.render.isError = true; } }); return that; }; //解析模板 Class.prototype.parse = function(html, refresh, callback){ var that = this ,isScriptTpl = typeof html === 'object' //是否模板元素 ,elem = isScriptTpl ? html : $(html) ,elemTemp = isScriptTpl ? html : elem.find('*[template]') ,fn = function(options){ var tpl = laytpl(options.dataElem.html()); options.dataElem.after(tpl.render($.extend({ params: router.params }, options.res))); typeof callback === 'function' && callback(); try { options.done && new Function('d', options.done)(options.res); } catch(e){ console.error(options.dataElem[0], '\n存在错误回调脚本\n\n', e) } } ,router = layui.router(); elem.find('title').remove(); that.container[refresh ? 'after' : 'html'](elem.children()); router.params = that.params || {}; //遍历模板区块 for(var i = elemTemp.length; i > 0; i--){ (function(){ var dataElem = elemTemp.eq(i - 1) ,layDone = dataElem.attr('lay-done') || dataElem.attr('lay-then') //获取回调 ,url = laytpl(dataElem.attr('lay-url')|| '').render(router) //接口 url ,data = laytpl(dataElem.attr('lay-data')|| '').render(router) //接口参数 ,headers = laytpl(dataElem.attr('lay-headers')|| '').render(router); //接口请求的头信息 try { data = new Function('return '+ data + ';')(); } catch(e) { hint.error('lay-data: ' + e.message); data = {}; }; try { headers = new Function('return '+ headers + ';')(); } catch(e) { hint.error('lay-headers: ' + e.message); headers = headers || {} }; if(url){ view.req({ type: dataElem.attr('lay-type') || 'get' ,url: url ,data: data ,dataType: 'json' ,headers: headers ,success: function(res){ fn({ dataElem: dataElem ,res: res ,done: layDone }); } }); } else { fn({ dataElem: dataElem ,done: layDone }); } }()); } return that; }; //自动渲染数据模板 Class.prototype.autoRender = function(id, callback){ var that = this; $(id || 'body').find('*[template]').each(function(index, item){ var othis = $(this); that.container = othis; that.parse(othis, 'refresh'); }); }; //直接渲染字符 Class.prototype.send = function(views, data){ var tpl = laytpl(views || this.container.html()).render(data || {}); this.container.html(tpl); return this; }; //局部刷新模板 Class.prototype.refresh = function(callback){ var that = this ,next = that.container.next() ,templateid = next.attr('lay-templateid'); if(that.id != templateid) return that; that.parse(that.container, 'refresh', function(){ that.container.siblings('[lay-templateid="'+ that.id +'"]:last').remove(); typeof callback === 'function' && callback(); }); return that; }; //视图请求成功后的回调 Class.prototype.then = function(callback){ this.then = callback; return this; }; //视图渲染完毕后的回调 Class.prototype.done = function(callback){ this.done = callback; return this; }; //Ajax请求setup view.reqSetup = function(){ var request=setter.request; if(request.tokenName){ $.ajaxSetup({ headers:{ [request.tokenName]:layui.data(setter.tableName)[request.tokenName] || '', [request.userId]:layui.data(setter.tableName)[request.userId] || '' }, dataFilter: function (responseText) { var res; try{ res = eval('('+responseText+')'); }catch (e) { return responseText; } if(res && res.code == setter.response.statusCode.logout) view.exit(); else return responseText; } }); } }; view.getParameterByName = function (name) { name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), results = regex.exec(location.search); return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); } //对外接口 exports('view', view); });