# P15 — 小程序前后端联调：Mock → 真实 API 切换

> 创建时间：2026-03-22
> 状态：草案
> 优先级：P0（dev-trace-log 的前置依赖）
> 关联 Spec：dev-trace-log（调试工具链）

---

## 一、背景

小程序前端已完成 H5 → 原生迁移（h5-miniprogram-migration spec）和格式统一（P13 spec），
26 个后端接口已全部实现（API 契约文档确认）。但当前 `services/api.ts` 所有函数返回空 Mock 数据，
`request` 导入已注释，前端与后端之间没有真实的 HTTP 通信。

本 PRD 覆盖"前后端联调"中 dev-trace-log 未涵盖的部分：将小程序从 Mock 数据切换到真实后端接口。

## 二、目标用户与场景

- 用户：开发者（前后端联调阶段）
- 场景：小程序连接本地 FastAPI 后端（localhost），验证登录、审核、任务、AI 模块的完整数据流

## 三、切换范围

### 3.1 本期切换（P0）

| 模块 | 涉及页面 | 涉及接口 |
|------|---------|---------|
| 认证 | login、apply、reviewing、no-permission | AUTH-1~5（login、dev-login、me、refresh、apply） |
| 任务 | task-list、task-detail（4 变体） | TASK-1~4（列表、详情、操作、绩效概览） |
| 审核 | reviewing、apply | AUTH-3（me，状态判断）、AUTH-5（apply） |
| AI | chat、chat-history | CHAT-1~3（对话列表、发送消息/SSE、历史记录） |

### 3.2 本期不做

| 模块 | 页面 | 原因 |
|------|------|------|
| 看板 | board-finance、board-customer、board-coach | 用户明确排除 |
| 助教 | coach-detail | 非优先联调模块 |
| 客户 | customer-detail、customer-service-records | 非优先联调模块 |
| 备注 | notes | 非优先联调模块 |
| 绩效 | performance、performance-records | 非优先联调模块 |
| 个人 | my-profile | 非优先联调模块 |

## 四、需求清单

### REQ-1：API 环境配置

**描述**：创建统一的 API 配置模块，支持开发/测试/生产环境切换。

**验收标准**：
- 创建 `apps/miniprogram/miniprogram/config/api.ts`
- 定义 `API_BASE_URL` 常量，开发环境指向 `http://localhost:8000`
- 支持通过构建变量或条件编译切换环境
- `utils/request.ts` 从配置模块读取 base URL，禁止硬编码

### REQ-2：恢复真实 API 调用

**描述**：将 `services/api.ts` 从 Mock 数据恢复为真实 HTTP 请求。

**验收标准**：
- 取消 `request` 导入的注释
- 移除 `delay()` 辅助函数
- 移除所有空 Mock 数据返回
- P0 模块（认证、任务、审核、AI）的 service 函数改为调用 `request()` 发起真实 HTTP 请求
- 非 P0 模块暂时保留 Mock（添加 `// TODO: P15 后续批次切换` 注释）

### REQ-3：请求层统一封装

**描述**：确保 `utils/request.ts` 提供完整的请求封装能力。

**验收标准**：
- 自动附加 `Authorization: Bearer <token>` 请求头（从 Storage 读取）
- 统一解析响应格式 `{ code: 0, data: ... }` / `{ code: number, message: string }`
- code ≠ 0 时抛出业务错误（含 code 和 message）
- 网络异常（超时、断连）抛出网络错误（区分于业务错误）
- Token 过期（401）自动尝试 refresh，refresh 失败跳转登录页
- 请求超时设置（默认 30s，AI 接口 120s）

### REQ-4：错误处理与用户反馈

**描述**：切换到真实接口后，网络错误、超时、空数据等场景需要有明确的用户反馈。

**验收标准**：
- 网络错误：显示"网络连接失败，请检查网络后重试"+ 重试按钮
- 请求超时：显示"请求超时，请稍后重试"+ 重试按钮
- 业务错误（code ≠ 0）：显示后端返回的 message
- 鉴权失败（401/403）：跳转登录页或显示无权限页
- 空数据：显示对应的空态页面（已有四态框架，确保正确触发）
- 所有错误场景记录到 console（开发环境），便于调试
- 页面级 `pageState` 四态（loading/empty/error/normal）在真实 API 场景下正确流转

### REQ-5：数据格式适配验证

