0%

C#简易电影记录管理系统:完结篇[权限分配]

本期概述

上一期,我们实现了简单的数据恢复(通过先前备份的Excel数据文件导入Sql Server来恢复数据);这期我们来一起学习下针对普通用户的权限分配功能(看看管理员是如何给普通用户进行权限分配的).

原理

在登录窗体类中创建一个全局变量FRight, 用来获取用户成功登录后的功能权限值, 权限值等于1为功能可用,0或者其它为不可用;当普通用户成功登录后,在主窗体FrmMain里获取这个全局变量,同时将相应的功能按钮的Enable属性设置为true或者false(这里管理员默认是拥有所有功能权限,系统只判断普通用户的功能权限);这里创建了一个FrmUserManager普通用户管理窗体(仅限于管理员使用),用于管理员创建普通用户以及修改普通用户账户信息和分配权限等(管理员本身信息只能被查看,不能被做任何修改).关于权限分配的实现,这里使用了CheckBox控件,通过判断CheckBox的Checked属性是否被点中来给普通用户赋予相应的功能权限,被点中则赋值1,否则默认为0,然后通过执行sql数据操作将权限值存入数据库.

数据库设计

这里由于增加了普通用户权限值,我们需要对数据库结构稍作修改.这里在MovieAccount表中增加4列内容 分别用于

RightFManager 判断普通用户管理界面权限 RightFRegistration 判断普通用户注册权限

RightFPwdChange 判断普通用户密码修改权限 RightFLog 判断普通用户日志查询权限

img

代码实施

首先我们需要在登录窗体类FrmLogin.cs里增加一个全局变量FRight, 用于获取登录成功的普通用户功能权限值.

1
2
//定义一个全局变量 数组FRight 来获取登录成功的普通用户功能权限
public static int[] FRight;

由于在数据库里新增了几列字段, 我们之前的查询语句也需要稍作修改, 这里需要新增几条字段 如下

1
2
3
//这里新增了 RightFManager,RightFRegistration,RightFPwdChange,RightFLog 几条字段 用于获取普通用户登录后的功能权限值 
string sql = "select MUserPwd,UserType,RightFManager,RightFRegistration,RightFPwdChange,RightFLog from MovieAccount where MUserName ='" + txtName.Text + "'";
//---------------------新增代码----------------------//

然后在判断登录成功的地方,添加获取功能权限值的代码,将获取普通用户的功能权限值传给全局变量(这里只获取普通用户的功能权限值).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/************用户登录成功后 对用户类型进行判断********************/

//用户功能权限索引i 对应的数据读取器sdr里的索引是 是 i+2
//FRight[0] = sdr.GetInt32(2); //RightFManager
//FRight[1] = sdr.GetInt32(3); //RightFRegistration
//FRight[2] = sdr.GetInt32(4); //RightFPwdChange
//FRight[3] = sdr.GetInt32(5); //RightFLog

//如果用户为普通用户 则检查 其功能权限 管理员不被检查
if (UserType == "NormalUser")
{
FRight = new int[4];
for (int i = 0; i < FRight.Length; i++)
{
if (sdr.GetInt32(i + 2) == 0) //如果数据读取器中读到数据库中的权限值为0
{
FRight[i] = 0; //则赋给全局变量0 说明该功能被禁用
}
else if (sdr.GetInt32(i + 2) == 1) //如果 为1
{
FRight[i] = 1; //赋给全局变量1 该功能可用
}
else
{
FRight[i] = 0; //否则默认为0 该功能不可用
}
}
}
/*****************************************************************/

这样,当普通用户登录成功后, 系统会自动将用户的权限值赋给全局变量 FRight;然后我们需要在主窗体类FrmMain.cs中获取该全局变量并做出相应的功能赋予与禁用,为此我们在FrmMain类的构造函数中加入如下代码.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public FrmMain()
{
InitializeComponent();
/************************ 新增代码 ***********************************/
//窗体加载的时候 自动获取 并判断普通用户的功能权限

//当用户为普通用户的时候 需要判断下其功能权限 管理员不接受检查
if (FrmLogin.UserType == "NormalUser")
{
if (FrmLogin.FRight[0] == 1) //对应的功能权限为1的时候 本功能开放
tsbManager.Enabled = true;
else
tsbManager.Enabled = false; //否则 禁用本功能
if (FrmLogin.FRight[1] == 1)
tsbRegistration.Enabled = true;
else
tsbRegistration.Enabled = false;
if (FrmLogin.FRight[2] == 1)
tsbPwdChange.Enabled = true;
else
tsbPwdChange.Enabled = false;
if (FrmLogin.FRight[3] == 1)
tsbLog.Enabled = true;
else
tsbLog.Enabled = false;

}
/************************ 新增代码 ***********************************/
}

