权限角色菜单(前端)

一、后端对接部分

通过前端固定文件中记录的菜单树形结构进行显示或者隐藏侧边栏菜单控制角色菜单权限

  由于本框架有不同的模块,因此无法统一用最简单的文件传输形式传给后端存储,所以由以下方式多选出来的结果集传给后端保存,前端通过后端保存的结果集判断是否包含此权限

上述结构最终会形成如下数组结构,分为不同模块,每个模块都有自己的回显多选菜单,数据权限的选中结果和菜单选中结果

[
    {
        "label": "系统模块",
        "value": "baseHome",
        "selectedKeys": [],
        "checkedKeys": [
            "baseHome_index"
        ],
        "requestChecked": [
            "/数据1",
            "/数据2"
        ],
        "requestList": [
            {
                "labelName": "工作台",
                "keyName": "baseHome_index",
                "requestList": [
                    {
                        "label": "数据1",
                        "value": "/数据1"
                    },
                    {
                        "label": "数据2",
                        "value": "/数据2"
                    }
                ]
            }
        ]
    },
    {
        "label": "安防模块",
        "value": "security",
        "selectedKeys": [],
        "checkedKeys": [
            "security_comprehensive",
            "security_personList",
            "security_carList"
        ],
        "requestChecked": [
            "/mange",
            "/req",
            "/mange",
            "/req",
            "/mange",
            "/req",
            "/mange",
            "/req"
        ],
        "requestList": [
            {
                "labelName": "人员信息列表",
                "keyName": "security_personList",
                "requestList": [
                    {
                        "label": "借口1",
                        "value": "/mange"
                    },
                    {
                        "label": "借口2",
                        "value": "/req"
                    }
                ]
            },
            {
                "labelName": "人员信息列表",
                "keyName": "security_personList",
                "requestList": [
                    {
                        "label": "借口1",
                        "value": "/mange"
                    },
                    {
                        "label": "借口2",
                        "value": "/req"
                    }
                ]
            },
            {
                "labelName": "车辆信息列表",
                "keyName": "security_carList",
                "requestList": [
                    {
                        "label": "借口1",
                        "value": "/mange"
                    },
                    {
                        "label": "借口2",
                        "value": "/req"
                    }
                ]
            },
            {
                "labelName": "车辆信息列表",
                "keyName": "security_carList",
                "requestList": [
                    {
                        "label": "借口1",
                        "value": "/mange"
                    },
                    {
                        "label": "借口2",
                        "value": "/req"
                    }
                ]
            }
        ]
    },
    {
        "label": "安全教育",
        "value": "education",
        "selectedKeys": [],
        "checkedKeys": [
            "education_index"
        ],
        "requestChecked": [
            "/安全教育数据1"
        ],
        "requestList": [
            {
                "labelName": "安全教育工作台",
                "keyName": "education_index",
                "requestList": [
                    {
                        "label": "安全教育数据1",
                        "value": "/安全教育数据1"
                    }
                ]
            }
        ]
    }
]

前端发送该格式的json字符串给后端,后端需要保存字符串格式方便编辑回显,同时需要把里面的checkedKeys组合成一个新的数组,requestChecked组合成一个新的数组,在前台登录之后获取该用户的权限只需要这两个数组结果,前端通过比对是否包含这个数组中的值控制权限显示,例如

authRouter: ["baseHome_securityDevice", "baseHome_index", "baseHome_personList", "baseHome_roleList", "baseHome_logList", "baseHome_moduleList"],
authPath: ["/","/req","/req/add","/req/getList"],

每个不同的模块对应后端不同的包,由模块控制管理

模块以及模块对应的路由都在前端文件写死,只控制他的状态,通过checked控制此模块是否开启,如果后端没有部署该模块的接口包,则永远为关闭状态,只有开启的模块才可以进行上述角色中对该模块进行菜单管理

{ label: "系统模块", value: "baseHome", description: "这是系统模块", checked: true, children: 路由文件 },
{ label: "安防模块", value: "security", description: "这是安防模块", checked: true, children: 路由文件 },
{ label: "安全教育", value: "education", description: "这是安全教育", checked: true, children:路由文件 },

