Files
Neo-ZQYY/docs/miniprogram-dev/api-audit/chat.md

9.1 KiB
Raw Blame History

chat 页面数据来源排查

排查日期2026-03-18 页面路径pages/chat/chat

概览

分类 数量 说明
A. Mock 数据 4 来自 mock-data.ts 或页面内联 mock联调时需替换为 API
B. 硬编码数据 3 直接写死在 data 或方法中的值
C. 已对接 API 0 当前页面无任何真实 API 调用
D. 前端计算/派生数据 6 由工具函数或页面逻辑计算得出
E. 路由参数 1 onLoad(options) 获取
F. WXML 硬编码文案 8 模板中直接写死的中文文案

一、Mock 数据

A1. mockChatMessages — 历史消息列表

项目 内容
来源 import { mockChatMessages } from '../../utils/mock-data'
类型 ChatMessage[]
使用位置 loadMessages()enrichMessages(mockChatMessages)this.setData({ messages })
涉及字段 id, role, content, timestamp, referenceCard(含 type, title, summary, data
联调替换 需替换为 AI 对话历史 API(如 GET /api/chat/messages?customerId=xxx),返回分页消息列表
当前 mock 条数 6 条(msg-001 ~ msg-006

A2. mockAIReplies — AI 回复模板(页面内联 mock

项目 内容
来源 chat.ts 顶部常量 const mockAIReplies = [...]
类型 string[]3 条固定回复文案)
使用位置 triggerAIReply()mockAIReplies[this._msgCounter % mockAIReplies.length]
联调替换 需替换为 AI 对话流式接口(如 POST /api/chat/sendSSE/WebSocket 流式返回)
当前值 ['根据数据分析,这位客户近期消费频次有所下降...', '好的,我已经记录了你的需求...', '这位客户偏好中式台球...']

A3. simulateStreamOutput — 模拟流式输出

项目 内容
来源 import { simulateStreamOutput } from '../../utils/chat'
类型 工具函数,逐字 setTimeout(tick, 50) 模拟打字效果
使用位置 triggerAIReply() 中调用,将 mock 回复逐字输出
联调替换 替换为真实 SSE/WebSocket 流式读取逻辑,callback 接口可复用

A4. referenceCard — 页面顶部引用卡片(条件构造)

项目 内容
来源 loadMessages() 中根据 customerId 内联构造
代码 { title: '客户详情', summary: \正在查看客户 ${customerId} 的相关信息` }`
联调替换 需从 客户详情 API 获取客户名称等信息填充,或由跳转页面通过路由参数传入

二、硬编码数据

B1. statusBarHeight 回退值

项目 内容
字段 statusBarHeight
位置 onLoad()sysInfo.statusBarHeight || 44
当前值 44(回退默认值)
应获取自 wx.getWindowInfo().statusBarHeight已获取44 仅为兜底)
风险等级 — 兜底值合理,不同机型差异可忽略

B2. loadMessages 延迟时间

项目 内容
字段 setTimeout(() => { ... }, 500)
位置 loadMessages() 方法
当前值 500ms 模拟网络延迟
联调处理 替换为真实 API 调用后移除 setTimeout,改用 API 响应回调
风险等级 — 联调时必须移除,否则造成不必要的 500ms 延迟

B3. triggerAIReply 延迟时间

项目 内容
字段 setTimeout(() => { this.triggerAIReply() }, 300)
位置 onSendMessage() 末尾
当前值 300ms 延迟触发 AI 回复
联调处理 替换为发送消息 API 成功回调后触发流式接收
风险等级 — 联调时需重构为 API 驱动的流程

三、已对接 API

无。 当前页面 0 个真实 API 调用。

注:项目中已存在 utils/request.ts(封装了 wx.request),联调时可直接使用。


四、前端计算/派生数据

D1. enrichMessages() 派生字段

对每条消息计算以下展示字段:

派生字段 计算逻辑 来源函数
timeLabel 相对时间文案(刚刚/N分钟前/MM-DD formatRelativeTime(m.timestamp)
imTimeLabel IM 时间格式HH:mm / MM-DD HH:mm formatIMTime(m.timestamp)
showTimeDivider 是否显示时间分割线首条必显示间隔≥5分钟显示 shouldShowTimeDivider(prev, curr)
referenceCard.dataList Record<string,string> 转为 {key,value}[]wx:for toDataList(m.referenceCard.data)

D2. 用户发送消息时的派生字段

派生字段 计算逻辑
userMsg.timeLabel 固定为 '刚刚'
userMsg.imTimeLabel formatIMTime(new Date().toISOString())
userMsg.showTimeDivider shouldShowTimeDivider(prevTs, now)
userMsg.id msg-user-${this._msgCounter}(自增计数器)
userMsg.timestamp new Date().toISOString()(客户端当前时间)

D3. AI 回复消息的派生字段

同 D2 逻辑,id 格式为 msg-ai-${this._msgCounter}

D4. pageState 状态机

状态值 触发条件
'loading' loadMessages() 开始时
'empty' 消息列表为空且无引用卡片
'normal' 消息加载成功且有内容
'error' loadMessages() 捕获异常

D5. isStreaming / streamingContent

字段 说明
isStreaming AI 流式回复进行中标志,控制输入框禁用和打字指示器
streamingContent 流式输出的当前内容片段

D6. scrollToId

滚动锚点,通过 scrollToBottom() 方法设置为 'scroll-bottom',驱动 scroll-view 滚动到底部。


五、路由参数

E1. customerId

项目 内容
获取方式 onLoad(options)options?.customerId || ''
用途 1. 传入 loadMessages(customerId) 加载对应客户的对话2. 决定是否显示页面顶部引用卡片
当前状态 仅用于 mock 逻辑判断,未传入任何 API
联调需求 作为 API 请求参数传入消息列表接口

六、WXML 硬编码文案

编号 文案 位置 说明
F1 加载中... 加载态 g-toast-loading-text 通用加载文案,可保留
F2 加载失败,请重试 错误态 error-text 通用错误文案,可保留
F3 重新加载 错误态 retry-btn-text 按钮文案,可保留
F4 引用内容 引用卡片 reference-tag 标签文案,可保留
F5 你好,我是 AI 助手 空对话提示 empty-text 欢迎语,建议后续从配置获取
F6 有什么可以帮你的? 空对话提示 empty-sub 副标题,建议后续从配置获取
F7 输入消息... 输入框 placeholder 占位文案,可保留
F8 AI 助手 chat.jsonnavigationBarTitleText 导航栏标题,可保留

七、联调 TODO

优先级 P0阻塞联调

  • 替换消息列表加载loadMessages()mockChatMessages → 调用 GET /api/chat/messages 接口

    • 入参:customerId(可选)、分页参数
    • 出参:ChatMessage[]
    • 移除 setTimeout(..., 500) 模拟延迟
  • 替换 AI 回复流程triggerAIReply()mockAIReplies + simulateStreamOutput → 调用 POST /api/chat/send 流式接口

    • 入参:content(用户消息)、customerIdconversationId
    • 出参SSE/WebSocket 流式文本
    • 保留 isStreaming 状态控制和逐字渲染逻辑
  • 替换引用卡片数据loadMessages() 中内联构造的 referenceCard → 从客户详情 API 或路由参数获取真实客户信息

优先级 P1联调后优化

  • 消息发送 APIonSendMessage() 中用户消息需先通过 API 持久化,再触发 AI 回复
  • 对话会话管理:当前无 conversationId 概念,需增加会话创建/恢复逻辑
  • 消息 ID 生成:当前使用前端自增计数器 _msgCounter,联调后应使用服务端返回的 ID

优先级 P2体验优化

  • 错误重试onRetry() 当前仅重新调用 loadMessages(),需增加 toast 提示
  • 空对话欢迎语F5/F6 硬编码文案考虑从后端配置获取
  • 移除 simulateStreamOutput:联调完成后,utils/chat.ts 中的模拟函数可删除(保留 simulateStreamOutputSync 用于测试)
  • 移除 mockAIReplies:页面内联 mock 常量清理
  • 移除 mock-data.tsmockChatMessages 引用:确认其他页面不再使用后,清理 ChatMessage 相关 mock

依赖确认

依赖项 状态 说明
utils/request.ts 已存在 封装了 wx.request,可直接使用
AI 对话 API后端 待确认 需确认接口设计REST vs WebSocket、流式协议
客户详情 API 待确认 引用卡片需要客户基本信息
对话会话 API 待确认 会话创建、历史会话列表