From 0894833b8fc4c92452587d4a73eb3c7bb457e33b Mon Sep 17 00:00:00 2001 From: root Date: Mon, 9 Mar 2026 19:43:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=20#3=20=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E9=A1=B5=E9=9D=A2=E5=92=8C=E8=AE=A4=E8=AF=81=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.js | 3 +-- src/router/index.js | 36 +++++++++++++++++++++++++++++------- src/stores/index.js | 3 +++ src/stores/user.js | 16 +++++++++++++++- src/views/login/index.vue | 7 +++++-- 5 files changed, 53 insertions(+), 12 deletions(-) create mode 100644 src/stores/index.js 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 @@