二、前端代码处理

前端权限通过比对后端存的值来切割现在展示的侧边栏

//通过请求路由菜单接口获取权限路由,把不存在的路由置灰
      const routerStore = useRouterStore()
      this.siderRouter.forEach((item, index) => {
        item.disabled = true;
        if (item.hasOwnProperty("children") && item.children.length != 0) {
          item.children.forEach((itemChild, indexChild) => {
            if (routerStore.authRouter.indexOf(itemChild.key) != -1) {
              itemChild.disabled = false;
              item.disabled = false;
            } else {
              itemChild.disabled = true;
            }
            // 管理员的判断不置灰权限
            if(useStore().userInfo.userId == '-1'){
              itemChild.disabled = false;
              item.disabled = false;
            }
          });
        } else {
          if (routerStore.authRouter.indexOf(item.key) != -1) {
            item.disabled = false;
          } else {
            item.disabled = true;
          }
        }

        // 管理员的判断不置灰权限
        if(useStore().userInfo.userId == '-1'){
          item.disabled = false;
        }
      });

本地文件通过更改disable标出哪些是没有权限的节点不删减源文件,在父框架中调用时先赋值再判断如果disable为true则切割不展示

//处理切割菜单
      this.sideRouter.forEach((item, index) => {
        if (item.hasOwnProperty("children") && item.children.length != 0) {
          item.children.forEach((itemChild, indexChild) => {
            if (itemChild.disabled) {
              item.children.splice(itemChild);
            }
          });
        } else if (item.disabled) {
          this.sideRouter.splice(item);
        }
      });
前端pinia路由权限文件解读

label

中文名

key

对应router的name,antd侧边栏默认自动读取这个key用于点击跳转

disabled

权限中是否启用这个菜单,在处理方法中判断true的切割掉,最后把剩下的赋值给最外层的侧边栏,源文件部分不做切割只用disable做标识

parentPathName

父节点的router的name

childrenPathName

重要:侧边栏只分一级和二级,剩余的属于这个模块的路由如果不在这里归纳进数组,在头部模块栏切换时出现刷新或者后退前进操作将无法知道每个当前的路由的父级模块是谁侧边栏哪一个该选中,因此每个最低一级的侧边栏需要把他所属的页面router的name值放进这个数组,在父级路由守卫有重要作用,此做法避免了为了寻找某个路由的模块遍历所有的路由文件影响性能

moudel

这个侧边栏属于哪个模块,用于路由守卫方便判断不用遍历路由表提升性能

requestList

该层级包含哪些数据接口,和上面childrenPathName一样最底层一级需要把这个模块所有的接口全部写上,在权限判断是否能调用接口的axios全局拦截器里面有重要作用

children

如果有下一级则在children中展示,默认侧边栏只做两级,因为路由守卫和头部侧边公共组件还有axios全局拦截器有多次遍历操作,层级过高的树形结构影响性能

