abp(net core)+easyui+efcore实现仓储管理系统目录
abp(net core)+easyui+efcore实现仓储管理系统——EasyUI前端页面框架 (十八)
在上面文章abp(net core)+easyui+efcore实现仓储管理系统——ABP WebAPI与EasyUI结合增删改查之九(三十五) 的学习之后,我们已经实现了在控制器中实现查询功能,今天我们来通过ABP自动帮助我们生成的WebAPI接口,来实现查询功能。
十七、 WebAPI接口查询
1. 在Visual Studio 2017的“解决方案资源管理器”中,右键单击在领域层“ABP.TPLMS.Web.Mvc”项目中的Views\Orgs目录。 找到Index.cshmtl文件,添加一个查询条件相关代码。具体代码如下:
<div data-options="region:'center'" style="overflow: hidden;"> <div id="containter" style="width: 1000px; height: auto; margin: 0px auto;"> <div style="margin-bottom:1px;font-weight:bold;"> <a href="#" id="add" class="easyui-linkbutton" data-options="iconCls:'icon-add'" style="width:100px; height:30px; ">添加a> <a href="#" id="del" class="easyui-linkbutton" data-options="iconCls:'icon-remove'" style="width:100px; height:30px; ">删除a> <a href="#" id="edit" class="easyui-linkbutton" data-options="iconCls:'icon-edit'" style="width:100px; height:30px; ">修改a> <a href="#" id="reload" class="easyui-linkbutton" data-options="iconCls:'icon-reload'" style="width:100px; height:30px; ">刷新a> div> <div id="dg-button"> <form name="searchform" method="post" action="" id="searchform"> <label for="OrgName">组织名称:label> <input name="OrgName" id="OrgName" class="easyui-validatebox" data-options="width:200" /> <label for="OrgCode">组织代码:label> <input name="OrgCode" id="OrgCode" class="easyui-validatebox" data-options="width:150" /> <label for="CustomCode">海关代码:label> <input name="CustomCode" id="CustomCode" class="easyui-validatebox" data-options="width:100" /> <input name="SkipCount" type="hidden" value="1" /> <input name="MaxResultCount" type="hidden" value="1000" /> <a href="#" id="search" class="easyui-linkbutton" data-options="iconCls:'icon-search'" onclick="Search()">查询a> form> div> <div data-options="region:'center',split:false" style="height:500px;"> <table id="dgOrg">table> div> div> div>
2.在Visual Studio 2017的“解决方案资源管理器”中,右键单击“ABP.TPLMS.Application”项目的 “Orgs”文件夹中,找到Paged OrgResultRequestDto.cs文件,添加查询条件属性。代码如下。
public class PagedOrgResultRequestDto : PagedResultRequestDto
{
public string Keyword { get; set; }
public string OrgName { get; set; }
public string OrgCode { get; set; }
public string CustomCode { get; set; }
}
}
3. 在Visual Studio 2017的“解决方案资源管理器”中,找到领域层“ABP.TPLMS.Web.Mvc”项目中的wwwroot目录下的view-resources\Orgs文件夹下,找到Index.js文件,把 $("#dgOrg").treegrid方法 中的URL属性改为abp.appPath + "api/services/app/org/GetAll"。代码如下。
function initable() { $("#dgOrg").treegrid({ url: abp.appPath + "api/services/app/org/GetAll", method:"GET", title: "组织管理", pagination: false, toolbar: "#dg-button", fit: true, fitColumns: false, loadMsg: "正在加载组织信息...", nowarp: false, border: false, idField: "Id", sortName: "Id", sortOrder: "asc", treeField: "Name", frozenColumns: [[//冻结列 { field: "chk", checkbox: true, align: "left", width: 50 } ]], columns: [[ { title: "编号", field: "Id", width: 50, sortable: true }, { title: "组织名称", field: "Name", width: 200, sortable: true }, { title: "代码", field: "BizCode", width: 100, sortable: true }, { title: "海关代码", field: "CustomCode", width: 100, sortable: true }, { title: "状态", field: "Status", width: 80, sortable: false }, { title: "类型", field: "Type", width: 80, sortable: false }, { title: "父节点", field: "ParentName", width: 120, sortable: false }, { title: '创建时间', field: 'CreationTime', width: 130, align: 'center' } ]] }); }
function Search() { var _$form = $('form[name=searchform]'); var params = _$form.serializeFormToObject(); $('#dgOrg').treegrid({ queryParams: params }); }
5.在Visual Studio 2017的“解决方案资源管理器”中,右键单击“ABP.TPLMS.Application”项目的 “Orgs”文件夹中,找到OrgAppService.cs文件。重写CreateFilteredQuery方法。代码如下。关于GetParentOrgs方法,在这里要说明一点,这个方法的具体作用是找到我们查询到的组织信息的所有上级组织。这个方法通过递归算法来查找条件当前查询条件的组织信息中的第一条的所有上级组织信息。这个方法暂时还有缺陷,可以自行修正。
protected override IQueryableCreateFilteredQuery(PagedOrgResultRequestDto input) { var qry= base.CreateFilteredQuery(input) .Where(t=>t.Name.Contains(input.OrgName)) .Where(t => t.BizCode.Contains(input.OrgCode)) .Where(t => t.CustomCode.Contains(input.CustomCode)); List list = qry.ToList (); var qry1 = base.CreateFilteredQuery(input); List listParent = new List (); GetParentOrgs(listParent, list[0].ParentId, qry1); return qry.Union (listParent); } private void GetParentOrgs(List orgs, int ParentId, IQueryable listOrgs) { List lstOrgs = listOrgs.Where(x => x.Id == ParentId).ToList(); if (lstOrgs == null || lstOrgs .Count <= 0) { return; } else { for (int i = 0; i < lstOrgs.Count; i++) { var org= lstOrgs[i]; if (!orgs.Contains(org)) { orgs.Add(org); } GetParentOrgs(orgs, dr.ParentId, listOrgs); } } }
6.在Visual Studio 2017中按F5运行应用程序。
7.在浏览器中的地址栏中输入“http://localhost:5000/”,然后输入管理员用户名进行登录。
8.在主界面的菜单中,选择“Business->组织管理”菜单项,浏览器中呈现一个货物信息列表与四个按钮。如下图。
9. 我们发现没有显示数据,那么数据是否已经获取呢,我们在浏览器中按F12,然后再次点击“组织管理”菜单,得到下图。发现数据已经获取。
10. 从上图中可以看出这个返回的结果是经过ABP包装后的结果。ABP把它包装成一个MvcAjaxResponse对象,而这个包装过的结果却不是TreeGrid所需要的json格式字符串。我们先解释一下这些属性:
success:一个布尔值(true或false),指示操作的是否成功,如果为true,abp.ajax解板promise并调用done处理程序,如果为false(如果有方法调用中抛出异常),它调用fail处理程序,并使用abp.message.error函数显示error信息。
result:返回控制器里操作的结果,如果success为true时服务器发送一个返回值后,它才可用。
error:如果success为false,这个属性包含一个错误明细信息的对象。
targetUrl:提供一个URL给服务端,在有需要的时候,把客户端定向到这个URL。
unAuthorizedRequest:服务端给客户端一个通知:这个操作未被认证或用户未被认证。如果为true,abp.ajax重新载入当前页面。
_abp:一个特殊的标志,表示响应是ABP包装的,你不需要使用它,abp.ajax会处理它。
11.知道了问题所在,在Visual Studio 2017的“解决方案资源管理器”中,右键单击“ABP.TPLMS.Application”项目的 “Orgs”文件夹中,找到OrgAppService.cs文件。重写GetAll方法,并加上DontWrapResult特性,让ABP不要进行包装。代码如下。
[DontWrapResult] public override Task> GetAll(PagedOrgResultRequestDto input) { return base.GetAll(input); }
12. 重复上面的第6、7、8步。得到如下图结果,返回的JSON数据,还是无法让treeGrid显示记录。
13.我们发现TreeGrid能接受的JSON数据与WebAPI接口返回的JSON数据。还是有不一样的地方,WebpAPI接口返回的总数是totalCount,而不是“total”,接口返回的数据集合是items,而不是“rows”。
WebAPI接口返回的JSON数据:
{"totalCount":13,"items":[
{"name":"虹桥火车站店","hotKey":"","parentId":7,"parentName":"上海公司","isLeaf":true,"isAutoExpand":true,"iconName":"",
"status":1,"type":1,"bizCode":"SHHQHCZ","customCode":"2011","creationTime":"0001-01-01T00:00:00","updateTime":"0001-01-01T00:00:00",
"createId":0,"sortNo":0,"_parentId":7,"id":15},
{"name":"迪斯尼店","hotKey":"","parentId":7,"parentName":"上海公司","isLeaf":true,"isAutoExpand":false,"iconName":"",
"status":1,"type":1,"bizCode":"SHDSN","customCode":"1","creationTime":"0001-01-01T00:00:00","updateTime":"0001-01-01T00:00:00",
"createId":0,"sortNo":0,"_parentId":7,"id":14},
{"name":"上海陆家嘴店","hotKey":"","parentId":7,"parentName":"上海公司","isLeaf":true,"isAutoExpand":true,"iconName":"",
"status":1,"type":1,"bizCode":"SHLJZ","customCode":"2010","creationTime":"0001-01-01T00:00:00","updateTime":"0001-01-01T00:00:00",
"createId":0,"sortNo":0,"_parentId":7,"id":13}]} 其他略
Treegird能接受的JSON数据:
{"total":13,"rows":[
{"name":"虹桥火车站店","hotKey":"","parentId":7,"parentName":"上海公司","isLeaf":true,"isAutoExpand":true,"iconName":"",
"status":1,"type":1,"bizCode":"SHHQHCZ","customCode":"2011","creationTime":"0001-01-01T00:00:00","updateTime":"0001-01-01T00:00:00",
"createId":0,"sortNo":0,"_parentId":7,"id":15},
{"name":"迪斯尼店","hotKey":"","parentId":7,"parentName":"上海公司","isLeaf":true,"isAutoExpand":false,
"iconName":"","status":1,"type":1,"bizCode":"SHDSN","customCode":"1","creationTime":"0001-01-01T00:00:00","updateTime":"0001-01-01T00:00:00",
"createId":0,"sortNo":0,"_parentId":7,"id":14},
{"name":"上海陆家嘴店","hotKey":"","parentId":7,"parentName":"上海公司","isLeaf":true,"isAutoExpand":true,"iconName":"",
"status":1,"type":1,"bizCode":"SHLJZ","customCode":"2010","creationTime":"0001-01-01T00:00:00","updateTime":"0001-01-01T00:00:00",
"createId":0,"sortNo":0,"_parentId":7,"id":13}]} 其他略
14.现在我们知道了两种的不同,我们来创建一个我们需要的类。在Visual Studio 2017的“解决方案资源管理器”中,右键单击“ABP.TPLMS.Application”项目的 “Orgs\Dto”文件夹中,在弹出菜单中“添加->类”。
15.创建一个新的类“PagedOrgResultDto”。这个类的代码如下。
namespace ABP.TPLMS.Orgs.Dto { public class PagedOrgResultDto{ public int Total { get; set; } public IReadOnlyList Rows { get; set; } } }
[DontWrapResult] public PagedOrgResultDtoGetAllOrgs(PagedOrgResultRequestDto input) { PagedOrgResultDto orgs = new PagedOrgResultDto (); var allOrgs=GetAll(input); orgs.Rows = allOrgs.Result.Items; orgs.Total = allOrgs.Result.TotalCount; return orgs; }
17. 在Visual Studio 2017的“解决方案资源管理器”中,找到领域层“ABP.TPLMS.Web.Mvc”项目中的wwwroot目录下的view-resources\Orgs文件夹下,找到Index.js文件,把 $("#dgOrg").treegrid方法 中的URL属性改为abp.appPath + "api/services/app/org/GetAllOrgs"。
18. 重复上面的第6、7、8步,并在浏览器中按F12,打开调试器。得到如下图结果,还是无法让treeGrid显示记录,虽然说已经返回的符合treeGrid需要的JSON数据。仔细看下图,我们发现total是13,而实际的记录却只有10条。
19. 在Visual Studio 2017的“解决方案资源管理器”中,左键单击“ABP.TPLMS.Application”项目的 “Orgs”文件夹中,找到OrgAppService.cs文件。在GetAllOrgs方法中设置断点,然后在页面上点击“刷新”按钮,我们发现其中有个属性MaxResultCount的值为10。如下图。
20. 在Visual Studio 2017的“解决方案资源管理器”中,修改GetAllOrgs方法中的代码。代码如下。
[DontWrapResult] public PagedOrgResultDtoGetAllOrgs(PagedOrgResultRequestDto input) { PagedOrgResultDto orgs = new PagedOrgResultDto (); input.MaxResultCount = 1000;//这里可以修改为根据传递参数来决定数量 var allOrgs=GetAll(input); orgs.Rows = allOrgs.Result.Items; orgs.Total = allOrgs.Result.TotalCount; return orgs; }
21. 重复上面的第6、7、8步。得到如下图结果,返回的JSON数据,还是无法让treeGrid显示记录。
22.我们发现TreeGrid能接受的JSON数据与WebAPI接口返回的JSON数据。还是有不一样的地方,WebpAPI接口返回的JSON数据是首字母小写,此处,所有属性都是小骆峰式命名,即使它们在服务端是大骆峰式命名。
WebAPI接口返回的JSON数据:
{"total":13,"rows": [{"name":"虹桥火车站店","hotKey":"","parentId":7,"parentName":"上海公司","isLeaf":true,"isAutoExpand":true,"iconName":"",
"status":1,"type":1,"bizCode":"SHHQHCZ","customCode":"2011","creationTime":"0001-01-01T00:00:00","updateTime":"0001-01-01T00:00:00",
"createId":0,"sortNo":0,"_parentId":7,"id":15}, {"name":"迪斯尼店","hotKey":"","parentId":7,"parentName":"上海公司","isLeaf":true,"isAutoExpand":false,"iconName":"",
"status":1,"type":1,"bizCode":"SHDSN","customCode":"1","creationTime":"0001-01-01T00:00:00","updateTime":"0001-01-01T00:00:00",
"createId":0,"sortNo":0,"_parentId":7,"id":14}, {"name":"上海陆家嘴店","hotKey":"","parentId":7,"parentName":"上海公司","isLeaf":true,"isAutoExpand":true,"iconName":"",
"status":1,"type":1,"bizCode":"SHLJZ","customCode":"2010","creationTime":"0001-01-01T00:00:00","updateTime":"0001-01-01T00:00:00",
"createId":0,"sortNo":0,"_parentId":7,"id":13}]} 其他略
23.我们再来查看Index.js文件中的javascipt代码,指定字段名称的地方是首字母大小。 在Visual Studio 2017的“解决方案资源管理器”中,找到领域层“ABP.TPLMS.Web.Mvc”项目中的wwwroot目录下的view-resources\Orgs文件夹下,找到Index.js文件,修改initable函数。如下。
function initable() { $("#dgOrg").treegrid({ url: abp.appPath + "api/services/app/org/GetAllOrgs", method:"GET", title: "组织管理", pagination: false, toolbar: "#dg-button", fit: true, fitColumns: false, loadMsg: "正在加载组织信息...", nowarp: false, border: false, idField: "id", sortName: "id", sortOrder: "asc", treeField: "name", frozenColumns: [[//冻结列 { field: "chk", checkbox: true, align: "left", width: 50 } ]], columns: [[ { title: "编号", field: "id", width: 50, sortable: true }, { title: "组织名称", field: "name", width: 200, sortable: true }, { title: "代码", field: "bizCode", width: 100, sortable: true }, { title: "海关代码", field: "customCode", width: 100, sortable: true }, { title: "状态", field: "status", width: 80, sortable: false }, { title: "类型", field: "type", width: 80, sortable: false }, { title: "父节点", field: "parentName", width: 120, sortable: false }, { title: '创建时间', field: 'creationTime', width: 130, align: 'center' } ]] }); }
25.在“组织代码”中输入“SH”,然后点击“查询”按钮。如下图。至此通过WebAPI接口进行查询功能完成。