很久沒寫文章了前幾天有幾個朋友問了我很多關於業務系統(ERPDRPCRM等)設計裡很多概念性東西花了很長時間給他解釋最後他門還是知其然不知其所以然這對於剛跨出學校大門的朋友來說理解起確實有點枯燥這裡我以以前參與的用友ERPDRP產品項目裡的部分設計為參考通過幾篇文章來和大家分享業務系統裡的部門平台通用部分的設計應用
本文主要介紹業務系統設計裡的菜單設計關注我博客的朋友或許以前見過一篇我寫的關於菜單的文章文章連接使用RadControls的RadMenu控件開發系統菜單 這篇文章主要是介紹了RadControls的RadMenu控件的基本使用沒有詳細介紹到菜單如何設計為什麼要那麼設計本文就以這片文章為基礎同樣通過此文章的示例程序和示例數據庫結合業務系統設計的相關術語介紹業務系統的菜單設計
首先看看上面的數據庫設計結構其中ID為自動編號的主鍵字段Code為菜單編碼(也稱業務編碼)Name為菜單名稱 Url為單擊菜單所導航的路徑ImageUrl為菜單上顯示的圖片地址ShortCut為快捷鍵Order為菜單項顯示順序Grade為菜單級限EndGrade為是否為末級菜單(既最後一菜單項)SupMenuCode為當前菜單項的父級菜單編碼(對應於Code字段)完整的還應該包括是否受權限控制等字段這裡不一一列出
上面的數據庫設計其實很簡單需要主要的字段有Code菜單編碼(也稱業務編碼)在業務系統裡通常設計為每一菜單項都可以認為是一個業務操作這裡的Code非常重要業務系統的後續工作都是從這裡開始通常與權限設計結合使用得最多
系統菜單應該是多層次結構的比如常見的Windows菜單業務系統裡的菜單設計同樣如此通過SupMenuCode字段來標記該菜單項屬於那一項菜單的子菜單如果沒有父級菜單(系統頂層菜單)則標記為
既然菜單有層次結構那就一定有層次標識通過Grade來標記EndGrade則表示當前菜單項在該層次級別上的菜單項上是否為末級
分析清楚了需求和菜單設計方案下面我們著手代碼開發下圖為項目解決方案截圖
如上圖Menucs裡封裝了數據庫查詢功能App_Data下存放的Access數據庫RadControls為RadMenu控件所需要的相關文件Defaultaspx則為菜單UI界面
首先需要配置數據庫連串如下
private static string connectionString =
Provider=Microsoft
jet
OLEDB
;data Source=
+ HttpContext
Current
Server
MapPath(@
App_Data\MenuDB
mdb
);
接著我們需要一個執行SQL的方法如下代碼塊
private DataTable ExecuteQuery(string cmdText)
{
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
using (OleDbDataAdapter oda = new OleDbDataAdapter(cmdText
conn))
{
DataSet ds = new DataSet();
oda
Fill(ds);
return ds
Tables[
];
}
}
}
最後我們還需要寫兩個方法一個是查詢頂層菜單的方法一個則是實現查詢菜單下的子菜單方法(做法有很多種我個人建議把所有的數據查詢出然後在操作內存數據這裡為了方便理解我故采用多次查詢數據庫的方式來實現)
public DataTable GetMenu()
{
string sql =
select * from menu where grade=
;
return ExecuteQuery(sql);
}
public DataTable GetMenuBySupCode(string supMenuCode)
{
string sql =
select * from menu where supmenucode=
+ supMenuCode +
;
return ExecuteQuery(sql);
}
OK准備工作做好後現在就是需要到UI層上去做菜單的展現工作了菜單的展現我通過RadContrls的RadMenu控件來實現此控件相對ASPNET的標准Menu控件功能強大要使用RadMenu則需要注冊控件的引用如果你是通過RadContrls控件庫安裝包安裝的則會自動注冊到VS工具箱和標准控件使用方法一樣
<%@ Register Assembly=
RadMenu
Net
Namespace=
Telerik
WebControls
TagPrefix=
rad
%>
<%
菜單開始
%>
<rad:RadMenu ID=
SystemMenu
runat=
server
Skin=
Vista
>
</rad:RadMenu>
<%
菜單結束
%>
上面准備好了頂層菜單的查詢方法直接通過該方法查詢出頂層
菜單項對菜單進行初始化
protected void Page_Load(object sender
EventArgs e)
{
if (!IsPostBack)
{
InitMenu();
}
}
Menu menu = new Menu();
private void InitMenu()
{
//查詢出菜單配置信息
DataTable dtMenu = menu
GetMenu();
for (int i =
; i < dtMenu
Rows
Count; i++)
{
//Rad菜單項
RadMenuItem item = new RadMenuItem();
item
ID = dtMenu
Rows[i][
Code
]
ToString();
item
Text = dtMenu
Rows[i][
Name
]
ToString();
item
Value = dtMenu
Rows[i][
Url
]
ToString();
item
AccessKey = dtMenu
Rows[i][
ShortCut
]
ToString();
this
SystemMenu
Items
Add(item);
//菜建子菜單
InitSubMenu(item
dtMenu
Rows[i][
Code
]
ToString());
}
}
我們設計為多層次菜單結構那麼在初始化頂層菜單的時候就應該判斷該菜單項是否有子菜單如果有則也初始化子菜單如果是多級層次的結構通過遞歸算法來完成多層次的初始化如下代碼塊
private void InitSubMenu(RadMenuItem item
string supMenuCode)
{
//根據父菜單編碼查詢出子菜單配置項
DataTable dtMenu = menu
GetMenuBySupCode(supMenuCode);
if (dtMenu != null)
{
foreach (DataRow dataRow in dtMenu
Rows)
{
RadMenuItem subItem = new RadMenuItem();
subItem
ID = dataRow[
ID
]
ToString();
subItem
Text = dataRow[
Name
]
ToString();
subItem
Value = dataRow[
Url
]
ToString();
subItem
AccessKey = dataRow[
ShortCut
]
ToString();
item
Items
Add(subItem);
if (Convert
ToInt
(dataRow[
EndGrade
]) !=
)
{
InitSubMenu(subItem
Convert
ToString(dataRow[
Code
]));
}
}
}
}
如上就完成了系統的菜單設計實際項目開發中的設計與這樣的設計幾乎都大同小異主要是了解設計思想或許看完了本文你還是沒有明白為什麼要這樣設計如果是這樣那請你關注下一篇文章下一篇文章中就用到了菜單中的業務編碼應該可以給一個滿意的答案
From:http://tw.wingwit.com/Article/program/net/201311/13398.html