Vue实战电商系统-四权限管理

news/2024/7/10 1:47:04 标签: vue

Vue实战电商系统-四权限管理

  • 四.权限管理
    • 1.权限管理-用户列表
        • 1.新建分支并推送
        • 2.新建rights.vue并配置路由
        • 3.权限管理-权限列表的页面布局
        • 4.数据获取并渲染
        • *5.权限等级筛选
    • 2.权限管理业务逻辑分析
    • 3.权限管理-角色管理
        • 1.新建roles.vue并配置路由
        • 3.权限管理-角色列表的页面布局
        • 4.数据获取并渲染
        • 5.展开行内容填充
        • 6.增加角色,编辑角色,删除角色
        • 7.权限标签的删除
        • 8.分配权限功能
    • 4.用户管理-用户列表
    • 5.上传代码

四.权限管理

1.权限管理-用户列表

1.新建分支并推送

在开发一个新功能模块之前,首先要创建一个新分支rights并把它推送到码云上的云端仓库中。

首先检查一下当前是否处于主分支master

git branch

接着创建一个新分支rights(权限管理)切换到新分支

git checkout -b rights

检查:

git branch

进行推送:

git push -u origin rights

完成之后,就可以进行代码的编写了(此时的分支应该是处于新建分支rights上面)。

vue_27">2.新建rights.vue并配置路由

rights.vue

<template>
  <div>
    <h2>权限列表</h2>
  </div>
</template>

<script>

export default {

}
</script>

<style></style>

配置路由:

import Rights from '../components/power/Rights.vue'
...
{
	  ...
      path: '/home',
      component: Home,
      redirect: '/welcome',
      children: [
        ...
        {
          path: '/rights',
          component: Rights
        }
      ]
    }

3.权限管理-权限列表的页面布局

权限管理-权限列表的页面布局和用户管理-用户列表的布局类似,最上方的面包屑导航然后卡片视图,在卡片视图里面是一张表格。这些基本组件在之前都用过直接复制粘贴就完事了。

4.数据获取并渲染

直接贴代码,rights.vue

<template>
    <div>
        <!-- 面包屑导航区域 -->
        <el-breadcrumb separator="/">
            <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item>权限管理</el-breadcrumb-item>
            <el-breadcrumb-item>权限列表</el-breadcrumb-item>
        </el-breadcrumb>
        <!-- 卡片视图区域 -->
        <el-card>
            <el-table :data="rightslist" style="width: 100%" border stripe :cell-style="rowClass" :header-cell-style="headClass">
                <el-table-column type="index" label="#"></el-table-column>
                <el-table-column prop="authName" label="权限名称"></el-table-column>
                <el-table-column prop="path" label="路径"></el-table-column>
                <el-table-column label="权限等级">
                    <template slot-scope="scope">
                        <el-tag :type="rightslevellist[scope.row.level].type">{{rightslevellist[scope.row.level].text}}</el-tag>
                    </template>
                </el-table-column>
            </el-table>
        </el-card>
    </div>
</template>

<script>

export default {
  data() {
    return {
      // 存放权限列表的数据
      rightslist: [],
      // 权限等级对应的标签栏的映射
      rightslevellist: [
        { level: 0, type: 'none', text: '一级' },
        { level: 1, type: 'success', text: '二级' },
        { level: 2, type: 'warning', text: '三级' }
      ]
    }
  },
  created() {
    this.getRightsList()
  },
  methods: {
    // 获取权限列表
    async getRightsList() {
      const { data: res } = await this.$http.get('rights/list')
      console.log(res)
      if (res.meta.status !== 200) return this.$message.error('获取权限列表失败!')
      this.rightslist = res.data
    },
    // 表头样式设置
    headClass () {
      return 'text-align: center;'
    },
    // 表格样式设置
    rowClass () {
      return 'text-align: center;'
    }
  }
}
</script>

<style></style>

在渲染标签栏时除了上面采用的方法以外:

<template slot-scope="scope">
   <el-tag :type="rightslevellist[scope.row.level].type">{{rightslevellist[scope.row.level].text}}</el-tag>
</template>

还可以用v-ifv-else-if以及v-else标签来完成:

<template slot-scope="scope">
   <el-tag v-if="scope.row.level === '0'">一级</el-tag>
   <el-tag type="success" v-else-if="scope.row.level === '1'">二级</el-tag>
   <el-tag type="warning" v-else>三级</el-tag>
</template>

