feat:前端增加全局路由钩子

This commit is contained in:
fanxb 2022-03-20 22:19:37 +08:00
parent 022d24ae54
commit ff87689671
8 changed files with 159 additions and 98 deletions

View File

@ -0,0 +1,18 @@
<template>
<div></div>
</template>
<script>
import { mapState } from "vuex";
export default {
name: "homeTop",
data() {
return {};
},
computed: {
...mapState("globalConfig", ["userInfo"]),
},
};
</script>
<style lang="less" scoped></style>

View File

@ -1,5 +1,7 @@
import Vue from "vue"; import Vue from "vue";
import VueRouter from "vue-router"; import VueRouter from "vue-router";
import vuex from "../store/index.js";
import { GLOBAL_CONFIG, SUPPORT_NO_LOGIN, TOKEN } from "@/store/modules/globalConfig";
Vue.use(VueRouter); Vue.use(VueRouter);
@ -17,11 +19,11 @@ const routes = [
path: "/public", path: "/public",
component: () => import("@/views/public/index"), component: () => import("@/views/public/index"),
children: [ children: [
{ path: "/login", component: () => import("@/views/public/login/index") }, { path: "login", component: () => import("@/views/public/login/index") },
{ path: "/register", component: () => import("@/views/public/register/index") }, { path: "register", component: () => import("@/views/public/register/index") },
{ path: "/resetPassword", component: () => import("@/views/public/passwordReset/index") }, { path: "resetPassword", component: () => import("@/views/public/passwordReset/index") },
{ path: "/oauth/github", component: () => import("@/views/public/oauth/github/index") }, { path: "oauth/github", component: () => import("@/views/public/oauth/github/index") },
{ path: "/404", component: () => import("@/views/public/notFound/index") } { path: "404", component: () => import("@/views/public/notFound/index") },
] ]
}, },
{ path: "*", redirect: "/public/404" } { path: "*", redirect: "/public/404" }
@ -32,4 +34,40 @@ const router = new VueRouter({
routes routes
}); });
/**
* 在此进行登录信息判断以及重定向到登录页面
*/
router.beforeEach((to, from, next) => {
let supportNoLogin = to.path === '/' || to.path.startsWith("/public");
vuex.commit(GLOBAL_CONFIG + "/" + SUPPORT_NO_LOGIN, supportNoLogin);
if (!supportNoLogin && !checkJwtValid()) {
//如不支持未登录进入切jwt已过期直接跳转到登录页面
next({
path: "/public/login?to=" + btoa(location.href),
replace: true
});
} else {
next();
}
})
/**
* 检查jwt是否有效
*/
function checkJwtValid () {
let token = vuex.state[GLOBAL_CONFIG][TOKEN];
try {
if (token && token.trim().length > 0) {
//检查token是否还有效
let content = window.atob(token.split(".")[1]);
if (content.exp > Date.now() / 1000) {
return true;
}
}
} catch (err) {
console.error(err);
}
return false;
}
export default router; export default router;

View File

