extjs+MVC4+PetaPoco+AutoFac+AutoMapper後臺管理系統(附源碼)

前言

本項目使用的開發環境及技術列舉以下:
一、開發環境
IDE:VS2010+MVC4
數據庫:SQLServer2008
二、技術
前端:Extjs
後端:
(1)、數據持久層:輕量級ORM框架PetaPoco
(2)、依賴注入:AutoFac
(3)、對象關係映射:AutoMapper
(4)、數據驗證(MVC自帶的驗證封裝使用)
(5)、SQL翻譯機
(6)、緩存html

以上使用都參考或直接借鑑使用了園子內牛人們的代碼,只是學習交流使用而已,還請勿怪,我爲了簡便,沒有分多個類庫,而是以文
件夾的形式分的,你們能夠根據文件夾分紅類庫也是同樣的。好了,廢話很少說,仍是先上幾張圖你們看看吧,若是有興趣再往下看前端

 

項目截圖

要點一:Extjs

 

本項目雖然功能很少,可是基本已經涵蓋了extjs的全部基本用法了,對於通常的extjs初學者或是簡單應用的開發應該是足夠了,後
臺開發主要在tab、grid、treegrid的用法比較多,也是比較麻煩的地方,下面直接上代碼,你們看看web

首頁佈局:ajax

 

  1 /**
  2 * 程序主入口
  3 */
  4 Ext.onReady(function () {
  5     /**
  6     * 上,panel.Panel
  7     */
  8     this.topPanel = Ext.create('Ext.panel.Panel', {
  9         region: 'north',
 10         height: 55
 11     });
 12     /**
 13     * 左,panel.Panel
 14     */
 15     this.leftPanel = Ext.create('Ext.panel.Panel', {
 16         region: 'west',
 17         title: '主菜單',
 18         iconCls: 'House',
 19         width: 200,
 20         layout: 'accordion',
 21         collapsible: true
 22     });
 23     /**
 24     * 右,tab.Panel
 25     */
 26     this.rightPanel = Ext.create('Ext.tab.Panel', {
 27         region: 'center',
 28         layout: 'fit',
 29         id: 'mainContent',
 30         collapisble: true,
 31         tabWidth: 120,   
 32         items: [{ title: '首頁', html: ' <iframe scrolling="auto" frameborder="0" width="100%" height="100%" src="' + DefaultUrl + '"> </iframe>'}]
 33     });
 34     /**
 35     * 下,panel.Panel
 36     */
 37     this.bottomPanel = Ext.create('Ext.panel.Panel', {
 38         region: 'south',
 39         layout: 'fit',
 40         id: 'foot',
 41         collapisble: true,
 42         height: 30,
 43         html:'<div>歡迎您光臨!</div>'
 44     });
 45     /**
 46     * 組建樹
 47     */
 48     Ext.define('TreeModelExtension', {
 49         extend: 'Ext.data.Model',
 50         //當Model實體類模型被用在某個TreeStore上,而且第一次實例化的時候 ,這些個屬性會添加到Model實體類的的原型(prototype )上 (至於上述代碼,則是經過把他設置爲根節點的時候觸發實例化處理的)
 51         fields: [
 52             {name: 'text',  type: 'string'},
 53             {name: 'url',  type: 'string'}
 54         ],
 55     });
 56     var buildTree = function (json) {
 57         return Ext.create('Ext.tree.Panel', {
 58             rootVisible: false,
 59             border: false,
 60             store: Ext.create('Ext.data.TreeStore', {
 61                 model:'TreeModelExtension',
 62                 root: {
 63                     expanded: true,
 64                     children: json.children
 65                 }
 66             }),
 67             listeners: {
 68                 'itemdblclick': function (view, record, item,
 69                                         index, e) {
 70                     var id = record.get('id');
 71                     var text = record.get('text');
 72                     var iconCls = record.get('iconCls');
 73                     var leaf = record.get('leaf');
 74                     var url = record.get('url');
 75                     if (leaf) {      //沒有子節點時才建立新的tab顯示
 76                         var tabs = Ext.getCmp('mainContent');  //獲取佈局頁的Tab組件
 77                         var Loadtab = Ext.getCmp(id);          //判斷Tab是否已經加載
 78                         if(Loadtab==undefined){                  //未加載則加載                          
 79                             tabs.add({
 80                                 id:id,
 81                                 closable: true,
 82                                 //這種方式採起了加載多個iframe的方式,優化看如何採起一個iframe的方式
 83                                 html: ' <iframe scrolling="auto" frameborder="0" width="100%" height="100%" src="' + url + '"> </iframe>',
 84                                 iconCls: iconCls,
 85                                 title: text
 86                             }).show()
 87                         }else{                                           //已加載則設置爲活動頁
 88                             //tabs.setActiveTab(id);           //適合於數據量較大,可是不須要實時改變得狀況下,直接將已打開的tab設置爲活動tab
 89 
 90                             //適合於須要實時展現最新數據的狀況,先移除已打開的此tab,而後再從新加載
 91                             tabs.remove(id);
 92                             tabs.add({
 93                                 id: id,
 94                                 closable: true,
 95                                 //這種方式採起了加載多個iframe的方式,優化看如何採起一個iframe的方式
 96                                 html: ' <iframe scrolling="auto" frameborder="0" width="100%" height="100%" src="' + url + '"> </iframe>',
 97                                 iconCls: iconCls,
 98                                 title: text
 99                             }).show()
100                         }
101                     }
102                 },
103                 scope: this
104             }
105         });
106     };
107     /**
108     * 加載菜單樹
109     */
110     Ext.Ajax.request({
111         url: AjaxPath,
112 
113         success: function (response) {
114             var json = Ext.JSON.decode(response.responseText)
115             Ext.each(json.data, function (el) {
116                 var panel = Ext.create(
117                                                 'Ext.panel.Panel', {
118                                                     id: el.id,
119                                                     title: el.text,
120                                                     iconCls:el.iconCls,
121                                                     layout: 'fit'
122                                                 });
123                 panel.add(buildTree(el));
124                 leftPanel.add(panel);
125             });
126         },
127         failure: function (request) {
128             Ext.MessageBox.show({
129                 title: '操做提示',
130                 msg: "鏈接服務器失敗",
131                 buttons: Ext.MessageBox.OK,
132                 icon: Ext.MessageBox.ERROR
133             });
134         },
135         method: 'post'
136     });
137     /**
138     * Viewport
139     */
140     Ext.create('Ext.container.Viewport', {
141         layout: 'border',
142         renderTo: Ext.getBody(),
143         items: [this.topPanel, this.leftPanel, this.rightPanel, this.bottomPanel]
144     });
145 });
View Code

 

 

 

