动态路由处理用户
-
在UserServiceImpl中的getUserInfo方法中的getMenuListByUserId添加权限列表
//权限列表 List<Menu> menuList = menuService.getMenuListByUserId(loginUser.getId()); data.put("menuList",menuList);
-
在MenuMapper.xml中添加一个select语句:
<select id="getMenuListByUserId" resultType="Menu"> SELECT * FROM x_menu a, x_role_menu b, x_user_role c WHERE a.`menu_id` = b.`menu_id` AND b.`role_id` = c.`role_id` AND a.`parent_id` = #{pid} AND c.`user_id` = #{userId} </select>
-
在配置文件中配置别名:
mybatis-plus.type-aliases-package=com.zz.*.entity
-
在MenuMapper中定义对应的方法:
public interface MenuMapper extends BaseMapper<Menu> { public List<Menu> getMenuListByUserId(@Param("userId") Integer userId, @Param("pid") Integer pid); }
-
在IMenuService接口中创建一个方法:
List<Menu> getMenuListByUserId(Integer userId);
-
并在对应的MenuServiceImpl中实现该方法:
@Override public List<Menu> getMenuListByUserId(Integer userId) { // 一级菜单 List<Menu> menuList = this.getBaseMapper().getMenuListByUserId(userId, 0); // 子菜单 setMenuChildrenByUserId(userId, menuList); return menuList; } private void setMenuChildrenByUserId(Integer userId, List<Menu> menuList) { if (menuList != null) { for (Menu menu : menuList) { List<Menu> subMenuList = this.getBaseMapper().getMenuListByUserId(userId, menu.getMenuId()); menu.setChildren(subMenuList); // 递归 setMenuChildrenByUserId(userId,subMenuList); } } }
-
在UserServiceImpl中的getUserInfo方法中调用刚刚创建的getMenuListByUserId方法:
//权限列表 List<Menu> menuList = menuService.getMenuListByUserId(loginUser.getId()); data.put("menuList",menuList);
前端配置
-
找到之前的路由配置(src/router/index.js),保留基础路由,将其他的删掉或注释:
export const constantRoutes = [ { path: '/login', component: () => import('@/views/login/index'), hidden: true }, { path: '/404', component: () => import('@/views/404'), hidden: true }, { path: '/', component: Layout, redirect: '/dashboard', children: [{ path: 'dashboard', name: 'Dashboard', component: () => import('@/views/dashboard/index'), meta: { title: '首页', icon: 'dashboard' , affix:true} }] }, ]
-
获取菜单数据并保存至Vuex(src/store/modules/user.js)
import { login, logout, getInfo } from '@/api/user' import { getToken, setToken, removeToken } from '@/utils/auth' import { resetRouter } from '@/router' const getDefaultState = () => { return { token: getToken(), name: '', avatar: '', menuList:[] } } const state = getDefaultState() const mutations = { RESET_STATE: (state) => { Object.assign(state, getDefaultState()) }, SET_TOKEN: (state, token) => { state.token = token }, SET_NAME: (state, name) => { state.name = name }, SET_AVATAR: (state, avatar) => { state.avatar = avatar }, SET_MENU_LIST: (state,menuList) => { state.menuList=menuList } } const actions = { // user login login({ commit }, userInfo) { const { username, password } = userInfo return new Promise((resolve, reject) => { login({ username: username.trim(), password: password }).then(response => { const { data } = response commit('SET_TOKEN', data.token) setToken(data.token) resolve() }).catch(error => { reject(error) }) }) }, // get user info getInfo({ commit, state }) { return new Promise((resolve, reject) => { getInfo(state.token).then(response => { const { data } = response if (!data) { return reject('Verification failed, please Login again.') } const { name, avatar, menuList} = data commit('SET_NAME', name) commit('SET_AVATAR', avatar) commit('SET_MENU_LIST',menuList) resolve(data) }).catch(error => { reject(error) }) }) }, // user logout logout({ commit, state }) { return new Promise((resolve, reject) => { logout(state.token).then(() => { removeToken() // must remove token first resetRouter() commit('RESET_STATE') resolve() }).catch(error => { reject(error) }) }) }, // remove token resetToken({ commit }) { return new Promise(resolve => { removeToken() // must remove token first commit('RESET_STATE') resolve() }) } } export default { namespaced: true, state, mutations, actions }
-
修改src/store/getters.js中的const getters中的内容
const getters = { sidebar: state => state.app.sidebar, device: state => state.app.device, token: state => state.user.token, avatar: state => state.user.avatar, name: state => state.user.name, menuList: state => state.user.menuList, visitedViews: state => state.tagsView.visitedViews, cachedViews: state => state.tagsView.cachedViews, permission_routes: state => state.permission.routes } export default getters
-
路由转换:修改src目录下的permission.js
import router from './router' import store from './store' import { Message } from 'element-ui' import NProgress from 'nprogress' // progress bar import 'nprogress/nprogress.css' // progress bar style import { getToken } from '@/utils/auth' // get token from cookie import getPageTitle from '@/utils/get-page-title' import Layout from '@/layout' NProgress.configure({ showSpinner: false }) // NProgress Configuration const whiteList = ['/login'] // no redirect whitelist router.beforeEach(async(to, from, next) => { // start progress bar NProgress.start() // set page title document.title = getPageTitle(to.meta.title) // determine whether the user has logged in const hasToken = getToken() if (hasToken) { if (to.path === '/login') { // if is logged in, redirect to the home page next({ path: '/' }) NProgress.done() } else { const hasGetUserInfo = store.getters.name if (hasGetUserInfo) { next() } else { try { // get user info await store.dispatch('user/getInfo') //路由转换 let myRoutes=myFilterAsyncRoutes(store.getters.menuList); //404 myRoutes.push({ path:'*', redirect:'/404', hidden:true }); //动态添加路由 router.addRoutes(myRoutes); //存至全局变量 global.myRoutes=myRoutes; next({...to,replace:true}) // 防止刷新后页面空白 //next() } catch (error) { // remove token and go to login page to re-login await store.dispatch('user/resetToken') Message.error(error || 'Has Error') next(`/login?redirect=${to.path}`) NProgress.done() } } } } else { /* has no token*/ if (whiteList.indexOf(to.path) !== -1) { // in the free login whitelist, go directly next() } else { // other pages that do not have permission to access are redirected to the login page. next(`/login?redirect=${to.path}`) NProgress.done() } } }) router.afterEach(() => { // finish progress bar NProgress.done() }) function myFilterAsyncRoutes(menuList) { menuList.filter(menu => { if (menu.component === 'Layout') { menu.component = Layout console.log(menu.component); } else { menu.component = require(`@/views/${menu.component}.vue`).default } // 递归处理子菜单 if (menu.children && menu.children.length) { menu.children = myFilterAsyncRoutes(menu.children) } return true }) return menuList; }
-
路由合并(src/layout/components/sidebar/index.vue)
routes() { return this.$router.options.routes.concat(global.myRoutes); },