因为获取到的level字段是数值,但是在表格中显示的是Tag标签,因此做一个列表映射,说明每一个等级对应的Tag标签颜色(type)以及对应的标签文字说明(一级,二级,三级)。其实整体逻辑是跟主页home.vue侧边导航栏菜单数据获取是一样的。

*5.权限等级筛选

在表格的最后一列显示的是权限等级标签,当权限数据很多的时候筛选权限等级会非常有必要。

筛选的方法在elementUI-table表格筛选实现。

在要筛选的列上添加属性filter-methodfilters,代码如下::

<el-table-column label="权限等级"
  :filters="[{ text: '一级', value: '0' }, { text: '二级', value: '1' }, { text: '三级', value: '2' }]"
  :filter-method="rightsLevelfilterTag"
  filter-placement="bottom-end">
    <template slot-scope="scope">
        <!-- <el-tag :type="rightslevellist[scope.row.level].type">{{rightslevellist[scope.row.level].text}}</el-tag> -->
        <el-tag v-if="scope.row.level === '0'">一级</el-tag>
        <el-tag type="success" v-else-if="scope.row.level === '1'">二级</el-tag>
        <el-tag type="warning" v-else>三级</el-tag>
    </template>
</el-table-column>
...
methods: {
  // 自定义筛选不同的权限等级
  rightsLevelfilterTag(value, row) {
    return row.level === value
  }
}

2.权限管理业务逻辑分析

在电商后台管理系统中,不同的账户对应着不同级别的管理员。就类似于在某一些购物APP中,对于商品管理这个模块,如果你开了一个店铺那你可以进行对自己的商品进行增删改查,但是普通的用户就无法进行增删改,这就是不同角色对应的不同权限
在用户和权限之间如果直接寻找关系会比较错乱复杂,因此引入角色这样一个中间元素作为桥梁权限分配到角色上,每个角色都拥有不同的权限,同时账户对应的角色有哪些,就具有哪些权限。

3.权限管理-角色管理

vue_188">1.新建roles.vue并配置路由

roles.vue

<template>
  <div>
    <h2>角色列表</h2>
  </div>
</template>

<script>

export default {

}
</script>

<style></style>

配置路由:

import Rolesfrom '../components/power/Roles.vue'
...
{
	  ...
      path: '/home',
      component: Home,
      redirect: '/welcome',
      children: [
        ...
        {
          path: '/roles',
          component: Roles
        }
      ]
    }

3.权限管理-角色列表的页面布局

权限管理-角色列表的页面布局懂得都懂,直接复制粘贴就完事了。

4.数据获取并渲染

roles.vue

<template>
    <div>
        <!-- 面包屑导航区域 -->
        <el-breadcrumb separator="/">
            <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item>权限管理</el-breadcrumb-item>
            <el-breadcrumb-item>角色列表</el-breadcrumb-item>
        </el-breadcrumb>
        <!-- 卡片视图区域 -->
        <el-card>
            <el-row>
                <el-col :span="4">
                    <el-button type="primary">添加角色</el-button>
                </el-col>
            </el-row>
            <el-table :data="roleslist" style="width: 100%" border stripe :cell-style="rowClass" :header-cell-style="headClass">
                <!-- 展开列 -->
                <el-table-column type="expand"></el-table-column>
                <!-- 索引列 -->
                <el-table-column type="index" label="#"></el-table-column>
                <el-table-column prop="roleName" label="角色名称"></el-table-column>
                <el-table-column prop="roleDesc" label="角色描述"></el-table-column>
                <el-table-column label="操作" width="300px">
                    <template slot-scope="scope">
                        <el-button type="primary" icon="el-icon-edit" size="mini">编辑</el-button>
                        <el-button type="danger" icon="el-icon-delete" size="mini">删除</el-button>
                        <el-button type="warning" icon="el-icon-setting" size="mini">分配权限</el-button>
                    </template>
                </el-table-column>
            </el-table>
        </el-card>
    </div>
</template>

<script>

export default {
  data() {
    return {
      // 所有角色列表数据
      roleslist: []
    }
  },
  created() {
    this.getRolesList()
  },
  methods: {
    // 获取角色列表信息
    async getRolesList() {
      const { data: res } = await this.$http.get('roles')
      console.log(res)
      if (res.meta.status !== 200) return this.$message.error('获取角色列表失败!')
      this.roleslist = res.data
    },
    // 表头样式设置
    headClass () {
      return 'text-align: center;'
    },
    // 表格样式设置
    rowClass () {
      return 'text-align: center;'
    }
  }
}
</script>

