1.新建访问的控制器动作返回视图,在视图中使用easyui的treegrid插件来得到后台得到的json数据显示多级菜单
public ActionResult Menu() { return View(); }
视图:
@{ ViewBag.Title = "Menu"; Layout = "~/Views/Shared/_GridView.cshtml"; } @section header{} @section body{ <div id="dataGrid" class="easyui-layout" data-options="fit:true"> <table id="gridView"></table> </div> } @section scripts{ <script src="~/Content/oa/scripts/xlayout.js"></script> <script type="text/javascript"> $(function () { alert(22) load(); }); function load() { $('#gridView').treegrid({ url: '/WxMenu/MenuGridView', title: '微信菜单配置', treeField: 'Text', fit: true, fitColumns: true, idField: 'Id', loadMsg: '数据正在加载中......', sortName: 'Orderby', sortOrder: 'asc', pagination: true, singleSelect: true, pageSize: 15, pageNumber: 1, pageList: [15, 30, 45, 60], queryParams: {}, rownumbers: true, checkOnSelect: true, selectOnCheck: true, lines: true, columns: [[ { field: 'ck', checkbox: true, width: 50 }, { field: 'Text', title: '菜单名字', width: 160, align: 'left' }, { field: 'MenuId', title: '菜单编码', width: 100, align: 'left', formatter: function (value, row, index) { return value == "-1" ? "" : value; } }, { field: 'IsEnable', title: '有效', width: 50, align: 'center', formatter: function (value, row, index) { return "<span style=\"color:{1};\">{0}</span>".format( value == "1" ? "已启用" : "已禁用", value == "1" ? "green" : "red"); } }, { field: 'OrderBy', title: '排序号', width: 80, align: 'left' }, { field: 'Target', title: '动作类型', width: 100, align: 'center', formatter: function (value, row, index) { switch (value) { case 'view': return "跳转URL"; case 'click': return "点击推事件"; case 'scancode_push': return "扫码推事件"; case 'scancode_waitmsg': return "扫码推事件且弹出(消息接收中)提示框"; case 'pic_sysphoto': return "弹出系统拍照发图"; case 'pic_photo_or_album': return "弹出拍照或者相册发图"; case 'pic_weixin': return "弹出微信相册发图器"; case 'location_select': return "弹出地理位置选择器"; case 'media_id': return "下发消息(除文本消息)"; case 'view_limited': return "跳转图文消息URL"; } } }, { field: 'Ico', title: 'MenuKey', width: 100, align: 'left' }, { field: 'Url', title: '菜单URL', width: 300, align: 'left' } ]], toolbar: [{ id: 'btnAdd', text: '添加', iconCls: 'icon-add', handler: function () { showWindow("添加菜单", "/OA/WeiXin/MenuEdit/0", 700, 400); } }, { id: 'btnAdd', text: '编辑', iconCls: 'icon-edit', handler: function () { var row = $('#gridView').datagrid('getSelected'); if (!row) { showMsg("系统提示", "请选择要编辑的行", true); return; } if (row.Id == "0") { showMsg("系统提示", "此数据不能修改", true); return; } showWindow("添加菜单", "/OA/WeiXin/MenuEdit/" + row.Id, 700, 400); } }, { id: 'btnDelete', text: '删除', iconCls: 'icon-remove', handler: function () { var rows = $('#gridView').datagrid('getChecked'); if (!rows || rows.length == 0) { showMsg("系统提示", "请选择要删除的行", true); return; } showConfirm('系统提示', '删除数据后将无法恢复,还确认删除吗?', function () { var ids = new Array(); var isRoot = false; $.each(rows, function (i, n) { ids.push("'" + n.Id + "'"); isRoot = n.MenuId == "10000"; if (isRoot) return false; }); if (isRoot) { showMsg("系统提示", "菜单(微信公众平台菜单)不能删除!", true); return; } showProcess(true, "系统提示", "正在删除中......"); setTimeout(function () { $.ajax({ url: "/OA/WeiXin/MenuDelete", data: { ids: ids.toString(",") }, dataType: "json", type: "POST", traditional: true, success: function (result) { showProcess(false); if (result.Success) { showMsg("系统提示", result.Message, false); $('#gridView').datagrid('reload'); } else { showMsg("系统提示", result.Message, true); } } }); }, 2000); }); } }, { id: 'btnRefresh', text: '更新', iconCls: 'icon-reload', handler: function () { $('#gridView').treegrid('reload'); } }, { id: 'btnRefresh', text: '发布到微信公众平台', iconCls: 'icon-redo', handler: function () { $.ajax({ url: "/WxMenu/MenuToWeiXin", data: {}, dataType: "json", type: "POST", traditional: true, beforeSend: function () { showProcess(true, "系统提示", "正发布到微信公众平台......"); }, error: function () { }, success: function (result) { showMsg("系统提示", result.Message, false); }, complete: function () { showProcess(false); } }); } }], onLoadSuccess: function () { var pager = $('#gridView').treegrid('getPager'); pager.pagination({ beforePageText: '第', afterPageText: '页 共 {pages} 页', displayMsg: '当前显示 {from} - {to} 条记录 共 {total} 条记录', buttons: [] }); } }); } function radWindowCallBackFn() { showMsg("系统提示", "存盘成功!", false); $('#gridView').treegrid('reload'); } </script>}
2. 后台动作返回一个content()。
public ActionResult MenuGridView(int? page, int? rows, string sort = "", string order = "asc") { return Content(GetMenuGridTree()); }
3.通过GetMenuGridTree()函数来返回一个json对象:
public string GetMenuGridTree() { NHibernateHelper nhlper = new NHibernateHelper(); ISession session = nhlper.GetSession(); List<TreeModel> result = new List<TreeModel>(); List<TreeModel> children = new List<TreeModel>(); IEnumerable<WeiXinMenu> kinds = session.Query<WeiXinMenu>(); WeiXinMenu root = kinds.FirstOrDefault(c => c.ParentId == "-1"); GetMenuGridTree(kinds, children, "10000"); result.Add(new TreeModel { Id = root.Id.ToString(), MenuId = root.MenuId, Text = root.MenuName, Url = root.MenuUrl, ParentMenuId = root.ParentId.ToString(), IsEnable = root.IsEnable, OrderBy = root.OrderBy.ToString(), Target = root.MenuType, Ico = root.MenuKey, children = children }); return JsonConvert.SerializeObject(result); }
其中NHibernateHelper是申明了一个Nhibernate的辅助类,用来建立一个isessionfactory(会话工厂),然后打开一个isession,如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using NHibernate; using NHibernate.Cfg; namespace Data { public class NHibernateHelper { private ISessionFactory _sessionFactory; public NHibernateHelper() { //创建ISessionFactory _sessionFactory = GetSessionFactory(); } public ISessionFactory GetSessionFactory() { //配置ISessionFactory return (new Configuration()).Configure().BuildSessionFactory(); } public ISession GetSession() { return _sessionFactory.OpenSession(); } } }
其中TreeModel类,是创建一个有递归子类的数据库存的菜单表的类。跟我们在Nhibernate中持久化实体的菜单类似,如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Domain.OrmLib.Model { public class TreeModel { public string Id { get; set; } public string MenuId { get; set; } public string Text { get; set; } public string Url { get; set; } public string Ico { get; set; } public string ParentMenuId { get; set; } public string IsEnable { get; set; } public string OrderBy { get; set; } public string Target { get; set; } public string IsStretch { get; set; } public string IsEdit { get; set; } public string IsDelete { get; set; } public string Remark { get; set; } public string state { get; set; } public string iconCls { get; set; } public List<TreeModel> children { get; set; } } }
其中IEnumerable<WeiXinMenu> kinds = session.Query<WeiXinMenu>();这句就是通过Nhibernate的会话isession查询到并枚举我们的实体WeiXinMenu。先把root根部的实体查询出来。
GetMenuGridTree()方法就是递归的调用得到剩下的chilren.
private void GetMenuGridTree(IEnumerable<WeiXinMenu> kinds, List<TreeModel> children, string pId) { foreach (WeiXinMenu p in kinds.Where(c => c.ParentId == pId).OrderBy(c => c.OrderBy)) { TreeModel gt = new TreeModel(); gt.Id = p.Id.ToString(); gt.MenuId = p.MenuId; gt.Text = p.MenuName; gt.Url = p.MenuUrl; gt.ParentMenuId = p.ParentId; gt.IsEnable = p.IsEnable; gt.OrderBy = p.OrderBy.ToString(); gt.Target = p.MenuType; gt.Ico = p.MenuKey; List<TreeModel> childrenTmp = new List<TreeModel>(); GetMenuGridTree(kinds, childrenTmp, p.MenuId); /* if (childrenTmp.Count > 0) { gt.state = "closed"; } */ gt.children = childrenTmp; children.Add(gt); } }