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 VueRouter from "vue-router";
import vuex from "../store/index.js";
import { GLOBAL_CONFIG, SUPPORT_NO_LOGIN, TOKEN } from "@/store/modules/globalConfig";
Vue.use(VueRouter);
@ -17,11 +19,11 @@ const routes = [
path: "/public",
component: () => import("@/views/public/index"),
children: [
{ path: "/login", component: () => import("@/views/public/login/index") },
{ path: "/register", component: () => import("@/views/public/register/index") },
{ path: "/resetPassword", component: () => import("@/views/public/passwordReset/index") },
{ path: "/oauth/github", component: () => import("@/views/public/oauth/github/index") },
{ path: "/404", component: () => import("@/views/public/notFound/index") }
{ path: "login", component: () => import("@/views/public/login/index") },
{ path: "register", component: () => import("@/views/public/register/index") },
{ path: "resetPassword", component: () => import("@/views/public/passwordReset/index") },
{ path: "oauth/github", component: () => import("@/views/public/oauth/github/index") },
{ path: "404", component: () => import("@/views/public/notFound/index") },
]
},
{ path: "*", redirect: "/public/404" }
@ -32,4 +34,40 @@ const router = new VueRouter({
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;

View File

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

View File

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

View File

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