關於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然後展示到頁面)
$.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代碼的編寫。
(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代碼
$(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="background-color: #000000; 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程序快速開發個人見解以及經歷