摘要:项目背景物业管理后台,不同角色拥有不同权限采用技术实现权限管理需要后端接口支持,这里仅提供前端解决方案。前端代码可参考如果有更好的想法和建议,欢迎评论。
项目背景:物业管理后台,不同角色拥有不同权限
采用技术:Vue.js + Vuex + Element UI
实现 RBAC 权限管理需要后端接口支持,这里仅提供前端解决方案。大致思路:
因代码篇幅较大,对代码进行了删减,文中 “...” 即为省略的一部分代码。
首先登录成功后,从后台拉取用户当前可显示的菜单和可用权限列表,分别将其存入 store 的 nav(菜单导航) 和 auth(用户可用权限) 中,
在用户切换路由时,判断是否存在 auth ,如果不存在,则重新获取,判断当前访问地址 to.meta.alias 是否在
用户可用权限列表中,如果不存在,则提示无权限,否则进入路由。
2. 路由切换前进行鉴权
路由定义的部分代码,对每个路由添加了 meta 属性,用于鉴权。
这里 component 采用了异步引入的方式。
// ... // 系统管理 { path: "/system", component: Main, name: "系统管理", redirect: "/system/organization", children: [{ path: "/system/organization", component: () => import ("@/views/System/Organization.vue"), name: "组织结构", // requiresAuth 用于确认此地址是否需要验证 // alias 用于获取后端返回rbac权限对应的前端路由地址和导航菜单图标 meta: {requiresAuth: true, alias: "Pmsadmin/Oragnize/list"} }, { path: "/system/user", component: () => import ("@/views/System/User.vue"), name: "人员管理", redirect: "/system/user/index", children: [ { path: "/system/user/index", component: () => import ("@/views/System/UserList.vue"), name: "职员列表", meta: {requiresAuth: true, alias: "Pmsadmin/Admin/list"} } ] }, { path: "/system/auth", component: () => import ("@/views/System/Auth.vue"), name: "角色管理", meta: {requiresAuth: true, alias: "Pmsadmin/Role/list"} } ] } // ...路由钩子 beforeEach
router.beforeEach((to, from, next) => { document.title = `${configs.title} - ${to.name}`; const {hasAuth, auth} = store.state.user; // 未拿到权限,则获取 if (!hasAuth) { store.dispatch("getUserAuth"); console.log("重新获取用户权限"); // next(); } // 如果未登录,跳转 if (window.localStorage.getItem("IS_LOGIN") === null && to.path !== "/login") { console.log("未登录状态"); next({ path: "/login", query: {redirect: to.fullPath} // 将跳转的路由path作为参数,登录成功后跳转到该路由 }) } else { // 需要鉴权的路由地址 console.log(to, auth.indexOf(to.meta.alias), auth); if (to.meta.requiresAuth) { if (auth.indexOf(to.meta.alias) > -1) { console.log("有权限进入"); next(); } else { if(auth.length > 0) { Message.error({ message: "当前用户权限不足,无法访问", showClose: true, }); } else { next(); } } } else { next(); } } });在 Vuex 的 state 中,定义好 nav 对象
// 登录用户信息 const user = { name: "", // 用户名 avatar: "", // 用户头像 auth: [], // 用户权限 hasAuth: false // 是否已经加载用户权限 }; // 导航菜单 const nav = [];通过 action 异步获取数据
// 获取用户权限 const getUserAuth = async ({commit}) => { const res = await http.post("YOUR_URL", {}); if (res === null) return; console.log("getUserAuth", res.param); commit("SET_USER_AUTH", res.param.auth); commit("SET_SIDE_NAV", res.param.nav); };Vuex 中的 mutation 的相关代码
// 设置用户权限 const SET_USER_AUTH = (state, auth) => { state.user.auth = auth.concat("欢迎使用"); state.user.hasAuth = true; }; // 设置导航菜单 const SET_SIDE_NAV = (state, nav) => { // 导航菜单 let _nav = [{ name: "欢迎使用", url: "/main", iconCls: "fa fa-bookmark" }]; // 权限菜单对应的路由地址 const route = { "系统管理": {iconCls: "fa fa-archive", url: ""}, "Pmsadmin/Oragnize/list": {iconCls: "", url: "/system/organization"}, "Pmsadmin/Admin/list": {iconCls: "", url: "/system/user/index"}, "Pmsadmin/Role/list": {iconCls: "", url: "/system/auth"}, "Pmsadmin/Log/record": {iconCls: "", url: "/system/logs"}, "项目管理": {iconCls: "fa fa-unlock-alt", url: ""}, "Pmsadmin/Project/list": {iconCls: "", url: "/project/list/index"}, "Pmsadmin/House/list": {iconCls: "", url: "/project/house"}, "Pmsadmin/Pack/list": {iconCls: "", url: "/project/pack"}, "广告位": {iconCls: "fa fa-edit", url: ""}, "Pmsadmin/Place/list": {iconCls: "", url: "/adsplace/list"}, "投诉建议": {iconCls: "fa fa-tasks", url: ""}, "Pmsadmin/Scategory/list": {iconCls: "", url: "/complain/type"}, "Pmsadmin/Complain/list": {iconCls: "", url: "/complain/list"}, "Pmsadmin/Suggest/list": {iconCls: "", url: "/complain/suggestion"}, "报事报修": {iconCls: "fa fa-user", url: ""}, "Pmsadmin/Rcategory/list": {iconCls: "", url: "/rcategory/type"}, "Pmsadmin/Rcategory/info": {iconCls: "", url: "/rcategory/public"}, "Pmsadmin/Repair/list": {iconCls: "", url: "/rcategory/personal"}, "便民服务": {iconCls: "fa fa-external-link", url: ""}, "Pmsadmin/Bcategory/list": {iconCls: "", url: "/bcategory/type"}, "Pmsadmin/Service/list": {iconCls: "", url: "/bcategory/list"}, "首座推荐": {iconCls: "fa fa-file-text", url: ""}, "Pmsadmin/stcategory/list": {iconCls: "", url: "/stcategory/type"}, "Pmsadmin/Store/list": {iconCls: "", url: "/stcategory/list"}, "招商租赁": {iconCls: "fa fa-leaf", url: ""}, "Pmsadmin/Bussiness/list": {iconCls: "", url: "/bussiness/list"}, "Pmsadmin/Company/list": {iconCls: "", url: "/bussiness/company"}, "Pmsadmin/Question/list": {iconCls: "", url: "/bussiness/question"}, "停车找车": {iconCls: "fa fa-ra", url: ""}, "Pmsadmin/Cplace/list": {iconCls: "", url: "/cplace/cmanage"}, "Pmsadmin/Clist/list": {iconCls: "", url: "/cplace/clist"}, "Pmsadmin/Cquestion/list": {iconCls: "", url: "/cplace/cquestion"}, }; for (let key in nav) { let item = nav[key]; let _temp = {}; let subItems = []; // 二级菜单临时数组 if (item.children && item.children.length > 0) { // 二级菜单 item.children.forEach(subItem => { subItems.push(Object.assign({}, { name: subItem.name || "", url: route[subItem.url].url || "", iconCls: route[subItem.url].iconCls || "", })) }); // 一级菜单 _temp = Object.assign({}, { name: item.name || "", url: item.url || "", iconCls: route[item.name].iconCls || "", children: subItems.slice(0) }); _nav.push(_temp); } } state.nav = _nav; };3. 后端接口返回内容
{ "status": 200, "info": "数据查询成功!", "param": { "nav": { "1": { "name": "系统管理", "url": "", "children": [ { "name": "组织结构", "url": "Pmsadmin/Oragnize/list" }, { "name": "人员管理", "url": "Pmsadmin/Admin/list" }, { "name": "角色管理", "url": "Pmsadmin/Role/list" }, { "name": "日志管理", "url": "Pmsadmin/Log/record" } ] }, "61": { "name": "广告位", "url": "", "children": [ { "name": "广告位列表", "url": "Pmsadmin/Place/list" } ] } }, "auth": [ "系统管理", "Pmsadmin/Oragnize/list", "Pmsadmin/Admin/list", "Pmsadmin/Role/list", "Pmsadmin/Log/record", "广告位", "Pmsadmin/Place/list" ] } }存在的问题
新增 修改 删除 按钮还无法实现根据用户权限控制其显示
代码上还存在着不足,期待大神能够有更优的解决方案。
前端代码可参考:https://github.com/kfw001/adm...
如果有更好的想法和建议,欢迎评论。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/91765.html
阅读 702·2021-11-23 09:51
阅读 2402·2021-10-11 11:10
阅读 1255·2021-09-23 11:21
阅读 1070·2021-09-10 10:50
阅读 857·2019-08-30 15:54
阅读 3294·2019-08-30 15:53
阅读 3272·2019-08-30 15:53
阅读 3169·2019-08-29 17:23