web程序快速开发
关于web程序快速开发个人见解以及经历
由于在之前公司业务的发展,需要在基于核心业务的基础上开发其他较为独立的业务系统,所以就有了这个基于Dapper,DDD概念的基础框架,由于个人基于这个框架已经经历过两个系统的开发,也因为其他项目团队需要基于这个框架进行其他系统的一些开发,所以需要对此框架有一些简单介绍和使用说明。
1.主要框架主体介绍
Dapper,DapperExtensions:Dapper框架集成。
Topever.AutoMapper:对象映射扩展,这个项目其实可以集成到公共项目Topevery.Infrastructure项目中。
Topevery.Dapper.Oracle:主要存放实体映射文件、仓储实现类。
Topevery.Infrastructure:框架中跟业务无关的公共类。
Topever.Core:主要存放实体类,仓储接口接口定义,实现对象状态(增删改)
Topevery.Application:应用服务,业务逻辑处理,数据处理
Topevery.Web:web站点,主要采用了webapi提供api接口,mvc模式提供路由以及视图展示。
2.快速开发,自然就需要借助一些代码生成的工具,所以这里使用了同事在之前在弄ABP框架使用的T4模板技术,基于原有的基础代码下,做了一些代码修改,生成相对应的代码逻辑。
因此主要的工作任务的重点就是前台工作的开发,其他一个项目组需要在短时间内开发完成一个系统开发,很荣幸的我被调入到了这个项目组,负责其中两个相对为独立简单的系统开发,10个模块,19张表,大部分的是单表的增删改查,相对复杂一点的主要是其中的两个需要走流程的业务。由于需要在两个星期左右交付这个软件,主要一个人承担这个开发任务,有一个前端配合静态页面处理,又因为客户要求需要第一个星期周末需要发布一个版本的时候,压力其实真的很大,当时自己整理了一下开发思路,第一步,搭建基础框架,把公司之前的基础框架搭建起来,维护其中的人员,角色,权限,菜单配置等基础信息(项目经理搭建了基础数据库),第二步,根据数据库设计word文档建立对应的pd文件,生成数据库实体。第三步,基础上个项目的T4模板项目修改代码,生成其中基础的实体,map映射,仓储接口,仓储实现,业务简单逻辑代码,输入输出DTO类。第四步,集成其他项目中使用到的一些扩展控件,比如文件上传,附件展示...。第五步,就可以正式的开始模块开发了。
简单介绍一些前端开发的一些东西吧,由于需要给负责前端开发的同事介绍这个东西,所以这里讲一下mvc以及webapi
ApiControllers:webapi提供,主要抛出接口给前端调用,这里主要引用Topever.Application项目中定义的服务
App_Start:webapi,MVC,路由配置,以及其他的一些配置存放
Controller:控制器,是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
Views:展示页面的存放。
前端主要使用了bootstrap,layer框架,使用局部视图展示,减少子页面加载的一些公用的东西(子页面加载使用的方法是通过ajax请求页面,返回html然后展示到页面)
1
2
3
4
5
6
7
8
9
10
11
12
13
|
$.fn.bindAddBtn = function (url, width, height, title) { $( this ).on( "click" , function () { $.topevery.ajax({ type: "get" , url: url, dataType: "html" }, function (data) { layer.open({ type: 1, title: title || "新增" , skin: 'layui-layer-rim' , //加上边框 area: [width + 'px' , height + 'px' ], //宽高 content: data }); }, true ); }); } |
主要封装了增删改查这几个基本操作的按钮代码,减少前端js代码的编写。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
( function ($) { /** * 设置jgrid的样式 */ $.jgrid.defaults.styleUI = "Bootstrap" ; $.fn.jgridInit = function (options) { $.fn.jgridInit.defaults = { datatype: "json" , mtype: "POST" , shrinkToFit: true , postData: options.postData, autowidth: true , height: options.height == null ? "100%" : options.height, rowNum: options.rowNum ? options.rowNum : 10, rowList: [10, 20, 50, 100], viewrecords: true , rownumbers: true , repeatitems: false , jsonReader: { root: function (obj) { return obj.result.rows; }, page: function (obj) { return obj.result.page; }, total: function (obj) { return obj.result.total; }, records: function (obj) { return obj.result.records; }, repeatitems: false }, sortname: options.sortname ? options.sortname : 'C_CREATE_TIME' , sortorder: 'desc' , pager: '#pager' , pginput: true , pgbuttons: true , gridComplete: function () { //$(this).setGridHeight($(".content-wrapper").outerHeight(true) - $(".nav-header").outerHeight(true) - 3 - $(".content-header").outerHeight(true) - 31 - 36 - 28 - 20); var header = $( ".content-wrapper" ).outerHeight( true ) - $( ".nav-header" ).outerHeight( true ) - 3 - $( ".content-header" ).outerHeight( true ) - $( this ).parent().parent().prev().find( ".ui-jqgrid-hbox" ).outerHeight( true ) - 31 - 28 - 20; //var header2 = $(".content-wrapper").outerHeight(true) //内容高度 // - $(".nav-header").outerHeight(true) //导航栏 // - $(".nav-header").parent().next().outerHeight(true) //导航栏和内容之间的分隔符 // - $(".content-header").outerHeight(true) //内容的头部搜索栏 // - $("div.ui-jqgrid-hbox").outerHeight(true) //grid的头 // - $("footer").outerHeight(true) // - $("#pager").outerHeight(true)-18; $( this ).setGridHeight(header); } }; var array = $.extend({}, $.fn.jgridInit.defaults, options); $( this ).jqGrid(array); } /** * 绑定添加按钮 * @param {} url * @param {} width * @param {} height * @param {} title * @returns {} */ $.fn.bindAddBtn = function (url, width, height, title) { $( this ).on( "click" , function () { $.topevery.ajax({ type: "get" , url: url, dataType: "html" }, function (data) { layer.open({ type: 1, title: title || "新增" , skin: 'layui-layer-rim' , //加上边框 area: [width + 'px' , height + 'px' ], //宽高 content: data }); }, true ); }); } /** * 绑定编辑 * @param {} url * @param {} obj * @param {} width * @param {} height * @param {} title * @returns {} */ $.fn.bindEditBtn = function (url, obj, width, height, title, extension) { $( this ).on( "click" , function () { var rowIndex = $(obj).jqGrid( 'getGridParam' , 'selrow' ); if (rowIndex != null ) { var rowData = $(obj).jqGrid( 'getRowData' , rowIndex); var extensionUrl = "" ; if (extension) { extensionUrl = extension; } /*layer弹出一个html页面或者html片段*/ $.topevery.ajax({ type: "get" , url: url + "?Id=" + rowData.id + extensionUrl, dataType: "html" }, function (data) { layer.open({ type: 1, title: title || "修改" , skin: 'layui-layer-rim' , //加上边框 area: [width + 'px' , height + 'px' ], //宽高 content: data }); }, true ); } else { layer.alert( "请选择一条记录!" ); } }); }, /** * 删除事件 * @param {} url * @param {} obj * @returns {} */ $.fn.bindDelBtn = function (url, obj) { $( this ).on( "click" , function () { var rowIndex = $(obj).jqGrid( 'getGridParam' , 'selrow' ); if (rowIndex) { var rowData = $(obj).jqGrid( 'getRowData' , rowIndex); $.topevery.ajax({ url: url, data: JSON.stringify({ "Id" : rowData.id }) }, function (data) { var message = "删除失败" ; if (data.success) { if (data.result.success) { $(obj).trigger( "reloadGrid" ); } message = data.result.message; } layer.msg(message, { icon: 1, title: false , //不显示标题 offset: 'rb' , time: 3000, //10秒后自动关闭 anim: 2 }); }); } else { layer.alert( "请选择一条记录!" ); } }); } /** * 绑定验证属性以及提交按钮 * @param {} options * @returns {} */ $.fn.bootstrapValidatorAndSumbit = function (url, options, validateForm) { if (validateForm == undefined) { validateForm = function () { return true ; }; } $( this ).bootstrapValidator({ message: '输入的值无效' , feedbackIcons: { valid: 'glyphicon glyphicon-ok' , invalid: 'glyphicon glyphicon-remove' , validating: 'glyphicon glyphicon-refresh' }, fields: options }).on( 'success.form.bv' , function (e) { e.preventDefault(); var $form = $(e.target); var bv = $form.data( 'bootstrapValidator' ); if (validateForm() && bv.isValid()) { $.topevery.ajax({ url: url, data: JSON.stringify($.topevery.serializeObject($form)) }, function (data) { var message = "新增失败" ; if (data.success) { if (data.result.success) { $( ".layui-layer-close" ).click(); $( '.query_btn' ).click(); } message = data.result.message; } layer.msg(message, { icon: 1, title: false , //不显示标题 offset: 'rb' , time: 3000, //10秒后自动关闭 anim: 2 }); } ); } }); }, } })(jQuery); |
页面js代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
$( function () { var getPostDataUrl = "" ; var deleteUrl = "" ; var addUrl = "" ; var grid = $( "#tblData" ); grid.jgridInit({ url: getPostDataUrl, colNames: [], //列头 colModel: [ ], postData: { } //查询参数 }); $( ".add_btn" ).bindAddBtn(addUrl, 600, 650); $( ".edit_btn" ).bindEditBtn(addUrl, grid, 600, 650); $( ".del_btn" ).bindDelBtn(deleteUrl, grid); $( ".query_btn" ).on( "click" , function () { $( "#tblData" ).jqGrid( 'setGridParam' , { url: getPostDataUrl, page: 1, postData: { } }).trigger( "reloadGrid" ); }); }); |
页面html代码
<div class="col-xs-12">
<div class="box-header nav-header">
</div>
</div>
<div class="col-xs-12" style=" height: 3px;"></div>
<div class="col-xs-12 ">
<!-- 工具栏 -->
<div class="content-header form-inline row">
<div class="form-group">
<input class="btn btn-success add_btn" type="button" value="上报">
<input class="btn btn-info edit_btn" type="button" value="修改">
<input class="btn btn-danger del_btn" type="button" value="删除">
<input class="btn btn-danger del_btn" type="button" value="导出">
</div>
<div class="form-group">
<input class="btn btn-success query_btn" type="button" value="查询">
</div>
</div>
<div class="box-body row">
<table id="tblData"></table>
<div id="pager"></div>
</div>
</div>
<script src="~/Views/BudgetManagement/EmergencyIndex.js"></script>
附一个页面效果
总结:这次开发经历,算是对自己的一个挑战。我乐于接受这种挑战。只是下一次挑战面前,自己更加从容一些,事情做得更加规范一些。
web程序快速开发的更多相关文章
- 关于web程序快速开发个人见解以及经历
由于在之前公司业务的发展,需要在基于核心业务的基础上开发其他较为独立的业务系统,所以就有了这个基于Dapper,DDD概念的基础框架,由于个人基于这个框架已经经历过两个系统的开发,也因为其他项目团队需 ...
- 微信小程序快速开发
微信小程序快速开发 一.注册小程序账号,下载IDE 1.官网注册https://mp.weixin.qq.com/,并下载IDE. 2.官方文档一向都是最好的学习资料. 注意:1)注册账号之后会有一个 ...
- Topshelf+Quartz3.0基于控制台应用程序快速开发可调度windows服务
1.TopShelf TopShelf是一个开源的跨平台的宿主服务框架.可通过.Net Core/.Net Framwork控制台应用程序快速开发windows服务,更加便于服务调试. 本文基于.Ne ...
- Web程序员开发App系列 - 开发我的第一个App,源码下载
Web程序员开发App系列 Web程序员开发App系列 - 认识HBuilder Web程序员开发App系列 - 申请苹果开发者账号 Web程序员开发App系列 - 调试Android和iOS手机代码 ...
- Web程序员开发App系列 - 调试Android和IOS手机代码(补图)
Web程序员开发App系列 Web程序员开发App系列 - 认识HBuilder Web程序员开发App系列 - 申请苹果开发者账号 Web程序员开发App系列 - 调试Android和iOS手机代码 ...
- Web程序员开发App系列 - 申请苹果开发者账号
Web程序员开发App系列 Web程序员开发App系列 - 认识HBuilder Web程序员开发App系列 - 申请苹果开发者账号 Web程序员开发App系列 - 调试Android和iOS手机代码 ...
- Web程序员开发App系列 - 认识HBuilder
Web程序员开发App系列 Web程序员开发App系列 - 认识HBuilder Web程序员开发App系列 - 申请苹果开发者账号 Web程序员开发App系列 - 调试Android和iOS手机代码 ...
- 微信小程序快速开发上手
微信小程序快速开发上手 介绍: 从实战开发角度,完整系统地介绍了小程序的开发环境.小程序的结构.小程序的组件与小程序的API,并提供了多个开发实例帮助读者快速掌握小程序的开发技能,并能自己动手开发出小 ...
- vue+uni-app商城实战 | 第一篇:【有来小店】微信小程序快速开发接入Spring Cloud OAuth2认证中心完成授权登录
一. 前言 本篇通过实战来讲述如何使用uni-app快速进行商城微信小程序的开发以及小程序如何接入后台Spring Cloud微服务. 有来商城 youlai-mall 项目是一套全栈商城系统,技术栈 ...
随机推荐
- 认清Android框架 MVC,MVP和MVVM
编者按:现在很多时候,我们都是面向搜索(或 Google 或百度).GitHub 编程,那么,在早期没有互联网的情况下,该如何学习编程,成为一名真正的开发者?亦或是作为一名小白,如何进入互联网编程时代 ...
- BZOJ3193 [JLOI2013]地形生成 【dp】
题目链接 BZOJ3193 题解 注意\(key\)是小于 第一问,显然按高度降序排序,逐个插入 如果高度各不相同,那么之前插入的都比当前插入的\(i\)大,可插入的位置个数就确定了 由于存在高度相同 ...
- 分库分表中间件sharding-jdbc的使用
数据分片产生的背景,可以查看https://shardingsphere.apache.org/document/current/cn/features/sharding/,包括了垂直拆分和水平拆分的 ...
- BZOJ 1031 [JSOI2007]字符加密Cipher 后缀数组教程
1031: [JSOI2007]字符加密Cipher Description 喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一 ...
- (转)JDK工具-javadoc命令
背景:最近在学习java基础知识,看到文档注释部分,一种是在dos命令下生成api文件,另一种是在eclipse下生成api文件.dos方式在<疯狂java讲义>中有详细的说明,eclip ...
- ASP.NET MVC验证框架中关于属性标记的通用扩展方法
http://www.cnblogs.com/wlb/archive/2009/12/01/1614209.html 之前写过一篇文章<ASP.NET MVC中的验证>,唯一的遗憾就是在使 ...
- linux command ------ dmesg
驱动开发中使用函数 printk() 打印的信息可以通过 dmesg 查看 简介 ‘dmesg’命令显示linux内核的环形缓冲区信息,我们可以从中获得诸如系统架构.cpu.挂载的硬件,RAM等多个运 ...
- (转)flask的context机制
本文转自:https://blog.tonyseek.com/post/the-context-mechanism-of-flask/ 作者:无知的 TonySeek 注意:本文仅仅作为个人mark, ...
- Hadoop生态圈-Flume的主流source源配置
Hadoop生态圈-Flume的主流source源配置 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客只是配置的是Flume主流的Source,想要了解更详细的配置信息请参 ...
- RAC手动中断订阅
__block RACDisposable* dispose = [[RACObserve(self, price) skip:1]subscribeNext:^(NSNumber* x) { [di ...