Vue基础篇一:编写第一个Vue程序
Vue基础篇二:Vue组件的核心概念
Vue基础篇三:Vue的计算属性与侦听器
Vue基础篇四:Vue的生命周期(秒杀案例实战)
Vue基础篇五:Vue的指令
Vue基础篇六:Vue使用JSX进行动态渲染
Vue提高篇一:使用Vuex进行状态管理
Vue提高篇二:使用vue-router实现静态路由
Vue提高篇三:使用vue-router实现动态路由
Vue提高篇四:使用Element UI组件库
Vue提高篇五:使用Jest进行单元测试
Vue提高篇六: 使用Vetur+ESLint+Prettier插件提升开发效率
Vue实战篇一: 使用Vue搭建注册登录界面
Vue实战篇二: 实现邮件验证码发送
Vue实战篇三:实现用户注册
Vue实战篇四:创建多步骤表单
Vue实战篇五:实现文件上传
Vue实战篇六:表格渲染动态数据
Vue实战篇七:表单校验
Vue实战篇八:实现弹出对话框进行交互
Vue实战篇九:使用省市区级联选择插件
Vue实战篇十:响应式布局
Vue实战篇十一:父组件获取子组件数据的常规方法
Vue实战篇十二:多项选择器的实际运用
Vue实战篇十三:实战分页组件
Vue实战篇十四:前端excel组件实现数据导入
Vue实战篇十五:表格数据多选在实际项目中的技巧
Vue实战篇十六:导航菜单
Vue实战篇十七:用树型组件实现一个知识目录
Vue实战篇十八:搭建一个知识库框架
Vue实战篇十九:使用printjs打印表单
Vue实战篇二十:自定义表格合计
Vue实战篇二十一:实战Prop的双向绑定
Vue实战篇二十二:生成二维码
Vue实战篇二十三:卡片风格与列表风格的切换
/**
* MybatisPlus分页插件配置类
*
* @author zhuhuix
* @date 2022-04-07
*/
@Configuration
@ConditionalOnClass(value = {MybatisPlusInterceptor.class})
@Mapper
public class MybatisPlusConfig {
// 3.4.0 版本以上使用MybatisPlusInterceptor
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
/**
* 用户查询条件
*
* @author zhuhuix
* @date 2021-09-28
*
* @date 2022-04-04
* 增加分页传入参数
*/
@ApiModel(value = "用户查询条件")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SysUserQueryDto {
@ApiModelProperty(value = "用户名")
private String userName;
@ApiModelProperty(value = "注册起始时间")
private Long createTimeStart;
@ApiModelProperty(value = "注册结束时间")
private Long createTimeEnd;
@ApiModelProperty(value = "当前页数")
private Integer currentPage;
@ApiModelProperty(value = "每页条数")
private Integer pageSize;
}
/**
* 用户分页返回数据
*
* @author zhuhuix
* @date 2022-04-07
*/
@ApiModel(value = "用户分页数据")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SysUserDto {
// 当前查询第几页
private Integer currentPage;
// 每页显示数量
private Integer pageSize;
// 总页数=总数据量/每页显示数量
private Long totalPage;
private List<SysUser> sysUserList;
}
/**
* 用户信息接口
*
* @author zhuhuix
* @date 2020-04-03
*
* @date 2022-04-07
* 增加分页查询接口
*/
public interface SysUserService {
...
/**
* 根据条件查询用户信息,并返回分页用户列表
* @param sysUserQueryDto 查询条件
* @return 分页用户数据
*/
SysUserDto page(SysUserQueryDto sysUserQueryDto);
}
/**
* 用户接口实现类
*
* @author zhuhuix
* @date 2020-04-03
*
* @date 2022-04-07
* 实现分页查询
*/
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class SysUserServiceImpl implements SysUserService {
private final SysUserMapper sysUserMapper;
...
@Override
public SysUserDto page(SysUserQueryDto sysUserQueryDto) {
QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
if (!StringUtils.isEmpty(sysUserQueryDto.getUserName())) {
queryWrapper.lambda().like(SysUser::getUserName, sysUserQueryDto.getUserName())
.or().like(SysUser::getNickName, sysUserQueryDto.getUserName());
}
if (!StringUtils.isEmpty(sysUserQueryDto.getCreateTimeStart())
&& !StringUtils.isEmpty(sysUserQueryDto.getCreateTimeEnd())) {
queryWrapper.and(wrapper -> wrapper.lambda().between(SysUser::getCreateTime,
new Timestamp(sysUserQueryDto.getCreateTimeStart()),
new Timestamp(sysUserQueryDto.getCreateTimeEnd())));
}
// 根据前端的分页查询参数进行分页查询
Page<SysUser> page = new Page<>(sysUserQueryDto.getCurrentPage(), sysUserQueryDto.getPageSize());
sysUserMapper.selectPage(page, queryWrapper);
SysUserDto sysUserDto = new SysUserDto();
sysUserDto.setCurrentPage(sysUserQueryDto.getCurrentPage());
sysUserDto.setPageSize(sysUserQueryDto.getPageSize());
sysUserDto.setTotalPage(page.getTotal());
sysUserDto.setSysUserList(page.getRecords());
return sysUserDto;
}
}
/**
* api用户信息
*
* @author zhuhuix
* @date 2021-08-16
*
* @date 2022-04-07
* 增加分页查询接口
*/
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/api/user")
@Api(tags = "用户信息接口")
public class SysUserController {
private final SysUserService sysUserService;
...
@ApiOperation("根据条件查询返回用户分页列表")
@PostMapping("/page")
public ResponseEntity<Object> getSysUserPage(@RequestBody SysUserQueryDto sysUserQueryDto) {
return ResponseEntity.ok(sysUserService.page(sysUserQueryDto));
}
}
import request from '@/utils/request'
...
// 获取用户分页信息接口
export function getUserPageList(params) {
return request({
url: '/api/user/page',
method: 'post',
data: JSON.stringify(params)
})
}
<el-pagination
background // 显示背景色
:current-page="currentPage" // 当前页数
:page-sizes="[5, 10, 15, 20]" // 每页显示条数的选项列表
:page-size="pageSize" // 每页显示条数
layout="sizes,prev, pager, next" // 布局,分别为显示每页条数选项列表,前一页,当前页,后一页
:total="totalPage" //总共页数
@size-change="handleSizeChange" // 每页显示条数变化触发事件
@current-change="handleCurrentChange" // 翻页后触发事件
/>
<template>
<div class="app-container">
<div class="head-container">
<el-input
v-model="userName"
size="small"
clearable
placeholder="输入账号或用户名称搜索"
style="width: 200px"
class="filter-item"
@keyup.enter.native="doQuery"
/>
<el-date-picker
v-model="createTime"
:default-time="['00:00:00', '23:59:59']"
type="daterange"
range-separator=":"
size="small"
class="date-item"
value-format="yyyy-MM-dd HH:mm:ss"
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
<el-button
class="filter-item"
size="mini"
type="success"
icon="el-icon-search"
@click="doQuery"
>搜索el-button>
<el-button
class="filter-item"
size="mini"
type="danger"
icon="el-icon-circle-plus-outline"
:disabled="selections.length === 0"
@click="doDelete"
>删除el-button>
div>
<el-row>
<el-dialog
append-to-body
:close-on-click-modal="false"
:visible.sync="showDialog"
title="角色分配"
width="600px"
>
<el-form
ref="form"
:inline="true"
:model="form"
size="small"
label-width="76px"
>
<el-form-item label="登录账号" prop="userName">
<el-input v-model="form.userName" :disabled="true" />
el-form-item>
<el-form-item label="昵称" prop="nickName">
<el-input v-model="form.nickName" :disabled="true" />
el-form-item>
<el-form-item style="margin-bottom: 0" label="角色" prop="userRoles">
<el-select
v-model="userRoles"
style="width: 455px"
multiple
filterable
placeholder="请选择"
@remove-tag="deleteTag"
@change="changeRole"
>
<el-option
v-for="item in roles"
:key="item.roleCode"
:label="item.roleName"
:value="item.id"
/>
el-select>
el-form-item>
el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="doCancel">取消el-button>
<el-button
:loading="formLoading"
type="primary"
@click="doSubmit"
>确认el-button>
div>
el-dialog>
<el-tabs v-model="activeName" type="border-card">
<el-tab-pane label="用户列表" name="userList">
<el-table
ref="table"
v-loading="loading"
:data="users"
style="width: 100%; font-size: 12px"
@selection-change="selectionChangeHandler"
>
<el-table-column type="selection" width="55" />
<el-table-column
:show-overflow-tooltip="true"
width="150"
prop="userName"
label="登录账号"
/>
<el-table-column
:show-overflow-tooltip="true"
width="150"
prop="nickName"
label="用户昵称"
/>
<el-table-column prop="gender" width="60" label="性别">
<template slot-scope="scope">
<el-tag v-if="scope.row.gender === 1" type="success">男el-tag>
<el-tag v-if="scope.row.gender === 2" type="warning">女el-tag>
<el-tag v-if="scope.row.gender === 0" type="info">未知el-tag>
template>
el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="phone"
width="150"
label="电话"
/>
<el-table-column
:show-overflow-tooltip="true"
prop="city"
label="所在地区"
>
<template slot-scope="scope">
<span>{{ scope.row.province }} {{ scope.row.city }}
{{ scope.row.country }}span>
template>
el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="avatarUrl"
width="80"
label="头像"
>
<template slot-scope="scope">
<img
:src="
scope.row.avatarUrl
? baseApi + '/file/' + scope.row.avatarUrl
: Avatar
"
class="avatar"
>
template>
el-table-column>
<el-table-column
:show-overflow-tooltip="true"
prop="createTime"
width="155"
label="注册日期"
>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}span>
template>
el-table-column>
<el-table-column
label="操作"
width="160"
align="center"
fixed="right"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
round
@click="doAssignRole(scope.row.id)"
>分配角色el-button>
template>
el-table-column>
el-table>
<el-pagination
class="page"
background
:current-page="currentPage"
:page-sizes="[5, 10, 15, 20]"
:page-size="pageSize"
layout="sizes,prev, pager, next"
:total="totalPage"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
el-tab-pane>
el-tabs>
el-row>
div>
template>
<script>
import { mapGetters } from 'vuex'
import Avatar from '@/assets/images/avatar.png'
import { parseTime } from '@/utils/index'
import { getUserPageList, deleteUser, getInfoById, getUserRoles, saveUserRoles } from '@/api/user'
import { getRoleList } from '@/api/role'
export default {
name: '用户管理',
data() {
return {
Avatar: Avatar,
activeName: 'userList',
showDialog: false,
loading: false,
formLoading: true,
form: {},
totalPage: 0,
currentPage: 1,
pageSize: 5,
users: [],
selections: [],
userName: '',
createTime: null,
roles: [],
userRoles: []
}
},
computed: {
...mapGetters([
'baseApi'
])
},
created() {
},
methods: {
parseTime,
doQuery() {
this.users = []
var param = { userName: this.userName }
if (this.createTime != null) {
param.createTimeStart = Date.parse(this.createTime[0])
param.createTimeEnd = Date.parse(this.createTime[1])
}
param.pageSize = this.pageSize
param.currentPage = this.currentPage
// 替换成分页查询接口
getUserPageList(param).then(res => {
if (res) {
this.totalPage = res.totalPage
this.currentPage = res.currentPage
this.users = res.sysUserList
}
})
},
// 每页条数改变
handleSizeChange(val) {
this.pageSize = val
this.doQuery()
},
// 翻页
handleCurrentChange(val) {
this.currentPage = val
this.doQuery()
},
doDelete() {
const ids = []
this.selections.forEach((res) => {
ids.push(res.id)
})
this.$confirm(`确认删除这些用户吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() =>
deleteUser(ids).then(res => {
if (res) {
this.$notify({
title: '删除成功',
type: 'success',
duration: 2500
})
this.doQuery()
}
})
).catch(() => {
})
},
// 选择改变
selectionChangeHandler(val) {
this.selections = val
},
doAssignRole(id) {
this.form = {}
this.userRoles = []
this.roles = []
this.showDialog = true
this.formLoading = true
getInfoById(id).then((res) => {
this.form = { id: res.id, userName: res.userName, nickName: res.nickName, gender: res.gender, phone: res.phone }
var param = {}
getRoleList(param).then(res => {
if (res) {
this.roles = res
}
getUserRoles(id).then((res) => {
if (res) {
res.forEach(role => {
this.userRoles.push(role.id)
})
}
this.formLoading = false
})
})
})
},
doCancel() {
this.showDialog = false
this.form = {}
},
doSubmit() {
this.formLoading = true
saveUserRoles(this.form.id, this.userRoles).then(() => {
this.showDialog = false
this.$notify({
title: '保存成功',
type: 'success',
duration: 2500
})
})
},
deleteTag(value) {
this.userRoles.forEach(function(data, index) {
if (data.id === value) {
this.userRoles.splice(index, value)
}
})
},
changeRole(value) {
// console.log(this.userRoles)
}
}
}
script>
<style rel="stylesheet/scss" lang="scss">
.avatar {
width: 32px;
height: 32px;
border-radius: 50%;
}
.page{
float: right;
margin-top: 5px;
}
style>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .el-input-number .el-input__inner {
text-align: left;
}
style>