1. 程式人生 > >使用Jquery+EasyUI 進行框架專案開發案例講解之四--組織機構管理原始碼分享

使用Jquery+EasyUI 進行框架專案開發案例講解之四--組織機構管理原始碼分享

使用Jquery+EasyUI 進行框架專案開發案例講解之四

組織機構管理原始碼分享 

 在上三篇文章

  我們分享了使用Jquery EasyUI來進行ASP.NET專案的開發的相關方法,每一個模組都有其共用性,細細理解與掌握,我相信使用EasyUI進行開發還是相當方便的。

  接下來我分享“組織機構管理”模組主要的核心程式碼組織機構管理使用的EasyUI控制元件,主要是EasyUI的TreeGrid控制元件,組織機構管理主介面如下圖所示:

  

 在進行程式碼講解之前,我們先來回顧一個TreeGrid相關的知識。easyUI TreeGrid 從$.fn.datagrid.defaults繼承,覆蓋預設值$.fn.treegrid.defaults。treegrid 是使用顯示分層資料在grid中,treegrid 是基於datagrid和關聯treeview 和關聯可編輯的grid,treegrid 允許你建立定製的,非同步載入展開行資料,和顯示分層的資料在多列中。如下圖所示:

  使用示例

  通過html標記建立treegrid ,大多數情況下treegrid 遵循相同的結構格式化為datagrid
<table id="tt" class="easyui-treegrid" style="width:600px;height:400px"  
        data-options="url:'get_data.aspx',idField:'id',treeField:'name'">  
    <thead>  
        <tr>  
            <th data-options="field:'name',width:180">Task Name</th>  
            <th data-options="field:'persons',width:60,align:'right'">Persons</th>  
            <th data-options="field:'begin',width:80">Begin Date</th>  
            <th data-options="field:'end',width:80">End Date</th>  
        </tr>  
    </thead>  
</table> 

使用javascript建立treegrid 

<table id="tt" style="width:600px;height:400px"></table>  
$('#tt').treegrid({  
    url:'get_data.aspx',  
    idField:'id',  
    treeField:'name',  
    columns:[[  
        {title:'Task Name',field:'name',width:180},  
        {field:'persons',title:'Persons',width:60,align:'right'},  
        {field:'begin',title:'Begin Date',width:80},  
        {field:'end',title:'End Date',width:80}  
    ]]  
}); 

屬性

  屬性從 datagrid繼承,以下是treegrid新增的屬性.

NameTypeDescriptionDefault
idFieldstring定義鍵欄位標識一個tree節點,該項是必須的.null
treeFieldstring定義tree節點欄位,該項是必須的.null
animateboolean定義當節點展開/關閉的時候,是否顯示動畫效果.false
loaderfunction(param,success,error)定義如何從遠端伺服器端載入資料. 返回false將終止這個動作. 這個函式提供一下引數 :
param: 傳遞給遠端伺服器的引數物件.
success(data): 當檢索資料成功之後執行的回撥函式.
error(): 當檢索資料失敗的時候呼叫的回撥函式.
json loader
loadFilterfunction(data,parentId)返回過濾後的顯示資料.

  事件

  事件從datagrid繼承, 以下是datagrid新增事件.

NameParametersDescription
onClickRowrow當用戶點選一個節點時觸發.
onDblClickRowrow當用戶雙擊一個節點時觸發.
onClickCellfield,row當用戶點選一個表格的時觸發.
onDblClickCellfield,row當用戶雙擊一個表格的時觸發.
onBeforeLoadrow, param一個請求去載入資料之前觸發, 返回false將取消載入動作.
onLoadSuccessrow, data資料載入成功之後觸發.
onLoadErrorarguments資料載入失敗之後觸發,arguments 引數和jQuery.ajax的error函式一樣.
onBeforeExpandrow節點展開之前觸發,返回false將取消展開動作.
onExpandrow節點展開後觸發.
onBeforeCollapserow節點摺疊之前觸發,返回false取消折疊動作.
onCollapserow節點摺疊後觸發.
onContextMenue, row在節點上右鍵點選觸發.
onBeforeEditrow使用者開始編輯一個節點時觸發.
onAfterEditrow,changes使用者結束編輯節點時觸發.
onCancelEditrow使用者取消編輯節點時觸發.

   方法

  許多方法提供一個引數,引數名為id, 這個引數指明tree節點值.