<style></style>

在表格的第一列是一个展开效果,点击>图标即可展开该角色对应的一级权限,二级权限等等详情

5.展开行内容填充

<!-- 展开列 -->
<el-table-column type="expand">
    <template slot-scope="scope">
        <el-row :class="['bdbottom', index1 === 0 ? 'bdtop' : '']" v-for="(item1,index1) in scope.row.children" :key="item1.id">
            <!-- 渲染一级权限 -->
            <el-col :span="5">
                <el-tag>{{item1.authName}}</el-tag>
                <i class="el-icon-caret-right"></i>
            </el-col>
            <!-- 渲染二级和三级权限 -->
            <el-col :span="19">
                <!-- 嵌套渲染二级权限 -->
                <el-row :class="[index2 === 0 ? '' : 'bdtop']" v-for="(item2,index2) in item1.children" :key="item2.id">
                    <el-col :span="6">
                        <el-tag type="success">{{item2.authName}}</el-tag>
                        <i class="el-icon-caret-right"></i>
                    </el-col>
                    <el-col :span="18">
                        <el-tag type="warning" v-for="(item3,index3) in item2.children" :key="item3.id">{{item3.authName}}</el-tag>
                    </el-col>
                </el-row>
            </el-col>
        </el-row>
    </template>
</el-table-column>
...
<style>
.el-tag {
  margin: 8px;
}
.bdtop {
  border-top: 1px solid #eee;
}
.bdbottom {
  border-bottom: 1px solid #eee;
}
</style>

最终的实现效果如下图:
权限管理-角色管理
界面显示优化

1.当打开控制台缩小页面时,可能会出现宽度不够导致界面元素错乱,解决办法:在global.css中添加min-width属性。如下所示:

html,body,#app {
    height: 100%;
    margin: 0;
    padding: 0;
    min-width: 1366px; //指定屏幕最小宽度
}

2.在一级权限(商品管理,订单管理,权限管理等)标签的位置没有处于垂直居中。解决办法:

.vcenter {
  display: flex;
  align-items: center;
}

然后给需要居中的一级权限和二级权限的标签所在行el-row加上该样式即可。

6.增加角色,编辑角色,删除角色

在角色列表中的增加角色,编辑角色,删除角色这些功能和用户列表的增删改基本相同,复制粘贴就完事了。

7.权限标签的删除

首先为三级权限tag标签添加可删除的属性closable
接着绑定方法,编写代码:

...
<el-tag type="warning" v-for="(item3,index3) in item2.children" :key="item3.id" closable @close="deleteRightsById(scope.row, item3.id)">{{item3.authName}}</el-tag>
...
// 点击标签的删除按钮移除对应权限
async deleteRightsById(role, rightid) {
  const confirmResult = await this.$confirm('确定将此权限从该角色中移除吗', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).catch(err => err)
  console.log(confirmResult)
  if (confirmResult !== 'confirm') {
    return this.$message.info('已取消操作')
  }
  const { data: res } = await this.$http.delete(`roles/${role.id}/rights/${rightid}`)
  console.log(res)
  if (res.meta.status !== 200) return this.$message.error('移除权限失败')
  this.$message.success('移除权限成功')
  // 重新拉取用户信息列表
  this.getRolesList()
}

但是,在这里存在一个不完美的地方,就是每次移除完角色权限后展开行(展开区域)会被重新合上,非常不友好。因此,为了避免这种情况,在最后一步重新拉取用户信息列表的地方,把this.getRolesList()改成role.children = res.data,因为调用删除的接口后,在返回的数据中除了状态码还把最新的权限数据(执行移除后的数据)封装在data中了,直接赋值就可以,直接赋值就避免了重新渲染整个页面

最后一步就是把 closable @close="deleteRightsById(scope.row, item3.id)"复制一遍给一级权限标签和二级权限标签就行了,注意要把对应的权限id(item3.id)改掉

8.分配权限功能

和增加用户这类差不多,点击事件,弹出对话框,获取数据,渲染数据,提交数据…只贴主要代码:

// 展示分配权限的对话框
async showSetRightDialog() {
  // 在对话框显示之前获取到全部权限的数据用于树状显示
  const { data: res } = await this.$http.get('rights/tree')
  if (res.meta.status !== 200) return this.$message.error('获取权限数据失败')
  // 把获取到的权限数据保存到data中
  this.rightslist = res.data
  console.log(this.rightslist)
  this.setRightDialogVisible = true
}

然后就是在对话框中渲染出树形的权限数据

