积分系统总结
今天积分系统MPM (Merit Points Management) 完成。
asp.net MVC4.0 EF DBFirst EasyUI 登陆页面采用bootstrap。(还是bootstrap好看些!)
功能很少,就一个模型层,和一个 webUI 展现层。
权限判断采用 过滤器,每一个Action都会经过过滤器。
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new MyActionFilterAttribute());
}
/// <summary>
/// 标记为NoFilterAttribute 属性的的方法,过滤器在这里扑捉到,然后 直接 return,不做权限管控
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class NoFilterAttribute : Attribute { }
/// <summary>
/// Action方法 过滤器 类
/// </summary>
public class MyActionFilterAttribute : ActionFilterAttribute
{
/// <summary>
/// 在 Action方法之前 调用
/// </summary>
/// <param name="filterContext"></param>
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
string strController = filterContext.RouteData.Values["controller"].ToString();
if (strController == "Login" || strController == "Home")
{
return;
}
object[] attrs = filterContext.ActionDescriptor.GetCustomAttributes(typeof(NoFilterAttribute), true);
if (attrs.Length > 0) return;
HttpSessionStateBase session = filterContext.HttpContext.Session;
if (session != null)
{
var activeSession = session["KT.MPM.web"];
if (activeSession == null)
{
filterContext.HttpContext.Response.Redirect("/Login");
return;
}
var userWorkNum = activeSession.ToString();
var mpmDb = new MPMEntities();
if (mpmDb.SysPower.FirstOrDefault(x => x.UserWorkNum == userWorkNum) == null)
{
filterContext.HttpContext.Response.Redirect("/Login");
}
}
base.OnActionExecuting(filterContext);
}
}
}
这样做呢,还是比较消性能的。
UI 框架的搭建 没有 采用 Easyui 官方 documentation 页面的那种,不采用Iframe,直接 ajax 加载 子页面。这样速度确实很快。缺点就是不好调试。
我使用了Iframe
主页面代码如下:
@{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } <style> .treegrid-tr-tree td { border-style: none; } .datagrid-btable td { border-style: none; } </style> <body class="easyui-layout" style="text-align: left"> <div region="west" split="true" title="菜单" style="width: 250px; padding: 5px;"> <table id="MenuTree" style="width:100%" title="" class="easyui-treegrid" data-options=" method:'post', url:'@Url.Action("Index")',onClickRow:fun, treeField:'MenuName', fixed:true, idField:'MenuID' "> <thead> <tr> <th data-options="field:'MenuName',width:230,formatter:formatUrl"></th> </tr> </thead> </table> <script> function fun(row) { addTab(row.MenuName, row.Url); } function formatUrl(val, row) { if (row.Url != "") { return '<span class="e-link" href="javascript:void(0)" onclick="addTab(' + "'" + row.MenuName + "'" + ',' + "'" + row.Url + "'" + ')">' + row.MenuName + '</span>'; } else { return '<a class="e-link" href="javascript:void(0)">' + row.MenuName + '</a>'; } } $(document).ready(function () { }); </script> </div> <div region="center"> <div id="tt" class="easyui-tabs" fit="true" border="false" plain="true"> </div> </div> <script> function addTab(title, url) { if ($('#tt').tabs('exists', title)) { $('#tt').tabs('select', title); } else { var content = '<iframe scrolling="auto" frameborder="0" src="' + url + '" style="width:100%;height:99%;"></iframe>'; $('#tt').tabs('add', { title: title, content: content, closable: true }); } } function showMsgTopCenter(title, msg) { $.messager.show({ title: title, msg: msg, showType: 'null', showSpeed: 0, style: { top: document.body.scrollTop + document.documentElement.scrollTop, timeout: 1000 } }); } </script>
easyui 请求的数据都是 JSON 格式,所以项目中 大量用到了 json.net
比如一个有页脚的json :
public string UserOtherRecordForOther(UserOtherRecordData model)
{
var dataGridJson = new DataGridJson();
var data = _mpmDb.view_UserOtherRecordForOther.Where(x => x.ObjectUser == model.RecordUser).Where(
y => y.CreateDate == model.CreateDate).ToList();
dataGridJson.rows = data;
dataGridJson.footer = new List<view_UserOtherRecordForOther>()
{
new view_UserOtherRecordForOther()
{
AllPoint=data.Sum(x=>x.AllPoint),
OutputValue=data.Sum(x=>x.OutputValue)
}
};
return JsonConvert.SerializeObject(dataGridJson);
}
public class DataGridJson
{
public static int i = 10;
public int total { get; set; } //记录的总条数
public object rows { get; set; } //具体内容
public object footer { get; set; } //具体内容
}
里面必须再包一层List.
使用到了一个扩展方法 来获取 当前登陆用户的工号。
namespace KT.MPM.web.Controllers { public static class Expend { public static string GetUserWorkNum(this Controller controller) { return controller.Session["KT.MPM.web"].ToString(); } } }
也有人说,直接 写一个类,继承 Controller 类不就好了嘛。
还有一个Excel 导出功能。
使用的是 NPOI 。
function ToExcel() { location.href = '@Url.Action("ExportExcel", "EveryDayPointReport")' + '?createDate=' + CreateDate_Temp; }
[FilterConfig.NoFilterAttribute] public ActionResult ExportExcel(DateTime? createDate) { String newfileName = DateTime.Now.ToString("yyyyMMddHHmmssff"); var list = Search(createDate); var fileOne = new FileStream(Server.MapPath("/template/EveryDayReport.xls"), FileMode.Open, FileAccess.ReadWrite); var wbOne = new HSSFWorkbook(fileOne); var sheet = (HSSFSheet)wbOne.GetSheetAt(0); int startRow = 2; foreach (var item in list) { var rowOne = (HSSFRow)sheet.CreateRow(startRow); rowOne.CreateCell(0).SetCellValue(item.UserWorkNum); rowOne.CreateCell(1).SetCellValue(item.UserName); 。。。。。。 startRow = startRow + 1; } var ms = new MemoryStream(); wbOne.Write(ms); return File(ms.ToArray(), "application/vnd.ms-excel", HttpUtility.UrlEncode(string.Format("{0}.xls", newfileName))); }
MVC就这点好,这样写,永远不会启动迅雷之后下载到错误的页面。以前用aspx 页面里面的导出功能,直接就把aspx页面给下载过来了。必须用一般处理程序做。
每次 dataGrid 查询,只不过是 轻量级 的发送 轻量级 的送回来(只需要更改datagrid 的url 参数)。服务端 客户端 都消耗 比较少。