P5-员工分页查询功能开发
1.需求分析
1.1页面分析
系统员工很多的时候,如果都在一个页面进行展示就会显得比较乱,不便于查看,所以需要进行分页,来展示数据
2.代码开发
2.1程序执行流程分析
- 页面发送Ajax请求,将分页参数(page,pageSize,name)提交到服务器
- 服务端Controller接收页面提交的参数并调用Service查询数据
- Service调用Mapper操作数据库查询分页数据
- Controller将查询到的分页数据响应给页面
- 页面接收到分页数据并通过ElementUI的Table组件展示到页面
2.1前端页面
2.1.1 list.html 代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 引入样式 -->
<link rel="stylesheet" href="../../plugins/element-ui/index.css" />
<link rel="stylesheet" href="../../styles/common.css" />
<link rel="stylesheet" href="../../styles/page.css" />
<style>
#member-app .notAdmin::after{
border: 0 !important;
}
</style>
</head>
<body>
<div class="dashboard-container" id="member-app">
<div class="container">
<div class="tableBar">
<el-input
v-model="input"
placeholder="请输入员工姓名"
style="width: 250px"
clearable
@keyup.enter.native="handleQuery"
>
<i
slot="prefix"
class="el-input__icon el-icon-search"
style="cursor: pointer"
@click="handleQuery"
></i>
</el-input>
<el-button
type="primary"
@click="addMemberHandle('add')"
>
+ 添加员工
</el-button>
</div>
<el-table
:data="tableData"
stripe
class="tableBox"
>
<el-table-column
prop="name"
label="员工姓名"
></el-table-column>
<el-table-column
prop="username"
label="账号"
></el-table-column>
<el-table-column
prop="phone"
label="手机号"
></el-table-column>
<el-table-column label="账号状态">
<template slot-scope="scope">
{{ String(scope.row.status) === '0' ? '已禁用' : '正常' }}
</template>
</el-table-column>
<el-table-column
label="操作"
width="160"
align="center"
>
<template slot-scope="scope">
<el-button
type="text"
size="small"
class="blueBug"
@click="addMemberHandle(scope.row.id)"
:class="{notAdmin:user !== 'admin'}"
>
编辑
</el-button>
<el-button
type="text"
size="small"
class="delBut non"
@click="statusHandle(scope.row)"
v-if="user === 'admin'"
>
{{ scope.row.status == '1' ? '禁用' : '启用' }}
</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
class="pageList"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="counts"
:current-page.sync="page"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
></el-pagination>
</div>
</div>
<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<script src="../../plugins/vue/vue.js"></script>
<!-- 引入组件库 -->
<script src="../../plugins/element-ui/index.js"></script>
<!-- 引入axios -->
<script src="../../plugins/axios/axios.min.js"></script>
<script src="../../js/request.js"></script>
<script src="../../api/member.js"></script>
<script>
new Vue({
el: '#member-app',
data() {
return {
input: '',
counts: 0,
page: 1,
pageSize: 10,
tableData : [],
id : '',
status : '',
}
},
computed: {},
created() {
this.init()
this.user = JSON.parse(localStorage.getItem('userInfo')).username
},
mounted() {
},
methods: {
async init () {
const params = {
page: this.page,
pageSize: this.pageSize,
name: this.input ? this.input : undefined
}
await getMemberList(params).then(res => {
if (String(res.code) === '1') {
this.tableData = res.data.records || []
this.counts = res.data.total
}
}).catch(err => {
this.$message.error('请求出错了:' + err)
})
},
handleQuery() {
this.page = 1;
this.init();
},
// 添加
addMemberHandle (st) {
if (st === 'add'){
window.parent.menuHandle({
id: '2',
url: '/backend/page/member/add.html',
name: '添加员工'
},true)
} else {
window.parent.menuHandle({
id: '2',
url: '/backend/page/member/add.html?id='+st,
name: '修改员工'
},true)
}
},
//状态修改
statusHandle (row) {
this.id = row.id
this.status = row.status
this.$confirm('确认调整该账号的状态?', '提示', {
'confirmButtonText': '确定',
'cancelButtonText': '取消',
'type': 'warning'
}).then(() => {
enableOrDisableEmployee({ 'id': this.id, 'status': !this.status ? 1 : 0 }).then(res => {
console.log('enableOrDisableEmployee',res)
if (String(res.code) === '1') {
this.$message.success('账号状态更改成功!')
this.handleQuery()
}
}).catch(err => {
this.$message.error('请求出错了:' + err)
})
})
},
handleSizeChange (val) {
this.pageSize = val
this.init()
},
handleCurrentChange (val) {
this.page = val
this.init()
}
}
})
</script>
</body>
</html>
2.2.2 页面js代码
getMemberList
function getMemberList (params) {
return $axios({
url: '/employee/page',
method: 'get',
params
})
}
2.2.3 参数传递格式化
request拦截器
(function (win) {
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
baseURL: '/',
// 超时
timeout: 10000
})
// request拦截器
service.interceptors.request.use(config => {
// 是否需要设置 token
// const isToken = (config.headers || {}).isToken === false
// if (getToken() && !isToken) {
// config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
// }
// get请求映射params参数
if (config.method === 'get' && config.params) {
let url = config.url + '?';
for (const propName of Object.keys(config.params)) {
const value = config.params[propName];
var part = encodeURIComponent(propName) + "=";
if (value !== null && typeof(value) !== "undefined") {
if (typeof value === 'object') {
for (const key of Object.keys(value)) {
let params = propName + '[' + key + ']';
var subPart = encodeURIComponent(params) + "=";
url += subPart + encodeURIComponent(value[key]) + "&";
}
} else {
url += part + encodeURIComponent(value) + "&";
}
}
}
url = url.slice(0, -1);
config.params = {};
config.url = url;
}
return config
}, error => {
console.log(error)
Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {
if (res.data.code === 0 && res.data.msg === 'NOTLOGIN') {// 返回登录页面
console.log('---/backend/page/login/login.html---')
localStorage.removeItem('userInfo')
window.top.location.href = '/backend/page/login/login.html'
} else {
return res.data
}
},
error => {
console.log('err' + error)
let { message } = error;
if (message == "Network Error") {
message = "后端接口连接异常";
}
else if (message.includes("timeout")) {
message = "系统接口请求超时";
}
else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常";
}
window.ELEMENT.Message({
message: message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
win.$axios = service
})(window);
2.2后代代码实现
后端返回的数据,要和前端对应
2.2.1 配置Mybatis Plus分页插件
分页查询使用Mybatis Plus 分页插件实现
package com.jq.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
/**
* 配置 Mybatis Plus 分页插件
* 拦截器的方式加入插件
* @Bean :交给spring管理
*/
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
//拦截器的方式加入插件
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
2.2.1 Controller代码
/**
* 员工信息分页查询
* 参数:根据Ajax传递的参数进行配置 int page,int pageSize
* 返回值 根据前端判断
* @param page
* @param pageSize
* @return
*/
@GetMapping("/page")
public R<Page>page(int page,int pageSize,String name){
log.info("page={},pageSize={},name={}",page,pageSize,name);
//构造分页条件构造器 page,pageSize
Page pageInfo=new Page(page,pageSize);
//条件构造器 name
LambdaQueryWrapper <Employee>queryWrapper=new LambdaQueryWrapper();
//添加过滤条件,判断name是否为空StringUtils.isNotEmpty(name)
queryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);
//添加排序条件
queryWrapper.orderByDesc(Employee::getUpdateTime);
//执行查询
employeeService.page(pageInfo,queryWrapper);
return R.success(pageInfo);
}