NameParameterDescription
optionsnone返回treegrid的 options物件.
resizeoptions設定treegrid 大小,options包含兩個屬性:
width: treegrid新的寬度.
height: treegrid新的高度.
fixRowHeightid固定特定行高度.
loadDatadata載入 treegrid 資料.
reloadid重新載入treegrid 資料.如果傳遞了id引數, 重新載入特定的tree行, 其他的重新載入所有tree行.

示例程式碼:

$('#tt').treegrid('reload', 2);	// 重新載入指定id值是2的行
$('#tt').treegrid('reload');	// 重新載入所有行
reloadFooterfooter重新載入頁尾資料.
getDatanone得到載入資料.
getFooterRowsnone得到頁尾資料.
getRootnone得到根節點, 返回的是節點物件
getRootsnone得到根節點, 返回的是節點陣列.
getParentid得到父節點.
getChildrenid得到子節點.
getSelectednone得到選中節點並返回它, 如果沒有選中節點返回null.
getSelectionsnone得到所有的選中節點.
getLevelid得到特定的節點的層級.
findid查詢特定的節點和返回節點資料.
selectid選中一個節點.
unselectid取消選中一個節點.
selectAllnone選中所有節點.
unselectAllnone取消選中所有節點.
collapseid摺疊一個節點.
expandid展開一個節點.
collapseAllid摺疊所有節點.
expandAllid展開所有節點.
expandToid展開從根節點到指定的節點.
toggleid切換節點的 expanded(展開)/collapsed (關閉)狀態.
appendparam附加一個節點到父節點. 'param' 引數包含以下屬性:
parent:父節點id , 如果沒有分配, 附加作為根節點.
data: 陣列, 節點資料.
示例程式碼:
// 新增一些節點到選中節點
var node = $('#tt').treegrid('getSelected');
$('#tt').treegrid('append',{
	parent: node.id,  // 節點有一個'id'值,定義是通過'idField'屬性
	data: [{
		id: '073',
		name: 'name73'
	}]
});
removeid移除一個節點和其子節點.
refreshid重新整理特定的節點.
beginEditid開始編輯一個節點.
endEditid結束編輯一個節點.
cancelEditid取消編輯一個節點.
getEditorsid得到特定行編輯器.每一個編輯器都有以下屬性:
actions:編輯器可以做的動作.
target: 目標編輯器jQuery物件.
field:欄位名.
type:編輯器型別.
getEditoroptions得到特定的編輯器, options 包含兩個屬性:
id:行節點id.
field: 欄位名.

以上知識對於充分理解並應用TreeGrid非常的重要,對於不明白的童鞋可以看下!下面分享如何使用EasyUI的TreeGrid控制元件進行我們的組織機構管理的開發,當然還涉及到其他的知識點,在前面的文章已有介紹,不明白的可以看下前面的文章,這兒重在說明一些方法,當然大家也可交流討論,提出你們在開發過程中使用的常用方式方法。

  一、“組織機構管理”主介面UI的ASPX程式碼如下:

<%@ Page Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="OrganizeAdmin.aspx.cs" Inherits="RDIFramework.WebApp.Modules.OrganizeAdmin" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">      
     <div id="toolbar">
        <%=base.BuildToolBarButtons()%>
    </div>
    <table id="organizeGrid"></table> 
    <script type="text/javascript" src="../Scripts/Business/OrganizeAdmin.js?v=5"></script>   