<!-- 树形控件 -->
<el-tree
  :data="rightslist"
  :props="treetProps"
  show-checkbox
  // node-key,每个树节点用来作为唯一标识的属性,也就是说当我选中该节点我想要选中的并不是该文本而是它的权限id号
  node-key="id"
  // 默认展开全部节点
  :default-expand-all="true">
</el-tree>
...
// 在data域中定义以下两个属性
// 权限列表的树形数据
rightslist: [],
// 树形控件的属性绑定对象
treetProps: {
  // 在树形控件中父子间的嵌套关系用哪个字段来表示
  children: 'children',
  // 在树形控件中的文字显示的是哪个字段
  label: 'authName'
}

最关键的其实还是将该角色已有的权限加载在树形控件上

<el-dialog
  title="分配权限"
  :visible.sync="setRightDialogVisible"
  width="40%"
  @close="setRightDialogClosed">
<el-tree
  :data="rightslist"
  :props="treetProps"
  show-checkbox
  node-key="id"
  :default-expand-all="true"
  // default-checked-keys,已经被选中的几个节点
  :default-checked-keys="defKeys">
</el-tree>
<span slot="footer" class="dialog-footer">
  <el-button @click="setRightDialogVisible = false">取 消</el-button>
  <el-button type="primary" @click="setRightDialogVisible = false">确 定</el-button>
</span>
</el-dialog>
...
// 实现逻辑就是将该角色的所拥有三级权限的id获取到并保存在一个数组中
async showSetRightDialog(role) {
  // 在对话框显示之前获取到全部权限的数据用于树状显示
  const { data: res } = await this.$http.get('rights/tree')
  if (res.meta.status !== 200) return this.$message.error('获取权限数据失败')
  // 把获取到的权限数据保存到data中
  this.rightslist = res.data
  console.log(this.rightslist)
  // 递归获取三级权限的id
  this.getLeafKeys(role, this.defKeys)
  this.setRightDialogVisible = true
},
// 通过递归的形式,获取角色下所拥有的三级权限的id并保存到数组 defKeys 中
getLeafKeys(node, arr) {
  // 如果当前节点不包含children属性,说明该节点是三级权限节点,即是角色所拥有的权限
  if (!node.children) {
    return arr.push(node.id)
  }
  // 如果还不是三级节点那么就继续进行递归
  node.children.forEach(item => {
    this.getLeafKeys(item, arr)
  })
}
// 关闭分配权限的弹出框时要清空存放三级权限的数据列表
setRightDialogClosed() {
  this.defKeys = []
}

在树形控件中分配权限需要用到控件的两个方法,getCheckedKeysgetHalfCheckedKeys。作用分别是返回目前被选中的节点的 key 所组成的数组以及返回目前半选中的节点的 key 所组成的数组

逻辑代码如下:

// 点击确定为角色分配新的权限
async allotRights() {
  const keys = [...this.$refs.treeRef.getCheckedKeys(), ...this.$refs.treeRef.getHalfCheckedKeys()]
  const idStr = keys.join(',')
  const { data: res } = await this.$http.post(`roles/${this.roleId}/rights`, { rids: idStr })
  console.log(res)
  if (res.meta.status !== 200) return this.$message.error('更新权限失败')
  this.$message.success('更新权限成功')
  // 更新权限完成之后需要重新刷新一遍角色列表
  this.getRolesList()
  // 关闭分配权限对话框
  this.setRightDialogVisible = false
}

4.用户管理-用户列表

之前在做用户管理部分的时候,还剩下一个分配角色功能没做。现在角色功能已经完成了,所以回过头去做分配角色功能模块。

<!-- 分配角色对话框 -->
<el-dialog
  title="分配角色"
  :visible.sync="setRolesdialogVisible"
  width="40%"
  @close="setRolesDialogClosed">
  <div>
    <p>当前用户 : {{ userInfo.username }}</p>
    <p>当前角色 : {{ userInfo.role_name }}</p>
    <p>分配新角色 :
      <el-select v-model="newRolesid" placeholder="请选择">
        <el-option
          v-for="item in roleslist"
          :key="item.id"
          :label="item.roleName"
          :value="item.id">
        </el-option>
      </el-select>
    </p>
  </div>
  <span slot="footer" class="dialog-footer">
      <el-button @click="setRolesdialogVisible = false">取 消</el-button>
      <el-button type="primary" @click="saveRolesInfo">确 定</el-button>
  </span>
