更新于:

分页实现

目录

分页实现

以 [系统管理 -> 租户管理 -> 租户列表] 菜单为例子,讲解它的分页 + 搜索的实现。

# 1. 前端分页实现

# 1.1 Vue 界面

界面 tenant/index.vue (opens new window) 相关的代码如下:

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
<template>
<!-- 搜索工作栏 -->
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="租户名" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入租户名" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="联系人" prop="contactName">
<el-input v-model="queryParams.contactName" placeholder="请输入联系人" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="联系手机" prop="contactMobile">
<el-input v-model="queryParams.contactMobile" placeholder="请输入联系手机" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="租户状态" prop="status">
<el-select v-model="queryParams.status" placeholder="请选择租户状态" clearable>
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)"
:key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>

<!-- 列表 -->
<el-table v-loading="loading" :data="list">
<!-- 省略每一列... -->
</el-table>

<!-- 分页组件 -->
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
@pagination="getList"/>

</template>

<script>
import { getTenantPage } from "@/api/system/tenant";

export default {
name: "Tenant",
components: {},
data() {
// 遮罩层
return {
// 遮罩层
loading: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 租户列表
list: [],
// 查询参数
queryParams: {
pageNo: 1,
pageSize: 10,
// 搜索条件
name: null,
contactName: null,
contactMobile: null,
status: undefined,
},
}
},
created() {
this.getList();
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
// 处理查询参数
let params = {...this.queryParams};
// 执行查询
getTenantPage(params).then(response => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNo = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
}
}
}
</script>

# 1.2 API 请求

请求 system/tenant.js ( opens new window) 相关的代码如下:

1
2
3
4
5
6
7
8
9
10
import request from '@/utils/request'

// 获得租户分页
export function getTenantPage(query) {
return request({
url: '/system/tenant/page',
method: 'get',
params: query
})
}

# 2. 后端分页实现

# 2.1 Controller 接口

TenantController ( opens new window) 类中,定义 /admin-api/system/tenant/page 接口。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Tag(name = "管理后台 - 租户")
@RestController
@RequestMapping("/system/tenant")
public class TenantController {

@Resource
private TenantService tenantService;

@GetMapping("/page")
@Operation(summary = "获得租户分页")
@PreAuthorize("@ss.hasPermission('system:tenant:query')")
public CommonResult<PageResult<TenantRespVO>> getTenantPage(@Valid TenantPageReqVO pageVO) {
PageResult<TenantDO> pageResult = tenantService.getTenantPage(pageVO);
return success(TenantConvert.INSTANCE.convertPage(pageResult));
}

}

# 2.1.1 分页参数 PageParam

分页请求,需要继承 PageParam (opens new window) 类。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Schema(description="分页参数")
@Data
public class PageParam implements Serializable {

private static final Integer PAGE_NO = 1;
private static final Integer PAGE_SIZE = 10;

@Schema(description = "页码,从 1 开始", required = true,example = "1")
@NotNull(message = "页码不能为空")
@Min(value = 1, message = "页码最小值为 1")
private Integer pageNo = PAGE_NO;

@Schema(description = "每页条数,最大值为 100", required = true, example = "10")
@NotNull(message = "每页条数不能为空")
@Min(value = 1, message = "每页条数最小值为 1")
@Max(value = 100, message = "每页条数最大值为 100")
private Integer pageSize = PAGE_SIZE;

}

分页条件,在子类中进行定义。以 TenantPageReqVO 举例子,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Schema(description = "管理后台 - 租户分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class TenantPageReqVO extends PageParam {

@Schema(description = "租户名", example = "芋道")
private String name;

@Schema(description = "联系人", example = "芋艿")
private String contactName;

@Schema(description = "联系手机", example = "15601691300")
private String contactMobile;

@Schema(description = "租户状态(0正常 1停用)", example = "1")
private Integer status;

@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@Schema(description = "创建时间")
private LocalDateTime[] createTime;

}

# 2.1.2 分页结果 PageResult

分页结果 PageResult ( opens new window) 类,代码如下:

1
2
3
4
5
6
7
8
9
10
11
@Schema(description = "分页结果")
@Data
public final class PageResult<T> implements Serializable {

@Schema(description = "数据", required = true)
private List<T> list;

@Schema(description = "总量", required = true)
private Long total;

}

分页结果的数据 list 的每一项,通过自定义 VO 类,例如说 TenantRespVO (opens new window) 类。

# 2.2 Mapper 查询

TenantMapper (opens new window) 类中,定义 selectPage 查询方法。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Mapper
public interface TenantMapper extends BaseMapperX<TenantDO> {

default PageResult<TenantDO> selectPage(TenantPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<TenantDO>()
.likeIfPresent(TenantDO::getName, reqVO.getName()) // 如果 name 不为空,则进行 like 查询
.likeIfPresent(TenantDO::getContactName, reqVO.getContactName())
.likeIfPresent(TenantDO::getContactMobile, reqVO.getContactMobile())
.eqIfPresent(TenantDO::getStatus, reqVO.getStatus()) // 如果 status 不为空,则进行 = 查询
.betweenIfPresent(TenantDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime()) // 如果 create 不为空,则进行 between 查询
.orderByDesc(TenantDO::getId)); // 按照 id 倒序
}

}

针对 MyBatis Plus 分页查询的二次分装,在 BaseMapperX (opens new window) 中实现,主要是将 MyBatis 的分页结果 IPage,转换成项目的分页结果 PageResult。代码如下图:

BaseMapperX 实现

上次更新: 2023/03/04, 22:58:24

本站由 钟意 使用 Stellar 1.25.0 主题创建。
又拍云 提供CDN加速/云存储服务
vercel 提供托管服务
湘ICP备2023019799号-1
总访问 次 | 本页访问