不知不覺本系統寫了快三個月了,最近寫頁面的具體功能時感覺到有點吃力,很多地方如果張嘴來講的話可以說得很細,很全面,可寫成文字的話,就不太會寫了,有些地方想講得清晰的話,得用多幾倍的文字+實例+變化中的圖片才能表達得清楚,而寫這些又太費時間了,近段時間又特忙,所以只能是盡力而為,希望大家自行研究,如果有什么地方不明白的,發發評論或郵件給我,我再重新詳細講解。
說回正題,對于頁面訪問權限以及每個按鍵的權限控制,很久以前用過好幾種不同的方法,比如為每個控件分配名稱或編碼,然后在寫代碼時綁定這些值,又比如用xml來配置制權限等方法。這些方法都比較麻煩,而且由于都是使用編碼方法,開發時需要一個個進行綁定,容易出錯。經過后來不斷的完善,最后完成了本系統所采用的頁面控件注冊管理來綁定控件權限(如有雷同,純屬巧合,哈哈...),首先創建菜單,并綁定好對應的文件(頁面),然后將系統要用到的名稱添加到公用標識庫中,跟著在頁面控件權限管理頁面對各個頁面控件進行綁定(只需要點擊鼠標即可),通過職位(角色)來賦于不同的操作權限,只需要設置好管理員的職位,那么該管理員就擁有他所綁定的角色的全部權限了。
如下面的說明
首先在后端注冊菜單(菜單綁定頁面)

創建公用頁面權限標識,待用

為需要綁定頁面控件權限的菜單頁面綁定操作控件(左列為上圖錄入的公共控件名稱,右列為已綁定的頁面控件,只需要點擊鼠標就可以輕松綁定)

創建好部門

在不同部門創建相應的職位(角色)

為不同角色設置菜單與頁面控件操作權限

開發說明:(主要講講與上一章中不同的內容)
1、PagePowerSignPublicList.aspx.cs 公用頁面控件權限標識列表管理文件
這個頁面是比較經典的普通列表頁面,比較代碼,有以下一些地方和菜單頁面不一樣的
1 #region 加載數據 2 /// <summary>讀取數據</summary> 3 public override void LoadData() 4 { 5 //設置排序 6 if (sortList == null) 7 { 8 Sort(null); 9 }10 11 //綁定Grid表格12 bll.BindGrid(Grid1, Grid1.PageIndex + 1, Grid1.PageSize, null, sortList);13 }14 15 #endregion對于排序函數的調用,菜單頁面是有層次感列表,所以要自定義排序函數,而對于正常的列表,我們直接調用父類的Sort(null)函數即可
綁定Grid表格也與菜單頁面調用的不一樣,bll.BindGrid()函數使用的是參數中需要添加當前在第幾頁,每個頁面顯示多少行,null是條件參數,后面會詳細解釋它怎么使用,最后一個參數是排序規則參數
另外,Delete()刪除函數也使用批量刪除功能,不過會在刪除前進行檢查,發現指定記錄不能刪除時,則彈出提示是那個Id的記錄無法刪除,大家自行比較一下兩個列表文件就明白了。
2、PagePowerSignPublicEdit.aspx.cs公用頁面控件權限標識編輯文件
這個文件要注意的地方是Save()函數