Grid行內增刪改查:sql

  1 Ext.onReady(function () {
  2     //    ExtJS組件自適應瀏覽器大小改變,看還有沒有其餘實現方式
  3     Ext.EventManager.onWindowResize(function () {
  4         Ext.ComponentManager.each(function (cmpId, cmp, length) {
  5             if (cmp.hasOwnProperty("renderTo")) {
  6                 cmp.doLayout();
  7             }
  8         });
  9     });
 10     var toolbar = Ext.create('Ext.toolbar.Toolbar', {
 11         renderTo: document.body,
 12         items: [
 13         // 使用右對齊容器
 14         '->', // 等同 { xtype: 'tbfill' }
 15         {
 16         xtype: 'textfield',
 17         name: 'roleName',
 18         id: 'roleName',
 19         emptyText: '輸入角色名關鍵字',
 20         listeners: {
 21             specialkey: function (field, e) {
 22                 if (e.getKey() == Ext.EventObject.ENTER) {
 23                     store.load({                //傳遞查詢條件參數
 24                         params: {
 25                             roleName: Ext.getCmp('roleName').getValue()
 26                         }
 27                     });
 28                 }
 29             }
 30         }
 31     },
 32     {
 33         // xtype: 'button', // 默認的工具欄類型
 34         text: '查詢',
 35         tooltip: '根據數據條件查詢數據',
 36         iconCls: "Zoom",
 37         listeners: {
 38             click: function () {
 39                 store.load({                //傳遞查詢條件參數
 40                     params: {
 41                         roleName: Ext.getCmp('roleName').getValue()
 42                     }
 43                 });
 44             }
 45         }
 46     },
 47     // 添加工具欄項之間的垂直分隔條
 48         '-', // 等同 {xtype: 'tbseparator'} 建立 Ext.toolbar.Separator
 49     {
 50     // xtype: 'button', // 默認的工具欄類型
 51     text: '重置',
 52     tooltip: '清空當前查詢條件',
 53     iconCls: "Arrowrotateanticlockwise",
 54     handler: function () {                   //此事件能夠代替click事件
 55         Ext.getCmp('roleName').setValue("");
 56     }
 57 },
 58     ]
 59 });
 60 //1.定義Model
 61 Ext.define("BeiDream.model.BeiDream_Role", {
 62     extend: "Ext.data.Model",
 63     fields: [
 64         { name: 'ID', type: 'int' },
 65         { name: 'Name', type: 'string' },
 66         { name: 'Description', type: 'string' },
 67         { name: 'IsUsed', type: 'boolean', defaultValue: true }
 68     ]
 69 });
 70 //2.建立store
 71 var store = Ext.create("Ext.data.Store", {
 72     model: "BeiDream.model.BeiDream_Role",
 73     autoLoad: true,
 74     pageSize: 10,
 75     proxy: {
 76         type: 'ajax',
 77         api: {
 78             read: RoleListUrl, //查詢
 79             create: AddUrl, //建立
 80             update: UpdateUrl, //更新,必須真正修改了纔會觸發
 81             destroy: RemoveUrl //刪除
 82         },
 83         reader: {
 84             type: 'json',
 85             root: 'data'
 86         },
 87         writer: {
 88             type: 'json',  //默認格式          //MVC下後臺使用模型自動進行轉換,若是是普通webform,則配置root:'data',encode:'true',這樣以後就可使用request【data】獲取
 89             writeAllFields: true,   //false只提交修改過的字段
 90             allowSingle: false      //默認爲true,爲true時,一條數據不以數組形式提交,爲false時,都以數組形式提交,這樣避免了提交了一條數據時,後臺是list模型沒法接收到數據問題
 91         },
 92         listeners: {
 93             exception: function (proxy, response, operation) {
 94                 grid.store.load();    //刪除失敗,數據從新加載
 95                 var resText = Ext.decode(response.responseText);
 96                 Ext.MessageBox.show({
 97                     title: '服務器端異常',
 98                     msg: resText.msg,
 99                     icon: Ext.MessageBox.ERROR,
100                     buttons: Ext.Msg.OK
101                 });
102             }
103         }
104     }
105     //    sorters: [{
106     //        //排序字段。  
107     //        property: 'id'
108     //    }] 
109 });
110 store.on('beforeload', function (store, options) {
111     var params = { roleName: Ext.getCmp('roleName').getValue() };
112     Ext.apply(store.proxy.extraParams, params);
113 });
114 var Gridtoolbar = Ext.create('Ext.toolbar.Toolbar', {
115     renderTo: document.body,
116     items: [{
117         text: '新增',
118         tooltip: '新增一條數據',
119         iconCls: 'Add',
120         handler: function () {
121             RowEditing.cancelEdit();
122             // Create a model instance
123             var r = new BeiDream.model.BeiDream_Role();
124             Ext.getCmp('RoleGrid').getStore().insert(0, r);
125             RowEditing.startEdit(0, 0);
126         }
127     }, '-', {
128         text: '編輯',
129         tooltip: '編輯當前選擇行數據',
130         iconCls: 'Pencil',
131         handler: function () {
132             RowEditing.cancelEdit();
133             var data = Ext.getCmp("RoleGrid").getSelectionModel().getSelection();
134             RowEditing.startEdit(data[0].index, 0);
135         },
136         disabled: true
137     }, '-', {
138         itemId: 'removeUser',
139         text: '刪除',
140         tooltip: '能夠多選刪除多條數據',
141         iconCls: 'Delete',
142         handler: function () {
143             Ext.MessageBox.confirm('提示', '肯定刪除該記錄?', function (btn) {
144                 if (btn != 'yes') {
145                     return;
146                 }
147                 var sm = Ext.getCmp('RoleGrid').getSelectionModel();
148                 RowEditing.cancelEdit();
149 
150                 var store = Ext.getCmp('RoleGrid').getStore();
151                 store.remove(sm.getSelection());
152                 store.sync(); //根據狀態執行對應的服務器方法,delete,放在remove後才能成功執行服務器方法
153                 if (store.getCount() > 0) {
154                     sm.select(0);
155                 }
156             });
157         },
158         disabled: true
159     }, '-', {
160         itemId: 'gridSync',
161         text: '保存',
162         tooltip: '保存到服務器',
163         iconCls: 'Disk',
164         handler: function () {
165             grid.store.sync();
166             grid.store.commitChanges();   //執行commitChanges()提交數據修改。
167         }
168     }, '-', {
169         itemId: 'gridCancel',
170         text: '取消',
171         tooltip: '取消全部的已編輯數據',
172         iconCls: 'Decline',
173         handler: function () {
174             Ext.MessageBox.confirm('提示', '肯定取消已編輯數據嗎?', function (btn) {
175                 if (btn != 'yes') {
176                     return;
177                 }
178                 grid.store.rejectChanges();   //執行rejectChanges()撤銷全部修改,將修改過的record恢復到原來的狀態
179             });
180         }
181     }, '-', {
182         itemId: 'gridrefresh',
183         text: '刷新',
184         tooltip: '從新加載數據',
185         iconCls: 'Arrowrefresh',
186         handler: function () {
187             grid.store.load();
188         }
189     }, '->', {
190         itemId: 'ImportExcel',
191         text: '導入Excel',
192         tooltip: '導入角色數據',
193         iconCls: 'Pageexcel',
194         handler: function () {
195             Ext.MessageBox.show({
196                 title: '暫未開放',
197                 msg: '即將開放',
198                 icon: Ext.MessageBox.ERROR,
199                 buttons: Ext.Msg.OK
200             });
201         }
202     }, '-', {
203         itemId: 'ExportExcel',
204         text: '導出Ecxel',
205         tooltip: '角色數據導出Excel',
206         iconCls: 'Pageexcel',
207         handler: function () {
208             Ext.MessageBox.show({
209                 title: '暫未開放',
210                 msg: '即將開放',
211                 icon: Ext.MessageBox.ERROR,
212                 buttons: Ext.Msg.OK
213             });
214         }
215     }
216     ]
217 });
218 var RowEditing = Ext.create('Ext.grid.plugin.RowEditing', { // 行編輯模式
219     clicksToEdit: 2,   //雙擊進行修改  1-單擊   2-雙擊   
220     autoCancel: false,
221     saveBtnText: '肯定',
222     cancelBtnText: '取消',
223     errorsText: '錯誤',
224     dirtyText: '你要確認或取消更改',
225     listeners: {
226         cancelEdit: function (rowEditing, context) {
227             // Canceling editing of a locally added, unsaved record: remove it
228             if (context.record.phantom) {    //服務器上是否有此條記錄的標誌,true爲沒有
229                 store.remove(context.record);
230             }
231         },
232         Edit: function (rowEditing, context) {
233             //store.sync();     //根據狀態執行對應的服務器方法,Add/Edit
234             var IsValidate = ValidateInput(context.record.data, context.record.phantom);
235             if (!IsValidate) {
236                 grid.store.rejectChanges();
237             }
238         },
239         validateedit: function (rowEditing, context) {
240 
241         }
242     }
243 });
244 function ValidateInput(data, IsAdd) {
245     var IsValidate;
246     Ext.Ajax.request({
247         url: ValidateInputUrl,
248         method: 'POST',
249         jsonData: data,
250         params: { IsAdd: IsAdd },
251         async: false,
252         success: function (response) {
253             var resText = Ext.decode(response.responseText);
254             if (resText.success) {
255                 Ext.MessageBox.alert('警告', resText.msg);
256                 IsValidate = false;
257             } else {
258                 IsValidate = true;
259             }
260         },
261         failure: function (response, options) {
262             Ext.MessageBox.alert('服務器異常', response.status);
263         }
264     });
265     return IsValidate;
266 }
267 //多選框變化
268 function selectchange() {
269     var count = this.getCount();
270     //刪除
271     if (count == 0) {
272         Gridtoolbar.items.items[2].disable();
273         Gridtoolbar.items.items[4].disable();
274     }
275     else {
276         Gridtoolbar.items.items[2].enable();
277         Gridtoolbar.items.items[4].enable();
278     }
279 }
280 //3.建立grid
281 var grid = Ext.create("Ext.grid.Panel", {
282     id: "RoleGrid",
283     xtype: "grid",
284     store: store,
285     columnLines: true,
286     renderTo: Ext.getBody(),
287     selModel: {
288         injectCheckbox: 0,
289         listeners: {
290             'selectionchange': selectchange
291         },
292         mode: "MULTI",     //"SINGLE"/"SIMPLE"/"MULTI"
293         checkOnly: false     //只能經過checkbox選擇
294     },
295     selType: "checkboxmodel",
296     columns: [
297         { xtype: "rownumberer", text: "序號", width: 40, align: 'center' },
298         { id: "id", text: "ID", width: 40, dataIndex: 'ID', sortable: true, hidden: true },
299         { text: '角色名稱', dataIndex: 'Name', flex: 1, editor: "textfield" },
300         { text: '角色描述', dataIndex: 'Description', flex: 1, editor: "textfield" },
301         { text: '是否啓用', dataIndex: 'IsUsed', flex: 1, xtype: 'checkcolumn', editor: { xtype: 'checkbox', cls: 'x-grid-checkheader-editor'} }
302     ],
303     plugins: [RowEditing],
304     listeners: {
305         itemdblclick: function (me, record, item, index, e, eOpts) {
306             //雙擊事件的操做
307         }
308     },
309     tbar: Gridtoolbar,
310     bbar: { xtype: "pagingtoolbar", store: store, displayInfo: true, emptyMsg: "沒有記錄" }
311 });
312 });

