回《【開源】EnterpriseFrameWork框架系列文章索引》
從本章開始進入框架的第二塊內容“EnterpriseFrameWork框架的基礎功能”,包括:權限管理、字典數據管理、報表管理和消息管理四塊,這些功能又包括兩個版本,Web版和Winform版也就是說有兩套界面。
既然開始講基礎功能,順便說一下EnterpriseFrameWork框架的適用范圍,前面也有提到過就是此框架適合中小團隊這是一方面,還一方面就是此框架適合行業應用系統軟件的開發,你用它做一個“超市庫存管理系統”、“企業EPR”等類似系統是非常適合的;但如果覺得用它有Web開發模式,就用它來開發互聯網應用的話還是很麻煩的;互聯網的功能的開放性、隨意性在此框架中受很大的限制,所以在這系列完成后,下一個系列中我會繼續分享針對“互聯網應用開發框架系列”,敬請期待!
繼續本章的內容講解框架的“權限管理”,從本章的講解思路分成下面幾個部分:
1)功能清單介紹
2)功能界面展示
3)核心業務流程圖與數據庫表關系圖
4)關鍵點的技術實現代碼
框架中的權限管理的思想類似於Windows操作系統中的用戶和用戶組的設計,用戶配置角色,角色配置菜單,所以用戶沒必要跟菜單直接關聯,通過角色進行關聯。
框架中權限除了到菜單級別,還可以精確到頁面內部的一個按鈕、數據展示或操作內容,也就是頁面子權限。
簡要的說明一下頁面子權限的實現方式,在每個頁面定義了一組權限標識,角色配置菜單同時勾選子權限標識保存起來。打開這個頁面的時候根據配置的子權限標識控制頁面的操作內容。舉個列子,比如查看“工作日志的頁面”有員工、經理、老總三個級別,首頁我們在日志頁面三個定義子權限標識分別為“員工權限”、“經理權限”和“老總權限”,再在角色配置權限的界面分別對三個角色配置相應的頁面子權限。
那么不同級別的用戶登錄后,打開此頁面看到的內容就不一樣了。
1.權限管理功能清單
模塊名稱 |
功能名稱 |
功能說明 |
權限管理 |
系統登錄 |
輸入正確用戶名和密碼,點擊確定登錄 |
系統主界面 |
登錄后進入的主界面,菜單根據用戶配置的權限動態生成 |
|
機構管理 |
添加機構、啟用停用機構 |
|
用戶部門管理 |
用戶管理,新增、修改、停用用戶,用戶配置部門和設置角色 |
|
系統菜單管理 |
菜單維護,新增、修改、刪除菜單,設置菜單的圖片等 |
|
角色權限配置 |
角色維護,新增、刪除角色 |
2. 權限管理功能界面展示,包括Winform版和Web版
1)登錄
2)主界面
3)機構管理
4)用戶部門管理
5)系統菜單管理
6)角色權限配置
3.權限管理核心業務流程圖與數據庫表關系圖
4.權限管理關鍵點技術實現
1)登錄控制器LoginController

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using EFWBaseLib.Entity; using EFWBaseLib.ObjectModel.RightManager; using EFWBaseLib.ObjectModel.UserLogin; using EFWBaseLib.WinController.IViewform; using EFWCoreLib.CoreFrame.BusinessArchitecture; using EFWCoreLib.CoreFrame.Init; using EFWCoreLib.WinformFrame.Controller; using EFWCoreLib.WinformFrame.Common; using System.Management; using EFWCoreLib.CoreFrame.Common; namespace EFWBaseLib.WinController.Ation { [EFWCoreLib.WinformFrame.Controller.Menu] [View(DllName = "EFWWin.exe", ViewTypeName = "EFWWin.Viewform.FrmLogin", DefaultView = true)] [View(DllName = "EFWWin.exe", ViewTypeName = "EFWWin.Viewform.FrmMain")] [View(DllName = "EFWWin.exe", ViewTypeName = "EFWWin.Viewform.FrmMainRibbon")] [View(DllName = "EFWWin.exe", ViewTypeName = "EFWWin.Viewform.FrmSetting")] [View(DllName = "EFWWin.exe", ViewTypeName = "EFWWin.Viewform.ReDept")] [View(DllName = "EFWWin.exe", ViewTypeName = "EFWWin.Viewform.FrmPassWord")] [View(DllName = "EFWWin.exe", ViewTypeName = "EFWWin.Viewform.FrmWeclome")] public class LoginController : BaseController { IfrmLogin frmlogin; IfrmMain frmmain; #region 登錄 private Form _frmsplash; public Form Frmsplash { get { return _frmsplash; } set { _frmsplash = value; } } public override void Init() { frmlogin = (IfrmLogin)iBaseView["FrmLogin"]; int mainStyle = EFWCoreLib.WinformFrame.Common.CustomConfigManager.GetMainStyle(); if (mainStyle == 0) frmmain = (IfrmMain)iBaseView["FrmMain"]; else frmmain = (IfrmMain)iBaseView["FrmMainRibbon"]; } public void UserLogin() { User user = NewObject<User>(); bool islogin = user.UserLogin(frmlogin.usercode, frmlogin.password); if (islogin) { BaseUser EbaseUser = user.GetUser(frmlogin.usercode); SysLoginRight right = new SysLoginRight(); right.UserId = EbaseUser.UserId; right.EmpId = EbaseUser.EmpId; right.WorkId = EbaseUser.WorkId; Dept dept = NewObject<Dept>(); BaseDept EbaseDept = dept.GetDefaultDept(EbaseUser.EmpId); if (EbaseDept != null) { right.DeptId = EbaseDept.DeptId; right.DeptName = EbaseDept.Name; } BaseEmployee EbaseEmp = (BaseEmployee)NewObject<BaseEmployee>().getmodel(EbaseUser.EmpId); right.EmpName = EbaseEmp.Name; BaseWorkers EbaseWork = (BaseWorkers)NewObject<BaseWorkers>().getmodel(EbaseUser.WorkId); right.WorkName = EbaseWork.WorkName; if (EbaseWork.DelFlag == 0) { string regkey = EbaseWork.RegKey; DESEncryptor des = new DESEncryptor(); des.InputString = regkey; des.DesDecrypt(); string[] ret = (des.OutString == null ? "" : des.OutString).Split(new char[] { '|' }); if (ret.Length == 2 && ret[0] == EbaseWork.WorkName && Convert.ToDateTime(ret[1]) > DateTime.Now) { AppGlobal.cache.Add("RoleUser", right); frmmain.UserName = right.EmpName; frmmain.DeptName = right.DeptName; frmmain.WorkName = right.WorkName; frmmain.modules = NewObject<Module>().GetModuleList(right.UserId).OrderBy(x => x.SortId).ToList(); frmmain.menus = NewObject<EFWBaseLib.ObjectModel.RightManager.Menu>().GetMenuList(right.UserId); frmmain.depts = NewObject<Dept>().GetHaveDept(right.EmpId); frmmain.showSysMenu(); ShowWeclomeForm(); ((Form)frmmain).Icon = System.Drawing.Icon.ExtractAssociatedIcon(EFWCoreLib.CoreFrame.Init.AppGlobal.AppRootPath + @"images\msn.ico"); ((Form)frmmain).Show(); //InitMessageForm();//? CustomConfigManager.xmlDoc = null; } else { throw new Exception("登錄用戶的當前機構注冊碼不正確!"); } } else { throw new Exception("登錄用戶的當前機構還未啟用!"); } } else { throw new Exception("輸入的用戶名密碼不正確!"); } } public void ShowWeclomeForm() { frmmain.ShowForm((Form)iBaseView["FrmWeclome"], "首頁", "1"); } public string GetBackGroundImage() { return CustomConfigManager.GetBackgroundImage(); } public void ReLogin() { frmlogin.isReLogin = true; ((Form)frmlogin).ShowDialog(); } public void Quit() { _frmsplash.Dispose(); } #endregion #region 設置 public void OpenSetting() { List<InputLanguage> list = new List<InputLanguage>(); foreach (InputLanguage val in InputLanguage.InstalledInputLanguages) { list.Add(val); } ((IfrmSetting)iBaseView["FrmSetting"]).languageList = list; ((IfrmSetting)iBaseView["FrmSetting"]).inputMethod_CH = CustomConfigManager.GetInputMethod(EFWCoreLib.WinformFrame.CustomControl.EN_CH.CH); ((IfrmSetting)iBaseView["FrmSetting"]).inputMethod_EN = CustomConfigManager.GetInputMethod(EFWCoreLib.WinformFrame.CustomControl.EN_CH.EN); //打印機 ManagementObjectSearcher query; ManagementObjectCollection queryCollection; string _classname = "SELECT * FROM Win32_Printer"; query = new ManagementObjectSearcher(_classname); queryCollection = query.Get(); ((IfrmSetting)iBaseView["FrmSetting"]).loadPrinter(queryCollection, CustomConfigManager.GetPrinter(0), CustomConfigManager.GetPrinter(1), CustomConfigManager.GetPrinter(2)); //消息 ((IfrmSetting)iBaseView["FrmSetting"]).runacceptMessage = CustomConfigManager.GetrunacceptMessage() == 1 ? true : false; ((IfrmSetting)iBaseView["FrmSetting"]).displayWay = CustomConfigManager.GetDisplayWay() == 1 ? true : false; ((IfrmSetting)iBaseView["FrmSetting"]).setbackgroundImage = CustomConfigManager.GetBackgroundImage(); ((IfrmSetting)iBaseView["FrmSetting"]).mainStyle = CustomConfigManager.GetMainStyle(); ((Form)iBaseView["FrmSetting"]).ShowDialog(); } public void SaveSetting() { ((Form)iBaseView["FrmSetting"]).Close(); CustomConfigManager.SaveConfig(((IfrmSetting)iBaseView["FrmSetting"]).inputMethod_EN, ((IfrmSetting)iBaseView["FrmSetting"]).inputMethod_CH, ((IfrmSetting)iBaseView["FrmSetting"]).printfirst, ((IfrmSetting)iBaseView["FrmSetting"]).printsecond, ((IfrmSetting)iBaseView["FrmSetting"]).printthree, ((IfrmSetting)iBaseView["FrmSetting"]).runacceptMessage ? 1 : 0, ((IfrmSetting)iBaseView["FrmSetting"]).displayWay ? 1 : 0, ((IfrmSetting)iBaseView["FrmSetting"]).setbackgroundImage, ((IfrmSetting)iBaseView["FrmSetting"]).mainStyle); } #endregion #region 切換科室 public void OpenReDept() { ((IfrmReSetDept)iBaseView["ReDept"]).UserName = base.GetSysLoginRight.EmpName; ((IfrmReSetDept)iBaseView["ReDept"]).WorkName = base.GetSysLoginRight.WorkName; ((IfrmReSetDept)iBaseView["ReDept"]).loadDepts(frmmain.depts,GetSysLoginRight.DeptId); ((Form)iBaseView["ReDept"]).ShowDialog(); } public void SaveReDept() { BaseDept dept = ((IfrmReSetDept)iBaseView["ReDept"]).getDept(); ((SysLoginRight)EFWCoreLib.CoreFrame.Init.AppGlobal.cache.GetData("RoleUser")).DeptId = dept.DeptId; ((SysLoginRight)EFWCoreLib.CoreFrame.Init.AppGlobal.cache.GetData("RoleUser")).DeptName = dept.Name; frmmain.DeptName = dept.Name; } #endregion #region 修改密碼 public void OpenPass() { ((IfrmPassWord)iBaseView["FrmPassWord"]).clearPass(); ((Form)iBaseView["FrmPassWord"]).ShowDialog(); } public void AlterPass() { bool b = NewObject<User>().AlterPassWrod(GetSysLoginRight.UserId, ((IfrmPassWord)iBaseView["FrmPassWord"]).oldpass, ((IfrmPassWord)iBaseView["FrmPassWord"]).newpass); if (b == false) throw new Exception("您輸入的原始密碼不正確!"); } #endregion #region 消息提醒 /*//? MessageTimer mstimer = null;//消息提醒觸發器 public void InitMessageForm() { if (mstimer != null) { mstimer.Enabled = false; if (TaskbarForm.instance != null) TaskbarForm.instance.ClearMessages(); } mstimer = new MessageTimer(); mstimer.FrmMain = (Form)frmmain; //mstimer.Interval = 20000; mstimer.Enabled = true; } public void ShowMessageForm() { TaskbarForm.ShowForm((Form)frmmain); } */ #endregion } }
2)頁面內部子權限控制
3)關於Web版與Winform版配置菜單的不同之處
Web版菜單配置人員部門管理,如:ModulePlugin/UserLogin/PageUI/DeptEmployeeManager.aspx
Winform版菜單配置人員部門管理,如:EFWBaseLib.WinController.Ation.EmpUserController
前者是配置界面文件地址,后者是配置控制器對象;后來想想這兩個方式有沒有辦法統一,都配置控制器對象?但兩者的實現方式確實思路不一樣,應該說后者更超前一點吧,因為以前后者也是配置界面文件的,后來引入了控制器的概念,一個業務操作的出發點不是從菜單開始,而是又控制器來安排的,比如:點界面修改按鈕會彈出另外一個修改界面,傳統的實現是先Show出窗體,再在窗體Load事件加載修改數據;這種傳統的方式開發起來很簡單,但是有個最大的問題就是把對后台數據的操作分隔開,前后相隔到不同的文件代碼或方法中;而用控制器的方式是這樣,點修改按鈕,向控制器發送一個方法消息,控制器先從后台加載數據,然后在賦值在界面上並Show出窗體;如果我們修改界面換掉了,或不用彈出窗了,控制器前面的數據加載代碼都無需修改,只需修改展示代碼;所以控制器承擔了后台數據訪問與前台界面的展示,所以配菜單的方式由以前的配置界面文件,轉變為配置控制器;
再說一下Web版的菜單配置,web頁面向后台獲取數據都是通過ajax請求並返回數據;而控制器不能主動發送數據到web頁面,兩者不能雙向通訊,這也是Http底層協議的所決定,所以Web版無法像Winform版這種方式來實現;