以简求快 Java快速开发框架LML功能菜单管理
无论你现在身处什么样的职位,一定要保持每天看书的好习惯。
前面几集,让大家对LML能够有一个快速的预览和了解。以后几集我会简单的开发一些实例程序,管理功能等,向大家展现一下LML的简单,虽然不能做到完美,但是我觉得它总有它的用武之地。
也可能,经过前几集的痛苦折磨,你已经烦透了这个山寨货。在这,我真诚的向您道歉,耽误了您的时间我很过意不去。不过,从我个人这方面来讲,还没有停止山寨行为的打算,因为我没有能力从头开始建造自己的框架,而又有建造框架的野心,最后就只能山寨了。我渴望进步,虽然我能力有限。
接下来我大致讲解一下[功能菜单管理]开发过程:
我一直没有形成自主的菜单思想,所以在LML中我只是把Castle MonoRail中的菜单概念,照搬照抄了过来。菜单即链接,LML中每一个Action中的任何一个方法都可以成为一个菜单,实际情况下我们从没有把一个没有返回视图的方法作为一个菜单,但是它可能对应着一个权限。
复习了一下上一集说到的菜单和权限,下面开发功能:
1,[功能菜单管理]隶属于[系统管理],所以先创建[系统管理]的菜单和权限
@SysMenu(MenuId = "System", MenuName = "系统管理", MenuPic = "sys.png", MenuParent = "", MenuLevel = 1, MenuSort = 1) @SysPower(PowerId = "SystemPower", PowerMenu = "System", PowerName = "系统管理查看") public void System() { }
2,新建一个Action类MenuPowerMangerAction 继承自PageBaseAction
package LML.Action.System; import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; import org.hibernate.HibernateException; import LML.Core.Helper.DBHelper; import LML.Core.Helper.SQLBuilderHelper; import LML.Core.System.Area; import LML.Core.System.Menu; import LML.Core.System.PageBaseAction; import LML.Core.System.Pager; import LML.Core.System.Power; import LML.Core.System.SysMenu; import LML.Core.System.SysMenuPower; import LML.Core.System.SysPower; import LML.Model.Sysmenu; import LML.Model.Syspower; @Area("System") public class MenuPowerMangerAction extends PageBaseAction{ private String parentMenuId; private String menuName; public String getMenuName() { return menuName; } public void setMenuName(String menuName) { this.menuName = menuName; } public String getParentMenuId() { return parentMenuId; } public void setParentMenuId(String parentMenuId) { this.parentMenuId = parentMenuId; } @SysMenu(MenuId="MenuPowerManger",MenuName=功能菜单管理",MenuPic="",MenuParent="System",MenuLevel=2,MenuSort=1) @SysPower(PowerId="MenuPowerMangerPower",PowerMenu="MenuPowerManger",PowerName="功能菜单管理查看") public String List() { Pager pager = null; try { pager = DBHelper.ShowPager(pageSize, page, "*", "sysmenu", GetStrWhere(), "order by sort"); } catch (SQLException e) { // TODO Auto-generated catch block //e.printStackTrace(); System.out.println(e.getMessage()); } setPager(pager); return SUCCESS; } private String GetStrWhere() { String strWhere=""; strWhere+=SQLBuilderHelper.QueryString(strWhere,"name","like","'%",ParamValue("menuName",menuName,true),"%'","and"); if(parentMenuId!=null&&!parentMenuId.trim().equals("")) { strWhere+=SQLBuilderHelper.QueryString(strWhere,"parent","=","'",ParamValue("parentMenuId",parentMenuId,true),"'","and"); } else { strWhere+=SQLBuilderHelper.QueryString(strWhere,"level","=","","1","","and"); } return strWhere; } public String Init() { try { try { DBHelper.ExecuteNoneQuery("delete from sysmenu"); DBHelper.ExecuteNoneQuery("delete from syspower"); } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } ArrayList<Menu> menuList=SysMenuPower.getMenu(); ArrayList<Power> powerList=SysMenuPower.getPower(); if(!menuList.isEmpty()) { for(Menu m :menuList ) { Sysmenu sysMenu=new Sysmenu(); sysMenu.setId(m.MenuId); sysMenu.setName(m.MenuName); sysMenu.setPic(m.MenuPic); sysMenu.setUrl(m.MenuUrl+".action"); sysMenu.setLevel((short) m.MenuLevel); sysMenu.setSort((short)m.MenuSort); sysMenu.setParent(m.MenuParent); DBHelper.Create(sysMenu); } } if(!powerList.isEmpty()) { for(Power p:powerList) { Syspower sysPower=new Syspower(); sysPower.setId(p.PowerId); sysPower.setMenu(p.PowerMenu); sysPower.setName(p.PowerName); DBHelper.Create(sysPower); } } return JavaScript("alert('初始化成功,请刷新!')"); } catch (IOException e) { // TODO Auto-generated catch block return JavaScript("alert('初始化失败,请重试!')"); //e.printStackTrace(); } } }
3,新建和Action对应的Views文件夹以及一个html模板,List.Html
#set($layout="default_Pager.html") <div class="articles"> <div class="clear tabtext"> <!--style="display:none;"--> <div class="tab1" style="display:none;"> <!--内容开始--> <form action="?" name="form1" id="form1"> <input name="parentMenuId" value="$!parentMenuId" type="hidden" /> <!--查询条件模块开始--> <div class="admin_search"> <div class="admin_search_top"> <span>查询方式</span></div> <div class="admin_search_contant"> <div class="admin_search_contant_left"> <span>菜单名称:</span><input name="menuName" value="$!menuName" type="text" /> </div> <div class="admin_search_contant_right"> <table border="0" cellspacing="0" cellpadding="0" onclick="DoSearch()" class="right"> <tr> <td class="search_button bt1"> <a id="seach">查询</a> </td> <td class="search_button_right"> </td> </tr> </table> </div> <div class="clear"></div> </div> </div> <!--查询条件模块结束--> </form> <div class="table_name"> <div class="table_name_left"> <img src="/Theme/1/base/images/dian1.png" /><span>功能菜单管理</span></div> <div class="table_name_right"> <div class="admin_page_left"> <ul> #if("$!fatherMenuId"!=""&&"$!fatherMenuId"!="-1") <li> <table border="0" cellspacing="0" cellpadding="0" onclick="window.location.href='/System/MenuInfo/List.aspx?fatherMenuId=$!GrandId'"> <tr> <td class="admin_page_left_left btn7"> <a>返回</a> </td> <td class="admin_page_left_right"> </td> </tr> </table> </li> #end <li> <table border="0" cellspacing="0" cellpadding="0" onclick="Initialize()"> <tr> <td class="admin_page_left_left btn8"> <a>初始化</a> </td> <td class="admin_page_left_right"> </td> </tr> </table> </li> </ul> </div> </div> </div> <!--表格列表开始--> <table width="100%" border="0" cellspacing="0" cellpadding="0" class="table" name="table" id="table"> <tr> <th width="15%"> 菜单名称 </th> <th width="15%"> 菜单层级 </th> <th width="15%"> 父级菜单 </th> <th width="20%"> 链接地址 </th> <th width="20%"> 操作 </th> </tr> #if($pager.result.rowCount==0) <tr> <td colspan="7" align="center" style="color: Red; font-weight: bold;"> 暂无记录 </td> </tr> #else #foreach($ItemRow in $pager.result.rows) <tr> <td class="table_blue"> <a href="?parentMenuId=$!ItemRow.id" target="_self">$!{ItemRow.name}</a> </td> <td> $!ItemRow.level </td> <td> $!ItemRow.parent </td> <td> $!ItemRow.url </td> <td class="table_operating"> </td> </tr> #end #end </table> <!--表格列表开始--> <!--内容结束--> </div> </div> </div> <script type="text/javascript"> //查询提交form function DoSearch() { jQuery("#form1").submit(); } //初始化 function Initialize() { if (confirm('您确定要初始化吗?')) { window.open("MenuPowerManger_Init.action", "iframe_data"); } } </script>
由于没有开发用户自定义菜单,所以整体上功能菜单管理只包括两块:列表和初始化。下面说说应该注意的几点:
1, 域的概念。
由于当前的Action类在System包下,所以我们要这样声明一个域:@Area("System"),关于域,LML做的挺脆弱,还有些牵强,以后有时间一定改正。当然,就目前来说,如果不这么声明,就会发生生成菜单后无法找到Action的情况了。
2, 分页和查询条件
这一块LML并没有像原生的SSH那样使用List来实现分页,至于我们分页方法的参数,还有生成查询条件的方法,我就不多说了。
3, 初始化
初始化大概思想就是先删除所有初始化进入数据库的菜单和权限,然后从SysMenuPower中调用相应的getMenu()和getPower()方法获取系统中包含的所有菜单 (ArrayList<Menu>)和权限(ArrayList<Power>),接着就可以迭代着两个方法的返回值,循环的插入数据库了。
其他,应该没有什么需要特别注意的了。到此,LML的菜单权限管理就基本应用了。根据实际需求,应该还会有其他角色对应管理等等。就不多说了吧,从我提供的源码中也可以看到相应的模块。模块开发千篇一律,没有必要一一列举,那样太浪费大家的时间了。
抱歉,我可能写的比较混乱,这貌似是我这种.net程序员的习惯。
下集预告:一个基本的模块,CRUD。