使用通用許可權管理系統元件的隨想
本人供職於國內一家比較知名的物流公司,一直從事於基層公司物流軟體的規劃和設計開發工作,在長期的工作實踐中深深地體會到作為不是專業的軟體行業而又從事軟體開發行業的業餘性的軟體開發設計人員來說,在工作中需要克服的困難和麵對的艱辛有多大多難。
對與專業的軟體開發設計公司來說,毋庸置疑的一點是都會有自己成熟穩定的開發框架和元件,並且是在不斷的完善中,對供職其中的開發設計人員在完成業務性的開發設計工作外日常工作的一個重心就在於瞭解、熟悉進而創新性的完善他。作為軟體開發設計人員都知道,任何一個軟體系統都離不開使用者管理、許可權管理等做為核心存在的基本功能,而這僅是上述所說成熟穩定的開發框架和元件的其中一部分。正因為有了成熟穩定開發框架和元件,設計開發人員並不需要去重新構建,從效率和易用性的考慮這節省了大量的開發時間,並且框架強制使用公共的約定,因此它能有效地解決一些共有的問題,也能避免我們寫一大堆自定義模組來實現這些效能,我們所需要做的就是將這些共用模組放在框架中實現。框架節省了我們不少的時間和精力,並且讓擴充套件變得更容易。
以上作為拋磚引玉,現在回到正題。近期考慮為公司(本人供職的基層公司,以下所稱的公司均同此)構建一個倉庫管理方面的資訊系統。在此之前,基於自己的愛好和公司實際業務的需要,曾經多次嘗試利用自己所學(2011年開始接觸學習C#)的技術來構建一個相對穩定成熟的業務系統,以滿足自己的“虛榮心”和公司業務的實際需要,也嘗試過使用一些第三方的開源的技術和框架,可一直沒有能找到一個相對穩定且開發快捷的途徑,大量的時間浪費在尋找框架工具和核心基礎功能上,不光花費了大量的時間,所開發的程式碼無論質量還是執行效率都不盡人意,且程式碼無所謂乾淨清晰,估計現在讓我自己讀起來都有些費勁。
其實算起來從最初接觸《走火入魔許可權管理系統》是在2012年了,那個時候接觸的還是網上免費的V3.2的版本,隨著這幾年來軟體作者的持續改進,程式碼質量和功能日趨完善。到2013年11月,當V4.0版本出來時,感覺到了軟體的強大和對自己日後工作學習的幫助,毅然以個人名義定購了原始碼(呵呵,花的是個人的MONEY,雖然當時有點肉痛,不過經過近半年的接觸學習,覺得還是物有所值的)。
在接觸到新原始碼後,不到一星期就開始準備以一個簡單進銷存為業務藍本著手,抱著在實踐中學習,在學習中完善的心態開始開發練習。當然這是在對作者程式碼質量和核心功能(使用者許可權管理)充分認可的基礎上才可行的。由於作者的原始碼已經包含了所有的關於使用者以及許可權的核心功能,所以在開始開發時我基本上都沒考慮這方面的開發(要知道這個可是我以前花了近兩年的時間也沒有總結出來的經驗,現在有現成的哪能不拿來就用呢,何況功能還那麼強大),直接就以業務藍本著手,開始規劃業務流程、資料庫設計、介面設計(基本上也都是參考),並開始編碼。說到編碼,作者也充分考慮到了程式碼的規範性的要求,提供了一個通用的程式碼生成工具,系統所需要的基本功能在設計好資料庫的基礎上一鍵生成,極大的提高了程式碼開發的質量和效率,而且所生成的程式碼可讀性更強、效率更高、更易被其他軟體開發者所接受,要實現稍微複雜一點的業務邏輯也只需要少量程式碼的改變就能完成。整個《進銷存業務系統》從設計到開發,真正的程式碼開發(含資料庫建表、介面開發)不到1月的時間。
以下是開發例項:
介面主頁面實現左欄手風琴選單,先看效果:
實現步驟:
1、 在主頁面上拖入一個DX的navbarcontrol控制元件,排好版,引數預設
2、編寫核心程式碼:
3、 private void Link_ItemClick(object sender, NavBarLinkEventArgs e)
4、 {
5、 ShowForm((NavBarItem)sender);
6、 }
7、
8、 #region private void LoadTreeModule(TreeNode treeNode) 載入模組選單
9、 /// <summary>
10、 /// 載入模組選單
11、 /// </summary>
12、 /// <param name="group">當前節點</param>
13、 private void LoadModule(List<BaseModuleEntity> moduleEntities, NavBarGroup group)
14、 {
15、 int i = 0;
16、 foreach (BaseModuleEntity moduleEntity in moduleEntities) //以每個子選單做迴圈
17、 {
18、 if (moduleEntity.ParentId == int.Parse(group.Name.Trim()))
19、 {
20、 NavBarItem groupItem = new NavBarItem(); //為每個子選單建立新item,構造體中傳遞子選單名,和子選單ID
21、 groupItem.LargeImageIndex = groupItem.SmallImageIndex = string.IsNullOrEmpty(moduleEntity.ImageIndex) ? i : int.Parse(moduleEntity.ImageIndex);
22、 groupItem.Caption = moduleEntity.FullName;
23、 groupItem.Tag = moduleEntity.FormName;
24、 groupItem.Hint = moduleEntity.AssemblyName;
25、 groupItem.LinkClicked += Link_ItemClick;
26、 group.ItemLinks.Add(groupItem); //在每個組裡新增子選單
27、
28、 i += 1;
29、 }
30、 }
31、 }
32、 #endregion
33、
34、
35、 #region private void LoadTree() 載入樹形結構資料
36、 /// <summary>
37、 /// 載入樹形結構資料
38、 /// </summary>
39、 private void LoadTree()
40、 {
41、 this.navBarControl1.Groups.Clear();//清空控制元件的值
42、
43、 // 這裡是需要載入的跟節點主鍵
44、 int? rootMenuId = null;
45、 int i = 0;
46、
47、 DotNetService dotNetService = new DotNetService();
48、 List<BaseModuleEntity> moduleEntitys = ClientPermissionCache.Instance.UserModuleList;
49、
50、 rootMenuId = 10005235;
51、 foreach (BaseModuleEntity moduleEntity in moduleEntitys)
52、 {
53、 //~這部分可以單獨調優,只是為了把左側功能欄項載入好,要新增項只需修改判斷條件。
54、 //if (string.IsNullOrEmpty(dr[BaseModuleEntity.FieldParentId].ToString()))
55、 if (moduleEntity.ParentId == rootMenuId)
56、 {
57、 //新增Group
58、
59、 NavBarGroup group = navBarControl1.Groups.Add(); // 為每個主選單建立個新分組
60、 group.Caption = moduleEntity.FullName;
61、 group.LargeImageIndex = group.SmallImageIndex = string.IsNullOrEmpty(moduleEntity.ImageIndex) ? i : int.Parse(moduleEntity.ImageIndex);// Convert.ToInt32(row[BaseModuleTable.FieldImageIndex]);
62、 group.Tag = moduleEntity.Target;
63、 group.Name = moduleEntity.Id.ToString();
64、 i += 1;
65、
66、 LoadModule(moduleEntitys, group);
67、
68、 }
69、 }
70、 }
71、 #endregion
記得在初始化窗體時呼叫就OK了。呼叫的程式碼:this.LoadTree();
以下是系統銷售訂單主介面