本期概述
上一期,我們實現了簡單的數據恢復(通過先前備份的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, 用於獲取登錄成功的普通用戶功能權限值.
//定義一個全局變量 數組FRight 來獲取登錄成功的普通用戶功能權限 public static int[] FRight;
由於在數據庫里新增了幾列字段, 我們之前的查詢語句也需要稍作修改, 這里需要新增幾條字段 如下
//這里新增了 RightFManager,RightFRegistration,RightFPwdChange,RightFLog 幾條字段 用於獲取普通用戶登錄后的功能權限值 string sql = "select MUserPwd,UserType,RightFManager,RightFRegistration,RightFPwdChange,RightFLog from MovieAccount where MUserName ='" + txtName.Text + "'"; //---------------------新增代碼----------------------//
然后在判斷登錄成功的地方,添加獲取功能權限值的代碼,將獲取普通用戶的功能權限值傳給全局變量(這里只獲取普通用戶的功能權限值).
/************用戶登錄成功后 對用戶類型進行判斷********************/ //用戶功能權限索引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類的構造函數中加入如下代碼.
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個方法.
/// <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. 詳細請看代碼注釋
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(); } } }
最后,由於在數據庫中新增了幾列普通用戶功能權限的字段,我們的用戶注冊窗體也需要稍作修改(這里普通用戶注冊是默認禁用其所有功能權限,需要管理員在普通用戶管理窗體賦予其相應的功能權限).
//----------------------新增代碼-------------------------// //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