这样,当我们普通用户登录以后,系统就能自动根据其数据库中的权限值,来进行判断并赋予相应的功能权限了.

我们来简单测试下

这里使用普通用户User44 来登陆系统,从数据库中我们可以看到其 RightFManager管理界面权限 和 RightFRegistration用户注册权限值 都为1(1为功能可用),密码修改和日志查看功能为0(0为功能不可用).

img

使用普通用户user44 登录系统

img

登录成功后,系统跳转到主界面FrmMain, 我们发现 管理界面和用户注册功能为可用, 密码修改和日志查询为不可用.

img

用户权限功能判断成功之后,我们便要开始写管理员给普通用户分配权限的功能,我们新建一个普通用户管理窗体FrmUserManager(该功能仅限于管理员使用).

控件名称以及界面设计如下

DataGridView name: dgvUserManger

快速搜索 name: txtUserQuery 用户名 name: txtUserName 密码 name: txtPwd 用户类型 name: cboUserType

管理界面 name: chkManager 用户注册 name: chkManager 密码修改 name: chkRegistration 日志查询 name: chkPwdChange

查看所有 name: btnUserCheck 添加用户 name: btnUserAdd 保存修改 name: btnUserChange 删除用户 name: btnUserDelete

返回主界面 name: btnBack 退出系统 name: btnExit

img

在实施代码之前,由于这里用到,我们需要简单了解一下SQLHelper数据库操作类. SQLHelper是微软提供的.NET Framework的数据库操作组件;用于帮助程序简化掉那些重复的数据库操作语句,包括SqlConnection,SqlCommand,SqlDataReader等等。SQLHelper封装过后通常是只需要给数据库操作方法传入一些参数如数据库连接字符串,Sql查询语句,Sql参数等,便可以访问数据库了,十分方便. [详情可以看这里]

好了,这里给出我的SqlHelper类,里面包含了我们数据库操作需要的2个方法.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/// <summary>
/// SqlHelper 数据库帮助类
/// </summary>
class SqlHelper
{
static string connStr = ConfigurationManager.ConnectionStrings["str"].ConnectionString;

static SqlConnection conn = new SqlConnection(connStr);
/// <summary>
/// ExcuteNonQuery 用于执行增删改方法
/// </summary>
/// <param name="strSql">增删改Sql语句</param>
/// <param name="paras">Sql参数数组</param>
/// <returns>返回一个整数值,用于判断是否操作成功</returns>
public static int ExcuteNonQuery(string strSql, params SqlParameter[] paras)
{
SqlCommand cmd = new SqlCommand(strSql, conn); //执行sql指令 外面调用需传入2个参数 Sql查询语句和 Sql连接
cmd.Parameters.AddRange(paras); //添加 查询语句执行的参数数组
conn.Open(); //执行前 需打开数据库连接
int n = cmd.ExecuteNonQuery(); //执行 cmd指令操作 返回成功操作的行数
conn.Close(); //用完关闭数据库 节约资源
return n; //返回成功操作的行数
}

/// <summary>
/// ExecuteDataTable 用于执行 查 方法
/// </summary>
/// <param name="strSql">Sql Select语句</param>
/// <returns>返回 查询结果表</returns>
public static DataTable ExecuteDataTable(string strSql)
{
SqlCommand cmd = new SqlCommand(strSql, conn); //执行sql指令 外面调用需传入2个参数 Sql查询语句和 Sql连接
SqlDataAdapter da = new SqlDataAdapter(cmd); //使用SqlDataAdapter数据适配器来加载cmd操作指令
DataTable dt = new DataTable(); //创建 DataTable
da.Fill(dt); //将SqlDataAdapter 获取的结果集 填充到 DataTable中
return dt; //返回 DataTable
}
}

然后,我们开始实施FrmUserManager.cs的代码, 这里使用了几个私有变量 例如rightFManager,rightFRegistration等,用于获取CheckBox被点中后的值,然后通过数据库操作将其存入数据库(这里系统默认管理员账户信息是不能被修改的).我们使用了一个私有变量strUType 用于获取用户类型,当类型为”Administrator”,则将所用操作控件(用户名,密码和权限设置的CheckBox等)的Enable属性设置为false. 详细请看代码注释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.Data.SqlClient;

/*******************************************************

** 作者: SoFlash - 博客园 http://www.cnblogs.com/longwu

** 描述: FrmUserManager.cs 用户管理窗体 用于管理员对 普通用户密码修改

******************************************************/