TreeGrid展現:前臺代碼和後臺模型結合數據庫

Ext.onReady(function () {
    //    ExtJS組件自適應瀏覽器大小改變,看還有沒有其餘實現方式
    Ext.EventManager.onWindowResize(function () {
        Ext.ComponentManager.each(function (cmpId, cmp, length) {
            if (cmp.hasOwnProperty("renderTo")) {
                cmp.doLayout();
            }
        });
    });
Ext.create('Ext.container.Viewport', {
    layout: 'border',
    renderTo: Ext.getBody(),
    items: [{
        title: '主菜單模塊',
        region: 'west',
        xtype: 'panel',
        margins: '5 0 0 5',
        width: 200,
        collapsible: true,   // 可摺疊/展開
        id: 'NavigationMenucontainer',
        layout: 'fit'
    }, {
        title: '子菜單列表',
        region: 'center',     // 必須指定中間區域
        xtype: 'panel',
        layout: 'fit',
        id: 'Gridcontainer',
        margins: '5 5 0 0'
    }]
});

    var NavigationMenu=Ext.getCmp('NavigationMenucontainer');
    /**
    * 加載菜單樹
    */
    Ext.Ajax.request({
        url: AjaxPath,
        success: function (response) {
            var json = Ext.JSON.decode(response.responseText)
            Ext.each(json.data, function (el) {
                var panel = Ext.create(
                                                'Ext.panel.Panel', {
                                                    id: el.id,
                                                    layout: 'fit'
                                                });
                var ShowGrid=CreateGrid(el.id);
                Gridcontainer.add(ShowGrid);    //初始化,加載主菜單下的菜單
                panel.add(buildTree(el));
                NavigationMenu.add(panel);
            });
        },
        failure: function (request) {
            Ext.MessageBox.show({
                title: '操做提示',
                msg: "鏈接服務器失敗",
                buttons: Ext.MessageBox.OK,
                icon: Ext.MessageBox.ERROR
            });
        },
        method: 'post'
    });
    var Gridcontainer=Ext.getCmp('Gridcontainer');
   /**
    * 組建樹
    */
    Ext.define('TreeModelExtension', {
        extend: 'Ext.data.Model',
        //當Model實體類模型被用在某個TreeStore上,而且第一次實例化的時候 ,這些個屬性會添加到Model實體類的的原型(prototype )上 (至於上述代碼,則是經過把他設置爲根節點的時候觸發實例化處理的)
        fields: [
            {name: 'text',  type: 'string'},
            {name: 'url',  type: 'string'}
        ],
    });
    var buildTree = function (json) {
        return Ext.create('Ext.tree.Panel', {
            id:'MenuTree',
            rootVisible: true,
            border: false,
            store: Ext.create('Ext.data.TreeStore', {
                model:'TreeModelExtension',
                root: {
                    id:json.id,
                    text:json.text,
                    iconCls: json.iconCls,
                    expanded: json.expanded,
                    children: json.children
                }
            }),
            listeners: {
                'itemclick': function (view, record, item,
                                        index, e) {
                        var ParentID = record.get('id');
                        var ShowGrid=CreateGrid(ParentID);
                        Gridcontainer.add(ShowGrid);
                    },
                scope: this
            }
        });
    };

function CreateGrid(ParentID) {
var Gridtoolbar = Ext.create('Ext.toolbar.Toolbar', {
    renderTo: document.body,
    items: [{
        text: '新增',
        tooltip: '新增一條數據',
        iconCls: 'Add',
        handler: function () {
            RowEditing.cancelEdit();
            // Create a model instance
            var r = new BeiDream.model.BeiDream_NavigationMenu();
            Ext.getCmp('NavigationMenuGrid').getStore().insert(0, r);
            RowEditing.startEdit(0, 0);
        }
    }, '-', {
        text: '編輯',
        tooltip: '編輯當前選擇行數據',
        iconCls: 'Pencil',
        handler: function () {
            RowEditing.cancelEdit();
            var data = Ext.getCmp("NavigationMenuGrid").getSelectionModel().getSelection();
            RowEditing.startEdit(data[0].index, 0);
        },
        disabled: true
    }, '-', {
        itemId: 'removeUser',
        text: '刪除',
        tooltip: '能夠多選刪除多條數據',
        iconCls: 'Delete',
        handler: function () {
            Ext.MessageBox.confirm('提示', '肯定刪除該記錄?', function (btn) {
                if (btn != 'yes') {
                    return;
                }
                var sm = Ext.getCmp('NavigationMenuGrid').getSelectionModel();
                RowEditing.cancelEdit();

                var store = Ext.getCmp('NavigationMenuGrid').getStore();
                store.remove(sm.getSelection());
                store.sync(); //根據狀態執行對應的服務器方法,delete,放在remove後才能成功執行服務器方法
                if (store.getCount() > 0) {
                    sm.select(0);
                }
            });
        },
        disabled: true
    }, '-', {
        itemId: 'gridSync',
        text: '保存',
        tooltip: '保存到服務器',
        iconCls: 'Disk',
        handler: function () {
            var grid=Ext.getCmp('NavigationMenuGrid');
            grid.store.sync();
            grid.store.commitChanges();   //執行commitChanges()提交數據修改。
        }
    }, '-', {
        itemId: 'gridCancel',
        text: '取消',
        tooltip: '取消全部的已編輯數據',
        iconCls: 'Decline',
        handler: function () {
            Ext.MessageBox.confirm('提示', '肯定取消已編輯數據嗎?', function (btn) {
                if (btn != 'yes') {
                    return;
                }
                var grid=Ext.getCmp('NavigationMenuGrid');
                grid.store.rejectChanges();   //執行rejectChanges()撤銷全部修改,將修改過的record恢復到原來的狀態
            });
        }
    }, '-', {
        itemId: 'gridrefresh',
        text: '刷新',
        tooltip: '從新加載數據',
        iconCls: 'Arrowrefresh',
        handler: function () {
             var grid=Ext.getCmp('NavigationMenuGrid');
            grid.store.load();
        }
    }
    ]
});

var RowEditing = Ext.create('Ext.grid.plugin.RowEditing', { // 行編輯模式
    clicksToEdit: 2,   //雙擊進行修改  1-單擊   2-雙擊   
    autoCancel: false,
    saveBtnText: '肯定',
    cancelBtnText: '取消',
    errorsText: '錯誤',
    dirtyText: '你要確認或取消更改',
    listeners: {
//        beforeedit: function (rowEditing,e,context) {
//            if(e.colldx==2 && e.record.data.IsLeaf==false){
//                return false;
//            }else{
//               return true;
//            }
//        },
        cancelEdit: function (rowEditing, context) {
            // Canceling editing of a locally added, unsaved record: remove it
            if (context.record.phantom) {    //服務器上是否有此條記錄的標誌,true爲沒有
                store.remove(context.record);
            }
        },
        Edit: function (rowEditing, context) {
            //store.sync();     //根據狀態執行對應的服務器方法,Add/Edit
            //var IsValidate = ValidateInput(context.record.data, context.record.phantom);
//            if (!IsValidate) {
//                grid.store.rejectChanges(); 
//            }
        }
    }
});
function ValidateInput(data, IsAdd) {
    var IsValidate;
    Ext.Ajax.request({
        url: ValidateInputUrl,
        method: 'POST',
        jsonData: data,
        params: { IsAdd: IsAdd },
        async: false,
        success: function (response) {
            var resText = Ext.decode(response.responseText);
            if (resText.success) {
                Ext.MessageBox.alert('警告', resText.msg);
                IsValidate = false;
            } else {
                IsValidate = true;
            }
        },
        failure: function (response, options) {
            Ext.MessageBox.alert('服務器異常', response.status);
        }
    });
    return IsValidate;
}
//多選框變化
function selectchange() {
    var count = this.getCount();
    //刪除
    if (count == 0) {
        Gridtoolbar.items.items[2].disable();
        Gridtoolbar.items.items[4].disable();
    }
    else {
        Gridtoolbar.items.items[2].enable();
        Gridtoolbar.items.items[4].enable();
    }
}
//1.定義Model
Ext.define("BeiDream.model.BeiDream_NavigationMenu", {
    extend: "Ext.data.Model",
    fields: [
        { name: 'ID', type: 'int' },
        { name: 'ParentID', type: 'int' },
        { name: 'ShowName', type: 'string', defaultValue: '名稱......' },
        { name: 'IsLeaf', type: 'boolean', defaultValue: true },
        { name: 'url', type: 'string' },
        { name: 'OrderNo', type: 'int', defaultValue: 1 },
        { name: 'iconCls', type: 'string' },
        { name: 'Expanded', type: 'boolean', defaultValue: false }
    ]
});
//2.建立store
var store = Ext.create("Ext.data.Store", {
    model: "BeiDream.model.BeiDream_NavigationMenu",
    autoLoad: true,
    pageSize: 15,
    proxy: {
        type: 'ajax',
        api: {
            read: MenuListUrl, //查詢
            create: AddUrl, //建立
            update: UpdateUrl, //更新,必須真正修改了纔會觸發
            destroy: RemoveUrl //刪除
        },
        reader: {
            type: 'json',
            root: 'data'
        },
        writer: {
            type: 'json',  //默認格式          //MVC下後臺使用模型自動進行轉換,若是是普通webform,則配置root:'data',encode:'true',這樣以後就可使用request【data】獲取
            writeAllFields: true,   //false只提交修改過的字段
            allowSingle: false      //默認爲true,爲true時,一條數據不以數組形式提交,爲false時,都以數組形式提交,這樣避免了提交了一條數據時,後臺是list模型沒法接收到數據問題
        },
        listeners: {
            exception: function (proxy, response, operation) {
//                 var grid=Ext.getCmp('NavigationMenuGrid');
//                grid.store.load();    //刪除失敗,數據從新加載
                var resText = Ext.decode(response.responseText);
                Ext.MessageBox.show({
                    title: '服務器端異常',
                    msg: resText.msg,
                    icon: Ext.MessageBox.ERROR,
                    buttons: Ext.Msg.OK
                });
            }
        }
    }
});
store.on('beforeload', function (store, options) {
    var params = { ParentID: ParentID };
    Ext.apply(store.proxy.extraParams, params);
});
        return Ext.create("Ext.grid.Panel", {
        id: "NavigationMenuGrid",
        xtype: "grid",
        store: store,
        columnLines: true,
        selModel: {
            injectCheckbox: 0,
            listeners: {
                'selectionchange': selectchange
            },
            mode: "SINGLE",     //"SINGLE"/"SIMPLE"/"MULTI"
            checkOnly: false     //只能經過checkbox選擇
        },
        selType: "checkboxmodel",
        columns: [
            { xtype: "rownumberer", text: "序號", width: 40, align: 'center' },
            { id: "id", text: "ID", width: 40, dataIndex: 'ID', sortable: true, hidden: true },
            { id: "id", text: "ParentID", width: 40, dataIndex: 'ParentID', sortable: true, hidden: true },
            { text: '名稱', dataIndex: 'ShowName', flex: 1, editor: {
                xtype: 'textfield',
                allowBlank: false
            }  },
            { text: '是否爲模塊', dataIndex: 'IsLeaf', flex: 1, xtype: 'checkcolumn', editor: { xtype: 'checkbox', cls: 'x-grid-checkheader-editor'} },
            { text: '控制器路徑', dataIndex: 'url', flex: 1, editor : {
                    xtype: 'combobox',
                    editable:false,    
                    listeners: {
                        //點擊下拉列表事件
                        expand: function (me, event, eOpts) {
                            var grid=Ext.getCmp('NavigationMenuGrid');
                            var record = grid.getSelectionModel().getLastSelected();
                            if(record!=null){
                               if(record.data.IsLeaf==true){
                                      currentComboBox = me;
                                      f_openSelectControllerWin();
                               }else{
                                    Ext.MessageBox.alert('警告', '只有模塊才擁有控制器!');
                               }
                            }                          

                        }
                    }
            }  },
            { text: '排序號', dataIndex: 'OrderNo',align:"center", width: 48, flex: 1,editor: {
                xtype: 'numberfield',
                allowBlank: false,
                minValue: 1,
                maxValue: 150000
            } },
            { text: '圖標', dataIndex: 'iconCls',align:"center", width: 48,renderer : function(value) {
                    return "<div Align='center' style='height:16px;width:16px' class="+value+"></div>";
               } ,editor : {
                    xtype: 'combobox',
                    editable:false,    
                    listeners: {
                        //點擊下拉列表事件
                        expand: function (me, event, eOpts) {
                            currentComboBox = me;
                            f_openIconsWin();
                        }
                    }
            } },
            { text: '是否展開', dataIndex: 'Expanded', flex: 1, xtype: 'checkcolumn', editor: { xtype: 'checkbox', cls: 'x-grid-checkheader-editor'} }
        ],
        plugins: [RowEditing],
        tbar: Gridtoolbar,
        bbar: { xtype: "pagingtoolbar", store: store, displayInfo: true, emptyMsg: "沒有記錄" }
    });
  };
});

