feat: 客服
This commit is contained in:
+517
@@ -0,0 +1,517 @@
|
||||
# 信任桥商城 AI 智能客服产品需求文档
|
||||
|
||||
> 文档版本:v1.0(评审稿)
|
||||
> 编制日期:2026-07-17
|
||||
> 适用范围:商城 H5、微信小程序、App、客服管理后台、客服后端
|
||||
> 前置能力:现有客服会话、消息、文件、语音、商品/订单卡片、WebSocket
|
||||
|
||||
## 1. 结论
|
||||
|
||||
在现有客服系统中接入 AI 智能体可行,且不需要新建一套独立聊天系统。
|
||||
|
||||
推荐采用“同一会话、后端路由、AI 优先、按需转人工”的模式:用户仍进入现有客服页面;用户消息先由后端客服路由服务接收。在 AI 服务状态下,消息交给 AI 智能体回答,不通知真实客服;当用户表达“人工客服、人工、真人、转人工”等明确意图,或 AI 服务发生异常时,会话切换为待人工状态,再通过现有 WebSocket 通知客服后台。
|
||||
|
||||
AI 模型必须由商城后端调用,前端和小程序不得保存模型 API Key。模型供应商通过配置接入,首期可使用现有阿里云百炼/DashScope OpenAI 兼容接口,后续可替换模型而不改用户端。
|
||||
|
||||
## 2. 项目背景
|
||||
|
||||
目前客服系统已经具备:
|
||||
|
||||
- 用户端和后台端实时聊天。
|
||||
- 文本、图片、文件、语音、商品、订单和引用消息。
|
||||
- 消息撤回、删除、已读和语音转文字。
|
||||
- WebSocket 心跳、断线重连和未读提醒。
|
||||
- 客服主动联系会员。
|
||||
- 后台查看会员、浏览商品和交易订单。
|
||||
|
||||
当前所有用户消息都会进入人工客服工作台。业务量增长后,商品规则、物流时效、退换货流程等重复问题会占用大量人工坐席。本项目通过 AI 完成首轮接待,仅将确实需要人工处理的会话推送给真实客服。
|
||||
|
||||
## 3. 产品目标
|
||||
|
||||
### 3.1 核心目标
|
||||
|
||||
1. 用户进入客服页后首先与 AI 智能客服交流。
|
||||
2. AI 能回答商城规则、商品、订单、物流和售后等常见问题。
|
||||
3. 用户明确要求人工时,立即停止 AI 自动回复并通知真实客服。
|
||||
4. 未触发人工的 AI 会话不进入人工待处理提醒,避免坐席被无效消息打扰。
|
||||
5. 转人工时自动向客服提供问题摘要、相关商品/订单和最近对话,减少重复询问。
|
||||
6. AI 故障时不阻断现有客服能力,可自动降级到人工客服。
|
||||
|
||||
### 3.2 建议成功指标
|
||||
|
||||
- AI 首次响应时间 P95 小于 5 秒。
|
||||
- 用户消息处理成功率不低于 99.9%。
|
||||
- 明确转人工意图识别召回率不低于 99%。
|
||||
- “不需要人工”等否定表达误转率低于 1%。
|
||||
- 人工接入后 AI 继续自动回复的并发事故为 0。
|
||||
- 首期 AI 独立解决率达到 30% 后再逐步扩大流量。
|
||||
|
||||
### 3.3 本期不做
|
||||
|
||||
- AI 自动退款、改价、取消订单等资金或订单写操作。
|
||||
- AI 代替人工作出赔付承诺。
|
||||
- AI 主动营销和批量外呼。
|
||||
- 多智能体协作编排。
|
||||
- 将用户隐私数据用于外部模型训练。
|
||||
|
||||
## 4. 产品原则
|
||||
|
||||
1. **AI 身份透明**:明确显示“AI 智能客服”,不能伪装成真人。
|
||||
2. **转人工随时可用**:用户可以输入关键词,也可以点击“转人工”按钮。
|
||||
3. **人工优先**:进入待人工或人工服务状态后,AI 立即停止业务回答。
|
||||
4. **事实来自系统**:订单、物流、价格等动态数据必须通过后端工具查询,禁止模型凭空编造。
|
||||
5. **最小数据传输**:只向模型发送回答当前问题所必需的信息。
|
||||
6. **可降级**:模型超时、限流或不可用时,客服系统仍能正常保存消息并转人工。
|
||||
|
||||
## 5. 角色定义
|
||||
|
||||
| 角色 | 说明 |
|
||||
| --- | --- |
|
||||
| 会员 | 商城已登录用户,使用本人头像和名称 |
|
||||
| AI 智能客服 | 默认首轮接待,使用 TB 客服头像并显示 AI 标识 |
|
||||
| 人工客服 | 后台坐席,可接管、回复、结束人工服务或交回 AI |
|
||||
| 客服管理员 | 配置 AI 开关、转人工规则、知识库、服务时间和数据报表 |
|
||||
|
||||
## 6. 会话状态
|
||||
|
||||
每个客服会话只能处于以下一种服务状态:
|
||||
|
||||
| 状态 | 含义 | AI 是否回复 | 是否通知人工 |
|
||||
| --- | --- | --- | --- |
|
||||
| `AI_ACTIVE` | AI 正在接待 | 是 | 否 |
|
||||
| `HUMAN_PENDING` | 已申请人工,等待接入 | 否,仅发送一次系统提示 | 是 |
|
||||
| `HUMAN_ACTIVE` | 人工客服已接管 | 否 | 是 |
|
||||
| `CLOSED` | 本轮服务结束 | 否 | 否 |
|
||||
|
||||
状态流转:
|
||||
|
||||
```text
|
||||
进入客服 / 重新咨询
|
||||
↓
|
||||
AI_ACTIVE
|
||||
├─ 普通咨询 → AI 回复 → AI_ACTIVE
|
||||
├─ 转人工意图 → HUMAN_PENDING → 客服接入 → HUMAN_ACTIVE
|
||||
└─ AI 故障/高风险 → HUMAN_PENDING
|
||||
|
||||
HUMAN_ACTIVE
|
||||
├─ 客服结束会话 → CLOSED
|
||||
└─ 客服交回 AI → AI_ACTIVE
|
||||
```
|
||||
|
||||
状态切换必须在后端事务中完成,不能仅靠前端控制。人工接入与 AI 回复并发时,以人工接入为最高优先级;AI 返回结果前必须再次检查会话状态,状态已改变则丢弃 AI 回复。
|
||||
|
||||
## 7. 用户端需求
|
||||
|
||||
### 7.1 首次进入
|
||||
|
||||
页面标题保持“全媒体智能客服”,聊天区显示欢迎消息:
|
||||
|
||||
> 您好,我是 AI 智能客服,可以帮您查询商品、订单、物流和售后问题。如需人工服务,请输入“人工客服”或点击“转人工”。
|
||||
|
||||
AI 消息使用现有 TB 客服头像,并在名称旁显示“AI”标识。人工接入后名称和状态切换为实际客服名称或“人工客服”。
|
||||
|
||||
### 7.2 AI 对话
|
||||
|
||||
- 用户文本消息先保存,再异步交给 AI,避免模型失败导致消息丢失。
|
||||
- 等待回复时显示“AI 正在输入…”。
|
||||
- AI 回复按正常客服消息存储并通过 WebSocket 推送。
|
||||
- 单次回复建议控制在 300 字以内,复杂步骤使用短段落或编号。
|
||||
- 商品、订单类回答优先附带现有商品卡片或订单卡片。
|
||||
- AI 无法确认时明确说明,并引导用户补充信息或转人工。
|
||||
|
||||
### 7.3 转人工
|
||||
|
||||
支持两种入口:
|
||||
|
||||
1. 用户输入明确转人工表达。
|
||||
2. 输入区“+”面板提供固定的“转人工”按钮。
|
||||
|
||||
触发后立即显示:
|
||||
|
||||
> 已为您通知人工客服,请稍候。等待期间您可以继续发送消息。
|
||||
|
||||
进入 `HUMAN_PENDING` 后:
|
||||
|
||||
- AI 不再回答业务问题。
|
||||
- 用户后续消息继续保存,并实时推送后台。
|
||||
- 重复输入“人工”不重复创建请求、不重复播放提醒音。
|
||||
- 客服接入后显示“人工客服已接入”。
|
||||
|
||||
### 7.4 结束人工服务
|
||||
|
||||
客服结束服务后显示系统消息:
|
||||
|
||||
> 本次人工服务已结束,如有其他问题可以继续咨询 AI 智能客服。
|
||||
|
||||
用户再次发送消息时,可以创建新一轮 `AI_ACTIVE` 服务。
|
||||
|
||||
## 8. 转人工识别规则
|
||||
|
||||
### 8.1 P0 规则
|
||||
|
||||
首期采用“规则优先 + 意图识别补充”的方式,不能只使用简单的字符串包含判断。
|
||||
|
||||
默认正向词库:
|
||||
|
||||
- 人工
|
||||
- 人工客服
|
||||
- 转人工
|
||||
- 找人工
|
||||
- 真人
|
||||
- 真人客服
|
||||
- 客服人员
|
||||
- 找个人
|
||||
- 让客服联系我
|
||||
- 我要投诉
|
||||
|
||||
支持同音、空格、标点和常见变体,例如“人 工”“转一下人工”“找真人聊”“人工!”。词库必须支持后台配置,修改后无需重新发布前端。
|
||||
|
||||
### 8.2 否定表达
|
||||
|
||||
以下表达不能触发转人工:
|
||||
|
||||
- 不需要人工
|
||||
- 不用转人工
|
||||
- 先不用真人
|
||||
- AI 就可以
|
||||
- 机器人回答就行
|
||||
|
||||
判断顺序:文本标准化 → 否定规则 → 明确转人工规则 → 可选语义意图识别。转人工检测由后端完成,前端检测只能用于交互加速,不能作为最终依据。
|
||||
|
||||
### 8.3 系统自动转人工
|
||||
|
||||
除用户主动要求外,以下系统异常必须自动转人工,避免用户卡死:
|
||||
|
||||
- AI 请求连续两次超时或失败。
|
||||
- AI 返回内容被安全审核拦截。
|
||||
- 当前问题涉及退款争议、投诉、账户安全且 AI 无法给出确定流程。
|
||||
- AI 连续两轮判断“无法回答”。
|
||||
|
||||
系统自动转人工时,`transferReason` 必须记录具体原因。此类规则可在后台单独开关。
|
||||
|
||||
## 9. 人工客服后台需求
|
||||
|
||||
### 9.1 会话分组
|
||||
|
||||
后台会话列表增加:
|
||||
|
||||
- **待人工**:`HUMAN_PENDING`,默认置顶并显示红点、提醒音。
|
||||
- **服务中**:`HUMAN_ACTIVE`。
|
||||
- **AI 会话**:`AI_ACTIVE`,默认不提醒,仅供查看和质检。
|
||||
- **已结束**:`CLOSED`。
|
||||
|
||||
只有进入 `HUMAN_PENDING` 的会话产生新人工任务提醒。AI 正常问答不增加人工未读数量,不播放提醒音。
|
||||
|
||||
### 9.2 待人工卡片
|
||||
|
||||
会话列表至少显示:
|
||||
|
||||
- 用户头像、名称、用户 ID。
|
||||
- 等待时长。
|
||||
- 转人工原因。
|
||||
- 最近一条用户消息。
|
||||
- 是否携带商品或订单。
|
||||
|
||||
### 9.3 人工接管
|
||||
|
||||
客服点击“接入”后:
|
||||
|
||||
1. 后端原子地将状态改为 `HUMAN_ACTIVE` 并绑定客服 ID。
|
||||
2. 其他客服看到“已由某某接入”,不能重复接入。
|
||||
3. 用户端收到接入事件。
|
||||
4. AI 停止生成和发送消息。
|
||||
|
||||
客服也可以从 AI 会话中主动点击“接管”,此操作直接进入 `HUMAN_ACTIVE`。
|
||||
|
||||
### 9.4 AI 移交摘要
|
||||
|
||||
转人工时后台顶部显示 AI 自动摘要:
|
||||
|
||||
- 用户当前诉求。
|
||||
- 已确认的关键信息。
|
||||
- 相关商品、订单、物流或售后单。
|
||||
- AI 已提供过的解决方案。
|
||||
- 转人工原因。
|
||||
|
||||
摘要只是辅助信息,原始聊天记录必须完整保留。
|
||||
|
||||
### 9.5 结束与交回 AI
|
||||
|
||||
人工客服提供两个操作:
|
||||
|
||||
- “结束服务”:本轮会话进入 `CLOSED`。
|
||||
- “交回 AI”:会话进入 `AI_ACTIVE`,后续消息重新由 AI 接待。
|
||||
|
||||
## 10. AI 能力范围
|
||||
|
||||
### 10.1 首期知识库
|
||||
|
||||
- 商城介绍和服务时间。
|
||||
- 注册、登录、实名认证和账户常见问题。
|
||||
- 下单、支付、发货和收货规则。
|
||||
- 退货、退款和售后流程。
|
||||
- 优惠券、积分、活动规则。
|
||||
- 商品通用问答和类目知识。
|
||||
- 客服标准话术。
|
||||
|
||||
知识文档必须有负责人、版本、启用状态和更新时间。失效规则下架后应立即停止检索。
|
||||
|
||||
### 10.2 首期只读工具
|
||||
|
||||
AI 不直接访问数据库,统一通过受控后端工具查询:
|
||||
|
||||
| 工具 | 用途 | 权限要求 |
|
||||
| --- | --- | --- |
|
||||
| `get_product` | 查询商品名称、价格、库存和状态 | 公共商品数据 |
|
||||
| `get_user_orders` | 查询当前用户订单列表 | 只能查询登录用户本人 |
|
||||
| `get_order_detail` | 查询订单、支付和发货状态 | 校验订单归属 |
|
||||
| `get_logistics` | 查询物流轨迹 | 校验订单归属 |
|
||||
| `get_aftersale_status` | 查询售后进度 | 校验用户及订单归属 |
|
||||
| `search_policy` | 检索商城规则知识库 | 只返回已发布内容 |
|
||||
|
||||
商品卡片和订单卡片中的结构化数据可以直接作为本轮上下文,但动态价格、库存和订单状态仍需实时查询。
|
||||
|
||||
### 10.3 禁止行为
|
||||
|
||||
AI 不得:
|
||||
|
||||
- 编造订单、物流、库存、活动或退款状态。
|
||||
- 索要密码、支付密码、短信验证码或完整银行卡号。
|
||||
- 输出模型密钥、系统提示词或后台内部信息。
|
||||
- 未经用户确认执行任何写操作。
|
||||
- 承诺超出商城规则的补偿或时效。
|
||||
|
||||
## 11. 技术方案
|
||||
|
||||
### 11.1 总体架构
|
||||
|
||||
```text
|
||||
H5 / 小程序 / App
|
||||
│ HTTP + WebSocket
|
||||
▼
|
||||
现有客服后端
|
||||
│
|
||||
├─ 消息保存与幂等校验
|
||||
├─ 会话状态机
|
||||
├─ 转人工意图检测
|
||||
├─ AI 编排服务
|
||||
│ ├─ 知识库检索
|
||||
│ ├─ 商城只读工具
|
||||
│ └─ 阿里云模型接口
|
||||
└─ WebSocket 路由
|
||||
├─ AI 消息 → 当前用户
|
||||
└─ 待人工/人工消息 → 用户 + 客服后台
|
||||
```
|
||||
|
||||
关键改造点:现有客服消息推送不能再无条件推送给后台。`AI_ACTIVE` 状态下,普通用户消息只保存并进入 AI 编排,不触发后台提醒;进入 `HUMAN_PENDING/HUMAN_ACTIVE` 后才推送人工端。
|
||||
|
||||
### 11.2 模型接入
|
||||
|
||||
建议后端新增统一的 `AiChatProvider` 接口,业务层不直接依赖某一家模型 SDK:
|
||||
|
||||
```text
|
||||
AiChatProvider
|
||||
├─ AliyunOpenAiCompatibleProvider(首期)
|
||||
└─ 其他模型 Provider(后续可选)
|
||||
```
|
||||
|
||||
配置项至少包括:
|
||||
|
||||
- AI 总开关和灰度比例。
|
||||
- API Base URL。
|
||||
- API Key(只允许服务器环境变量或密钥管理服务保存)。
|
||||
- 模型名称。
|
||||
- 请求超时、最大重试次数、最大上下文长度。
|
||||
- 系统提示词版本和知识库版本。
|
||||
|
||||
严禁将 API Key 写入 Git、前端 `.env`、小程序代码或消息内容。日志中也必须脱敏。
|
||||
|
||||
### 11.3 上下文策略
|
||||
|
||||
每次模型请求建议包含:
|
||||
|
||||
- 固定系统规则。
|
||||
- 最近 10 至 20 条有效消息。
|
||||
- 当前会话摘要。
|
||||
- 用户主动发送的商品/订单上下文。
|
||||
- 经权限校验后的工具查询结果。
|
||||
- 知识库命中片段及版本。
|
||||
|
||||
长会话通过摘要压缩,不能无限携带全部历史消息。撤回或仅本地删除的消息需要按现有业务规则决定是否进入 AI 上下文。
|
||||
|
||||
### 11.4 并发与幂等
|
||||
|
||||
- 每条用户消息使用唯一请求 ID。
|
||||
- 同一会话的 AI 任务串行处理,避免回复顺序错乱。
|
||||
- AI 返回前再次检查会话状态和任务版本。
|
||||
- WebSocket 重复推送不得造成重复消息。
|
||||
- 转人工状态切换使用数据库条件更新或分布式锁,避免多客服同时接入。
|
||||
|
||||
## 12. 数据设计建议
|
||||
|
||||
### 12.1 会话扩展字段
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `service_mode` | varchar | `AI_ACTIVE/HUMAN_PENDING/HUMAN_ACTIVE/CLOSED` |
|
||||
| `assigned_admin_id` | bigint | 当前接入客服 ID |
|
||||
| `transfer_reason` | varchar | 用户主动、AI 超时、无法回答等 |
|
||||
| `transfer_time` | datetime | 进入待人工时间 |
|
||||
| `ai_session_id` | varchar | 模型侧会话标识,可为空 |
|
||||
| `ai_summary` | text | 移交摘要 |
|
||||
| `ai_prompt_version` | varchar | 提示词版本 |
|
||||
| `state_version` | int | 状态并发控制版本 |
|
||||
|
||||
### 12.2 消息扩展建议
|
||||
|
||||
现有 `senderType` 建议增加 AI 类型,例如:
|
||||
|
||||
- `1`:人工客服。
|
||||
- `2`:会员。
|
||||
- `3`:AI 智能客服。
|
||||
- `4`:系统事件。
|
||||
|
||||
AI 调用明细建议单独建表,不把大量调试信息塞入消息正文:请求 ID、模型、耗时、Token 用量、知识命中、工具调用、结果状态、错误码和提示词版本。
|
||||
|
||||
## 13. 接口建议
|
||||
|
||||
可复用现有发送和消息查询接口,并新增以下能力:
|
||||
|
||||
| 接口 | 方法 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `/kefu/user/transfer-human` | POST | 用户主动申请人工,幂等 |
|
||||
| `/kefu/conversation/takeover` | POST | 客服接管会话 |
|
||||
| `/kefu/conversation/return-ai` | POST | 客服交回 AI |
|
||||
| `/kefu/conversation/close-service` | POST | 结束本轮服务 |
|
||||
| `/kefu/ai/config` | GET/PUT | AI 和转人工规则配置 |
|
||||
| `/kefu/ai/knowledge/*` | CRUD | 知识文档管理 |
|
||||
| `/kefu/ai/records` | GET | AI 调用和质检记录 |
|
||||
|
||||
建议新增 WebSocket 事件:
|
||||
|
||||
| 事件 | 接收端 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `kefu_ai_typing` | 用户端 | AI 正在生成回复 |
|
||||
| `kefu_transfer_requested` | 后台 | 新的待人工任务 |
|
||||
| `kefu_human_joined` | 用户端、后台 | 人工已接入 |
|
||||
| `kefu_returned_to_ai` | 用户端、后台 | 已交回 AI |
|
||||
| `kefu_service_closed` | 用户端、后台 | 本轮服务结束 |
|
||||
|
||||
## 14. 后台配置
|
||||
|
||||
客服管理后台增加“AI 客服设置”:
|
||||
|
||||
- AI 总开关。
|
||||
- 灰度用户比例和商户范围。
|
||||
- 模型地址、模型名称和连通性测试。
|
||||
- 转人工关键词、否定词和系统自动转人工规则。
|
||||
- 欢迎语、等待语、离线语。
|
||||
- 人工服务时间和超时提醒。
|
||||
- 知识库文档管理。
|
||||
- AI 会话抽检、错误记录和效果报表。
|
||||
|
||||
API Key 只支持重新设置,页面不得回显完整值。
|
||||
|
||||
## 15. 异常与降级
|
||||
|
||||
| 场景 | 处理方式 |
|
||||
| --- | --- |
|
||||
| 模型单次超时 | 重试一次,期间保留“正在输入”状态 |
|
||||
| 连续失败两次 | 转 `HUMAN_PENDING` 并通知人工 |
|
||||
| 模型限流 | 短暂排队;超过阈值转人工 |
|
||||
| 知识库不可用 | 仅回答可确认问题,否则转人工 |
|
||||
| WebSocket 断开 | 现有自动重连;消息通过历史接口补齐 |
|
||||
| 人工均不在线 | 告知已留言和服务时间,保留待处理任务 |
|
||||
| AI 总开关关闭 | 新消息直接按现有人工客服流程处理 |
|
||||
|
||||
## 16. 安全与合规
|
||||
|
||||
- 模型调用由后端完成,所有工具调用必须复用登录身份和数据权限。
|
||||
- 订单、地址、手机号等敏感信息按回答需要最小化传输并脱敏。
|
||||
- 用户输入、模型输出和工具结果进行安全审查。
|
||||
- 保存模型调用审计记录,支持按会话追溯。
|
||||
- 用户删除本人聊天记录不等于删除平台审计记录,具体保留周期需由公司隐私政策确定。
|
||||
- 测试环境和生产环境使用不同密钥、知识库和日志配置。
|
||||
|
||||
## 17. 埋点与报表
|
||||
|
||||
建议统计:
|
||||
|
||||
- AI 会话数、AI 消息数、平均响应时间。
|
||||
- AI 独立解决率。
|
||||
- 转人工率和各转人工原因占比。
|
||||
- 关键词触发率、否定词拦截率、误转人工率。
|
||||
- 人工首次响应时间和平均等待时间。
|
||||
- 模型错误率、超时率和 Token 成本。
|
||||
- 知识库命中率、未命中问题排行。
|
||||
- 用户“有帮助/没帮助”评价。
|
||||
|
||||
## 18. 验收标准
|
||||
|
||||
### 18.1 AI 接待
|
||||
|
||||
- 新会话默认进入 `AI_ACTIVE`。
|
||||
- 普通问题由 AI 回复,后台不产生人工提醒和人工未读数。
|
||||
- AI 消息正确显示 AI 身份、头像、时间和消息状态。
|
||||
- 商品和订单问题能使用真实结构化数据回答。
|
||||
|
||||
### 18.2 转人工
|
||||
|
||||
- 输入“人工客服、人工、真人、转人工”等表达后 1 秒内进入待人工状态。
|
||||
- 输入“不需要人工、先不用真人”等否定表达不转人工。
|
||||
- 转人工后 AI 不再发送业务回复。
|
||||
- 后台只产生一次待人工提醒,并显示原因和等待时长。
|
||||
- 一名客服接入后,其他客服不能重复接入。
|
||||
- 用户端及时显示人工已接入。
|
||||
|
||||
### 18.3 异常
|
||||
|
||||
- 模型超时或不可用时消息不丢失。
|
||||
- 达到失败阈值后自动转人工。
|
||||
- WebSocket 重连后不重复显示 AI 消息。
|
||||
- 关闭 AI 开关后现有人工客服功能完整可用。
|
||||
|
||||
### 18.4 跨端
|
||||
|
||||
- H5、微信小程序和 App 核心状态、消息和转人工行为一致。
|
||||
- 小程序前端包内不存在模型 API Key。
|
||||
- 切后台、弱网和网络恢复后会话状态正确。
|
||||
|
||||
## 19. 分阶段实施
|
||||
|
||||
### 阶段一:基础路由与转人工
|
||||
|
||||
- 增加会话状态机。
|
||||
- 接入一个后端 AI Provider。
|
||||
- 实现关键词、否定词和固定转人工按钮。
|
||||
- 后台增加待人工分组、接入和结束服务。
|
||||
- AI 暂只回答通用知识库问题。
|
||||
|
||||
### 阶段二:商城数据工具
|
||||
|
||||
- 接入商品、订单、物流和售后只读工具。
|
||||
- 增加移交摘要。
|
||||
- 增加知识库管理、调用日志和基础报表。
|
||||
|
||||
### 阶段三:灰度和优化
|
||||
|
||||
- 先内部账号和测试环境验证。
|
||||
- 生产环境按 10% → 30% → 50% → 100% 灰度。
|
||||
- 根据未命中问题和误转案例优化词库、知识库和提示词。
|
||||
- 达到稳定指标后再评估有限的写操作能力。
|
||||
|
||||
## 20. 开发工作量判断
|
||||
|
||||
本项目难度为中等。聊天 UI、消息持久化和 WebSocket 已经具备,主要工作不在重新开发聊天页面,而在后端增加会话状态机、AI 编排、推送路由和后台待人工工作流。
|
||||
|
||||
推荐开发顺序:
|
||||
|
||||
1. 会话状态和消息发送方扩展。
|
||||
2. 转人工规则与后台提醒路由。
|
||||
3. AI Provider 和基础问答。
|
||||
4. 后台接入/结束/交回 AI。
|
||||
5. 商品、订单等只读工具。
|
||||
6. 知识库、摘要、日志、报表与灰度。
|
||||
|
||||
首期应优先保证转人工可靠和 AI 可随时关闭,再逐步提高 AI 回答能力。
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
# Design System
|
||||
|
||||
## Overview
|
||||
|
||||
HashMall 客服前台采用轻量、克制的移动产品界面。用户在商城浏览或订单处理过程中进入,因此页面应像商城内部的原生工具,而不是独立活动页。默认使用浅色主题,消息阅读区保持低干扰。
|
||||
|
||||
## Color
|
||||
|
||||
- Brand primary: `#7934F6`
|
||||
- Brand pressed: `#6426D8`
|
||||
- Brand soft: `#F2EBFF`
|
||||
- Page background: `#F5F5F7`
|
||||
- Surface: `#FFFFFF`
|
||||
- Primary text: `#1A1A1D`
|
||||
- Secondary text: `#5F6068`
|
||||
- Muted text: `#777983`
|
||||
- Divider: `#E7E7EC`
|
||||
- Success: `#168A5B`
|
||||
- Warning: `#A45A00`
|
||||
- Error: `#C93636`
|
||||
|
||||
品牌色只用于主按钮、本人消息气泡、焦点和少量状态标识。客服消息使用白色表面和清晰正文色。
|
||||
|
||||
## Typography
|
||||
|
||||
使用平台系统无衬线字体。H5 优先 `-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`,小程序沿用系统字体。
|
||||
|
||||
- Page title: 17px / 600
|
||||
- Section or state title: 16px / 600
|
||||
- Message body: 15px / 400, line-height 1.55
|
||||
- Supporting text: 13px / 400
|
||||
- Caption and timestamp: 12px / 400
|
||||
|
||||
消息正文允许换行和长字符串断行,不使用装饰性字体。
|
||||
|
||||
## Layout
|
||||
|
||||
- 页面采用纵向三段结构:状态/导航、可滚动消息区、固定输入区。
|
||||
- 内容宽度在桌面 H5 最大 720px,移动端占满视口。
|
||||
- 页面横向安全间距 16px,气泡最大宽度约 76%。
|
||||
- 使用 4、8、12、16、24px 的间距节奏。
|
||||
- 输入区适配底部安全区和软键盘,不用固定像素高度锁死页面。
|
||||
|
||||
## Components
|
||||
|
||||
### Message bubble
|
||||
|
||||
- 本人消息:紫色实底、白字,圆角 14px,右上角保留较小圆角以区分方向。
|
||||
- 客服消息:白色实底、深色文字,可使用 1px 中性边界,不叠加宽阴影。
|
||||
- 气泡内文本可选中;URL、图片、卡片按明确组件渲染。
|
||||
|
||||
### Composer
|
||||
|
||||
- 白色表面与顶部细分隔线。
|
||||
- 文本输入框使用中性浅灰背景,圆角 12px。
|
||||
- 图片与更多操作使用至少 44px 的触控区。
|
||||
- 发送按钮使用品牌色;空文本时为明确禁用状态。
|
||||
|
||||
### Context card
|
||||
|
||||
- 商品或订单上下文在输入区上方单层展示。
|
||||
- 使用缩略图、两行标题和一组关键元数据,不嵌套卡片。
|
||||
- 提供“发送”与“移除”两个清晰动作。
|
||||
|
||||
### Status feedback
|
||||
|
||||
- 连接中、离线、轮询中显示在顶部状态条,状态文字与图标同时变化。
|
||||
- 发送失败在对应消息旁展示“重新发送”,不使用全屏弹窗。
|
||||
- 首屏使用消息骨架,空状态提供简短欢迎语和可执行提示。
|
||||
|
||||
## Motion
|
||||
|
||||
- 状态切换和新消息定位使用 150 至 220ms 的 ease-out。
|
||||
- 不做页面入场编排或弹跳动画。
|
||||
- 系统启用减少动态效果时取消非必要过渡。
|
||||
|
||||
## Responsive and platform behavior
|
||||
|
||||
- H5 与微信小程序均使用 uni-app 原生组件。
|
||||
- Socket 使用 `uni.connectSocket`,图片使用 `uni.chooseMedia`/兼容接口和 `uni.previewImage`。
|
||||
- H5 处理 `100dvh` 与 iOS 软键盘;小程序处理 `safe-area-inset-bottom`、导航栏和 `cursor-spacing`。
|
||||
- 不使用浏览器全局 `WebSocket`、DOM 文件选择器或 iframe 作为核心能力。
|
||||
@@ -0,0 +1,88 @@
|
||||
# 接入 HashMall 商城
|
||||
|
||||
独立项目验证完成后,将 `src/pages/customer-service`、`src/components/customer-service`、`src/api`、`src/services`、`src/config`、`src/adapters` 和客服静态资源合入商城工程。
|
||||
|
||||
## 1. 注册页面
|
||||
|
||||
建议在商城 `pages.json` 中将客服页放入分包:
|
||||
|
||||
```json
|
||||
{
|
||||
"root": "pages/customer_service_package",
|
||||
"pages": [
|
||||
{
|
||||
"path": "chat/chat",
|
||||
"style": {
|
||||
"navigationBarTitleText": "在线客服",
|
||||
"navigationBarBackgroundColor": "#FFFFFF",
|
||||
"navigationBarTextStyle": "black"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
合入分包时需要同步调整 `hashmall.js` 中的 `CHAT_ROUTE` 和页面内 `@/` 引用路径。
|
||||
|
||||
## 2. 初始化商城适配
|
||||
|
||||
商城启动后设置登录页。应用级 Authorization 应由商城现有配置注入,不要复制到客服源码或提交 Git。
|
||||
|
||||
```js
|
||||
configureHashMallIntegration({
|
||||
loginPage: '/pages/login_package/login/login',
|
||||
appAuthorization: Authorization
|
||||
})
|
||||
```
|
||||
|
||||
客服请求会继续读取商城已有的:
|
||||
|
||||
- Token:`fcc-token`
|
||||
- 用户缓存:`fcc-user-data`
|
||||
- 用户详情接口:`/user/getUserInfo`
|
||||
|
||||
## 3. “我的”页入口
|
||||
|
||||
把当前客服电话弹窗或第三方客服跳转替换为:
|
||||
|
||||
```js
|
||||
openCustomerService()
|
||||
```
|
||||
|
||||
## 4. 商品详情入口
|
||||
|
||||
```js
|
||||
openProductConsultation({
|
||||
goodsId: goods.id,
|
||||
goodsName: goods.name,
|
||||
goodsMainGraph: goods.mainGraph,
|
||||
currentPrice: goods.currentPrice
|
||||
})
|
||||
```
|
||||
|
||||
页面只把该对象作为待发送预览。正式发送前后端仍需按 `goodsId` 校验并补齐可信商品信息。
|
||||
|
||||
## 5. 订单入口
|
||||
|
||||
```js
|
||||
openOrderConsultation({
|
||||
id: order.id,
|
||||
orderNo: order.orderNo,
|
||||
goodsName: order.goodsName,
|
||||
goodsMainGraph: order.goodsMainGraph,
|
||||
payAmount: order.payAmount
|
||||
})
|
||||
```
|
||||
|
||||
正式发送前后端必须校验订单归属当前登录用户。
|
||||
|
||||
## 6. 小程序配置
|
||||
|
||||
微信公众平台需要配置测试或正式环境的:
|
||||
|
||||
- request 合法域名
|
||||
- socket 合法域名
|
||||
- uploadFile 合法域名
|
||||
- downloadFile 合法域名
|
||||
|
||||
测试环境 API 为 `https://api.o.tbmall.xin`,Socket 使用对应的 `wss://api.o.tbmall.xin`。
|
||||
@@ -0,0 +1,37 @@
|
||||
# Product
|
||||
|
||||
## Register
|
||||
|
||||
product
|
||||
|
||||
## Users
|
||||
|
||||
HashMall 已登录会员在浏览商品、查看订单或使用个人中心时,通过 H5 或微信小程序联系平台客服。用户通常带着明确问题进入,需要快速恢复历史会话、提供商品或订单上下文,并在弱网或切换应用后继续沟通。
|
||||
|
||||
## Product Purpose
|
||||
|
||||
提供 HashMall 自有的跨端客服聊天体验,替代电话号码弹窗和第三方 iframe 客服。产品需要可靠完成文本、图片、商品卡片和订单卡片的双向消息收发,复用现有后台客服工作台,并保证用户身份、会话归属与消息恢复正确。
|
||||
|
||||
## Brand Personality
|
||||
|
||||
清晰、可靠、克制。界面延续商城现有紫色品牌识别,但客服工具的重点是阅读和处理消息,品牌色只用于关键动作、本人消息和连接状态,不用于大面积装饰。
|
||||
|
||||
## Anti-references
|
||||
|
||||
- 不做第三方网页嵌套式客服,不使用 iframe 作为核心界面。
|
||||
- 不模仿社交应用的娱乐化皮肤、夸张气泡或装饰动画。
|
||||
- 不使用大面积渐变、玻璃拟态、过度圆角和层层卡片。
|
||||
- 不把网络错误、发送失败和登录失效隐藏在无反馈的加载状态中。
|
||||
- 不依赖仅在浏览器存在的 API,避免 H5 可用而小程序失效。
|
||||
|
||||
## Design Principles
|
||||
|
||||
1. 消息优先:视觉层级首先服务于消息阅读、输入和状态判断。
|
||||
2. 失败可恢复:每个网络动作都有明确状态,草稿、失败消息和断线消息能够恢复。
|
||||
3. 上下文由用户确认:商品和订单信息先展示,再由用户主动发送。
|
||||
4. 跨端一致,遵循平台:业务能力一致,键盘、导航、图片选择和返回行为遵循终端习惯。
|
||||
5. 身份来自可信登录态:页面参数只描述咨询场景,不决定用户身份或数据权限。
|
||||
|
||||
## Accessibility & Inclusion
|
||||
|
||||
以 WCAG 2.1 AA 为基线。正文和状态文字保持足够对比度;连接、失败和已读状态不只依赖颜色;触控区域不小于 44px;支持系统减少动态效果;消息内容允许系统字体缩放,并兼顾长文本、无图片和慢网用户。
|
||||
@@ -0,0 +1,506 @@
|
||||
# HashMall 前台客服系统产品需求文档
|
||||
|
||||
> 文档状态:已确认插件化方案,进入开发
|
||||
> 文档版本:v0.2
|
||||
> 编制日期:2026-07-16
|
||||
> 插件目录:`frontend-web/uni_modules/hashmall-customer-service/`
|
||||
> 目标终端:H5、微信小程序,结构上兼容后续 App 接入
|
||||
|
||||
## 1. 文档目的
|
||||
|
||||
本文档定义 HashMall 商城前台客服系统的产品范围、用户流程、交互要求、接口依赖、跨端兼容、安全前置条件和验收标准。
|
||||
|
||||
客服前台以 `uni_modules` 插件形式直接内嵌现有 `frontend-web` 商城工程,复用宿主登录态、请求封装、页面生命周期和构建流程;不创建、部署或运行独立客服前端服务。
|
||||
|
||||
## 2. 项目背景
|
||||
|
||||
HashMall 已经完成客服系统的主要后端能力和管理后台客服工作台,商城前台目前仍使用第三方 H5 客服页面或电话号码弹窗,没有接入自有客服会话。
|
||||
|
||||
现有前台客服入口包括:
|
||||
|
||||
- “我的”页服务工具中的“联系客服”。
|
||||
- 商品详情页的客服入口。
|
||||
- 订单列表或订单详情中的售后咨询入口。
|
||||
- 现有 `pages/rwa_package/setting/kefu.vue` 通过 `iframe` 加载第三方客服 H5。
|
||||
|
||||
微信小程序不能沿用当前 `iframe` 方案;即使改用小程序 `web-view`,也会受业务域名、登录态透传、返回导航和页面体验限制。因此新客服前台应采用 uni-app 原生页面与组件实现,不依赖 iframe。
|
||||
|
||||
## 3. 现状梳理
|
||||
|
||||
### 3.1 已完成的后端能力
|
||||
|
||||
当前 `backend/JST-ERP` 分支已经包含:
|
||||
|
||||
- 客服会话、客服消息、商品浏览历史数据表和 DAO。
|
||||
- 用户发送消息、查询历史消息、查询浏览记录、查询订单、记录商品浏览等接口。
|
||||
- 后台会话列表、会话详情、置顶、删除、消息发送和已读接口。
|
||||
- `/ws/kefu` 与 `/api/ws/kefu` WebSocket 端点。
|
||||
- 新消息、会话变化、已读状态变化的实时推送。
|
||||
- 文本、图片、商品卡片和订单卡片四种消息类型。
|
||||
|
||||
### 3.2 已完成的管理后台能力
|
||||
|
||||
当前管理后台已经包含:
|
||||
|
||||
- 会话列表、置顶、删除、未读数量。
|
||||
- 客服与会员聊天区。
|
||||
- 文本、表情和图片消息。
|
||||
- 会员资料、最近浏览和交易订单侧栏。
|
||||
- WebSocket 实时刷新与断线重连。
|
||||
- 图片上传后发送可访问 URL。
|
||||
|
||||
### 3.3 前台现状与缺口
|
||||
|
||||
当前商城前台:
|
||||
|
||||
- 没有自有客服聊天页。
|
||||
- “我的”页客服入口主要弹出电话联系方式。
|
||||
- 部分入口跳转到第三方 H5 客服页面。
|
||||
- 没有复用自有客服消息接口。
|
||||
- 没有接入自有客服 WebSocket。
|
||||
- 没有发送商品卡片、订单卡片的完整流程。
|
||||
- 没有客服消息发送状态、失败重试、断线恢复和历史消息分页体验。
|
||||
- 商品详情页尚未统一接入客服浏览记录上报。
|
||||
|
||||
## 4. 产品目标
|
||||
|
||||
### 4.1 核心目标
|
||||
|
||||
1. 用户能够从商城关键场景进入自有客服聊天页。
|
||||
2. 用户与后台客服能够实时收发消息并查看历史记录。
|
||||
3. H5 与微信小程序保持一致的核心功能和主要视觉体验。
|
||||
4. 用户可以携带商品或订单上下文发起咨询,减少描述成本。
|
||||
5. 网络异常、切后台、WebSocket 断开时不丢消息,并能自动恢复。
|
||||
6. 用户只能访问本人的会话和消息,不能通过修改参数读取他人数据。
|
||||
|
||||
### 4.2 成功指标
|
||||
|
||||
首期上线后建议关注:
|
||||
|
||||
- 客服入口点击至聊天页成功率不低于 99.5%。
|
||||
- 文本消息发送成功率不低于 99.9%。
|
||||
- 在线情况下新消息端到端可见时间 P95 不超过 2 秒。
|
||||
- WebSocket 断线后 10 秒内自动恢复率不低于 99%。
|
||||
- 由商品或订单场景进入时,上下文卡片发送率可被埋点统计。
|
||||
- 因身份错误导致的跨用户数据访问事件为 0。
|
||||
|
||||
## 5. 用户与使用场景
|
||||
|
||||
### 5.1 用户角色
|
||||
|
||||
- 已登录会员:使用全部客服能力。
|
||||
- 未登录访客:可看客服说明;发起聊天时必须先登录。
|
||||
- 后台客服:使用现有管理后台接收和回复消息,不属于本项目前台开发范围。
|
||||
|
||||
首期不支持匿名访客会话,避免设备身份、会话合并和隐私归属问题。
|
||||
|
||||
### 5.2 主要场景
|
||||
|
||||
1. 通用咨询:用户从“我的 → 联系客服”进入聊天页。
|
||||
2. 商品咨询:用户从商品详情进入,页面展示待咨询商品,可一键发送商品卡片。
|
||||
3. 订单咨询:用户从订单详情或售后场景进入,可一键发送订单卡片。
|
||||
4. 历史追问:用户再次进入客服页,继续原有会话并查看历史消息。
|
||||
5. 客服回复:页面打开时实时收到;页面关闭后,后续可扩展消息角标或订阅消息提醒。
|
||||
|
||||
## 6. 产品范围
|
||||
|
||||
### 6.1 P0:首期必须完成
|
||||
|
||||
- 登录校验与当前用户识别。
|
||||
- 单一客服会话的创建或恢复。
|
||||
- 历史消息加载和向上翻页。
|
||||
- 文本消息发送与接收。
|
||||
- 图片选择、压缩、上传、发送与预览。
|
||||
- WebSocket 连接、心跳、断线重连。
|
||||
- WebSocket 不可用时 3 至 5 秒轮询兜底。
|
||||
- 发送中、发送成功、发送失败状态。
|
||||
- 失败消息手动重试,防止重复发送。
|
||||
- 商品上下文卡片发送。
|
||||
- 订单上下文卡片发送。
|
||||
- H5 与微信小程序兼容。
|
||||
- 空状态、加载状态、错误状态和网络状态提示。
|
||||
- 基础埋点和错误日志。
|
||||
|
||||
### 6.2 P1:建议紧随首期
|
||||
|
||||
- 表情面板。
|
||||
- 从聊天页主动选择最近浏览商品。
|
||||
- 从聊天页主动选择历史订单。
|
||||
- 用户侧未读数量与已读回执。
|
||||
- “客服正在输入”状态。
|
||||
- 客服在线状态和服务时间提示。
|
||||
- 小程序订阅消息或站内消息提醒。
|
||||
|
||||
### 6.3 本期不做
|
||||
|
||||
- 语音、视频和实时音视频通话。
|
||||
- 多客服技能组、智能分配和排队系统。
|
||||
- 机器人客服和知识库问答。
|
||||
- 消息撤回、引用回复、群聊。
|
||||
- 客服评价、投诉工单和 SLA 统计。
|
||||
- 独立访客身份体系。
|
||||
|
||||
## 7. 信息架构
|
||||
|
||||
独立前台客服项目建议规划以下产品模块:
|
||||
|
||||
```text
|
||||
客服聊天页
|
||||
├─ 顶部导航与连接状态
|
||||
├─ 服务时间/系统公告
|
||||
├─ 历史消息区
|
||||
│ ├─ 文本消息
|
||||
│ ├─ 图片消息
|
||||
│ ├─ 商品卡片
|
||||
│ ├─ 订单卡片
|
||||
│ └─ 时间分隔与状态提示
|
||||
├─ 场景上下文提示条
|
||||
├─ 消息输入区
|
||||
│ ├─ 文本输入
|
||||
│ ├─ 图片选择
|
||||
│ ├─ 表情入口(P1)
|
||||
│ └─ 更多功能
|
||||
├─ 商品选择面板(P1)
|
||||
├─ 订单选择面板(P1)
|
||||
└─ 图片预览
|
||||
```
|
||||
|
||||
建议正式接入商城后的页面路由为:
|
||||
|
||||
```text
|
||||
/pages/customer-service/chat
|
||||
```
|
||||
|
||||
建议作为分包页面注册,避免客服资源增加商城主包体积。
|
||||
|
||||
## 8. 核心用户流程
|
||||
|
||||
### 8.1 进入客服页
|
||||
|
||||
1. 用户点击客服入口。
|
||||
2. 系统检查商城登录态。
|
||||
3. 未登录时跳转登录页,并记录客服目标页及场景参数。
|
||||
4. 登录成功后返回客服页。
|
||||
5. 页面从可信登录态获取当前用户,不从 URL 接收用户 ID。
|
||||
6. 加载最近一页历史消息和会话信息。
|
||||
7. 建立 WebSocket 并发送心跳。
|
||||
8. 若入口携带商品或订单上下文,在输入区上方展示待发送卡片,不自动发送。
|
||||
|
||||
### 8.2 发送文本消息
|
||||
|
||||
1. 用户输入内容,空白内容不能发送。
|
||||
2. 前端生成本地消息 ID,立即在消息区展示“发送中”。
|
||||
3. 调用发送接口。
|
||||
4. 成功后用服务端消息 ID 替换本地状态。
|
||||
5. 失败后显示失败标识,点击可重试。
|
||||
6. 重试必须复用幂等键,避免网络超时导致重复消息。
|
||||
|
||||
### 8.3 发送图片消息
|
||||
|
||||
1. 用户从相册选择图片或在 H5 选择本地文件。
|
||||
2. 校验格式、大小与数量。
|
||||
3. 客户端在支持的终端压缩长边和质量。
|
||||
4. 先上传到现有文件服务,获得 HTTPS 图片 URL。
|
||||
5. 再发送 `contentType=2` 的客服消息。
|
||||
6. 上传或发送失败时允许重试。
|
||||
7. 首期每次最多选择 1 张,单张原图建议不超过 10 MB,压缩后建议不超过 2 MB。
|
||||
|
||||
禁止把大图片 Base64 长期写入 `kefu_message.content`。
|
||||
|
||||
### 8.4 发送商品卡片
|
||||
|
||||
1. 从商品详情进入时携带 `goodsId`,不得在 URL 携带完整商品价格等可篡改展示数据。
|
||||
2. 客服页通过商品接口获取最新商品信息。
|
||||
3. 用户点击“发送商品”后发送 `contentType=10`。
|
||||
4. 卡片至少展示商品主图、名称、规格或价格、商品状态。
|
||||
5. 点击卡片返回商品详情;商品下架时显示“商品已失效”。
|
||||
|
||||
### 8.5 发送订单卡片
|
||||
|
||||
1. 从订单场景进入时携带 `orderId`。
|
||||
2. 客服页通过有权限校验的订单接口获取当前用户的订单摘要。
|
||||
3. 用户确认后发送 `contentType=11`。
|
||||
4. 卡片至少展示商品主图、商品名称、订单号、金额和订单状态。
|
||||
5. 用户只能发送归属于自己的订单。
|
||||
|
||||
### 8.6 实时消息与恢复
|
||||
|
||||
1. WebSocket 收到 `kefu_message_type` 后按消息 ID 去重并插入列表。
|
||||
2. 收到 `kefu_conversation_change` 后更新会话摘要。
|
||||
3. 收到 `kefu_message_read_status_change` 后更新已读状态。
|
||||
4. 每 25 至 30 秒发送一次 `ping`,收到 `pong` 视为连接存活。
|
||||
5. 断线按 2、4、8、15、30 秒退避重连,最大间隔 30 秒。
|
||||
6. 应用切到前台时立即检查连接,并拉取断线期间的新消息。
|
||||
7. WebSocket 连续失败后启用 3 至 5 秒轮询;恢复连接后停止轮询。
|
||||
|
||||
## 9. 页面与交互要求
|
||||
|
||||
### 9.1 顶部区域
|
||||
|
||||
- 标题默认“在线客服”。
|
||||
- 可展示“在线”“连接中”“网络异常”等连接状态。
|
||||
- 服务时间由配置返回,不在前端硬编码。
|
||||
- 微信小程序使用原生导航栏或自定义导航栏时必须适配安全区。
|
||||
|
||||
### 9.2 消息列表
|
||||
|
||||
- 客服消息居左,会员消息居右。
|
||||
- 连续消息按时间间隔展示时间分隔,建议超过 5 分钟显示一次。
|
||||
- 首次进入滚动到最新消息。
|
||||
- 用户主动向上滚动时,新消息到达不得强制抢夺滚动位置,应显示“有新消息”按钮。
|
||||
- 向上触顶加载更早消息,并保持加载前后的视觉位置。
|
||||
- 文本必须换行并防止超长字符串撑破布局。
|
||||
- 图片支持缩略图、加载占位、失败占位和全屏预览。
|
||||
- 商品、订单卡片需要结构化解析失败兜底,不能因单条脏数据导致整页报错。
|
||||
|
||||
### 9.3 输入区
|
||||
|
||||
- 支持多行输入,最多显示 4 行后内部滚动。
|
||||
- 文本长度上限首期建议 1000 字,与后端最终限制保持一致。
|
||||
- 发送按钮仅在有有效内容时可用。
|
||||
- 微信小程序需适配键盘顶起、底部安全区和 `cursor-spacing`。
|
||||
- H5 需兼容 iOS Safari 软键盘造成的可视区域变化。
|
||||
- 页面销毁时停止计时器、轮询和 Socket,防止重复连接。
|
||||
|
||||
### 9.4 状态反馈
|
||||
|
||||
- 首屏加载:骨架或明确加载状态。
|
||||
- 无历史消息:欢迎语及常见咨询提示。
|
||||
- 发送中:消息旁显示加载状态。
|
||||
- 发送失败:红色失败标识与重试入口。
|
||||
- 网络离线:顶部非阻塞提示,不清空输入内容。
|
||||
- 登录失效:保存未发送草稿,重新登录后恢复。
|
||||
|
||||
## 10. 跨端兼容要求
|
||||
|
||||
| 能力 | H5 | 微信小程序 | 产品要求 |
|
||||
|---|---|---|---|
|
||||
| 页面实现 | uni-app 原生页面 | uni-app 原生页面 | 不使用 iframe 承载核心聊天 |
|
||||
| 网络请求 | `uni.request` | `uni.request` | API 域名必须配置 HTTPS |
|
||||
| WebSocket | `uni.connectSocket` | `uni.connectSocket` | 不直接依赖浏览器 `WebSocket` 全局对象 |
|
||||
| 图片选择 | H5 文件选择 | `uni.chooseMedia`/兼容接口 | 统一封装并限制大小 |
|
||||
| 图片上传 | `uni.uploadFile` | `uni.uploadFile` | 上传域名加入小程序合法域名 |
|
||||
| 图片预览 | `uni.previewImage` | `uni.previewImage` | 行为保持一致 |
|
||||
| 键盘适配 | iOS/Android 浏览器 | 微信键盘与安全区 | 真机验收 |
|
||||
| 返回行为 | 浏览器/uni 路由 | 小程序页面栈 | 从登录返回时恢复上下文 |
|
||||
| 域名要求 | HTTPS/WSS | request/socket/upload 合法域名 | 发布前配置完成 |
|
||||
|
||||
微信小程序发布前必须在平台后台配置:
|
||||
|
||||
- `request` 合法域名。
|
||||
- `socket` 合法域名。
|
||||
- `uploadFile` 合法域名。
|
||||
- `downloadFile` 合法域名(如图片预览需要)。
|
||||
|
||||
测试环境建议使用 `https://api.o.tbmall.xin` 和对应 `wss` 地址;正式环境使用正式 API 域名。域名必须由环境配置注入,不允许散落硬编码。
|
||||
|
||||
## 11. 当前接口依赖
|
||||
|
||||
### 11.1 用户消息接口
|
||||
|
||||
| 功能 | 方法 | 当前路径 |
|
||||
|---|---|---|
|
||||
| 发送消息 | POST | `/kefu/user/send` |
|
||||
| 查询会话和消息 | GET | `/kefu/user/messages` |
|
||||
| 最近浏览 | GET | `/kefu/user/browse-history` |
|
||||
| 交易订单 | GET | `/kefu/user/orders` |
|
||||
| 记录商品浏览 | POST | `/kefu/user/browse-record` |
|
||||
|
||||
后端同时提供部分兼容路径,但新前台只使用一套规范路径,避免后续维护重复接口。
|
||||
|
||||
### 11.2 WebSocket
|
||||
|
||||
- 端点:`/ws/kefu` 或代理路径 `/api/ws/kefu`。
|
||||
- 当前会员连接参数:`userType=member`、`userId`、`mchId`、`conversationId`。
|
||||
- 心跳输入:字符串 `ping`。
|
||||
- 心跳响应:`{"type":"pong"}`。
|
||||
|
||||
当前事件类型:
|
||||
|
||||
| 事件 | 说明 |
|
||||
|---|---|
|
||||
| `kefu_connected` | 连接建立成功 |
|
||||
| `kefu_message_type` | 新客服消息 |
|
||||
| `kefu_conversation_change` | 会话信息变化 |
|
||||
| `kefu_message_read_status_change` | 消息已读状态变化 |
|
||||
|
||||
### 11.3 消息类型
|
||||
|
||||
| `contentType` | 类型 | `content` 建议格式 |
|
||||
|---:|---|---|
|
||||
| 1 | 文本 | UTF-8 字符串 |
|
||||
| 2 | 图片 | HTTPS 图片 URL |
|
||||
| 10 | 商品卡片 | 版本化 JSON |
|
||||
| 11 | 订单卡片 | 版本化 JSON |
|
||||
|
||||
商品和订单卡片建议增加 `schemaVersion`,并定义稳定字段,避免前后台各自猜测 JSON 结构。
|
||||
|
||||
## 12. 上线前后端必须补强项
|
||||
|
||||
以下问题不影响原型演示,但属于正式开发和上线的前置条件。
|
||||
|
||||
### 12.1 身份与数据权限(阻断上线)
|
||||
|
||||
当前用户接口允许客户端直接传 `userId`,且接口描述为免后台登录;WebSocket 也直接信任查询参数中的 `userId`。这会产生读取他人消息、订单或浏览记录的风险。
|
||||
|
||||
上线前必须:
|
||||
|
||||
1. 用户接口强制校验商城 `HSM-AUTH` 登录态。
|
||||
2. 后端从认证上下文取得会员 ID,忽略客户端提交的 `userId`。
|
||||
3. 会话、订单、浏览记录均按认证用户和商户双重校验。
|
||||
4. WebSocket 握手必须校验短期 token 或商城登录 token,并由服务端解析用户身份。
|
||||
5. 禁止仅通过 `userType=member&userId=...` 建立会员连接。
|
||||
6. 限制允许来源,正式环境不应保持 `AllowedOriginPatterns("*")`。
|
||||
|
||||
### 12.2 历史消息分页(阻断完整体验)
|
||||
|
||||
当前消息按 ID 正序分页,直接请求第一页可能得到最早的 80 条而不是最新消息。需要提供以下任一方案:
|
||||
|
||||
- 游标分页:`beforeMessageId` + `limit`,默认返回最新一页。
|
||||
- 倒序查询最新消息,返回前端后再按时间正序展示。
|
||||
|
||||
接口还应支持断线补偿参数 `afterMessageId`,只拉取最后已知消息之后的数据。
|
||||
|
||||
### 12.3 幂等与消息状态
|
||||
|
||||
发送接口建议新增:
|
||||
|
||||
- `clientMessageId`:客户端生成且在用户维度唯一。
|
||||
- 服务端唯一索引或幂等检查。
|
||||
- 统一 `createdAt` 服务端时间。
|
||||
- 明确发送失败错误码。
|
||||
|
||||
### 12.4 用户侧已读
|
||||
|
||||
当前 `readStatus` 主要表达后台是否已读会员消息,不能完整表达会员是否已读客服回复。若 P1 要展示用户未读角标,需要新增用户侧未读数或双向已读字段及接口。
|
||||
|
||||
### 12.5 内容安全与限制
|
||||
|
||||
- 后端校验允许的 `contentType`。
|
||||
- 文本长度限制并过滤危险 HTML,前端不得使用未净化的 `v-html`。
|
||||
- 图片 URL 只允许可信 CDN/OSS 域名。
|
||||
- 商品、订单卡片必须由服务端校验归属和关键展示信息。
|
||||
- 按用户和 IP 做发送频率限制。
|
||||
- 对恶意内容、重复刷屏和超大请求保留审计日志。
|
||||
|
||||
## 13. 前台项目技术边界
|
||||
|
||||
插件实现遵循:
|
||||
|
||||
- 技术栈与商城统一采用 uni-app,避免维护两套终端代码。
|
||||
- 客服核心逻辑封装在 `hashmall-customer-service` 组件中,由商城客服页直接承载。
|
||||
- 请求层复用商城 `HSM-AUTH` 与统一错误处理。
|
||||
- Socket 层使用 `uni.connectSocket` 封装单例连接。
|
||||
- 不在组件内硬编码 API、WSS、用户 ID、商户 ID 或客服号码。
|
||||
- H5 与小程序平台差异通过条件编译或适配器隔离。
|
||||
- 公共请求、认证和上传能力直接复用宿主工程;平台差异由插件内部适配。
|
||||
|
||||
插件代码目录结构:
|
||||
|
||||
```text
|
||||
frontend-web/uni_modules/hashmall-customer-service/
|
||||
├─ components/
|
||||
│ ├─ hashmall-customer-service/
|
||||
│ ├─ kefu-message-item/
|
||||
│ └─ kefu-context-card/
|
||||
├─ js_sdk/
|
||||
│ ├─ api.js
|
||||
│ └─ kefu-socket.js
|
||||
├─ static/
|
||||
├─ docs/
|
||||
├─ package.json
|
||||
└─ readme.md
|
||||
```
|
||||
|
||||
## 14. 埋点与可观测性
|
||||
|
||||
建议埋点:
|
||||
|
||||
- `customer_service_entry_click`:入口与场景来源。
|
||||
- `customer_service_page_view`:页面打开成功。
|
||||
- `customer_service_ws_connected`:连接耗时与重连次数。
|
||||
- `customer_service_message_send`:消息类型、结果、耗时,不记录正文。
|
||||
- `customer_service_card_send`:商品或订单卡片发送。
|
||||
- `customer_service_history_load`:分页结果与耗时。
|
||||
- `customer_service_error`:接口、Socket、解析、上传错误码。
|
||||
|
||||
日志和埋点不得记录 token、完整消息正文、订单隐私信息和图片内容。
|
||||
|
||||
## 15. 验收标准
|
||||
|
||||
### 15.1 功能验收
|
||||
|
||||
- 已登录用户能从“我的”、商品、订单三个场景进入客服页。
|
||||
- 未登录用户被引导登录,登录后能返回原咨询场景。
|
||||
- 首次进入能创建或恢复会话,并展示最新历史消息。
|
||||
- 文本消息双向实时送达。
|
||||
- 图片可选择、上传、发送、接收和预览。
|
||||
- 商品和订单卡片可发送、正确展示并跳回相应详情。
|
||||
- 发送失败可重试,网络超时不会生成重复消息。
|
||||
- 向上滚动能连续加载更早消息且无重复、无跳动。
|
||||
- WebSocket 断开后自动重连,断线消息能够补齐。
|
||||
- WebSocket 不可用时轮询兜底可继续收取消息。
|
||||
- 页面重复进入退出不会产生多个 Socket 或重复轮询。
|
||||
|
||||
### 15.2 安全验收
|
||||
|
||||
- 修改 URL、请求体或 Socket 参数不能访问其他会员数据。
|
||||
- 失效 token 无法查询和发送消息。
|
||||
- 用户不能发送不属于自己的订单卡片。
|
||||
- 用户不能伪造商品关键字段欺骗后台客服。
|
||||
- 非法消息类型、超长文本、非可信图片 URL 被后端拒绝。
|
||||
|
||||
### 15.3 兼容验收
|
||||
|
||||
- 微信开发者工具基础功能通过。
|
||||
- 至少一台 iOS 微信真机和一台 Android 微信真机通过。
|
||||
- iOS Safari 与 Android Chrome H5 通过。
|
||||
- 键盘弹起、图片选择、后台切换、弱网和断网恢复通过。
|
||||
- 小程序合法域名配置完整,正式包无“域名不合法”错误。
|
||||
|
||||
## 16. 实施阶段建议
|
||||
|
||||
### 阶段 A:接口收口与安全改造
|
||||
|
||||
- 用户接口改为从 token 获取用户身份。
|
||||
- WebSocket 增加认证。
|
||||
- 消息分页改为最新页/游标模式。
|
||||
- 增加发送幂等字段。
|
||||
- 固化商品、订单卡片协议。
|
||||
|
||||
### 阶段 B:独立前台客服 MVP
|
||||
|
||||
- 完成登录适配、聊天页、文本、图片、历史消息。
|
||||
- 完成 WebSocket、心跳、重连、轮询兜底。
|
||||
- 在 H5 和微信小程序独立联调。
|
||||
|
||||
### 阶段 C:商城场景接入
|
||||
|
||||
- 替换“我的”页电话弹窗和第三方客服 H5。
|
||||
- 接入商品详情与订单详情上下文。
|
||||
- 商品详情统一上报浏览记录。
|
||||
- 完成小程序分包与合法域名配置。
|
||||
|
||||
### 阶段 D:灰度与上线
|
||||
|
||||
- 测试环境全链路验收。
|
||||
- 小范围用户灰度。
|
||||
- 观察连接率、发送成功率和错误率。
|
||||
- 达标后全量替换旧客服入口。
|
||||
|
||||
## 17. 待产品与研发确认
|
||||
|
||||
1. 首期是否只支持平台客服,还是区分平台客服、云仓客服和商家客服。
|
||||
2. 客服服务时间、非工作时间欢迎语及联系电话由谁配置。
|
||||
3. 商品和订单卡片是否纳入 P0。
|
||||
4. 是否需要用户侧消息未读角标和小程序订阅消息。
|
||||
5. 图片上传沿用哪个现有接口及 OSS/CDN 域名。
|
||||
6. 客服聊天记录保留期限和用户侧是否允许删除。
|
||||
7. 旧第三方客服系统是一次性替换,还是保留灰度开关。
|
||||
8. 独立项目最终以分包、源码模块还是私有组件包的方式并入商城。
|
||||
|
||||
## 18. 结论
|
||||
|
||||
现有后端与管理后台已经具备客服前台 MVP 所需的大部分业务基础,前台开发的主要工作集中在跨端聊天体验、可靠消息状态、Socket 生命周期和商城场景接入。
|
||||
|
||||
正式编码前应优先完成用户身份校验、WebSocket 鉴权和历史消息分页三项后端收口。否则即使前台页面能够运行,也不满足正式上线的数据安全和完整体验要求。
|
||||
Reference in New Issue
Block a user