若依RuoYi-Vue-master,登录后根据用户菜单权限显示第一个菜单
·
用户登录后,不需要显示同样的首页,登录后直接跳转到路由菜单第一个页面。
本文章是从其他多个文章中总结出符合自己的内容。如有抄袭请见谅。只做学习记录使用。
1、修改文件 src\permission.js
防止当用户登录之后,点击浏览器做上角的后退按钮, 会出现跳到404的情况。
/* has token*/
if (to.path === '/login') {
// 修改默认首页。
// 注释
// next({ path: '/' })
// 添加
location.href = store.state.permission.indexPage
// 修改默认首页。
NProgress.done()
} else if (isWhiteList(to.path)) {
没有token需要跳转到登录页面。
// 没有token
if (isWhiteList(to.path)) {
// 在免登录白名单,直接进入
next()
} else {
// 修改默认首页。
// 注释
// next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页
// 添加
next(`/login`) // 否则全部重定向到登录页。
// 修改默认首页。
NProgress.done()
}
完整代码如下:
import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { getToken } from '@/utils/auth'
import { isPathMatch } from '@/utils/validate'
import { isRelogin } from '@/utils/request'
NProgress.configure({ showSpinner: false })
const whiteList = ['/login', '/register']
const isWhiteList = (path) => {
return whiteList.some(pattern => isPathMatch(pattern, path))
}
router.beforeEach((to, from, next) => {
NProgress.start()
if (getToken()) {
to.meta.title && store.dispatch('settings/setTitle', to.meta.title)
/* has token*/
if (to.path === '/login') {
// 修改默认首页。
// 注释
// next({ path: '/' })
// 添加
location.href = store.state.permission.indexPage
// 修改默认首页。
NProgress.done()
} else if (isWhiteList(to.path)) {
next()
} else {
if (store.getters.roles.length === 0) {
isRelogin.show = true
// 判断当前用户是否已拉取完user_info信息
store.dispatch('GetInfo').then(() => {
isRelogin.show = false
store.dispatch('GenerateRoutes').then(accessRoutes => {
// 根据roles权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
})
}).catch(err => {
store.dispatch('LogOut').then(() => {
Message.error(err)
next({ path: '/' })
})
})
} else {
next()
}
}
} else {
// 没有token
if (isWhiteList(to.path)) {
// 在免登录白名单,直接进入
next()
} else {
// 修改默认首页。
// 注释
// next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页
// 添加
next(`/login`) // 否则全部重定向到登录页。
// 修改默认首页。
NProgress.done()
}
}
})
router.afterEach(() => {
NProgress.done()
})
2、修改文件 src\store\modules\permission.js
添加首页变量定义
state: {
routes: [],
addRoutes: [],
defaultRoutes: [],
topbarRouters: [],
sidebarRouters: [],
// 修改默认首页
indexPage: ''
},
mutations: {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
},
SET_DEFAULT_ROUTES: (state, routes) => {
state.defaultRoutes = constantRoutes.concat(routes)
},
SET_TOPBAR_ROUTES: (state, routes) => {
state.topbarRouters = routes
},
SET_SIDEBAR_ROUTERS: (state, routes) => {
state.sidebarRouters = routes
},
// 修改默认首页
SET_INDEX_PAGE: (state, indexPage) => {
state.indexPage = indexPage
},
},
取得新首页的路由信息
actions: {
// 生成路由
GenerateRoutes({ commit }) {
return new Promise(resolve => {
// 向后端请求路由数据
getRouters().then(res => {
// 修改默认首页。
// 添加
const sdata = JSON.parse(JSON.stringify(res.data))
const rdata = JSON.parse(JSON.stringify(res.data))
// 登录后跳转404,要看看登录页url的redirect重定向值是什么。
if(res.data.length > 0){
// 登录的用户有菜单权限
let pathIndex = ''
// 第一个菜单要区分有子菜单和没有子菜单的情况
if (res.data[0].path == '/') {
// 一级子菜单
pathIndex = res.data[0].path + res.data[0].children[0].path
} else {
if (res.data[0].children) {
if (res.data[0].children[0].children && res.data[0].children[0].children.length > 0) {
// 三级子菜单
pathIndex = res.data[0].path + '/' + res.data[0].children[0].path + '/' + res.data[0].children[0].children[0].path
} else {
// 二级子菜单
pathIndex = res.data[0].path + '/' + res.data[0].children[0].path
}
}
}
// console.log('store permission---', pathIndex)
const sidebarRoutes = filterAsyncRouter(sdata)
const rewriteRoutes = filterAsyncRouter(rdata, false, true)
// 如果登录之后,用户跳到的路由是存在但没有权限的路由,那就要提示无权限。但是需要有一个接口返回全部路由来作为参考。这个功能后续再考虑是否完善。
const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true }) // 当输入不存在的路由时,直接跳转到404
router.addRoutes(asyncRoutes)
commit('SET_ROUTES', rewriteRoutes)
commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
commit('SET_DEFAULT_ROUTES', sidebarRoutes)
commit('SET_TOPBAR_ROUTES', sidebarRoutes)
//修改默认首页
commit('SET_INDEX_PAGE', pathIndex)
resolve(rewriteRoutes)
} else {
// 登录的用户没有任何一个菜单权限
Message({
message: '非常抱歉,该用户没有菜单权限!',
type: 'warning'
});
resolve()
}
// 注释
// const sdata = JSON.parse(JSON.stringify(res.data))
// const rdata = JSON.parse(JSON.stringify(res.data))
// const sidebarRoutes = filterAsyncRouter(sdata)
// const rewriteRoutes = filterAsyncRouter(rdata, false, true)
// const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
// rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
// router.addRoutes(asyncRoutes)
// commit('SET_ROUTES', rewriteRoutes)
// commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
// commit('SET_DEFAULT_ROUTES', sidebarRoutes)
// commit('SET_TOPBAR_ROUTES', sidebarRoutes)
// resolve(rewriteRoutes)
// 修改默认首页。
})
})
}
}
完整代码如下:
import auth from '@/plugins/auth'
import router, { constantRoutes, dynamicRoutes } from '@/router'
import { getRouters } from '@/api/menu'
import Layout from '@/layout/index'
import ParentView from '@/components/ParentView'
import InnerLink from '@/layout/components/InnerLink'
const permission = {
state: {
routes: [],
addRoutes: [],
defaultRoutes: [],
topbarRouters: [],
sidebarRouters: [],
// 修改默认首页
indexPage: ''
},
mutations: {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
},
SET_DEFAULT_ROUTES: (state, routes) => {
state.defaultRoutes = constantRoutes.concat(routes)
},
SET_TOPBAR_ROUTES: (state, routes) => {
state.topbarRouters = routes
},
SET_SIDEBAR_ROUTERS: (state, routes) => {
state.sidebarRouters = routes
},
// 修改默认首页
SET_INDEX_PAGE: (state, indexPage) => {
state.indexPage = indexPage
},
},
actions: {
// 生成路由
GenerateRoutes({ commit }) {
return new Promise(resolve => {
// 向后端请求路由数据
getRouters().then(res => {
// 修改默认首页。
// 添加
const sdata = JSON.parse(JSON.stringify(res.data))
const rdata = JSON.parse(JSON.stringify(res.data))
// 登录后跳转404,要看看登录页url的redirect重定向值是什么。
if(res.data.length > 0){
// 登录的用户有菜单权限
let pathIndex = ''
// 第一个菜单要区分有子菜单和没有子菜单的情况
if (res.data[0].path == '/') {
// 一级子菜单
pathIndex = res.data[0].path + res.data[0].children[0].path
} else {
if (res.data[0].children) {
if (res.data[0].children[0].children && res.data[0].children[0].children.length > 0) {
// 三级子菜单
pathIndex = res.data[0].path + '/' + res.data[0].children[0].path + '/' + res.data[0].children[0].children[0].path
} else {
// 二级子菜单
pathIndex = res.data[0].path + '/' + res.data[0].children[0].path
}
}
}
// console.log('store permission---', pathIndex)
const sidebarRoutes = filterAsyncRouter(sdata)
const rewriteRoutes = filterAsyncRouter(rdata, false, true)
// 如果登录之后,用户跳到的路由是存在但没有权限的路由,那就要提示无权限。但是需要有一个接口返回全部路由来作为参考。这个功能后续再考虑是否完善。
const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true }) // 当输入不存在的路由时,直接跳转到404
router.addRoutes(asyncRoutes)
commit('SET_ROUTES', rewriteRoutes)
commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
commit('SET_DEFAULT_ROUTES', sidebarRoutes)
commit('SET_TOPBAR_ROUTES', sidebarRoutes)
//修改默认首页
commit('SET_INDEX_PAGE', pathIndex)
resolve(rewriteRoutes)
} else {
// 登录的用户没有任何一个菜单权限
Message({
message: '非常抱歉,该用户没有菜单权限!',
type: 'warning'
});
resolve()
}
// 注释
// const sdata = JSON.parse(JSON.stringify(res.data))
// const rdata = JSON.parse(JSON.stringify(res.data))
// const sidebarRoutes = filterAsyncRouter(sdata)
// const rewriteRoutes = filterAsyncRouter(rdata, false, true)
// const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
// rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
// router.addRoutes(asyncRoutes)
// commit('SET_ROUTES', rewriteRoutes)
// commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes))
// commit('SET_DEFAULT_ROUTES', sidebarRoutes)
// commit('SET_TOPBAR_ROUTES', sidebarRoutes)
// resolve(rewriteRoutes)
// 修改默认首页。
})
})
}
}
}
// 遍历后台传来的路由字符串,转换为组件对象
function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
return asyncRouterMap.filter(route => {
if (type && route.children) {
route.children = filterChildren(route.children)
}
if (route.component) {
// Layout ParentView 组件特殊处理
if (route.component === 'Layout') {
route.component = Layout
} else if (route.component === 'ParentView') {
route.component = ParentView
} else if (route.component === 'InnerLink') {
route.component = InnerLink
} else {
route.component = loadView(route.component)
}
}
if (route.children != null && route.children && route.children.length) {
route.children = filterAsyncRouter(route.children, route, type)
} else {
delete route['children']
delete route['redirect']
}
return true
})
}
function filterChildren(childrenMap, lastRouter = false) {
var children = []
childrenMap.forEach(el => {
el.path = lastRouter ? lastRouter.path + '/' + el.path : el.path
if (el.children && el.children.length && el.component === 'ParentView') {
children = children.concat(filterChildren(el.children, el))
} else {
children.push(el)
}
})
return children
}
// 动态路由遍历,验证是否具备权限
export function filterDynamicRoutes(routes) {
const res = []
routes.forEach(route => {
if (route.permissions) {
if (auth.hasPermiOr(route.permissions)) {
res.push(route)
}
} else if (route.roles) {
if (auth.hasRoleOr(route.roles)) {
res.push(route)
}
}
})
return res
}
export const loadView = (view) => {
if (process.env.NODE_ENV === 'development') {
return (resolve) => require([`@/views/${view}`], resolve)
} else {
// 使用 import 实现生产环境的路由懒加载
return () => import(`@/views/${view}`)
}
}
export default permission
3、修改文件 src\router\index.js 注释掉原首页路由信息
// {
// path: '',
// component: Layout,
// redirect: 'index',
// children: [
// {
// path: 'index',
// component: () => import('@/views/index'),
// name: 'Index',
// meta: { title: '首页', icon: 'dashboard', affix: true }
// }
// ]
// },
4、修改文件 src\utils\request.js
注:后经过测试,此处修改不需要。还是用原代码 location.href = '/index'
store.dispatch('LogOut').then(() => {
// 修改默认首页。
// 注释
// location.href = '/index'
// 添加
let indexurl = this.$store.state.permission.indexPage
location.href = indexurl
// 修改默认首页。
})
完整代码如下:
// 响应拦截器
service.interceptors.response.use(res => {
// 未设置状态码则默认成功状态
const code = res.data.code || 200
// 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default']
// 二进制数据则直接返回
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
return res.data
}
if (code === 401) {
if (!isRelogin.show) {
isRelogin.show = true
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
isRelogin.show = false
store.dispatch('LogOut').then(() => {
// 修改默认首页。
// 注释
// location.href = '/index'
// 添加
let indexurl = this.$store.state.permission.indexPage
location.href = indexurl
// 修改默认首页。
})
}).catch(() => {
isRelogin.show = false
})
}
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
} else if (code === 500) {
Message({ message: msg, type: 'error' })
return Promise.reject(new Error(msg))
} else if (code === 601) {
Message({ message: msg, type: 'warning' })
return Promise.reject('error')
} else if (code !== 200) {
Notification.error({ title: msg })
return Promise.reject('error')
} else {
return res.data
}
},
error => {
console.log('err' + error)
let { message } = error
if (message == "Network Error") {
message = "后端接口连接异常"
} else if (message.includes("timeout")) {
message = "系统接口请求超时"
} else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.slice(-3) + "异常"
}
Message({ message: message, type: 'error', duration: 5 * 1000 })
return Promise.reject(error)
}
)
5、修改文件 src\layout\components\Navbar.vue
修改logout函数
logout() {
this.$confirm('确定注销并退出系统吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$store.dispatch('LogOut').then(() => {
// 修改默认首页。
// 注释
// location.href = '/index'
// 添加
let indexurl = this.$store.state.permission.indexPage
console.log(indexurl)
location.href = indexurl
// 修改默认首页。
})
}).catch(() => {})
}
6、修改文件 src\views\login.vue
修改登陆函数
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, { expires: 30 })
Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 })
Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 })
} else {
Cookies.remove("username")
Cookies.remove("password")
Cookies.remove('rememberMe')
}
this.$store.dispatch("Login", this.loginForm).then(() => {
// 修改默认首页。
// 注释
// this.$router.push({ path: this.redirect || "/" }).catch(()=>{})
// 添加
// 1、跳到登录后指定跳转的页面或者登录后跳到首页
// this.$router.push({ path: this.redirect || '/' }).catch(() => {})
// 2、登录后跳到路由默认的第一个路由页面
this.$store.dispatch('GetInfo').then(res => {
// 拉取完user_info信息
const roles = res.roles
this.$store.dispatch('GenerateRoutes', { roles }).then(accessRoutes => {
// 根据roles权限生成可访问的路由表
if(accessRoutes) {
// 登录用户有菜单权限。
// console.log(accessRoutes, from, to.fullPath)
this.$router.addRoutes(accessRoutes) // 动态添加可访问路由表
let pathIndex = ''
pathIndex = accessRoutes[0].path + '/' + accessRoutes[0].children[0].path // 设置默认首页地址indexPage
// console.log(this.redirect, pathIndex)
// 1、this.redirect == undefined,主要针对直接从http://172.16.6.205:9090/login,登入系统。
// 2、this.redirect == '/',主要针对直接从这个http://172.16.6.205:9090/login?redirect=%2F,登入系统。因为没有设置重定向的路由
// 如果登录的时候出现1、2两种情况,那么就跳到路由的第一个路由页面,如果登录的时候,有设置可以访问的重定向地址,那么登录后就跳到重定向地址。
if (pathIndex != '') {
this.$router.push({ path: this.redirect == '/' || this.redirect == undefined ? pathIndex : this.redirect }).catch(() => {}) // 跳转重定向页面或跳到默认首页indexPage
}
} else {
// 登录的用户没有任何一个菜单路由权限,那么要去掉登录按钮的loading状态。从新获取验证码。
this.loading = false
this.getCode()
}
})
}).catch(err => {
this.$store.dispatch('LogOut').then(() => {
Message.error(err)
next({ path: '/login' })
})
})
// 修改默认首页。
}).catch(() => {
this.loading = false
if (this.captchaEnabled) {
this.getCode()
}
})
}
})
}
7、修改文件 src\components\Breadcrumb\index.vue
注释首页的判断
// 判断是否为首页
// if (!this.isDashboard(matched[0])) {
// matched = [{ path: "/index", meta: { title: "首页" } }].concat(matched)
// }
8、修改文件 src\layout\components\TagsView\index.vue
添加关闭最后一个标签页的判断,不允许关闭。
closeSelectedTag(view) {
// 修改默认首页。
// 添加
if (this.visitedViews.length == 1) {
this.$modal.msgWarning("当前为最后一个页签,不允许删除。");
return;
}
// 修改默认首页。
this.$tab.closePage(view).then(({ visitedViews }) => {
if (this.isActive(view)) {
this.toLastView(visitedViews, view)
}
})
},
9、修改文件 src\views\error\404.vue和401.vue
修改页面的返回首页链接
<router-link :to="indexPage" class="bullshit__return-home">
返回首页
</router-link>
export default {
name: 'Page404',
computed: {
// 修改默认首页。
// 添加
...mapState({
indexPage: state => state.permission.indexPage,
}),
// 修改默认首页。
message() {
return '找不到网页!'
}
}
}
至此修改就完成了。测试通过。目前还没有发现有大问题。发现问题再进行修改吧。
更多推荐



所有评论(0)