要點二:後臺MVC的傳參綁定,返回值自定義

MVC方便了Ajax的異步實現,而且方便的模型傳參,代碼以下編程

 1         /// <summary>
 2         /// 返回數據庫新增後的實體,供前臺的extjs的 grid的store更新數據,這樣就不須要進行從新加載store了,刪,改相似
 3         /// </summary>
 4         /// <param name="Roles"></param>
 5         /// <returns></returns>
 6         [Anonymous]
 7         [HttpPost]
 8         public ActionResult Add(List<BeiDream_Role> Roles)
 9         {
10             List<BeiDream_Role> AddRoles = new List<BeiDream_Role>();
11             List<Object> ListObj = RoleService.Add(Roles);
12             if (ListObj.Count == 0)
13             {
14                 List<string> msg = new List<string>();
15                 msg.Add("添加角色失敗!");
16                 return this.ExtjsJsonResult(false, msg);
17             }
18             else
19             {
20                 foreach (var item in ListObj)
21                 {
22                     AddRoles.Add(RoleService.GetModelByID(item));
23                 }
24                 List<string> msg = new List<string>();
25                 msg.Add("添加角色成功!");
26                 return this.ExtjsJsonResult(true, AddRoles, msg);
27             }
28 
29         }

能夠看到我直接經過後臺模型來接收前臺傳遞過來的參數,而不須要去一一解析參數值json

