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

15 KiB
Raw Blame History

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/*                                 │
└─────────────────────────────────────────────────────────────┘

调用流程

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

// 修改前
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 遵循统一的结构:

// 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 (认证模块)

// 微信登录
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 (用户模块 - 扩展已有)

// 已有
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 (商品模块)

// 商品列表
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 (订单模块 - 扩展已有)

// 一番赏金额计算
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 (仓库模块)

// 仓库首页
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 (优惠券模块)

// 优惠券列表
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 (福利模块)

// 福利屋列表
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 (收藏模块)

// 收藏列表
export const getCollectionList = async (page) => {...}

// 添加收藏
export const addCollection = async (goodsId) => {...}

// 取消收藏
export const cancelCollection = async (goodsId) => {...}

// 收藏状态
export const getCollectionStatus = async (goodsId) => {...}

3.9 rank.js (排行榜模块)

// 排行榜列表
export const getRankList = async (type, page) => {...}

3.10 invitation.js (邀请模块)

// 邀请信息
export const getInvitationInfo = async () => {...}

// 邀请记录
export const getInvitationRecord = async (page) => {...}

3.11 redeem.js (兑换码模块)

// 使用兑换码
export const useRedeemCode = async (code) => {...}

3.12 pay.js (支付模块)

// 微信支付
export const wxPay = async (orderId) => {...}

// 余额支付
export const balancePay = async (orderId) => {...}

// 充值
export const recharge = async (amount) => {...}

Data Models

标准响应格式

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 的响应:

export const getGoodsList = async (params) => {
    // 直接返回,错误由 RequestManager 统一处理
    return await RequestManager.post('/goods_list', params);
};

如需数据转换,在成功时处理:

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. 其他模块: 收藏、排行榜、邀请、兑换码