</asp:Content>

  可以看到,程式碼非常的簡潔,使用EasyUI開發的好處就在於此,不需要你拖動服務端的控制元件等這種常規的Asp.NET開發方式,對於這種開發方式的好處不言而喻。

  綁定當前登入使用者所擁有的功能按鈕列表程式碼如下: 

 /// <summary>
        /// 獲得頁面的許可權
        /// </summary>
        private void GetPermission()
        {
            this.permissionAdd = this.IsAuthorized("OrganizeManagement.Add");
            this.permissionEdit = this.IsAuthorized("OrganizeManagement.Edit");
            this.permissionMove = this.IsAuthorized("OrganizeManagement.Move");
            this.permissionDelete = this.IsAuthorized("OrganizeManagement.Delete");
            this.permissionExport = this.IsAuthorized("OrganizeManagement.Export");
            //this.permissionAccredit = this.IsAuthorized("UserManagement.Accredit");
            this.permissionUserOrganizePermission = this.IsAuthorized("OrganizeManagement.UserOrganizePermission");
            this.permissionRolerOrganizePermission = this.IsAuthorized("OrganizeManagement.RolerOrganizePermission");
        }

        /// <summary>
        /// 載入工具欄
        /// </summary>
        /// <returns>工具欄HTML</returns>
        public override string BuildToolBarButtons()
        {
            StringBuilder sb = new StringBuilder();
            string linkbtn_template = "<a id=\"btn{0}\" class=\"easyui-linkbutton\" style=\"float:left\"  plain=\"true\" href=\"javascript:;\" icon=\"{1}\"  {2} title=\"{3}\">{4}</a>";
            sb.Append("<a id=\"a_refresh\" class=\"easyui-linkbutton\" style=\"float:left\"  plain=\"true\" href=\"javascript:;\" icon=\"icon-reload\"  title=\"重新載入\">重新整理</a> ");
            sb.Append("<div class='datagrid-btn-separator'></div> ");
            sb.Append(string.Format(linkbtn_template, "Add", "icon-add", permissionAdd ? "" : "disabled=\"True\"", "新增組織機構", "新增"));
            sb.Append(string.Format(linkbtn_template, "Edit", "icon-edit", permissionEdit ? "" : "disabled=\"True\"", "修改選中的組織機構", "修改"));                      
            sb.Append(string.Format(linkbtn_template, "Delete", "icon-delete0", permissionDelete ? "" : "disabled=\"True\"", "刪除選中組織機構", "刪除"));
            sb.Append("<div class='datagrid-btn-separator'></div> ");
            sb.Append(string.Format(linkbtn_template, "MoveTo", "icon-shape_move_forwards", permissionMove ? "" : "disabled=\"True\"", "移動選中的組織機構", "移動"));
            sb.Append(string.Format(linkbtn_template, "Export", "icon-export", permissionExport ? "" : "disabled=\"True\"", "匯出組織機構資料", "匯出"));
            sb.Append("<div class='datagrid-btn-separator'></div> ");
            sb.Append(string.Format(linkbtn_template, "UserOrganizePermission", "icon-layout_key", permissionUserOrganizePermission ? "" : "disabled=\"True\"", "設定使用者組織機構許可權", "使用者組織機構許可權"));
            sb.Append(string.Format(linkbtn_template, "RoleOrganizePermission", "icon-ruby_key", permissionRolerOrganizePermission ? "" : "disabled=\"True\"", "設定角色組織機構許可權", "角色組織機構許可權"));
            return sb.ToString();
        }

 繫結TreeGridJS程式碼如下:

$(function () {
    autoResize({ dataGrid: '#organizeGrid', gridType: 'treegrid', callback: mygrid.bindGrid, height: 5 });
    $('#btnAdd').click(OrganizeAdminMethod.AddOrganize); //新增組織機構
    $('#btnEdit').click(OrganizeAdminMethod.EditOrganize); //修改組織機構
    $('#btnDelete').click(OrganizeAdminMethod.DeleteOrganize); //刪除組織機構
    $('#btnMoveTo').click(OrganizeAdminMethod.MoveTo); //移動組織機構
    $('#btnExport').click(OrganizeAdminMethod.ExportOrganize); //匯出組織機構資料
    $('#btnUserOrganizePermission').click(OrganizeAdminMethod.SetUserOrganizePermission); //設定使用者組織機構許可權
    $('#btnRoleOrganizePermission').click(OrganizeAdminMethod.SetRoleOrganizePermission); //設定角色組織機構許可權
    $('#a_refresh').click(function () { //重新整理
        mygrid.reload();
    });
});