返回值自定義:重寫了ActionResult,實現了extjs須要的返回值後端

 1    /// <summary>
 2     /// 擴展的jsonResult模型,適用於extjs須要的json數據類型
 3     /// </summary>
 4     public class JsonResultExtension:ActionResult
 5     {
 6         public bool success { get; set; }
 7         public string msg { get; set; }
 8         public object data { get; set; }
 9         public long? total { get; set; }
10         public Dictionary<string, string> errors { get; set; }
11         /// <summary>
12         /// 是否序列化爲extjs須要的json格式,不然進行普通序列化
13         /// </summary>
14         public bool ExtjsUISerialize { get; set; }
15         public override void ExecuteResult(ControllerContext context)
16         {
17 
18             if (context == null)
19             {
20                 throw new ArgumentNullException("context");
21             }
22             HttpResponseBase response = context.HttpContext.Response;
23             response.ContentType = "application/json";
24 
25             StringWriter sw = new StringWriter();
26             //IsoDateTimeConverter timeFormat = new IsoDateTimeConverter();
27             //timeFormat.DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
28             IsoDateTimeConverter timeFormat = new IsoDateTimeConverter();
29             timeFormat.DateTimeFormat = "yyyy-MM-dd";
30             JsonSerializer serializer = JsonSerializer.Create(
31                 new JsonSerializerSettings
32                 {
33                     Converters = new JsonConverter[] { timeFormat },
34                     ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
35                     NullValueHandling = NullValueHandling.Ignore    //忽略爲null的值序列化
36 
37                 }
38                 );
39 
40 
41             using (JsonWriter jsonWriter = new JsonTextWriter(sw))
42             {
43                 jsonWriter.Formatting = Formatting.Indented;
44 
45                 if (ExtjsUISerialize)
46                     serializer.Serialize(jsonWriter, this);
47                 else
48                     serializer.Serialize(jsonWriter, data);
49             }
50             response.Write(sw.ToString());
51 
52         }
53     }

