前情提要
- 上一节讲解了如何用表格的形式来管理用户列表
- 这一节将要讲解用户管理功能的其它部分,用户的权限,组群,以及组群的权限
用户的权限
- 根据程序的设计,所有的用户在注册时都默认会有一个ROLE_USER的权限,现在可能需要给用户添加ROLE_ADMIN的权限,或者删除用户的ROLE_ADMIN权限
- 由于spring data rest本身是以url的形式给出了一个权限的所有者,不方便查看,所以需要将所有者具体的表示出来,这里用来的spring data rest为我们提供的Projection
- 在后端项目的kmhc.domain.user包中添加如下代码
package kmhc.domain.user;
import org.springframework.data.rest.core.config.Projection;
@Projection(name = "inlineUser", types = { Authority.class })
public interface AuthorityInlineUser {
Long getId();
String getAuthority();
User getUser();
}
- 有了这个类后,就可以使用inline的方式将权限的所有者显示出来
- 然后写前端代码,和用户本身设计一样,首先在views/admin下创建一个名叫Authority.vue的文件
<template>
<v-container fluid>
<v-row>
<v-col cols="12">
<v-data-table :headers="headers" :items="authorities" class="elevation-1">
<template v-slot:top>
<v-toolbar flat>
<v-toolbar-title>用户权限管理</v-toolbar-title>
<v-divider class="mx-4" inset vertical></v-divider>
<v-spacer></v-spacer>
<!--对话框,用于修改或者新建-->
<v-dialog v-model="dialog" max-width="600px">
<template v-slot:activator="{ on, attrs }">
<!--点击这个按钮的时候,将状态切换为创建-->
<v-btn color="primary" dark class="mb-2" v-bind="attrs" v-on="on" @click="state.create=true">
New Authority
</v-btn>
</template>
<v-card>
<v-card-title>
<span class="headline">{{ formTitle }}</span>
</v-card-title>
<v-card-text>
<v-form ref="authorityForm" v-model="valid" lazy-validation autocomplete="off">
<!--用户名-->
<v-row>
<v-col cols="12">
<v-text-field v-model="editedItem.user.id" :rules="rules.userRules" label="User"></v-text-field>
</v-col>
</v-row>
<!--权限名-->
<v-row>
<v-col cols="12">
<v-text-field v-model="editedItem.authority" :rules="rules.authorityRules" label="Authority"></v-text-field>
</v-col>
</v-row>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text @click="close">Cancel</v-btn>
<!--判断是创建还是删除-->
<v-btn v-if="state.create" :disabled="!valid" color="blue darken-1" text @click="create">Create</v-btn>
<v-btn v-if="state.update" :disabled="!valid" color="blue darken-1" text @click="update">Update</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<!--删除对话框,用以再次确认-->
<v-dialog v-model="dialogDelete" max-width="500px">
<v-card>
<v-card-title class="headline">Are you sure you want to delete this item?</v-card-title>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text @click="closeDelete()">Cancel</v-btn>
<v-btn color="blue darken-1" text @click="deleteItemConfirm()">OK</v-btn>
<v-spacer></v-spacer>
</v-card-actions>
</v-card>
</v-dialog>
</v-toolbar>
</template>
<template v-slot:item.actions="{ item }">
<v-icon small class="mr-2" @click="editItem(item)">
mdi-pencil
</v-icon>
<v-icon small @click="deleteItem(item)">
mdi-delete
</v-icon>
</template>
<template v-slot:no-data>
<v-btn color="primary" @click="initialize">
Reset
</v-btn>
</template>
</v-data-table>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
name: 'AuthorityAdmin',
data: () => ({
state: {
create: false,
update: false
},
valid: true,
dialog: false,
dialogDelete: false,
headers: [
{
text: 'User',
align: 'start',
sortable: false,
value: 'user.id'
},
{
text: 'Authority',
align: 'start',
sortable: false,
value: 'authority'
},
{
text: 'Actions',
value: 'actions',
sortable: false
}
],
authorities: [],
editedIndex: -1,
editedItem: {
user: {
id: 0
},
authority: ''
},
defaultItem: {
user: {
id: 0
},
authority: ''
},
rules: {
userRules: [
v => !!v || 'User is none!',
v => v > 0 || 'Please input a valid user id!'
],
authorityRules: [
v => !!v || 'Authority is none!'
]
}
}),
computed: {
formTitle () {
return this.editedIndex === -1 ? 'New Authority' : 'Edit Authority'
}
},
watch: {
dialog (val) {
val || this.close()
},
dialogDelete (val) {
val || this.closeDelete()
}
},
methods: {
initialize () {
// 获取全部用户权限(分页默认为10个一页)
this.axios.get('http://127.0.0.1:9001/api/authorities', {
params: {
projection: 'inlineUser'
}
})
.then(response => {
console.log(response)
// 设置用户权限列表
this.authorities = response.data._embedded.authorities
}).catch(error => {
console.log(error)
})
},
editItem (item) {
this.editedIndex = this.authorities.indexOf(item)
this.editedItem = Object.assign({}, item)
this.dialog = true
this.state.update = true
},
deleteItem (item) {
this.editedIndex = this.authorities.indexOf(item)
this.editedItem = Object.assign({}, item)
this.dialogDelete = true
},
deleteItemConfirm () {
const authority = this.authorities[this.editedIndex]
this.axios.delete(authority._links.self.href)
.then(response => {
console.log(response)
}).catch(error => {
console.log(error)
})
this.authorities.splice(this.editedIndex, 1)
this.closeDelete()
},
close () {
this.dialog = false
this.$nextTick(() => {
this.editedItem = Object.assign({}, this.defaultItem)
this.editedIndex = -1
})
this.state.create = false
this.state.update = false
},
closeDelete () {
this.dialogDelete = false
this.$nextTick(() => {
this.editedItem = Object.assign({}, this.defaultItem)
this.editedIndex = -1
})
},
create () {
const valid = this.$refs.authorityForm.validate()
if (valid) {
this.axios.post('http://127.0.0.1:9001/api/authorities', {
user: 'http://127.0.0.1:9001/users/' + this.editedItem.user.id,
authority: this.editedItem.authority
}
).then(response => {
console.log(response)
this.initialize()
}).catch(error => {
console.log(error)
})
this.close()
}
},
update () {
const valid = this.$refs.authorityForm.validate()
if (valid) {
const authority = this.authorities[this.editedIndex]
this.axios.patch(authority._links.self.href, {
user: 'http://127.0.0.1:9001/users/' + this.editedItem.user.id,
authority: this.editedItem.authority
}
).then(response => {
console.log(response)
this.initialize()
}).catch(error => {
console.log(error)
})
this.close()
}
}
},
created () {
this.initialize()
}
}
</script>
- 然后为Authority.vue添加一个路由
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
},
{
// 登录视图
path: '/login',
name: 'Login',
component: () => import('../views/Login.vue')
},
{
// 注册视图
path: '/register',
name: 'Register',
component: () => import('../views/Register.vue')
},
{
// 用户基本信息后台管理
path: '/admin/users',
name: 'UserAdmin',
component: () => import('../views/admin/User.vue')
},
{
// 用户权限后台管理
path: '/admin/authorities',
name: 'AuthorityAdmin',
component: () => import('../views/admin/Authority.vue')
}
]
const router = new VueRouter({
routes
})
export default router
测试用户权限管理功能
- 添加一个用户权限
- 修改一个用户权限
- 删除一个用户权限
组群和组群权限
- 这一部分和用户权限相似,请读者仿照代码自行完成,加强理解
- 代码已上传至我的gitee仓库,请自行查看
更多
- 这个后台管理系统还有很多美中不足的地方,只是一个简单的样例,希望读者们能够查阅资料,并结合以前学过的知识自行补全
至此,一个简单的后台管理系统的基本内容已讲解完毕,下一节会讲解如何部署这个系统到线上