143 lines
6.5 KiB
Markdown
143 lines
6.5 KiB
Markdown
# chat-history 页面数据来源排查
|
||
|
||
> 排查日期:2026-03-18
|
||
> 页面路径:pages/chat-history/chat-history
|
||
> 排查范围:chat-history.ts / .wxml / .wxss / .json + 引用的 mock-data.ts / sort.ts / time.ts
|
||
|
||
## 概览
|
||
|
||
| 分类 | 数量 | 说明 |
|
||
|------|------|------|
|
||
| A. Mock 数据 | 5 字段 | 全部列表数据来自 `mockChatHistory`,无真实 API |
|
||
| B. 硬编码数据 | 5 处 | `ICON_GRADIENTS` 配色、延迟常量、回退值、跳转路径 |
|
||
| C. 已对接 API | 0 | 页面尚未对接任何后端接口 |
|
||
| D. 前端计算/派生 | 4 字段 | `timeLabel`、`iconGradient`、`pageState`、`statusBarHeight` |
|
||
| E. 路由参数 | 0 | 本页无接收路由参数(跳转时传出 `historyId`) |
|
||
| F. WXML 硬编码文案 | 6 处 | 加载/错误/空态/底部提示等 UI 文案 |
|
||
|
||
---
|
||
|
||
## 一、Mock 数据(来自 mock-data.ts)
|
||
|
||
数据源:`import { mockChatHistory } from '../../utils/mock-data'`
|
||
类型定义:`ChatHistoryItem`
|
||
|
||
| # | 字段 | 类型 | Mock 值示例 | 说明 |
|
||
|---|------|------|-------------|------|
|
||
| 1 | `id` | `string` | `'chat-001'` | 对话记录唯一 ID |
|
||
| 2 | `title` | `string` | `'张伟消费分析'` | 对话标题 |
|
||
| 3 | `lastMessage` | `string` | `'已记录。下次回访张伟时...'` | 最后一条消息摘要 |
|
||
| 4 | `timestamp` | `string` | `'2026-03-05T14:02:03+08:00'` | ISO 8601 时间戳 |
|
||
| 5 | `customerName` | `string?` | `'张伟'` / `undefined` | 可选,关联客户名 |
|
||
|
||
Mock 数据条数:4 条(`mockChatHistory` 数组长度)
|
||
|
||
---
|
||
|
||
## 二、硬编码数据
|
||
|
||
| # | 位置 | 值 | 说明 |
|
||
|---|------|-----|------|
|
||
| 1 | `chat-history.ts` 顶部常量 `ICON_GRADIENTS` | 6 组 CSS 渐变色 | VI 规范 §6.2 AI 图标配色系统(indigo/purple/red/orange/yellow/blue) |
|
||
| 2 | `chat-history.ts` → `loadData()` | `setTimeout(..., 400)` | 模拟网络延迟 400ms,联调时需替换为真实异步调用 |
|
||
| 3 | `chat-history.ts` → `onPullDownRefresh()` | `setTimeout(() => wx.stopPullDownRefresh(), 600)` | 下拉刷新 600ms 后停止,联调时需与真实请求回调绑定 |
|
||
| 4 | `chat-history.ts` → `onLoad()` | `sysInfo.statusBarHeight \|\| 44` | 状态栏高度回退值 44(当前 WXML 中未消费该值) |
|
||
| 5 | `chat-history.ts` → `onItemTap()` | `'/pages/chat/chat?historyId=' + id` | 跳转路径硬编码 |
|
||
|
||
---
|
||
|
||
## 三、已对接 API
|
||
|
||
**无。** 页面当前 0 个真实 API 调用。
|
||
|
||
代码中有明确 TODO 注释:
|
||
```typescript
|
||
// TODO: 替换为真实 API 调用
|
||
const sorted = sortByTimestamp(mockChatHistory)
|
||
```
|
||
|
||
---
|
||
|
||
## 四、前端计算/派生数据
|
||
|
||
| # | 字段 | 计算逻辑 | 依赖 |
|
||
|---|------|----------|------|
|
||
| 1 | `timeLabel` | `formatRelativeTime(item.timestamp)` | `time.ts` → 将 ISO 时间戳转为「刚刚/N分钟前/N小时前/N天前/MM-DD/YYYY-MM-DD」 |
|
||
| 2 | `iconGradient` | `ICON_GRADIENTS[Math.floor(Math.random() * ICON_GRADIENTS.length)]` | 从 6 色渐变数组中随机取一个(每次渲染结果不同) |
|
||
| 3 | `pageState` | 状态机:`'loading'` → `'normal'` / `'empty'` / `'error'` | 根据 `list.length === 0` 判断空态,`catch` 进入错误态 |
|
||
| 4 | `statusBarHeight` | `wx.getWindowInfo().statusBarHeight \|\| 44` | 系统 API 获取(当前 WXML 未消费此值) |
|
||
|
||
---
|
||
|
||
## 五、路由参数
|
||
|
||
**本页无接收路由参数。** `onLoad()` 未读取 `options` 参数。
|
||
|
||
传出参数(跳转时):
|
||
|
||
| 目标页 | 参数 | 来源 |
|
||
|--------|------|------|
|
||
| `/pages/chat/chat` | `historyId={item.id}` | 列表项的 `id` 字段(当前为 Mock) |
|
||
|
||
---
|
||
|
||
## 六、WXML 硬编码文案
|
||
|
||
| # | 位置 | 文案 | 说明 |
|
||
|---|------|------|------|
|
||
| 1 | 加载态 toast | `加载中...` | loading 浮层文案 |
|
||
| 2 | 错误态 emoji | `😵` | 错误图标(emoji) |
|
||
| 3 | 错误态文案 | `加载失败,请重试` | 错误提示 |
|
||
| 4 | 错误态按钮 | `重新加载` | 重试按钮文案 |
|
||
| 5 | 空态描述 | `暂无对话记录` | `<t-empty description="暂无对话记录" />` |
|
||
| 6 | 底部提示 | `— 已加载全部记录 —` | 列表底部 footer |
|
||
|
||
---
|
||
|
||
## 七、联调 TODO
|
||
|
||
### 7.1 必须替换的 Mock 数据
|
||
|
||
| 优先级 | 改动项 | 当前状态 | 联调目标 |
|
||
|--------|--------|----------|----------|
|
||
| P0 | `mockChatHistory` → 真实 API | `loadData()` 中直接引用 mock 数组 | 调用后端 `GET /api/chat/history` 或类似接口,返回 `ChatHistoryItem[]` |
|
||
| P0 | 移除 `setTimeout(…, 400)` 模拟延迟 | 硬编码 400ms | 替换为 `wx.request` / 封装的 `http.get()` 异步调用 |
|
||
| P1 | 下拉刷新绑定真实请求 | `onPullDownRefresh` 中 600ms 后固定停止 | 在 API 回调中调用 `wx.stopPullDownRefresh()` |
|
||
|
||
### 7.2 需确认的接口契约
|
||
|
||
| 字段 | 问题 | 建议 |
|
||
|------|------|------|
|
||
| `id` | Mock 为 `chat-001` 格式,后端实际 ID 格式? | 确认是 UUID / 自增 ID / 其他 |
|
||
| `title` | 对话标题由谁生成?后端还是前端? | 确认接口是否返回 `title` |
|
||
| `lastMessage` | 是否需要截断?最大长度? | 确认接口返回的是完整消息还是摘要 |
|
||
| `timestamp` | 后端返回格式?ISO 8601 / Unix ms? | `formatRelativeTime` 两种都支持 |
|
||
| `customerName` | 可选字段,后端是否一定返回? | 确认接口契约中该字段的 nullable 语义 |
|
||
|
||
### 7.3 需关注的前端逻辑
|
||
|
||
| 项目 | 说明 |
|
||
|------|------|
|
||
| `iconGradient` 随机分配 | 每次渲染/刷新颜色会变,是否需要按 `id` 哈希固定? |
|
||
| `statusBarHeight` 未使用 | `data.statusBarHeight` 已计算但 WXML 中无消费,可能是自定义导航栏残留代码 |
|
||
| 分页/无限滚动 | 当前一次性加载全部,数据量大时需要分页 |
|
||
| 错误态重试 | `onRetry` 调用 `loadData()`,联调后需确认错误处理(网络超时/401/500 等) |
|
||
| `import { mockChatHistory }` | 联调完成后需删除此 import 及 `mock-data.ts` 中对应导出 |
|
||
|
||
### 7.4 引用的工具函数(无需改动)
|
||
|
||
| 函数 | 文件 | 用途 | 联调影响 |
|
||
|------|------|------|----------|
|
||
| `sortByTimestamp()` | `utils/sort.ts` | 按 `timestamp` 降序排列 | 纯函数,无需改动 |
|
||
| `formatRelativeTime()` | `utils/time.ts` | 时间戳 → 相对时间文案 | 纯函数,无需改动 |
|
||
|
||
### 7.5 引用的组件
|
||
|
||
| 组件 | 路径 | 数据依赖 |
|
||
|------|------|----------|
|
||
| `ai-float-button` | `/components/ai-float-button/` | 无 props 传入,组件内部自治 |
|
||
| `dev-fab` | `/components/dev-fab/` | 开发调试用浮动按钮,上线前移除 |
|
||
| `t-loading` | TDesign | 无数据依赖 |
|
||
| `t-icon` | TDesign | `name`/`size`/`color` 硬编码 |
|
||
| `t-empty` | TDesign | `description` 硬编码 |
|