特性標註及權限驗證,代碼以下api

 1     /// <summary>
 2     /// 權限攔截
 3     /// </summary>
 4     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
 5     public class PermissionFilterAttribute : ActionFilterAttribute
 6     {
 7         /// <summary>
 8         /// 權限攔截
 9         /// </summary>
10         /// <param name="filterContext"></param>
11         public override void OnActionExecuting(ActionExecutingContext filterContext)
12         {
13             if (!this.CheckAnonymous(filterContext))
14             {
15                 //未登陸驗證
16                 if (SessionHelper.Get("UserID") == null)
17                 {
18                     //跳轉到登陸頁面
19                     filterContext.RequestContext.HttpContext.Response.Redirect("~/Admin/User/Login");
20                 }
21             }
22         }
23         /// <summary>
24         /// [Anonymous標記]驗證是否匿名訪問
25         /// </summary>
26         /// <param name="filterContext"></param>
27         /// <returns></returns>
28         public bool CheckAnonymous(ActionExecutingContext filterContext)
29         {
30             //驗證是不是匿名訪問的Action
31             object[] attrsAnonymous = filterContext.ActionDescriptor.GetCustomAttributes(typeof(AnonymousAttribute), true);
32             //是不是Anonymous
33             var Anonymous = attrsAnonymous.Length == 1;
34             return Anonymous;
35         }
36     }

經過寫一個BaseController來進行權限的驗證,這樣就不須要全部須要驗證的Controller加標註了,固然BaseController還能夠增長其餘通用的處理

1     /// <summary>
2     /// Admin後臺系統公共控制器(須要驗證的模塊)
3     /// </summary>
4     [PermissionFilter]
5     public class BaseController:Controller
6     {
7 
8     }

 要點三:輕量級ORM框架PetaPoco  

  非侵入性ORM框架,只須要一個PetaPoco.cs文件就OK了,不過我對其進行了再次封裝,實現了工做單元,仍是上代碼吧

      一:封裝

 1    public interface IDataRepository<TEntity> : IDependency where TEntity : class
 2         {
 3             #region 屬性
 4 
 5             /// <summary>
 6             ///     獲取 當前實體的查詢數據集
 7             /// </summary>
 8             Database PetaPocoDB { get; }
 9 
10             #endregion
11 
12             #region 公共方法
13 
14             /// <summary>
15             ///     插入實體記錄
16             /// </summary>
17             /// <param name="entity"> 實體對象 </param>
18             /// <returns> 操做影響的行數 </returns>
19             bool Add(TEntity entity);
20 
21             /// <summary>
22             ///     批量插入實體記錄集合
23             /// </summary>
24             /// <param name="entities"> 實體記錄集合 </param>
25             /// <returns> 操做影響的行數 </returns>
26             List<object> Add(IEnumerable<TEntity> entities);
27 
28             /// <summary>
29             ///     刪除實體記錄
30             /// </summary>
31             /// <param name="entity"> 實體對象 </param>
32             /// <returns> 操做影響的行數 </returns>
33             int Delete(TEntity entity);
34 
35             /// <summary>
36             ///     刪除實體記錄集合
37             /// </summary>
38             /// <param name="entities"> 實體記錄集合 </param>
39             /// <returns> 操做影響的行數 </returns>
40             bool Delete(IEnumerable<TEntity> entities);
41 
42             /// <summary>
43             ///     更新實體記錄
44             /// </summary>
45             /// <param name="entity"> 實體對象 </param>
46             /// <returns> 操做影響的行數 </returns>
47             int Update(TEntity entity);
48 
49             /// <summary>
50             ///     更新實體記錄
51             /// </summary>
52             /// <param name="entity"> 實體對象 </param>
53             /// <returns> 操做影響的行數 </returns>
54             bool Update(IEnumerable<TEntity> entities);
55             /// <summary>
56             /// 根據主鍵ID獲取實體
57             /// </summary>
58             /// <param name="KeyID">主鍵ID</param>
59             /// <returns>實體</returns>
60             TEntity GetModelByID(object KeyID);
61 
62             /// <summary>
63             /// 動態查詢,返回dynamic類型的列表
64             /// 請使用標準SQL語句進行查詢(SELECT ... FROM ...)
65             /// </summary> 
66             /// <returns></returns>
67             PagedList<dynamic> DynamicPagedList(int pageIndex, int pageSize, Sql sql);
68 
69             PagedList<TEntity> PagedList(int pageIndex, int pageSize, string sql, params object[] args);
70 
71             PagedList<TEntity> PagedList(int pageIndex, int pageSize, Sql sql);
72 
73             PagedList<TDto> PagedList<TDto>(int pageIndex, int pageSize, string sql, params object[] args);
74 
75             PagedList<TDto> PagedList<TDto>(int pageIndex, int pageSize, Sql sql);
76             #endregion
77         }
View Code

     二:使用,具體封裝和使用,你們仍是去下載源碼看吧

 1     public class NavigationMenuService : DbContextBase<BeiDream_NavigationMenu>, INavigationMenuService, IDependency
 2     {
 3         public NavigationMenuService(IUnitOfWork unitOfWork)
 4             : base(unitOfWork)
 5         { }
 6         public List<NavigationMenu> GetNavigationMenu(int id)
 7         {
 8             var sql = Sql.Builder.Where("ParentID=@0",id);
 9             sql.OrderBy("OrderNo ASC");   //默認ASC升序,降序爲DESC
10             List<BeiDream_NavigationMenu> List = this.PetaPocoDB.Fetch<BeiDream_NavigationMenu>(sql);
11             return AutoMapperHelper.GetMapper(List);
12         }
13         public List<NavigationMenu> GetNavigationMenuNoLeaf(int id)
14         {
15             var sql = Sql.Builder.Where("ParentID=@0", id);
16             sql.Where("IsLeaf=@0", false);
17             sql.OrderBy("OrderNo ASC");   //默認ASC升序,降序爲DESC
18             List<BeiDream_NavigationMenu> List = this.PetaPocoDB.Fetch<BeiDream_NavigationMenu>(sql);
19             return AutoMapperHelper.GetMapper(List);
20         }
21         /// <summary>
22         /// 遞歸查詢產品分類列表
23         /// </summary>
24         /// <param name="list">父級產品分類列表</param>
25         public void GetNavigationMenus(ref List<NavigationMenu> list)
26         {
27             foreach (NavigationMenu season in list)
28             {
29                 List<NavigationMenu> lstSeason = GetNavigationMenu(season.id);
30                 season.children = lstSeason;
31                 if (list.Count > 0)
32                 {
33                     GetNavigationMenus(ref lstSeason);
34                 }
35             }
36         }
37         /// <summary>
38         /// 遞歸查詢產品分類列表
39         /// </summary>
40         /// <param name="list">父級產品分類列表</param>
41         public void GetNavigationMenusNoLeaf(ref List<NavigationMenu> list)
42         {
43             foreach (NavigationMenu season in list)
44             {
45                 List<NavigationMenu> lstSeason = GetNavigationMenuNoLeaf(season.id);
46                 season.children = lstSeason;
47                 if (list.Count > 0)
48                 {
49                     GetNavigationMenusNoLeaf(ref lstSeason);
50                 }
51             }
52         }
53     }
View Code

 

