ABP框架实战 1.基础信息维护

在之前的一个开发项目中,因为公司战略发展,引用了这个ABP开源框架作为新项目的基础版本,由于客户的要求需要迁移旧系统数据,以及其他的一些原因,数据库采用了Oracle数据库管理。所以引用了Dapper这个ORM框架作为数据访问的扩展,在前期的开发过程中,碰到过很多的坑,但是通过学习阳光铭睿tkb至简这两位博主写的一系列文章,以及其他同事的帮助下,慢慢的熟悉了ABP框架的一些原理以及思路。

下面简单介绍一下这个Abp框架以及一些学习的资料:

ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称。

ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应用程序的新起点,它旨在成为一个通用的WEB应用程序框架和项目模板。

ASP.NET Boilerplate 基于DDD的经典分层架构思想,实现了众多DDD的概念(但没有实现所有DDD的概念)。

ABP的官方网站http://www.aspnetboilerplate.com

ABP在Github上的开源项目https://github.com/aspnetboilerplate

阳光铭睿:http://www.cnblogs.com/mienreal/p/4528470.html

tkb至简:http://www.cnblogs.com/farb/p/ABPTheory.html

1.在历经了7个月(1607-1701)的时间,项目前两期的开发工作也算是全部的完成了,幸运的我一直留到了最后,负责后续功能以及App对接的开发,以及试运行问题过程中客户提出问题的维护。

2.在后面的某个日期中,全体这个项目的参与人员进行了一次会议总结,总体来说还算不错吧。

3.在后来的某一天,自己想要在最基础的框架上面弄一个基础的框架管理,关于简单的用户-部门-角色-权限管理这一块,可能还有很多地方没有弄完善的地方,目前还存在一部分的,但是简单来说也能满足一些简单的管理需求吧。(因为在这个项目开发过程中,这一块的数据管理是用的之前公司成熟的一套PMI框架,引用的单点登录,所以只能够参照他的思路来弄)

项目总体框架:

这里链接一个同事写的一篇文章吧,上面有关于这个项目框架的一些详细介绍http://www.cnblogs.com/yuanbeier/articles/6394484.html

下面讲一下自己弄这个的开发过程吧。

a.建立PDM,数据对应关系

b.生成数据库,以及实体,其实这里在ABP最初始的做法是采用Code First模式先建立实体在生成数据结构,个人觉得看自己习惯吧。

c.创立对应的Application Services, Controller,View,Js

