专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »DotNet » winform:C# WinForm中实现基于角色的权限菜单 »正文

winform:C# WinForm中实现基于角色的权限菜单

来源: 发布时间:星期四, 2009年2月12日 浏览:216次 评论:0


基于角色权限菜单功能实现在有开发经验员看来仅仅是小菜然而却让许多初学者苦不堪言为此我将我近期花了几天时间写权限菜单写成文字贴上博客给初学者参考由于自己也是个正在努力学习菜鸟对问题分析和见解必然不够透彻还望过路老师们多多批评为谢!

、建立 SQL Server 数据库模型

1、原始方案

共设立了 5个实体模型:

A、操作员(Operator):存储系统登录用户名称、密码、启用状态等信息
B、权限组(RightsGroup):存储系统权限分组(即:权限角色)名称等信息
C、权限关系(RightsRelation):用于将A项和B项的间多对多关系拆解成两个对多关系
D、权限列表(RightsList):存储系统菜单项(即:权限项)标题、内部名称、权限状态等信息
E、权限组关系(RightGroupRelation):用于将B项和D项的间多对多关系拆解成两个对多关系

通过上面描述可以清楚看到C项和E项仅仅是为了拆解多对多关系而设立实体关系变得相对复杂了点稍作考虑便知既然是使用 C# WinForm + SQL Server 来完成这功能则可以考虑使用实体类来模拟数据库模型并将实体类打包成泛型集合后存储到 SQL Server 数据库 varBinary(max) 字段这样便可以将原始方案数据库模型缩减成 3个实体模型降低了关系复杂程度将原始方案稍作修改后即可得到如下改进方案

2、改进方案

如上所述改进后方案仅包含如下 3个实体模型:

A、操作员(Operator):存储系统登录用户名称、密码、启用状态、权限集合等信息
B、权限组(RightsGroup):存储系统权限分组(即:权限角色)名称、权限集合等信息
C、权限关系(RightsRelation):用于将A项和B项的间多对多关系拆解成两个对多关系

很容易看出仅将原始方案 E 项更改为 A项和 B 项字段即可将实体关系复杂度降低 40%现在我们来看看改进方案 SQL Server 数据库实现脚本代码:

-- 判断是否存在 操作员信息表(Operator)如果存在则删除表 Operator
exists(Select * From SysObjects Where Name = 'Operator')
Drop Table [Operator]
Go

-- 创建 操作员信息表(Operator)
Create Table [Operator]
(
-- 主键列自动增长 标识种子为 1
[Id] identity(1,1) Constra [PK_OperatorId] Primary Key,

-- 操作员姓名
[OperatorName] nVarChar(50) Constra [UQ_OperatorName] Unique(OperatorName) Not Null,

-- 密码
[Password] nVarChar(50) Constra [CK_Password] Check(len([Password])>=6) Not Null,

-- 操作员权限列表
[RightsList] varBinary(max) Null,

-- 用户当前状态
[State] bit Constra [DF_State] Default('true') Constra [CK_State] Check([State] in ('true','false')) Not Null,
)
Go

-- 判断是否存在 权限组信息表(RightsGroup)如果存在则删除表 RightsGroup
exists(Select * From SysObjects Where Name = 'RightsGroup')
Drop Table [RightsGroup]
Go

-- 创建 权限组信息表(RightsGroup)
Create Table [RightsGroup]
(
-- 主键列自动增长 标识种子为 1
[Id] Identity(1,1) Constra [PK_RightsGroupId] Primary Key,

-- 权限组名称
[GroupName] nVarChar(50) Constra[UQ_GroupName] Unique (GroupName) Not Null,

-- 组权限列表
[GroupRightsList] varBinary(max) Null,
)
Go

-- 判断是否存在权限关系表(RightsRelation)如果存在则删除表 RightsRelation
exists(Select * From SysObjects Where Name = 'RightsRelation')
drop table [RightsRelation]
Go

-- 创建 权限关系表(RightsRelation)
Create Table [RightsRelation]
(
-- 主键列自动增长 标识种子为 1
[Id] Identity(1, 1) Constra [PK_RightsRelationId] Primary Key,

-- 操作员 Id
[OperatorId] Constra [FK_OperatorId] Foreign Key References Operator([Id]) Not Null,

-- 权限组 Id
[RightsGroupId] Constra [FK_RightsGroupId] Foreign Key References RightsGroup([Id]) Not Null
)
Go


2、建立实体类

建立了 SQL Server 数据库模型的后我们开始建立实体类来作为权限管理数据传输载体

1、实体模型基类(ModelBase)

C#源码清单:

using ;
using .Collections.Generic;
using .Text;

CodingMouse.CMHotelManager.Model
{
/// <summary>
/// 实体模型基类
/// </summary>
[Serializable]
public ModelBase
{
#region Private Members
_id;
_modelName;
#endregion

#region Public Properties
/// <summary>
/// 实体模型 ID
/// </summary>
public Id
{
get { _id; }
{ _id = value; }
}
/// <summary>
/// 实体模型名称
/// </summary>
public ModelName
{
get { _modelName; }
{ _modelName = value; }
}
#endregion

#region Public Methods
/// <summary>
/// 无参构造
/// </summary>
public ModelBase { }

/// <summary>
/// 带参构造
/// </summary>
/// <param name="id">实体模型 ID</param>
/// <param name="modelName">实体模型名称</param>


public ModelBase( id, modelName)
{
this.Id = id;
this.ModelName = modelName;
}
#endregion
}
}


2、操作员实体类(Operator)

C#源码清单:

using ;
using .Collections.Generic;
using .Text;

CodingMouse.CMHotelManager.Model
{
/// <summary>
/// 操作员实体类
/// </summary>
[Serializable]
public Operator : ModelBase
{
#region Private Members
_password;
Dictionary<, Rights> _rightsCollection;
bool _state;
#endregion

#region Public Properties
/// <summary>
/// 操作员密码
/// </summary>
public Password
{
get { _password; }
{ _password = value; }
}
/// <summary>
/// 权限集合(键值用于存储菜单/工具栏项 Name 属性)
/// </summary>
public Dictionary<, Rights> RightsCollection
{
get { _rightsCollection; }
{ _rightsCollection = value; }
}
/// <summary>
/// 操作员状态
/// </summary>
public bool State
{
get { _state; }
{ _state = value; }
}
#endregion

#region Public Methods
/// <summary>
/// 无参构造(基类属性赋值介绍说明:Id - 操作员 ID / ModelName - 操作员名称)
/// </summary>
public Operator { }

/// <summary>
/// 带参构造
/// </summary>
/// <param name="operatorId">操作员 ID</param>
/// <param name="name">操作员名称</param>
/// <param name="password">操作员密码</param>
/// <param name="rightsCollection">权限集合(键值用于存储菜单/工具栏项 Name 属性)</param>
/// <param name="state">操作员状态</param>
public Operator(
operatorId,
name,
password,
Dictionary<, Rights> rightsCollection,
bool state)
: base(operatorId, name)
{
this.Password = password;
this.RightsCollection = rightsCollection;
this.State = state;
}
#endregion
}
}

3、权限组实体类(RightsGroup)

C#源码清单:

using ;
using .Collections.Generic;
using .Text;

CodingMouse.CMHotelManager.Model
{
/// <summary>
/// 权限组实体类
/// </summary>
[Serializable]
public RightsGroup : ModelBase
{
#region Private Members
Dictionary<, Rights> _groupRightsCollection;
#endregion

#region Public Properties
/// <summary>
/// 组权限集合
/// </summary>
public Dictionary<, Rights> GroupRightsCollection
{
get { _groupRightsCollection; }
{ _groupRightsCollection = value; }
}
#endregion

#region Public Methods
/// <summary>
/// 无参构造(基类属性赋值介绍说明:Id - 权限组 ID / ModelName - 权限组名称)
/// </summary>
public RightsGroup { }
/// <summary>
/// 带参构造
/// </summary>
/// <param name="groupId">权限组 ID</param>
/// <param name="groupName">权限组名称</param>
/// <param name="groupRightsCollection">组权限集合</param>
public RightsGroup(
groupId,
groupName,
Dictionary<, Rights> groupRightsCollection)
: base(groupId, groupName)
{
this.GroupRightsCollection = groupRightsCollection;
}
#endregion
}
}

4、权限关系实体类(RightsRelation)

C#源码清单:

using ;
using .Collections.Generic;
using .Text;

