# Axios 迁移完成 ## ✅ 已完成 已成功将请求封装从 fetch 迁移到 axios,完整复刻 JeecgBoot 前端的请求封装。 ### 核心文件 ``` src/utils/http/ ├── index.ts # 主入口,配置 transform ├── Axios.ts # Axios 封装类 ├── axiosTransform.ts # 转换器接口定义 ├── checkStatus.ts # HTTP 状态码检查 └── helper.ts # 辅助函数 src/utils/ ├── sign.ts # 请求签名(MD5) └── tenant.ts # 多租户管理 src/types/ └── axios.d.ts # 类型定义 ``` ### 核心功能 1. **请求签名** - MD5 签名,防篡改 2. **多租户支持** - 自动添加租户ID 3. **请求/响应拦截** - 完整的拦截器链 4. **错误处理** - 统一的错误提示 5. **参数处理** - GET/POST 参数自动处理 6. **文件上传** - 支持单文件和批量上传 7. **时间戳防缓存** - GET 请求自动添加时间戳 ### 使用方式 #### 1. 基础请求 ```typescript import { defHttp } from "@/utils/http"; // GET 请求 const data = await defHttp.get({ url: "/api/users", params: { id: 1 } }); // POST 请求 const result = await defHttp.post({ url: "/api/users", data: { name: "张三" } }); // PUT 请求 await defHttp.put({ url: "/api/users/1", data: { name: "李四" } }); // DELETE 请求 await defHttp.delete({ url: "/api/users/1" }); ``` #### 2. 文件上传 ```typescript import { defHttp } from "@/utils/http"; // 单文件上传 const file = document.querySelector('input[type="file"]').files[0]; const result = await defHttp.uploadFile( { url: "/api/upload" }, { file, name: "file" } ); ``` #### 3. 使用服务层 ```typescript import { userService } from "@/services"; // 分页查询 const users = await userService.list({ pageNo: 1, pageSize: 10 }); // CRUD 操作 await userService.add({ username: "test" }); await userService.edit({ id: "1", username: "updated" }); await userService.delete("1"); ``` #### 4. 自定义选项 ```typescript // 跳过错误提示 const data = await defHttp.get( { url: "/api/check" }, { errorMessageMode: "none" } ); // 显示成功提示 await defHttp.post( { url: "/api/save", data: {} }, { successMessageMode: "success" } ); // 返回原生响应 const response = await defHttp.get( { url: "/api/data" }, { isReturnNativeResponse: true } ); ``` ### 自动添加的请求头 所有请求会自动添加以下请求头: ```typescript { "X-Timestamp": "1234567890", // 时间戳 "X-Sign": "abc123...", // MD5 签名 "X-Version": "v3", // 版本标识 "X-Tenant-ID": "0", // 租户ID "Content-Type": "application/json" // 内容类型 } ``` ### 签名算法 请求签名使用 MD5 算法: ``` 签名字符串 = URL路径 + 排序后的参数 + 签名密钥 签名 = MD5(签名字符串) ``` 示例: ``` URL: /api/user/list 参数: { name: "张三", age: 20 } 密钥: DD05F1C54D63749EEEB10B4F8B6830B1 签名字符串: /api/user/listaage=20&name=张三DD05F1C54D63749EEEB10B4F8B6830B1 签名: MD5(签名字符串) ``` ### 多租户 系统支持多租户,会自动从 localStorage 读取租户ID: ```typescript // 设置租户ID import { setTenantId } from "@/utils/tenant"; setTenantId("123"); // 设置临时租户ID(优先级更高) import { setShareTenantId } from "@/utils/tenant"; setShareTenantId("456"); ``` ### 与 JeecgBoot 的差异 | 功能 | JeecgBoot | 当前实现 | 说明 | |------|-----------|----------|------| | 基础库 | axios | axios | ✅ 相同 | | 请求签名 | ✅ | ✅ | ✅ 已实现 | | 多租户 | ✅ | ✅ | ✅ 已实现 | | Token 认证 | ✅ | ❌ | 使用 Cookie 代替 | | 请求取消 | ✅ | ❌ | 可选功能 | | 流式数据 | ✅ | ❌ | 可选功能 | | 低代码应用ID | ✅ | ❌ | 特定场景 | | 乾坤微前端 | ✅ | ❌ | 特定场景 | ### 配置修改 如需修改签名密钥或其他配置,编辑以下文件: ```typescript // src/utils/sign.ts const SIGN_KEY = "DD05F1C54D63749EEEB10B4F8B6830B1"; // 修改签名密钥 // src/config/api.ts export const API_PREFIX = "/sohoyw-som"; // 修改API前缀 export const TIMEOUT = 30000; // 修改超时时间 ``` ### 注意事项 1. **签名密钥** - 需要与后端约定一致 2. **租户ID** - 多租户系统必须设置 3. **Cookie** - 使用 Cookie 认证,确保后端支持 4. **跨域** - 开发环境使用 Vite 代理 ### 迁移检查清单 - [x] 安装 axios 和 crypto-js - [x] 创建 axios 封装类 - [x] 实现请求/响应拦截器 - [x] 实现请求签名 - [x] 实现多租户支持 - [x] 更新所有服务层调用 - [x] 测试基础 CRUD 操作 - [x] 测试文件上传 - [x] 测试错误处理 ## 🎉 完成 现在项目已经完全使用 axios + JeecgBoot 风格的请求封装!