10 KiB
10 KiB
P9:小程序前端 — 详情与对话模块 — miniapp-fe-details
优先级:P9(依赖 P3 + P4 + P5-A) 预估工作量:大 P5-B 承接:T1 同时细化 P5 应用 3/6/7 的 Prompt JSON 结构
需求(Requirements)
用户故事
- 作为助教,我在客户详情页能看到客户全信息、消费记录(三种样式)、指数总览、备注、AI 分析。
- 作为助教,我在助教详情页能看到助教信息、客户数、工龄、备注。
- 作为助教,我在 AI 对话页能与 AI 流式对话,看到来源页面信息。
- 作为助教,我能查看历史 AI 对话记录。
验收标准
- AC1:消费记录区分三种样式(台桌结账→下沉台费明细、商城订单、充值)
- AC2:消费记录默认 10 条,拉到底懒加载(每次 10 条)
- AC3:金额为 0 的项不展示;有团购/折扣时展示正价+实付
- AC4:总金额仅在消费条目 >1 时出现
- AC5:AI 对话支持流式展示(逐字输出)
- AC6:从其他页面进入 chat.html 时新开对话,第一条消息为页面上下文
- AC7:对话历史列表可查看、可继续对话
页面清单
customer-detail(客户详情)
- 客户信息卡片(昵称、手机、会员卡等级、余额、注册日期)
- 指数总览(WBI/NCI/SPI 展示分 + 爱心 icon)
- 消费记录列表(三种样式,懒加载)
- 台桌结账:下沉到
dwd_table_fee_log,每条台费详情,关联总金额汇总 - 商城订单:助教列表(花名+级别+课程类型+服务时长+定档绩效)、支付金额、食品酒水总金额
- 充值:充值金额、支付方式
- 台桌结账:下沉到
- 备注列表
- AI 维客线索(应用 8 整合线索 + 人工,读取
member_retention_clue;Emoji 作为二级标签、提供者显示规则见下方"维客线索提供者显示规则"章节) - AI 客户分析(应用 7 缓存:运营策略数组 + 总结,结账单出现后自动生成;从
ai_cachecache_type=app7_customer_analysis 读取) - "问问助手"入口 → chat.html
coach-detail(助教详情)
- 助教信息卡片(花名、级别、工龄)
- 客户数(RS > 2 的客户数量)
- 备注按钮(查看此助教为该客户做的备注)
customer-service-records(客户服务记录)
- 服务记录列表(时间 + 持续时长)
chat(AI 对话)
- 来源展示(来源页面 title + 基本信息)
- 对话界面(IM 风格)
- AI 回复流式展示(SSE)
- 消息输入 + 发送
chat-history(对话历史)
- 历史对话列表(按时间倒序)
- 点击进入继续对话
后端 API 需求
| API | 说明 |
|---|---|
GET /api/customers/:id |
客户详情 |
GET /api/customers/:id/consumption-records |
消费记录(分页,懒加载) |
GET /api/customers/:id/indexes |
客户指数总览 |
GET /api/coaches/:id |
助教详情 |
GET /api/coaches/:id/customer-count |
助教客户数(RS>2) |
GET /api/customers/:id/service-records |
客户服务记录 |
POST /api/chat/conversations |
创建对话 |
POST /api/chat/conversations/:id/messages |
发送消息(SSE 流式返回) |
GET /api/chat/conversations |
对话历史列表 |
GET /api/chat/conversations/:id/messages |
对话消息列表 |
消费记录 settle_type 区分
settle_type 与消费记录类型映射(已校准,数据源:DWD-DOC 01-业务全景)
| settle_type | 含义 | 数量占比 | 消费记录样式 |
|---|---|---|---|
| 1 | 台桌结账 | 78.6% | 下沉到 dwd_table_fee_log 台费明细 |
| 3 | 商城订单 | 21.4% | 助教列表 + 支付金额 + 食品酒水(含 477 笔纯超休/激励课订单) |
| 5 | 正常充值 | — | 从 dwd_recharge_order 单独查询 |
| 7 | 充值退款 | 极少(10 笔) | 不在消费记录中展示 |
| 6 | 结算退款 | 极少(1 笔) | 不在消费记录中展示 |
金额字段说明(已校准,数据源:DWD-DOC 02-账务全景 + consume 口径文档)
⚠️ 不得直接使用 consume_money(三种历史口径混合,不稳定)。
正价金额(消费项目合计,全时期一致):
items_sum = table_charge_money + goods_money + assistant_pd_money
+ assistant_cx_money + electricity_money
实付金额需按支付渠道拆分展示:
| 支付渠道 | 字段 | 说明 |
|---|---|---|
| 线上支付 | pay_amount |
不含 balance,= point_amount + cash_amount |
| 储值卡 | balance_amount |
独立渠道,= recharge_card_amount + gift_card_amount |
| 团购券抵扣 | coupon_amount |
门店实际抵扣额 |
| 会员折扣 | member_discount_amount |
仅 settle_type=1 |
| 台费调整 | adjust_amount |
手动调价 |
| 抹零 | rounding_amount |
收支平衡减项 |
团购券三层价格体系(展示时注意区分):
- 顾客支付价 →
PCR.sale_price - 平台结算价 →
SH.pl_coupon_sale_amount(= SUM(GR.ledger_unit_price)) - 门店抵扣价 →
SH.coupon_amount(= SUM(GR.ledger_amount))
已知限制:
online_pay_channel全为 0,无法区分微信/支付宝(聚合支付接入)settlement_head_ex中payment_method、is_use_coupon、is_activity等字段全为 0,不可用- 团购券与会员折扣不叠加
- 2025-11-09 前台费明细
is_delete=1,历史数据不完整
维客线索提供者显示规则
后端过滤策略(安全性优先)
⚠️ 重要:维客线索的过滤必须在后端完成,客户端不进行任何过滤逻辑,以防止数据泄露风险。
客户详情页后端返回规则:
后端应返回所有相关的维客线索(包括系统生成、当前用户、他人记录、备注分析),但需要根据用户权限进行脱敏:
| 线索类型 | 返回条件 | 说明 |
|---|---|---|
| 系统生成 | 总是返回 | source = 'ai_consumption',完整返回 |
| 我的记录 | 总是返回 | source = 'manual' 且 recorded_by_assistant_id = 当前用户ID,完整返回 |
| 他人记录 | 返回完整版本 | source = 'manual' 且 recorded_by_assistant_id ≠ 当前用户ID,返回 recorded_by_name |
| 备注分析 | 返回完整版本 | source = 'ai_note',返回原备注的 recorded_by_name |
前端显示规则
客户详情页:前端直接显示后端返回的所有维客线索,显示具体人名:
| source 值 | 显示文案 |
|---|---|
ai_consumption |
By:系统 |
manual 且有 recordedByAssistantId |
By:我 |
manual 或 ai_note 且有 recordedByName |
By:{recordedByName} |
多条线索时,提供者用逗号分隔展示(如"By:系统, 王芳, 李明")
任务详情页:前端根据后端返回的脱敏数据显示(详见 P6 规范)
多人情况处理
当同一客户有多条维客线索时,前端按以下规则展示:
- 按时间排序:按
created_at升序排列(最早的在前) - 取最先反馈:
- 如果有"By:系统"的线索,优先显示最早的"By:系统"
- 如果没有"By:系统",则显示最早的"By:我"或其他人名
- 单条展示:维客线索卡片中仅显示一条(最优先的),其他线索可通过"查看全部"或列表展开查看
前端实现示例
// 客户详情页:直接显示后端返回的数据
function getClueProvider(clue: RetentionClue): string {
if (clue.source === 'ai_consumption') {
return 'By:系统'
}
if (clue.source === 'manual' && clue.recordedByAssistantId) {
return 'By:我'
}
if (clue.recordedByName) {
return `By:${clue.recordedByName}`
}
return 'By:某人' // 备用
}
// 从多条线索中选择最优先的
function selectPrimaryClue(clues: RetentionClue[]): RetentionClue {
const sorted = clues.sort((a, b) =>
new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
)
const systemClue = sorted.find(c => c.source === 'ai_consumption')
if (systemClue) return systemClue
return sorted[0]
}
小程序前端开发强制规范
以下规范适用于本 SPEC 中所有小程序页面实现,具有强制约束力。
- 原型图是唯一视觉真相:
docs/h5_ui/pages/*.html中的结构、层次、元素、配色、间距、交互行为是小程序页面实现的唯一参考标准。任何偏离原型图的实现都需要明确的产品确认。 - WXML ≠ HTML:严禁在小程序中使用 HTML 标签(div/span/p/a/img 等),必须使用小程序原生标签(view/text/image/navigator 等)。
- WXSS ≠ CSS:使用 rpx 单位、仅支持有限选择器、无 DOM/BOM API、样式隔离机制不同。Tailwind CSS 类名必须手动转换为 WXSS。
- TDesign 优先:凡 TDesign 组件库能覆盖的 UI 元素,必须使用 TDesign 组件;自定义实现仅限 TDesign 无法覆盖的场景。
- Power 文档优先:实现前必须加载
wechat-miniprogramPower 的相关 steering 文件(view-layer.md、tdesign.md、builtin-components.md),确保语法和组件用法正确。 - 项目踩坑指南必读:实现前必须阅读
docs/prd/MIGRATION-PLAYBOOK.md第六章,该文档是基于本项目实际转换经验的避坑手册,涵盖 WXML/WXSS 差异、事件系统、TDesign 用法、rpx 换算规则及新页面开发 Checklist。
任务清单
- T1:实现客户详情 API
- T1-a:细化 P5 应用 3(维客线索)Prompt JSON 结构,实现
consumption_records、member_cards等字段的拼接函数(对应 P5-T6-完整) - T1-b:细化 P5 应用 6(备注分析)Prompt JSON 结构,实现
consumption_data字段的拼接函数(对应 P5-T9-完整) - T1-c:细化 P5 应用 7(客户分析)Prompt JSON 结构,实现
objective_data字段的拼接函数(对应 P5-T10-完整)
- T1-a:细化 P5 应用 3(维客线索)Prompt JSON 结构,实现
- T2:实现消费记录分页 API(三种样式区分 + 懒加载)
- T3:实现客户指数总览 API
- T4:实现助教详情 API
- T5:实现对话 API(创建/发送/历史/消息列表,SSE 流式)
- T6:实现 customer-detail 小程序页面
- T7:实现 coach-detail 小程序页面
- T8:实现 customer-service-records 小程序页面
- T9:实现 chat 小程序页面(流式展示 + 来源信息)
- T10:实现 chat-history 小程序页面