开发者社区> 游客ybhescv4ieeug> 正文

茫茫人海遇见了你,不早也不晚。关于Admin Work 框架中"按钮级权限"功能架构的思考与实现

简介: 茫茫人海遇见了你,不早也不晚。关于Admin Work 框架中"按钮级权限"功能架构的思考与实现
+关注继续查看
福利推荐:阿里云、腾讯云、华为云等大品牌云产品全线2折优惠活动来袭,4核8G云服务器899元/3年,新老用户共享优惠,点击这里立即抢购>>>

“人生是为心的修行而设立的道场。人生的目的就是在灾难和幸运才考验中磨炼自己的心志,磨炼灵魂,造就一颗美丽的心灵”

----来自《稻盛和夫给年轻人的忠告》

前言

????在VueAdminWork框架中一直有一个功能至今还没实现,就是关于 "按钮级权限"也可以叫做 "功能点权限" 地实现。

????一开始也想实现这个功能,随便从网上找几个类似的指令集成进去就好,但是我觉得这样千篇一律也没有什么意思,就想着能不能把这个功能做的尽量完善、方便、扩展性强点。最近正好有时间,就想着如何把这个功能实现一下。


总体功能概述

??? VueAdminWork的权限是基于RBAC权限模型设计而来。什么是RBAC大家可以网上查阅相关的资料,网上有很多这样的介绍。

不同角色的用户拥有不同的菜单权限。所以在这一模型下,我们得把按钮都依附于页面或者菜单下。

所以我们打算设计成两种都能控制的形式

  • 基于后端的控制方式
  • 基于前端的控制方式

基于后端的就是某个用户拥有不同的角色就相当于拥有不同的菜单权限,拥有不同的菜单那么就拥有不同的按钮。这样就可以实现了此功能

但是,我们还得考虑一点就是不是所有的页面都是受角色控制的,一些公共的页面,如个人中心,登录,工作台等,都是不受控制的,在这一环境下,我们就得使用 "基于前端的控制方式"?


基于后端的控制方式具体实现思路

  1. 根据当前登录用户的角色获取菜单并且把所有的按钮查询出来放在菜单数据下,然后再通过一系列前端的处理,放入 `pinia` 状态中
  2. 根据按钮的不同展示位置属性进行分类,
    有的按钮是要放在页面最顶部,如:新增;
    有的按钮是放在 表格 中用来操作每一行的数据,如:编辑、删除等
  3. 在分类好之后,通过特定的组件容器把按钮展示出来。

说起来不算难,可是要真正实现这一功能,还是需要一点时间的。这里我们还是通过 mock 进行接口数据的模拟

先来看一下数据结构