要點四:依賴注入框架Autofac

目前使用心得最大的好處就是不須要配置即實現了面向接口編程,特別是和MVC結合,實現構造函數注入就更加方便了,固然它還有其餘
功能,好比生命週期惟一實例,單例啊等等,暫時還研究不深,只是簡單應用,你們看看具體實現吧

 1         private static void AutofacMvcRegister()
 2         {
 3             ContainerBuilder builder = new ContainerBuilder();
 4             builder.RegisterGeneric(typeof(DbContextBase<>)).As(typeof(IDataRepository<>));
 5             Type baseType = typeof(IDependency);
 6             Assembly[] assemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies()
 7                 .Select(Assembly.Load).ToArray();
 8             assemblies = assemblies.Union(new[] { Assembly.GetExecutingAssembly() }).ToArray();
 9             builder.RegisterAssemblyTypes(assemblies)
10                 .Where(type => baseType.IsAssignableFrom(type) && !type.IsAbstract)
11                 .AsImplementedInterfaces().InstancePerLifetimeScope();//InstancePerLifetimeScope 保證生命週期基於請求
12 
13             //無效
14             //builder.RegisterType<DefaultCacheAdapter>().PropertiesAutowired().As<ICacheStorage>();
15 
16             builder.RegisterControllers(Assembly.GetExecutingAssembly());
17             builder.RegisterFilterProvider();
18             IContainer container = builder.Build();
19             DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
20         }

要點五;對象關係映射AutoMapper

目前也只是簡單應用,先看代碼,它是如何簡化咱們的工做量的

 1         public static List<NavigationMenu> GetMapper(List<BeiDream_NavigationMenu> List)
 2         {
 3             List<NavigationMenu> NavigationMenuList = new List<NavigationMenu>();
 4             foreach (var item in List)
 5             {
 6                 //NavigationMenu DaoModel = new NavigationMenu();
 7                 //DaoModel.id = item.ID;
 8                 //DaoModel.text = item.ShowName;
 9                 //DaoModel.leaf = item.IsLeaf;
10                 //DaoModel.url = item.url;
11                 //DaoModel.Expanded = item.Expanded;
12                 //DaoModel.children = null;
13                 NavigationMenu DaoModel = item.ToDestination<BeiDream_NavigationMenu, NavigationMenu>();
14                 NavigationMenuList.Add(DaoModel);
15             }
16             return NavigationMenuList;
17         }

註釋掉的是不使用automapper以前的代碼,沒註釋掉的是使用automapper,擴展了方法直接一句代碼實現轉化,是否是很easy,固然實
現這些以前,咱們須要給他定義規則,而後還要註冊,代碼以下,具體的請看源碼

 1     public class NavigationMenuProfile : Profile
 2     {
 3         protected override void Configure()
 4         {
 5             CreateMap<BeiDream_NavigationMenu, NavigationMenu>()
 6                 .ForMember(dest => dest.id, opt => opt.MapFrom(src => src.ID))
 7                 .ForMember(dest => dest.text, opt => opt.MapFrom(src => src.ShowName))
 8                 .ForMember(dest => dest.leaf, opt => opt.MapFrom(src => src.IsLeaf));
 9         }
10     }

要點六:數據驗證

extjs前臺驗證咱們已經作了,可是客戶端傳來的東西咱們不能徹底相信,後臺須要再次驗證,咱們看到mvc的官方demo。一句話就實現
了驗證,咱們是否是能夠本身作驗證呢,看代碼

 1         [Anonymous]
 2         public ActionResult SaveUser(BeiDream_User model, List<int> Roles)
 3         {
 4             var ValidateResult = Validation.Validate(model);//服務器端的驗證
 5             if (ValidateResult.IsValid)     //驗證成功
 6             {
 7                 bool IsExitUser = UserService.PetaPocoDB.Exists<BeiDream_User>(model.ID);
 8                 if (!IsExitUser)
 9                 {
10                     FilterGroup userRoleGroup = new FilterGroup();
11                     FilterHelper.CreateFilterGroup(userRoleGroup, null, "UserName", model.UserName, GroupOperatorQueryEnum.and, RuleOperatorQueryEnum.equal);
12                     bool IsExist = UserService.IsExist(userRoleGroup);
13                     if (IsExist)
14                     {
15                         List<string> errorName=new List<string>();
16                         errorName.Add("UserName");
17                         ValidationResult error = new ValidationResult("已存在相同的用戶名", errorName);
18                         ValidateResult.Add(error);
19                          return this.ExtjsFromJsonResult(false,ValidateResult); 
20                     }
21                     else
22                     {
23                         bool IsSaveSuccess = TransactionService.AddUserAndUserRole(model, Roles);
24                         List<string> msg = new List<string>();
25                         msg.Add(IsSaveSuccess ? "用戶信息保存成功!" : "用戶信息保存失敗!");
26                         return this.ExtjsFromJsonResult(true, null, msg); 
27                     }
28                 }
29                 else
30                 {
31                     FilterGroup userRoleGroup = new FilterGroup();
32                     FilterHelper.CreateFilterGroup(userRoleGroup, null, "UserName", model.UserName, GroupOperatorQueryEnum.and, RuleOperatorQueryEnum.equal);
33                     FilterHelper.CreateFilterGroup(userRoleGroup, null, "ID", model.ID, GroupOperatorQueryEnum.and, RuleOperatorQueryEnum.notequal);
34                     bool IsExist = UserService.IsExist(userRoleGroup);
35                     if (IsExist)
36                     {
37                         List<string> errorName = new List<string>();
38                         errorName.Add("UserName");
39                         ValidationResult error = new ValidationResult("已存在相同的用戶名", errorName);
40                         ValidateResult.Add(error);
41                         return this.ExtjsFromJsonResult(false, ValidateResult); 
42                     }
43                     else
44                     {
45                         bool IsSaveSuccess = TransactionService.UpdateUserAndUserRole(model, Roles);
46                         List<string> msg = new List<string>();
47                         msg.Add(IsSaveSuccess ? "用戶信息保存成功!" : "用戶信息保存失敗!");
48                         return this.ExtjsFromJsonResult(true, null, msg); 
49                     }
50                 }
51             }
52             else
53             {
54                 return this.ExtjsFromJsonResult(false,ValidateResult);   //驗證失敗,返回失敗的驗證結果,給出前臺提示信息
55             }          
56         }

