diff --git a/src/components/CustomPagination.vue b/src/components/CustomPagination.vue new file mode 100644 index 0000000..089d064 --- /dev/null +++ b/src/components/CustomPagination.vue @@ -0,0 +1,87 @@ + + + + + diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue index 0107105..721c47f 100644 --- a/src/layouts/MainLayout.vue +++ b/src/layouts/MainLayout.vue @@ -110,7 +110,7 @@ - + diff --git a/src/layouts/establish.vue b/src/layouts/establish.vue index 4171591..d675d29 100644 --- a/src/layouts/establish.vue +++ b/src/layouts/establish.vue @@ -149,7 +149,7 @@ const pageButtons = { // 文章保存页面按钮 articlesave: [ - { id: 'view-articles', label: '查看文章列表', icon: 'icon-new-tag' }, + { id: 'view-articles', label: '文章', icon: 'icon-new-tag' }, ...baseButtons ], @@ -164,7 +164,8 @@ const pageButtons = { const isbuttonsave = () => { try { // 获取当前页面路径名称 - const currentPath = globalStore.getValue('localpath')?.name || 'default'; + // const currentPath = globalStore.getValue('localpath')?.name || 'default'; + const currentPath = router.currentRoute.value.path.split('/')[1]; // 返回对应页面的按钮配置,如果没有则返回默认配置 return pageButtons[currentPath] || pageButtons.default; } catch (error) { diff --git a/src/services/apiService.js b/src/services/apiService.js index dbece34..dd78763 100644 --- a/src/services/apiService.js +++ b/src/services/apiService.js @@ -9,12 +9,53 @@ const api = axios.create({ 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 60bc21e..d41c60a 100644 --- a/src/services/articleService.js +++ b/src/services/articleService.js @@ -7,14 +7,14 @@ import api from './apiService' class ArticleService { /** * 分页查询文章列表 - * @param {import('../types').PaginationParams} params - 分页查询参数 + * @param {import('../types').ArticlePagination} params - 分页查询参数 * @param status 文章状态(0:未发表 1:已发表 2:已删除) * @param page 页码,从0开始(可选,默认为0) * @param size 每页大小(可选,默认为10,最大为100) * @returns {Promise>} */ getPagedArticles(params = {}) { - return api.get(`/articles/status/page?title=${params.title || ''}&categoryid=${params.categoryid || 0}&attributeid=${params.attributeid || 0}&status=${params.status || 1}&page=${params.page || 0}&size=${params.size || 10}`) + 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}`) } /** * 获取已发布文章列表 diff --git a/src/services/categoryAttributeService.js b/src/services/categoryAttributeService.js index c91ca62..f8bc974 100644 --- a/src/services/categoryAttributeService.js +++ b/src/services/categoryAttributeService.js @@ -10,7 +10,7 @@ class CategoryAttributeService { * @returns {Promise>} */ getAllAttributes() { - return api.get('/category-attributes') + return api.get('/categoryattributes') } /** @@ -19,7 +19,7 @@ class CategoryAttributeService { * @returns {Promise>} */ getAttributeById(attributeid) { - return api.get(`/category-attributes/${attributeid}`) + return api.get(`/categoryattributes/${attributeid}`) } /** @@ -28,7 +28,7 @@ class CategoryAttributeService { * @returns {Promise>} */ getAttributesByCategory(categoryid) { - return api.get(`/category-attributes/category/${categoryid}`) + return api.get(`/categoryattributes/category/${categoryid}`) } /** @@ -37,7 +37,7 @@ class CategoryAttributeService { * @returns {Promise>} */ createAttribute(attributeData) { - return api.post('/category-attributes', attributeData) + return api.post('/categoryattributes', attributeData) } } diff --git a/src/services/categoryService.js b/src/services/categoryService.js index e66384f..31d9a64 100644 --- a/src/services/categoryService.js +++ b/src/services/categoryService.js @@ -11,6 +11,13 @@ class CategoryService { getAllCategories() { return api.get('/categories') } + /** + * 获取分类树 + * @returns {Promise>} + */ + getCategoryTree() { + return api.get('/categories/tree') + } } // 创建并导出服务实例 diff --git a/src/services/messageService.js b/src/services/messageService.js index a514fa9..1293d58 100644 --- a/src/services/messageService.js +++ b/src/services/messageService.js @@ -11,7 +11,7 @@ class MessageService { * @returns {Promise>} */ getMessageCountByArticleId(articleid) { - return apiService.get(`/messages/count?articleid=${articleid}`) + return apiService.get(`/messages/count/${articleid}`) } /** @@ -33,9 +33,6 @@ class MessageService { * @param {number} articleid - 文章ID * @returns {Promise>} */ - getMessagesByArticleId(articleid) { - return apiService.get(`/messages/article/${articleid}`) - } /** * 获取所有留言 diff --git a/src/services/nonsenseService.js b/src/services/nonsenseService.js index 017776d..1b276e7 100644 --- a/src/services/nonsenseService.js +++ b/src/services/nonsenseService.js @@ -10,12 +10,12 @@ class NonsenseService { return apiService.get('/nonsense') } /** - * 根据状态获取疯言疯语内容 - * @param {number} status - 状态值(1:已发表, 0:草稿) + * 根据分页信息获取疯言疯语内容 + * @param {import('../types').NosensePageDto} page - 分页信息对象 * @returns {Promise>} */ - getNonsenseByStatus(status){ - return apiService.get(`/nonsense/status/${status}`) + getNonsenseByStatus(page){ + return apiService.get(`/nonsense/page?status=${page.status}&pageNum=${page.pageNum}&pageSize=${page.pageSize}`) } /** * 保存疯言疯语内容 diff --git a/src/types/index.ts b/src/types/index.ts index 35e0e57..9429f89 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -32,9 +32,18 @@ export interface ArticleDto { viewCount?: number likes?: number markdownscontent: string - } - +/** + * 文章分页接口 + */ +export interface ArticlePagination { + status?: number | undefined + title?: string | undefined + attributeid?: number | undefined + categoryid?: number | undefined + pagenum?: number | undefined + pagesize?: number | undefined +} /** * 留言类型接口 */ diff --git a/src/views/Footer.vue b/src/views/Footer.vue index 5cc1d00..d74042c 100644 --- a/src/views/Footer.vue +++ b/src/views/Footer.vue @@ -12,7 +12,7 @@ @@ -74,6 +74,8 @@ onUnmounted(() => { margin-top: 3rem; padding: 2rem 0; width: 100%; + position: relative; + bottom: 0; } /* 页脚内容 */ diff --git a/src/views/aboutme.vue b/src/views/aboutme.vue index 089e091..3a255e7 100644 --- a/src/views/aboutme.vue +++ b/src/views/aboutme.vue @@ -92,7 +92,7 @@ Gradle Java 17+ + class="skill-tag-link">Java 8 @@ -124,7 +124,6 @@ const goToMessageBoard = () => { \ No newline at end of file diff --git a/vite.config.js b/vite.config.js index bcddc23..a3ad833 100644 --- a/vite.config.js +++ b/vite.config.js @@ -31,7 +31,7 @@ export default defineConfig({ // 配置API代理 '/api': { // target: 'http://www.qf1121.top', - target: 'http://localhost:7071', + target: 'http://localhost:7070', changeOrigin: true, rewrite: (path) => path }