任何人只要在對的地方做對的事,就值得尊敬!
對於系統而言,管理員必須保證每一個用戶只能做自己該做的事。所以任何一個項目,必然有一套權限管理策略。復雜的就很復雜了,我將一切從簡。園子里有號稱能將權限管理做的極致的,咱也沒留意看過,誰知道呢。由於是實驗型項目,我只是使用了單角色,具體業務大家可具體對待。
曾經我還是ASP.Net的初學者的時候,某一本從入門到精通類似的書上在介紹母板的時候,信口開河的預言:母板的出現將取代網頁frameset的架構設計。當時我是深信不疑,把作者佩服的五體投地。但是,我一直懷疑母板(或者概念類似母板的一類)的作用,書上可能介紹說把若干個網頁相同的部分提取為母板,這樣直接引用即便於管理,又減少頁面代碼。問題就在這里,你需要在某一頁面主動引用母板,母板就只能類似於#define,只能是在模板引擎在解析的時候將母板加以替換而已。這樣,我們在訪問引用同一母板的任何一個頁面,母板都會被重新替換,重新解析和加載!當我們需要的眾多頁面的公用部分沒必要甚至不可以重復加載的情況下,我們依然需要frameset/iframe。
下面,給出首頁的frameset源碼:
首頁,Index
<!DOCTYPEhtmlPUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <htmlxmlns="http://www.w3.org/1999/xhtml"> <head> <metahttp-equiv="Content-Type"content="text/html; charset=utf-8"/> <metahttp-equiv="X-UA-Compatible"content="IE=EmulateIE8"/> <title>蜜蜂的智慧</title> </head> <framesetstyle="border: 0"rows="92,*,24"frameborder="no"border="0"framespacing="0"> <framesrc="FrameWork_Top.action"name="topFrame"scrolling="No"noresize="noresize"id="topFrame"/> <framesrc="FrameWork_Middle.action"name="mainFrame"id="mainFrame"/> <framesrc="FrameWork_Bottom.action"name="bottomFrame"scrolling="No"noresize="noresize"id="bottomFrame"/> </frameset> <noframes> <body> </body> </noframes> </html>
以上,毫無疑問的吧。在mainFrame中,還有一個框架,代碼如下:
mainFrame
<!DOCTYPEhtmlPUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <htmlxmlns="http://www.w3.org/1999/xhtml"> <head> <metahttp-equiv="Content-Type"content="text/html; charset=utf-8"/> <title></title> <framesetrows="*"cols="200,4,*"border="0"framespacing="0"id="frame1"frameborder="no"> <framename="leftarea"id="leftarea"scrolling="auto"noresize="noresize"marginheight="0"src="FrameWork_Menu.action"frameborder="0"> <framename="middleframe"scrolling="no"noresize="noresize"src="FrameWork_MiddleLeft.action"frameborder="0"> <framesetrows="*"cols="*,4"frameborder="no"border="0"framespacing="0"id="frame2"> <framename="main"scrolling="auto"noresize="noresize"src="FrameWork_MainIndex.action"frameborder="0"id="mainindex"> <framename="rightframe"src="FrameWork_MiddleRight.action"frameborder="0"scrolling="no"noresize="noresize"> </frameset> </frameset> <noframes> </noframes> </html>
框架嵌套了,貌似有點點麻煩。現在找出來我們的關注點,leftarea是我們展現菜單的frame,mainindex是展現所有業務界面的地方。框架就是這樣了,沒有什么難度,也沒有任何特別之處。現在信息技術高速發展,審美觀點也是每天一個樣,每天都會有更好看的框架和樣式。但是,管理系統真的需要花哨嗎?再怎么變真的能夠擺脫查詢列表嗎?
還記得我們的約定嗎?一個html頁面一定會對應着一個同名的Action方法。下面給出需要用到的Action代碼,記住不要引用layout:
主頁Action
public String Index() { returnSUCCESS; } public String Top() { returnSUCCESS; } public String Middle() { returnSUCCESS; } public String Bottom() { returnSUCCESS; } public String Menu() { try { String roleId = GlobalInfo.getValue("roleId"); if (roleId.equals("supper")) { setMenu(DBHelper .ExecuteResult("select * from sysmenu order by sort asc")); } else { setMenu(DBHelper .ExecuteResult("select * from sysmenu where id in (select menuid from roleMenu where roleId='" + roleId + "') order by sort asc")); } } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } returnSUCCESS; } public String MiddleLeft() { returnSUCCESS; } public String MainIndex() { returnSUCCESS; } public String MiddleRight() { returnSUCCESS; }
框架基本上就是這個樣子了,下面我們繼續關注一下菜單的問題:
我們要獲得當前登錄用戶的菜單,這當然必須在設計的時候考慮到,我這里使用roleMenu表,比較簡單,可根據實際情況進行擴充,數據庫導出文件可下載(最后給出連接)。
菜單Action
private Result menu; public Result getMenu() { returnmenu; } publicvoid setMenu(Result menu) { this.menu = menu; } public String Menu() { try { String roleId = GlobalInfo.getValue("roleId"); if (roleId.equals("supper")) { setMenu(DBHelper .ExecuteResult("select * from sysmenu order by sort asc")); } else { setMenu(DBHelper .ExecuteResult("select * from sysmenu where id in (select menuid from roleMenu where roleId='" + roleId + "') order by sort asc")); } } catch (HibernateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } returnSUCCESS; }
經過上一集的介紹,我相信大家對Result數據集都已經很熟悉了,這里就不多費手指了。我們使用先前在用戶登錄時保存的用戶角色來驗證用戶,假如是特權用戶就直接賦予全部菜單,如果不是就看運氣了,有什么就是什么了!
查詢用戶菜單
setMenu(DBHelper
.ExecuteResult("select * from sysmenu where id in (select menuid from roleMenu where roleId='"
+ roleId + "') order by sort asc"));
大家肯定都知道自己的項目在設計之初的菜單層級是怎么設置的,我這里使用最簡單的吧,只有兩級菜單。原則上菜單是可以無限級別的,可惜我們的項目一直都沒用的上這么多的菜單。雖然菜單可以開放給用戶自行維護,用戶甚至可以把現有的系統納入進來,哎,誰讓我們的用戶都比較懶呢,你要是不給他們弄好了,他們才不會自己動手呢!除非遇上了檢查!
針對我們的兩級菜單,給出菜單頁面的源代碼:
菜單展示頁面的源碼
<!DOCTYPEhtmlPUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <htmlxmlns="http://www.w3.org/1999/xhtml"> <head> <metahttp-equiv="Content-Type"content="text/html; charset=utf-8"/> <metahttp-equiv="X-UA-Compatible"content="IE=EmulateIE8"/> <title>蜜蜂的智慧</title> <linkrel="stylesheet"type="text/css"href="../Theme/1/base/css/menu.css"/> <scripttype="text/javascript"src="../Content/javascript/jquery-1.6.2.min.js"></script> <scripttype="text/javascript"src="../Content/javascript/Framework/index.js"></script> </head> <bodystyle="background: url(../Theme/1/base/images/menu_bg.jpg) repeat-y;"> <divid="menu"style="height:100%;"> <divclass="content"> <divclass="menu_info"> <ulid="first_menu"> #foreach($item in $menu.rows) #if("$item.level"=="1") <liclass="L1"><ahref="javascript:c('$item.Id');"id="$item.Id"><span> <imgsrc="../Content/images/menu/$item.pic"align="absMiddle"/>$item.name</span></a></li> <ulid="${item.id}d"style="display: none;"class="U1"> #foreach($item2 in $menu.rows) #if("$item2.parent"=="$item.id") <liclass="L22"><ahref="javascript:;"id="$item2.Id"onclick="OpenUrl('$item2.id','/Wisdom/$item2.url');"> <span>$item2.name</span></a></li> #end #end </ul> #end #end </ul> </div> </div> </div> <divclass="key"onclick="initHidemenu(bottom);"> </div> <scriptlanguage="JavaScript"> function OpenUrl(id, url) { $("#mainindex", window.parent.document).attr("src", url); $(".L22 > a").removeClass("active"); $(id).addClass("active"); }; $("#first_menu > li > a > span").hover( function () { $(this).stop().animate({ paddingLeft: "15px" }, 200); }, function () { $(this).stop().animate({ paddingLeft: "5px" }); } ); </script> </body> </html>
需要注意的地方就是,菜單的雙層循環,第一層循環是獲得用戶菜單的一級菜單,第二層循環是獲得當前一級菜單的二級子菜單。
首頁整體就這樣了。很多人可能不是很熟悉velocity語法,百度吧,我也會整理一下我們經常用到的velocity語句。這一定是最簡單的。
數據庫文件下載:http://files.cnblogs.com/Bytime/120731233430.zip
下集預告:velocity常用基本語法。