namespace 电影记录管理系统
{
public partial class FrmUserManager : Form
{

//定义私有变量-功能权限值 用于获取 radiobutton 被check后的返回值
private int rightFManager = 0;
private int rightFRegistration = 0;
private int rightFPwdChange = 0;
private int rightFLog = 0;

//strType 用于获取 当前DataGridView 被点中行的用户类型
private string strUType = "";

public FrmUserManager()
{
InitializeComponent();
}

private void CheckAllUsers()
{
//查看当前所有用户
string sql = "select * from MovieAccount";
dgvUserManger.DataSource = SqlHelper.ExecuteDataTable(sql);
}

private void dgvUserManger_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
//点中DataGridView后,将当前行内容传递给文本框 便于在文本框中修改
txtUserName.Text = dgvUserManger.Rows[e.RowIndex].Cells["MUserName"].Value.ToString();
txtPwd.Text = dgvUserManger.Rows[e.RowIndex].Cells["MUserPwd"].Value.ToString();
cboUserType.Text = dgvUserManger.Rows[e.RowIndex].Cells["UserType"].Value.ToString();

//获取用户类型
strUType = cboUserType.Text.Trim();

/************************************************************************************/
//每次点击 DataGridView新的行之前 都要把前一次点击行的 CheckBox 状态调整为系统默认状态 全未选中 并且都可选
//比如 如果之前 点了NormalUser 再点Administer 会保留之前NormalUser的选择项 这里我们需要清空
chkManager.Checked = false;
chkRegistration.Checked = false;
chkManager.Checked = false;
chkLog.Checked = false;

txtUserName.Enabled = true;
txtPwd.Enabled = true;
cboUserType.Enabled = true;
chkManager.Enabled = true;
chkPwdChange.Enabled = true;
chkRegistration.Enabled = true;
chkLog.Enabled = true;

/************************************************************************************/
if (strUType == "NormalUser")
{
//如果先前点击了 DataGridView里的 管理员行内容 checkbox 会保留之前的点击状态 我们需要先前的点击状态清除
chkManager.Checked = true;
chkRegistration.Checked = true;
chkManager.Checked = true;
chkLog.Checked = true;

//获取当前DataGridView被点中行内容中的用户权限值
rightFManager = Convert.ToInt32(dgvUserManger.Rows[e.RowIndex].Cells["RightFManager"].Value);
rightFRegistration = Convert.ToInt32(dgvUserManger.Rows[e.RowIndex].Cells["RightFRegistration"].Value);
rightFPwdChange = Convert.ToInt32(dgvUserManger.Rows[e.RowIndex].Cells["RightFPwdChange"].Value);
rightFLog = Convert.ToInt32(dgvUserManger.Rows[e.RowIndex].Cells["RightFLog"].Value);

//同时判断获取的权限值 并相应的选中Checkbox
if (rightFManager == 1)
chkManager.Checked = true;
else
chkManager.Checked = false;
if (rightFRegistration == 1)
chkRegistration.Checked = true;
else
chkRegistration.Checked = false;
if (rightFPwdChange == 1)
chkPwdChange.Checked = true;
else
chkPwdChange.Checked = false;
if (rightFLog == 1)
chkLog.Checked = true;
else
chkLog.Checked = false;

}
//当用户类型为管理员的时候,将所有的CheckBox禁用, 管理员功能权限不允许设置
else if (strUType == "Administrator")
{
chkManager.Enabled = false;
chkPwdChange.Enabled = false;
chkRegistration.Enabled = false;
chkLog.Enabled = false;

txtUserName.Enabled = false;
txtPwd.Enabled = false;
cboUserType.Enabled = false;
}

}
//查询用户信息
private void txtUserQuery_TextChanged(object sender, EventArgs e)
{

string sql = "";

if (txtUserQuery.Text.Trim() == "")
{
//执行查询语句
sql = "select * from MovieAccount";
}
else
{
//全局搜索 (通过用户ID 用户名和 用户类型进行模糊查找)
sql = "select * from MovieAccount where(MId like'%" + txtUserQuery.Text.Trim() + "%')or(MUserName like'%" + txtUserQuery.Text.Trim() + "%')or(UserType like'%" + txtUserQuery.Text.Trim() + "%')";
}
//调用SqlHelper类里的查方法
dgvUserManger.DataSource = SqlHelper.ExecuteDataTable(sql);

}
//调用查看所有用户的方法来刷新当前 DataGridView的内容
private void btnUserCheck_Click(object sender, EventArgs e)
{
//点击 "查看所有" 按钮 调用 CheckAllUsers() 方法 刷新 并查当前看所有用户
CheckAllUsers();
}

//添加用户
private void btnUserAdd_Click(object sender, EventArgs e)
{

//使用SQL插入数据语句
string sql = "insert into MovieAccount(MUserName,MUserPwd,UserType,RightFManager,RightFRegistration,RightFPwdChange,RightFLog) values (@MUserName,@MUserPwd,@UserType,@RightFManager,@RightFRegistration,@RightFPwdChange,@RightFLog)";

//判断插入的数据是否为空,如果为空,则提示重新插入!
if (txtUserName.Text.Trim() == "" || txtPwd.Text.Trim() == "" || cboUserType.Text == "")
{
MessageBox.Show("插入数据不能为空,请按要求插入数据!");
return;
}
if (cboUserType.Text == "Administrator")
{
MessageBox.Show("暂不开放注册管理员功能!");
return;
}

//判断 哪些CheckBox 被选中
AdjustChecked();

//向数据库插入参数
SqlParameter[] param ={
new SqlParameter("@MUserName",txtUserName.Text.Trim()),
new SqlParameter("@MUserPwd",txtPwd.Text.Trim()),
new SqlParameter("@UserType",cboUserType.Text.Trim()),
new SqlParameter("@RightFManager",rightFManager),
new SqlParameter("@RightFRegistration",rightFRegistration),
new SqlParameter("@RightFPwdChange",rightFPwdChange),
new SqlParameter("@RightFLog",rightFLog)

};
//调用 SqlHelper 增 方法
int n = SqlHelper.ExcuteNonQuery(sql, param);

if (n > 0)
{
MessageBox.Show("数据插入成功!");
}
else
{
MessageBox.Show("插入失败!");
return;
}

//调用CheckAllUsers() 方法 用于刷新 在添加完成数据后 自动刷新数据
CheckAllUsers();
}

//保存修改的信息
private void btnUserChange_Click(object sender, EventArgs e)
{
//在对数据进行修改之前 对文本框的内容做一下检查 是否用户已经输入内容, 如果为空 则提示重新输入
if (txtUserName.Text.Trim() == "" || txtPwd.Text.Trim() == "" || cboUserType.Text.Trim() == "")
{
MessageBox.Show("文本框的输入不能为空!");
return;
}
if (cboUserType.Text == "Administrator")
{
MessageBox.Show("暂不开放注册管理员功能!");
return;
}

//判断 哪些CheckBox 被选中
AdjustChecked();

//使用SQL update 更新语句
//获取文本框 和ComboBox 输入的内容, 通过用户的ID(MId) 进行更新(ID为当前鼠标点击行的MId)
string sqlUpdate = "update MovieAccount set MUserName = @MUserName, MUserPwd = @MUserPwd,UserType=@UserType,RightFManager=@RightFManager,RightFRegistration=@RightFRegistration,RightFPwdChange=@RightFPwdChange,RightFLog=@RightFLog where MId=@MId";

SqlParameter[] param ={
new SqlParameter("@MUserName",txtUserName.Text.Trim()),
new SqlParameter("@MUserPwd",txtPwd.Text.Trim()),
new SqlParameter("@UserType",cboUserType.Text.Trim()),
new SqlParameter("@RightFManager",rightFManager),
new SqlParameter("@RightFRegistration",rightFRegistration),
new SqlParameter("@RightFPwdChange",rightFPwdChange),
new SqlParameter("@RightFLog",rightFLog),
new SqlParameter("@MId",dgvUserManger.CurrentRow.Cells[0].Value),
};

//调用 SqlHelper 更新方法
int n = SqlHelper.ExcuteNonQuery(sqlUpdate, param);

//判定 如果n=0,则说明没有获取到数据,ExecuteNonQuery执行不成功
if (n == 0)
{
//提示更新失败
MessageBox.Show("更新失败!");
return;// 并且返回
}
else
{
//否则更新成功
MessageBox.Show("恭喜你!更新成功!");
}

//保存完以后 调用刷新方法,将更新后的数据 显示在datagridview上面
CheckAllUsers();
}

//删除DataGridView里 选中的用户
private void btnUserDelete_Click(object sender, EventArgs e)
{
//使用sql删除语句
string sqlDelete = null;
//如果datagridview的当前行被选中
if (dgvUserManger.CurrentRow.Selected)
{
//获取当前点中行的MID 并且 将当前行的MID号 赋给SQL 语句
sqlDelete = "delete from MovieAccount where MId=@MId";
}

SqlParameter[] param = {
new SqlParameter("@MId",Convert.ToInt32(dgvUserManger.CurrentRow.Cells[0].Value))
};
//调用 SqlHelper 删除的方法
int n = SqlHelper.ExcuteNonQuery(sqlDelete, param);

//如果n>0 说明删除数据成功
if (n > 0)
{
MessageBox.Show("删除成功!");
}
else //否则失败
{
MessageBox.Show("不存在的ID!");
}
//删除完后 刷新一下当前数据
CheckAllUsers();
}
//导入当前用户管理窗体的时候 自动查看所有用户信息 以及给Combobox赋予2个选项 管理员和 普通用户
private void FrmUserManager_Load(object sender, EventArgs e)
{
CheckAllUsers();
cboUserType.Items.Add("Administrator");
cboUserType.Items.Add("NormalUser");
}

//判断CheckBox是否被点重或是取消, 用于更新和修改用户权限
private void AdjustChecked()
{
//当相应的功能权限 checkbox 被点中 或者取消 将分别赋值 并传给相应的私有变量 用于数据库添加,更新等操作
if (chkManager.Checked == true)
rightFManager = 1;
else
rightFManager = 0;
if (chkRegistration.Checked == true)
rightFRegistration = 1;
else
rightFRegistration = 0;
if (chkPwdChange.Checked == true)
rightFPwdChange = 1;
else
rightFPwdChange = 0;
if (chkLog.Checked == true)
rightFLog = 1;
else
rightFLog = 0;
}

//返回主窗体
private void btnBack_Click(object sender, EventArgs e)
{
FrmMain main = new FrmMain();
main.Show();
this.Hide();
}

//直接退出系统
private void btnExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}