d.然后就是具体的编码业务完成了,这个前段采用最快速的easyui开发,在这里参考了之前一个同事写的一个基类,然后在其思路上重新了写了一个基类,在这里的思路也正是考虑到ABP的约定大于规范的开发思路

  1 var TopeveryBase = Base.extend({
  2     /*构造方法*/
  3     constructor: function () {
  4     },
  5     /*初始化表格*/
  6     initGrid: function (options) {
  7         options = $.extend({}, { id: "grid", width: "100%", height: "600", method: "post", singleSelect: true }, options || {});
  8         if (options.url == null) {
  9             options.url = $("#" + options.id).attr("url");
 10         }
 11         if (typeof (options.url) == "undefined") {
 12             options.url = $("#" + options.id).attr("turl");
 13         }
 14         if ($("#" + options.id).attr("singleSelect") === "false") {
 15             options.singleSelect = true;
 16         }
 17         var gridParm = {
 18             idField: "id",
 19             fitColumns: true,
 20             loadMsg: false,
 21             nowrap: false,
 22             queryParams: options.queryParams,
 23             method: options.method,
 24             singleSelect: options.singleSelect,
 25             iconCls: "icon-save",
 26             striped: true,
 27             height: options.height,
 28             animate: true,
 29             collapsible: true,
 30             border: true,
 31             rownumbers: true, //行号
 32             pagination: options.pagination || true, //分页控件
 33             pageSize: 10,
 34             pageList: [1, 10, 20, 50, 100, 250, 500, 1000],
 35             sortName: "Id",
 36             sortOrder: "desc",
 37             toolbar: '#toolbarWrap',
 38             onLoadSuccess: function (data) {
 39                 $(this).datagrid('doCellTip', { 'max-width': '400px', 'delay': 500 });
 40                 $(this).datagrid("clearSelections").datagrid("clearChecked");
 41             },
 42             loader: function (param, success, error) {
 43                 if (typeof (param.sort) == "undefined") {
 44                     param.sort = "Id";
 45                 }
 46                 if (typeof (param.order) == "undefined") {
 47                     param.order = "desc";
 48                 }
 49                 var postParm = {
 50                     PageIndex: param.page,
 51                     PageCount: param.rows,
 52                     sort: param.sort,
 53                     order: param.order
 54                 };
 55                 if (options.queryParams != null) {
 56                     postParm = $.extend({}, postParm, options.queryParams);
 57                 }
 58                 postParm = $.extend({}, postParm);
 59                 var formpostdata = topevery.form2Json("selectFrom");
 60                 postParm = $.extend({}, postParm, formpostdata);
 61                 /* 获取详情*/
 62                 easyuiBase.ajax({
 63                     type: "post",
 64                     url: options.url,
 65                     data: JSON.stringify(postParm),
 66                     loading: false
 67                 }, function (data) {
 68                     if (data.Success) {
 69                         var array = new Object();
 70                         array.rows = data.Result.Rows;
 71                         array.total = data.Result.Total;
 72                         success(array);
 73                     } else {
 74                         error();
 75                     }
 76                 }, true);
 77             }
 78         };
 79         for (var i = 0; i < $(".easyui-textbox").length; i++) {
 80             $("#" + $('.easyui-textbox').eq(i)[0].id + "").textbox({
 81                 inputEvents: $.extend({}, $.fn.textbox.defaults.inputEvents, {
 82                     keyup: function (event) {
 83                         if (event.keyCode === 13) {
 84                             User.loadInfo();
 85                         }
 86                     }
 87                 })
 88             });
 89         };
 90         if (options.columns != null) {
 91             gridParm.columns = options.columns;
 92         }
 93         $("#" + options.id).datagrid(gridParm);
 94     },
 95     /**
 96      * 
 97      * @param {} id 修改时所用查询编号
 98      * @param {} 加载修改查看 callback 回调函数
 99      * @param {} 新增修改之后 callback1 回调函数
100      * @param {} options 参数集合
101      * @returns {} 
102      */
103     View: function (id, callback, callback1, options) {
104         if (id > 0) {
105             options = $.extend({}, { id: "edit", btn: "save", sumbit: "sumbitForm", grid: "grid" }, options || {});
106         } else {
107             options = $.extend({}, { id: "add", btn: "save", sumbit: "sumbitForm", grid: "grid" }, options || {});
108         }
109         var urlstring = $("#" + options.id).attr("url").split(',');
110         //geturl  获取修改需要加载信息
111         if (options.geturl == null) {
112             if (urlstring.length > 0) {
113                 options.geturl = urlstring[1];
114             }
115         }
116         ///新增or修改url
117         if (options.url == null) {
118             options.url = urlstring[0];
119         }
120         $("#" + options.sumbit).form("reset");
121         if (id !== "undefined" && id != null) {
122             //修改时  数据加载到页面
123             easyuiBase.ajax({
124                 type: "POST",
125                 url: options.geturl,
126                 data: JSON.stringify({ Id: id }),
127                 loading: false
128             }, function (data) {
129                 if (data.Success) {
130                     var row = data.Result;
131                     $("#" + options.sumbit).form("load", row);
132                     callback(row);
133                 } else {
134                     error();
135                 }
136             });
137         }
138         //弹出层dialog Id
139         if (options.name == null) {
140             options.name = $("#" + options.id).attr("name");
141         }
142         $("#" + options.name).dialog('open');
143         $("#" + options.btn).click(function () {
144             if ($("#" + options.sumbit).form('validate') === false) {
145                 return;
146             }
147             easyuiBase.ajax({
148                 type: "post",
149                 url: options.url,
150                 data: JSON.stringify(easyuiBase.form2Json(options.sumbit)),
151                 loading: false
152             }, function (data) {
153                 if (data.Success) {
154                     if (data.Result.IsSuccess) {
155                         $("#" + options.name).dialog('close');
156                         try {
157                             topeveryMessage.show(data.Result.Message);
158                         } catch (e) {
159                         }
160                         $("#" + options.sumbit).form("reset");
161                         $("#" + options.grid).datagrid("load");
162                         $("#" + options.btn).unbind();
163                         if (callback1 !== "undefined" && callback1 != null) {
164                             callback1(data.Result);
165                         }
166                     } else {
167                         try {
168                             topeveryMessage.show(data.Result.Message);
169                         } catch (e) {
170 
171                         }
172                     }
173                 } else {
174                     error();
175                 }
176             });
177         });
178     },
179     //删除
180     delData: function (options, callback) {
181         options = $.extend({}, { id: "delete", grid: "grid" }, options || {});
182         var urlstring = $("#" + options.id).attr("url");
183         ///删除url
184         if (options.url == null) {
185             options.url = urlstring;
186         }
187         var arrRows = $('#' + options.grid).datagrid('getSelections');
188         if (arrRows.length === 0) {
189             $.messager.alert('提示', '请选择一条需要删除的记录!', 'info');
190         } else {
191             var ids = [];
192             $.each(arrRows, function () {
193                 ids.push(this.Id);
194             });
195             easyuiBase.ajax({
196                 type: "post",
197                 url: options.url,
198                 data: JSON.stringify({ "Ids": ids.join() }),
199                 contentType: "application/json",
200                 loading: false
201             }, function (data) {
202                 if (data.Success) {
203                     if (data.Result.IsSuccess) {
204                         try {
205                             $("#" + options.grid).datagrid('reload');
206                         } catch (e) {
207 
208                         }
209                         callback();
210                         topeveryMessage.show(data.Result.Message);
211                     } else {
212                         try {
213                             topeveryMessage.show(data.Result.Message);
214                         } catch (e) {
215 
216                         }
217                     }
218                 } else {
219                     error();
220                 }
221             }, true);
222         }
223     },
224     ///搜索
225     loadInfo: function (options) {
226         options = $.extend({}, { grid: "grid" }, options || {});
227         $('#' + options.grid).datagrid('load'); //点击搜索
228     },
229     //清空
230     empty: function (options) {
231         options = $.extend({}, { sumbit: "selectFrom", grid: "grid", tree: "tree" }, options || {});
232         $("#" + options.sumbit).form("reset");
233         $("#" + options.grid).datagrid("load");
234         $('#' + options.tree).find('.tree-node-selected').removeClass('tree-node-selected');
235     }
236 });
TopeveryBase
 1 var DirectoryManageList;
 2 var base;
 3 var load;
 4 var defaultDeptId;
 5 var tree;
 6 $(function () {
 7     DirectoryManageList = TopeveryBase.extend({
 8     });
 9     load = function (row) {
10         $("#LoginPassword1").textbox("setValue", row.LoginPassword);
11     }
12     base = new DirectoryManageList();
13     var columns = [
14         [
15             { field: "Id", checkbox: true },
16             { width: 100, title: '用户名', field: 'Name', align: 'center' },
17             { width: 100, title: '登录名', field: 'LoginName', align: 'center' },
18             { width: 100, title: '电话', field: 'TelNum', align: 'center' },
19             {
20                 width: 100, title: '默认部门', field: 'DefaultDeptName', align: 'center'
21             },
22             { width: 100, title: '邮件', field: 'Email', align: 'center' },
23             { width: 80, title: '手机', field: 'MobileNum', align: 'center' },
24             {
25                 title: '操作',
26                 field: 'Action',
27                 width: '15%',
28                 align: 'center',
29                 formatter: function (value, row, index) {
30                     var c = ' <a href="#"   class="easyui-modifyoperate"  onclick="base.View(' + row.Id + ',load)">修改</a>';
31                     var d = ' <a href="#"   class="easyui-modifyoperate"  onclick="base.View(' + row.Id + ',load)">部门角色权限</a>';
32                     return c + "&nbsp"+d;
33                 }
34             }
35         ]
36     ];
37     base.initGrid({ columns: columns });
38     $('#DefaultDeptId').combotree({
39         url: "/Dept/GetDeptList",
40         panelHeight: 'auto',
41         panelMaxHeight: 150,
42         loadFilter: function (data) {
43             var object = new Array;
44             object.push({ id: 0, text: " ", children: data, state: "0", attributes: "" });
45             return object;
46         }
47     }),
48     $('#tree').tree({
49         url: "/Dept/GetDeptList",
50         loadFilter: function (data) {
51             var object = new Array;
52             object.push({ id: 0, text: "部门树", children: data, state: "0", attributes: "" });
53             return object;
54         },
55         onClick: function (node) { //单击事件  
56             defaultDeptId = node.id;
57             $("#defaultDeptId").val(defaultDeptId);
58             base.loadInfo();
59         }
60     });
61 });
实例Js
@using System.Web.Optimization
<div style="width: 10%; float: left; height: 100%; background-color: #fff;">
    <ul id="tree"></ul>