**描述**：验证前端数据结构与后端接口返回的数据结构一致，不一致处做适配。

**验收标准**：
- 后端响应统一 camelCase（ResponseWrapperMiddleware 已处理）
- 前端类型定义（`services/api.ts` 中的 interface）与后端实际返回字段一一对应
- 分页格式对齐：`{ items: T[], total, page, pageSize }`
- 金额字段：number 类型，保留 2 位小数，前端通过 `formatMoney()` 展示
- 时间字段：ISO 8601 字符串，前端通过 `formatDateShort()` / `formatDateFull()` 展示
- 不一致处在 service 层做适配转换，不在页面层处理

### REQ-6：SSE 流式对接（AI 模块）

**描述**：AI 对话模块的 SSE 流式响应需要特殊处理，不能用普通 HTTP 请求。

**验收标准**：
- `services/api.ts` 中 chat 相关函数使用 SSE 方式调用后端
- 支持流式接收 token 并实时渲染到对话界面
- SSE 连接异常时显示错误提示并允许重试
- SSE 超时处理（AI 响应可能较慢，超时阈值 120s）
- 流式过程中显示"正在思考..."loading 态

### REQ-7：登录流程对接

**描述**：小程序登录流程从 Mock 切换到真实微信登录 → 后端换 Token 流程。

**验收标准**：
- 开发环境使用 `POST /api/xcx/dev-login`（openid 模拟登录）
- 登录成功后将 access_token 和 refresh_token 存入 Storage
- `app.ts` 中 `checkAuthStatus()` 调用真实 `GET /api/xcx/me` 判断用户状态
- 根据用户 status（new/pending/approved/rejected/disabled）正确路由到对应页面
- Token 过期自动 refresh，refresh 失败清除 Storage 并跳转登录页

## 五、数据流

```
小程序页面
  ↓ 调用 service 函数
services/api.ts
  ↓ 调用 request()
utils/request.ts
  ↓ wx.request() + Authorization header
  ↓ 响应解析 + 错误处理
FastAPI 后端 (localhost:8000)
  ↓ ResponseWrapperMiddleware (camelCase)
  ↓ { code: 0, data: ... }
返回页面 → 更新 data → 渲染
```

## 六、依赖与约束

| 依赖项 | 状态 | 说明 |
|--------|------|------|
| 后端 26 个接口 | ✅ 已实现 | API 契约文档确认 |
| API 契约文档 | ✅ 已就绪 | `docs/miniprogram-dev/API-contract.md` |
| 前端类型定义 | ✅ 已定义 | `services/api.ts` 中的 interface |
| 四态框架 | ✅ 已实现 | loading/empty/error/normal |
| 格式化工具函数 | ✅ 已实现 | P13 spec 已完成 |
| request.ts 封装 | ⚠️ 需验证 | 文件存在但当前未使用 |
| dev-trace-log | 🔜 并行开发 | 联调时提供调试可视化 |

## 七、验收标准（整体）

1. 登录流程：dev-login → 获取 token → 自动路由到正确页面
2. 任务列表：真实数据加载、分页、筛选正常工作
3. 任务详情：4 种变体页面正确渲染真实数据
4. AI 对话：SSE 流式响应实时渲染，错误时有提示
5. 错误场景：断网、超时、401、403、空数据均有正确的用户反馈
6. 非 P0 模块：保持 Mock 不受影响

## 八、风险

| 风险 | 影响 | 缓解措施 |
|------|------|---------|
| 后端接口返回格式与前端类型不一致 | 页面渲染异常 | REQ-5 要求逐字段验证 |
| 微信开发者工具不支持 localhost | 无法联调 | 使用 dev-login 绕过微信登录；配置开发者工具"不校验合法域名" |
| SSE 在小程序中的兼容性 | AI 模块无法工作 | 需验证 wx.request 的 enableChunked 或使用 requestTask |
| Token 过期处理不完善 | 用户体验中断 | REQ-3 要求自动 refresh |

## 九、与 dev-trace-log 的关系

本 PRD 是 dev-trace-log 的前置依赖：
- 没有真实 API 调用 → trace 系统无数据可采集
- 建议并行推进：先完成 REQ-1~3（基础设施），再逐模块切换（REQ-7 → REQ-2 → REQ-4~6）
- 切换过程中使用 dev-trace-log 的 span 链路验证每个接口的完整处理流程
