持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情
大家好~我是小方,欢迎大家关注笋货测试笔记体完记得俾个like呀
回顾
上篇我们已经完成了用户模块相关的接口开发,接下来我们来进行前后端联调,展示用户数据并进行相关的用户操作
新增列表和修改用户信息api
在/src/api/user.js
,新增如下代码:
export function getUserList(params) {
return request({
url: '/user/list',
method: 'get',
params
})
}
export function updateUser(data) {
return request({
url: '/user/update',
method: 'post',
data
})
}
用户管理新增Table展示
在src/views
新增user
目录,在user
目录下新增index.vue
文件,新增完之后,我们的路由也要更改
用户列表的展示,这里我们用到的是element组件的Table表格,直接把官网的demo复制过去调试
我们先来调整一下代码,引入分页组件,从vue-template-admin
中,将src/components/Pagination
复制到我们的项目中,也是放在同样的位置,同理,也把src/utils/scroll-to.js
复制过去
引用分页组件和api接口,在表格下新增分页组件
在methods
下新增获取用户列表数据,这里是要请求后端接口,注意一下~
初始化进入这个页面,请求用户列表接口,获取到数据后,渲染页面
接着来调整表格相关的字段,列名的字段要跟后端返参的字段名保持一致
调整后,页面长这样
继续优化一下页面的一些展示,用户角色引入el-tag
加入这段代码
对应也要在filters新增一个map进行映射
是否冻结引入Switch 开关
这里我们要加入一个事件,监听Switch 开关
值的变化
userStateChaged
事件代码如下:
async userStateChaged(row) {
this.updateUserForm.id = row.id
this.updateUserForm.is_valid = row.is_valid
const { msg } = await updateUser(this.updateUserForm)
this.$message({
message: msg,
type: 'success'
})
await this.getUserInfos()
}
这里记得要定义用户信息表单
在Table上面,我们加入一个搜索框进行搜索用户
两个按钮分别加入search
和refresh
事件
async search() {
await this.getUserInfos()
},
async refresh() {
this.listQuery.page = 1
this.listQuery.limit = 20
this.listQuery.search = undefined
await this.getUserInfos()
}
新增弹窗编辑用户信息
我们给编辑按钮加上点击事件,点击后,进入到编辑用户信息表单
<el-dialog
title="编辑用户"
width="550px"
:visible.sync="dialogFrom"
:close-on-click-modal="false"
@close="cancelSubmit('userForm')"
>
<el-form ref="userForm" :inline="true" :rules="rules" :model="updateUserForm" size="small">
<el-form-item label="用户ID" prop="account">
<el-input v-model="updateUserForm.id" :disabled="true" style="width:120px" />
</el-form-item>
<el-form-item label="角色" prop="role">
<el-select v-model="updateUserForm.role" placeholder="请选择角色类型" style="width:120px">
<el-option
v-for="item in role"
:key="item.type"
:label="item.name"
:value="item.type"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" size="small" @click="addSubmit('userForm')">确定</el-button>
<el-button type="danger" size="small" @click="cancelSubmit('userForm')">取消</el-button>
</el-form-item>
</el-form>
这个弹窗我们用dialogFrom
进行来控制,如果dialogFrom=true
就弹窗表单,否则就不展示
点击编辑时,编辑事件代码 弹窗表单的确定按钮事件代码 取消按钮事件代码
src/views/user/index.vue
完整代码
<template>
<div class="app-container">
<el-card class="user-card">
<el-form ref="listQuery" size="small" :inline="true" :model="listQuery" class="demo-form-inline">
<el-form-item>
<el-input v-model="listQuery.search" style="width: 230px" clearable placeholder="请输入用户名" />
</el-form-item>
<el-form-item>
<div style="float: right;">
<el-button icon="el-icon-search" size="small" type="primary" @click="search()">查询</el-button>
<el-button icon="el-icon-refresh" size="small" @click="refresh('listQuery')">重置</el-button>
</div>
</el-form-item>
</el-form>
<div :style="{padding:'20px 0'}">
<el-table v-loading="listLoading" :data="lists" style="width: 100%" size="small">
<el-table-column align="center" type="index" label="序号" min-width="60px" />
<el-table-column align="center" prop="username" label="用户名" width="100px" />
<el-table-column align="center" prop="name" label="姓名" width="100px" />
<el-table-column align="center" prop="role" label="用户角色" width="120px">
<template slot-scope="{row}">
<el-tag
:type="row.role === 0 ? 'success' :
row.role === 1 ? 'warning' : ''"
effect="plain"
size="small"
disable-transitions
>{{ row.role | roleName }}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" prop="email" label="邮箱号" width="220px" />
<el-table-column align="center" prop="is_valid" label="是否冻结" width="120px">
<template slot-scope="{row}">
<el-switch
v-model="row.is_valid"
@change="userStateChaged(row)"
/>
</template>
</el-table-column>
<el-table-column align="center" prop="create_time" label="创建时间" width="150px" />
<el-table-column align="center" prop="last_login_time" label="上次登录时间" width="150px" />
<el-table-column fixed="right" align="center" label="操作" min-width="80px">
<template slot-scope="scope">
<el-button type="text" size="small" @click="editUser(scope.row)">编辑</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getUserInfos" />
</div>
</el-card>
<el-dialog
title="编辑用户"
width="550px"
:visible.sync="dialogFrom"
:close-on-click-modal="false"
@close="cancelSubmit('updateUserForm')"
>
<el-form ref="updateUserForm" :inline="true" :rules="rules" :model="updateUserForm" size="small">
<el-form-item label="用户ID" prop="id">
<el-input v-model="updateUserForm.id" :disabled="true" style="width:120px" />
</el-form-item>
<el-form-item label="角色" prop="role">
<el-select v-model="updateUserForm.role" placeholder="请选择角色类型" style="width:120px">
<el-option
v-for="item in role"
:key="item.type"
:label="item.name"
:value="item.type"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" size="small" @click="addSubmit('updateUserForm')">确定</el-button>
<el-button type="danger" size="small" @click="cancelSubmit('updateUserForm')">取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
</template>
<script>
import Pagination from '@/components/Pagination'
import { getUserList, updateUser } from '@/api/user'
export default {
name: 'UserIndex',
components: { Pagination },
filters: {
roleName(role) {
const roleMap = {
0: '普通用户',
1: '组长',
2: '超级管理员'
}
return roleMap[role]
}
},
props: {},
data() {
return {
total: 0,
lists: null,
listLoading: true,
dialogFrom: false,
listQuery: {
page: 1,
limit: 20,
search: undefined
},
updateUserForm: {
id: undefined,
is_valid: undefined,
role: undefined
},
role: [
{
type: 0,
name: '普通用户'
},
{ type: 1,
name: '组长'
},
{ type: 2,
name: '超级管理员'
}
],
rules: {
role: [
{ required: true, message: '请选择角色类型', trigger: 'change' }
],
id: [
{ required: true, message: '请输入用户id', trigger: 'blur' }
]
}
}
},
computed: {},
watch: {},
created() {
this.getUserInfos()
},
methods: {
async getUserInfos() {
this.listLoading = true
await getUserList(this.listQuery).then(response => {
this.lists = response.data.lists
this.total = response.data.total
this.listLoading = false
})
},
async userStateChaged(row) {
this.updateUserForm.id = row.id
this.updateUserForm.is_valid = row.is_valid
try {
const { msg } = await updateUser(this.updateUserForm)
this.$message({
message: msg,
type: 'success'
})
await this.getUserInfos()
} catch (e) {
await this.getUserInfos()
}
},
async search() {
await this.getUserInfos()
},
async refresh() {
this.listQuery.page = 1
this.listQuery.limit = 20
this.listQuery.search = undefined
await this.getUserInfos()
},
editUser(row) {
this.dialogFrom = true
this.updateUserForm.id = row.id
this.updateUserForm.role = row.role
},
async edit(formName) {
const { msg } = await updateUser(this.updateUserForm)
this.$message({
message: msg,
type: 'success'
})
this.cancelSubmit(formName)
await this.getUserInfos()
},
addSubmit(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.edit(formName)
}
})
},
cancelSubmit(formName) {
// 等页面刷新完之后,再执行回调函数中的方法,因为this.dialogFrom = false 它是异步的
this.$nextTick(() => {
this.dialogFrom = false
})
this.$refs[formName].resetFields()
}
}
}
</script>
<style>
.user-card {
width: 100%;
border-radius: 10px;
}
</style>
页面最终展示效果
后端项目修复bug及优化
DbUtils.update_model
修改一下,不然传过来的布尔值无法更新
UserDao
里主动抛出的异常,统一用NormalException
进行接收,@record_log
装饰器,如果不是主动抛出的异常,就记录详细日志信息
总结
今天进行了用户模块的前后端联调,我们的用户模块已经开发完毕,下期我们来进行项目管理的开发~
- 项目地址
- 今日已提交代码
- 后端:5b6986f
- 前端:bdaf447