diff --git a/README_API.md b/README_API.md
new file mode 100644
index 0000000..515b1c8
--- /dev/null
+++ b/README_API.md
@@ -0,0 +1,407 @@
+# 前端调用文档
+
+## 项目概述
+
+这是一个基于Vue 3的博客前端项目,提供文章展示、分类浏览、留言板等功能。项目使用Vue 3 Composition API进行开发,集成了Vue Router进行路由管理,并使用Element Plus等UI库提供用户界面。
+
+## 技术栈
+
+- **前端框架**: Vue 3
+- **构建工具**: Vite
+- **路由管理**: Vue Router 4
+- **UI组件库**: Element Plus、Ant Design Vue
+- **HTTP客户端**: Axios
+- **编程语言**: JavaScript/TypeScript
+
+## 项目结构
+
+```
+src/
+├── App.vue # 应用根组件
+├── assets/ # 静态资源
+│ └── index.css # 全局样式
+├── img/ # 图片资源
+├── index.vue # 首页主组件
+├── main.js # 应用入口文件
+├── router/ # 路由配置
+│ └── Router.js # 路由定义
+└── views/ # 视图组件
+ ├── aboutme.vue # 关于页面
+ ├── aericle.vue # 文章分类目录页面
+ ├── articlecontents.vue # 文章内容页面
+ ├── home.vue # 首页内容组件
+ ├── leftmodlue.vue # 左侧边栏组件
+ ├── messageboard.vue # 留言板页面
+ └── nonsense.vue # 疯言疯语页面
+```
+
+## 路由配置
+
+路由配置位于 `src/router/Router.js`,定义了应用的所有路由映射关系:
+
+| 路由路径 | 组件 | 功能描述 |
+|---------|------|---------|
+| `/` | home.vue | 默认路由,重定向到首页 |
+| `/:type` | home.vue | 首页,可根据type参数筛选文章 |
+| `/aericle` | aericle.vue | 文章分类目录页面 |
+| `/nonsense` | nonsense.vue | 疯言疯语页面 |
+| `/message` | messageboard.vue | 留言板页面 |
+| `/about` | aboutme.vue | 关于页面 |
+| `/articlecontents/:url` | articlecontents.vue | 文章内容详情页 |
+
+## 主要组件说明
+
+### 1. App.vue
+
+应用根组件,负责渲染主页面组件。
+
+```vue
+
+
+
+
+```
+
+### 2. index.vue
+
+主页面组件,包含顶部导航栏、Hero区域和内容展示区。
+
+主要功能:
+- 响应式布局,适配不同屏幕宽度
+- 导航菜单切换不同页面
+- 打字机效果展示欢迎语
+
+### 3. home.vue
+
+首页文章列表组件,用于展示文章卡片列表。
+
+主要功能:
+- 展示文章标题、作者、发布时间等信息
+- 点击文章卡片跳转到文章详情页
+- 支持文章筛选功能
+
+### 4. aericle.vue
+
+文章分类目录组件,展示文章的分类结构。
+
+主要功能:
+- 展示不同分类下的文章数量
+- 点击分类项可以跳转到对应的文章列表
+
+### 5. articlecontents.vue
+
+文章内容详情组件,用于展示单篇文章的完整内容。
+
+主要功能:
+- 获取URL参数并展示对应文章内容
+- 支持通过参数向服务器请求相关文章
+
+### 6. messageboard.vue
+
+留言板组件,支持用户发表评论和回复。
+
+主要功能:
+- 展示留言列表和回复
+- 支持发表新留言
+- 支持回复他人留言
+
+### 7. nonsense.vue
+
+疯言疯语组件,展示一些非正式的简短内容。
+
+## 后端API接口
+
+项目后端基于Spring Boot开发,提供了以下主要API接口:
+
+### 文章管理API
+
+#### 1. 获取文章列表
+
+```
+GET /api/articles
+```
+
+**功能**: 获取所有文章列表
+
+**返回**: 包含文章列表的ResponseMessage对象
+
+#### 2. 获取单篇文章
+
+```
+GET /api/articles/{id}
+```
+
+**功能**: 根据ID获取单篇文章详情
+
+**参数**: id - 文章ID
+
+**返回**: 包含文章信息的ResponseMessage对象
+
+#### 3. 根据分类获取文章
+
+```
+GET /api/articles/category/{categoryId}
+```
+
+**功能**: 获取指定分类下的所有文章
+
+**参数**: categoryId - 分类ID
+
+**返回**: 包含文章列表的ResponseMessage对象
+
+#### 4. 获取热门文章
+
+```
+GET /api/articles/popular
+```
+
+**功能**: 获取浏览量最高的文章列表
+
+**返回**: 包含热门文章列表的ResponseMessage对象
+
+#### 5. 创建文章 (需要认证)
+
+```
+POST /api/articles
+```
+
+**功能**: 创建新文章
+
+**权限**: 需要AUTHOR角色
+
+**参数**: ArticleDto对象 (JSON格式)
+
+**返回**: 包含新创建文章信息的ResponseMessage对象
+
+#### 6. 更新文章 (需要认证)
+
+```
+PUT /api/articles/{id}
+```
+
+**功能**: 更新现有文章
+
+**权限**: 需要AUTHOR或ADMIN角色
+
+**参数**:
+- id - 文章ID
+- ArticleDto对象 (JSON格式)
+
+**返回**: 包含更新后文章信息的ResponseMessage对象
+
+#### 7. 删除文章 (需要认证)
+
+```
+DELETE /api/articles/{id}
+```
+
+**功能**: 删除指定文章
+
+**权限**: 需要AUTHOR或ADMIN角色
+
+**参数**: id - 文章ID
+
+**返回**: 包含被删除文章信息的ResponseMessage对象
+
+### 留言管理API
+
+#### 1. 获取所有留言
+
+```
+GET /api/messages
+```
+
+**功能**: 获取所有留言列表
+
+**返回**: 包含留言列表的ResponseMessage对象
+
+#### 2. 获取单条留言
+
+```
+GET /api/messages/{id}
+```
+
+**功能**: 根据ID获取单条留言详情
+
+**参数**: id - 留言ID
+
+**返回**: 包含留言信息的ResponseMessage对象
+
+#### 3. 保存留言
+
+```
+POST /api/messages
+```
+
+**功能**: 保存新留言
+
+**参数**: MessageDto对象 (JSON格式)
+
+**返回**: 包含保存后留言信息的ResponseMessage对象
+
+#### 4. 删除留言
+
+```
+DELETE /api/messages/{id}
+```
+
+**功能**: 删除指定留言
+
+**参数**: id - 留言ID
+
+**返回**: 包含删除结果的ResponseMessage对象
+
+## 前端API调用说明
+
+项目中使用Axios进行HTTP请求,推荐创建统一的API服务模块来封装所有后端API调用。以下是一个示例:
+
+```javascript
+import axios from 'axios';
+
+// 创建axios实例
+const api = axios.create({
+ baseURL: 'http://localhost:8080/api', // 后端API基础URL
+ timeout: 10000, // 请求超时时间
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+});
+
+// 请求拦截器
+api.interceptors.request.use(
+ config => {
+ // 可以在这里添加token等认证信息
+ const token = localStorage.getItem('token');
+ if (token) {
+ config.headers.Authorization = `Bearer ${token}`;
+ }
+ return config;
+ },
+ error => {
+ return Promise.reject(error);
+ }
+);
+
+// 响应拦截器
+api.interceptors.response.use(
+ response => {
+ return response.data;
+ },
+ error => {
+ // 统一错误处理
+ console.error('API请求错误:', error);
+ return Promise.reject(error);
+ }
+);
+
+// 文章相关API
+export const articleAPI = {
+ // 获取所有文章
+ getAllArticles: () => api.get('/articles'),
+ // 获取单篇文章
+ getArticleById: (id) => api.get(`/articles/${id}`),
+ // 根据分类获取文章
+ getArticlesByCategory: (categoryId) => api.get(`/articles/category/${categoryId}`),
+ // 获取热门文章
+ getPopularArticles: () => api.get('/articles/popular'),
+ // 创建文章
+ createArticle: (articleData) => api.post('/articles', articleData),
+ // 更新文章
+ updateArticle: (id, articleData) => api.put(`/articles/${id}`, articleData),
+ // 删除文章
+ deleteArticle: (id) => api.delete(`/articles/${id}`)
+};
+
+// 留言相关API
+export const messageAPI = {
+ // 获取所有留言
+ getAllMessages: () => api.get('/messages'),
+ // 获取单条留言
+ getMessageById: (id) => api.get(`/messages/${id}`),
+ // 保存留言
+ saveMessage: (messageData) => api.post('/messages', messageData),
+ // 删除留言
+ deleteMessage: (id) => api.delete(`/messages/${id}`)
+};
+
+// 导出默认的api对象
+export default api;
+```
+
+## 开发指南
+
+### 安装依赖
+
+```bash
+npm install
+```
+
+### 启动开发服务器
+
+```bash
+npm run dev
+```
+
+开发服务器将在 http://localhost:3000 启动
+
+### 构建生产版本
+
+```bash
+npm run build
+```
+
+构建后的文件将生成在 `dist` 目录中
+
+### 预览生产版本
+
+```bash
+npm run preview
+```
+
+## 部署说明
+
+1. 确保后端服务已部署并运行在正确的端口上
+2. 修改前端API请求的基础URL指向实际的后端服务地址
+3. 构建生产版本并部署到Web服务器
+4. 配置Web服务器以支持单页应用路由 (SPA fallback)
+
+## 注意事项
+
+1. 项目使用了Element Plus和Ant Design Vue两个UI库,请注意组件的正确引入和使用方式
+2. 后端服务默认端口为8080,前端开发服务器端口为3000
+3. 确保CORS配置正确,允许前端域名访问后端API
+4. 对于需要认证的API,需要在请求头中添加正确的认证信息
+
+## 附录:数据模型
+
+### 文章数据模型 (Article)
+
+```javascript
+{
+ articleid: Number, // 文章ID
+ title: String, // 文章标题
+ content: String, // 文章内容
+ author: String, // 作者
+ authorid: Number, // 作者ID
+ typeid: Number, // 分类ID
+ publishedAt: String, // 发布时间
+ viewCount: Number, // 浏览次数
+ status: Number, // 状态 (1表示已发布)
+ img: String // 文章图片
+}
+```
+
+### 留言数据模型 (Message)
+
+```javascript
+{
+ id: Number, // 留言ID
+ nickname: String, // 昵称
+ email: String, // 邮箱
+ content: String, // 留言内容
+ time: String, // 留言时间
+ replies: Array // 回复列表
+}
+```
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index c26a5df..a330f84 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
"dependencies": {
"ant-design-vue": "^4.2.6",
"antd": "^5.27.3",
- "axios": "^1.11.0",
+ "axios": "^1.12.2",
"element-plus": "^2.11.2",
"vue": "^3.5.18",
"vue-router": "^4.5.1"
@@ -2647,9 +2647,9 @@
"license": "MIT"
},
"node_modules/axios": {
- "version": "1.11.0",
- "resolved": "https://registry.npmmirror.com/axios/-/axios-1.11.0.tgz",
- "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==",
+ "version": "1.12.2",
+ "resolved": "https://registry.npmmirror.com/axios/-/axios-1.12.2.tgz",
+ "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
diff --git a/package.json b/package.json
index 4d07dd0..1067cf0 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,7 @@
"dependencies": {
"ant-design-vue": "^4.2.6",
"antd": "^5.27.3",
- "axios": "^1.11.0",
+ "axios": "^1.12.2",
"element-plus": "^2.11.2",
"vue": "^3.5.18",
"vue-router": "^4.5.1"
diff --git a/src/axios/api.js b/src/axios/api.js
new file mode 100644
index 0000000..06023f3
--- /dev/null
+++ b/src/axios/api.js
@@ -0,0 +1,86 @@
+import axios from 'axios'
+
+// 创建axios实例
+const service = axios.create({
+ baseURL: 'http://localhost:8080/api', // api的base_url
+ timeout: 3000, // 请求超时时间
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ // withCredentials: true, // 跨域请求时是否需要使用凭证
+})
+
+// 请求拦截器 - 添加认证token
+service.interceptors.request.use(
+ config => {
+ const token = localStorage.getItem('token')
+ if (token) {
+ config.headers.Authorization = `Bearer ${token}`
+ }
+ return config
+ },
+ error => {
+ return Promise.reject(error)
+ }
+)
+
+// 响应拦截器 - 统一处理响应
+service.interceptors.response.use(
+ response => {
+ // 检查响应是否成功
+ if (response.data && response.data.success) {
+ return response.data
+ } else {
+ // 处理业务错误
+ return Promise.reject(new Error(response.data?.message || '请求失败'))
+ }
+ },
+ error => {
+ // 处理HTTP错误
+ console.error('API请求错误:', error)
+ // 可以在这里添加全局错误处理,如显示错误提示
+ return Promise.reject(error)
+ }
+)
+
+// 文章相关API
+export const articleAPI = {
+ // 获取所有文章
+ getAllArticles: () => service.get('/articles'),
+ // 获取单篇文章
+ getArticleById: (id) => service.get(`/articles/${id}`),
+ // 根据分类获取文章
+ getArticlesByCategory: (categoryId) => service.get(`/articles/category/${categoryId}`),
+ // 获取热门文章
+ getPopularArticles: () => service.get('/articles/popular'),
+ // 创建文章
+ createArticle: (articleData) => service.post('/articles', articleData),
+ // 更新文章
+ updateArticle: (id, articleData) => service.put(`/articles/${id}`, articleData),
+ // 删除文章
+ deleteArticle: (id) => service.delete(`/articles/${id}`)
+}
+
+// 留言相关API
+export const messageAPI = {
+ // 获取所有留言
+ getAllMessages: () => service.get('/messages'),
+ // 获取单条留言
+ getMessageById: (id) => service.get(`/messages/${id}`),
+ // 根据文章ID获取留言
+ getMessagesByArticleId: (articleId) => service.get(`/messages/article/${articleId}`),
+ // 获取根留言
+ getRootMessages: () => service.get('/messages/root'),
+ // 根据父留言ID获取回复
+ getRepliesByParentId: (parentId) => service.get(`/messages/parent/${parentId}`),
+ // 根据昵称搜索留言
+ searchMessagesByNickname: (nickname) => service.get(`/messages/search?nickname=${nickname}`),
+ // 获取文章评论数量
+ getMessageCountByArticleId: (articleId) => service.get(`/messages/count/${articleId}`),
+ // 创建留言
+ saveMessage: (messageData) => service.post('/messages', messageData),
+ // 删除留言
+ deleteMessage: (id) => service.delete(`/messages/${id}`)
+}
+
+export default service
\ No newline at end of file
diff --git a/src/index.vue b/src/index.vue
index d836378..cb5e5fd 100644
--- a/src/index.vue
+++ b/src/index.vue
@@ -105,10 +105,7 @@ const handleSelect = (key: string) => {
*/
const updatePageState = (url: string) => {
classhero.value = url !== '/:type';
- console.log("当前路径是:"+url);
classnonsenset.value = url == '/nonsense';
- console.log( classnonsenset.value);
-
};
/**
@@ -154,14 +151,12 @@ const handleScroll = () => {
isconts.value = true;
isScrollingleftmodlue.value = true;
}
- console.log("好耶滚动了");
};
/**
* 添加滚动监听
*/
const addScrollListener = () => {
- console.log("添加滚动监听");
window.addEventListener('scroll', handleScroll);
};
@@ -169,7 +164,6 @@ const addScrollListener = () => {
* 移除滚动监听
*/
const removeScrollListener = () => {
- console.log("移除滚动监听");
window.removeEventListener('scroll', handleScroll);
};
@@ -184,7 +178,6 @@ const handleResize = () => {
isScrollingleftmodlue.value = true;
classnonsenset.value = false;
isconts.value = true;
- // removeScrollListener();
} else {
windowwidth.value = true;
diff --git a/src/views/aericle.vue b/src/views/aericle.vue
index 9261b7f..6298aba 100644
--- a/src/views/aericle.vue
+++ b/src/views/aericle.vue
@@ -5,11 +5,11 @@
-
{{ items[index].title }}
+
{{ items[index] }}
共{{ contentsum(items) }}篇
@@ -18,12 +18,26 @@
\ No newline at end of file
diff --git a/src/views/home.vue b/src/views/home.vue
index f0a84c9..37b0db0 100644
--- a/src/views/home.vue
+++ b/src/views/home.vue
@@ -5,7 +5,7 @@
class="article-card"
v-for="item in datas"
:key="item.title + item.publishedAt"
- @click="aericleClick(item.aur)"
+ @click="aericleClick(item.articleid)"
>
{{ item.title }}
{{ item.author }}
@@ -18,8 +18,21 @@