在vuex中存储从后端获取的用户角色,将获取的roles存储在mutations的函数中,通过mutations的函数将roles数据存储在state中。
在用户登陆之前进行路由拦截
如果该用户登录的用户名,密码正确,则将token值存储在localstroge中,在beforeEach中通过判断是否有token,如果token存在且该用户跳转页面是登录页面,则放行,如果token存在跳转的路径是其他页面,得判断角色是否存在,若存在则放行否则还需要去获取用户的角色信息,并将获取的角色信息(roleId)去请求后端的路由信息,此时的路由是后端返回的路由信息通过处理将后台获取的路由信息转换为动态路由,这个过程首先需要将后台的路由信息进行递归遍历,将遍历后的数据返回,将返回的数据通过Promise的resolve进行数据处理。
accessRoutes=await store.dispatch( //accessRoutes是从后端获取的路由信 “permission/generateRoutes”, roles[0] );将路由信息添加到router中 router.addRoutes(accessRoutes); next({ …to, replace: true }) //放行
//路由拦截
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";
NProgress.configure({ showSpinner: false }); // NProgress Configuration
const whiteList = ["/login", "/auth-redirect"]; // no redirect whitelist
router.beforeEach(async (to, from, next) => {
// start progress bar
NProgress.start();
// NProgress.inc()
// set page title
document.title = getPageTitle(to.meta.title);
// determine whether the user has logged in
const hasToken = getToken();
if (hasToken) {
//用户登录并获取到cookie中的值
if (to.path === "/login") {
//跳转的路径是登录页面
// if is logged in, redirect to the home page
next({ path: "/" }); //放行
NProgress.done(); //进度条 hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939
} else {
//跳转的页面时系统内的页面
// determine whether the user has obtained his permission roles through getInfo
const hasRoles = store.getters.roles && store.getters.roles.length > 0; //角色的判断
if (hasRoles) {
//有角色信息放行
next();
} else {
//没有角色信息则请求vuex中的user中的getInfo
try {
// get user info
// note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
const { roles } = await store.dispatch("user/getInfo");
// generate accessible routes map based on roles
//请求路由信息
const accessRoutes = await store.dispatch(
//accessRoutes是从后端获取的路由信息
"permission/generateRoutes",
roles[0]
);
// dynamically add accessible routes
router.addRoutes(accessRoutes); //动态路由信息
// hack method to ensure that addRoutes is complete
// set the replace: true, so the navigation will not leave a history record
next({ ...to, replace: true }); //解决出现白屏的问题,...to的目的是路由添加完了在进入页面,replace-重进一次,不保留重复历史
} 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();
});
//permission/generateRoutes
generateRoutes({ commit }, roles) {
//角色信息--默认的角色(初始化)
return new Promise((resolve) => {
let roleId;
if (roles.roleCode == "SUPERADMIN") {
//管理员,角色id为roleCode
roleId = roles.roleCode;
} else {
roleId = roles.id; //不是管理员则获取role.id
}
//请求路由的接口
getRouters({ roleId }).then((res) => {
const accessedRoutes = generateRoutes(res.data.list); //将res.data.list生成路由信息
console.log(accessedRoutes, "accessedRoutes");
commit("SET_ROUTES", accessedRoutes);
resolve(accessedRoutes);
});
//根据角色id请求权限
getPermissions({ roleId }).then((res) => {
console.log(res, "di");
commit("SET_PERMISSION", res.data.list);
});
});
},
//user/getInfo
// get user info---角色信息
getInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo(state.token)
.then((response) => {
const { data } = response;
if (!data) {
reject("Verification failed, please Login again.");
}
const { roles, userInfo } = data;
// roles must be a non-empty array
if (!roles || roles.length <= 0) {
reject("getInfo: roles must be a non-null array!");
}
commit("CRT_ROLE", roles[0]);
commit("SET_ROLES", roles); //将roles存储到vuex
commit("SET_NAME", userInfo.username);
commit("SET_AVATAR", userInfo.portrait);
commit("SET_INTRODUCTION", "");
resolve(data);
})
.catch((error) => {
reject(error);
});
});
},
//将res.data.list生成路由信息
export function generateRoutes(array) {
var routerArray = [];
for (let i = 0; i < array.length; i++) {
const temp = array[i];
const router = {};
const meta = {};
meta["title"] = temp.name;
meta["icon"] = temp.icon;
meta["noCache"] = temp.noCache;
meta["activeMenu"] = temp.activeMenu;
meta["menuId"] = temp.id;
if (temp.component === "Layout") {
router["component"] = () => import("@/layout");
} else {
const path = temp.component
? temp.component
: "/views/error-page/404.vue";
router["component"] = (resolve) => require([`@/views/${path}`], resolve);
}
router["name"] = temp.name;
router["path"] = temp.path;
router["hidden"] = temp.hidden;
router["redirect"] = temp.redirect;
router["meta"] = meta;
if (temp.children) {
const children = generateRoutes(temp.children);
router["children"] = children;
}
routerArray.push(router);
}
return routerArray;
}