@ -1,105 +1,115 @@
import localforage from "localforage"; import localforage from "localforage";
import HttpUtil from "../../util/HttpUtil"; import HttpUtil from "../../util/HttpUtil";
const USER_INFO = "userInfo"; export const GLOBAL_CONFIG = "globalConfig";
const TOKEN = "token"; export const USER_INFO = "userInfo";
const SERVER_CONFIG = "serverConfig"; export const TOKEN = "token";
export const SERVER_CONFIG = "serverConfig";
export const SUPPORT_NO_LOGIN = "supportNoLogin";
/** /**
* 存储全局配置 * 存储全局配置
*/ */
const state = { const state = {
/** /**
* 用户信息 * 用户信息
*/ */
[USER_INFO]: {}, [USER_INFO]: {},
/** /**
* token * token,null说明未获取登录凭证
*/ */
[TOKEN]: null, [TOKEN]: null,
/** /**
* 是否已经初始化完成,避免多次重复初始化 * 是否已经初始化完成,避免多次重复初始化
*/ */
isInit: false, isInit: false,
/** /**
* 是否移动端 * 是否移动端
*/ */
isPhone: false, isPhone: false,
/** /**
* 服务端全局配置 * 是否支持未登录进入页面
*/ */
[SERVER_CONFIG]: {} [SUPPORT_NO_LOGIN]: false,
/**
* 服务端全局配置
*/
[SERVER_CONFIG]: {}
}; };
const getters = {}; const getters = {};
const actions = { const actions = {
//登陆后的,初始化数据 //登陆后的,初始化数据
async init(context) { async init (context) {
if (context.state.isInit) { if (context.state.isInit) {
return; return;
} }
const token = await localforage.getItem(TOKEN); const token = await localforage.getItem(TOKEN);
await context.dispatch("setToken", token); await context.dispatch("setToken", token);
let userInfo = await localforage.getItem(USER_INFO); let userInfo = await localforage.getItem(USER_INFO);
if (userInfo) { if (userInfo) {
context.commit(USER_INFO, userInfo); context.commit(USER_INFO, userInfo);
} }
try { try {
await context.dispatch("refreshUserInfo"); await context.dispatch("refreshUserInfo");
} catch (err) { } catch (err) {
console.error(err); console.error(err);
} }
context.commit("isInit", true); context.commit("isInit", true);
context.commit("isPhone", /Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)); context.commit("isPhone", /Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent));
}, },
async refreshUserInfo({ commit }) { async refreshUserInfo ({ commit }) {
let userInfo = await HttpUtil.get("/user/currentUserInfo"); let userInfo = await HttpUtil.get("/user/currentUserInfo");
await localforage.setItem(USER_INFO, userInfo); await localforage.setItem(USER_INFO, userInfo);
commit(USER_INFO, userInfo); commit(USER_INFO, userInfo);
}, },
async setToken({ commit }, token) { async setToken ({ commit }, token) {
await localforage.setItem(TOKEN, token); await localforage.setItem(TOKEN, token);
commit(TOKEN, token); commit(TOKEN, token);
}, },
//登出清除数据 //登出清除数据
async clear(context) { async clear (context) {
await localforage.removeItem("userInfo"); await localforage.removeItem("userInfo");
await localforage.removeItem("token"); await localforage.removeItem("token");
context.commit(USER_INFO, null); context.commit(USER_INFO, null);
context.commit(TOKEN, null); context.commit(TOKEN, null);
context.commit("isInit", false); context.commit("isInit", false);
}, },
/** /**
* 从服务器读取全局配置 * 从服务器读取全局配置
*/ */
async refreshServerConfig({ commit }) { async refreshServerConfig ({ commit }) {
commit(SERVER_CONFIG, await HttpUtil.get("/common/config/global")); commit(SERVER_CONFIG, await HttpUtil.get("/common/config/global"));
} }
}; };
const mutations = { const mutations = {
userInfo(state, userInfo) { userInfo (state, userInfo) {
state.userInfo = userInfo; state.userInfo = userInfo;
}, },
token(state, token) { token (state, token) {
state.token = token; state.token = token;
}, },
isInit(state, isInit) { isInit (state, isInit) {
state.isInit = isInit; state.isInit = isInit;
}, },
isPhone(state, status) { isPhone (state, status) {
state.isPhone = status; state.isPhone = status;
}, },
[SERVER_CONFIG](state, serverConfig) { [SERVER_CONFIG] (state, serverConfig) {
state[SERVER_CONFIG] = serverConfig; state[SERVER_CONFIG] = serverConfig;
} },
[SUPPORT_NO_LOGIN] (state, val) {
state[SUPPORT_NO_LOGIN] = val;
}
}; };
export default { export default {
namespaced: true, namespaced: true,
state, state,
getters, getters,
actions, actions,
mutations mutations
}; };

View File

@ -1,5 +0,0 @@
/**
* 测试用
*/
export const TEST = "test";
export const COUNT = "count";

View File

@ -9,9 +9,9 @@
</template> </template>
<script> <script>
import Content from "@/layout/main/Content.vue"; import Content from "@/layout/manage/Content.vue";
import Bottom from "@/layout/main/Bottom.vue"; import Bottom from "@/layout/manage/Bottom.vue";
import Top from "@//layout/main/Top.vue"; import Top from "@/layout/manage/Top.vue";
import httpUtil from "../../util/HttpUtil"; import httpUtil from "../../util/HttpUtil";
export default { export default {