HaniBlindBox/docs/前端适配调整/前端API适配方案.md
2026-01-03 15:21:36 +08:00

302 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 前端API适配方案
## 1. 问题概述
在将后端从 PHP (ThinkPHP 6.0) 迁移到 .NET 10 的过程中,前端 UniApp 项目需要进行适配调整。主要问题包括:
1. **请求格式不兼容**:前端使用 `application/x-www-form-urlencoded`,后端期望 `application/json`
2. **请求方式不一致**同一接口在不同页面使用不同的请求方式GET/POST
3. **部分接口遗漏**:如 `/api/goods_list`、`/api/coupon` 等接口未正确对接
## 2. 当前前端请求机制分析
### 2.1 请求封装 (`honey_box/common/request.js`)
当前请求封装的关键特点:
```javascript
// POST 请求使用 form-urlencoded
if (method.toUpperCase() == 'POST') {
header = {
'content-type': 'application/x-www-form-urlencoded',
// ...
}
} else {
// GET 请求使用 json
header = {
'content-type': 'application/json',
// ...
}
}
```
### 2.2 签名机制
前端对所有请求都添加了签名参数:
- `timestamp`: 时间戳
- `nonce`: 随机字符串
- `sign`: MD5签名
签名算法:
1. 参数按键名排序
2. 拼接为 `key=value&` 格式
3. 添加密钥 `host + timestamp`
4. MD5 加密
## 3. 适配方案
### 方案一:前端统一改为 JSON 格式(推荐)
#### 3.1 修改 `request.js`
将 POST 请求的 Content-Type 改为 `application/json`
```javascript
// 修改前
if (method.toUpperCase() == 'POST') {
header = {
'content-type': 'application/x-www-form-urlencoded',
// ...
}
}
// 修改后
if (method.toUpperCase() == 'POST') {
header = {
'content-type': 'application/json',
// ...
}
}
```
#### 3.2 完整修改示例
```javascript
static request(param, backpage, backtype) {
return new Promise((resolve, reject) => {
// ... 参数检查代码 ...
const url = param.url || ''
const method = param.method || 'POST'
const data = param.data || {}
const Loading = param.Loading || false
const token = uni.getStorageSync('token')
let client = platform.code
// ... URL 拼接代码 ...
// 添加签名参数
data.timestamp = Math.floor(Date.now() / 1000)
data.nonce = RequestManager.generateNonce()
// 生成签名
const sortedParams = {}
Object.keys(data).sort().forEach(key => {
sortedParams[key] = data[key]
})
let signStr = ''
for (const key in sortedParams) {
if (typeof sortedParams[key] === 'object') {
signStr += key + '=' + JSON.stringify(sortedParams[key]) + '&'
} else {
signStr += key + '=' + sortedParams[key] + '&'
}
}
const timestamp = data.timestamp
const appSecret = host + timestamp
signStr = signStr.substring(0, signStr.length - 1) + appSecret
const sign = md5(signStr)
data.sign = sign
// 统一使用 JSON 格式
const header = {
'content-type': 'application/json',
client: client,
token: token,
adid: uni.getStorageSync('_ad_id'),
clickid: uni.getStorageSync('_click_id')
}
// ... 发起请求代码 ...
})
}
```
### 方案二:后端兼容 form-urlencoded备选
如果不想修改前端,可以在后端添加中间件支持 form-urlencoded
```csharp
// 在 Program.cs 中添加
builder.Services.AddControllers()
.AddNewtonsoftJson()
.ConfigureApiBehaviorOptions(options =>
{
// 支持 form-urlencoded
});
```
但这种方案不推荐,因为:
1. 增加后端复杂度
2. 不符合 RESTful API 规范
3. 后续维护困难
## 4. 接口请求方式统一
### 4.1 当前接口请求方式对照表
| 接口路径 | PHP 旧版 | C# 新版 | 前端当前使用 | 需要调整 |
|---------|---------|---------|-------------|---------|
| `/api/config` | GET/POST | GET | GET | ✅ 无需调整 |
| `/api/getPlatformConfig` | GET/POST | GET | GET | ✅ 无需调整 |
| `/api/getAdvert` | GET/POST | GET/POST | GET | ✅ 无需调整 |
| `/api/getDanye` | GET/POST | GET | GET | ✅ 无需调整 |
| `/api/goods_list` | POST | POST | POST | ✅ 无需调整 |
| `/api/goods_detail` | POST | POST | POST | ✅ 无需调整 |
| `/api/user` | POST | POST | GET | ⚠️ 需要调整 |
| `/api/login` | POST | POST | POST | ✅ 无需调整 |
| `/api/mobileLogin` | POST | POST | POST | ✅ 无需调整 |
| `/api/coupon_list` | POST | POST | POST | ✅ 无需调整 |
| `/api/order_list` | POST | POST | POST | ✅ 无需调整 |
### 4.2 需要调整的接口
#### `/api/user` - 获取用户信息
**问题**:前端 `user.js` 使用 GET 请求,后端期望 POST
```javascript
// honey_box/common/server/user.js
// 修改前
export const getUserInfo = async () => {
const res = await RequestManager.get('/userInfo');
// ...
}
// 修改后
export const getUserInfo = async () => {
const res = await RequestManager.post('/user');
// ...
}
```
## 5. 遗漏接口清单
根据分析,以下接口可能存在问题:
### 5.1 商品相关
| 接口 | 状态 | 说明 |
|-----|------|-----|
| `POST /api/goods_list` | ⚠️ 需检查 | 前端请求格式需改为 JSON |
| `POST /api/goods_detail` | ⚠️ 需检查 | 前端请求格式需改为 JSON |
### 5.2 优惠券相关
| 接口 | 状态 | 说明 |
|-----|------|-----|
| `POST /api/coupon_list` | ⚠️ 需检查 | 前端请求格式需改为 JSON |
| `POST /api/coupon_detail` | ⚠️ 需检查 | 前端请求格式需改为 JSON |
| `POST /api/coupon_ling` | ⚠️ 需检查 | 前端请求格式需改为 JSON |
### 5.3 订单相关
| 接口 | 状态 | 说明 |
|-----|------|-----|
| `POST /api/ordermoney` | ⚠️ 需检查 | 前端请求格式需改为 JSON |
| `POST /api/orderbuy` | ⚠️ 需检查 | 前端请求格式需改为 JSON |
## 6. 实施步骤
### 第一阶段:修改请求封装(核心)
1. 修改 `honey_box/common/request.js`
2. 将 POST 请求的 Content-Type 改为 `application/json`
3. 测试基础接口(登录、配置获取)
### 第二阶段:统一接口调用方式
1. 检查 `honey_box/common/server/` 下所有接口文件
2. 统一使用正确的请求方式GET/POST
3. 确保接口路径与后端一致
### 第三阶段:逐模块测试
1. 用户认证模块(登录、注册、绑定手机号)
2. 商品模块(列表、详情、奖品)
3. 订单模块(下单、支付、抽奖)
4. 仓库模块(回收、发货)
5. 福利模块(签到、任务)
## 7. 代码修改清单
### 7.1 `honey_box/common/request.js`
```diff
- header = {
- 'content-type': 'application/x-www-form-urlencoded',
- client: client,
- token: token,
- adid: uni.getStorageSync('_ad_id'),
- clickid: uni.getStorageSync('_click_id')
- }
+ header = {
+ 'content-type': 'application/json',
+ client: client,
+ token: token,
+ adid: uni.getStorageSync('_ad_id'),
+ clickid: uni.getStorageSync('_click_id')
+ }
```
### 7.2 `honey_box/common/server/user.js`
```diff
export const getUserInfo = async () => {
- const res = await RequestManager.get('/userInfo');
+ const res = await RequestManager.post('/user');
if (res.status == 1) {
res.data.money = common.removeTrailingZeros(res.data.money);
res.data.integral = common.removeTrailingZeros(res.data.integral);
res.data.money2 = common.removeTrailingZeros(res.data.money2);
return res.data;
} else {
return null;
}
};
```
## 8. 测试验证
### 8.1 测试用例
| 测试项 | 预期结果 | 实际结果 |
|-------|---------|---------|
| 获取系统配置 | 返回配置数据 | |
| 手机号登录 | 返回 token | |
| 获取用户信息 | 返回用户数据 | |
| 获取商品列表 | 返回商品分页数据 | |
| 获取优惠券列表 | 返回优惠券数据 | |
| 创建订单 | 返回订单信息 | |
### 8.2 调试工具
前端已集成 eruda 调试工具,可在开发环境查看网络请求详情。
## 9. 注意事项
1. **签名机制保持不变**:修改 Content-Type 不影响签名计算
2. **Token 传递方式不变**:继续通过 header 传递
3. **响应格式不变**:后端返回格式与 PHP 版本保持一致
4. **错误码保持一致**status 码含义不变
## 10. 回滚方案
如果修改后出现问题,可以:
1. 恢复 `request.js` 中的 Content-Type 为 `application/x-www-form-urlencoded`
2. 在后端添加 form-urlencoded 支持中间件
3. 逐步排查问题接口