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

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

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

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

前言

   在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 和 角色查询出不同的按钮。当然这还需要前端进一步的处理。此功能我们以后再讲如何实现


相关文章
|
5月前
|
人工智能 自然语言处理 数据可视化
两大 智能体框架 Dify vs Langchain 的全面分析,该怎么选?资深架构师 做一个彻底的解密
两大 智能体框架 Dify vs Langchain 的全面分析,该怎么选?资深架构师 做一个彻底的解密
两大 智能体框架 Dify vs Langchain 的全面分析,该怎么选?资深架构师 做一个彻底的解密
|
1月前
|
人工智能 自然语言处理 JavaScript
Github又一AI黑科技项目,打造全栈架构,只需一个统一框架?
Motia 是一款现代化后端框架,融合 API 接口、后台任务、事件系统与 AI Agent,支持 JavaScript、TypeScript、Python 多语言协同开发。它提供可视化 Workbench、自动观测追踪、零配置部署等功能,帮助开发者高效构建事件驱动的工作流,显著降低部署与运维成本,提升 AI 项目落地效率。
217 0
|
6月前
|
网络协议 Java 应用服务中间件
框架源码私享笔记(01)Tomcat核心架构功能 | 配置详解
本文首先分享了《活出意义来》一书序言中的感悟,强调成功如同幸福,不是刻意追求就能得到,而是全心投入时的副产品。接着探讨了Tomcat的核心功能与架构解析,包括网络连接器(Connector)和Servlet容器(Container),并介绍了其处理HTTP请求的工作流程。文章还详细解释了Tomcat的server.xml配置文件,涵盖了从顶级容器Server到子组件Connector、Engine、Host、Context等的配置参数及作用,帮助读者理解Tomcat的内部机制和配置方法。
|
8月前
|
机器学习/深度学习 安全 算法
十大主流联邦学习框架:技术特性、架构分析与对比研究
联邦学习(FL)是保障数据隐私的分布式模型训练关键技术。业界开发了多种开源和商业框架,如TensorFlow Federated、PySyft、NVFlare、FATE、Flower等,支持模型训练、数据安全、通信协议等功能。这些框架在灵活性、易用性、安全性和扩展性方面各有特色,适用于不同应用场景。选择合适的框架需综合考虑开源与商业、数据分区支持、安全性、易用性和技术生态集成等因素。联邦学习已在医疗、金融等领域广泛应用,选择适配具体需求的框架对实现最优模型性能至关重要。
1592 79
十大主流联邦学习框架:技术特性、架构分析与对比研究
|
4月前
|
Java 开发者 Spring
Spring框架 - 深度揭秘Spring框架的基础架构与工作原理
所以,当你进入这个Spring的世界,看似一片混乱,但细看之下,你会发现这里有个牢固的结构支撑,一切皆有可能。不论你要建设的是一座宏大的城堡,还是个小巧的花园,只要你的工具箱里有Spring,你就能轻松搞定。
203 9
|
6月前
|
运维 供应链 前端开发
中小医院云HIS系统源码,系统融合HIS与EMR功能,采用B/S架构与SaaS模式,快速交付并简化运维
这是一套专为中小医院和乡镇卫生院设计的云HIS系统源码,基于云端部署,采用B/S架构与SaaS模式,快速交付并简化运维。系统融合HIS与EMR功能,涵盖门诊挂号、预约管理、一体化电子病历、医生护士工作站、收费财务、药品进销存及统计分析等模块。技术栈包括前端Angular+Nginx,后端Java+Spring系列框架,数据库使用MySQL+MyCat。该系统实现患者管理、医嘱处理、费用结算、药品管控等核心业务全流程数字化,助力医疗机构提升效率和服务质量。
363 4
|
6月前
|
算法 前端开发 定位技术
地铁站内导航系统解决方案:技术架构与核心功能设计解析
本文旨在分享一套地铁站内导航系统技术方案,通过蓝牙Beacon技术与AI算法的结合,解决传统导航定位不准确、路径规划不合理等问题,提升乘客出行体验,同时为地铁运营商提供数据支持与增值服务。 如需获取校地铁站内智能导航系统方案文档可前往文章最下方获取,如有项目合作及技术交流欢迎私信我们哦~
387 1
|
6月前
|
存储 智能硬件
CPU的定义与功能与架构
CPU(中央处理器)是计算机的核心部件,负责执行程序指令、控制数据传输和进行运算。它能处理算术与逻辑运算,并协调其他硬件协同工作。x86架构源于英特尔,适用于PC和服务器,采用复杂指令集;ARM架构则由Acorn等公司开发,广泛用于移动设备和嵌入式系统,采用精简指令集,功耗低且能效比高。
594 5
|
6月前
|
监控 安全 Cloud Native
企业网络架构安全持续增强框架
企业网络架构安全评估与防护体系构建需采用分层防御、动态适应、主动治理的方法。通过系统化的实施框架,涵盖分层安全架构(核心、基础、边界、终端、治理层)和动态安全能力集成(持续监控、自动化响应、自适应防护)。关键步骤包括系统性风险评估、零信任网络重构、纵深防御技术选型及云原生安全集成。最终形成韧性安全架构,实现从被动防御到主动免疫的转变,确保安全投入与业务创新的平衡。
|
7月前
|
人工智能 自然语言处理 并行计算
MeteoRA:多任务AI框架革新!动态切换+MoE架构,推理效率提升200%
MeteoRA 是南京大学推出的多任务嵌入框架,基于 LoRA 和 MoE 架构,支持动态任务切换与高效推理。
299 3

热门文章

最新文章