CodingMouse.CMHotelManager.Model
{
/// <summary>
/// 权限关系实体类
/// </summary>
[Serializable]
public RightsRelation
{
#region Private Members
_id;
_operatorId;
_operatorName;
_rightsGroupId;
rightsGroupName;
#endregion

#region Public Properties
/// <summary>
/// 权限关系 ID
/// </summary>
public Id
{
get { _id; }
{ _id = value; }
}
/// <summary>
/// 操作员 ID
/// </summary>
public OperatorId
{
get { _operatorId; }
{ _operatorId = value; }
}
/// <summary>
/// 操作员名称(便于在 WinForm DataGridView Control控件中实现数据绑定)
/// </summary>
public OperatorName
{
get { _operatorName; }
{ _operatorName = value; }
}
/// <summary>


/// 权限组 ID
/// </summary>
public RightsGroupId
{
get { _rightsGroupId; }
{ _rightsGroupId = value; }
}
/// <summary>
/// 权限组名称(便于在 WinForm DataGridView Control控件中实现数据绑定)
/// </summary>
public RightsGroupName
{
get { rightsGroupName; }
{ rightsGroupName = value; }
}
#endregion

#region Public Methods
/// <summary>
/// 无参构造
/// </summary>
public RightsRelation { }
/// <summary>
/// 带参构造
/// </summary>
/// <param name="id">权限关系 ID</param>
/// <param name="operatorId">操作员 ID</param>
/// <param name="operatorName">操作员名称</param>
/// <param name="rightsGroupId">权限组 ID</param>
/// <param name="rightsGroupName">权限组名称</param>
public RightsRelation(
id,
operatorId,
operatorName,
rightsGroupId,
rightsGroupName)
{
this.Id = id;
this.OperatorId = operatorId;
this.OperatorName = operatorName;
this.RightsGroupId = rightsGroupId;
this.RightsGroupName = rightsGroupName;
}
#endregion
}
}

3、具体代码实现

采用多层开发模式有助于降低耦合度便于维护所以我们本文具体代码实现也使用了多层开发模式限于篇幅只列举出具体代码实现类源码同时也是由于本文并不是讲解多层开发文章所以对于完成本文主题功能所涉及简单工厂、抽象工厂、接口定义、数据库访问等类源码就不再罗列

()数据访问层

1、操作员数据访问操作类(OperatorService)

C#源码清单:

using ;
using .Collections.Generic;
using .Text;
using .IO;
using .Data;
using .Data.SqlClient;
using .Configuration;
using .Runtime.Serialization.Formatters.Binary;
using DBUtility = CodingMouse.CMHotelManager.DBUtility;
using IDAL = CodingMouse.CMHotelManager.IDAL;
using Model = CodingMouse.CMHotelManager.Model;

CodingMouse.CMHotelManager.DAL
{
/// <summary>
/// 操作员数据访问操作类
/// </summary>
public OperatorService : IDAL.IOperatorService
{

#region IOperatorService 成员

/// <summary>
/// 根据操作员名称和密码获取操作员实体
/// </summary>
/// <param name="name">操作员名称</param>
/// <param name="pwd">操作员密码</param>
/// <s>操作员实体</s>
public Model.Operator GetOperatorInfoByName( name, pwd)
{
//SQL命令
sqltxt = .Format("Select Id, OperatorName, Password, RightsList, State From Operator Where OperatorName = '{0}' And Password = '{1}'", name, pwd);

//创建操作员实体
Model.Operator tmpOperator = Model.Operator;

// 转换数据库存储 2进制数据为 Byte 以便进而转换为操作员权限集合
// 从配置文件读取连接
connectionString = ConfigurationManager.ConnectionStrings["SQLSERVER"].ConnectionString;
// 执行 SQL 命令
using (SqlConnection conn = SqlConnection(connectionString))
{
SqlCommand cmd = SqlCommand(sqltxt, conn);
conn.Open;

using (SqlDataReader myReader = cmd.ExecuteReader(
CommandBehavior.CloseConnection |
CommandBehavior.SingleResult |
CommandBehavior.SingleRow))
{
(myReader.Read)
{
//将数据集转换成实体集合
tmpOperator.Id = Convert.ToInt32(myReader["Id"]);
tmpOperator.ModelName = Convert.(myReader["OperatorName"]);
tmpOperator.Password = Convert.(myReader["Password"]);
tmpOperator.State = Convert.ToBoolean(myReader["State"]);

// 读取权限集合
.Data.SqlTypes.SqlBytes s = myReader.GetSqlBytes(3); // 只能指定列序号
// 将流反序列化为权限集合对象
BinaryFormatter bf = BinaryFormatter;
(!s.IsNull)
tmpOperator.RightsCollection = (bf.Deserialize(s.Stream) as Dictionary<, Model.Rights>);
//
// throw Exception(.Format("操作员 [{0}] 没有任何权限禁止登录!", tmpOperator.ModelName));
}

//如果没有读取到内容则抛出异常
throw Exception("登录名称或用户密码不正确!");
}
}

// 如果操作员已经被禁用
(!tmpOperator.State)
throw Exception(.Format("操作员 [{0}] 已被禁用请和管理员联系!", tmpOperator.ModelName));
// 返回结果
tmpOperator;
}

/// <summary>
/// 添加操作员
/// </summary>
/// <param name="addOperator">要添加操作员实体</param>


/// <s>True:成功/False:失败</s>
public bool AddOperator(Model.Operator addOperator)
{
// 验证密码长度
(addOperator.Password.Trim.Length < 6)
throw Exception("用户密码长度不能小于 6位!");
// 转换操作员权限集合为数据库可存取 Byte
MemoryStream ms = MemoryStream;
BinaryFormatter bf = BinaryFormatter;
bf.Serialize(ms, addOperator.RightsCollection);
rigthsByteArray = [()(ms.Length)];
ms.Position = 0;
ms.Read(rigthsByteArray, 0, ()(ms.Length));
ms.Close;

// 拼接 SQL 命令
sqlTxt = "Insert Into Operator (OperatorName, Password, RightsList, State) Values " +
"(@OperatorName, @Password, @RightsList, @State)";

// 从配置文件读取连接
connectionString = ConfigurationManager.ConnectionStrings["SQLSERVER"].ConnectionString;
// 执行 SQL 命令
using (SqlConnection conn = SqlConnection(connectionString))
{
SqlCommand cmd = SqlCommand(sqlTxt, conn);
SqlParameter prm1 = SqlParameter("@OperatorName", SqlDbType.NVarChar, 50);
prm1.Value = addOperator.ModelName;
SqlParameter prm2 = SqlParameter("@Password", SqlDbType.NVarChar, 50);
prm2.Value = addOperator.Password;
SqlParameter prm3 = SqlParameter("@RightsList", SqlDbType.VarBinary, rigthsByteArray.Length,
ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, rigthsByteArray);
SqlParameter prm4 = SqlParameter("@State", SqlDbType.Bit);
prm4.Value = addOperator.State;

cmd.Parameters.AddRange( SqlParameter { prm1, prm2, prm3, prm4 });
conn.Open;

(cmd.ExecuteNonQuery >= 1)
true;

false;
}
}

/// <summary>
/// 删除操作员
/// </summary>
/// <param name="id">要删除操作员 ID</param>
/// <s>True:成功/False:失败</s>
public bool DeleteOperatorByID( id)
{
// 删除单个信息 SQL 命令
sqlTxt = .Format("Delete From Operator Where Id = {0}", id);
// 创建 SQL 执行对象
DBUtility.AbstractDBProvider dbProvider = DBUtility.AbstractDBProvider.Instance;
// 执行 删除操作
rowsAffected;
dbProvider.RunCommand(sqlTxt, out rowsAffected);

(rowsAffected >= 1)
true;

false;
}

/// <summary>
/// 修改操作员
/// </summary>
/// <param name="currentOperator">要修改操作员实体</param>
/// <s>True:成功/False:失败</s>
public bool ModyOperator(Model.Operator currentOperator)
{
// 验证密码长度
(currentOperator.Password.Trim.Length < 6)
throw Exception("用户密码长度不能小于 6位!");
// 转换操作员权限集合为数据库可存取 Byte
MemoryStream ms = MemoryStream;
BinaryFormatter bf = BinaryFormatter;
bf.Serialize(ms, currentOperator.RightsCollection);
rigthsByteArray = [()(ms.Length)];
ms.Position = 0;
ms.Read(rigthsByteArray, 0, ()(ms.Length));
ms.Close;

// 拼接 SQL 命令
sqlTxt = "Update Operator Set OperatorName = @OperatorName, " +
"Password = @Password, RightsList = @RightsList, State = @State Where Id = @Id";

// 从配置文件读取连接
connectionString = ConfigurationManager.ConnectionStrings["SQLSERVER"].ConnectionString;
// 执行 SQL 命令
using(SqlConnection conn = SqlConnection(connectionString))
{
SqlCommand cmd = SqlCommand(sqlTxt, conn);
SqlParameter prm1 = SqlParameter("@OperatorName", SqlDbType.NVarChar, 50);
prm1.Value = currentOperator.ModelName;
SqlParameter prm2 = SqlParameter("@Password", SqlDbType.NVarChar, 50);
prm2.Value = currentOperator.Password;
SqlParameter prm3 = SqlParameter("@RightsList", SqlDbType.VarBinary, rigthsByteArray.Length,
ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, rigthsByteArray);
SqlParameter prm4 = SqlParameter("@State", SqlDbType.Bit);
prm4.Value = currentOperator.State;
SqlParameter prm5 = SqlParameter("@Id", SqlDbType.Int);
prm5.Value = currentOperator.Id;

cmd.Parameters.AddRange( SqlParameter { prm1, prm2, prm3, prm4, prm5 });
conn.Open;

(cmd.ExecuteNonQuery >= 1)
true;

false;
}
}

/// <summary>
/// 获取所有操作员信息
/// </summary>
/// <s>操作员实体集合</s>
public Dictionary<, Model.Operator> GetAllOperatorInfo


{
//SQL命令
sqltxt = "Select Id, OperatorName, Password, RightsList, State From Operator";
//创建操作员实体集合
Dictionary<, Model.Operator> operatorCollection = Dictionary<, Model.Operator>;
//定义操作员实体
Model.Operator tmpOperator = null;

// 转换数据库存储 2进制数据为 Byte 以便进而转换为操作员权限集合
// 从配置文件读取连接
connectionString = ConfigurationManager.ConnectionStrings["SQLSERVER"].ConnectionString;
// 执行 SQL 命令
using (SqlConnection conn = SqlConnection(connectionString))
{
SqlCommand cmd = SqlCommand(sqltxt, conn);
conn.Open;

using (SqlDataReader myReader = cmd.ExecuteReader(
CommandBehavior.CloseConnection))
{
while (myReader.Read)
{
// 创建操作员实体
tmpOperator = Model.Operator;
//将数据集转换成实体集合
tmpOperator.Id = Convert.ToInt32(myReader["Id"]);
tmpOperator.ModelName = Convert.(myReader["OperatorName"]);
tmpOperator.Password = Convert.(myReader["Password"]);
tmpOperator.State = Convert.ToBoolean(myReader["State"]);

// 读取权限集合
.Data.SqlTypes.SqlBytes s = myReader.GetSqlBytes(3); // 只能指定列序号
// 将流反序列化为权限集合对象
BinaryFormatter bf = BinaryFormatter;
(!s.IsNull)
tmpOperator.RightsCollection = (bf.Deserialize(s.Stream) as Dictionary<, Model.Rights>);

// 添加到操作员实体集合
operatorCollection.Add(tmpOperator.ModelName, tmpOperator);
}
}
}

// 返回结果
operatorCollection;
}

/// <summary>
/// 根据操作员名称校验操作员是否存在
/// </summary>
/// <param name="operatorName">操作员名称</param>
/// <s>True:存在/Flase:不存在</s>
public bool CheckOperatorExist( operatorName)
{
//创建查询信息 SQL
sqlTxt = .Format(
"Select Count(*) From Operator Where OperatorName = '{0}'",
operatorName);
//创建SQL执行对象
DBUtility.AbstractDBProvider dbProvider = DBUtility.AbstractDBProvider.Instance;
//执行查询操作
result = Convert.ToInt32(dbProvider.RunCommand(sqlTxt));

(result >= 1)
true;

false;
}

#endregion
}
}