1 #region 保存 2 /// <summary> 3 /// 數據保存 4 /// </summary> 5 /// <returns></returns> 6 public override string Save() 7 { 8 string result = string.Empty; 9 int id = ConvertHelper.Cint0(hidId.Text);10 11 try12 {13 #region 數據驗證14 15 if (string.IsNullOrEmpty(txtCName.Text.Trim()))16 {17 return txtCName.Label + "不能為空!";18 }19 var sName = StringHelper.Left(txtCName.Text, 20);20 if (PagePowerSignPublicBll.GetInstence().Exist(x => x.CName == sName && x.Id != id))21 {22 return txtCName.Label + "已存在!請重新輸入!";23 }24 if (string.IsNullOrEmpty(txtEName.Text.Trim()))25 {26 return txtEName.Label + "不能為空!";27 }28 var sEname = StringHelper.Left(txtEName.Text, 50);29 if (PagePowerSignPublicBll.GetInstence().Exist(x => x.EName == sEname && x.Id != id))30 {31 return txtEName.Label + "已存在!請重新輸入!";32 }33 34 #endregion35 36 #region 賦值37 //定義是否更新標識——即當前記錄的名稱是否改變了38 bool isUpdate = false;39 40 //獲取實體41 var model = new PagePowerSignPublic(x => x.Id == id);42 43 //判斷是否有改變名稱44 if (id > 0 && (sName != model.CName || sEname != model.EName))45 {46 isUpdate = true;47 }48 49 //設置名稱50 model.CName = sName;51 //設置英文名稱52 model.EName = sEname;53 #endregion54 55 //----------------------------------------------------------56 //存儲到數據庫57 PagePowerSignPublicBll.GetInstence().Save(this, model);58 59 //判斷是否需要同步更新關聯表字段60 if (isUpdate)61 {62 //調用更新函數,同步更新對應的所有記錄63 PagePowerSignBll.GetInstence().UpdateValue_For_PagePowerSignPublic_Id(this, model.Id, PagePowerSignTable.CName, model.CName, PagePowerSignTable.EName, model.EName);64 }65 }66 catch (Exception e)67 {68 result = "保存失敗!";69 70 //出現異常,保存出錯日志信息71 CommonBll.WriteLog(result, e);72 }73 74 return result;75 }76 #endregionView Code在函數中,大家可以找到下面這些代碼
1 //定義是否更新標識——即當前記錄的名稱是否改變了 2 bool isUpdate = false; 3 4 //判斷是否有改變名稱 5 if (id > 0 && (sName != model.CName || sEname != model.EName)) 6 { 7 isUpdate = true; 8 } 9 10 //判斷是否需要同步更新關聯表字段11 if (isUpdate)12 {13 //調用更新函數,同步更新對應的所有記錄14 PagePowerSignBll.GetInstence().UpdateValue_For_PagePowerSignPublic_Id(this, model.Id, PagePowerSignTable.CName, model.CName, PagePowerSignTable.EName, model.EName);15 }這是用于我們修改A表記錄的名稱時,同步修改其他關聯表引用了這個記錄名稱字段的所有記錄
為什么要這么處理呢?大家在看數據字典的數據庫結構時,會發現很多表與其他表關聯時,不單將其他表的Id引用了過來,還將這個Id對應的名稱也引用了,這種操作方式使我們在編寫查詢語句時,幾乎可以做到不用多表關聯,因為我們想要顯示的內容已經在查詢的表中存在了,這樣處理后,我們在修改相關表的名稱時,就必須同步修改關聯表中的名稱,對于這些關聯表名稱的修改,我們的T4模板也生成了相應的函數,如:UpdateValue_For_表名_Id()函數,然后直接按上面代碼編寫方法實現就可以了。
3、UseLogList.aspx.cs用戶操作日志管理文件
這個文件要注意的是InquiryCondition()函數
1 /// <summary> 2 /// 查詢條件 3 /// </summary> 4 /// <returns></returns> 5 PRivate List<ConditionHelper.SqlqueryCondition> InquiryCondition() 6 { 7 var wheres = new List<ConditionHelper.SqlqueryCondition>(); 8 9 //如果Id有值時,即表示查詢的是指定管理員的操作日志10 if (_id != 0)11 {12 wheres.Add(new ConditionHelper.SqlqueryCondition(ConstraintType.Where, LoginLogTable.Manager_Id, Comparison.Equals, _id));13 }14 15 //起始時間16 if (!string.IsNullOrEmpty(dpStart.Text.Trim()))17 {18 wheres.Add(new ConditionHelper.SqlqueryCondition(ConstraintType.And, LoginLogTable.AddDate, Comparison.GreaterOrEquals, StringHelper.FilterSql(dpStart.Text)));19 //終止時間20 if (!string.IsNullOrEmpty(dpEnd.Text.Trim()))21 {22 wheres.Add(new ConditionHelper.SqlqueryCondition(ConstraintType.And, LoginLogTable.AddDate, Comparison.LessOrEquals, StringHelper.FilterSql(dpEnd.Text)));23 }24 }25 26 //ip地址27 if (!string.IsNullOrEmpty(txtIp.Text.Trim()))28 {29 wheres.Add(new ConditionHelper.SqlqueryCondition(ConstraintType.And, LoginLogTable.Ip, Comparison.Equals, StringHelper.FilterSql(txtIp.Text)));30 }31 //登錄備注信息32 if (!string.IsNullOrEmpty(txtloginfo.Text.Trim()))33 {34 wheres.Add(new ConditionHelper.SqlqueryCondition(ConstraintType.And, LoginLogTable.Notes, Comparison.Like, "%" + StringHelper.FilterSql(txtloginfo.Text) + "%"));35 }36 37 return wheres;38 }
這是查詢條件函數,ConditionHelper.SqlqueryCondition這個類是自定義封裝條件類
它的構造函數(public SqlqueryCondition(ConstraintType ctype, string columnname, Comparison cparsion, object value, bool isParent
新聞熱點
疑難解答