vue+springmvc前后端分离开发(十七)(在前端补全用户管理功能)

前情提要

  • 上一节讲解了如何用表格的形式来管理用户列表
  • 这一节将要讲解用户管理功能的其它部分,用户的权限,组群,以及组群的权限

用户的权限

  • 根据程序的设计,所有的用户在注册时都默认会有一个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仓库,请自行查看

更多

  • 这个后台管理系统还有很多美中不足的地方,只是一个简单的样例,希望读者们能够查阅资料,并结合以前学过的知识自行补全

至此,一个简单的后台管理系统的基本内容已讲解完毕,下一节会讲解如何部署这个系统到线上

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值