From dcded0178fca461e50d029cbb97a680dd241c851 Mon Sep 17 00:00:00 2001 From: zpc Date: Sat, 3 Jan 2026 15:21:36 +0800 Subject: [PATCH] =?UTF-8?q?=E5=89=8D=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .kiro/specs/frontend-api-refactor/design.md | 495 ++++++++++++++++++ .../frontend-api-refactor/requirements.md | 81 +++ .kiro/specs/frontend-api-refactor/tasks.md | 180 +++++++ .../request.js修改方案.md | 280 ++++++++++ .../前端API适配方案.md | 301 +++++++++++ docs/前端适配调整/实施检查清单.md | 194 +++++++ docs/前端适配调整/接口对照表.md | 261 +++++++++ honey_box/common/request.js | 2 +- 8 files changed, 1793 insertions(+), 1 deletion(-) create mode 100644 .kiro/specs/frontend-api-refactor/design.md create mode 100644 .kiro/specs/frontend-api-refactor/requirements.md create mode 100644 .kiro/specs/frontend-api-refactor/tasks.md create mode 100644 docs/前端适配调整/request.js修改方案.md create mode 100644 docs/前端适配调整/前端API适配方案.md create mode 100644 docs/前端适配调整/实施检查清单.md create mode 100644 docs/前端适配调整/接口对照表.md diff --git a/.kiro/specs/frontend-api-refactor/design.md b/.kiro/specs/frontend-api-refactor/design.md new file mode 100644 index 00000000..46d53481 --- /dev/null +++ b/.kiro/specs/frontend-api-refactor/design.md @@ -0,0 +1,495 @@ +# 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} 标准响应格式 + */ +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 { + status: number; // 1=成功, 0=失败, -1=未登录, -9=需绑定手机号 + msg: string; // 提示信息 + data: T; // 业务数据 +} + +interface PaginatedResponse { + 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. **其他模块**: 收藏、排行榜、邀请、兑换码 diff --git a/.kiro/specs/frontend-api-refactor/requirements.md b/.kiro/specs/frontend-api-refactor/requirements.md new file mode 100644 index 00000000..82302c5e --- /dev/null +++ b/.kiro/specs/frontend-api-refactor/requirements.md @@ -0,0 +1,81 @@ +# Requirements Document + +## Introduction + +本需求文档描述前端 API 接口调用重构工作。目标是将分散在页面和组件中的接口调用统一收敛到 `common/server/` 模块,实现接口集中管理,并在改造过程中记录所有 API 地址,用于核对 C# 后端迁移完整性。 + +## Glossary + +- **Server_Module**: `honey_box/common/server/` 目录下的 API 接口封装模块 +- **RequestManager**: 现有的网络请求工具类 (`honey_box/common/request.js`) +- **Page**: `honey_box/pages/` 目录下的页面文件 +- **Component**: `honey_box/components/` 目录下的组件文件 +- **API_Registry**: 接口清单文档,记录所有前端使用的 API 地址及迁移状态 + +## Requirements + +### Requirement 1: 修改请求格式 + +**User Story:** As a 开发者, I want POST 请求使用 JSON 格式, so that 与 C# 后端兼容。 + +#### Acceptance Criteria + +1. WHEN 发送 POST 请求 THEN RequestManager SHALL 使用 `application/json` 作为 Content-Type +2. WHEN 发送请求 THEN RequestManager SHALL 保持现有签名机制不变 +3. WHEN 请求完成 THEN RequestManager SHALL 返回与 PHP 版本一致的响应格式 + +### Requirement 2: 创建 Server 模块 + +**User Story:** As a 开发者, I want 按业务域划分 API 模块, so that 接口集中管理便于维护。 + +#### Acceptance Criteria + +1. THE Server_Module SHALL 按业务域划分为独立文件(auth、user、goods、order、warehouse、coupon、welfare、collection、address、config、rank、invitation、redeem、pay) +2. WHEN 定义接口函数 THEN Server_Module SHALL 使用语义化的函数名(如 `getUserInfo`、`getGoodsList`) +3. WHEN 接口调用失败 THEN Server_Module SHALL 统一处理错误并返回标准格式 +4. THE Server_Module SHALL 不使用 index.js 统一导出,各模块独立导入 + +### Requirement 3: 重构页面接口调用 + +**User Story:** As a 开发者, I want 页面通过 Server 模块调用接口, so that 接口路径不再硬编码在页面中。 + +#### Acceptance Criteria + +1. WHEN 页面需要调用接口 THEN Page SHALL 从对应 Server_Module 导入函数 +2. WHEN 页面调用接口 THEN Page SHALL 使用 `await` 方式调用导入的函数 +3. THE Page SHALL 不再直接使用 `this.req()`、`RequestManager.post()` 等方式硬编码 URL +4. WHEN 重构页面 THEN 开发者 SHALL 记录该页面使用的所有 API 地址到 API_Registry + +### Requirement 4: 重构组件接口调用 + +**User Story:** As a 开发者, I want 组件通过 Server 模块调用接口, so that 组件中的接口也能集中管理。 + +#### Acceptance Criteria + +1. WHEN 组件需要调用接口 THEN Component SHALL 从对应 Server_Module 导入函数 +2. WHEN 组件调用接口 THEN Component SHALL 使用 `await` 方式调用导入的函数 +3. THE Component SHALL 不再直接使用 `this.req()`、`RequestManager.post()` 等方式硬编码 URL +4. WHEN 重构组件 THEN 开发者 SHALL 记录该组件使用的所有 API 地址到 API_Registry + +### Requirement 5: 生成接口清单 + +**User Story:** As a 开发者, I want 记录所有前端使用的 API 地址, so that 能核对 C# 后端是否遗漏接口。 + +#### Acceptance Criteria + +1. THE API_Registry SHALL 记录每个接口的 URL 路径 +2. THE API_Registry SHALL 记录每个接口所属的 Server_Module +3. THE API_Registry SHALL 记录每个接口的请求方式(GET/POST) +4. THE API_Registry SHALL 标注每个接口在 C# 后端的迁移状态(已迁移/未迁移/待确认) +5. THE API_Registry SHALL 记录每个接口被哪些页面/组件使用 + +### Requirement 6: 保持功能兼容 + +**User Story:** As a 用户, I want 重构后功能正常, so that 不影响正常使用。 + +#### Acceptance Criteria + +1. WHEN 重构完成 THEN 所有现有功能 SHALL 正常工作 +2. WHEN 接口返回错误 THEN 系统 SHALL 正确显示错误提示 +3. WHEN 用户未登录 THEN 系统 SHALL 正确跳转到登录页 +4. WHEN 需要绑定手机号 THEN 系统 SHALL 正确跳转到绑定页面 diff --git a/.kiro/specs/frontend-api-refactor/tasks.md b/.kiro/specs/frontend-api-refactor/tasks.md new file mode 100644 index 00000000..eb42b70e --- /dev/null +++ b/.kiro/specs/frontend-api-refactor/tasks.md @@ -0,0 +1,180 @@ +# Implementation Plan: Frontend API Refactor + +## Overview + +将前端 API 调用从分散的 `this.req()` 和 `RequestManager.post()` 模式重构为集中的 Server Module 模式。改造过程中记录所有 API 地址,生成接口清单用于核对 C# 后端迁移完整性。 + +## Tasks + +- [x] 1. 修改 RequestManager 请求格式 + - [x] 1.1 修改 POST 请求 Content-Type 为 application/json + - 修改 `honey_box/common/request.js` 第 166 行 + - 将 `'content-type': 'application/x-www-form-urlencoded'` 改为 `'content-type': 'application/json'` + - _Requirements: 1.1_ + +- [ ] 2. 创建 Server Modules + - [ ] 2.1 创建 auth.js 认证模块 + - 创建 `honey_box/common/server/auth.js` + - 实现: wxLogin, mobileLogin, bindMobileByWx, bindMobileByCode, recordLogin, logOff + - _Requirements: 2.1, 2.2, 2.3_ + - [ ] 2.2 扩展 user.js 用户模块 + - 修改 `honey_box/common/server/user.js` + - 新增: updateUserInfo, getVipList, getProfitMoney, getProfitIntegral, getProfitScore, getProfitPay + - _Requirements: 2.1, 2.2, 2.3_ + - [ ] 2.3 创建 goods.js 商品模块 + - 创建 `honey_box/common/server/goods.js` + - 实现: getGoodsList, getGoodsDetail, getGoodsChildren, getGoodsExtend, getGoodsNumList, getGoodsNumDetail, getGoodsPrizeCount, getGoodsPrizeContent, getGoodsPrizeLogs + - _Requirements: 2.1, 2.2, 2.3_ + - [ ] 2.4 扩展 order.js 订单模块 + - 修改 `honey_box/common/server/order.js` + - 新增: calcOrderMoney, createOrder, calcInfiniteOrderMoney, createInfiniteOrder, calcMallOrderMoney, getOrderList, getOrderDetail, getPrizeOrderLog, getInfinitePrizeOrderLog, useItemCard + - _Requirements: 2.1, 2.2, 2.3_ + - [ ] 2.5 创建 warehouse.js 仓库模块 + - 创建 `honey_box/common/server/warehouse.js` + - 实现: getWarehouseIndex, recoveryPrize, sendPrize, confirmSend, getSendRecord, getSendRecordDetail, getRecoveryRecord, getLogistics + - _Requirements: 2.1, 2.2, 2.3_ + - [ ] 2.6 创建 coupon.js 优惠券模块 + - 创建 `honey_box/common/server/coupon.js` + - 实现: getCouponList, getCouponDetail, receiveCoupon, shareCoupon, synthesisCoupon, calcSynthesis + - _Requirements: 2.1, 2.2, 2.3_ + - [ ] 2.7 创建 welfare.js 福利模块 + - 创建 `honey_box/common/server/welfare.js` + - 实现: getWelfareHouseList, getWelfareHouseDetail, buyWelfareHouse, getSignInfo, doSign, getTaskList, receiveTaskReward + - _Requirements: 2.1, 2.2, 2.3_ + - [ ] 2.8 创建 collection.js 收藏模块 + - 创建 `honey_box/common/server/collection.js` + - 实现: getCollectionList, addCollection, cancelCollection, getCollectionStatus + - _Requirements: 2.1, 2.2, 2.3_ + - [ ] 2.9 创建 rank.js 排行榜模块 + - 创建 `honey_box/common/server/rank.js` + - 实现: getRankList + - _Requirements: 2.1, 2.2, 2.3_ + - [ ] 2.10 创建 invitation.js 邀请模块 + - 创建 `honey_box/common/server/invitation.js` + - 实现: getInvitationInfo, getInvitationRecord + - _Requirements: 2.1, 2.2, 2.3_ + - [ ] 2.11 创建 redeem.js 兑换码模块 + - 创建 `honey_box/common/server/redeem.js` + - 实现: useRedeemCode + - _Requirements: 2.1, 2.2, 2.3_ + - [ ] 2.12 创建 pay.js 支付模块 + - 创建 `honey_box/common/server/pay.js` + - 实现: wxPay, balancePay, recharge + - _Requirements: 2.1, 2.2, 2.3_ + +- [ ] 3. Checkpoint - Server Modules 完成 + - 确保所有 Server Module 创建完成 + - 检查函数命名是否语义化 + - 确认错误处理逻辑一致 + +- [ ] 4. 重构页面接口调用 - shouye 模块 + - [ ] 4.1 重构 pages/shouye/index.vue + - 替换 this.req() 调用为 Server Module 导入 + - 记录使用的 API 地址到清单 + - _Requirements: 3.1, 3.2, 3.3, 3.4_ + - [ ] 4.2 重构 pages/shouye/detail.vue + - 替换 this.req() 调用为 Server Module 导入 + - 记录使用的 API 地址到清单 + - _Requirements: 3.1, 3.2, 3.3, 3.4_ + - [ ] 4.3 重构 pages/shouye/detail_wuxian.vue + - 替换 this.req() 调用为 Server Module 导入 + - 记录使用的 API 地址到清单 + - _Requirements: 3.1, 3.2, 3.3, 3.4_ + - [ ] 4.4 重构 pages/shouye 其他页面 + - 包括: bangdan.vue, ranking.vue, dada_ranking.vue, yaoqing_ranking.vue, rili.vue, danye.vue, huanxiang.vue, slots.vue + - 记录使用的 API 地址到清单 + - _Requirements: 3.1, 3.2, 3.3, 3.4_ + +- [ ] 5. 重构页面接口调用 - user 模块 + - [ ] 5.1 重构 pages/user/login.vue + - 替换登录相关接口调用 + - 记录使用的 API 地址到清单 + - _Requirements: 3.1, 3.2, 3.3, 3.4_ + - [ ] 5.2 重构 pages/user/index.vue + - 替换用户信息相关接口调用 + - 记录使用的 API 地址到清单 + - _Requirements: 3.1, 3.2, 3.3, 3.4_ + - [ ] 5.3 重构 pages/user 其他页面 + - 包括: bangding.vue, bangdingweb.vue, vip.vue, coupon.vue, my_coupon.vue, order.vue, myCa.vue, change.vue, bi_jl.vue, jf_jl.vue, xfjl.vue, fhjl.vue, hsjl.vue, tui-guang.vue, yetx.vue, recharge-page.vue, cancel-account-page.vue, wuliu_detail.vue + - 记录使用的 API 地址到清单 + - _Requirements: 3.1, 3.2, 3.3, 3.4_ + +- [ ] 6. 重构页面接口调用 - other 模块 + - [ ] 6.1 重构 pages/other 所有页面 + - 包括: about.vue, address_edit.vue, choose_address.vue, order_info.vue, order_list.vue, prize_draw.vue, web-detail-lucky.vue, web-pay-order.vue, web-pay-success.vue + - 记录使用的 API 地址到清单 + - _Requirements: 3.1, 3.2, 3.3, 3.4_ + +- [ ] 7. 重构页面接口调用 - 其他模块 + - [ ] 7.1 重构 pages/mall/index.vue + - 替换商城相关接口调用 + - 记录使用的 API 地址到清单 + - _Requirements: 3.1, 3.2, 3.3, 3.4_ + - [ ] 7.2 重构 pages/infinite 所有页面 + - 包括: index.vue, benefit.vue, bonus_house.vue, bonus_house_details.vue, daily_check_in.vue, reward_records.vue + - 记录使用的 API 地址到清单 + - _Requirements: 3.1, 3.2, 3.3, 3.4_ + - [ ] 7.3 重构 pages/hegui/hegui.vue + - 替换盒柜相关接口调用 + - 记录使用的 API 地址到清单 + - _Requirements: 3.1, 3.2, 3.3, 3.4_ + - [ ] 7.4 重构 pages/guize/guize.vue + - 替换规则相关接口调用 + - 记录使用的 API 地址到清单 + - _Requirements: 3.1, 3.2, 3.3, 3.4_ + +- [ ] 8. 重构 package 分包页面 + - [ ] 8.1 重构 package/index 所有页面 + - 包括: coupon-center.vue, leitai.vue, lian-ji.vue, sign.vue + - 记录使用的 API 地址到清单 + - _Requirements: 3.1, 3.2, 3.3, 3.4_ + - [ ] 8.2 重构 package/mine 所有页面 + - 包括: collect.vue, coupon-detail.vue, equity.vue, qy-rule.vue, skill-card.vue, ti-qu.vue + - 记录使用的 API 地址到清单 + - _Requirements: 3.1, 3.2, 3.3, 3.4_ + +- [ ] 9. Checkpoint - 页面重构完成 + - 确保所有页面不再使用 this.req() 硬编码 URL + - 检查 API 地址清单完整性 + +- [ ] 10. 重构组件接口调用 + - [ ] 10.1 重构 components/detail-lucky 组件 + - 包括: detail-lucky.vue, detail-lucky-canvas.vue, detail-lucky-web.vue, detail-bao-xiang.vue, detail-grand-prize.vue + - 记录使用的 API 地址到清单 + - _Requirements: 4.1, 4.2, 4.3, 4.4_ + - [ ] 10.2 重构 components/pay-dialog/pay-dialog.vue + - 替换支付相关接口调用 + - 记录使用的 API 地址到清单 + - _Requirements: 4.1, 4.2, 4.3, 4.4_ + - [ ] 10.3 重构 components/order-confirm-popup 组件 + - 包括: order-confirm-popup.vue, order-confirm-popup-flw.vue + - 记录使用的 API 地址到清单 + - _Requirements: 4.1, 4.2, 4.3, 4.4_ + - [ ] 10.4 重构其他使用接口的组件 + - 检查并重构: collect-btn, coupon-pop, detail-toolbar, detail-wuxian-lingzhu, detail-wuxian-rage 等 + - 记录使用的 API 地址到清单 + - _Requirements: 4.1, 4.2, 4.3, 4.4_ + +- [ ] 11. 生成接口清单文档 + - [ ] 11.1 创建 API 接口清单文档 + - 创建 `docs/前端适配调整/API接口清单.md` + - 记录所有 API URL、所属模块、请求方式、使用位置 + - _Requirements: 5.1, 5.2, 5.3, 5.5_ + - [ ] 11.2 标注 C# 后端迁移状态 + - 对照 C# 后端代码,标注每个接口的迁移状态 + - 列出未迁移的接口清单 + - _Requirements: 5.4_ + +- [ ] 12. Final Checkpoint - 功能验证 + - 确保所有功能正常工作 + - 验证错误提示正确显示 + - 验证登录跳转正常 + - 验证绑定手机号跳转正常 + - _Requirements: 6.1, 6.2, 6.3, 6.4_ + +## Notes + +- 每个任务完成后需记录该文件使用的 API 地址 +- 重构时保持原有业务逻辑不变 +- 如发现未迁移的接口,记录到清单中 +- 建议按模块逐一测试,确保功能正常 diff --git a/docs/前端适配调整/request.js修改方案.md b/docs/前端适配调整/request.js修改方案.md new file mode 100644 index 00000000..41835876 --- /dev/null +++ b/docs/前端适配调整/request.js修改方案.md @@ -0,0 +1,280 @@ +# request.js 修改方案 + +## 1. 核心修改 + +### 1.1 修改 Content-Type + +将 POST 请求的 Content-Type 从 `application/x-www-form-urlencoded` 改为 `application/json`。 + +### 1.2 修改位置 + +文件:`honey_box/common/request.js` + +找到以下代码块(约第 130-140 行): + +```javascript +if (method.toUpperCase() == 'POST') { + // ... 签名计算代码 ... + + header = { + 'content-type': 'application/x-www-form-urlencoded', + client: client, + token: token, + adid: uni.getStorageSync('_ad_id'), + clickid: uni.getStorageSync('_click_id') + } +} +``` + +### 1.3 修改后代码 + +```javascript +if (method.toUpperCase() == 'POST') { + // ... 签名计算代码保持不变 ... + + header = { + 'content-type': 'application/json', // 修改这一行 + client: client, + token: token, + adid: uni.getStorageSync('_ad_id'), + clickid: uni.getStorageSync('_click_id') + } +} +``` + +## 2. 完整修改后的 request.js + +```javascript +/** + * 网络请求工具类 + * 封装统一的网络请求方法 + */ + +import EnvConfig from '@/common/env.js' +import md5 from 'js-md5' + +import { apiWhiteList } from '@/common/config.js' +import RouterManager from '@/common/router.js' +import { platform } from '@/common/platform/PlatformFactory' + +class RequestManager { + // 缓存对象 + static cache = { + data: new Map(), + expireTime: 5 * 60 * 1000, + timestamps: new Map() + }; + + static isCacheValid(cacheKey) { + const now = Date.now(); + if (this.cache.data.has(cacheKey)) { + const timestamp = this.cache.timestamps.get(cacheKey); + return now - timestamp < this.cache.expireTime; + } + return false; + } + + static updateCache(cacheKey, data) { + this.cache.data.set(cacheKey, data); + this.cache.timestamps.set(cacheKey, Date.now()); + } + + static getCache(url, data = {}, showLoading = false) { + const cacheKey = url + JSON.stringify(data); + if (this.isCacheValid(cacheKey)) { + console.log(cacheKey + '缓存有效'); + return Promise.resolve(this.cache.data.get(cacheKey)); + } + return this.get(url, data, showLoading).then(result => { + this.updateCache(cacheKey, result); + return result; + }); + } + + static isUrlInWhitelist(url) { + return apiWhiteList.some(whiteItem => url.indexOf(whiteItem) > -1); + } + + static generateNonce() { + return md5(Date.now() + Math.random().toString(36).substring(2, 15)); + } + + static request(param, backpage, backtype) { + return new Promise((resolve, reject) => { + if (!param || typeof param !== 'object') { + reject(new Error('请求参数错误')) + return + } + + uni.getNetworkType({ + success: function (res) { + if (res.networkType == 'none') { + uni.showToast({ + title: '网络连接异常,请检查网络', + icon: 'none' + }) + reject(new Error('网络连接异常')) + return + } + } + }) + + 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 + const apiBaseUrl = EnvConfig.apiBaseUrl + + let requestUrl = '' + if (url.startsWith('http://') || url.startsWith('https://')) { + requestUrl = url + } else { + const baseUrlWithSlash = apiBaseUrl.endsWith('/') ? apiBaseUrl : apiBaseUrl + '/' + const path = url.startsWith('/') ? url.substring(1) : url + requestUrl = baseUrlWithSlash + path + } + + const hostRegex = /^(?:https?:\/\/)?([^\/]+)/i + const matches = requestUrl.match(hostRegex) + const host = matches && matches[1] ? matches[1] : 'localhost' + + let header = {} + + // 添加签名参数 + 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 格式的请求头 + header = { + 'content-type': 'application/json', // 关键修改:统一使用 JSON + client: client, + token: token, + adid: uni.getStorageSync('_ad_id'), + clickid: uni.getStorageSync('_click_id') + } + + if (!Loading) { + uni.showLoading({ + title: '加载中...' + }) + } + + uni.request({ + url: requestUrl, + method: method.toUpperCase(), + header: header, + data: data, + success: res => { + // ... 响应处理代码保持不变 ... + }, + fail: e => { + console.error('网络请求失败:', e) + uni.showToast({ + title: e.errMsg || '请求失败', + icon: 'none' + }) + typeof param.fail == 'function' && param.fail(e) + reject(e) + }, + complete: () => { + uni.hideLoading() + typeof param.complete == 'function' && param.complete() + } + }) + }) + } + + static get(url, data = {}, showLoading = true) { + return this.request({ + url, + data, + method: 'GET', + Loading: !showLoading + }) + } + + static post(url, data = {}, showLoading = true) { + return this.request({ + url, + data, + method: 'POST', + Loading: !showLoading + }) + } +} + +export default RequestManager; +``` + +## 3. 签名机制说明 + +修改 Content-Type 后,签名机制保持不变: + +1. 参数按键名排序 +2. 拼接为 `key=value&` 格式 +3. 添加密钥 `host + timestamp` +4. MD5 加密生成签名 + +后端需要确保能正确解析 JSON 格式的请求体并验证签名。 + +## 4. 后端签名验证 + +C# 后端需要从 JSON 请求体中提取参数进行签名验证: + +```csharp +// 示例:签名验证中间件 +public class SignatureValidationMiddleware +{ + public async Task InvokeAsync(HttpContext context) + { + if (context.Request.Method == "POST" && + context.Request.ContentType?.Contains("application/json") == true) + { + // 读取请求体 + context.Request.EnableBuffering(); + var body = await new StreamReader(context.Request.Body).ReadToEndAsync(); + context.Request.Body.Position = 0; + + // 解析 JSON 并验证签名 + var data = JsonSerializer.Deserialize>(body); + // ... 签名验证逻辑 ... + } + + await _next(context); + } +} +``` + +## 5. 测试验证 + +修改后需要测试以下场景: + +1. **登录接口**:`POST /api/login` +2. **获取用户信息**:`POST /api/user` +3. **商品列表**:`POST /api/goods_list` +4. **创建订单**:`POST /api/orderbuy` + +确保签名验证通过,数据正确传递。 diff --git a/docs/前端适配调整/前端API适配方案.md b/docs/前端适配调整/前端API适配方案.md new file mode 100644 index 00000000..9c922d2b --- /dev/null +++ b/docs/前端适配调整/前端API适配方案.md @@ -0,0 +1,301 @@ +# 前端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. 逐步排查问题接口 diff --git a/docs/前端适配调整/实施检查清单.md b/docs/前端适配调整/实施检查清单.md new file mode 100644 index 00000000..7a4162a6 --- /dev/null +++ b/docs/前端适配调整/实施检查清单.md @@ -0,0 +1,194 @@ +# 前端适配实施检查清单 + +## 1. 修改前准备 + +- [ ] 备份当前前端代码 +- [ ] 确认后端 API 已部署并可访问 +- [ ] 准备测试账号和测试数据 + +## 2. 核心文件修改 + +### 2.1 request.js 修改 + +- [ ] 修改 `honey_box/common/request.js` +- [ ] 将 POST 请求的 Content-Type 改为 `application/json` +- [ ] 测试基础请求功能 + +### 2.2 接口文件修改 + +#### user.js +- [ ] 修改 `honey_box/common/server/user.js` +- [ ] 将 `/userInfo` 改为 `/user` +- [ ] 将 GET 请求改为 POST 请求 + +```javascript +// 修改前 +export const getUserInfo = async () => { + const res = await RequestManager.get('/userInfo'); + // ... +} + +// 修改后 +export const getUserInfo = async () => { + const res = await RequestManager.post('/user'); + // ... +} +``` + +#### config.js +- [ ] 检查 `honey_box/common/server/config.js` +- [ ] 确认接口路径正确 + +#### mall.js +- [ ] 检查 `honey_box/common/server/mall.js` +- [ ] 确认接口路径正确 + +#### order.js +- [ ] 检查 `honey_box/common/server/order.js` +- [ ] 确认接口路径正确 + +#### userAddress.js +- [ ] 检查 `honey_box/common/server/userAddress.js` +- [ ] 确认接口路径正确 + +## 3. 页面级别检查 + +### 3.1 用户模块 (`pages/user/`) + +- [ ] 登录页面 - 微信登录 +- [ ] 登录页面 - 手机号登录 +- [ ] 用户中心 - 获取用户信息 +- [ ] 用户中心 - 更新用户信息 +- [ ] 绑定手机号页面 +- [ ] VIP 页面 + +### 3.2 首页模块 (`pages/shouye/`) + +- [ ] 首页 - 商品列表 +- [ ] 商品详情页 +- [ ] 抽奖页面 +- [ ] 排行榜页面 + +### 3.3 商城模块 (`pages/mall/`) + +- [ ] 商城首页 +- [ ] 商品详情 +- [ ] 购买流程 + +### 3.4 福利模块 (`pages/infinite/`) + +- [ ] 签到页面 +- [ ] 任务列表 +- [ ] 福利屋 + +### 3.5 盒柜模块 (`pages/hegui/`) + +- [ ] 仓库首页 +- [ ] 回收功能 +- [ ] 发货功能 +- [ ] 物流查询 + +### 3.6 其他页面 (`pages/other/`) + +- [ ] 地址管理 +- [ ] 支付页面 +- [ ] 订单列表 +- [ ] 订单详情 + +## 4. 功能测试清单 + +### 4.1 用户认证 + +| 测试项 | 预期结果 | 测试结果 | 备注 | +|-------|---------|---------|------| +| 微信登录 | 返回 token | | | +| 手机号登录 | 返回 token | | | +| 获取用户信息 | 返回用户数据 | | | +| 更新昵称 | 更新成功 | | | +| 更新头像 | 更新成功 | | | +| 绑定手机号 | 绑定成功 | | | + +### 4.2 商品浏览 + +| 测试项 | 预期结果 | 测试结果 | 备注 | +|-------|---------|---------|------| +| 获取商品列表 | 返回分页数据 | | | +| 获取商品详情 | 返回详情数据 | | | +| 获取奖品列表 | 返回奖品数据 | | | +| 获取箱号列表 | 返回箱号数据 | | | +| 收藏商品 | 收藏成功 | | | +| 取消收藏 | 取消成功 | | | + +### 4.3 订单流程 + +| 测试项 | 预期结果 | 测试结果 | 备注 | +|-------|---------|---------|------| +| 计算订单金额 | 返回金额数据 | | | +| 创建订单 | 返回订单号 | | | +| 获取抽奖结果 | 返回中奖数据 | | | +| 获取订单列表 | 返回订单列表 | | | +| 获取订单详情 | 返回订单详情 | | | + +### 4.4 仓库操作 + +| 测试项 | 预期结果 | 测试结果 | 备注 | +|-------|---------|---------|------| +| 获取仓库列表 | 返回奖品列表 | | | +| 回收奖品 | 回收成功 | | | +| 发货奖品 | 发货成功 | | | +| 查看物流 | 返回物流信息 | | | + +### 4.5 优惠券 + +| 测试项 | 预期结果 | 测试结果 | 备注 | +|-------|---------|---------|------| +| 获取优惠券列表 | 返回优惠券列表 | | | +| 领取优惠券 | 领取成功 | | | +| 分享优惠券 | 分享成功 | | | +| 合成优惠券 | 合成成功 | | | + +### 4.6 福利功能 + +| 测试项 | 预期结果 | 测试结果 | 备注 | +|-------|---------|---------|------| +| 获取签到信息 | 返回签到数据 | | | +| 执行签到 | 签到成功 | | | +| 获取任务列表 | 返回任务列表 | | | +| 领取任务奖励 | 领取成功 | | | + +## 5. 错误处理检查 + +- [ ] 网络错误提示正常 +- [ ] 未登录跳转正常 +- [ ] 需绑定手机号提示正常 +- [ ] 业务错误提示正常 + +## 6. 兼容性测试 + +- [ ] 微信小程序 +- [ ] H5 网页版 +- [ ] Android APP +- [ ] iOS APP + +## 7. 上线前确认 + +- [ ] 所有测试用例通过 +- [ ] 错误日志无异常 +- [ ] 性能无明显下降 +- [ ] 用户体验无影响 + +## 8. 回滚方案 + +如果出现问题: + +1. 恢复 `request.js` 中的 Content-Type +2. 在后端添加 form-urlencoded 支持 +3. 逐步排查问题接口 + +## 9. 问题记录 + +| 问题描述 | 影响范围 | 解决方案 | 状态 | +|---------|---------|---------|------| +| | | | | +| | | | | +| | | | | diff --git a/docs/前端适配调整/接口对照表.md b/docs/前端适配调整/接口对照表.md new file mode 100644 index 00000000..87cb6cf3 --- /dev/null +++ b/docs/前端适配调整/接口对照表.md @@ -0,0 +1,261 @@ +# 前端接口对照表 + +## 1. 接口完整对照 + +### 1.1 用户认证模块 + +| 功能 | PHP 旧接口 | C# 新接口 | 请求方式 | 请求格式 | 状态 | +|-----|-----------|----------|---------|---------|------| +| 微信登录 | `/login` | `/api/login` | POST | JSON | ✅ 已实现 | +| 手机号登录 | `/mobileLogin` | `/api/mobileLogin` | POST | JSON | ✅ 已实现 | +| 获取用户信息 | `/user` | `/api/user` | POST | JSON | ✅ 已实现 | +| 更新用户信息 | `/update_userinfo` | `/api/update_userinfo` | POST | JSON | ✅ 已实现 | +| 微信绑定手机号 | `/login_bind_mobile` | `/api/login_bind_mobile` | POST | JSON | ✅ 已实现 | +| 验证码绑定手机号 | `/bindMobile` | `/api/bindMobile` | POST | JSON | ✅ 已实现 | +| 记录登录 | `/login_record` | `/api/login_record` | GET/POST | JSON | ✅ 已实现 | +| 账号注销 | `/user_log_off` | `/api/user_log_off` | POST | JSON | ✅ 已实现 | + +### 1.2 配置模块 + +| 功能 | PHP 旧接口 | C# 新接口 | 请求方式 | 请求格式 | 状态 | +|-----|-----------|----------|---------|---------|------| +| 系统配置 | `/config` | `/api/config` | GET | - | ✅ 已实现 | +| 平台配置 | `/getPlatformConfig` | `/api/getPlatformConfig` | GET | - | ✅ 已实现 | +| 广告列表 | `/getAdvert` | `/api/getAdvert` | GET/POST | Query | ✅ 已实现 | +| 单页内容 | `/getDanye` | `/api/getDanye` | GET | Query | ✅ 已实现 | + +### 1.3 商品模块 + +| 功能 | PHP 旧接口 | C# 新接口 | 请求方式 | 请求格式 | 状态 | +|-----|-----------|----------|---------|---------|------| +| 商品列表 | `/goods` | `/api/goods_list` | POST | JSON | ✅ 已实现 | +| 商品详情 | `/goodsdetail` | `/api/goods_detail` | POST | JSON | ✅ 已实现 | +| 子奖品列表 | `/goods_children` | `/api/goods_children` | POST | JSON | ✅ 已实现 | +| 商品扩展配置 | `/goods_extend` | `/api/goods_extend` | POST | JSON | ✅ 已实现 | +| 箱号列表 | `/goods_num_list` | `/api/goods_num_list` | POST | JSON | ✅ 已实现 | +| 箱号详情 | `/goods_num_detail` | `/api/goods_num_detail` | POST | JSON | ✅ 已实现 | +| 奖品数量统计 | `/goodslist_count` | `/api/goods_prize_count` | POST | JSON | ✅ 已实现 | +| 奖品内容 | `/goodslist_content` | `/api/goods_prize_content` | POST | JSON | ✅ 已实现 | +| 中奖记录 | `/shang_log` | `/api/goods_prize_logs` | POST | JSON | ✅ 已实现 | + +### 1.4 订单模块 + +| 功能 | PHP 旧接口 | C# 新接口 | 请求方式 | 请求格式 | 状态 | +|-----|-----------|----------|---------|---------|------| +| 一番赏金额计算 | `/ordermoney` | `/api/ordermoney` | POST | JSON | ✅ 已实现 | +| 一番赏下单 | `/orderbuy` | `/api/orderbuy` | POST | JSON | ✅ 已实现 | +| 无限赏金额计算 | `/infinite_ordermoney` | `/api/infinite_ordermoney` | POST | JSON | ✅ 已实现 | +| 无限赏下单 | `/infinite_orderbuy` | `/api/infinite_orderbuy` | POST | JSON | ✅ 已实现 | +| 商城金额计算 | `/mall_ordermoney` | `/api/mall_ordermoney` | POST | JSON | ✅ 已实现 | +| 订单列表 | `/order_list` | `/api/order_list` | POST | JSON | ✅ 已实现 | +| 订单详情 | `/order_detail` | `/api/order_detail` | POST | JSON | ✅ 已实现 | + +### 1.5 抽奖结果模块 + +| 功能 | PHP 旧接口 | C# 新接口 | 请求方式 | 请求格式 | 状态 | +|-----|-----------|----------|---------|---------|------| +| 一番赏抽奖结果 | `/prizeorderlog` | `/api/prizeorderlog` | POST | JSON | ✅ 已实现 | +| 无限赏抽奖结果 | `/infinite_prizeorderlog` | `/api/infinite_prizeorderlog` | POST | JSON | ✅ 已实现 | +| 无限赏中奖记录 | `/infinite_shang_log` | `/api/infinite_shang_log` | POST | JSON | ✅ 已实现 | +| 无限赏用户记录 | `/infinite_prizerecords` | `/api/infinite_prizerecords` | POST | JSON | ✅ 已实现 | +| 道具卡抽奖 | `/item_card_chou` | `/api/item_card_chou` | POST | JSON | ✅ 已实现 | + +### 1.6 仓库模块 + +| 功能 | PHP 旧接口 | C# 新接口 | 请求方式 | 请求格式 | 状态 | +|-----|-----------|----------|---------|---------|------| +| 仓库首页 | `/warehouse_index` | `/api/warehouse_index` | POST | JSON | ✅ 已实现 | +| 回收奖品 | `/warehouse_recovery` | `/api/warehouse_recovery` | POST | JSON | ✅ 已实现 | +| 发货奖品 | `/warehouse_send` | `/api/warehouse_send` | POST | JSON | ✅ 已实现 | +| 确认发货 | `/warehouse_send_confirm` | `/api/warehouse_send_confirm` | POST | JSON | ✅ 已实现 | +| 发货记录 | `/warehouse_send_record` | `/api/warehouse_send_record` | POST | JSON | ✅ 已实现 | +| 发货详情 | `/warehouse_send_record_detail` | `/api/warehouse_send_record_detail` | POST | JSON | ✅ 已实现 | +| 回收记录 | `/warehouse_recovery_record` | `/api/warehouse_recovery_record` | POST | JSON | ✅ 已实现 | +| 物流信息 | `/warehouse_order_logistics` | `/api/warehouse_order_logistics` | POST | JSON | ✅ 已实现 | + +### 1.7 优惠券模块 + +| 功能 | PHP 旧接口 | C# 新接口 | 请求方式 | 请求格式 | 状态 | +|-----|-----------|----------|---------|---------|------| +| 优惠券列表 | `/coupon_list` | `/api/coupon_list` | POST | JSON | ✅ 已实现 | +| 优惠券详情 | `/coupon_detail` | `/api/coupon_detail` | POST | JSON | ✅ 已实现 | +| 领取优惠券 | `/coupon_ling` | `/api/coupon_ling` | POST | JSON | ✅ 已实现 | +| 分享优惠券 | `/coupon_share` | `/api/coupon_share` | POST | JSON | ✅ 已实现 | +| 合成优惠券 | `/coupon_synthesis` | `/api/coupon_synthesis` | POST | JSON | ✅ 已实现 | +| 计算合成 | `/coupon_ji_suan` | `/api/coupon_ji_suan` | POST | JSON | ✅ 已实现 | + +### 1.8 资产模块 + +| 功能 | PHP 旧接口 | C# 新接口 | 请求方式 | 请求格式 | 状态 | +|-----|-----------|----------|---------|---------|------| +| 余额明细 | `/profitMoney` | `/api/profitMoney` | POST | JSON | ✅ 已实现 | +| 吧唧币明细 | `/profitIntegral` | `/api/profitIntegral` | POST | JSON | ✅ 已实现 | +| 积分明细 | `/profitScore` | `/api/profitScore` | POST | JSON | ✅ 已实现 | +| 支付记录 | `/profitPay` | `/api/profitPay` | POST | JSON | ✅ 已实现 | + +### 1.9 VIP模块 + +| 功能 | PHP 旧接口 | C# 新接口 | 请求方式 | 请求格式 | 状态 | +|-----|-----------|----------|---------|---------|------| +| VIP信息 | `/vip_list` | `/api/vip_list` | POST | JSON | ✅ 已实现 | + +### 1.10 福利模块 + +| 功能 | PHP 旧接口 | C# 新接口 | 请求方式 | 请求格式 | 状态 | +|-----|-----------|----------|---------|---------|------| +| 福利屋列表 | `/welfare_house_list` | `/api/welfare_house_list` | POST | JSON | ✅ 已实现 | +| 福利屋详情 | `/welfare_house_detail` | `/api/welfare_house_detail` | POST | JSON | ✅ 已实现 | +| 福利屋下单 | `/welfare_house_buy` | `/api/welfare_house_buy` | POST | JSON | ✅ 已实现 | +| 签到信息 | `/sign_info` | `/api/sign_info` | POST | JSON | ✅ 已实现 | +| 执行签到 | `/sign_do` | `/api/sign_do` | POST | JSON | ✅ 已实现 | +| 任务列表 | `/task_list` | `/api/task_list` | POST | JSON | ✅ 已实现 | +| 领取任务奖励 | `/task_receive` | `/api/task_receive` | POST | JSON | ✅ 已实现 | + +### 1.11 收藏模块 + +| 功能 | PHP 旧接口 | C# 新接口 | 请求方式 | 请求格式 | 状态 | +|-----|-----------|----------|---------|---------|------| +| 收藏列表 | `/collection_list` | `/api/collection_list` | POST | JSON | ✅ 已实现 | +| 添加收藏 | `/collection_add` | `/api/collection_add` | POST | JSON | ✅ 已实现 | +| 取消收藏 | `/collection_cancel` | `/api/collection_cancel` | POST | JSON | ✅ 已实现 | +| 收藏状态 | `/goods_collection_status` | `/api/goods_collection_status` | POST | JSON | ✅ 已实现 | + +### 1.12 排行榜模块 + +| 功能 | PHP 旧接口 | C# 新接口 | 请求方式 | 请求格式 | 状态 | +|-----|-----------|----------|---------|---------|------| +| 排行榜列表 | `/rank_list` | `/api/rank_list` | POST | JSON | ✅ 已实现 | + +### 1.13 邀请模块 + +| 功能 | PHP 旧接口 | C# 新接口 | 请求方式 | 请求格式 | 状态 | +|-----|-----------|----------|---------|---------|------| +| 邀请信息 | `/invitation_info` | `/api/invitation_info` | POST | JSON | ✅ 已实现 | +| 邀请记录 | `/invitation_record` | `/api/invitation_record` | POST | JSON | ✅ 已实现 | + +### 1.14 兑换码模块 + +| 功能 | PHP 旧接口 | C# 新接口 | 请求方式 | 请求格式 | 状态 | +|-----|-----------|----------|---------|---------|------| +| 兑换码使用 | `/redeem_code` | `/api/redeem_code` | POST | JSON | ✅ 已实现 | + +## 2. 接口路径变更汇总 + +以下接口路径发生了变化,前端需要更新: + +| 旧路径 | 新路径 | 说明 | +|-------|-------|------| +| `/goods` | `/api/goods_list` | 商品列表 | +| `/goodsdetail` | `/api/goods_detail` | 商品详情 | +| `/goodslist_count` | `/api/goods_prize_count` | 奖品统计 | +| `/goodslist_content` | `/api/goods_prize_content` | 奖品内容 | +| `/shang_log` | `/api/goods_prize_logs` | 中奖记录 | +| `/userInfo` | `/api/user` | 用户信息(前端 user.js 中使用) | + +## 3. 请求参数字段变更 + +### 3.1 商品列表 + +```javascript +// 旧参数 +{ + page: 1, + type: 0, + keyword: "" +} + +// 新参数(保持一致) +{ + page: 1, + type: 0, + keyword: "", + pageSize: 15 // 新增可选参数 +} +``` + +### 3.2 订单列表 + +```javascript +// 旧参数 +{ + page: 1, + page_size: 20 +} + +// 新参数 +{ + page: 1, + pageSize: 20 // 字段名变更:page_size -> pageSize +} +``` + +### 3.3 中奖记录 + +```javascript +// 旧参数 +{ + goods_id: 1001, + goods_num: 0, + shang_id: 0, + page: 1, + page_size: 15 +} + +// 新参数 +{ + goodsId: 1001, // 字段名变更 + goodsNum: 0, // 字段名变更 + shangId: 0, // 字段名变更 + page: 1, + pageSize: 15 // 字段名变更 +} +``` + +## 4. 响应格式对比 + +### 4.1 通用响应格式(保持一致) + +```json +{ + "status": 1, + "msg": "success", + "data": {} +} +``` + +### 4.2 分页响应格式 + +```json +// PHP 旧版 +{ + "status": 1, + "data": { + "data": [], + "total": 100, + "current_page": 1, + "last_page": 10 + } +} + +// C# 新版(保持一致) +{ + "status": 1, + "data": { + "data": [], + "total": 100, + "currentPage": 1, // 字段名可能有变化 + "lastPage": 10 + } +} +``` + +## 5. 前端文件修改清单 + +| 文件路径 | 修改内容 | 优先级 | +|---------|---------|-------| +| `common/request.js` | Content-Type 改为 JSON | 高 | +| `common/server/user.js` | 接口路径和请求方式 | 高 | +| `common/server/config.js` | 检查接口路径 | 中 | +| `common/server/mall.js` | 检查接口路径 | 中 | +| `common/server/order.js` | 检查接口路径 | 中 | +| `pages/*/` 各页面文件 | 检查直接调用的接口 | 低 | diff --git a/honey_box/common/request.js b/honey_box/common/request.js index 06103310..baa9807e 100644 --- a/honey_box/common/request.js +++ b/honey_box/common/request.js @@ -192,7 +192,7 @@ class RequestManager { data.sign = sign header = { - 'content-type': 'application/x-www-form-urlencoded', + 'content-type': 'application/json', client: client, token: token, adid: uni.getStorageSync('_ad_id'),