Merge remote-tracking branch 'origin/master' into dev

This commit is contained in:
xingyu 2022-10-26 09:00:08 +08:00
commit d87dc01dc8
8 changed files with 27 additions and 23 deletions

View File

@ -67,7 +67,7 @@ export default {
}, },
// //
childrenMenus() { childrenMenus() {
var childrenMenus = []; const childrenMenus = [];
this.routers.map((router) => { this.routers.map((router) => {
for (var item in router.children) { for (var item in router.children) {
if (router.children[item].parentPath === undefined) { if (router.children[item].parentPath === undefined) {

View File

@ -5,6 +5,7 @@ import dialogDragWidth from './dialog/dragWidth'
import dialogDragHeight from './dialog/dragHeight' import dialogDragHeight from './dialog/dragHeight'
import clipboard from './module/clipboard' import clipboard from './module/clipboard'
// Vue自定义指令https://v2.cn.vuejs.org/v2/guide/custom-directive.html
const install = function(Vue) { const install = function(Vue) {
Vue.directive('hasRole', hasRole) Vue.directive('hasRole', hasRole)
Vue.directive('hasPermi', hasPermi) Vue.directive('hasPermi', hasPermi)

View File

@ -2,22 +2,21 @@
* 操作权限处理 * 操作权限处理
* Copyright (c) 2019 ruoyi * Copyright (c) 2019 ruoyi
*/ */
import store from '@/store' import store from '@/store'
export default { export default {
inserted(el, binding, vnode) { inserted(el, binding, vnode) {
const { value } = binding const { value } = binding
const all_permission = "*:*:*"; const all_permission = "*:*:*"; // 全部权限
const permissions = store.getters && store.getters.permissions const permissions = store.getters && store.getters.permissions // 用户拥有的权限标识的数组
if (value && value instanceof Array && value.length > 0) { if (value && value instanceof Array && value.length > 0) {
// 判断是否有权限
const permissionFlag = value const permissionFlag = value
const hasPermissions = permissions.some(permission => { const hasPermissions = permissions.some(permission => {
return all_permission === permission || permissionFlag.includes(permission) return all_permission === permission || permissionFlag.includes(permission)
}) })
// 如果没有权限,则移除元素
if (!hasPermissions) { if (!hasPermissions) {
el.parentNode && el.parentNode.removeChild(el) el.parentNode && el.parentNode.removeChild(el)
} }

View File

@ -2,22 +2,22 @@
* 角色权限处理 * 角色权限处理
* Copyright (c) 2019 ruoyi * Copyright (c) 2019 ruoyi
*/ */
import store from '@/store' import store from '@/store'
export default { export default {
inserted(el, binding, vnode) { inserted(el, binding, vnode) {
const { value } = binding const { value } = binding
const super_admin = "admin"; const super_admin = "admin";
const roles = store.getters && store.getters.roles const roles = store.getters && store.getters.roles // 用户拥有的角色标识的数组
if (value && value instanceof Array && value.length > 0) { if (value && value instanceof Array && value.length > 0) {
// 判断是否有角色
const roleFlag = value const roleFlag = value
const hasRole = roles.some(role => { const hasRole = roles.some(role => {
return super_admin === role || roleFlag.includes(role) return super_admin === role || roleFlag.includes(role)
}) })
// 如果没有角色,则移除元素
if (!hasRole) { if (!hasRole) {
el.parentNode && el.parentNode.removeChild(el) el.parentNode && el.parentNode.removeChild(el)
} }

View File

@ -12,6 +12,7 @@
:collapse-transition="false" :collapse-transition="false"
mode="vertical" mode="vertical"
> >
<!-- 根据 sidebarRouters 路由生成菜单 -->
<sidebar-item <sidebar-item
v-for="(route, index) in sidebarRouters" v-for="(route, index) in sidebarRouters"
:key="route.path + index" :key="route.path + index"

View File

@ -24,11 +24,11 @@ router.beforeEach((to, from, next) => {
isRelogin.show = true isRelogin.show = true
// 获取字典数据 add by 芋艿 // 获取字典数据 add by 芋艿
store.dispatch('dict/loadDictDatas') store.dispatch('dict/loadDictDatas')
// 判断当前用户是否已拉取完user_info信息 // 判断当前用户是否已拉取完 user_info 信息
store.dispatch('GetInfo').then(() => { store.dispatch('GetInfo').then(() => {
isRelogin.show = false isRelogin.show = false
store.dispatch('GenerateRoutes').then(accessRoutes => { store.dispatch('GenerateRoutes').then(accessRoutes => {
// 根据roles权限生成可访问的路由表 // 根据 roles 权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表 router.addRoutes(accessRoutes) // 动态添加可访问路由表
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
}) })

View File

@ -8,18 +8,20 @@ Vue.use(Router)
/** /**
* Note: 路由配置项 * Note: 路由配置项
* *
* hidden: true // 当设置 true 的时候该路由不会再侧边栏出现 如401login等页面或者如一些编辑页面/edit/1 * hidden: true // 【重要】当设置 true 的时候该路由不会再侧边栏出现 如 401login 等页面,或者如一些编辑页面 /edit/1
* alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时自动会变成嵌套的模式--如组件页面 * alwaysShow: true // 当你一个路由下面的 children 声明的路由大于1个时自动会变成嵌套的模式--如组件页面
* // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面 * // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面
* // 若你想不管路由下面的 children 声明的个数都显示你的根路由 * // 若你想不管路由下面的 children 声明的个数都显示你的根路由
* // 你可以设置 alwaysShow: true这样它就会忽略之前定义的规则一直显示根路由 * // 你可以设置 alwaysShow: true这样它就会忽略之前定义的规则一直显示根路由
* path: '/login', // 【重要】访问的 URL 路径
* component: Layout, // 【重要】对应的组件;也可以是 (resolve) => require(['@/views/login'], resolve),
* redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 * redirect: noRedirect // 当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
* name:'router-name' // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题 * name:'router-name' // 【重要】设定路由的名字,一定要填写不然使用 <keep-alive> 时会出现各种问题
* meta : { * meta : {
noCache: true // 如果设置为true则不会被 <keep-alive> 缓存(默认 false) noCache: true // 【重要】如果设置为 true则不会被 <keep-alive> 缓存(默认 false)
title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字 title: 'title' // 【重要】设置该路由在侧边栏和面包屑中展示的名字
icon: 'svg-name' // 设置该路由的图标对应路径src/assets/icons/svg icon: 'svg-name' // 【重要】设置该路由的图标,对应路径 src/assets/icons/svg
breadcrumb: false // 如果设置为false则不会在breadcrumb面包屑中显示 breadcrumb: false // 如果设置为 false则不会在 breadcrumb 面包屑中显示
activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。 activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。
} }
*/ */

View File

@ -8,7 +8,8 @@ const permission = {
state: { state: {
routes: [], routes: [],
addRoutes: [], addRoutes: [],
sidebarRouters: [] sidebarRouters: [], // 左侧边菜单的路由,被 Sidebar/index.vue 使用
topbarRouters: [], // 顶部菜单的路由,被 TopNav/index.vue 使用
}, },
mutations: { mutations: {
SET_ROUTES: (state, routes) => { SET_ROUTES: (state, routes) => {
@ -29,10 +30,10 @@ const permission = {
// 生成路由 // 生成路由
GenerateRoutes({ commit }) { GenerateRoutes({ commit }) {
return new Promise(resolve => { return new Promise(resolve => {
// 向后端请求路由数据 // 向后端请求路由数据(菜单)
getRouters().then(res => { getRouters().then(res => {
const sdata = JSON.parse(JSON.stringify(res.data)) const sdata = JSON.parse(JSON.stringify(res.data)) // 【重要】用于菜单中的数据
const rdata = JSON.parse(JSON.stringify(res.data)) const rdata = JSON.parse(JSON.stringify(res.data)) // 用于最后添加到 Router 中的数据
const sidebarRoutes = filterAsyncRouter(sdata) const sidebarRoutes = filterAsyncRouter(sdata)
const rewriteRoutes = filterAsyncRouter(rdata, false, true) const rewriteRoutes = filterAsyncRouter(rdata, false, true)
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true }) rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
@ -57,7 +58,7 @@ function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
icon: route.icon, icon: route.icon,
noCache: !route.keepAlive, noCache: !route.keepAlive,
} }
// 路由地址转首字母大写驼峰,作为路由名称,适配keepAlive // 路由地址转首字母大写驼峰,作为路由名称,适配 keepAlive
route.name = toCamelCase(route.path, true) route.name = toCamelCase(route.path, true)
route.hidden = !route.visible route.hidden = !route.visible
// 处理 component 属性 // 处理 component 属性