From 47df45277ebb2d44a2a56db992d1c75a08c2723d Mon Sep 17 00:00:00 2001 From: qingfeng1121 Date: Tue, 23 Dec 2025 22:57:57 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E7=A7=BB=E9=99=A4=E8=B0=83?= =?UTF-8?q?=E8=AF=95=E6=97=A5=E5=BF=97=EF=BC=8C=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=95=B4=E6=B4=81=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/layouts/MainLayout.vue | 2 +- src/router/Router.js | 59 ++++++++++++++++++++++++++++++++-- src/services/apiService.js | 43 +------------------------ src/services/articleService.js | 2 +- src/views/articlecontents.vue | 2 +- src/views/home.vue | 2 +- src/views/nonsense.vue | 2 +- vite.config.js | 11 ------- 8 files changed, 62 insertions(+), 61 deletions(-) diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue index 721c47f..345d7c0 100644 --- a/src/layouts/MainLayout.vue +++ b/src/layouts/MainLayout.vue @@ -257,7 +257,7 @@ const handleAttributeClick = (attribute: any) => { id: attribute.attributeid, name: attribute.attributename }) - console.log(attribute) + // console.log(attribute) router.push('/home/aericletype',) closeAttributeModal() } diff --git a/src/router/Router.js b/src/router/Router.js index 1fb0ded..24bebc9 100644 --- a/src/router/Router.js +++ b/src/router/Router.js @@ -8,6 +8,10 @@ import AboutMePage from '../views/aboutme.vue' import ArticleContentPage from '../views/articlecontents.vue' import LoginPage from '../views/login.vue' import ArticleSavePage from '../views/articlesave.vue' +// 导入全局状态管理 +import { useGlobalStore } from '@/store/globalStore' +// 导入Element Plus消息组件 +import { ElMessage } from 'element-plus' /** * 路由配置数组 @@ -101,7 +105,8 @@ const routes = [ name: 'articlesave', component: ArticleSavePage, meta: { - title: '保存文章' + title: '保存文章', + requiresAuth: true // 需要登录才能访问 } } ] @@ -119,15 +124,63 @@ const router = createRouter({ }) /** - * 全局路由守卫 - 处理页面标题 + * 检查token是否过期的工具函数 + * @param {string} token - JWT token字符串 + * @returns {boolean} - token是否已过期 + */ +const isTokenExpired = (token) => { + try { + const payload = JSON.parse(atob(token.split('.')[1])) + const exp = payload.exp * 1000 // 转换为毫秒 + return Date.now() > exp + } catch (error) { + return true // 解析失败视为过期 + } +} + +/** + * 全局路由守卫 - 处理页面标题和认证 */ router.beforeEach((to, from, next) => { + // 设置页面标题 if (to.meta.title) { document.title = to.meta.title + ' - 个人博客' } else { document.title = '个人博客' } - next() + + // 获取全局状态 + const globalStore = useGlobalStore() + + // 从localStorage获取token + const token = localStorage.getItem('token') + + // 如果有token但登录状态为false,自动恢复登录状态 + if (token && !globalStore.Login && !isTokenExpired(token)) { + globalStore.setLoginStatus(true) + } + + // 如果有token但已过期,清除token和登录状态 + if (token && isTokenExpired(token)) { + localStorage.removeItem('token') + globalStore.setLoginStatus(false) + ElMessage.error('登录已过期,请重新登录') + } + + // 检查是否需要认证 + if (to.meta.requiresAuth) { + // 如果已登录,允许访问 + if (globalStore.Login) { + next() + } else { + // 未登录,重定向到登录页 + ElMessage.warning('请先登录') + next('/login') + } + } else { + // 不需要认证的路由,直接允许访问 + next() + } }) export default router; \ No newline at end of file diff --git a/src/services/apiService.js b/src/services/apiService.js index dd78763..6984d35 100644 --- a/src/services/apiService.js +++ b/src/services/apiService.js @@ -4,58 +4,17 @@ import { ElMessage } from 'element-plus' // 创建axios实例 const api = axios.create({ - baseURL: '/api', // API基础URL,使用相对路径,通过Vite代理转发 + baseURL: '/api', timeout: 10000, // 请求超时时间 withCredentials: true // 允许跨域请求携带凭证(如cookies) }) -// 解析JWT token,获取过期时间 -const parseJwt = (token) => { - try { - // 移除Bearer前缀(如果有) - const pureToken = token.replace('Bearer ', '') - // 解析payload部分 - const base64Url = pureToken.split('.')[1] - const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/') - const jsonPayload = decodeURIComponent( - window - .atob(base64) - .split('') - .map((c) => `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`) - .join('') - ) - return JSON.parse(jsonPayload) - } catch (e) { - console.error('解析JWT token失败:', e) - return null - } -} - -// 验证token是否过期 -const isTokenExpired = (token) => { - const decodedToken = parseJwt(token) - if (!decodedToken || !decodedToken.exp) { - return true // 如果解析失败或没有过期时间,认为token无效 - } - // 比较过期时间和当前时间(转换为秒) - const currentTime = Math.floor(Date.now() / 1000) - return decodedToken.exp < currentTime -} - // 请求拦截器 api.interceptors.request.use( config => { // 从localStorage获取token let token = localStorage.getItem('token') if (token) { - // 验证token是否过期 - if (isTokenExpired(token)) { - // token过期,移除token并跳转到登录页 - localStorage.removeItem('token') - ElMessage.error('登录已过期,请重新登录') - // window.location.href = '/login' - return Promise.reject(new Error('token已过期')) - } // 确保不重复添加Bearer前缀 if (!token.startsWith('Bearer ')) { config.headers['Authorization'] = `Bearer ${token}` diff --git a/src/services/articleService.js b/src/services/articleService.js index d41c60a..2a84c15 100644 --- a/src/services/articleService.js +++ b/src/services/articleService.js @@ -14,7 +14,7 @@ class ArticleService { * @returns {Promise>} */ getPagedArticles(params = {}) { - return api.get(`/articles/status/page?title=${params.title || ''}&categoryid=${params.categoryid || ''}&attributeid=${params.attributeid || ''}&status=${params.status !== undefined ? params.status : 1}&page=${params.page || 0}&size=${params.size || 10}`) + return api.get(`/articles/status/page?title=${params.title || ''}&categoryid=${params.categoryid || 0}&attributeid=${params.attributeid || 0}&status=${params.status !== undefined ? params.status : 1}&page=${params.page || 0}&size=${params.size || 10}`) } /** * 获取已发布文章列表 diff --git a/src/views/articlecontents.vue b/src/views/articlecontents.vue index 3d11e5c..bf03492 100644 --- a/src/views/articlecontents.vue +++ b/src/views/articlecontents.vue @@ -151,7 +151,7 @@ const fetchArticleData = async (): Promise => { try { // 从全局状态获取文章信息 const response = await globalStore.getValue('articleInfo') - console.log('获取文章数据:', response) + // console.log('获取文章数据:', response) return response || null } catch (err) { console.error('获取文章数据失败:', err) diff --git a/src/views/home.vue b/src/views/home.vue index f9b49d2..25cf9b8 100644 --- a/src/views/home.vue +++ b/src/views/home.vue @@ -135,7 +135,7 @@ const fetchArticles = async () => { return } // 3. 为文章列表补充额外信息 - console.log('补充额外信息后的文章列表:', response.data) + // console.log('补充额外信息后的文章列表:', response.data) // 4. 更新文章列表 articleList.value = response.data // 5. 更新总页数 diff --git a/src/views/nonsense.vue b/src/views/nonsense.vue index db0eaca..8331df0 100644 --- a/src/views/nonsense.vue +++ b/src/views/nonsense.vue @@ -112,7 +112,7 @@ const loadNonsenseList = async () => { // 初始化字符样式 // initializeCharStyles() // 开始颜色变化定时器 - console.log(displayedNonsenseList.value) + // console.log(displayedNonsenseList.value) } else { ElMessage.error('加载吐槽内容失败') error.value = true diff --git a/vite.config.js b/vite.config.js index a3ad833..2b28865 100644 --- a/vite.config.js +++ b/vite.config.js @@ -7,8 +7,6 @@ import AutoImport from 'unplugin-auto-import/vite' import Components from 'unplugin-vue-components/vite' import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' - -// https://vite.dev/config/ export default defineConfig({ plugins: [ vue(), @@ -27,15 +25,6 @@ export default defineConfig({ }, server: { host: '0.0.0.0', - proxy: { - // 配置API代理 - '/api': { - // target: 'http://www.qf1121.top', - target: 'http://localhost:7070', - changeOrigin: true, - rewrite: (path) => path - } - } }, })