diff --git a/src/main.js b/src/main.js index 1238c56..7263518 100644 --- a/src/main.js +++ b/src/main.js @@ -1,14 +1,13 @@ import { createApp } from 'vue' -import { createPinia } from 'pinia' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import * as ElementPlusIconsVue from '@element-plus/icons-vue' import router from './router' import App from './App.vue' +import { pinia } from './stores' import './style.css' const app = createApp(App) -const pinia = createPinia() // 注册所有 Element Plus 图标 for (const [key, component] of Object.entries(ElementPlusIconsVue)) { diff --git a/src/router/index.js b/src/router/index.js index 10fc0c0..fd53555 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,4 +1,6 @@ import { createRouter, createWebHistory } from 'vue-router' +import { useUserStore } from '../stores/user' +import { pinia } from '../stores' const routes = [ { @@ -83,15 +85,35 @@ const router = createRouter({ }) // 路由守卫 -router.beforeEach((to, from, next) => { - const token = localStorage.getItem('admin_token') +router.beforeEach(async (to, from, next) => { + const userStore = useUserStore(pinia) + const token = userStore.token - if (to.meta.requiresAuth && !token) { - next('/login') - } else if (to.path === '/login' && token) { - next('/') - } else { + if (!to.meta.requiresAuth) { + if (to.path === '/login' && token) { + try { + await userStore.ensureProfileLoaded() + next('/') + } catch (error) { + next() + } + return + } next() + return + } + + if (!token) { + next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) + return + } + + try { + await userStore.ensureProfileLoaded() + next() + } catch (error) { + userStore.logout() + next('/login') } }) diff --git a/src/stores/index.js b/src/stores/index.js new file mode 100644 index 0000000..c569ef7 --- /dev/null +++ b/src/stores/index.js @@ -0,0 +1,3 @@ +import { createPinia } from 'pinia' + +export const pinia = createPinia() diff --git a/src/stores/user.js b/src/stores/user.js index 4c7ba5a..3e40a71 100644 --- a/src/stores/user.js +++ b/src/stores/user.js @@ -1,5 +1,5 @@ import { defineStore } from 'pinia' -import { login as loginApi, getProfile } from '../api/auth' +import { getProfile, login as loginApi, logout as logoutApi } from '../api/auth' export const useUserStore = defineStore('user', { state: () => ({ @@ -35,7 +35,21 @@ export const useUserStore = defineStore('user', { } }, + async ensureProfileLoaded() { + if (!this.token) { + throw new Error('未登录') + } + if (this.userInfo) { + return this.userInfo + } + const res = await this.fetchUserInfo() + return res.data + }, + logout() { + if (this.token) { + logoutApi().catch(() => {}) + } this.token = '' this.userInfo = null localStorage.removeItem('admin_token') diff --git a/src/views/login/index.vue b/src/views/login/index.vue index ea5b7d5..258b3f3 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -59,12 +59,13 @@