2、权限组数据访问操作类(RightsGroupService)

C#源码清单:

using ;
using .Collections.Generic;
using .Text;
using .IO;
using .Data;
using .Data.SqlClient;
using .Configuration;
using .Runtime.Serialization.Formatters.Binary;
using DBUtility = CodingMouse.CMHotelManager.DBUtility;
using IDAL = CodingMouse.CMHotelManager.IDAL;
using Model = CodingMouse.CMHotelManager.Model;

CodingMouse.CMHotelManager.DAL
{
/// <summary>
/// 权限组数据访问操作类
/// </summary>
public RightsGroupService : IDAL.IRightsGroupService
{
#region IRightsGroupService 成员

/// <summary>
/// 获取所有权限组信息
/// </summary>
/// <s>权限组实体集合</s>
public Dictionary<, Model.RightsGroup> GetAllRightsGroupInfo
{
//SQL命令
sqltxt = "Select Id, GroupName, GroupRightsList From RightsGroup";
//创建权限组实体集合
Dictionary<, Model.RightsGroup> rightsGroupCollection = Dictionary<, Model.RightsGroup>;
//定义权限组实体
Model.RightsGroup tmpRightsGroup = null;

// 转换数据库存储 2进制数据为 Byte 以便进而转换为权限组权限集合
// 从配置文件读取连接
connectionString = ConfigurationManager.ConnectionStrings["SQLSERVER"].ConnectionString;
// 执行 SQL 命令
using (SqlConnection conn = SqlConnection(connectionString))
{
SqlCommand cmd = SqlCommand(sqltxt, conn);
conn.Open;

using (SqlDataReader myReader = cmd.ExecuteReader(
CommandBehavior.CloseConnection))
{
while (myReader.Read)
{
// 创建权限组实体
tmpRightsGroup = Model.RightsGroup;
//将数据集转换成实体集合
tmpRightsGroup.Id = Convert.ToInt32(myReader["Id"]);
tmpRightsGroup.ModelName = Convert.(myReader["GroupName"]);

// 读取权限集合
.Data.SqlTypes.SqlBytes s = myReader.GetSqlBytes(2); // 只能指定列序号
// 将流反序列化为权限集合对象
BinaryFormatter bf = BinaryFormatter;
(!s.IsNull)
tmpRightsGroup.GroupRightsCollection = (bf.Deserialize(s.Stream) as Dictionary<, Model.Rights>);

// 添加到权限组实体集合


rightsGroupCollection.Add(tmpRightsGroup.ModelName, tmpRightsGroup);
}
}
}

// 返回结果
rightsGroupCollection;
}

/// <summary>
/// 添加权限组
/// </summary>
/// <param name="addRightsGroup">要添加权限组实体</param>
/// <s>True:成功/False:失败</s>
public bool AddRightsGroup(Model.RightsGroup addRightsGroup)
{
// 转换权限组权限集合为数据库可存取 Byte
MemoryStream ms = MemoryStream;
BinaryFormatter bf = BinaryFormatter;
bf.Serialize(ms, addRightsGroup.GroupRightsCollection);
rigthsByteArray = [()(ms.Length)];
ms.Position = 0;
ms.Read(rigthsByteArray, 0, ()(ms.Length));
ms.Close;

// 拼接 SQL 命令
sqlTxt = "Insert Into RightsGroup (GroupName, GroupRightsList) Values " +
"(@GroupName, @GroupRightsList)";

// 从配置文件读取连接
connectionString = ConfigurationManager.ConnectionStrings["SQLSERVER"].ConnectionString;
// 执行 SQL 命令
using (SqlConnection conn = SqlConnection(connectionString))
{
SqlCommand cmd = SqlCommand(sqlTxt, conn);
SqlParameter prm1 = SqlParameter("@GroupName", SqlDbType.NVarChar, 50);
prm1.Value = addRightsGroup.ModelName;
SqlParameter prm2 = SqlParameter("@GroupRightsList", SqlDbType.VarBinary, rigthsByteArray.Length,
ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, rigthsByteArray);

cmd.Parameters.AddRange( SqlParameter { prm1, prm2 });
conn.Open;

(cmd.ExecuteNonQuery >= 1)
true;

false;
}
}

/// <summary>
/// 删除权限组
/// </summary>
/// <param name="id">要删除权限组 ID</param>
/// <s>True:成功/False:失败</s>
public bool DeleteRightsGroupByID( id)
{
// 删除单个信息 SQL 命令
sqlTxt = .Format("Delete From RightsGroup Where Id = {0}", id);
// 创建 SQL 执行对象
DBUtility.AbstractDBProvider dbProvider = DBUtility.AbstractDBProvider.Instance;
// 执行 删除操作
rowsAffected;
dbProvider.RunCommand(sqlTxt, out rowsAffected);

(rowsAffected >= 1)
true;

false;
}

/// <summary>
/// 修改权限组
/// </summary>
/// <param name="currentRightsGroup">要修改权限组实体</param>
/// <s>True:成功/False:失败</s>
public bool ModyRightsGroup(Model.RightsGroup currentRightsGroup)
{
// 转换权限组权限集合为数据库可存取 Byte
MemoryStream ms = MemoryStream;
BinaryFormatter bf = BinaryFormatter;
bf.Serialize(ms, currentRightsGroup.GroupRightsCollection);
rigthsByteArray = [()(ms.Length)];
ms.Position = 0;
ms.Read(rigthsByteArray, 0, ()(ms.Length));
ms.Close;

// 拼接 SQL 命令
sqlTxt = "Update RightsGroup Set GroupName = @GroupName, GroupRightsList = @GroupRightsList Where Id = @Id";

// 从配置文件读取连接
connectionString = ConfigurationManager.ConnectionStrings["SQLSERVER"].ConnectionString;
// 执行 SQL 命令
using (SqlConnection conn = SqlConnection(connectionString))
{
SqlCommand cmd = SqlCommand(sqlTxt, conn);
SqlParameter prm1 = SqlParameter("@GroupName", SqlDbType.NVarChar, 50);
prm1.Value = currentRightsGroup.ModelName;
SqlParameter prm2 = SqlParameter("@GroupRightsList", SqlDbType.VarBinary, rigthsByteArray.Length,
ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, rigthsByteArray);
SqlParameter prm3 = SqlParameter("@Id", SqlDbType.Int);
prm3.Value = currentRightsGroup.Id;

cmd.Parameters.AddRange( SqlParameter { prm1, prm2, prm3 });
conn.Open;

(cmd.ExecuteNonQuery >= 1)
true;

false;
}
}

/// <summary>
/// 根据权限组名称校验权限组是否已经存在
/// </summary>
/// <param name="rightsGroupName">权限组名称</param>
/// <s>True:存在/False:不存在</s>
public bool CheckRightsGroupExist( rightsGroupName)
{
//SQL命令
sqlTxt = .Format("Select Count(*) From RightsGroup Where GroupName = '{0}'", rightsGroupName);

//创建SQL执行对象
DBUtility.AbstractDBProvider dbProvider = DBUtility.AbstractDBProvider.Instance;
//执行查询操作
result = Convert.ToInt32(dbProvider.RunCommand(sqlTxt));

(result >= 1)
true;



false;
}

#endregion
}
}