var mygrid = {
    bindGrid: function (winsize) {       
        navgrid = $('#organizeGrid').treegrid({
            toolbar: '#toolbar',
            title: '組織機構列表',
            iconCls: 'icon icon-org',
            width: winsize.width,
            height: winsize.height,            
            nowrap: true,
            rownumbers: true,
            animate: true,
            resizable: true,
            collapsible: false,
            url: actionUrl,
            idField: 'Id',
            treeField: 'FullName',
            frozenColumns: [[
                { title: '組織機構名稱', field: 'FullName', width: 200 },
                { title: '編碼', field: 'Code', width: 100 }
            ]],
            columns: [[
                { title: '簡稱', field: 'ShortName', width: 120 },                      
                { title: '主負責人', field: 'Manager', width: 70, align: 'center' },
                { title: '電話', field: 'OuterPhone', width: 100, align: 'center' },
                { title: '傳真', field: 'Fax', width: 100, align: 'center' },
                { title: '有效', field: 'Enabled', width: 50, align: 'center', formatter: imgcheckbox },
                { title: '排序', field: 'SortCode', width: 80, align: 'center' },
                { title: '備註', field: 'Description', width: 300 },
                { title: 'ParentId', field: 'ParentId', hidden: true },
                { title: 'Category', field: 'Category', hidden: true },
                { title: 'InnerPhone', field: 'InnerPhone', hidden: true },
                { title: 'Postalcode', field: 'Postalcode', hidden: true },
                { title: 'Address', field: 'Address', hidden: true },
                { title: 'Web', field: 'Web', hidden: true },
                { title: 'AssistantManager', field: 'AssistantManager', hidden: true },
                { title: 'IsInnerOrganize', field: 'IsInnerOrganize', hidden: true }
            ]]
        });
    },
    reload: function () {
        navgrid.treegrid('reload');
    },
    selected: function () {
        return navgrid.treegrid('getSelected');
    }
}

var imgcheckbox = function (cellvalue, options, rowObject) {
    return cellvalue ? '<img src="/css/icon/ok.png" alt="正常" title="正常" />' : '<img src="/css/icon/stop.png" alt="禁用" title="禁用" />';
}

新增組織機構介面視窗如下:

  

  在新增組織機構介面,主負責人,副主管資料域的繫結控制元件使用的是“ComboGrid"控制元件,繫結的程式碼如下:

bindComboGrid: function () {
        top.$('#txt_Manager,#txt_AssistantManager').combogrid({
            panelWidth: 320,
            idField: 'Id',
            textField: 'RealName',
            url: 'Modules/handler/UserAdminHandler.ashx?action=GetUserListByPage',
            sortName: 'SortCode',
            sortOrder: 'asc',
            fitColumns: true,
            showPageList: false,
            striped: true,
            pagination: true,
            rownumbers: true,
            fitColumns: true,
            pageSize: 10,
            pageList: [10, 20, 30, 50],
            method: 'post',
            columns: [[
                { title: '登入名', field: 'UserName', width: 60, sortable: true },
                { title: '使用者名稱', field: 'RealName', width: 70 }
            ]]
        });

修改組織機構介面如下: 

  

  ”修改組織機構“程式碼如下: 

EditOrganize: function () { //修改組織機構
        if ($(this).linkbutton('options').disabled == true) {
            return;
        }
        //功能程式碼邏輯...
        var row = mygrid.selected();
        if (row) {
            var editDailog = top.$.hDialog({
                href: formUrl, title: '修改組織機構', iconCls: 'icon-edit', width: 750, height: 520,
                onLoad: function () {
                    pubMethod.bindCtrl(row.Id);
                    pubMethod.bindCategory();
                    pubMethod.bindComboGrid();
                    top.$('#txt_Code').val(row.Code);
                    top.$('#txt_FullName').val(row.FullName);
                    top.$('#txt_ShortName').val(row.ShortName);
                    top.$('#txt_ParentId').combotree('setValue', row.ParentId);
                    top.$('#txt_Category').combobox('setValue', row.Category);
                    top.$('#txt_Manager').combogrid('setValue', row.Manager);
                    top.$('#txt_AssistantManager').combogrid('setValue', row.AssistantManager);
                    top.$('#txt_OuterPhone').val(row.OuterPhone);
                    top.$('#txt_InnerPhone').val(row.InnerPhone);
                    top.$('#txt_Fax').val(row.Fax);
                    top.$('#txt_Postalcode').val(row.Postalcode);
                    top.$('#txt_Web').val(row.Web);
                    top.$('#txt_Address').val(row.Address);
                    top.$('#chk_Enabled').attr('checked', row.Enabled == "1");
                    top.$('#chk_IsInnerOrganize').attr('checked', row.IsInnerOrganize == "1");
                    top.$('#txt_Description').val(row.Description);
                },
                submit: function () {
                    if (top.$('#uiform').validate().form()) {
                        
                        //儲存時判斷當前節點所選的父節點,不能為當前節點的子節點,這樣就亂套了....
                        var treeParentId = top.$('#txt_ParentId').combotree('tree'); // 得到樹物件
                        var node = treeParentId.tree('getSelected');
                        if (node) {                            
                            var nodeParentId = treeParentId.tree('find', row.Id);
                            var children = treeParentId.tree('getChildren', nodeParentId.target);
                            var nodeIds = '';
                            var isFind = 'false';
                            for (var index = 0; index < children.length; index++) {
                                if (children[index].id == node.id) {
                                    isFind = 'true';
                                    break;
                                }
                            }

                            if (isFind == 'true') {
                                top.$.messager.alert('溫馨提示', '請選擇父節點元素!', 'warning');
                                return;
                            }
                        }


                        var vparentid = top.$('#txt_ParentId').combobox('getValue');
                        var vcategory = top.$('#txt_Category').combobox('getValue');
                        var vmanager = top.$('#txt_Manager').combogrid('getText');
                        var vassistantmanager = top.$('#txt_AssistantManager').combogrid('getText');
                        var query = 'action=EditOrganize&vparentid=' + vparentid + '&vcategory=' + vcategory + '&KeyId=' + row.Id + '&vmanager=' + vmanager + '&vassistantmanager=' + vassistantmanager + '&'
                                  + top.$('#uiform').serialize();
                        $.ajaxjson(actionUrl, query, function (d) {
                            if (d.Success) {
                                msg.ok(d.Message);
                                editDailog.dialog('close');
                                mygrid.reload();
                            } else {
                                MessageOrRedirect(d);
                            }
                        });
                    }
                }
            });


        } else {
            msg.warning('請選擇要修改的組織機構!');
            return false;
        }
        return false;
    }

刪除組織機構程式碼如下:  

DeleteOrganize: function () { //刪除組織機構
        if ($(this).linkbutton('options').disabled == true) {
            return;
        }
        //功能程式碼邏輯...
        var row = mygrid.selected();
        if (row != null) {
            var childs = $('#organizeGrid').treegrid('getChildren', row.Id);
            if (childs.length > 0) {
                $.messager.alert('警告提示', '當前所選有子節點資料,不能刪除。', 'warning');
                return false;
            }
            var query = 'action=DeleteOrganize&KeyId=' + row.Id;
            $.messager.confirm('詢問提示', '確認要刪除選中的組織機構嗎?', function (data) {
                if (data) {
                    $.ajaxjson(actionUrl, query, function (d) {
                        if (d.Success) {
                            msg.ok(d.Message);
                            mygrid.reload();
                        } else {
                            MessageOrRedirect(d);
                        }
                    });
                }
                else {
                    return false;
                }
            });
        }
        else {
            msg.warning('請選擇要刪除的組織機構!');
            return false;
        }
        return false;
    }

“使用者-組織機構許可權設定”功能主要用於設定特定使用者可以訪問的組織機構。有時我們會有這樣的應用,某些資料屬於某個組織機構內部的資料,只能指定其他組織機構特定的使用者訪問,那麼通過此設定,我們就可以輕鬆的控制特定的使用者訪問指定的組織機構,“使用者-組織機構許可權設定”如下圖所示。

  

  在上圖中,我們可以看到對使用者“陳俊熙”設定了他可以訪問的組織機構,我們現在以他的使用者“wikstone”登入系統,可以看到當前使用者只能看到對應的組織機構了,如下圖所示:

  

  使用者-組織機構許可權設定程式碼如下:

SetUserOrganizePermission: function () { //設定使用者組織機構許可權
        if ($(this).linkbutton('options').disabled == true) {
            return;
        }
        //功能程式碼邏輯...
        var userGrid;
        var curResourceTargetResourceIds = [];
        var setDialog = top.$.hDialog({
            title: '(使用者-組織機構)許可權設定',
            width: 670, height: 600, iconCls: 'icon-layout_key', //cache: false,
            href: "Modules/html/PermissionBacthSetForm.htm?n=" + Math.random(),
            onLoad: function () {
                using('panel', function () {
                    top.$('#panelTarget').panel({ title: '組織機構列表', iconCls: 'icon-org', height: $(window).height() - 3 });
                });

                userGrid = top.$('#leftnav').datagrid({
                    title: '使用者列表',
                    url: 'Modules/handler/UserAdminHandler.ashx',
                    nowrap: false, //折行
                    //fit: true,
                    rownumbers: true, //行號
                    striped: true, //隔行變色
                    idField: 'Id', //主鍵
                    singleSelect: true, //單選
                    frozenColumns: [[]],
                    columns: [[
                        { title: '登入名', field: 'UserName', width: 120, align: 'left' },
                        { title: '使用者名稱', field: 'RealName', width: 150, align: 'left' }
                    ]],
                    onLoadSuccess: function (data) {
                        top.$('#rightnav').tree({
                            cascadeCheck: false, //聯動選中節點
                            checkbox: true,
                            lines: true,
                            url: 'Modules/handler/OrganizeAdminHander.ashx?action=treedata',
                            onSelect: function (node) {
                                top.$('#rightnav').tree('getChildren', node.target);
                            }
                        });
                        top.$('#leftnav').datagrid('selectRow', 0);
                    },
                    onSelect: function (rowIndex, rowData) {
                        curResourceTargetResourceIds = [];
                        var query = 'action=GetPermissionScopeTargetIds'
                                  + '&resourceCategory=PiUser&resourceId=' + rowData.Id
                                  + '&targetCategory=PiOrganize';
                        $.ajaxtext('handler/PermissionHandler.ashx', query, function (data) {
                            var targetResourceTree = top.$('#rightnav');
                            targetResourceTree.tree('uncheckedAll');
                            if (data == '' || data.toString() == '[object XMLDocument]') {
                                return;
                            }
                            curResourceTargetResourceIds = data.split(',');
                            for (var i = 0; i < curResourceTargetResourceIds.length; i++) {
                                var node = targetResourceTree.tree('find', curResourceTargetResourceIds[i]);
                                if (node)
                                    targetResourceTree.tree("check", node.target);
                            }
                        });
                    }
                });
            },
            submit: function () {
                var allSelectTargetResourceIds = permissionMgr.getSelectedResource().split(',');
                var grantResourceIds = '';
                var revokeResourceIds = '';
                var flagRevoke = 0;
                var flagGrant = 0;
                while (flagRevoke < curResourceTargetResourceIds.length) {
                    if ($.inArray(curResourceTargetResourceIds[flagRevoke], allSelectTargetResourceIds) == -1) {
                        revokeResourceIds += curResourceTargetResourceIds[flagRevoke] + ','; //得到收回的許可權列表
                    }
                    ++flagRevoke;
                }

                while (flagGrant < allSelectTargetResourceIds.length) {
                    if ($.inArray(allSelectTargetResourceIds[flagGrant], curResourceTargetResourceIds) == -1) {
                        grantResourceIds += allSelectTargetResourceIds[flagGrant] + ','; //得到授予的許可權列表
                    }
                    ++flagGrant;
                }

                var query = 'action=GrantRevokePermissionScopeTargets&resourceId=' + top.$('#leftnav').datagrid('getSelected').Id
                          + '&resourceCategory=PiUser&targetCategory=PiOrganize'
                          + '&grantTargetIds=' + grantResourceIds + "&revokeTargetIds=" + revokeResourceIds;
                $.ajaxjson('handler/PermissionHandler.ashx', query, function (d) {
                    if (d.Data > 0) {
                        msg.ok('設定成功!');
                    }
                    else {
                        alert(d.Message);
                    }
                });
            }
        });

    }

“角色-組織機構許可權設定”功能與“使用者-組織機構許可權設定”功能類似,這兒只是做的對角色的控制。(角色-組織機構)許可權設定介面如下:。

  

相關資源分享 

作者: 
出處: 
Email:[email protected] 
QQ交流:406590790 
QQ群:237326100 
框架部落格:http://blog.csdn.net/chinahuyong 
               http://www.cnblogs.com/huyong
RDIFramework.NET,基於.NET的快速資訊化系統開發、整合框架,給使用者和開發者最佳的.Net框架部署方案。 
關於作者:高階工程師、資訊系統專案管理師、DBA。專注於微軟平臺專案架構、管理和企業解決方案,多年專案開發與管理經驗,曾多次組織並開發多個大型專案,在面向物件、面向服務以及資料庫領域有一定的造詣。現主要從事基於  框架的技術開發、諮詢工作,主要服務於金融、醫療衛生、鐵路、電信、物流、物聯網、製造、零售等行業。 
如有問題或建議,請多多賜教! 
本文版權歸作者和CSDN共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,如有問題,可以通過郵箱或QQ 聯絡我,非常感謝。