之前介绍了My AppBox V2.0,今天把拦截器补上,适用FineUICore,实现登录超时跳转,url参数获取,以及操作日志的保存;
1. 继承扩展和引用
在Controller层,所有页面都引用了 SysPageController ,所以拦截器的扩展只针对 SysPageController 类就可以了,在 System.Web.Mvc 中扩展拦截器直接继承 Controller 类,扩展 OnResultExecuted 方法,在 Microsoft.AspNetCore.Mvc 中挪了位置,要继承 ActionFilterAttribute 类中的 OnResultExecuted 方法:
/// <summary>
/// 回发权限控制
/// </summary>
public class SysPageFilter : ActionFilterAttribute
{
#region 回发权限控制 OnResultExecuted
/// <summary>
/// 覆盖
/// </summary>
/// <param name="filterContext"></param>
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
//
base.OnResultExecuted(filterContext);
}
}
需要在 SysPageController 头上添加引用:
/// <summary>
/// 拦截器
/// </summary>
[SysPageFilter] //注解
public class SysPageController : BaseController
{
//
}
2. 超时登录的JS
当用户登录超时(直接判断Session在不在),需要弹出是否重新登录的提示,只需要抛出一段js就行了,执行的并不是跳转页面,而是触发顶层框架上的退出按钮方法:
//得到重新登录的js
private string GetSysLoginJs()
{
//确定后执行的js
string js = "top.window.F.doPostBack({url: 'btnHomePage_Click',disableControl: 'btnHomePage'}); ";
string conjs = "";
//如果顶层已经弹出了就不在此弹出了
conjs += "if(top.$('div.relodeMsg.f-messagebox-alert').length==0){";
Alert a = new Alert();
a.CssClass = "relodeMsg";
a.Message = "登录已过期<br/>点击【确定】跳转到登录页面";
a.Title = "提示";
a.OkScript = js;
a.IconFont = IconFont.Warning;
a.Target = Target.Top;
conjs += a.GetShowReference();
conjs += "}";
return conjs;
}
3. 是否第一次回发
我还为 HttpRequest 扩展了一个方法,判断是否是 Ajax 回发,如果为真则认为是点击按钮触发的拦截,与打开菜单区分
/// <summary>
/// HttpRequest 扩展
/// </summary>
public static class HttpRequestEx
{
/// <summary>
/// 是否是ajax回发
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public static bool IsAjax(this HttpRequest req)
{
bool result = false;
//请求头标识
var xreq = req.Headers.ContainsKey("x-requested-with");
if (xreq)
{
result = req.Headers["x-requested-with"] == "XMLHttpRequest";
}
return result;
}
}
4. 上代码,注意看注释
没有难点,注意看注释
internal class SysPageFilter : ActionFilterAttribute
{
/// <summary>
/// 覆盖
/// </summary>
/// <param name="filterContext"></param>
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
//得到用户
var value = filterContext.HttpContext.Session.GetString("LoginUser");
if (string.IsNullOrEmpty(value))
{
string conjs = GetSysLoginJs();
PageContext.RegisterStartupScript(conjs);
return;
}
JObject _value = JObject.Parse(value);
Mssystem_1 lodeuser = (Mssystem_1)_value.ToObject(typeof(Mssystem_1));
//为空时跳转 注意当前页面不是登录页面
if (filterContext.RouteData.Values.Values.ToList()[1].ToString() != "SysLogin" && lodeuser == null)
{
string conjs = GetSysLoginJs();
PageContext.RegisterStartupScript(conjs);
return;
}
//是否第一次回发, 即加载页面
if (!filterContext.HttpContext.Request.IsAjax())
{
string curMenuId = "";
//得到当前菜单ID
curMenuId = filterContext.HttpContext.Request.Query["MenuId"];
if (!string.IsNullOrEmpty(curMenuId))
{
bool b = true;//按钮权限开关,默认开
//如果是超级管理员,直接跳过权限
if (lodeuser.isadmin)
{
b = false;
}
if (b)
{
//判断该用户是否有该菜单权限
if (!lodeuser.menuids.Contains(Convert.ToInt32(curMenuId)))
{
string conjs = GetSysLoginJs();
PageContext.RegisterStartupScript(conjs);
return;
}
//得到数据库中 用户 菜单权限 显示的按钮ID
List<string> btnids = BLLsystem_1.GetUserBtnByMenu(lodeuser.sys10.System_10_10, curMenuId, false);
if (btnids != null)
{
StringBuilder sb = new StringBuilder();
foreach (string item in btnids)
{
//隐藏 也可以执行除隐藏之外的代码
sb.Append("if(F.ui." + item + "){F.ui." + item + ".hide();};");
}
//抛出
PageContext.RegisterStartupScript(sb.ToString());
}
}
//记录日志 用户点击菜单
BLLsystem_16.ClickMenuLog(lodeuser.System_1_10.ToString(), curMenuId);
}
}
//如果不用是第一次回发 记录点击的按钮
else
{
//加入算法获取MenuId
string MenuId = "";
//参数很难获取,谁会赶紧告诉我
string url = ((HttpRequestHeaders)((DefaultHttpRequest)filterContext.HttpContext.Request).Headers).HeaderReferer;
string query = url.Split("?")[1];
foreach (var item in query.Split('&'))
{
foreach (var _item in item.Split('='))
{
if (_item == "MenuId")
{
MenuId = item.Split('=')[1];
}
}
}
if (!string.IsNullOrEmpty(MenuId))
{
//触发事件名称,由后台判断是否是一个按钮方法
string streve = filterContext.RouteData.Values.Values.ToList()[2].ToString();
//记录日志 用户点击按钮
BLLsystem_16.ButtonLog(lodeuser.System_1_10.ToString(), MenuId, streve);
}
}
base.OnResultExecuted(filterContext);
}
}