關於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>
附一個頁面效果
總結:這次開發經歷,算是對自己的一個挑戰。我樂於接受這種挑戰。只是下一次挑戰面前,自己更加從容一些,事情做得更加規范一些。