你們能夠看到前臺傳進來的參數,咱們先進行驗證 var ValidateResult = Validation.Validate(model),驗證的條件咱們是在模型上定義好的,而後判斷驗證是否經過,經過進行下一步動做,不經過,把驗證的結果信息返回前臺,提示給用戶

要點七:SQL翻譯機

這個只能算是一個簡單的東西吧,而且感受用起來麻煩,可是我以爲用的熟練了,仍是很不錯的,只是省了手拼SQL的問題嘛,減小了出
錯概率,具體使用仍是看代碼吧

 1         [Anonymous]
 2         public ActionResult GetUserList(int page, int start, int limit, string UserKeyName, string RoleID)
 3         {
 4             RemoveSelectId();
 5             PagedList<BeiDream_User> PageList = null;
 6             FilterGroup userGroup = GetQueryConditions(UserKeyName, RoleID);
 7             PageList = UserService.GetPagedList(page, limit, userGroup);
 8             return this.ExtjsGridJsonResult(PageList, PageList.TotalItemCount);
 9         }
10         private FilterGroup GetQueryConditions(string UserKeyName, string RoleID)
11         {
12             FilterGroup userGroup = new FilterGroup();
13             if (!string.IsNullOrEmpty(RoleID))             //用戶角色不爲空時
14             {
15                 FilterGroup userRoleGroup = new FilterGroup();
16                 FilterHelper.CreateFilterGroup(userRoleGroup, null, "RoleID", RoleID, GroupOperatorQueryEnum.and, RuleOperatorQueryEnum.equal);
17                 //先根據用戶角色查出對應的用戶ID
18                 List<BeiDream_User_Role> List = UserRoleService.GetList(userRoleGroup);
19                 if (List.Count != 0)             //todo,此角色信息爲空狀況下,查到的用戶也應該爲空,目前未處理
20                 {
21                     if (string.IsNullOrEmpty(UserKeyName))
22                     {
23                         //再根據此用戶角色下的用戶ID,由於查出因此用戶ID,查詢條件是或的關係GroupOperatorQueryEnum.or,翻譯出對應用戶的查詢條件,最後查出對應用戶
24                         foreach (var item in List)
25                         {
26                             FilterHelper.CreateFilterGroup(userGroup, null, "ID", item.UserID, GroupOperatorQueryEnum.or, RuleOperatorQueryEnum.equal);
27                         }
28                     }
29                     else
30                     {
31                         //先翻譯出用戶名查詢條件,與其餘查詢條件是與的關係GroupOperatorQueryEnum.and
32                         FilterHelper.CreateFilterGroup(userGroup, null, "UserName", UserKeyName, GroupOperatorQueryEnum.and, RuleOperatorQueryEnum.like);
33                         //由於第二個查詢條件是多個查詢條件的結合組成再與第一個查詢條件結合,故放到子FilterGroup中
34                         List<FilterGroup> filterGroups = new List<FilterGroup>();
35                         FilterGroup userIDGroup = new FilterGroup();
36                         //再根據此用戶角色下的用戶ID,由於查出因此用戶ID,查詢條件是或的關係GroupOperatorQueryEnum.or,翻譯出對應用戶的查詢條件,最後查出對應用戶
37                         foreach (var item in List)
38                         {
39                             FilterHelper.CreateFilterGroup(userIDGroup, null, "ID", item.UserID, GroupOperatorQueryEnum.or, RuleOperatorQueryEnum.equal);
40                         }
41                         filterGroups.Add(userIDGroup);
42                         userGroup.groups = filterGroups;
43                     }
44                 }
45             }
46             else
47             {
48                 if (!string.IsNullOrEmpty(UserKeyName))
49                 {
50                     //先翻譯出用戶名查詢條件,與其餘查詢條件是與的關係GroupOperatorQueryEnum.and
51                     FilterHelper.CreateFilterGroup(userGroup, null, "UserName", UserKeyName, GroupOperatorQueryEnum.and, RuleOperatorQueryEnum.like);
52                 }
53             }
54             return userGroup;
55         } 
View Code

要點八:緩存

 緩存也就簡單應用Helper級別,主要用了.net自帶緩存和分佈式Memcached緩存,一個接口,兩個實現

 1     /// <summary>
 2     /// 緩存接口
 3     /// </summary>
 4    public interface ICacheStorage
 5     {
 6         #region 緩存操做
 7         /// <summary>
 8         /// 添加緩存
 9         /// </summary>
10         /// <param name="key"></param>
11         /// <param name="value"></param>
12         void Insert(string key, object value);
13         /// <summary>
14         /// 添加緩存(默認滑動時間爲20分鐘)
15         /// </summary>
16         /// <param name="key">key</param>
17         /// <param name="value">value</param>
18         /// <param name="expiration">絕對過時時間</param>
19         void Insert(string key, object value, DateTime expiration);
20         /// <summary>
21         /// 添加緩存
22         /// </summary>
23         /// <param name="key">key</param>
24         /// <param name="value">value</param>
25         /// <param name="expiration">過時時間</param>
26         void Insert(string key, object value, TimeSpan expiration);
27         /// <summary>
28         /// 得到key對應的value
29         /// </summary>
30         /// <param name="key"></param>
31         /// <returns></returns>
32         object Get(string key);
33         /// <summary>
34         /// 根據key刪除緩存
35         /// </summary>
36         /// <param name="key"></param>
37         void Remove(string key);
38         /// <summary>
39         /// 緩存是否存在key的value
40         /// </summary>
41         /// <param name="key">key</param>
42         /// <returns></returns>
43         bool Exist(string key);
44         /// <summary>
45         /// 獲取全部的緩存key
46         /// </summary>
47         /// <returns></returns>
48         List<string> GetCacheKeys();
49         /// <summary>
50         /// 清空緩存
51         /// </summary>
52         void Flush();
53         
54         #endregion
55     }

寫在最後

  寫博客真的是很累人的事,很敬佩那些能寫連載博客的牛人們,雖然本身作的項目很小,可是以爲寫成博客,要寫的要點仍是不少的
,上面我講的很粗略,可是主要的知識點都講出來了,這個項目其實沒有作完,不打算再繼續了,打算換了,接下來打算使用easyui
+knockout+ef來寫一個完整的權限管理系統,涉及菜單權限、按鈕權限、字段權限等等吧,路很長.....任重而道遠

最後,你們若是以爲有幫助,請點推薦哦!源碼下載地址:

猛戳這裏BeiDream.part1.rar!

猛戳這裏BeiDream.part2.rar!

相關文章
相關標籤/搜索