</div>
<table style="width: 90%!important; float: left;" singleSelect="false" id="grid" url="UserR/GetListAsync"></table>
<div id="toolbarWrap">
    <div class="toolbar-area">
        <div class="searching-area">
            <form name="selectFrom" id="selectFrom">
                <table>
                    <tr>
                        <td>
                            <input class="easyui-textbox" style="width: 120px; height: 30px;" id="Name1" name="Name" data-options="prompt:'用户名'" />
                            <input class="easyui-textbox" style="width: 120px; height: 30px;" id="LoginName1" name="LoginName" data-options="prompt:'登录名'" />
                            <input id="defaultDeptId" name="defaultDeptId" style="display: none;" />
                            <a href="#" class="search-btn easyui-normalyellowbutton" onclick="base.loadInfo();">查询</a>
                            <a href="#" class="search-btn easyui-normalyellowbutton" onclick="base.empty();">清空</a>
                        </td>
                    </tr>
                </table>
            </form>
        </div>
    </div>
    <div id="toolbar" class="toolbar operate-area-new">
        <a href="#" onclick="base.View();" class="easyui-normalbluebutton">新增用户</a>
        <a href="#" onclick="base.delData();" class="easyui-normalbluebutton">删除用户</a>
        <input type="hidden" id="edit" name="NewModifView" url="UserW/UserAddEditAsync,UserR/GetOneAsync">
        <input type="hidden" id="add" name="NewModifView" url="UserW/UserAddEditAsync">
        <input type="hidden" id="delete" url="UserW/DeleteUserAsync">
    </div>