3、权限关系数据访问操作类(RightsRelationService)

C#源码清单:

using ;
using .Collections.Generic;
using .Text;
using .Data;
using .Data.SqlClient;
using DBUtility = CodingMouse.CMHotelManager.DBUtility;
using IDAL = CodingMouse.CMHotelManager.IDAL;
using Model = CodingMouse.CMHotelManager.Model;

CodingMouse.CMHotelManager.DAL
{
/// <summary>
/// 权限关系数据访问操作类
/// </summary>
public RightsRelationService : IDAL.IRightsRelationService
{
#region IRightsRelationService 成员

/// <summary>
/// 添加单个权限关系
/// </summary>
/// <param name="rightsRelation">权限关系实体</param>
/// <s>True:成功/False:失败</s>
public bool AddRightsRelation(Model.RightsRelation rightsRelation)
{
// 拼接 SQL 命令
sqlTxt = .Format(
"Insert Into RightsRelation (OperatorId, RightsGroupId) " +
"Values ({0}, {1})",
rightsRelation.OperatorId, rightsRelation.RightsGroupId);

// 创建 SQL 执行对象
DBUtility.AbstractDBProvider dbProvider = DBUtility.AbstractDBProvider.Instance;
// 执行 SQL
rowsAffected;
dbProvider.RunCommand(sqlTxt, out rowsAffected);

(rowsAffected 1)
{
true;
}

{
false;
}
}

/// <summary>
/// 根据权限关系 ID 删除权限关系
/// </summary>
/// <param name="id">权限关系 ID</param>
/// <s>True:成功/False:失败</s>
public bool DeleteRightsRelationById( id)
{
bool isOk = false;

// 删除单个信息 SQL 命令
sqlTxt = .Format("Delete From RightsRelation Where Id = {0}", id);
// 创建 SQL 执行对象
DBUtility.AbstractDBProvider dbProvider = DBUtility.AbstractDBProvider.Instance;
// 执行 删除操作
rowsAffected;
dbProvider.RunCommand(sqlTxt, out rowsAffected);

(rowsAffected >= 1)
{
isOk = true;
}

{
isOk = false;
}

isOk;
}

/// <summary>
/// 根据操作员 ID 删除对应所有权限关系
/// </summary>
/// <param name="operatorId">操作员 ID</param>
/// <s>True:成功/False:失败</s>
public bool DeleteRightsRelationByOperatorId( operatorId)
{
bool isOk = false;

// 删除单个信息 SQL 命令
sqlTxt = .Format("Delete From RightsRelation Where OperatorId = {0}", operatorId);
// 创建 SQL 执行对象
DBUtility.AbstractDBProvider dbProvider = DBUtility.AbstractDBProvider.Instance;
// 执行 删除操作
rowsAffected;
dbProvider.RunCommand(sqlTxt, out rowsAffected);

(rowsAffected >= 1)
{
isOk = true;
}

{
isOk = false;
}

isOk;
}

/// <summary>
/// 修改单个权限关系
/// </summary>
/// <param name="rightsRelation">权限关系实体</param>
/// <s>True:成功/False:失败</s>
public bool ModyRightsRelation(Model.RightsRelation rightsRelation)
{
// 拼接 SQL 命令
sqlTxt = .Format(
"Update RightsRelation Set OperatorId = {0}, RightsGroupId = {1} Where Id = {2}",
rightsRelation.OperatorId, rightsRelation.RightsGroupId, rightsRelation.Id);

// 创建 SQL 执行对象
DBUtility.AbstractDBProvider dbProvider = DBUtility.AbstractDBProvider.Instance;
// 执行 SQL
rowsAffected;
dbProvider.RunCommand(sqlTxt, out rowsAffected);

(rowsAffected 1)
{
true;
}

{
false;
}
}

/// <summary>
/// 获取所有权限关系集合
/// </summary>
/// <s>权限关系集合</s>
public List<Model.RightsRelation> GetAllRightsRelation
{
//创建数据集
DataSet dsRightsRelation = DataSet("RightsRelation");
//创建客户集合
List<Model.RightsRelation> rightsRelationList = List<Model.RightsRelation>;
//创建查询客户信息 SQL
sqlTxt = "Select R.Id, R.OperatorId, O.OperatorName, R.RightsGroupId, " +
"G.GroupName As [RightsGroupName] From RightsRelation As R Join Operator As O " +
"On R.OperatorId = O.Id Join RightsGroup As G _disibledevent=>//创建SQL执行对象
DBUtility.AbstractDBProvider dbProvider = DBUtility.AbstractDBProvider.Instance;
//执行查询操作
dsRightsRelation = dbProvider.RunCommand(sqlTxt, "RightsRelation");


//将数据集转换成实体集合
foreach (DataRow row in dsRightsRelation.Tables["RightsRelation"].Rows)
{
Model.RightsRelation tmpRightsRelation = Model.RightsRelation;
tmpRightsRelation.Id = Convert.ToInt32(row["Id"]);
tmpRightsRelation.OperatorId = Convert.ToInt32(row["OperatorId"]);
tmpRightsRelation.OperatorName = Convert.(row["OperatorName"]);
tmpRightsRelation.RightsGroupId = Convert.ToInt32(row["RightsGroupId"]);
tmpRightsRelation.RightsGroupName = Convert.(row["RightsGroupName"]);

rightsRelationList.Add(tmpRightsRelation);
}

//返回所有客户集合
rightsRelationList;
}

/// <summary>
/// 根据操作员 ID 获取对应所有权限关系
/// </summary>
/// <param name="id">操作员 ID</param>
/// <s>权限关系集合</s>
public List<Model.RightsRelation> GetRightsRelationByOperatorId( id)
{
//创建数据集
DataSet dsRightsRelation = DataSet("RightsRelation");
//创建客户集合
List<Model.RightsRelation> rightsRelationList = List<Model.RightsRelation>;
//创建查询客户信息 SQL
sqlTxt = .Format("Select R.Id, R.OperatorId, O.OperatorName, R.RightsGroupId, " +
"G.GroupName As [RightsGroupName] From RightsRelation As R Join Operator As O " +
"On R.OperatorId = O.Id Join RightsGroup As G _disibledevent=>"Where OperatorId = {0}", id);
//创建SQL执行对象
DBUtility.AbstractDBProvider dbProvider = DBUtility.AbstractDBProvider.Instance;
//执行查询操作
dsRightsRelation = dbProvider.RunCommand(sqlTxt, "RightsRelation");
//将数据集转换成实体集合
foreach (DataRow row in dsRightsRelation.Tables["RightsRelation"].Rows)
{
Model.RightsRelation tmpRightsRelation = Model.RightsRelation;
tmpRightsRelation.Id = Convert.ToInt32(row["Id"]);
tmpRightsRelation.OperatorId = Convert.ToInt32(row["OperatorId"]);
tmpRightsRelation.OperatorName = Convert.(row["OperatorName"]);
tmpRightsRelation.RightsGroupId = Convert.ToInt32(row["RightsGroupId"]);
tmpRightsRelation.RightsGroupName = Convert.(row["RightsGroupName"]);

rightsRelationList.Add(tmpRightsRelation);
}

//返回所有客户集合
rightsRelationList;
}

/// <summary>
/// 根据权限组 ID 获取和此权限组相关权限关系数量
/// </summary>
/// <param name="id">权限组 ID</param>
/// <s>权限关系数量</s>
public GetRightsRelationCountByRightsGroupId( id)
{
// SQL命令
sqlTxt = .Format("Select Count(*) From RightsRelation Where RightsGroupId = {0}", id);

// 创建SQL执行对象
DBUtility.AbstractDBProvider dbProvider = DBUtility.AbstractDBProvider.Instance;
// 执行查询操作
result = Convert.ToInt32(dbProvider.RunCommand(sqlTxt));

// 返回结果
result;
}

#endregion
}
}

( 2)业务逻辑层(在本文中仅仅起到个数据传递者作用)

1、操作员数据访问操作类(OperatorManager)

C#源代码清单

using ;
using .Collections.Generic;
using .Text;
using DALFactory = CodingMouse.CMHotelManager.DALFactory;
using IBLL = CodingMouse.CMHotelManager.IBLL;
using IDAL = CodingMouse.CMHotelManager.IDAL;
using Model = CodingMouse.CMHotelManager.Model;

CodingMouse.CMHotelManager.BLL
{
/// <summary>
/// 操作员数据访问操作类
/// </summary>
public OperatorManager : IBLL.IOperatorManager
{

#region IOperatorManager 成员

/// <summary>
/// 根据操作员名称和密码获取操作员实体
/// </summary>
/// <param name="name">操作员名称</param>
/// <param name="pwd">操作员密码</param>
/// <s>操作员实体</s>
public Model.Operator GetOperatorInfoByName( name, pwd)
{
// 超级后门管理员账户(测试用千万别用于商业用途要不然被抓去坐监可别怪我!)
(name "CodingMouse" && pwd "20071117")
{
Model.Operator adminOperator = Model.Operator;
adminOperator.Id = 0;
adminOperator.ModelName = name;
adminOperator.Password = pwd;
adminOperator.RightsCollection = Dictionary<, Model.Rights>;
adminOperator.State = true;

adminOperator;
}

//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子


IDAL.IOperatorService operatorService = absDALFactory.BuildOperatorService;
//例子思路方法
operatorService.GetOperatorInfoByName(name, pwd);
}

/// <summary>
/// 添加操作员
/// </summary>
/// <param name="addOperator">要添加操作员实体</param>
/// <s>True:成功/False:失败</s>
public bool AddOperator(Model.Operator addOperator)
{
//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子
IDAL.IOperatorService operatorService = absDALFactory.BuildOperatorService;
//例子思路方法
operatorService.AddOperator(addOperator);
}

/// <summary>
/// 删除操作员
/// </summary>
/// <param name="id">要删除操作员 ID</param>
/// <s>True:成功/False:失败</s>
public bool DeleteOperatorByID( id)
{
//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子
IDAL.IOperatorService operatorService = absDALFactory.BuildOperatorService;
//例子思路方法
operatorService.DeleteOperatorByID(id);
}

/// <summary>
/// 修改操作员
/// </summary>
/// <param name="currentOperator">要修改操作员实体</param>
/// <s>True:成功/False:失败</s>
public bool ModyOperator(Model.Operator currentOperator)
{
//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子
IDAL.IOperatorService operatorService = absDALFactory.BuildOperatorService;
//例子思路方法
operatorService.ModyOperator(currentOperator);
}

/// <summary>
/// 获取所有操作员信息
/// </summary>
/// <s>操作员实体集合</s>
public Dictionary<, Model.Operator> GetAllOperatorInfo
{
//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子
IDAL.IOperatorService operatorService = absDALFactory.BuildOperatorService;
//例子思路方法
operatorService.GetAllOperatorInfo;
}

/// <summary>
/// 根据操作员名称校验操作员是否存在
/// </summary>
/// <param name="operatorName">操作员名称</param>
/// <s>True:存在/Flase:不存在</s>
public bool CheckOperatorExist( operatorName)
{
//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子
IDAL.IOperatorService operatorService = absDALFactory.BuildOperatorService;
//例子思路方法
operatorService.CheckOperatorExist(operatorName);
}

#endregion
}
}

2、权限组数据访问操作类(RightsGroupManager)

C#源码清单:

using ;
using .Collections.Generic;
using .Text;
using DALFactory = CodingMouse.CMHotelManager.DALFactory;
using IBLL = CodingMouse.CMHotelManager.IBLL;
using IDAL = CodingMouse.CMHotelManager.IDAL;
using Model = CodingMouse.CMHotelManager.Model;

CodingMouse.CMHotelManager.BLL
{
/// <summary>
/// 权限组数据访问操作类
/// </summary>
public RightsGroupManager : IBLL.IRightsGroupManager
{
#region IRightsGroupManager 成员

/// <summary>
/// 获取所有权限组信息
/// </summary>
/// <s>权限组实体集合</s>
public Dictionary<, Model.RightsGroup> GetAllRightsGroupInfo
{
//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子
IDAL.IRightsGroupService rightsGroupService = absDALFactory.BuildRightsGroupService;
//例子思路方法
rightsGroupService.GetAllRightsGroupInfo;
}

/// <summary>
/// 添加权限组
/// </summary>
/// <param name="addRightsGroup">要添加权限组实体</param>
/// <s>True:成功/False:失败</s>
public bool AddRightsGroup(Model.RightsGroup addRightsGroup)
{
//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子
IDAL.IRightsGroupService rightsGroupService = absDALFactory.BuildRightsGroupService;
//例子思路方法
rightsGroupService.AddRightsGroup(addRightsGroup);
}

/// <summary>


/// 删除权限组
/// </summary>
/// <param name="id">要删除权限组 ID</param>
/// <s>True:成功/False:失败</s>
public bool DeleteRightsGroupByID( id)
{
//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子
IDAL.IRightsGroupService rightsGroupService = absDALFactory.BuildRightsGroupService;
//例子思路方法
rightsGroupService.DeleteRightsGroupByID(id);
}

/// <summary>
/// 修改权限组
/// </summary>
/// <param name="currentRightsGroup">要修改权限组实体</param>
/// <s>True:成功/False:失败</s>
public bool ModyRightsGroup(Model.RightsGroup currentRightsGroup)
{
//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子
IDAL.IRightsGroupService rightsGroupService = absDALFactory.BuildRightsGroupService;
//例子思路方法
rightsGroupService.ModyRightsGroup(currentRightsGroup);
}

/// <summary>
/// 根据权限组名称校验权限组是否已经存在
/// </summary>
/// <param name="rightsGroupName">权限组名称</param>
/// <s>True:存在/False:不存在</s>
public bool CheckRightsGroupExist( rightsGroupName)
{
//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子
IDAL.IRightsGroupService rightsGroupService = absDALFactory.BuildRightsGroupService;
//例子思路方法
rightsGroupService.CheckRightsGroupExist(rightsGroupName);
}

#endregion
}
}

3、权限关系数据访问操作类(RightsRelationManager)

C#源码清单:

using ;
using .Collections.Generic;
using .Text;
using DALFactory = CodingMouse.CMHotelManager.DALFactory;
using IBLL = CodingMouse.CMHotelManager.IBLL;
using IDAL = CodingMouse.CMHotelManager.IDAL;
using Model = CodingMouse.CMHotelManager.Model;

CodingMouse.CMHotelManager.BLL
{
/// <summary>
/// 权限关系数据访问操作类
/// </summary>
public RightsRelationManager : IBLL.IRightsRelationManager
{
#region IRightsRelationManager 成员

/// <summary>
/// 添加单个权限关系
/// </summary>
/// <param name="rightsRelation">权限关系实体</param>
/// <s>True:成功/False:失败</s>
public bool AddRightsRelation(Model.RightsRelation rightsRelation)
{
//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子
IDAL.IRightsRelationService rightsRelationService = absDALFactory.BuildRightsRelationService;
//例子思路方法
rightsRelationService.AddRightsRelation(rightsRelation);
}

/// <summary>
/// 根据权限关系 ID 删除权限关系
/// </summary>
/// <param name="id">权限关系 ID</param>
/// <s>True:成功/False:失败</s>
public bool DeleteRightsRelationById( id)
{
//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子
IDAL.IRightsRelationService rightsRelationService = absDALFactory.BuildRightsRelationService;
//例子思路方法
rightsRelationService.DeleteRightsRelationById(id);
}

/// <summary>
/// 根据操作员 ID 删除对应所有权限关系
/// </summary>
/// <param name="operatorId">操作员 ID</param>
/// <s>True:成功/False:失败</s>
public bool DeleteRightsRelationByOperatorId( operatorId)
{
//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子
IDAL.IRightsRelationService rightsRelationService = absDALFactory.BuildRightsRelationService;
//例子思路方法
rightsRelationService.DeleteRightsRelationByOperatorId(operatorId);
}

/// <summary>
/// 修改单个权限关系
/// </summary>
/// <param name="rightsRelation">权限关系实体</param>
/// <s>True:成功/False:失败</s>
public bool ModyRightsRelation(Model.RightsRelation rightsRelation)
{
//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子
IDAL.IRightsRelationService rightsRelationService = absDALFactory.BuildRightsRelationService;


//例子思路方法
rightsRelationService.ModyRightsRelation(rightsRelation);
}

/// <summary>
/// 获取所有权限关系集合
/// </summary>
/// <s>权限关系集合</s>
public List<Model.RightsRelation> GetAllRightsRelation
{
//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子
IDAL.IRightsRelationService rightsRelationService = absDALFactory.BuildRightsRelationService;
//例子思路方法
rightsRelationService.GetAllRightsRelation;
}

/// <summary>
/// 根据操作员 ID 获取对应所有权限关系
/// </summary>
/// <param name="id">操作员 ID</param>
/// <s>权限关系集合</s>
public List<Model.RightsRelation> GetRightsRelationByOperatorId( id)
{
//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子
IDAL.IRightsRelationService rightsRelationService = absDALFactory.BuildRightsRelationService;
//例子思路方法
rightsRelationService.GetRightsRelationByOperatorId(id);
}

/// <summary>
/// 根据权限组 ID 获取和此权限组相关权限关系数量
/// </summary>
/// <param name="id">权限组 ID</param>
/// <s>权限关系数量</s>
public GetRightsRelationCountByRightsGroupId( id)
{
//定义并例子化抽象工厂类
DALFactory.AbstractDALFactory absDALFactory = DALFactory.AbstractDALFactory.Instance;
//工厂思路方法生成例子
IDAL.IRightsRelationService rightsRelationService = absDALFactory.BuildRightsRelationService;
//例子思路方法
rightsRelationService.GetRightsRelationCountByRightsGroupId(id);
}

#endregion
}
}

( 3)界面表示层(由于界面操作逻辑复杂度较高在此仅列出部分难点代码)

1、权限菜单数据管理类(RightsMenuDataManager)

C#源码清单:

using ;
using .Collections.Generic;
using .Text;
using .Windows.Forms;
using Model = CodingMouse.CMHotelManager.Model;

CodingMouse.CMHotelManager.UI.Common
{
/// <summary>
/// 权限菜单数据管理类
/// </summary>
public RightsMenuDataManager
{
#region Private Members
/// <summary>
/// 保存当前被管理菜单对象
/// </summary>
MenuStrip _msMain = null;
/// <summary>
/// 保存当前权限项 ID
/// </summary>
_rightsId = 0;
#endregion

#region Internal Properties
/// <summary>
/// 被管理菜单对象
/// </summary>
ernal MenuStrip MsMain
{
get { _msMain; }
{ _msMain = value; }
}
#endregion

#region Private Methods
/// <summary>
/// 使用递归法读取菜单权限子项
/// </summary>
/// <param name="rightCollection">要保存到菜单根项权限集合</param>
/// <param name="tsmiRootLevel">当前菜单权限相对根项</param>
private Model.Rights GetMenuRightsChildrenItem(Dictionary<, Model.Rights> rightCollection, ToolStripMenuItem tsmiRootLevel)
{
// 显示下级菜单项元素 Text
Model.Rights secondRights = null;

// 使用 ToolStripItem 基类遍历获取下级菜单项
foreach (ToolStripItem tsmiNextLevel in tsmiRootLevel.DropDownItems)
{
// ID 号累加
_rightsId;
// 显示下级菜单项元素 Text
secondRights = Model.Rights;
secondRights.Id = _rightsId;
secondRights.ModelName = tsmiNextLevel.Name;
secondRights.RightsState = false;
secondRights.ParentLevelRightsName = rightCollection[tsmiRootLevel.Name].ModelName;

// 如果是菜单项而不是其它菜单项类型
(tsmiNextLevel is ToolStripMenuItem)
{
secondRights.RightsCaption = tsmiNextLevel.Text;
// 添加当前项到集合
rightCollection.Add(secondRights.ModelName, secondRights);
// 使用递归添加所有次级子项到集合
GetMenuRightsChildrenItem(rightCollection, tsmiNextLevel as ToolStripMenuItem);
}
// 如果是分隔项而不是其它菜单项类型
(tsmiNextLevel is ToolStripSeparator)
{
secondRights.RightsCaption = "━━━━";
// 添加此菜单分隔项到集合
rightCollection.Add((tsmiNextLevel as ToolStripSeparator).Name, secondRights);
}
}

secondRights;
}
/// <summary>
/// 使用递归法加载菜单权限子项
/// </summary>
/// <param name="rightCollection">权限集合</param>
/// <param name="tsmiRootLevel">当前菜单权限相对根项</param>
private void LoadMenuRightsChildrenItem(Dictionary<, Model.Rights> rightCollection, ToolStripMenuItem tsmiRootLevel)


{
// 使用 ToolStripItem 基类遍历获取下级菜单项
foreach (ToolStripItem tsmiNextLevel in tsmiRootLevel.DropDownItems)
{
foreach (Model.Rights tmpRights in rightCollection.Values)
{
// 如果是菜单项而不是其它菜单项类型
(tsmiNextLevel is ToolStripMenuItem)
{
// 如果内部名称相同
(tsmiNextLevel.Name tmpRights.ModelName)
{
// 设置名称和显隐状态
tsmiNextLevel.Text = tmpRights.RightsCaption;
tsmiNextLevel.Visible = tmpRights.RightsState;

// 使用递归加载所有次级子项
LoadMenuRightsChildrenItem(rightCollection, tsmiNextLevel as ToolStripMenuItem);
;
}
}
// 如果是分隔项而不是其它菜单项类型
(tsmiNextLevel is ToolStripSeparator)
{
// 如果内部名称相同
(tsmiNextLevel.Name tmpRights.ModelName)
{
// 设置显隐状态
tsmiNextLevel.Visible = tmpRights.RightsState;
;
}
}
}
}
}
#endregion

#region Internal Methods
/// <summary>
/// 使用递归法读取菜单权限项
/// </summary>
/// <param name="rightCollection">要保存到目标权限集合</param>
/// <s>权限集合</s>
ernal Dictionary<, Model.Rights> ReadMenuRightsItem(Dictionary<, Model.Rights> rightCollection)
{
(!(this.MsMain is MenuStrip))
throw Exception("未指定被管理菜单对象!请使用本思路方法重载指定菜单对象!");

// 重载
this.ReadMenuRightsItem(this._msMain, rightCollection);
}
/// <summary>
/// 使用递归法读取菜单权限项
/// </summary>
/// <param name="msCurrentMenu">当前被管理菜单对象</param>
/// <param name="rightCollection">要保存到目标权限集合</param>
/// <s>权限集合</s>
ernal Dictionary<, Model.Rights> ReadMenuRightsItem(MenuStrip msCurrentMenu, Dictionary<, Model.Rights> rightCollection)
{
// 遍历获取菜单根项
foreach (ToolStripMenuItem tsmiRootLevel in msCurrentMenu.Items)
{
(tsmiRootLevel is ToolStripMenuItem)
{
// ID 号累加
_rightsId;
// 显示菜单根项元素 Text
Model.Rights rootRights = Model.Rights;
rootRights.Id = _rightsId;
rootRights.ModelName = tsmiRootLevel.Name;
rootRights.RightsCaption = tsmiRootLevel.Text;
rootRights.RightsState = false;
rootRights.ParentLevelRightsName = msCurrentMenu.Name;

// 如果未添加此权限则添加此权限到菜单根项权限集合
bool isExist = false;
foreach (Model.Rights tmpRights in rightCollection.Values)
{
(tmpRights.ModelName rootRights.ModelName)
isExist = true;
}
(!isExist)
rightCollection.Add(rootRights.ModelName, rootRights);

// 使用递归添加所有子项
GetMenuRightsChildrenItem(rightCollection, tsmiRootLevel);
}
}

rightCollection;
}
/// <summary>
/// 使用递归法加载菜单权限项
/// </summary>
/// <param name="rightCollection">要保存到目标权限集合</param>
/// <s>权限集合</s>
ernal void LoadMenuRightsItem(Dictionary<, Model.Rights> rightCollection)
{
(!(this.MsMain is MenuStrip))
throw Exception("未指定被管理菜单对象!请使用本思路方法重载指定菜单对象!");

// 重载
this.LoadMenuRightsItem(this._msMain, rightCollection);
}
/// <summary>
/// 使用递归法加载菜单权限项
/// </summary>
/// <param name="msCurrentMenu">当前被管理菜单对象</param>
/// <param name="rightCollection">权限集合</param>
ernal void LoadMenuRightsItem(MenuStrip msCurrentMenu, Dictionary<, Model.Rights> rightCollection)
{
foreach (Model.Rights tmpRights in rightCollection.Values)
{
// 遍历获取菜单根项
foreach (ToolStripMenuItem tsmiRootLevel in msCurrentMenu.Items)
{
(tsmiRootLevel is ToolStripMenuItem)
{
// 如果内部名称相同
(tsmiRootLevel.Name tmpRights.ModelName)
{
// 设置名称和显隐状态
tsmiRootLevel.Text = tmpRights.RightsCaption;
tsmiRootLevel.Visible = tmpRights.RightsState;
// 使用递归加载所有子项
LoadMenuRightsChildrenItem(rightCollection, tsmiRootLevel);
;
}
}
}
}
}
#endregion
}
}

2、权限菜单界面管理类(RightsMenuUIManager)

C#源码清单:

using ;
using .Collections.Generic;
using .Text;
using .Drawing;
using .Windows.Forms;
using IBLL = CodingMouse.CMHotelManager.IBLL;
using BLLFactory = CodingMouse.CMHotelManager.BLLFactory;
using Model = CodingMouse.CMHotelManager.Model;



CodingMouse.CMHotelManager.UI.Common
{
/// <summary>
/// 权限菜单界面管理类
/// </summary>
public RightsMenuUIManager
{
#region Private Members
DataGridView _dgvOperatorList = null;
DataGridView _dgvRightsList = null;
TreeView _tvRightsView = null;
MenuStrip _msMain = null;
Forms.frmRightsManager _rightsManagerUI = null;
#endregion

#region Internal Properties
/// <summary>
/// 要操作操作员列表 DataGridView 对象
/// </summary>
ernal DataGridView DgvOperatorList
{
get { _dgvOperatorList; }
{ _dgvOperatorList = value; }
}
/// <summary>
/// 要操作权限列表 DataGridView 对象
/// </summary>
ernal DataGridView DgvRightsList
{
get { _dgvRightsList; }
{ _dgvRightsList = value; }
}
/// <summary>
/// 要操作权限视图 TreeView 对象
/// </summary>
ernal TreeView TvRightsView
{
get { _tvRightsView; }
{ _tvRightsView = value; }
}
/// <summary>
/// 被管理菜单对象
/// </summary>
ernal MenuStrip MsMain
{
get { _msMain; }
{ _msMain = value; }
}
/// <summary>
/// 当前被管理操作界面
/// </summary>
ernal Forms.frmRightsManager RightsManagerUI
{
get { _rightsManagerUI; }
{ _rightsManagerUI = value; }
}
#endregion

#region Private Methods
/// <summary>
/// 加载所有树子节点
/// </summary>
/// <param name="currentChildTreeNode">当前子节点</param>
/// <param name="rightsCollection">所有权限集合</param>
/// <s>加载了所有次级子节点当前子节点</s>
private TreeNode LoadAllChildTreeNode(TreeNode currentChildTreeNode, Dictionary<, Model.Rights> rightsCollection)
{
// 如果是菜单分隔则设置突出显示
(currentChildTreeNode.Text "━━━━")
{
currentChildTreeNode.ForeColor = Color.Red;
currentChildTreeNode.ToolTipText = "<-- 菜单分隔 -->";
}
// 遍历同父权限项集合
foreach (Model.Rights tmpRights in rightsCollection.Values)
{
// 如果当前父级权限项权限名称和当前节点相同
(tmpRights.ParentLevelRightsName currentChildTreeNode.Tag.)
{
// 为当前节点创建新子节点
TreeNode ChildTreeNode = TreeNode(tmpRights.RightsCaption);
ChildTreeNode.Tag = tmpRights.ModelName;
ChildTreeNode.Checked = tmpRights.RightsState;
// 创建同父权限项集合
List<Model.Rights> sameNessParentRightsList = List<Model.Rights>;
// 获取所有和当前权限项具有相同父权限项权限项
foreach (Model.Rights sameNessParentRights in rightsCollection.Values)
{
(sameNessParentRights.ParentLevelRightsName tmpRights.ParentLevelRightsName)
sameNessParentRightsList.Add(sameNessParentRights);
}
// 递归添加到当前节点及其所有子节点
currentChildTreeNode.Nodes.Add(LoadAllChildTreeNode(ChildTreeNode, rightsCollection));
}
}

// 返回当前处理节点
currentChildTreeNode;
}
#endregion

#region Internal Methods
/// <summary>
/// 将操作员集合数据绑定显示到数据视图
/// </summary>
/// <param name="operatorCollection">操作员集合</param>
ernal void BindOperatorInfoToDataGridView(Dictionary<, Model.Operator> operatorCollection)
{
try
{
// 如果包含操作员信息
(operatorCollection.Count > 0)
{
// 将权限集合绑定显示在数据视图中
BindingSource source = BindingSource;
source.DataSource = operatorCollection.Values;
this._dgvOperatorList.DataSource = source;
// 设置中文列名及可写状态
this._dgvOperatorList.Columns["Id"].HeaderText = "编号";
this._dgvOperatorList.Columns["Id"].ToolTipText = "[只读列]";
this._dgvOperatorList.Columns["Id"].DisplayIndex = 0;
this._dgvOperatorList.Columns["Id"].ReadOnly = true;
this._dgvOperatorList.Columns["ModelName"].HeaderText = "操作员名称";
this._dgvOperatorList.Columns["ModelName"].ToolTipText = "[只读列]";
this._dgvOperatorList.Columns["ModelName"].DisplayIndex = 1;
this._dgvOperatorList.Columns["ModelName"].ReadOnly = true;
this._dgvOperatorList.Columns["Password"].HeaderText = "密码";
this._dgvOperatorList.Columns["Password"].DisplayIndex = 2;
this._dgvOperatorList.Columns["State"].HeaderText = "状态";
this._dgvOperatorList.Columns["State"].DisplayIndex = 3;
this._dgvOperatorList.Columns["RightsCollection"].HeaderText = "权限列表";


this._dgvOperatorList.Columns["RightsCollection"].DisplayIndex = 4;
this._dgvOperatorList.Columns["RightsCollection"].ReadOnly = true;
this._dgvOperatorList.Columns["RightsCollection"].Visible = false;

// 设置菜单分隔项权限标题列为只读
foreach (DataGridViewRow dgvRow in this._dgvOperatorList.Rows)
{
// 设置单元格工具栏提示
foreach (DataGridViewCell dgvCell in dgvRow.Cells)
{
(dgvCell.ReadOnly)
dgvCell.ToolTipText = "[只读格]";

dgvCell.ToolTipText = "[可写格]";
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(
ex.Message,
"加载失败",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}

/// <summary>
/// 将权限集合数据绑定显示到数据视图
/// </summary>
/// <param name="rightsCollection">权限集合</param>
ernal void BindDataToDataGridView(Dictionary<, Model.Rights> rightsCollection)
{
try
{
// 保存所有选择单元格
List<> selectedCellValueList = List<>;
foreach (DataGridViewCell dgvCell in _dgvRightsList.SelectedCells)
{
selectedCellValueList.Add(dgvCell.Value..Trim);
}

// 将权限集合绑定显示在数据视图中
BindingSource source = BindingSource;
source.DataSource = rightsCollection.Values;
this._dgvRightsList.DataSource = source;
// 设置中文列名及可写状态
this._dgvRightsList.Columns["Id"].HeaderText = "编号";
this._dgvRightsList.Columns["Id"].ToolTipText = "[只读列]";
this._dgvRightsList.Columns["Id"].ReadOnly = true;
this._dgvRightsList.Columns["Id"].DisplayIndex = 0;
this._dgvRightsList.Columns["RightsCaption"].HeaderText = "权限标题";
this._dgvRightsList.Columns["RightsCaption"].DisplayIndex = 1;
this._dgvRightsList.Columns["ModelName"].HeaderText = "内部名称";
this._dgvRightsList.Columns["ModelName"].ToolTipText = "[只读列]";
this._dgvRightsList.Columns["ModelName"].ReadOnly = true;
this._dgvRightsList.Columns["ModelName"].DisplayIndex = 2;
this._dgvRightsList.Columns["RightsState"].HeaderText = "权限状态";
this._dgvRightsList.Columns["RightsState"].DisplayIndex = 3;
this._dgvRightsList.Columns["ParentLevelRightsName"].HeaderText = "父级权限";
this._dgvRightsList.Columns["ParentLevelRightsName"].ToolTipText = "[只读列]";
this._dgvRightsList.Columns["ParentLevelRightsName"].ReadOnly = true;
this._dgvRightsList.Columns["ParentLevelRightsName"].DisplayIndex = 4;

// 设置菜单分隔项权限标题列为只读
foreach (DataGridViewRow dgvRow in this._dgvRightsList.Rows)
{
// 如果是菜单分隔项则设置为只读
(dgvRow.Cells["RightsCaption"].Value..Trim "━━━━")
dgvRow.Cells["RightsCaption"].ReadOnly = true;
// 设置单元格工具栏提示
foreach (DataGridViewCell dgvCell in dgvRow.Cells)
{
(dgvCell.ReadOnly)
{
dgvCell.ToolTipText = "[只读格]";
(dgvCell.Value..Trim "━━━━")
dgvCell.ToolTipText " | <-- 菜单分隔 -->";
}

dgvCell.ToolTipText = "[可写格]";
}
}

// 禁用关联选择
RightsManagerUI.IsRelatingChooseCells = false;
// 清除所有单元格选择
_dgvRightsList.ClearSelection;
// 还原原有选择
foreach ( dgvSelectedCellValue in selectedCellValueList)
{
foreach (DataGridViewRow dgvRow in _dgvRightsList.Rows)
{
foreach (DataGridViewCell dgvCell in dgvRow.Cells)
{
(dgvCell.Value..Trim dgvSelectedCellValue)
dgvCell.Selected = true;
}
}
}
// 启用关联选择
RightsManagerUI.IsRelatingChooseCells = true;
}
catch (Exception ex)
{
MessageBox.Show(
ex.Message,
"加载失败",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}

/// <summary>
/// 将数据绑定加载到树形视图
/// </summary>
/// <param name="rightsCollection">权限集合</param>
ernal void BindDataToTreeView(Dictionary<, Model.Rights> rightsCollection)
{
// 禁用树视图重绘
_tvRightsView.BeginUpdate;
// 清除原有节点
_tvRightsView.Nodes.Clear;
// 遍历权限集合以加载数据
foreach (Model.Rights tmpRights in rightsCollection.Values)
{
// 定义权限根项
TreeNode rootTreeNode = null;
// 如果是权限根项
(tmpRights.ParentLevelRightsName _msMain.Name)
{
rootTreeNode = TreeNode(tmpRights.RightsCaption);


rootTreeNode.Tag = tmpRights.ModelName;
rootTreeNode.Checked = tmpRights.RightsState;
_tvRightsView.Nodes.Add(rootTreeNode);
}
// 如果是权限子项

{
// 创建权限子项
TreeNode childTreeNode = TreeNode(tmpRights.RightsCaption);
childTreeNode.Tag = tmpRights.ModelName;
childTreeNode.Checked = tmpRights.RightsState;
// 将子项添加到对应父项中
foreach (TreeNode tmpTreeNode in _tvRightsView.Nodes)
{
// 如果和现存节点父级权限相同
(tmpTreeNode.Tag. tmpRights.ParentLevelRightsName)
{
// 递归添加所有层级子节点
tmpTreeNode.Nodes.Add(LoadAllChildTreeNode(childTreeNode, rightsCollection));
}
}
}
}

// 展开所有树节点
_tvRightsView.ExpandAll;

// 启用树视图重绘
_tvRightsView.EndUpdate;
}

/// <summary>
/// 选中/取消树节点及其子节点勾选状态
/// </summary>
/// <param name="currentTreeNode">当前操作节点</param>
ernal void CheckOrUnCheckTreeNode(TreeNode currentTreeNode)
{
// 如果有选中单元格
(_dgvOperatorList.SelectedCells.Count > 0)
{
// 保存当前选中行操作员名称
operatorName = _dgvOperatorList.Rows[_dgvOperatorList.SelectedCells[0].RowIndex].Cells["ModelName"].Value..Trim;
// 同步权限状态
RightsManagerUI.OperatorCollection[operatorName].RightsCollection[currentTreeNode.Tag.].RightsState = currentTreeNode.Checked;

// 同时选中/取消子节点勾选
foreach (TreeNode childTreeNode in currentTreeNode.Nodes)
{
// 同步子节点勾选状态
childTreeNode.Checked = currentTreeNode.Checked;
// 递归勾选下层子节点
CheckOrUnCheckTreeNode(childTreeNode);
}
}
}

/// <summary>
/// 加载操作员列表
/// </summary>
ernal void LoadOperatorList
{
BLLFactory.BLLFactory bllFactory = BLLFactory.BLLFactory;
IBLL.IOperatorManager operatorManager = bllFactory.BuildOperatorManager;

// 加载操作员列表
try
{
RightsManagerUI.OperatorCollection = operatorManager.GetAllOperatorInfo;
// 检查所有操作员权限列表
foreach (Model.Operator tmpOperator in RightsManagerUI.OperatorCollection.Values)
{
// 如果权限为空就创建个新空权限集合
(!(tmpOperator.RightsCollection is Dictionary<, Model.Rights>))
{
tmpOperator.RightsCollection = Dictionary<, Model.Rights>;
// 创建权限管理类例子
Common.RightsMenuDataManager rmdManager = Common.RightsMenuDataManager;
// 创建权限集合空结构
tmpOperator.RightsCollection = rmdManager.ReadMenuRightsItem(_msMain, tmpOperator.RightsCollection);
}
}

// 如果包含操作员信息
(RightsManagerUI.OperatorCollection.Count > 0)
{
// 将操作员集合数据绑定显示到数据视图
BindOperatorInfoToDataGridView(RightsManagerUI.OperatorCollection);
// 重新指定当前登录操作员对象
foreach (Model.Operator tmpOperator in RightsManagerUI.OperatorCollection.Values)
{
(tmpOperator.ModelName RightsManagerUI.CurrentOperator.ModelName)
{
RightsManagerUI.CurrentOperator = RightsManagerUI.OperatorCollection[RightsManagerUI.CurrentOperator.ModelName];
// 将数据绑定显示到数据视图
BindDataToDataGridView(RightsManagerUI.CurrentOperator.RightsCollection);
// 将数据绑定加载到树形视图
BindDataToTreeView(RightsManagerUI.CurrentOperator.RightsCollection);

// 在操作员列表中选中当前操作员
foreach (DataGridViewRow dgvRow in _dgvOperatorList.Rows)
{
(dgvRow.Cells["ModelName"].Value..Trim RightsManagerUI.CurrentOperator.ModelName)
{
dgvRow.Selected = true;
;
}
}

;
}
}
}

{
// 清空操作员列表数据行
DgvOperatorList.Rows.Clear;
}
}
catch (Exception ex)
{
MessageBox.Show(
ex.Message,
"加载失败",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
#endregion
}
}

4、文章结语

以上内容并未提供完整源代码演示仅仅提供种解决此类问题思路和思路方法

()技术难点

1、将集合对象存储到数据库中(先使用序列化将集合对象流化再将其转换为 Byte );
2、使用递归法解析菜单对象及应用权限菜单项权限设置(注意 MenuStrip 对象层级子项集合为 Items 其余均为 DropDownItems 所以在递归解析或应用设置时只能从第 2层级子项开始进行递归);
3、BindingSource 界面数据绑定对象 和 DataGridView 数据视图Control控件配合使用(注意在绑定 Dictionary<Key, T> 泛型集合内容时应直接将 BindingSource DataSource 属性设置为该集合 .Values 才能绑定到实际内容);
4、TreeView 树形视图Control控件使用(注意在增删树节点时应适当使用 BeginUpdate 和 EndUpdate 思路方法来防止闪屏问题);


5、隶属于多个权限组操作员权限应为其所从属多个权限组权限并集(不算难遍历下集合即可)

( 2)扩展研究

此外我所阐述这种解决方案还可以再扩展些人性化功能譬如本文没提及些人性化功能:

1、让管理员用户完全自定义各个操作员权限菜单标题(我已在自己项目扩展此功能);
2、让权限菜单项在禁用时同时将该项 Enabled 属性设置为 False 以防止被隐藏菜单项被快捷键呼出(太简单了读者自己在上面代码中添加少量代码即可实现)
3、让管理员自由选择使用基于用户或基于角色权限管理方案(由于在操作员和权限组两个实体模型中都各自存储了自身权限集合所以在这种相对松散权限关系下很容易实现此功能此功能我也已在自己项目中实现)
0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: