# API 集成指南 ## 概述 项目已完整配置 axios,包括请求拦截器、响应拦截器和 API 服务层。 ## 文件结构 ``` src/api/ ├── index.ts # axios 实例配置(请求/响应拦截器) └── auth.ts # 登录相关 API 接口定义 ``` ## 核心概念 ### 1. axios 实例配置 (`src/api/index.ts`) ```typescript // 创建 axios 实例 const instance = axios.create({ baseURL: 'http://localhost:3000/api', // 从环境变量读取 timeout: 10000 }) ``` **请求拦截器**:自动在请求头添加 Authorization token ```typescript instance.interceptors.request.use((config) => { const token = localStorage.getItem('auth_token') if (token) { config.headers.Authorization = `Bearer ${token}` } return config }) ``` **响应拦截器**:统一处理错误和 token 过期 ```typescript instance.interceptors.response.use( (response) => response.data, // 成功时返回 data (error) => { if (error.response?.status === 401) { // Token 过期,清除登录状态并跳转到登录页 } } ) ``` ### 2. API 服务层 (`src/api/auth.ts`) 定义所有 API 接口和类型: ```typescript // 定义请求/响应类型 export interface LoginRequest { username: string password: string } export interface LoginResponse { code: number message: string data: { token: string user: User } } // 定义 API 接口 export const loginApi = (credentials: LoginRequest): Promise => { return http.post('/auth/login', credentials) } ``` ### 3. 状态管理 (`src/stores/auth.ts`) 在 Pinia store 中调用 API: ```typescript const login = async (username: string, password: string): Promise => { try { const response = await loginApi({ username, password }) if (response.code === 200 && response.data) { token.value = response.data.token user.value = response.data.user // 保存到本地存储 localStorage.setItem('auth_token', token.value) localStorage.setItem('user', JSON.stringify(user.value)) return true } } catch (error) { console.error('登录失败:', error) return false } } ``` ## 登录流程详解 ### 前端请求流程 ``` 1. 用户在登录页输入用户名和密码 ↓ 2. 点击"登录"按钮调用 handleLogin() ↓ 3. authStore.login(username, password) 被调用 ↓ 4. loginApi({ username, password }) 发送 HTTP 请求 ↓ 5. axios 拦截器处理(添加 headers 等) ↓ 6. 发送 POST /auth/login 请求到后端 ``` ### 后端需要返回的数据格式 ```json { "code": 200, "message": "登录成功", "data": { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "user": { "id": "1", "username": "admin", "email": "admin@example.com", "role": "admin" } } } ``` **字段说明:** - `code`: HTTP 状态码(200 表示成功) - `message`: 返回消息 - `data.token`: JWT token,用于后续请求认证 - `data.user`: 用户信息对象 - `id`: 用户 ID - `username`: 用户名 - `email`: 邮箱 - `role`: 用户角色(admin 或 user) ## 环境配置 ### `.env.development` (开发环境) ``` VITE_API_URL=http://localhost:3000/api ``` ### `.env.production` (生产环境) ``` VITE_API_URL=https://api.example.com/api ``` ### 在代码中获取环境变量 ```typescript const baseURL = import.meta.env.VITE_API_URL || 'http://localhost:3000/api' ``` ## 使用示例 ### 1. 调用登录 API ```typescript import { loginApi } from '@/api/auth' const response = await loginApi({ username: 'admin', password: '123456' }) if (response.code === 200) { console.log('登录成功,用户信息:', response.data.user) console.log('Token:', response.data.token) } ``` ### 2. 在组件中使用 store ```vue ``` ### 3. 创建新的 API 接口 在 `src/api/` 中创建新文件,如 `users.ts`: ```typescript import http from './index' export interface User { id: number username: string email: string role: string } // 获取用户列表 export const getUsersApi = (page: number, limit: number) => { return http.get('/users', { params: { page, limit } }) } // 创建用户 export const createUserApi = (data: User) => { return http.post('/users', data) } // 更新用户 export const updateUserApi = (id: number, data: Partial) => { return http.put(`/users/${id}`, data) } // 删除用户 export const deleteUserApi = (id: number) => { return http.delete(`/users/${id}`) } ``` ## 错误处理 ### 全局错误处理 axios 响应拦截器已处理以下情况: | 状态码 | 处理方式 | |-------|--------| | 401 | Token 过期,清除登录状态,跳转到登录页 | | 其他 4xx/5xx | 返回错误信息 | | 网络错误 | 返回"网络错误"提示 | ### 在组件中处理错误 ```typescript try { const response = await loginApi({ username, password }) // 处理成功 } catch (error: any) { ElMessage.error(error?.message || '登录失败') } ``` ## 请求示例 ### POST 请求 (登录) ```typescript // 请求 POST /api/auth/login Content-Type: application/json Authorization: Bearer { "username": "admin", "password": "123456" } // 响应 { "code": 200, "message": "登录成功", "data": { "token": "...", "user": { ... } } } ``` ### GET 请求 (获取列表) ```typescript // 请求 GET /api/users?page=1&limit=10 Authorization: Bearer // 响应 { "code": 200, "message": "成功", "data": { "items": [...], "total": 100 } } ``` ### PUT 请求 (更新) ```typescript // 请求 PUT /api/users/1 Content-Type: application/json Authorization: Bearer { "username": "new_name", "email": "new@email.com" } // 响应 { "code": 200, "message": "更新成功", "data": { ... } } ``` ## 常见问题 ### Q: Token 过期怎么处理? A: 后端返回 401 时,拦截器会自动清除 token 并跳转到登录页。 ### Q: 如何添加其他请求头? A: 修改 `src/api/index.ts` 中的拦截器: ```typescript instance.interceptors.request.use((config) => { config.headers['Custom-Header'] = 'value' return config }) ``` ### Q: 如何处理超时? A: 已在 axios 配置中设置 `timeout: 10000`(10秒)。修改 `src/api/index.ts` 中的 `timeout` 值。 ### Q: 如何调用 API 时显示加载状态? A: 在组件中使用 `loading` ref: ```typescript const loading = ref(false) loading.value = true try { const response = await loginApi(...) } finally { loading.value = false } ``` ## 集成后端步骤 1. **启动后端服务** ```bash # 后端服务应该运行在 http://localhost:3000 ``` 2. **更新 API 地址** (如果不同) ``` 修改 .env.development 中的 VITE_API_URL ``` 3. **确保后端返回正确格式** ```json { "code": 200, "message": "...", "data": { ... } } ``` 4. **测试登录流程** - 访问 http://localhost:5173 - 输入用户名和密码 - 查看浏览器控制台的网络请求 5. **检查 Token 存储** - 打开浏览器开发者工具 → Application → LocalStorage - 应该看到 `auth_token` 和 `user` 字段 ## 下一步 - [ ] 集成后端登录接口 - [ ] 添加用户列表 API (`src/api/users.ts`) - [ ] 添加产品 API (`src/api/products.ts`) - [ ] 添加订单 API (`src/api/orders.ts`) - [ ] 实现 token 刷新机制 - [ ] 添加错误日志上报