• Vue项目实战之人力资源平台系统(十一)权限管理模块(上)


    前言

    一、权限管理的设计思想

    我们项目使用的是RBAC的权限模型,RBAC(Role-Based Access control) ,也就是基于角色的权限分配解决方案,相对于传统方案,RBAC提供了中间层Role(角色),其权限模式如下:
    在这里插入图片描述

    RBAC实现了用户和权限点的分离,想对某个用户设置权限,只需要对该用户设置相应的角色即可,而该角色就拥有了对应的权限,这样一来,权限的分配和设计就做到了极简,高效,当想对用户收回权限时,只需要收回角色即可

    二、给员工分配角色

    2.1 分配角色弹窗效果图

    在这里插入图片描述

    2.1 新建分配角色对话框组件

    用户和角色是1对多的关系,即一个用户可以拥有多个角色
    在src/views/employees/components/目录下新建assign-role.vue组件:

    <template>
      <el-dialog title="分配角色" :visible="showRoleDialog">
        <!-- el-checkbox-group选中的是 当前用户所拥有的角色  需要绑定 当前用户拥有的角色-->
        <el-checkbox-group>
          <!-- 选项 -->
        </el-checkbox-group>
        <el-row slot="footer" type="flex" justify="center">
          <el-col :span="6">
            <el-button type="primary" size="small">确定</el-button>
            <el-button size="small">取消</el-button>
          </el-col>
        </el-row>
      </el-dialog>
    </template>
    
    <script>
    export default {
      props: {
        showRoleDialog: {
          type: Boolean,
          default: false
        }
      }
    }
    </script>
    

    2.2 获取角色列表

    在src/views/employees/components/assign-role.vue中添加如下代码:

      <!-- 分配角色 -->
        <el-checkbox-group v-model="roleIds">
          <el-checkbox v-for="item in list" :key="item.id" :label="item.id">
            {{
              item.name
            }}
          </el-checkbox>
        </el-checkbox-group>
    
    import { getRoleList } from '@/api/setting'
    
    export default {
      props: {
        showRoleDialog: {
          type: Boolean,
          default: false
        },
        userId: {
          type: String,
          default: null
        }
      },
      data() {
        return {
          list: [], // 角色列表
        }
      },
      created() {
        this.getRoleList()
      },
      methods: {
        //  获取所有角色
        async getRoleList() {
          const { rows } = await getRoleList()
          this.list = rows
        }
      }
    }
    

    2.3 获取当前用户的角色信息

    首先,在src/views/employees/components/assign-role.vue中定义获取角色信息的方法:

    import { getUserDetailById } from '@/api/user'
    
    async getUserDetailById(id) {
          const { roleIds } = await getUserDetailById(id)
          this.roleIds = roleIds // 赋值本用户的角色
      }
    

    然后,在src/views/employees/index.vue中调用子组件方法:

    <el-button type="text" size="small" @click="editRole(row.id)">角色</el-button>
    
    
    <!-- 放置角色分配组件 -->
    <assign-role ref="assignRole" :show-role-dialog.sync="showRoleDialog" :user-id="userId" />
    
    
    // 编辑角色
    async  editRole(id) {
          this.userId = id // props传值 是异步的
          await this.$refs.assignRole.getUserDetailById(id) // 父组件调用子组件方法
          this.showRoleDialog = true
        },
    

    2.4 点击确定按钮给用户分配角色

    首先,在src/api/employees.js中封装分配角色的请求:

    /** *
    * 给用户分配角色
    * ***/
    export function assignRoles(data) {
      return request({
        url: '/sys/user/assignRoles',
        data,
        method: 'put'
      })
    }
    

    然后,在src/views/employees/components/assign-role.vue中绑定按钮点击事件:

    <el-button type="primary" size="small" @click="btnOK">确定</el-button>
    <el-button size="small" @click="btnCancel">取消</el-button>
    
    
    async btnOK() {
          await assignRoles({ id: this.userId, roleIds: this.roleIds })
          //   关闭窗体
          this.$emit('update:showRoleDialog', false)
        },
    
    //点击取消或关闭对话框时调用
    btnCancel() {
          this.roleIds = [] // 清空原来的数组
          this.$emit('update:showRoleDialog', false)
        }
    

    三、权限管理页面

    3.1 权限管理页面效果图

    在这里插入图片描述

    3.2 权限管理页面的基础布局

    在src/views/permission/index.vue中添加如下代码:

    <template>
      <div class="dashboard-container">
        <div class="app-container">
          <!-- 靠右的按钮 -->
          <page-tools>
            <template v-slot:after>
              <el-button type="primary" size="small">添加权限</el-button>
            </template>
          </page-tools>
          <!-- 表格 -->
          <el-table border>
            <el-table-column align="center" label="名称" />
            <el-table-column align="center" label="标识" />
            <el-table-column align="center" label="描述" />
            <el-table-column align="center" label="操作">
              <template>
                <el-button type="text">添加</el-button>
                <el-button type="text">编辑</el-button>
                <el-button type="text">删除</el-button>
              </template>
            </el-table-column>
    
    
          </el-table>
        </div>
      </div>
    </template>
    

    3.3 封装权限管理相关请求

    在src/api/permisson.js中添加如下代码:

    // 获取权限
    export function getPermissionList(params) {
      return request({
        url: '/sys/permission',
        params
      })
    }
    // 新增权限
    export function addPermission(data) {
      return request({
        url: '/sys/permission',
        method: 'post',
        data
      })
    }
    
    // 更新权限
    export function updatePermission(data) {
      return request({
        url: `/sys/permission/${data.id}`,
        method: 'put',
        data
      })
    }
    
    // 删除权限
    export function delPermission(id) {
      return request({
        url: `/sys/permission/${id}`,
        method: 'delete'
      })
    }
    // 获取权限详情
    export function getPermissionDetail(id) {
      return request({
        url: `/sys/permission/${id}`
      })
    }
    

    3.4 获取权限数据

    我们通过树形操作方法,将列表转化成层级数据,这里需要给el-table配置row-key属性 id才可显示树形结构
    在src/views/permission.js中添加如下代码:

            <el-table :data="list" border="" row-key="id">
              <el-table-column label="名称" prop="name" />
              <el-table-column label="标识" prop="code" />
              <el-table-column label="描述" prop="description" />
              <el-table-column label="操作">
                <template slot-scope="{ row }">
                  <el-button type="text" >添加</el-button>
                  <el-button type="text" >编辑</el-button>
                  <el-button type="text" >删除</el-button>
                </template>
              </el-table-column>
            </el-table>
    
    <script>
    import { getPermissionList } from '@/api/permission'
    import { transListToTreeData } from '@/utils'
    export default {
    data() {
        return {
          list: [],
        }
      },
      created() {
        this.getPermissionList()
      },
      methods: {
        async  getPermissionList() {
          this.list = transListToTreeData(await getPermissionList(), '0')
        }
      }
    }
    </script>
    

    3.5 新增、编辑和删除权限

    在src/views/permission.js中新建新增和编辑权限对话框:

       <!-- 靠右的按钮 -->
       <page-tools>
         <template v-slot:after>
            <el-button type="primary" size="small" @click="addPermission(1, '0')">添加权限</el-button>
         </template>
       </page-tools>
    
       <!-- 添加按钮只在 访问权的层级显示 当type==1 时才显示添加按钮 -->
       <el-button v-if="row.type === 1" type="text" @click="addPermission(2, row.id)">添加</el-button>
       <el-button type="text" @click="editPermission(row.id)">编辑</el-button>
       <el-button type="text" @click="delPermission(row.id)">删除</el-button>  
    
       <!-- 放置一个弹层 用来编辑新增节点 -->
       <el-dialog :title="`${showText}权限点`" :visible="showDialog" @close="btnCancel">
          <!-- 表单 -->
          <el-form ref="perForm" :model="formData" :rules="rules" label-width="120px">
            <el-form-item label="权限名称" prop="name">
              <el-input v-model="formData.name" style="width:90%" />
            </el-form-item>
            <el-form-item label="权限标识" prop="code">
              <el-input v-model="formData.code" style="width:90%" />
            </el-form-item>
            <el-form-item label="权限描述">
              <el-input v-model="formData.description" style="width:90%" />
            </el-form-item>
            <el-form-item label="开启">
              <el-switch
                v-model="formData.enVisible"
                active-value="1"
                inactive-value="0"
              />
            </el-form-item>
          </el-form>
          <el-row slot="footer" type="flex" justify="center">
            <el-col :span="6">
              <el-button size="small" type="primary" @click="btnOK">确定</el-button>
              <el-button size="small" @click="btnCancel">取消</el-button>
            </el-col>
          </el-row>
      </el-dialog>
    

    绑定数据:

    import { updatePermission, addPermission, getPermissionDetail, delPermission, getPermissionList } from '@/api/permission'
    
      data() {
        return {
          list: [],
          showDialog: false,
          formData: {
            name: '', // 名称
            code: '', // 标识
            description: '', // 描述
            type: '', // 类型 该类型 不需要显示 因为点击添加的时候已经知道类型了
            pid: '', // 因为做的是树 需要知道添加到哪个节点下了
            enVisible: '0' // 开启
          },
          rules: {
            name: [{ required: true, message: '权限名称不能为空', trigger: 'blur' }],
            code: [{ required: true, message: '权限标识不能为空', trigger: 'blur' }]
          }}
      },
      computed: {
        showText() {
          return this.formData.id ? '编辑权限' : '新增权限'
        }
      },
      methods: {
        delPermission(id) {
          this.$confirm('确认删除该权限点吗').then(() => {
            return delPermission(id)
          }).then(() => {
            this.$message.success('删除成功')
            // 重新拉取数据
            this.getPermissionList()
          })
        },
    
        addPermission(type, pid) {
          // 访问权的type = 1  按钮操作的权type =2
          // pid表示当前数据的父节点的标识
          // 记录当前添加的类型和父标识
          this.formData.type = type
          this.formData.pid = pid
          this.showDialog = true
        },
    
        async  editPermission(id) {
          this.formData = await getPermissionDetail(id)
          this.showDialog = true
        }
    
        btnOK() {
          this.$refs.permForm.validate().then(() => {
            // 校验成功
            if (this.formData.id) {
              // 认为是编辑
              return updatePermission(this.formData)
            }
            return addPermission(this.formData) // 新增接口
          }).then(() => {
            // 添加成功
            this.$message.success('操作成功')
            this.getPermissionList()
            this.showDialog = false
          })
        },
    
        btnCancel() {
          // 重置数据
          this.formData = {
            name: '', // 名称
            code: '', // 标识
            description: '', // 描述
            type: '', // 类型 该类型 不需要显示 因为点击添加的时候已经知道类型了
            pid: '', // 因为做的是树 需要知道添加到哪个节点下了
            enVisible: '0' // 开启
          }
          // 移除校验
          this.$refs.permForm.resetFields() // 移除校验
          this.showDialog = false
        },
      }
    

    四、给角色分配权限

    4.1 分配权限效果图

    在这里插入图片描述

    4.2 封装分配权限的请求

    在src/api/setting.js中添加如下代码:

    // 给角色分配权限
    export function assignPerm(data) {
      return request({
        url: '/sys/role/assignPrem',
        method: 'put',
        data
      })
    }
    

    4.3 新建分配权限弹窗

    在src/views/settings/index.vue中添加弹窗基本布局:

    <!-- 点击分配权限按钮 -->   
    <el-button size="small" type="success" @click="assignPerm(row.id)">分配权限</el-button>
    
        <!-- 放置一个弹层 -->
        <el-dialog title="分配权限" :visible="showPermDialog" @close="btnPermCancel">
          <!-- 权限是一颗树 -->
          <!-- 将数据绑定到组件上 -->
          <!-- check-strictly 如果为true 那表示父子勾选时  不互相关联 如果为false就互相关联 -->
          <!-- id作为唯一标识 -->
          <el-tree
            ref="permTree"
            :data="permData"
            :props="defaultProps"
            :show-checkbox="true"
            :check-strictly="true"
            :default-expand-all="true"
            :default-checked-keys="selectCheck"
            node-key="id"
          />
          <!-- 确定 取消 -->
          <el-row slot="footer" type="flex" justify="center">
            <el-col :span="6">
              <el-button type="primary" size="small" @click="btnPermOK">确定</el-button>
              <el-button size="small" @click="btnPermCancel">取消</el-button>
            </el-col>
          </el-row>
        </el-dialog>
    

    绑定数据:

    import { getRoleDetail, assignPerm } from '@/api/setting'
    import { transListToTreeData } from '@/utils'
    import { getPermissionList } from '@/api/permission'
      
    data() {
        return {
          showPermDialog: false, // 控制分配权限弹层的显示或者隐藏
          permData: [], // 接收权限数据
          defaultProps: {
            label: 'name'
          }, // 定义显示字段的名称 和 子属性的字段名称
          roleId: null, // 用来记录当前分配权限的id
          selectCheck: [] // 用来记录当前的权限点的标识
        }
    },
    methods: {
      // 点击分配权限
      // 获取权限点数据 在点击的时候调用 获取权限点数据
        async assignPerm(id) {
          this.permData = tranListToTreeData(await getPermissionList(), '0') // 转化list到树形数据
          this.roleId = id
          // 应该去获取 这个id的 权限点
          // 有id 就可以 id应该先记录下来
          const { permIds } = await getRoleDetail(id) // permIds是当前角色所拥有的权限点数据
          this.selectCheck = permIds // 将当前角色所拥有的权限id赋值
          this.showPermDialog = true
        },
        async  btnPermOK() {
          // 调用el-tree的方法
          await assignPerm({ permIds: this.$refs.permTree.getCheckedKeys(), id: this.roleId })
          this.$message.success('分配权限成功')
          this.showPermDialog = false
        },
        btnPermCancel() {
          this.selectCheck = [] // 重置数据
          this.showPermDialog = false
        }
    }
    

    总结

  • 相关阅读:
    批量xls转换为xlsx
    MPLS VPN跨域C1方案 RR反射器
    Azure Synapse Analytics 性能优化指南(3)——使用具体化视图优化性能(下)
    【C++庖丁解牛】高阶数据结构---红黑树详解
    C#调用Windows API实现自定义打印纸张大小
    C语言链表
    深度学习-参数量&模型大小&理论计算量
    ESP32 系列之 ESP-IDF 官方构建方案
    【DropBlock】《DropBlock:A regularization method for convolutional networks》
    软件测试用例
  • 原文地址:https://blog.csdn.net/qq_40652101/article/details/127119858