HaniBlindBox/.kiro/specs/frontend-api-refactor/design.md
2026-01-03 15:21:36 +08:00

496 lines
15 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.

# Design Document
## Overview
本设计文档描述前端 API 接口调用重构的技术方案。核心目标是将分散在页面和组件中的接口调用统一收敛到 `common/server/` 模块,实现接口集中管理、统一错误处理,并在改造过程中生成完整的 API 清单用于核对 C# 后端迁移完整性。
## Architecture
### 整体架构
```
┌─────────────────────────────────────────────────────────────┐
│ Pages / Components │
│ (pages/shouye/*.vue, pages/user/*.vue, components/*.vue) │
└─────────────────────────────┬───────────────────────────────┘
│ import { funcName } from '@/common/server/xxx.js'
┌─────────────────────────────────────────────────────────────┐
│ Server Modules │
│ common/server/ │
│ ├── auth.js (登录、注册、绑定) │
│ ├── user.js (用户信息、VIP) │
│ ├── goods.js (商品列表、详情、奖品) │
│ ├── order.js (订单、抽奖) │
│ ├── warehouse.js (仓库、回收、发货) │
│ ├── coupon.js (优惠券) │
│ ├── welfare.js (福利屋、签到、任务) │
│ ├── collection.js(收藏) │
│ ├── address.js (收货地址) - 已有 userAddress.js │
│ ├── config.js (系统配置) - 已有 │
│ ├── rank.js (排行榜) │
│ ├── invitation.js(邀请) │
│ ├── redeem.js (兑换码) │
│ └── pay.js (支付) │
└─────────────────────────────┬───────────────────────────────┘
│ RequestManager.get/post()
┌─────────────────────────────────────────────────────────────┐
│ RequestManager │
│ common/request.js │
│ - 统一请求封装 │
│ - 签名机制 │
│ - 错误处理 │
│ - Content-Type: application/json │
└─────────────────────────────┬───────────────────────────────┘
│ HTTP Request
┌─────────────────────────────────────────────────────────────┐
│ C# Backend API │
│ http://localhost:5238/api/* │
└─────────────────────────────────────────────────────────────┘
```
### 调用流程
```mermaid
sequenceDiagram
participant P as Page/Component
participant S as Server Module
participant R as RequestManager
participant B as Backend API
P->>S: import { getGoodsList } from '@/common/server/goods.js'
P->>S: await getGoodsList({ page: 1, type: 0 })
S->>R: RequestManager.post('/goods_list', data)
R->>R: 添加签名参数 (timestamp, nonce, sign)
R->>B: POST /api/goods_list (JSON)
B-->>R: { status: 1, data: {...} }
R-->>S: response
S->>S: 统一错误处理
S-->>P: 标准格式结果
```
## Components and Interfaces
### 1. RequestManager (已有,需修改)
**文件**: `honey_box/common/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',
// ...
}
}
```
**接口保持不变**:
- `static get(url, data, showLoading)` - GET 请求
- `static post(url, data, showLoading)` - POST 请求
- `static getCache(url, data, showLoading)` - 带缓存的 GET 请求
### 2. Server Module 标准结构
每个 Server Module 遵循统一的结构:
```javascript
// common/server/xxx.js
import RequestManager from '../request';
/**
* 函数名使用语义化命名
* @param {Object} params 请求参数
* @returns {Promise<Object>} 标准响应格式
*/
export const getFunctionName = async (params = {}) => {
const res = await RequestManager.post('/api_endpoint', params);
return res;
};
// 如需数据处理
export const getProcessedData = async (params = {}) => {
const res = await RequestManager.post('/api_endpoint', params);
if (res.status === 1 && res.data) {
// 数据处理逻辑
return res.data;
}
return null;
};
```
### 3. Server Modules 详细设计
#### 3.1 auth.js (认证模块)
```javascript
// 微信登录
export const wxLogin = async (code, userInfo) => {...}
// 手机号登录
export const mobileLogin = async (mobile, code) => {...}
// 微信绑定手机号
export const bindMobileByWx = async (encryptedData, iv) => {...}
// 验证码绑定手机号
export const bindMobileByCode = async (mobile, code) => {...}
// 记录登录
export const recordLogin = async () => {...}
// 账号注销
export const logOff = async () => {...}
```
#### 3.2 user.js (用户模块 - 扩展已有)
```javascript
// 已有
export const getUserInfo = async () => {...}
// 新增
export const updateUserInfo = async (data) => {...}
export const getVipList = async () => {...}
export const getProfitMoney = async (page) => {...}
export const getProfitIntegral = async (page) => {...}
export const getProfitScore = async (page) => {...}
export const getProfitPay = async (page) => {...}
```
#### 3.3 goods.js (商品模块)
```javascript
// 商品列表
export const getGoodsList = async (params) => {...}
// 商品详情
export const getGoodsDetail = async (goodsId) => {...}
// 子奖品列表
export const getGoodsChildren = async (goodsId) => {...}
// 商品扩展配置
export const getGoodsExtend = async (goodsId) => {...}
// 箱号列表
export const getGoodsNumList = async (goodsId) => {...}
// 箱号详情
export const getGoodsNumDetail = async (goodsId, goodsNum) => {...}
// 奖品数量统计
export const getGoodsPrizeCount = async (goodsId) => {...}
// 奖品内容
export const getGoodsPrizeContent = async (goodsId, shangId) => {...}
// 中奖记录
export const getGoodsPrizeLogs = async (params) => {...}
```
#### 3.4 order.js (订单模块 - 扩展已有)
```javascript
// 一番赏金额计算
export const calcOrderMoney = async (params) => {...}
// 一番赏下单
export const createOrder = async (params) => {...}
// 无限赏金额计算
export const calcInfiniteOrderMoney = async (params) => {...}
// 无限赏下单
export const createInfiniteOrder = async (params) => {...}
// 商城金额计算
export const calcMallOrderMoney = async (params) => {...}
// 订单列表
export const getOrderList = async (page, pageSize) => {...}
// 订单详情
export const getOrderDetail = async (orderId) => {...}
// 抽奖结果
export const getPrizeOrderLog = async (orderId) => {...}
// 无限赏抽奖结果
export const getInfinitePrizeOrderLog = async (orderId) => {...}
// 道具卡抽奖
export const useItemCard = async (params) => {...}
```
#### 3.5 warehouse.js (仓库模块)
```javascript
// 仓库首页
export const getWarehouseIndex = async (params) => {...}
// 回收奖品
export const recoveryPrize = async (ids) => {...}
// 发货奖品
export const sendPrize = async (params) => {...}
// 确认发货
export const confirmSend = async (params) => {...}
// 发货记录
export const getSendRecord = async (page) => {...}
// 发货详情
export const getSendRecordDetail = async (id) => {...}
// 回收记录
export const getRecoveryRecord = async (page) => {...}
// 物流信息
export const getLogistics = async (orderId) => {...}
```
#### 3.6 coupon.js (优惠券模块)
```javascript
// 优惠券列表
export const getCouponList = async (params) => {...}
// 优惠券详情
export const getCouponDetail = async (couponId) => {...}
// 领取优惠券
export const receiveCoupon = async (couponId) => {...}
// 分享优惠券
export const shareCoupon = async (couponId) => {...}
// 合成优惠券
export const synthesisCoupon = async (ids) => {...}
// 计算合成
export const calcSynthesis = async (ids) => {...}
```
#### 3.7 welfare.js (福利模块)
```javascript
// 福利屋列表
export const getWelfareHouseList = async () => {...}
// 福利屋详情
export const getWelfareHouseDetail = async (goodsId) => {...}
// 福利屋下单
export const buyWelfareHouse = async (params) => {...}
// 签到信息
export const getSignInfo = async () => {...}
// 执行签到
export const doSign = async () => {...}
// 任务列表
export const getTaskList = async () => {...}
// 领取任务奖励
export const receiveTaskReward = async (taskId) => {...}
```
#### 3.8 collection.js (收藏模块)
```javascript
// 收藏列表
export const getCollectionList = async (page) => {...}
// 添加收藏
export const addCollection = async (goodsId) => {...}
// 取消收藏
export const cancelCollection = async (goodsId) => {...}
// 收藏状态
export const getCollectionStatus = async (goodsId) => {...}
```
#### 3.9 rank.js (排行榜模块)
```javascript
// 排行榜列表
export const getRankList = async (type, page) => {...}
```
#### 3.10 invitation.js (邀请模块)
```javascript
// 邀请信息
export const getInvitationInfo = async () => {...}
// 邀请记录
export const getInvitationRecord = async (page) => {...}
```
#### 3.11 redeem.js (兑换码模块)
```javascript
// 使用兑换码
export const useRedeemCode = async (code) => {...}
```
#### 3.12 pay.js (支付模块)
```javascript
// 微信支付
export const wxPay = async (orderId) => {...}
// 余额支付
export const balancePay = async (orderId) => {...}
// 充值
export const recharge = async (amount) => {...}
```
## Data Models
### 标准响应格式
```typescript
interface ApiResponse<T> {
status: number; // 1=成功, 0=失败, -1=未登录, -9=需绑定手机号
msg: string; // 提示信息
data: T; // 业务数据
}
interface PaginatedResponse<T> {
status: number;
msg: string;
data: {
data: T[]; // 列表数据
total: number; // 总数
currentPage: number;
lastPage: number;
};
}
```
### 状态码定义
| 状态码 | 含义 | 处理方式 |
|-------|------|---------|
| 1 | 成功 | 返回数据 |
| 0 | 业务失败 | 显示 msg 提示 |
| -1 | 未登录 | 跳转登录页 |
| -9 | 需绑定手机号 | 跳转绑定页 |
| 2222 | 特殊状态 | 返回数据 |
## Correctness Properties
*A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.*
### Property 1: POST 请求使用 JSON 格式
*For any* POST 请求通过 RequestManager 发送, 请求头的 Content-Type 应为 `application/json`
**Validates: Requirements 1.1**
### Property 2: 签名机制一致性
*For any* 请求数据对象, 生成的签名应与原有算法保持一致:参数按键名排序 → 拼接为 key=value& 格式 → 添加密钥(host+timestamp) → MD5 加密
**Validates: Requirements 1.2**
### Property 3: 响应格式一致性
*For any* API 响应, 返回格式应包含 status、msg、data 三个字段,且 status 为数字类型
**Validates: Requirements 1.3**
### Property 4: 错误处理统一性
*For any* 接口调用返回 status !== 1 的响应, Server Module 应返回包含 status 和 msg 的标准格式对象
**Validates: Requirements 2.3, 6.2**
## Error Handling
### RequestManager 层错误处理
RequestManager 已实现以下错误处理逻辑(保持不变):
1. **网络异常**: 显示 "网络连接异常,请检查网络"
2. **status = 0**: 显示 msg 提示
3. **status = -1**: 清除 token跳转登录页
4. **status = -9**: 显示 msg跳转绑定手机号页面
5. **请求失败**: 显示错误信息
### Server Module 层错误处理
Server Module 不额外处理错误,直接返回 RequestManager 的响应:
```javascript
export const getGoodsList = async (params) => {
// 直接返回,错误由 RequestManager 统一处理
return await RequestManager.post('/goods_list', params);
};
```
如需数据转换,在成功时处理:
```javascript
export const getUserInfo = async () => {
const res = await RequestManager.post('/user');
if (res.status === 1 && res.data) {
// 数据处理
res.data.money = common.removeTrailingZeros(res.data.money);
return res.data;
}
return null;
};
```
## Testing Strategy
### 单元测试
由于前端 UniApp 项目的特殊性,主要通过以下方式验证:
1. **手动测试**: 在开发环境使用 eruda 调试工具检查请求
2. **接口测试**: 使用 Postman/curl 验证接口响应格式
### 测试用例
| 测试项 | 预期结果 |
|-------|---------|
| POST 请求 Content-Type | application/json |
| 签名参数存在 | timestamp, nonce, sign |
| 成功响应格式 | { status: 1, msg: "...", data: {...} } |
| 错误响应处理 | 显示 msg 提示 |
| 未登录处理 | 跳转登录页 |
| 需绑定手机号处理 | 跳转绑定页 |
### 集成测试清单
按模块逐一测试:
1. **认证模块**: 登录、绑定手机号
2. **用户模块**: 获取用户信息、VIP 信息
3. **商品模块**: 商品列表、详情、奖品
4. **订单模块**: 下单、支付、抽奖结果
5. **仓库模块**: 回收、发货
6. **优惠券模块**: 列表、领取、合成
7. **福利模块**: 签到、任务
8. **其他模块**: 收藏、排行榜、邀请、兑换码