本期概述
上一期,我们实现了简单的数据恢复(通过先前备份的Excel数据文件导入Sql Server来恢复数据);这期我们来一起学习下针对普通用户的权限分配功能(看看管理员是如何给普通用户进行权限分配的).
原理
在登录窗体类中创建一个全局变量FRight, 用来获取用户成功登录后的功能权限值, 权限值等于1为功能可用,0或者其它为不可用;当普通用户成功登录后,在主窗体FrmMain里获取这个全局变量,同时将相应的功能按钮的Enable属性设置为true或者false(这里管理员默认是拥有所有功能权限,系统只判断普通用户的功能权限);这里创建了一个FrmUserManager普通用户管理窗体(仅限于管理员使用),用于管理员创建普通用户以及修改普通用户账户信息和分配权限等(管理员本身信息只能被查看,不能被做任何修改).关于权限分配的实现,这里使用了CheckBox控件,通过判断CheckBox的Checked属性是否被点中来给普通用户赋予相应的功能权限,被点中则赋值1,否则默认为0,然后通过执行sql数据操作将权限值存入数据库.
数据库设计
这里由于增加了普通用户权限值,我们需要对数据库结构稍作修改.这里在MovieAccount表中增加4列内容 分别用于
RightFManager 判断普通用户管理界面权限 RightFRegistration 判断普通用户注册权限
RightFPwdChange 判断普通用户密码修改权限 RightFLog 判断普通用户日志查询权限
代码实施
首先我们需要在登录窗体类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为功能不可用).
使用普通用户user44 登录系统
登录成功后,系统跳转到主界面FrmMain, 我们发现 管理界面和用户注册功能为可用, 密码修改和日志查询为不可用.
用户权限功能判断成功之后,我们便要开始写管理员给普通用户分配权限的功能,我们新建一个普通用户管理窗体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
在实施代码之前,由于这里用到,我们需要简单了解一下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.
注册成功后,我们来到普通用户管理界面FrmUserManager, 查看普通用户user01的账户信息,其所有功能权限值为0 即所有功能不可用.
我们使用 普通用户user01登录检测下,发现所有功能不可用.
我们再次使用 管理员admin1登录系统,来到普通用户管理窗体给user01 赋予2个功能权限 管理界面 和 密码修改.
赋予功能权限后,普通用户user01 的管理界面功能 和 密码修改的功能的权限值 都被改成了1,为可用.
我们再次使用被赋予新功能权限的普通用户user01登录系统,发现功能权限被成功赋给了. :)
这样,我们的用户权限分配就做完了,同样到这里整个电影记录管理系统教程也告于段落了,感谢学友和那些支持我的网友们,是你们给了我一直写下去的动力. :)
附上源代码
MovieRecordManagementSystem10.zip
转自:https://www.cnblogs.com/longwu/archive/2012/03/07/2383089.html