using System;
using System.Data;// DataTable,DataView
using System.Web;// Server
using System.Text.RegularExpressions;// Regex
using Oracle.DataAccess.Client;// oracle 连接类
using System.Configuration;// ConfigurationManager
using System.Web.UI.WebControls;// TreeNodeCollection,TreeView,TreeNode,Panel
using System.Collections.Generic;// List
/*/--------------------------------------------------------------------------------//
// DrawMenus 的摘要说明
// 相关表结构在oracle下的脚本如下:
--用户列表
drop table USERS purge;
create table USERS
(
USERNAME VARCHAR2(25) primary key,
PASSWORD VARCHAR2(25) not null,
TAG VARCHAR2(25) ,
MENU_GROUP VARCHAR2(100) default null,
ROLE_LEVEL NUMBER default 0 not null
);
/
insert into users(username,password,role_level) values ('admin','admin',2);
insert into users(username,password) values ('guest','guest');
insert into users(username,password,menu_group,role_level) values ('a','a','a',2);
insert into users(username,password,menu_group,role_level) values ('b','b','b',2);
insert into users(username,password,menu_group,role_level) values ('c','c','c',2);
insert into users(username,password,role_level) values ('l0','l0',0);
insert into users(username,password,role_level) values ('l1','l1',1);
insert into users(username,password,role_level) values ('l2','l2',2);
--非继承用户测试
-- 1.菜单集之间用英文逗号{,}隔开
-- 2.菜单集和级别组间用竖杠{|}隔开,且竖杠前仅允许描述一个菜单集
-- 3.多个级别间用斜杠{/}隔开
insert into users(username,password,menu_group) values ('n0','n0','a|0-1,b|1-2');
insert into users(username,password,menu_group) values ('n1','n1','a|1/2,b|0/2,c');
insert into users(username,password,menu_group) values ('n2','n2','a|0/2,b|0/2');
insert into users(username,password,menu_group) values ('n3','n3','a|2,b|3,c|3');
insert into users(username,password,menu_group,role_level) values ('a0','a0','a,b,c',0);
insert into users(username,password,menu_group,role_level) values ('a1','a1','a,b,c',1);
insert into users(username,password,menu_group,role_level) values ('a2','a2','a,b,c',2);
insert into users(username,password,menu_group,role_level) values ('b0','b0','a1a,a1b,b1,c1',0);
insert into users(username,password,menu_group,role_level) values ('b1','b1','a1a1,a1a2,b2,c2',1);
insert into users(username,password,menu_group,role_level) values ('b2','b2','a1,b2,c3',2);
insert into users(username,password,menu_group,role_level) values ('r0','r0','a,b,c,root',0);
insert into users(username,password,menu_group,role_level) values ('r1','r1','a,b,c,root',1);
insert into users(username,password,menu_group,role_level) values ('r2','r2','a,b,c,root',2);
commit;
--菜单列表
drop table MENUS purge;
create table MENUS
(
MENU_ID VARCHAR2(25) primary key,
MENU_NAME VARCHAR2(50) not null,
PARENT_ID VARCHAR2(25) default null,
MENU_LEVEL NUMBER default 0 not null,
IMG_URL VARCHAR2(100) default null,
NAVI_URL VARCHAR2(100) default null
);
/
insert into menus(menu_id,menu_name) values ('root','根菜单');
insert into menus(menu_id,menu_name,parent_id) values ('a','默认菜单a','root');
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a1','a组a1菜单0权限','a',0);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a2','a组a2菜单1权限','a',1);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a3','a组a3菜单2权限','a',2);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a1a','a1组a1a菜单0权限','a1',0);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a1b','a1组a1b菜单1权限','a1',1);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a2a','a2组a2a菜单0权限','a2',0);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a2b','a2组a2b菜单1权限','a2',1);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a1a1','a1a组a1a1菜单0权限','a1a',0);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a1a2','a1a组a1a2菜单1权限','a1a',1);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a1b1','a1b组a1b1菜单0权限','a1b',0);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a1b2','a1b组a1b2菜单1权限','a1b',1);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a1a1a','a1a1组a1a1a菜单0权限','a1a1',0);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a1a1b','a1a1组a1a1b菜单1权限','a1a1',1);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a1a2a','a1a2组a1a2a菜单0权限','a1a2',0);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a1a2b','a1a2组a1a2b菜单1权限','a1a2',1);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a1b1a','a1b1组a1b1a菜单0权限','a1b1',0);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a1b1b','a1b1组a1b1b菜单1权限','a1b1',1);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a1b2a','a1b2组a1b2a菜单0权限','a1b2',0);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('a1b2b','a1b2组a1b2b菜单1权限','a1b2',1);
insert into menus(menu_id,menu_name,parent_id) values ('b','默认菜单b','root');
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('b1','b组b1菜单0权限','b',0);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('b2','b组b2菜单1权限','b',1);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('b3','b组b3菜单2权限','b',2);
insert into menus(menu_id,menu_name,parent_id) values ('c','默认菜单c','root');
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('c1','c组c1菜单0权限','c',0);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('c2','c组c2菜单1权限','c',1);
insert into menus(menu_id,menu_name,parent_id,menu_level) values ('c3','c组c3菜单2权限','c',2);
commit;
//--------------------------------------------------------------------------------/*/
public class DrawMenus : System.Web.UI.Page
{
private string _connStr = null;
// 权限结构体
public struct RoleGroup
{
public string menuName;
public string levelStr;
};
// 默认构造函数
public DrawMenus()
{
_connStr = "ConnectionString";
}
// 可指定连接字符串的构造函数
public DrawMenus(string str)
{
_connStr = str;
}
// 连接字符串属性
public string ConnStr
{
get { return _connStr; }
set { _connStr = value; }
}
// 获取用户权限数组
// 用户分组是指数据库基础结构表USERS中的menu_group字段表达式所表明的菜单权限设定字符串,主要有以下几种情况:
// 'root': 单一分组模式,此模式下默认分配role_level字段设定的向下包含权级
// 'a,b,c': 包含权级模式,此模式下默认分配role_level字段设定的向下包含权级
// 'a|0/2,b|0/2': 特定权级模式,此模式下仅单独指定斜杠分割的特定权级,其他权级不可用
// 'a|0-1,b|1-2': 区间权级模式,此模式下仅分配横杠两端指定的区间权级,可限定权级范围,例如1-1即限定仅为权级1可用
// 'a|2,b|3,c|3': 指定权级模式,此模式下根据指定的权级向下包含权级,此模式可分别指定不同的菜单组不同权级
public List<RoleGroup> GetUserRoleGroup(string userName)
{
string menuName_character_sets = @"[^a-zA-Z\d_]*";// 菜单名限定字符集,仅限: 字母,数字,下划线(不加反斜杠)
List<RoleGroup> groupList = new List<RoleGroup>();
RoleGroup role_group;
string menu_group = null;
string role_level = null;
string strSQL = "select menu_group,role_level from USERS where username='" + userName + "'";
// 读取用户菜单和权限
OracleConnection conn = new OracleConnection(ConfigurationManager.ConnectionStrings[ConnStr].ConnectionString);
OracleCommand oracmd = new OracleCommand(strSQL, conn);
conn.Open();
OracleDataReader oradr = oracmd.ExecuteReader();
if (oradr.Read())
{
menu_group = oradr[0].ToString().Trim();
role_level = oradr[1].ToString().Trim();
}
oradr.Close();
conn.Close();
// 处理菜单权限信息
if (menu_group.IndexOf(",") == -1)
{/* 单一分组模式 */
role_group.menuName = Regex.Replace(menu_group, menuName_character_sets, "").Trim();// 非限定字符全部清空
int eNum = Convert.ToInt32(role_level);// 因为role_level必定有数字值所以无需考虑正则表达式过滤
// 组合等级权级
string roleStr = null;
for (int i = eNum; i > 0; i--)
{
roleStr += i.ToString() + ",";
}
role_group.levelStr = roleStr + "0";
groupList.Add(role_group);
}
else
{// 切分权限组
foreach (string sp1 in menu_group.Split(','))
{// 切分为菜单组级别
if (sp1.IndexOf("|") == -1)
{/* 包含权级模式 */
role_group.menuName = Regex.Replace(sp1, menuName_character_sets, "").Trim();// 非限定字符全部清空
int eNum = Convert.ToInt32(role_level);// 因为role_level必定有数字值所以无需考虑正则表达式过滤
// 组合等级权级
string roleStr = null;
for (int i = eNum; i > 0; i--)
{
roleStr += i.ToString() + ",";
}
role_group.levelStr = roleStr + "0";
}
else
{
string[] sp2 = sp1.Split('|');
role_group.menuName = Regex.Replace(sp2[0], menuName_character_sets, "").Trim();// 非限定字符全部清空
if (sp2[1].IndexOf("/") != -1)
{/* 特定权级模式 */
// 切分特定权级
string roleStr = null;
foreach (string sp3 in sp2[1].Split('/'))
{
string lvNum = Regex.Replace(sp3, @"[^\d]*", "").Trim();// 非数字全部清空
if (lvNum.Length == 0) continue;// 没有正确结果则跳过
roleStr += lvNum + ",";
}
// 设定处理失败后的默认权限组,注意失败后剩余一个逗号
roleStr = roleStr == null ? "0" : roleStr.Substring(0, roleStr.Length - 1);// 设定初始权限0,截掉末尾逗号
// 赋值
role_group.levelStr = roleStr;
}
else if (sp2[1].IndexOf("-") != -1)
{/* 区间权级模式 */
string[] sp3 = sp2[1].Split('-');
// 处理数字格式
string sNumReg = Regex.Replace(sp3[0], @"[^\d]*", "").Trim();// 非数字全部清空
string eNumReg = Regex.Replace(sp3[1], @"[^\d]*", "").Trim();// 非数字全部清空
sNumReg = sNumReg.Length == 0 ? "0" : sNumReg;// 没有正确结果则赋值0
eNumReg = eNumReg.Length == 0 ? "0" : eNumReg;// 没有正确结果则赋值0
int sNumCnv = Convert.ToInt32(sNumReg);
int eNumCnv = Convert.ToInt32(eNumReg);
// 设置大小顺序
int sNum = sNumCnv < eNumCnv ? sNumCnv : eNumCnv;
int eNum = sNumCnv < eNumCnv ? eNumCnv : sNumCnv;
// 组合区间权级
string roleStr = null;// 设定默认权级
for (int i = sNum; i <= eNum; i++)
{
roleStr += i + ",";
}
// 处理逗号
roleStr = roleStr.Substring(0, roleStr.Length - 1);
// 赋值
role_group.levelStr = roleStr;
}
else
{/* 指定权级模式 */
string eNumReg = Regex.Replace(sp2[1], @"[^\d]*", "").Trim();// 非数字全部清空
eNumReg = eNumReg.Length == 0 ? "0" : eNumReg;// 没有正确结果则赋值0
int eNum = Convert.ToInt32(eNumReg);
// 组合等级权级
string roleStr = null;
for (int i = eNum; i > 0; i--)
{
roleStr += i.ToString() + ",";
}
role_group.levelStr = roleStr + "0";
}
}
groupList.Add(role_group);
}
}
return groupList;
}
// 获取主菜单列表
public DataTable GetMainMenus(List<RoleGroup> roleList)
{
if (roleList.Count == 0) return null;
DataTable dt = new DataTable();
try
{
string cmdText = null;
string menuList = null;
for (int i = 0; i < roleList.Count; i++)
{
menuList += "'" + roleList[i].menuName + (i == (roleList.Count - 1) ? "'" : "',");
}
cmdText = "select * from MENUS where menu_id in (" + menuList + ")";
OracleConnection conn = new OracleConnection(ConfigurationManager.ConnectionStrings[ConnStr].ConnectionString);
OracleCommand oracmd = conn.CreateCommand();
oracmd.CommandText = cmdText;
OracleDataAdapter orada = new OracleDataAdapter(oracmd);
orada.Fill(dt);
}
catch
{
}
return dt;
}
// 获取完整菜单表
public DataTable GetFullMenus(string userName)
{
List<RoleGroup> roleList = GetUserRoleGroup(userName);
if (roleList.Count == 0) return null;
DataTable dt = new DataTable();
try
{
// 生成遍历树时包含根节点
string cmdText = null;
cmdText = "select * from MENUS where menu_level in (" + roleList[0].levelStr + ") connect by prior menu_id=parent_id start with menu_id='" + roleList[0].menuName + "'";
for (int i = 1; i < roleList.Count; i++)
{
cmdText += " union select * from MENUS where menu_level in (" + roleList[i].levelStr + ") connect by prior menu_id=parent_id start with menu_id='" + roleList[i].menuName + "'";
}
OracleConnection conn = new OracleConnection(ConfigurationManager.ConnectionStrings[ConnStr].ConnectionString);
OracleCommand oracmd = conn.CreateCommand();
oracmd.CommandText = cmdText;
OracleDataAdapter orada = new OracleDataAdapter(oracmd);
orada.Fill(dt);
}
catch
{
}
return dt;
}
// 添加节点
public void AddNode(TreeNodeCollection menuNodes, string menuId, string menuName, string menuImage, string menuAddress, string menuTarget)
{
TreeNode newNode = new TreeNode();
newNode.Value = menuId;
newNode.Text = menuName;
newNode.ImageUrl = menuImage.Length != 0 ? menuImage : null;
newNode.NavigateUrl = menuAddress.Length != 0 ? menuAddress : null;
newNode.Target = menuTarget;
newNode.SelectAction = TreeNodeSelectAction.SelectExpand;// 选择展开
menuNodes.Add(newNode);
}
// 递归生成菜单树
public void AddTree(TreeView menuTree, DataTable menuTable, string menuRootId, TreeNode pNode, string menuTarget)
{
try
{
DataView dvTree = new DataView(menuTable);
if (pNode == null)
{// 根节点过滤
dvTree.RowFilter = "[MENU_ID]='" + menuRootId + "'";
}
else
{// 子节点过滤
dvTree.RowFilter = "[PARENT_ID]='" + menuRootId + "'";
}
foreach (DataRowView dvRow in dvTree)
{
TreeNode newNode = new TreeNode();
newNode.Value = dvRow["MENU_ID"].ToString();
newNode.Text = dvRow["MENU_NAME"].ToString();
newNode.ImageUrl = dvRow["IMG_URL"].ToString().Length != 0 ? dvRow["IMG_URL"].ToString() : null;
newNode.NavigateUrl = dvRow["NAVI_URL"].ToString().Length != 0 ? dvRow["NAVI_URL"].ToString() : null;
newNode.Target = menuTarget;
if (newNode.NavigateUrl.Length == 0)
{// 地址为空时
newNode.SelectAction = TreeNodeSelectAction.Expand;// 点击展开
}
if (pNode == null)
{// 添加当前节点的根节点
menuTree.ShowLines = true;// 显示关联线
menuTree.Nodes.Add(newNode);
}
else
{// 添加当前节点的子节点
newNode.Expanded = false;// 子节点默认展开模式
pNode.ChildNodes.Add(newNode);
}
AddTree(menuTree, menuTable, dvRow["MENU_ID"].ToString(), newNode, menuTarget);// 递归调用
}
}
catch
{
}
}
// 生成菜单
public void ShowMenus(TreeView menuTree, string userName, string menuTarget)
{
try
{
DataTable fullMenus = GetFullMenus(userName);
List<RoleGroup> list = GetUserRoleGroup(userName);
DataTable mainMenus = GetMainMenus(list);
foreach (DataRow dr in mainMenus.Rows)
{
AddTree(menuTree, fullMenus, dr["MENU_ID"].ToString(), null, menuTarget);
}
}
catch
{
}
}
// 生成主菜单
public void ShowMainMenu(TreeView menuTree, string userName, string menuTarget)
{
menuTree.Nodes.Clear();
try
{
List<RoleGroup> list = GetUserRoleGroup(userName);
DataTable mainMenus = GetMainMenus(list);
foreach (DataRow dr in mainMenus.Rows)
{
AddNode(menuTree.Nodes, dr["MENU_ID"].ToString(), dr["MENU_NAME"].ToString(), dr["IMG_URL"].ToString(), dr["NAVI_URL"].ToString(), menuTarget);
}
}
catch
{
}
}
// 生成子菜单
public void ShowSubMenu(TreeView menuTree, string userName, string menuTarget)
{
menuTree.SelectedNode.ChildNodes.Clear();
try
{
DataTable fullMenus = GetFullMenus(userName);
DataView dv = new DataView(fullMenus);
string selectedValue = menuTree.SelectedNode.Value;
if (selectedValue == null)
{
dv.RowFilter = "[MENU_ID]='" + selectedValue + "'";
}
else
{
dv.RowFilter = "[PARENT_ID]='" + selectedValue + "'";
}
foreach (DataRow dr in dv.ToTable().Rows)
{
AddNode(menuTree.SelectedNode.ChildNodes, dr["MENU_ID"].ToString(), dr["MENU_NAME"].ToString(), dr["IMG_URL"].ToString(), dr["NAVI_URL"].ToString(), menuTarget);
}
}
catch
{
}
}
}
DrawMenus.cs
最新推荐文章于 2024-01-24 22:33:04 发布