siderRouter: [
        {
          label: "工作台",
          key: "energy_index",
          icon: h(HomeOutlined),
          disabled: false,
          onlyAdmin: "0",
          parentPathName: "",
          number: 1,
          childrenPathName: [],
          moudel: "energy",
          requestList: [{ label: "能耗数据1", value: "/能耗数据1" }],
        },
        {
          label: "智能照明管理",
          key: "energy_lighting",
          icon: h(SoundOutlined),
          disabled: false,
          onlyAdmin: "0",
          parentPathName: "",
          number: 1,
          requestList: [],
          childrenPathName: [],
          moudel: "energy",
          children: [
            {
              label: "运行参数设置",
              key: "energy_parameter",
              disabled: false,
              onlyAdmin: "0",
              parentPathName: "energy_lighting",
              childrenPathName: [],
              moudel: "energy",
              requestList: [
                { label: "能耗数据2", value: "/能耗数据2" },
                { label: "能耗数据3", value: "/能耗数据3" },
              ],
              number: 1,
            },
            {
              label: "告警管理",
              key: "energy_alarmList",
              disabled: false,
              onlyAdmin: "0",
              parentPathName: "energy_lighting",
              childrenPathName: [],
              moudel: "energy",
              requestList: [
                { label: "能耗数据2", value: "/能耗数据2" },
                { label: "能耗数据3", value: "/能耗数据3" },
              ],
              number: 1,
            },
            {
              label: "电能耗TOP10",
              key: "energy_consumptionList",
              disabled: false,
              onlyAdmin: "0",
              parentPathName: "energy_lighting",
              childrenPathName: [],
              moudel: "energy",
              requestList: [
                { label: "能耗数据2", value: "/能耗数据2" },
                { label: "能耗数据3", value: "/能耗数据3" },
              ],
              number: 1,
            },
            {
              label: "数据监测",
              key: "energy_monitoringList",
              disabled: false,
              onlyAdmin: "0",
              parentPathName: "energy_lighting",
              childrenPathName: [],
              moudel: "energy",
              requestList: [
                { label: "能耗数据2", value: "/能耗数据2" },
                { label: "能耗数据3", value: "/能耗数据3" },
              ],
              number: 1,
            },
            {
              label: "计算关系管理",
              key: "energy_RelationshipList",
              disabled: false,
              onlyAdmin: "0",
              parentPathName: "energy_lighting",
              childrenPathName: [],
              moudel: "energy",
              requestList: [
                { label: "能耗数据2", value: "/能耗数据2" },
                { label: "能耗数据3", value: "/能耗数据3" },
              ],
              number: 1,
            },
            {
              label: "智能控制",
              key: "energy_controlList",
              disabled: false,
              onlyAdmin: "0",
              parentPathName: "energy_lighting",
              childrenPathName: [],
              moudel: "energy",
              requestList: [
                { label: "能耗数据2", value: "/能耗数据2" },
                { label: "能耗数据3", value: "/能耗数据3" },
              ],
              number: 1,
            },
          ],
        },
      ],

三、重构权限部分

总平台上传上面的文件,由列表管理部分可以对其进行删减增加,手动控制

租户平台通过租户号获取开通的模块拿到所有权限路由,再由管理员分配菜单和接口权限

  • 10
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在React函数组件项目中实现菜单路由权限可以通过以下步骤: 1. 首先,定义一个菜单配置文件,该配置文件包含了所有的菜单项及其对应的路由信息。例如: ```javascript const menuConfig = [ { title: '首页', path: '/', roles: ['admin', 'user'], // 角色权限,只有admin和user角色可以访问 }, { title: '用户管理', path: '/users', roles: ['admin'], // 只有admin角色可以访问 }, // 其他菜单项... ]; ``` 2. 在你的路由组件中,根据用户的角色信息动态生成可访问的路由。你可以使用React Router来管理路由。例如: ```javascript import { BrowserRouter as Router, Route, Redirect } from 'react-router-dom'; const App = () => { const userRole = getUserRole(); // 获取用户角色信息 const accessibleRoutes = menuConfig .filter(menu => menu.roles.includes(userRole)) // 过滤出用户角色可访问的菜单项 .map(menu => ( <Route key={menu.path} path={menu.path} component={menu.component} /> )); return ( <Router> {/* 其他路由配置 */} {accessibleRoutes} <Redirect to="/" /> {/* 默认跳转到首页 */} </Router> ); }; ``` 3. 在菜单组件中,根据用户角色信息动态生成可见的菜单项。你可以使用map方法遍历菜单配置文件,根据用户角色信息来判断是否显示菜单项。例如: ```javascript import { Link } from 'react-router-dom'; const Menu = () => { const userRole = getUserRole(); // 获取用户角色信息 const visibleMenus = menuConfig.filter(menu => menu.roles.includes(userRole) ); return ( <ul> {visibleMenus.map(menu => ( <li key={menu.path}> <Link to={menu.path}>{menu.title}</Link> </li> ))} </ul> ); }; ``` 通过以上步骤,你可以根据用户的角色信息动态生成可访问的路由和可见的菜单项,从而实现菜单路由权限控制。请根据你的项目需求进行相应的调整和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值