</div>
<div class="easyui-dialog" title="新增" data-options="iconCls:'pag-list',modal:true,collapsible:false,minimizable:false,maximizable:false,resizable:false,closed:true" id="NewModifView" style="width: 700px; height: 380px;  display: none;">
    <form id="sumbitForm" name="sumbitForm">
        <div class="house-lost-register-form">
            <input id="Id" name="Id" style="display: none;" />
            <p>
                <label>用户名:</label>
                <input type="text" class="easyui-textbox" maxlength="20" style="width: 215px; height: 30px;" id="Name" name="Name" required="required" missingMessage="用户名不能为空" />
                <label>登录名:</label>
                <input type="text" class="easyui-textbox" style="width: 215px; height: 30px;" id="LoginName" name="LoginName" required="required" missingMessage="登录名不能为空" />
            </p>
            <p>
                <label>登录密码:</label>
                <input type="text" class="easyui-textbox" style="width: 215px; height: 30px;" id="LoginPassword" name="LoginPassword" required="required" missingMessage="登录密码不能为空" />
                <label>重复登录密码:</label>
                <input type="text" class="easyui-textbox" style="width: 215px; height: 30px;" id="LoginPassword1" name="LoginPassword1" required="required" missingMessage="重复登录密码不能为空" validType="equalTo['#LoginPassword']" invalidMessage="两次输入密码不匹配" />
            </p>
            <p>
                <label>默认部门:</label>
                <input type="text" class="easyui-combotree" style="width: 215px; height: 30px;" id="DefaultDeptId" name="DefaultDeptId" />
                <label>电话:</label>
                <input type="text" class="easyui-textbox" style="width: 215px; height: 30px;" id="TelNum" name="TelNum" />
            </p>
            <p>
                <label>邮件:</label>
                <input type="text" class="easyui-textbox" style="width: 215px; height: 30px;" id="Email" name="Email" />
                <label>手机:</label>
                <input type="text" class="easyui-textbox" style="width: 215px; height: 30px;" id="MobileNum" name="MobileNum" />
            </p>
            <div style="padding-top: 20px; text-align: center;" id="ToView">
                <a href="#" class="easyui-normalbluebutton" id="save">确认</a>
            </div>
        </div>
    </form>
