47 KiB
小程序管理层视角 Storyboard 走查报告 — API 需求 Gap 分析
走查日期:2026-03-18 走查角色:管理层/店长 走查路线:3 个看板 → 助教详情 → 客户详情 → 服务记录 对比基准:前端内联 mock 数据 vs API 契约 (
API-contract.md) vs 八¾节 (NS1-xcx-backend-api.md)
场景 1:助教看板 → 助教详情 → 客户详情
1.1 board-coach(pages/board-coach/board-coach.ts)
API 调用
fetchBoardCoaches({ skill, sort, time })→CoachItem[]- 页面
onLoad()→loadData()→fetchBoardCoaches() - 下拉刷新
onPullDownRefresh()→loadData() - ⚠️ 筛选变更(
onSortChange/onSkillChange/onTimeChange)仅更新 data 状态,不调用loadData()(八¾节 F1 已记录)
前端期望字段(从内联 MOCK_COACHES 的 CoachItem 接口提取,共 18 个字段)
| 字段 | 类型 | 说明 | 数据源 |
|---|---|---|---|
id |
string | 助教 ID | dim_assistant |
name |
string | 助教姓名 | dim_assistant |
initial |
string | 姓名首字(头像占位) | 前端可计算 |
avatarGradient |
string | 头像渐变色 (blue/green/pink/amber/violet/cyan) | 前端可计算或后端分配 |
level |
string | 等级 key: star/senior/middle/junior | dim_assistant |
levelClass |
string | 等级样式类 | 前端可映射(LEVEL_CLASS 常量) |
skills |
Array<{text: string, cls: string}> |
技能列表含 emoji 和样式类 | cfg 表 |
topCustomers |
string[] |
Top 客户列表含 emoji 前缀(如 '💖 王先生') |
dws_member_assistant_relation_index |
perfHours |
number | 当期定档工时 | dws_assistant_salary_calc |
perfHoursBefore |
number? | 上期定档工时(可选) | dws_assistant_salary_calc (上期) |
perfGap |
string? | 距升档差距描述(如 "距升档 13.8h",已达标时不返回) |
后端计算 |
perfReached |
boolean | 是否已达标 | 后端计算 |
salary |
number | 工资总额(元) | dws_assistant_salary_calc |
salaryPerfHours |
number | 定档工时 | 同 perfHours |
salaryPerfBefore |
number? | 上期定档工时 | 同 perfHoursBefore |
svAmount |
number | 客源储值总额(元) | dws_member_consumption_summary |
svCustomerCount |
number | 储值客户数 | dws_member_consumption_summary |
svConsume |
number | 储值消耗额(元) | dws_member_consumption_summary |
taskRecall |
number | 召回任务完成数 | biz.coach_tasks |
taskCallback |
number | 回访任务完成数 | biz.coach_tasks |
筛选参数映射
| 筛选项 | 前端参数 | 后端参数 | 查询影响 |
|---|---|---|---|
| 排序维度 | sort: perf_desc/perf_asc/salary_desc/salary_asc/sv_desc/task_desc |
sort |
决定排序字段和方向 + 卡片模板(dimType) |
| 技能筛选 | skill: all/chinese/snooker/mahjong/karaoke |
skill |
WHERE 过滤助教技能类型 |
| 时间范围 | time: month/quarter/last_month/last_3m/last_quarter/last_6m |
time |
决定统计日期区间 |
交叉约束:time=last_6m + sort=sv_desc 不兼容(TIME_OPTIONS 注释标注)
页面跳转
- 点击助教卡片
onCoachTap→/pages/coach-detail/coach-detail?id={coachId} - Tab 切换 →
board-finance(switchTab)/board-customer(navigateTo)
API 契约 vs Mock 数据 vs 八¾节 差异
| 差异项 | API 契约 (BOARD-1) | 前端 Mock (CoachItem) | 八¾节 (B1) | 严重度 |
|---|---|---|---|---|
| 字段结构 | 扁平简单:id, name, avatar, level, level_class, skills(string[]), total_hours, total_income, customer_count, satisfaction |
丰富结构:4 维度 20 个字段,skills 为对象数组,含 topCustomers | 与 Mock 一致,详细列出 4 维度字段 | 🔴 高 |
initial 字段 |
❌ 无 | ✅ 有 | ✅ 有 | 🟠 中 |
avatarGradient 字段 |
❌ 无(仅 avatar URL) |
✅ 有 | ✅ 有 | 🟠 中 |
skills 类型 |
string[] |
Array<{text, cls}> |
Array<{text, cls}> |
🔴 高 |
topCustomers 字段 |
❌ 无 | ✅ 有 | ✅ 有 | 🔴 高 |
| 4 维度专属字段 | ❌ 全部缺失(仅 total_hours/total_income/customer_count/satisfaction) | ✅ 完整(perf/salary/sv/task 各 2-4 个字段) | ✅ 完整 | 🔴 高 |
sort 参数格式 |
sort=field:direction |
sort=perf_desc 等枚举 |
sort=perf_desc 等枚举 |
🟠 中 |
| 分页 | 无分页定义 | 无分页(全量返回) | 无分页 | 🟡 低 |
spec 未记录的 Gap
- 🔴 API 契约 BOARD-1 响应字段与前端实际需求严重不匹配 — 契约仅定义 10 个通用字段,前端需要 20 个含 4 维度专属字段
- 🔴
skills类型不一致 — 契约为string[],前端需要Array<{text, cls}>(含 emoji 和样式类) - 🔴
topCustomers字段契约完全缺失 — 前端每个助教卡片展示 Top 3 客户 - 🟠
sort参数格式不一致 — 契约用field:direction,前端用枚举值perf_desc - 🟠
initial/avatarGradient字段契约缺失 — 前端用于头像渲染,需确认由前端计算还是后端返回
1.2 coach-detail(pages/coach-detail/coach-detail.ts)
API 调用
fetchCoachDetail(coachId)→CoachCard | null(api.ts 返回类型过于简单)- 页面
onLoad({ id })→loadData(id)→fetchCoachDetail(id) - 实际使用内联 mock 数据组装 CoachDetail 对象
前端期望字段(从 mockCoachDetail + 各 mock 数组提取)
CoachDetail 基础信息:
| 字段 | 类型 | 说明 |
|---|---|---|
id |
string | 助教 ID |
name |
string | 助教姓名 |
avatar |
string | 头像 URL |
level |
string | 等级(中文:星级/高级/中级/初级) |
skills |
string[] | 技能列表 |
workYears |
number | 工龄 |
customerCount |
number | 客户数 |
hireDate |
string | 入职日期 |
performance 绩效指标:
| 字段 | 类型 | 说明 |
|---|---|---|
performance.monthlyHours |
number | 本月定档业绩工时 |
performance.monthlySalary |
number | 本月工资(预估) |
performance.customerBalance |
number | 客源储值余额 |
performance.tasksCompleted |
number | 本月任务完成数 |
performance.perfCurrent |
number | 当前绩效值 |
performance.perfTarget |
number | 目标绩效值 |
income 收入明细(本月/上月 Tab 切换):
| 字段 | 类型 | 说明 |
|---|---|---|
income.thisMonth |
IncomeItem[] |
本月收入明细(基础课时费/激励课时费/充值提成/酒水提成) |
income.lastMonth |
IncomeItem[] |
上月收入明细 |
IncomeItem: label |
string | 收入项名称 |
IncomeItem: amount |
string | 金额(格式化,如 "¥3,500") |
IncomeItem: color |
string | 颜色标识 |
任务执行区域(管理层视角核心):
| 字段 | 类型 | 说明 |
|---|---|---|
visibleTasks |
TaskItem[] |
可见任务(active 状态) |
hiddenTasks |
TaskItem[] |
隐藏任务(inactive 状态,被顶替但未过期) |
abandonedTasks |
AbandonedTask[] |
已放弃任务 |
TaskItem: typeLabel |
string | 任务类型标签(高优先召回/优先召回/关系构建/客户回访) |
TaskItem: typeClass |
string | 样式类(high-priority/priority/relationship/callback) |
TaskItem: customerName |
string | 客户姓名 |
TaskItem: noteCount |
number | 备注数量 |
TaskItem: pinned |
boolean | 是否置顶 |
TaskItem: notes |
Array<{pinned?, text, date}> |
备注列表(可选) |
AbandonedTask: customerName |
string | 客户姓名 |
AbandonedTask: reason |
string | 放弃原因 |
客户关系 TOP20(管理层关注指标):
| 字段 | 类型 | 说明 |
|---|---|---|
TopCustomer: id |
string | 客户 ID |
TopCustomer: name |
string | 客户姓名 |
TopCustomer: initial |
string | 姓名首字 |
TopCustomer: avatarGradient |
string | 头像渐变色 |
TopCustomer: heartEmoji |
string | 爱心 emoji(❤️/💛/🤍) |
TopCustomer: score |
string | 关系指数 |
TopCustomer: scoreColor |
string | 分数颜色(success/warning/gray) |
TopCustomer: serviceCount |
number | 服务次数 |
TopCustomer: balance |
string | 余额(格式化) |
TopCustomer: consume |
string | 消费额(格式化) |
近期服务明细:
| 字段 | 类型 | 说明 |
|---|---|---|
ServiceRecord: customerId |
string? | 客户 ID |
ServiceRecord: customerName |
string | 客户姓名 |
ServiceRecord: initial |
string | 姓名首字 |
ServiceRecord: avatarGradient |
string | 头像渐变色 |
ServiceRecord: type |
string | 课程类型(基础课/激励课) |
ServiceRecord: typeClass |
string | 样式类(basic/incentive) |
ServiceRecord: table |
string | 台桌号 |
ServiceRecord: duration |
string | 时长(格式化) |
ServiceRecord: income |
string | 收入(格式化) |
ServiceRecord: date |
string | 日期时间 |
ServiceRecord: perfHours |
string? | 定档工时(可选) |
历史月份统计(管理层评估助教表现):
| 字段 | 类型 | 说明 |
|---|---|---|
HistoryMonth: month |
string | 月份标签(本月/上月/4月...) |
HistoryMonth: estimated |
boolean | 是否预估 |
HistoryMonth: customers |
string | 客户数(格式化,如 "22人") |
HistoryMonth: hours |
string | 工时(格式化,如 "87.5h") |
HistoryMonth: salary |
string | 工资(格式化) |
HistoryMonth: callbackDone |
number | 回访完成数 |
HistoryMonth: recallDone |
number | 召回完成数 |
备注列表:
| 字段 | 类型 | 说明 |
|---|---|---|
NoteItem: id |
string | 备注 ID |
NoteItem: content |
string | 备注内容 |
NoteItem: timestamp |
string | 时间戳 |
NoteItem: score |
number | 评分 |
NoteItem: customerName |
string | 关联客户/管理员名 |
NoteItem: tagLabel |
string | 标签 |
NoteItem: createdAt |
string | 创建时间(格式化) |
绩效进度条数据(前端需要后端提供):
| 字段 | 类型 | 说明 |
|---|---|---|
tierNodes |
number[] | 档位节点数组(如 [0, 100, 130, 160, 190, 220]) |
maxHours |
number | 最大工时(进度条满值) |
筛选参数映射
- 无筛选项,单次加载全部数据
- 收入明细有本月/上月 Tab 切换(纯前端切换,数据一次性返回)
页面跳转
- 点击任务项
onTaskItemTap→/pages/customer-detail/customer-detail?name={customerName}(⚠️ 用 name 而非 id) - 点击客户卡片
onCustomerTap→/pages/customer-detail/customer-detail?id={customerId} - 点击服务记录
onSvcCardTap→/pages/customer-detail/customer-detail?id={customerId} - 查看更多服务记录
onViewMoreRecords→/pages/performance-records/performance-records?coachId={coachId} - 问问助手
onStartChat→/pages/chat/chat?coachId={coachId}
API 契约 vs Mock 数据 vs 八¾节 差异
| 差异项 | API 契约 (COACH-1) | 前端 Mock | 八¾节 | 严重度 |
|---|---|---|---|---|
| 返回类型 | api.ts 返回 CoachCard(仅 id/name/avatar/level/keyMetrics) |
实际需要 CoachDetail(含 performance/income/tasks/topCustomers/serviceRecords/historyMonths/notes) | 仅提到基本信息+任务分组+Top客户+服务记录 | 🔴 高 |
income 本月/上月明细 |
❌ 无 | ✅ 有(4 项收入分类 × 2 月) | ❌ 无 | 🔴 高 |
topCustomers TOP20 |
契约仅 top_customers: Array<{id, name, avatar, total_spend, visit_count}> |
Mock 含 20 条,每条含 heartEmoji/score/scoreColor/serviceCount/balance/consume | ❌ 未详细定义字段 | 🔴 高 |
historyMonths 历史月份 |
❌ 完全缺失 | ✅ 有(5 个月,含 estimated/customers/hours/salary/callbackDone/recallDone) | ❌ 完全缺失 | 🔴 高 |
tierNodes 档位节点 |
❌ 缺失 | ✅ 有(进度条组件需要) | ❌ 缺失 | 🟠 中 |
| 任务分组 | visible_tasks/hidden_tasks/abandoned_tasks |
同,但 TaskItem 结构含 notes 子数组 | ✅ 已确认 active/inactive/abandoned 映射 | 🟡 低 |
| 备注列表 | ❌ 未在 COACH-1 定义 | ✅ 有(含 score 字段) | ❌ 未提及 | 🟠 中 |
spec 未记录的 Gap
- 🔴 COACH-1 响应缺少
income收入明细(本月/上月 4 项分类)— 管理层评估助教收入结构的核心数据 - 🔴 COACH-1 响应缺少
historyMonths历史月份统计 — 管理层评估助教长期表现趋势 - 🔴
topCustomers字段结构不完整 — 契约仅 5 个字段,前端需要 10 个字段(含 heartEmoji/scoreColor/balance/consume) - 🟠 COACH-1 响应缺少
tierNodes/maxHours— 绩效进度条组件需要档位节点数据 - 🟠 COACH-1 响应缺少备注列表 — 管理层需要查看助教相关备注
- 🟠
onTaskItemTap用name而非id跳转客户详情 — 前端 Bug,name 不唯一 - 🟡 api.ts 中
fetchCoachDetail返回类型为CoachCard(mock-data.ts 中的简单类型),与实际需要的 CoachDetail 不匹配
场景 2:客户看板 → 客户详情 → 客户服务记录
2.1 board-customer(pages/board-customer/board-customer.ts)
API 调用
fetchBoardCustomers({ dimension, project })→CustomerItem[]- 页面
onLoad()→loadData()→fetchBoardCustomers() - 下拉刷新
onPullDownRefresh()→loadData() - ⚠️ 筛选变更(
onDimensionChange/onProjectChange)仅更新 data 状态,不调用loadData()(八¾节 F2 已记录) - ⚠️ 缺少分页参数
page/pageSize(八¾节 F3 已记录)
前端期望字段(从内联 MOCK_CUSTOMERS 的 CustomerItem 接口提取)
所有维度共享基础字段(每个 item 都返回):
| 字段 | 类型 | 说明 |
|---|---|---|
id |
string | 客户 member_id |
name |
string | 客户姓名 |
initial |
string | 姓名首字 |
avatarCls |
string | 头像样式类(avatar--amber/pink/blue 等) |
assistants |
AssistantInfo[] |
关联助教列表 |
AssistantInfo 结构:
| 字段 | 类型 | 说明 |
|---|---|---|
name |
string | 助教姓名 |
cls |
string | 样式类(assistant--assignee/abandoned/normal) |
heartScore |
number | 爱心分 0-10 |
badge |
string? | 标记(跟/弃) |
badgeCls |
string? | 标记样式类 |
8 维度专属字段(按 dimension 参数返回对应字段):
| 维度 | 专属字段 | 类型 | 说明 |
|---|---|---|---|
| recall | idealDays |
number | 理想到店间隔(天) |
elapsedDays |
number | 已过天数 | |
overdueDays |
number | 超期天数 | |
visits30d |
number | 近30天到店次数 | |
balance |
string | 余额(格式化) | |
recallIndex |
string | 召回指数 | |
| potential | potentialTags |
Array<{text, theme}> |
潜力标签 |
spend30d |
string | 近30天消费 | |
avgVisits |
string | 月均到店 | |
avgSpend |
string | 次均消费 | |
| balance | balance |
string | 当前余额 |
lastVisit |
string | 最近到店 | |
monthlyConsume |
string | 月均消耗 | |
availableMonths |
string | 可用月数 | |
| recharge | lastRecharge |
string | 最后充值日期 |
rechargeAmount |
string | 充值金额 | |
recharges60d |
string | 近60天充值次数 | |
currentBalance |
string | 当前余额 | |
| recent | daysAgo |
number | 距今天数 |
visitFreq |
string | 到店频率 | |
idealDays |
number | 理想间隔 | |
visits30d |
number | 近30天到店 | |
avgSpend |
string | 次均消费 | |
| spend60 | spend60d |
string | 近60天消费总额 |
visits60d |
string | 近60天到店次数 | |
highSpendTag |
boolean | 是否高消费标签 | |
avgSpend |
string | 次均消费 | |
| freq60 | visits60d |
string | 近60天到店次数 |
avgInterval |
string | 平均到店间隔 | |
weeklyVisits |
Array<{val, pct}> |
8周到店柱状图 | |
spend60d |
string | 近60天消费 | |
| loyal | intimacy |
string | 亲密度指数 |
topCoachName |
string | 最亲密助教姓名 | |
topCoachHeart |
number | 最亲密助教爱心分 | |
topCoachScore |
string | 最亲密助教关系指数 | |
coachName |
string | 主助教姓名 | |
coachRatio |
string | 主助教占比 | |
coachDetails |
Array<{name, cls, heartScore, badge?, avgDuration, serviceCount, coachSpend, relationIdx}> |
助教服务明细表 |
筛选参数映射
| 筛选项 | 前端参数 | 后端参数 | 查询影响 |
|---|---|---|---|
| 维度切换 | dimension: recall/potential/balance/recharge/recent/spend60/freq60/loyal |
dimension |
决定查询的 FDW 表和排序字段 |
| 项目筛选 | project: all/chinese/snooker/mahjong/karaoke |
project |
WHERE 过滤客户偏好项目 |
无交叉约束,8×5=40 种有效组合。
页面跳转
- 点击客户卡片
onCustomerTap→/pages/customer-detail/customer-detail?id={customerId} - Tab 切换 →
board-finance(switchTab)/board-coach(navigateTo)
API 契约 vs Mock 数据 vs 八¾节 差异
| 差异项 | API 契约 (BOARD-2) | 前端 Mock (CustomerItem) | 八¾节 (B2) | 严重度 |
|---|---|---|---|---|
| 字段结构 | 扁平简单:id, name, avatar, tags(string[]), total_spend, visit_count, last_visit, relation_index |
丰富结构:8 维度 40+ 专属字段 + assistants 对象数组 | 与 Mock 一致 | 🔴 高 |
assistants 字段 |
❌ 无 | ✅ 有(含 name/cls/heartScore/badge/badgeCls) | ✅ 有 | 🔴 高 |
avatarCls 字段 |
❌ 无(仅 avatar URL) |
✅ 有 | ✅ 有 | 🟠 中 |
initial 字段 |
❌ 无 | ✅ 有 | ✅ 有 | 🟠 中 |
| 8 维度专属字段 | ❌ 全部缺失 | ✅ 完整 | ✅ 完整 | 🔴 高 |
weeklyVisits 柱状图 |
❌ 无 | ✅ 有(freq60 维度,8 周数据) | ✅ 有 | 🔴 高 |
coachDetails 明细表 |
❌ 无 | ✅ 有(loyal 维度,助教服务明细) | ✅ 有 | 🔴 高 |
potentialTags 标签 |
❌ 无 | ✅ 有(potential 维度,含 text+theme) | ✅ 有 | 🟠 中 |
| 分页 | ✅ 有(page/pageSize) | ❌ 无(全量返回 3 条 mock) | ✅ 已确认 20 条懒加载 | 🟡 低 |
spec 未记录的 Gap
- 🔴 API 契约 BOARD-2 响应字段与前端实际需求严重不匹配 — 契约仅 8 个通用字段,前端需要 40+ 维度专属字段
- 🔴
assistants关联助教列表契约完全缺失 — 每个客户卡片展示关联助教及其爱心分/跟弃状态 - 🔴
weeklyVisits8 周柱状图数据契约缺失 — freq60 维度的核心可视化数据 - 🔴
coachDetails助教服务明细表契约缺失 — loyal 维度展示每个助教的详细服务数据 - 🟠
potentialTags标签结构契约缺失 — potential 维度展示客户潜力标签
2.2 customer-detail(pages/customer-detail/customer-detail.ts)
API 调用
fetchCustomerDetail(customerId)→MockCustomerDetail | null- 页面
onLoad()→loadDetail()→fetchCustomerDetail(id) - ⚠️
loadDetail()中 id 获取方式有 Bug:(this as any).__route__?.split('?')[1]无法正确解析 query 参数
前端期望字段(从内联 data 提取,管理层视角)
客户基础信息:
| 字段 | 类型 | 说明 |
|---|---|---|
detail.id |
string | 客户 ID |
detail.name |
string | 客户姓名 |
detail.avatarChar |
string | 头像字符 |
detail.phone |
string | 完整手机号(前端控制脱敏显示) |
detail.balance |
string | 余额(格式化) |
detail.consumption60d |
string | 近60天消费(格式化) |
detail.idealInterval |
string | 理想到店间隔 |
detail.daysSinceVisit |
string | 距上次到店天数 |
AI 洞察(管理层视角特有):
| 字段 | 类型 | 说明 |
|---|---|---|
aiInsight.summary |
string | AI 分析摘要 |
aiInsight.strategies |
Array<{color, text}> |
策略建议列表 |
维客线索(clues):
| 字段 | 类型 | 说明 |
|---|---|---|
clues[].category |
string | 线索大类(含换行符格式化) |
clues[].categoryColor |
string | 分类颜色 |
clues[].text |
string | 线索文本(含 emoji) |
clues[].source |
string | 来源(系统/助教名) |
clues[].detail |
string? | 详情(可选,展开显示) |
关联助教 coachTasks(管理层关注多助教对同一客户的服务):
| 字段 | 类型 | 说明 |
|---|---|---|
coachTasks[].name |
string | 助教姓名 |
coachTasks[].level |
string | 等级 |
coachTasks[].levelColor |
string | 等级颜色 |
coachTasks[].taskType |
string | 任务类型标签 |
coachTasks[].taskColor |
string | 任务颜色 |
coachTasks[].bgClass |
string | 背景样式类 |
coachTasks[].status |
string | 状态(normal/pinned/abandoned) |
coachTasks[].lastService |
string | 最后服务时间 |
coachTasks[].metrics |
Array<{label, value, color?}> |
指标列表(近60天次数/总时长/次均时长) |
喜好助教 favoriteCoaches:
| 字段 | 类型 | 说明 |
|---|---|---|
favoriteCoaches[].emoji |
string | 爱心 emoji |
favoriteCoaches[].name |
string | 助教姓名 |
favoriteCoaches[].relationIndex |
string | 关系指数 |
favoriteCoaches[].indexColor |
string | 指数颜色 |
favoriteCoaches[].bgClass |
string | 背景样式类 |
favoriteCoaches[].stats |
Array<{label, value, color?}> |
统计(基础/激励/上课/充值) |
消费记录 consumptionRecords(3 种类型,管理层关注消费结构):
| 字段 | 类型 | 说明 |
|---|---|---|
ConsumptionRecord.id |
string | 记录 ID |
ConsumptionRecord.type |
"table" | "shop" | "recharge" |
消费类型 |
ConsumptionRecord.date |
string | 日期 |
ConsumptionRecord.tableName |
string? | 台桌名(table 类型) |
ConsumptionRecord.startTime |
string? | 开始时间 |
ConsumptionRecord.endTime |
string? | 结束时间 |
ConsumptionRecord.duration |
string? | 时长 |
ConsumptionRecord.tableFee |
number? | 台费(优惠后) |
ConsumptionRecord.tableOrigPrice |
number? | 台费原价 |
ConsumptionRecord.coaches |
Array<{name, level, levelColor, courseType, hours, perfHours?, fee}> |
助教服务明细 |
ConsumptionRecord.foodAmount |
number? | 食品酒水金额(优惠后) |
ConsumptionRecord.foodOrigPrice |
number? | 食品酒水原价 |
ConsumptionRecord.totalAmount |
number? | 总金额 |
ConsumptionRecord.totalOrigPrice |
number? | 总原价 |
ConsumptionRecord.payMethod |
string? | 支付方式 |
ConsumptionRecord.rechargeAmount |
number? | 充值金额(recharge 类型) |
备注列表:
| 字段 | 类型 | 说明 |
|---|---|---|
sortedNotes[].id |
string | 备注 ID |
sortedNotes[].tagLabel |
string | 标签(管理员/助教名) |
sortedNotes[].createdAt |
string | 创建时间 |
sortedNotes[].content |
string | 备注内容 |
页面跳转
- 查看服务记录
onViewServiceRecords→/pages/customer-service-records/customer-service-records(⚠️ 未传 customerId 参数!) - 问问助手
onStartChat→/pages/chat/chat(⚠️ 未传 customerId 参数!)
API 契约 vs Mock 数据 差异
| 差异项 | API 契约 (CUST-1) | 前端 Mock | 严重度 |
|---|---|---|---|
aiInsight AI 洞察 |
❌ 完全缺失 | ✅ 有(summary + strategies) | 🔴 高 |
coachTasks 关联助教任务 |
❌ 完全缺失 | ✅ 有(4 个助教,含 metrics) | 🔴 高 |
favoriteCoaches 喜好助教 |
❌ 完全缺失 | ✅ 有(含 stats 统计) | 🔴 高 |
clues 维客线索 |
契约有 retention_clues 但结构不同 |
前端用 category/categoryColor/text/source/detail | 🟠 中 |
consumptionRecords 结构 |
契约为扁平 {id, date, type, type_class, amount, table, duration} |
前端为嵌套结构(含 coaches 子数组、tableFee/foodAmount 分项) | 🔴 高 |
balance/consumption60d/idealInterval/daysSinceVisit |
❌ 缺失 | ✅ 有 | 🟠 中 |
avatarChar |
❌ 无(仅 avatar URL) | ✅ 有 | 🟡 低 |
| 备注列表 | ❌ 未在 CUST-1 定义 | ✅ 有 | 🟠 中 |
spec 未记录的 Gap
- 🔴 CUST-1 缺少
aiInsightAI 洞察 — 管理层查看客户时的核心决策辅助信息(来源:biz.ai_cache app4_analysis) - 🔴 CUST-1 缺少
coachTasks关联助教任务区域 — 管理层关注多助教对同一客户的服务情况 - 🔴 CUST-1 缺少
favoriteCoaches喜好助教 — 展示客户与各助教的关系指数和服务统计 - 🔴 CUST-1 消费记录结构严重不匹配 — 契约为扁平结构,前端需要嵌套结构(含助教明细、台费/食品分项、原价/优惠后价格)
- 🟠
onViewServiceRecords跳转未传customerId— 前端 Bug - 🟠
onStartChat跳转未传customerId— 前端 Bug - 🟠
loadDetail()中 id 解析方式有 Bug — 应从onLoad(options)的 options 中获取
2.3 customer-service-records(pages/customer-service-records/customer-service-records.ts)
API 调用
fetchCustomerRecords({ customerId })→{ records, hasMore }- 页面
onLoad({ customerId, id })→loadData(id)→fetchCustomerRecords({ customerId: id }) - ⚠️ 首次加载拉取全部记录,月份切换仅本地过滤(八¾节 F10/L4 已记录)
前端期望字段
页面头部信息:
| 字段 | 类型 | 说明 |
|---|---|---|
customerName |
string | 客户姓名 |
customerPhone |
string | 脱敏手机号 |
customerPhoneFull |
string | 完整手机号 |
totalServiceCount |
number | 累计服务次数 |
relationIndex |
string | 关系指数 |
ServiceRecord 结构(转换后):
| 字段 | 类型 | 说明 |
|---|---|---|
table |
string | 台桌号 |
type |
string | 课程类型标签 |
typeClass |
'basic' | 'vip' | 'tip' | 'recharge' |
样式类 |
recordType |
'course' | 'recharge' |
记录类型 |
duration |
number | 折算后小时数 |
durationRaw |
number | 折算前小时数 |
income |
number | 到手金额 |
isEstimate |
boolean | 是否预估 |
drinks |
string | 饮品描述 |
date |
string | 显示日期+时间段 |
筛选参数映射
| 筛选项 | 前端参数 | 后端参数 | 查询影响 |
|---|---|---|---|
| 月份切换 | currentYear/currentMonth |
year/month |
按月筛选记录(当前为本地过滤) |
| 客户 ID | customerId |
customerId |
WHERE 过滤 |
页面跳转
- 无跳转(详情页,仅返回上一页)
API 契约 vs Mock 数据 差异
| 差异项 | API 契约 (CUST-2) | 前端 Mock | 严重度 |
|---|---|---|---|
| 源数据结构 | 契约返回 ServiceRecord 格式 | Mock 使用 ConsumptionRecord(来自 mock-data.ts),前端转换为 ServiceRecord | 🟠 中 |
customerPhone/customerPhoneFull |
契约有 customer_phone |
Mock 硬编码 | 🟡 低 |
tables 台桌列表 |
契约有 tables: Array<{id, name}> |
Mock 无(前端模拟台号) | 🟡 低 |
relationIndex |
契约有 relation_index |
Mock 硬编码 "0.85" |
🟡 低 |
| 月度统计 | ❌ 契约无 | ✅ 前端本地计算 monthCount/monthHours/monthRelation |
🟠 中 |
spec 未记录的 Gap
- 🟠 CUST-2 响应缺少月度统计汇总 — 前端需要
monthCount/monthHours,当前本地计算,联调后应由后端返回 - 🟠 首次加载全量 vs 按月分页 — 当前设计一次拉全部记录本地过滤,数据量大时需改为按月请求
场景 3:财务看板(最复杂)
3.1 board-finance(pages/board-finance/board-finance.ts)
API 调用
fetchBoardFinance()→BoardFinanceData(⚠️ 当前签名仅{ date?: string },缺少 time/area/compare 参数)- 页面
onLoad()→fetchBoardFinance()→ 设置pageState: 'normal' - ⚠️ 筛选变更(
onTimeChange/onAreaChange/toggleCompare)仅更新 data 状态,不调用 API(八¾节 F4/F5 已记录) - ⚠️ 所有 6 个板块数据完全内联在
data中,fetchBoardFinance返回的_data未使用
前端期望字段(从内联 data 提取,6 个板块完整结构)
板块 1:经营一览 (overview) — 8 个指标 + 8 个环比值
| 字段 | 类型 | 说明 |
|---|---|---|
overview.occurrence |
string | 发生额/正价(格式化,如 "¥823,456") |
overview.occurrenceCompare |
string | 环比百分比(如 "12.5%") |
overview.discount |
string | 总优惠(负值,如 "-¥113,336") |
overview.discountCompare |
string | 环比 |
overview.discountRate |
string | 优惠率(如 "13.8%") |
overview.discountRateCompare |
string | 环比 |
overview.confirmedRevenue |
string | 成交/确认收入 |
overview.confirmedCompare |
string | 环比 |
overview.cashIn |
string | 实收/现金流入 |
overview.cashInCompare |
string | 环比 |
overview.cashOut |
string | 现金支出 |
overview.cashOutCompare |
string | 环比 |
overview.cashBalance |
string | 现金结余 |
overview.cashBalanceCompare |
string | 环比 |
overview.balanceRate |
string | 结余率 |
overview.balanceRateCompare |
string | 环比 |
板块 2:预收资产 (recharge) — 储值卡 + 赠送卡矩阵
| 字段 | 类型 | 说明 |
|---|---|---|
recharge.actualIncome |
string | 储值卡充值实收 |
recharge.actualCompare |
string | 环比 |
recharge.firstCharge |
string | 首充 |
recharge.firstChargeCompare |
string | 环比 |
recharge.renewCharge |
string | 续费 |
recharge.renewChargeCompare |
string | 环比 |
recharge.consumed |
string | 消耗 |
recharge.consumedCompare |
string | 环比 |
recharge.cardBalance |
string | 储值卡总余额 |
recharge.cardBalanceCompare |
string | 环比 |
recharge.giftRows |
Array<{label, total, totalCompare, wine, wineCompare, table, tableCompare, coupon, couponCompare}> |
赠送卡矩阵(3行:新增/消费/余额 × 4列:合计/酒水卡/台费卡/抵用券) |
recharge.allCardBalance |
string | 全类别会员卡余额合计 |
recharge.allCardBalanceCompare |
string | 环比 |
赠送卡矩阵结构(3×4 = 12 个数据单元 + 12 个环比值 = 24 个字段):
- 行:新增 / 消费 / 余额
- 列:合计(total) / 酒水卡(wine) / 台费卡(table) / 抵用券(coupon)
板块 3:应计收入确认 (revenue) — 4 个子表
| 字段 | 类型 | 说明 |
|---|---|---|
revenue.structureRows |
Array<{id, name, desc?, amount, discount, booked, bookedCompare, isSub?}> |
收入结构表(9行,含子行标记) |
revenue.priceItems |
Array<{name, value, compare}> |
正价明细(4项) |
revenue.totalOccurrence |
string | 正价合计 |
revenue.totalOccurrenceCompare |
string | 环比 |
revenue.discountItems |
Array<{name, desc?, value, compare}> |
优惠明细(4项) |
revenue.confirmedTotal |
string | 确认收入合计 |
revenue.confirmedTotalCompare |
string | 环比 |
revenue.channelItems |
Array<{name, desc?, value, compare}> |
渠道明细(3项) |
收入结构表行结构:
- 开台与包厢(含 A区/B区/C区/团建区/麻将区 5 个子行)
- 助教基础课
- 助教激励课
- 食品酒水
板块 4:现金流入 (cashflow)
| 字段 | 类型 | 说明 |
|---|---|---|
cashflow.consumeItems |
Array<{name, desc, value, compare, isDown}> |
消费收款(3项:纸币现金/线上收款/团购平台) |
cashflow.rechargeItems |
Array<{name, desc, value, compare}> |
充值收款(1项:会员充值到账) |
cashflow.total |
string | 现金流入合计 |
cashflow.totalCompare |
string | 环比 |
板块 5:现金流出 (expense) — 4 个子分组
| 字段 | 类型 | 说明 |
|---|---|---|
expense.operationItems |
Array<{name, value, compare, isDown}> |
经营支出(3项:食品饮料/耗材/报销) |
expense.fixedItems |
Array<{name, value, compare, isFlat}> |
固定支出(4项:房租/水电/物业/人员工资) |
expense.coachItems |
Array<{name, value, compare, isDown}> |
助教分成(4项:基础课/激励课/充值提成/额外奖金) |
expense.platformItems |
Array<{name, value, compare}> |
平台服务费(3项:汇来米/美团/抖音) |
expense.total |
string | 现金流出合计 |
expense.totalCompare |
string | 环比 |
板块 6:助教分析 (coachAnalysis) — 基础课 + 激励课两个子表
| 字段 | 类型 | 说明 |
|---|---|---|
coachAnalysis.basic.totalPay |
string | 基础课总收入 |
coachAnalysis.basic.totalPayCompare |
string | 环比 |
coachAnalysis.basic.totalShare |
string | 基础课总分成 |
coachAnalysis.basic.totalShareCompare |
string | 环比 |
coachAnalysis.basic.avgHourly |
string | 平均时薪 |
coachAnalysis.basic.avgHourlyCompare |
string | 环比 |
coachAnalysis.basic.rows |
Array<{level, pay, payCompare, share, shareCompare, hourly, hourlyCompare, hourlyFlat?, payDown?, shareDown?}> |
按等级分行(初级/中级/高级/星级) |
coachAnalysis.incentive.* |
同 basic | 激励课(结构完全相同) |
每行字段:
level: string — 等级名pay: string — 收入payCompare: string — 收入环比payDown: boolean? — 收入是否下降share: string — 分成shareCompare: string — 分成环比shareDown: boolean? — 分成是否下降hourly: string — 时薪hourlyCompare: string — 时薪环比hourlyFlat: boolean? — 时薪是否持平
筛选参数映射
| 筛选项 | 前端参数 | 后端参数 | 查询影响 |
|---|---|---|---|
| 时间范围 | selectedTime: month/lastMonth/week/lastWeek/quarter3/quarter/lastQuarter/half6 |
time |
决定统计日期区间 |
| 区域筛选 | selectedArea: all/hall/hallA/hallB/hallC/mahjong/teamBuilding |
area |
WHERE 过滤区域;area≠all 时预收资产板块隐藏 |
| 环比开关 | compareEnabled: true/false |
compare: 0/1 |
控制是否返回环比数据 |
时间范围→日期区间映射(后端需实现):
month→ 当月1日 ~ 当月末日lastMonth→ 上月1日 ~ 上月末日week→ 本周一 ~ 本周日lastWeek→ 上周一 ~ 上周日quarter3→ 前3个月(不含本月)quarter→ 本季度第1天 ~ 本季度末日lastQuarter→ 上季度half6→ 最近6个月(不含本月)
目录导航 (sectionNav)
- 6 个板块:经营一览/预收资产/应计收入确认/现金流入/现金流出/助教分析
- 每个板块有 emoji + 标题 + sectionId
- 吸顶头显示当前板块 emoji + 标题 + 描述
- 板块描述(
_sectionDescs):6 段固定文案
帮助图标 (helpTip)
- 7 个指标解释:occurrence/discount/confirmed/cashIn/cashOut/balance/rechargeActual/firstCharge/renewCharge/consume/cardBalance/allCardBalance
- 每个含
title+content(多行文本)
API 契约 vs Mock 数据 vs 八¾节 差异
| 差异项 | API 契约 (BOARD-3) | 前端 Mock (内联 data) | 八¾节 (B3) | 严重度 |
|---|---|---|---|---|
| 响应结构 | 扁平 metrics: Array<{key, label, value, unit, trend, compareValue, sub_items}> |
6 个板块独立对象,深度嵌套结构 | 仅定义了参数,未定义完整响应结构 | 🔴 高 |
| 板块数量 | 未区分板块(单一 metrics 数组) | 6 个独立板块(overview/recharge/revenue/cashflow/expense/coachAnalysis) | 提到 6 个板块但未定义结构 | 🔴 高 |
| 环比数据格式 | trend: 'up'|'down'|'flat' + compareValue?: string |
每个值旁有独立的 xxxCompare 字段(百分比字符串) + isDown/isFlat 布尔标记 |
已确认需补充 compareValue 字段 |
🔴 高 |
| 赠送卡矩阵 | ❌ 完全缺失 | ✅ 3×4 矩阵(24 个字段) | ❌ 未详细定义 | 🔴 高 |
| 收入结构表 | ❌ 缺失 | ✅ 9 行含子行标记 | ❌ 未详细定义 | 🔴 高 |
| 助教分析子表 | ❌ 缺失 | ✅ 基础课+激励课各 4 行(按等级) | ❌ 未详细定义 | 🔴 高 |
| 现金流出 4 子分组 | ❌ 缺失 | ✅ 经营支出/固定支出/助教分成/平台服务费 | ❌ 未详细定义 | 🔴 高 |
time/area/compare 参数 |
八¾节末尾补充了参数定义 | 前端未传参(Bug) | ✅ 已定义 | 🟠 中(八¾节已补充) |
isDown/isFlat 标记 |
❌ 无 | ✅ 有(控制箭头颜色方向) | ❌ 无 | 🟠 中 |
| 帮助图标内容 | ❌ 完全缺失 | ✅ 12 个指标解释 | ❌ 未提及 | 🟡 低 |
spec 未记录的 Gap
- 🔴 BOARD-3 响应结构与前端实际需求完全不匹配 — 契约为扁平 metrics 数组,前端需要 6 个独立板块的深度嵌套结构
- 🔴 赠送卡矩阵(3×4=12 单元 + 12 环比)完全未定义 — 预收资产板块的核心数据
- 🔴 收入结构表(9 行含子行层级)完全未定义 — 应计收入确认板块的核心数据
- 🔴 助教分析子表(基础课+激励课各 4 行按等级)完全未定义
- 🔴 现金流出 4 个子分组(经营/固定/助教分成/平台服务费)完全未定义
- 🔴 环比数据格式不匹配 — 契约仅
trend+compareValue,前端需要每个值旁独立的xxxCompare字段 +isDown/isFlat布尔标记 - 🟠
isDown/isFlat布尔标记未定义 — 前端用于控制环比箭头方向和颜色 - 🟡 帮助图标内容(12 个指标解释文案)未定义 — 可硬编码在前端,但后端可提供配置化
场景 4:跨页面数据关联
4.1 board-coach → coach-detail → customer-detail → customer-service-records
参数传递链:
board-coach点击助教卡片 →coach-detail?id={coachId}coach-detail点击客户卡片 →customer-detail?id={customerId}coach-detail点击任务项 →customer-detail?name={customerName}(⚠️ 用 name 而非 id)customer-detail查看服务记录 →customer-service-records(⚠️ 未传 customerId)coach-detail查看更多服务记录 →performance-records?coachId={coachId}coach-detail问问助手 →chat?coachId={coachId}
跨页面 Gap:
- 🔴 步骤 3 用
name跳转,name 不唯一,应改为id - 🔴 步骤 4 未传
customerId,customer-service-records无法知道查哪个客户 - 🟠
customer-detail的onStartChat未传customerId,chat 页面无法关联客户上下文
4.2 board-customer → customer-detail → chat
参数传递链:
board-customer点击客户卡片 →customer-detail?id={customerId}customer-detail问问助手 →chat(⚠️ 未传参数)
跨页面 Gap:
- 🟠
chat页面无法获取客户上下文(customerId/customerName)
4.3 board-finance → coach-detail 入口
分析结果:
- board-finance 的助教分析板块(coachAnalysis)展示按等级汇总的数据,无跳转到 coach-detail 的入口
- 这是合理的设计 — 财务看板关注的是汇总数据而非个体
汇总 Gap 清单(按严重度排序)
🔴 高严重度(阻塞联调,必须在后端开发前解决)
| # | 类别 | Gap 描述 | 涉及接口 | 涉及页面 |
|---|---|---|---|---|
| G1 | 契约缺陷 | BOARD-3 响应结构与前端完全不匹配 — 契约为扁平 metrics 数组,前端需要 6 个独立板块的深度嵌套结构(overview/recharge/revenue/cashflow/expense/coachAnalysis),含 200+ 个字段 | BOARD-3 | board-finance |
| G2 | 契约缺陷 | BOARD-1 响应字段严重不足 — 契约仅 10 个通用字段,前端需要 20 个含 4 维度专属字段(perf/salary/sv/task),且 skills 类型不匹配(string[] vs Array<{text,cls}>) | BOARD-1 | board-coach |
| G3 | 契约缺陷 | BOARD-2 响应字段严重不足 — 契约仅 8 个通用字段,前端需要 40+ 维度专属字段(8 个维度各有独立字段集),且缺少 assistants 关联助教列表 | BOARD-2 | board-customer |
| G4 | 契约缺陷 | COACH-1 响应缺少多个核心区域 — 缺少 income 收入明细(本月/上月)、historyMonths 历史月份统计、tierNodes 档位节点、备注列表;topCustomers 字段结构不完整(契约 5 字段 vs 前端 10 字段) | COACH-1 | coach-detail |
| G5 | 契约缺陷 | CUST-1 响应缺少管理层核心数据 — 缺少 aiInsight AI 洞察、coachTasks 关联助教任务、favoriteCoaches 喜好助教;消费记录结构严重不匹配(契约扁平 vs 前端嵌套含助教明细) | CUST-1 | customer-detail |
| G6 | 契约缺陷 | BOARD-3 赠送卡矩阵完全未定义 — 预收资产板块的 3×4 矩阵(新增/消费/余额 × 合计/酒水卡/台费卡/抵用券)= 24 个数据字段 + 24 个环比字段 | BOARD-3 | board-finance |
| G7 | 契约缺陷 | BOARD-3 收入结构表完全未定义 — 9 行含子行层级(开台与包厢含 5 个区域子行 + 助教基础课 + 助教激励课 + 食品酒水),每行含 amount/discount/booked/bookedCompare | BOARD-3 | board-finance |
| G8 | 契约缺陷 | BOARD-3 助教分析子表完全未定义 — 基础课+激励课各含汇总行 + 4 个等级行(初级/中级/高级/星级),每行含 pay/share/hourly 及各自环比 | BOARD-3 | board-finance |
| G9 | 契约缺陷 | BOARD-3 现金流出 4 子分组完全未定义 — 经营支出(3项)/固定支出(4项)/助教分成(4项)/平台服务费(3项) | BOARD-3 | board-finance |
| G10 | 契约缺陷 | 环比数据格式不匹配 — 契约仅 trend + compareValue,前端需要每个值旁独立的 xxxCompare 百分比字段 + isDown/isFlat 布尔标记 |
BOARD-3 | board-finance |
| G11 | 前端 Bug | customer-detail 跳转 customer-service-records 未传 customerId — 服务记录页无法知道查哪个客户 | CUST-2 | customer-detail → customer-service-records |
| G12 | 前端 Bug | coach-detail 任务项跳转用 name 而非 id — onTaskItemTap 传 name={customerName},name 不唯一 |
— | coach-detail → customer-detail |
| G13 | 类型不匹配 | api.ts 中 fetchCoachDetail 返回类型为 CoachCard — 实际需要完整的 CoachDetail(含 performance/income/tasks/topCustomers/serviceRecords/historyMonths/notes),类型定义严重不足 | COACH-1 | coach-detail |
| G14 | 类型不匹配 | mock-data.ts 中的类型与页面内联 mock 完全脱节 — BoardFinanceData 仅含 4 个 metrics,实际页面需要 6 个板块 200+ 字段;CustomerCard/CoachCard 过于简单 | 全部看板 | 全部看板页 |
🟠 中严重度(影响功能完整性,联调前需解决)
| # | 类别 | Gap 描述 | 涉及接口 | 涉及页面 |
|---|---|---|---|---|
| G15 | 契约缺陷 | BOARD-1 sort 参数格式不一致 — 契约用 field:direction,前端用枚举值 perf_desc |
BOARD-1 | board-coach |
| G16 | 契约缺陷 | BOARD-1/2 缺少 initial/avatarGradient/avatarCls 字段 — 前端用于头像渲染,需确认由前端计算还是后端返回 | BOARD-1/2 | board-coach/board-customer |
| G17 | 契约缺陷 | CUST-1 缺少 balance/consumption60d/idealInterval/daysSinceVisit — 客户详情页头部展示的核心指标 | CUST-1 | customer-detail |
| G18 | 契约缺陷 | CUST-1 维客线索结构不匹配 — 契约用 tag/tag_color/emoji/text/source/desc,前端用 category/categoryColor/text/source/detail | CUST-1 | customer-detail |
| G19 | 契约缺陷 | CUST-1 缺少备注列表 — 客户详情页展示关联备注 | CUST-1 | customer-detail |
| G20 | 契约缺陷 | COACH-1 缺少备注列表 — 助教详情页展示关联备注 | COACH-1 | coach-detail |
| G21 | 契约缺陷 | CUST-2 缺少月度统计汇总 — 前端需要 monthCount/monthHours,当前本地计算 | CUST-2 | customer-service-records |
| G22 | 契约缺陷 | BOARD-3 isDown/isFlat 布尔标记未定义 — 前端用于控制环比箭头方向和颜色 | BOARD-3 | board-finance |
| G23 | 前端 Bug | customer-detail 的 onStartChat 未传 customerId — chat 页面无法关联客户上下文 | CHAT | customer-detail → chat |
| G24 | 前端 Bug | customer-detail 的 loadDetail() 中 id 解析方式有 Bug — 应从 onLoad(options) 获取,而非 __route__ 解析 |
CUST-1 | customer-detail |
| G25 | 设计缺陷 | BOARD-2 potentialTags 标签结构契约缺失 — potential 维度展示客户潜力标签(含 text+theme) | BOARD-2 | board-customer |
| G26 | 设计缺陷 | COACH-1 tierNodes/maxHours 缺失 — 绩效进度条组件需要档位节点数据,当前硬编码 [0, 100, 130, 160, 190, 220] |
COACH-1 | coach-detail |
🟡 低严重度(不阻塞联调,可后续优化)
| # | 类别 | Gap 描述 | 涉及接口 | 涉及页面 |
|---|---|---|---|---|
| G27 | 设计决策 | BOARD-1 无分页定义 — 当前全量返回,助教数量少(<50)可接受 | BOARD-1 | board-coach |
| G28 | 设计决策 | BOARD-3 帮助图标内容未定义 — 12 个指标解释文案,可硬编码在前端 | BOARD-3 | board-finance |
| G29 | 设计决策 | customer-service-records 首次加载全量 vs 按月分页 — 数据量小时可接受,量大时需改为按月请求 | CUST-2 | customer-service-records |
| G30 | 类型不匹配 | mock-data.ts ConsumptionRecord 结构过于简单 — 仅 6 个字段,customer-detail 内联 mock 有 16 个字段(含嵌套 coaches 数组) | CUST-1 | customer-detail |
| G31 | 契约缺陷 | CUST-2 tables 台桌列表 — 契约定义了但前端未使用(前端模拟台号) | CUST-2 | customer-service-records |
行动建议
优先级 1:更新 API 契约(阻塞后端开发)
以下接口的契约需要完全重写,以匹配前端实际需求:
- BOARD-3 财务看板 — 从扁平 metrics 改为 6 板块嵌套结构,补充赠送卡矩阵、收入结构表、助教分析子表、现金流出子分组的完整字段定义
- BOARD-1 助教看板 — 从 10 个通用字段扩展为 20 个含 4 维度专属字段,修正 skills 类型,补充 topCustomers
- BOARD-2 客户看板 — 从 8 个通用字段扩展为 40+ 维度专属字段,补充 assistants/weeklyVisits/coachDetails/potentialTags
- COACH-1 助教详情 — 补充 income/historyMonths/tierNodes/备注列表,扩展 topCustomers 字段
- CUST-1 客户详情 — 补充 aiInsight/coachTasks/favoriteCoaches/备注列表,重写消费记录为嵌套结构
优先级 2:修复前端 Bug(联调前必须完成)
- G11: customer-detail → customer-service-records 传 customerId
- G12: coach-detail onTaskItemTap 改用 id 而非 name
- G23: customer-detail → chat 传 customerId
- G24: customer-detail loadDetail() 修复 id 解析
- F1-F6: 看板筛选变更触发重新请求(八¾节已记录)
优先级 3:统一 mock-data.ts 类型定义
当前 mock-data.ts 中的类型(BoardFinanceData/CustomerCard/CoachCard/CustomerDetail)与页面内联 mock 数据严重脱节。建议:
- 将页面内联的完整接口定义(CoachItem/CustomerItem/CoachDetail 等)提取到
mock-data.ts或独立的types.ts - 更新
api.ts中各函数的返回类型 - 确保类型定义与更新后的 API 契约一致