</el-dialog>
...
// 展示分配角色的对话框
async setRoles(userInfo) {
  this.userInfo = userInfo
  // 在展示对话框之前获取所有可以分配的角色列表
  const { data: res } = await this.$http.get('roles')
  this.roleslist = res.data
  if (res.meta.status !== 200) return this.$message.error('获取角色列表失败')
  this.setRolesdialogVisible = true
},
setRolesDialogClosed() {
  // 当对话框关闭时要清空上一次选择的新分配的角色id
  this.newRolesid = ''
  // 当对话框关闭时要清空上一次要分配角色的用户数据对象
  this.userInfo = {}
},
async saveRolesInfo() {
  // 先要判断是否选择了新角色
  if (!this.newRolesid) {
    return this.$message.error('请选择要分配的新角色!')
  }
  const { data: res } = await this.$http.put(`users/${this.userInfo.id}/role`, { rid: this.newRolesid })
  this.roleslist = res.data
  if (res.meta.status !== 200) return this.$message.error('分配用户角色失败')
  this.$message.success('分配用户角色成功')
  // 分配完角色后重新获取一遍用户数据
  this.getUserList()
  this.setRolesdialogVisible = false
}

5.上传代码

git branch
git add .
git commit -m '完成权限管理功能'
git push
git checkout master
git merge rights
git push

http://www.niftyadmin.cn/n/909591.html

相关文章

最为精辟和实用的按键处理程序

新型的按键扫描程序 不过我在网上游逛了很久&#xff0c;也看过不少源程序了&#xff0c;没有发现这种按键处理办法的踪迹&#xff0c;所以&#xff0c;我将他共享出来&#xff0c;和广大同僚们共勉。我非常坚信这种按键处理办法的便捷和高效&#xff0c;你可以移植到任何一种嵌…

Vue实战电商系统-五商品管理

Vue实战电商系统-五商品管理商品管理1.新建goods_cate子分支并上传码云2.商品管理-商品分类1.新建文件并配置路由2.页面布局3.获取分类列表数据4.将数据渲染在树形表格控件中5.实现分页6.添加分类7.删除分类8.编辑分类3.商品管理-分类参数1.页面布局2.获取所有分类参数列表(级联…

Vue实战电商系统-七.数据统计

Vue实战电商系统-七.数据统计数据统计1.基本页面布局和路由配置2.安装Echarts并渲染图表3.获取折线图数据统计 1.基本页面布局和路由配置 同之前的一样就不说了。 2.安装Echarts并渲染图表 1.首先在可视化面板中安装运行依赖Echarts。 2.接着按照Echarts教程进行布局使用。…

函数的声明与定义

1.简介 函数定义&#xff1a;用于确定函数功能&#xff0c;一个完整的函数定义包括函数名称&#xff0c;形参类型&#xff0c;函数体等。 函数声明&#xff1a;C语言编译系统是由上往下编译的&#xff0c;如果被调函数A放在主调函数B后面&#xff0c;则需要声明函数A&#xff0…

滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(10月8日~10月11日)...

活动时间&#xff1a;2015年10月8日~2015年10月10日 更新日期&#xff1a;2015年10月8日 滴滴快车单单2.5倍&#xff0c;注册地址&#xff1a;http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单&#xff1a;http://www.cnblogs.com/mfryf/p…

基于网易云音乐API的微信小程序——网愈芸音乐

网愈芸音乐一.项目说明二.项目环境准备三.项目初始化1.新建项目2.安装依赖Vant Weapp&#xff0c;构建NPM四.项目具体开发过程1.欢迎页面(首页)&#xff1a;2.登陆页面1.界面设计2.逻辑分析3.MV页面1.界面设计2.逻辑分析4.音乐页面1.界面设计2.逻辑分析5.歌单页面1.界面设计2.拓…

Oracle笔记 二、常用dba命令行

1、给用户解锁 alter user scott account unlock; 2、注销、断开、切换当前用户连接 quit conn scott/tiger 3、用户权限查询 A .查看所有用户&#xff1a; select * from dba_users; select * from all_users; select * from user_users; B.查看用户或角色系统权限(直接赋值给…

个人前端面试题目总结(未工作)

个人前端面试题目总结个人前端面试题目总结(未工作)形式&#xff1a;电话面试面试内容不完全记录&#xff1a;关于React关于Vue*1.vue中数据双向绑定的原理*2.vue中的MVVM模式ES6中有哪些新特性1.const&#xff0c;let2.模板字符串(字符串的拼接)3.箭头函数4.函数参数的默认值5…