</div>

@Scripts.Render("~/js/User/IndexTest.js")
View

如果是简单的增删改查,就能够通过简单的一个页面就可以完成了。

 /// <summary>
        /// 去掉集合2中Id集合2中的数据
        /// </summary>
        /// <typeparam name="TF"></typeparam>
        /// <returns></returns>
        public IQueryable<TF> NotShorthand<TF>(List<IdInput> list, IRepository<TF> iRepository) where TF : class, IEntity<int> 
        {
            var idlist = new int[list.Count];
            for (var i = 0; i < list.Count; i++)
            {
                idlist.SetValue(list[i].Id, i);
            }
            var query = from t in iRepository.GetAll()
                        where !(idlist).Contains(t.Id)
                        select t;
            return query;
        }

        /// <summary>
        /// 排序  分页封装
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TF"></typeparam>
        /// <returns></returns>
        public async Task<PagedResultOutputDto<TF>> GetListAsync<T,TF>(IQueryable<T> query,int pageIndex,int pageCount,string sort)
        {
            query = !string.IsNullOrWhiteSpace(sort) ? query.OrderBy(sort) : query.OrderBy("Id desc");
            var count = query.Count();
            query = query.Skip((pageIndex - 1) * pageCount).Take(pageCount);
            var row = await query.ToListAsync();
            var data = row.MapTo<List<TF>>();
            return new PagedResultOutputDto<TF>(count, data);
        }
 /// <summary>
        /// 根据部门Id获取可以调入的人员
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultOutputDto<UserListOutputDto>> GetNotUserAsync(DeptListInput input)
        {
            var query1 = (from userDept in _userDeptRepository.GetAll()
                          join dept in _deptRepository.GetAll() on userDept.DeptId equals dept.Id
                          where userDept.DeptId == input.DeptId
                          select new IdInput { Id = userDept.UserId }).ToList();
            var query = NotShorthand(query1, _userRepository);
            if (!string.IsNullOrWhiteSpace(input.Name))
            {
                query = query.Where(x => x.Name.Contains(input.Name));
            }
            var list = await GetListAsync<Zero.Core.Authorization.User, UserListOutputDto>(query, input.PageIndex, input.PageCount, input.Sorting);
            return list;
        }
View Code

 

4.最后总结是,也许我自己也不知道我的目的是什么,弄这个的意义是什么,但是做自己想做的,想到了就去做吧。

5.发现问题,然后思考问题,最后去解决这个问题!

百度云地址:http://pan.baidu.com/s/1c2cjpLm  提取码:4b66



posted @ 2017-04-04 21:28  小吴的成长之路  阅读(1999)  评论(8编辑  收藏  举报