/**
@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);
});