最后,由于在数据库中新增了几列普通用户功能权限的字段,我们的用户注册窗体也需要稍作修改(这里普通用户注册是默认禁用其所有功能权限,需要管理员在普通用户管理窗体赋予其相应的功能权限).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//----------------------新增代码-------------------------//
//new一个 uType 来获取 radiobutton 点击事件下 触发的用户类型赋值
string uType = "";

int rightFManager = 0;
int rightFRegistration = 0;
int rightFPwdChange = 0;
int rightFLog = 0;

if (rdoAdministrator.Checked) //当管理员的radiobutton被点击后
{
uType = "Administrator"; //传给 uType 一个管理员
rightFManager = 1;
rightFRegistration = 1;
rightFPwdChange = 1;
rightFLog = 1;
}
else if (rdoNormalUser.Checked) //同理
{
uType = "NormalUser";
}
else //若不点击 则默认为普通用户注册
uType = "NormalUser";
//sql 插入语句 我们新增了 一列 UserType
string sqlInsert = "insert into MovieAccount(MUserName,MUserPwd,UserType,RightFManager,RightFRegistration,RightFPwdChange,RightFLog) values (@MUserName,@MUserPwd,@UserType,@RightFManager,@RightFRegistration,@RightFPwdChange,@RightFLog)";
//使用1个SQL参数数组 来装载 需要插入的数据
SqlParameter[] param = {
new SqlParameter("@MUserName",txtUid.Text),
new SqlParameter("@MUserPwd",txtPwd.Text),
new SqlParameter("@UserType",uType),
new SqlParameter("@RightFManager",rightFManager),
new SqlParameter("@RightFRegistration",rightFRegistration),
new SqlParameter("@RightFPwdChange",rightFPwdChange),
new SqlParameter("@RightFLog",rightFLog)
};
//----------------------新增代码-------------------------//

好了代码写完了 我们来运行测试下.

我们使用 管理员帐号admin1 登录,注册一个普通用户,帐号为user01.

img

img

注册成功后,我们来到普通用户管理界面FrmUserManager, 查看普通用户user01的账户信息,其所有功能权限值为0 即所有功能不可用.

img

我们使用 普通用户user01登录检测下,发现所有功能不可用.

img

我们再次使用 管理员admin1登录系统,来到普通用户管理窗体给user01 赋予2个功能权限 管理界面 和 密码修改.

img

赋予功能权限后,普通用户user01 的管理界面功能 和 密码修改的功能的权限值 都被改成了1,为可用.

img

我们再次使用被赋予新功能权限的普通用户user01登录系统,发现功能权限被成功赋给了. :)

img

这样,我们的用户权限分配就做完了,同样到这里整个电影记录管理系统教程也告于段落了,感谢学友和那些支持我的网友们,是你们给了我一直写下去的动力. :)

附上源代码

MovieRecordManagementSystem10.zip

转自:https://www.cnblogs.com/longwu/archive/2012/03/07/2383089.html