{
    menuUrl: '/system',
    menuName: '系统管理',
    iconPrefix: 'iconfont',
    icon: 'setting',
    parentPath: '',
    children: [
      {
        parentPath: '/system',
        menuUrl: '/system/department',
        menuName: '部门管理',
        cacheable: true,
        buttonList: [
          {
            name: '添加',
            code: 'add',
            // admin角色所能展示的按钮
            roleCode: 'ROLE_admin',
            placement: 'top',
            type: 'primary',
          },
          {
            name: '编辑',
            code: 'update',
            // editor角色所能展示的按钮
            roleCode: 'ROLE_editor',
            placement: 'tableLine',
            type: 'warning',
          },
          {
            name: '删除',
            code: 'delete',
            // 所有角色所能展示的按钮
            roleCode: 'ROLE_all',
            placement: 'tableLine',
            type: 'error',
          },
        ],
      },
     }

拿到数据之后我们进行分类

/**
     * 根据当前用户的 roleCode 返回 某个 path 下所有的 button
     * @param key 路由 path
     * @returns buttons
     */
    getButtonsListByRoleCode(key: string) {
      const userStore = useUserStore()
      const userRoleCode = userStore.userRoleCode
      const result = this.permissionButtonList.find((it) => it.key === key)
      if (result) {
        if (Array.isArray(result.buttonList) && result.buttonList.length > 0) {
          return result.buttonList.filter(
            (it) => userRoleCode.includes(it.roleCode) || it.roleCode === 'ROLE_all'
          )
        }
        return []
      } else {
        return []
      }
    },
    /**
     * 根据按钮的位置进行归类
     * @param key 路由 path
     * @returns buttons
     */
    getButtonListByPlacement(key: string) {
      const resultButtonList = this.getButtonsListByRoleCode(key)
      return resultButtonList.reduce((pre, cur) => {
        if (!(pre as any)[cur.placement]) {
          ;(pre as any)[cur.placement] = []
        }
        ;(pre as any)[cur.placement].push(cur)
        return pre
      }, {} as ButtonPlacement)
    },

然后再在页面上进行展示

// 动态展示
tableColumns.push({
    title: '操作',
    key: 'actions',
    align: 'center',
    render: (rowData) => {
      return useRenderAction(
        buttonModel.tableLine?.map((it) => {
          return {
            label: it.name,
            // onClick: eval(it.code + `.bind(null,rowData)`),
            onClick: () => {
              switch (it.code) {
                case 'update':
                  onUpdateItem(rowData)
                  break
                case 'delete':
                  onDeleteItem(rowData)
                  break
              }
            },
            type: it.type,
          } as TableActionModel
        }) || []
      )
    },
  })
// 通过组件容器进行展示
<PermissionButtons :buttons="topButtons" @click="onPermissionButtonClick" />

来看一下效果

ROLE_admin 所有的按钮4edc953e2c684bbe819ffa954c899c08.png

ROLE_editor 所有的按钮4edc953e2c684bbe819ffa954c899c08.png这样基本的功能算是实现了


基于前端的控制方式具体实现思路

这种方式下比较简单,就通过 v-permission 指令实现就好,用法也比较简单,和普通的指令用法一样

<template>
    // 指令接收的参数如果是多个的话可以是一个数组,如果只有一个就直接是一个字符串就好
    <DeleteButton v-permission="['ROLE_admin', 'ROLE_editor']" />
    <DeleteButton v-permission="'ROLE_admin'" />
  </template>


写在最后

今天的内容比较长,希望大家可以认真的看一下,应该会有收获的。在这种方式下,如果以后对某个用户进行权限控制也是比较方便扩展的,根据当前登录用户的 id 和 角色查询出不同的按钮。当然这还需要前端进一步的处理。此功能我们以后再讲如何实现


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Spring MVC框架:第七章:REST架构风格
Spring MVC框架:第七章:REST架构风格
56 0
【Laravel框架】对于Laravel框架架构的研究以及视图方法和内置会话在项目里的运用
【Laravel框架】对于Laravel框架架构的研究以及视图方法和内置会话在项目里的运用
101 0
Serverless Devs 重大更新,基于 Serverless 架构的 CI/CD 框架:Serverless-cd
近日,Serverless 开发者平台 Serverless Devs 重磅发布基于 Serverless 架构的轻量级 CI/CD 框架——Serverless-cd。Serverless-cd 是一款运行在 Serverless 架构上的功能强大而灵活,安全,低成本的CI/CD开源框架。
219 0
基于 Serverless 架构的 CI/CD 框架:Serverless-cd
近日,Serverless 开发者平台 Serverless Devs 重磅发布基于 Serverless 架构的轻量级 CI/CD 框架——**Serverless-cd**。Serverless-cd 是一款运行在 Serverless 架构上的功能强大而灵活,安全,低成本的CI/CD开源框架。该框架基于 Serverless Devs 开发者工具打造,通过 Serverless-cd开发者可
144 0
Shiro框架01之什么是shiro+shiro的架构+权限认证
Shiro框架01之什么是shiro+shiro的架构+权限认证
120 0
如何将传统 Web 框架迁移部署到 Serverless 架构?
与其说 Serverless 架构是一个新的概念,不如说它是一种全新的思路,一种新的编程范式。
59423 0
Spark框架深度理解三:运行架构、核心数据集RDD
Spark框架深度理解三:运行架构、核心数据集RDD
180 0
五分钟熟悉 Spring框架整体架构
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
66 0
Spring security (一)架构框架-Component、Service、Filter分析
??想要深入spring security的authentication (身份验证)和access-control(访问权限控制)工作流程,必须清楚spring security的主要技术点包括关键接口、类以及抽象类如何协同工作进行authentication 和access-control的实现。
158 0
带你全面解析Android框架体系架构view篇,系列篇
带你全面解析Android框架体系架构view篇,系列篇
132 0
文章
问答
文章排行榜
最热
最新
相关电子书
更多
基于英特尔?架构的阿里云服务网格ASM技术加速应用服务加密通
立即下载
以银行架构视角解读和落实银行数字化转型的两份重磅指导文件
立即下载
云原生架构容器&微服务优秀案例集
立即下载


http://www.vxiaotou.com