前端使用 Element UI 的 Pagination 组件 实现分页,结合搜索功能,展示租户列表。代码位于 tenant/index.vue,以下是核心部分的分析和注释。
搜索
重置
JavaScript 逻辑
前端通过 system/tenant.js 定义 API 请求,调用后端分页接口。
import request from '@/utils/request'
// 获得租户分页
export function getTenantPage(query) {
return request({
url: '/system/tenant/page',
method: 'get',
params: query
})
}
后端使用 MyBatis Plus 的分页功能,结合二次封装的 PageResult 类实现分页。TenantController 定义了分页接口。
@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> getTenantPage(@Valid TenantPageReqVO pageVO) {
PageResult pageResult = tenantService.getTenantPage(pageVO); // 调用 Service
return success(TenantConvert.INSTANCE.convertPage(pageResult)); // 转换并返回
}
}
分页请求继承 PageParam 类,定义页码和每页条数。
@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 继承 PageParam,添加搜索条件。
@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 = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "创建时间")
private LocalDateTime[] createTime;
}
分页结果使用 PageResult 类封装。
@Schema(description = "分页结果")
@Data
public final class PageResult implements Serializable {
@Schema(description = "数据", required = true)
private List list; // 数据列表
@Schema(description = "总量", required = true)
private Long total; // 总记录数
}
解析:
后端使用 MyBatis Plus 的分页功能,TenantMapper 定义分页查询。
@Mapper
public interface TenantMapper extends BaseMapperX {
default PageResult selectPage(TenantPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX()
.likeIfPresent(TenantDO::getName, reqVO.getName()) // 模糊查询租户名
.likeIfPresent(TenantDO::getContactName, reqVO.getContactName()) // 模糊查询联系人
.likeIfPresent(TenantDO::getContactMobile, reqVO.getContactMobile()) // 模糊查询联系手机
.eqIfPresent(TenantDO::getStatus, reqVO.getStatus()) // 精确匹配状态
.betweenIfPresent(TenantDO::getCreateTime, reqVO.getCreateTime()) // 时间范围查询
.orderByDesc(TenantDO::getId)); // 按 ID 倒序
}
}
BaseMapperX 封装了 MyBatis Plus 的分页逻辑。
default PageResult selectPage(PageParam pageParam, @Param("ew") Wrapper queryWrapper) {
return selectPage(pageParam, null, queryWrapper);
}
default PageResult selectPage(PageParam pageParam, Collection sortingFields, @Param("ew") Wrapper queryWrapper) {
// 特殊:不分页,直接查询全部
if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageSize())) {
List list = selectList(queryWrapper);
return new PageResult<>(list, (long) list.size());
}
// MyBatis Plus 查询
IPage mpPage = MyBatisUtils.buildPage(pageParam, sortingFields);
selectPage(mpPage, queryWrapper);
// 转换返回
return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
}
解析: