# board-coach 页面数据来源排查 > 排查日期:2026-03-18 > 页面路径:pages/board-coach/board-coach > 排查范围:board-coach.ts / board-coach.wxml / board-coach.wxss / board-coach.json + 引用工具函数 ## 概览 | 分类 | 数量 | 说明 | |------|------|------| | A. Mock 数据 | 1 组(6 条记录,含 ~20 个字段/条) | 页面内联 `MOCK_COACHES` 数组,未引用 `utils/mock-data.ts` | | B. 硬编码数据 | 6 组常量 + 3 个默认值 | 排序/技能/时间选项、等级/技能样式映射、默认筛选值 | | C. 已对接 API | 0 | 全部数据来自 Mock,无任何 `wx.request` / service 调用 | | D. 前端计算/派生数据 | 10 个派生字段 | `loadData()` 中通过 `formatMoney`/`formatHours`/`formatCount` 生成展示标签 | | E. 路由参数 | 0 | `onLoad()` 未读取任何 query 参数 | | F. WXML 硬编码文案 | 14 处 | Tab 标签、状态提示、维度标签等 | --- ## 一、Mock 数据 ### 1.1 页面内联 Mock:`MOCK_COACHES`(board-coach.ts L82-L161) 页面顶部定义了 `const MOCK_COACHES: CoachItem[]`,包含 6 位助教的完整数据。`loadData()` 通过 `setTimeout(400ms)` 模拟异步加载后直接使用该数组。 **未引用** `utils/mock-data.ts` 中的 `mockCoaches`(该文件有独立的 `CoachCard` 接口和 3 条记录,字段结构不同)。 | Mock 字段 | 类型 | 示例值 | 联调时应替换为 | |-----------|------|--------|---------------| | `id` | string | `'c1'` | API 返回的助教 ID | | `name` | string | `'小燕'` | 助教姓名 | | `initial` | string | `'小'` | 前端根据 name 首字计算,或 API 返回头像 URL | | `avatarGradient` | string | `'blue'` | API 返回头像 URL 后可移除,改用真实头像 | | `level` | string | `'star'` | 助教等级(API:`star/senior/middle/junior`) | | `skills` | Array | `[{text:'🎱', cls:'skill--chinese'}]` | API 返回技能列表,前端映射 cls | | `topCustomers` | string[] | `['💖 王先生','💖 李女士']` | API 返回 top 客户列表(含亲密度标记) | | `perfHours` | number | `86.2` | 定档业绩课时(API 聚合) | | `perfHoursBefore` | number? | `92.0` | 折前课时(API 聚合) | | `perfGap` | string? | `'距升档 13.8h'` | 可由前端计算或 API 直接返回 | | `perfReached` | boolean | `false` | 是否已达标(API 或前端判断) | | `salary` | number | `12680` | 预估工资(API 聚合) | | `salaryPerfHours` | number | `86.2` | 工资维度-定档课时 | | `salaryPerfBefore` | number? | `92.0` | 工资维度-折前课时 | | `svAmount` | number | `45200` | 客源储值金额(API 聚合) | | `svCustomerCount` | number | `18` | 储值客户数 | | `svConsume` | number | `8600` | 储值消耗金额 | | `taskRecall` | number | `18` | 召回任务完成数 | | `taskCallback` | number | `14` | 回访任务完成数 | **联调替换目标 API**(待后端提供): ``` GET /api/v1/board/coach/list Query: sort={selectedSort}&skill={selectedSkill}&time={selectedTime} Response: { coaches: CoachItem[] } ``` --- ## 二、硬编码数据 ### 2.1 筛选选项常量(board-coach.ts L14-L50) | 常量名 | 字段数 | 风险 | 说明 | |--------|--------|------|------| | `SORT_OPTIONS` | 6 项 | 🟡 中 | 排序维度选项,value/text 写死。若后端新增排序维度需同步修改 | | `SKILL_OPTIONS` | 5 项 | 🟡 中 | 技能筛选选项,含 emoji。若门店技能类型可配置则需改为 API 获取 | | `TIME_OPTIONS` | 6 项 | 🟢 低 | 时间范围选项,纯前端逻辑,变动概率低 | | `SORT_TO_DIM` | 6 项映射 | 🟢 低 | 排序值→维度类型映射,纯前端 UI 逻辑 | ### 2.2 样式映射常量(board-coach.ts L53-L68) | 常量名 | 风险 | 说明 | |--------|------|------| | `LEVEL_CLASS` | 🟢 低 | 等级→CSS 类映射,含中英文 key 兼容。纯前端样式逻辑 | | `SKILL_CLASS` | 🟢 低 | 技能 emoji→CSS 类映射。纯前端样式逻辑 | ### 2.3 data 对象默认值(board-coach.ts L165-L180) | 字段 | 硬编码值 | 风险 | 说明 | |------|----------|------|------| | `selectedSort` | `'perf_desc'` | 🟢 低 | 默认排序,合理默认值 | | `selectedSkill` | `'all'` | 🟢 低 | 默认不限技能 | | `selectedTime` | `'month'` | 🟢 低 | 默认本月 | | `dimType` | `'perf'` | 🟢 低 | 默认维度类型,与 selectedSort 联动 | | `filterBarVisible` | `true` | 🟢 低 | 筛选栏初始可见 | | `pageState` | `'loading'` | 🟢 低 | 页面初始状态 | | `activeTab` | `'coach'` | 🟢 低 | 当前 Tab 标识 | ### 2.4 `loadData()` 中的模拟延迟(board-coach.ts L195) ```typescript setTimeout(() => { ... }, 400) // 🔴 高风险:联调时必须替换为真实 API 调用 ``` ### 2.5 `onPullDownRefresh` 中的延迟(board-coach.ts L192) ```typescript setTimeout(() => wx.stopPullDownRefresh(), 500) // 🟡 中风险:联调后应在 API 回调中停止 ``` --- ## 三、已对接 API **无。** 当前页面 0 个 API 调用,全部数据来自页面内联 Mock。 页面中存在的导航跳转(非数据 API): - `wx.switchTab({ url: '/pages/board-finance/board-finance' })` — Tab 切换 - `wx.navigateTo({ url: '/pages/board-customer/board-customer' })` — Tab 切换 - `wx.navigateTo({ url: '/pages/coach-detail/coach-detail?id=' + id })` — 助教详情跳转 --- ## 四、前端计算/派生数据 ### 4.1 `loadData()` 中的格式化派生字段(board-coach.ts L197-L208) | 派生字段 | 源字段 | 格式化函数 | 输出示例 | |----------|--------|-----------|----------| | `perfHoursLabel` | `perfHours` | `formatHours()` | `'86.2h'` | | `perfHoursBeforeLabel` | `perfHoursBefore` | `formatHours()` | `'92h'` | | `salaryLabel` | `salary` | `formatMoney()` | `'¥12,680'` | | `salaryPerfHoursLabel` | `salaryPerfHours` | `formatHours()` | `'86.2h'` | | `salaryPerfBeforeLabel` | `salaryPerfBefore` | `formatHours()` | `'92h'` | | `svAmountLabel` | `svAmount` | `formatMoney()` | `'¥45,200'` | | `svCustomerCountLabel` | `svCustomerCount` | `formatCount(n,'人')` | `'18人'` | | `svConsumeLabel` | `svConsume` | `formatMoney()` | `'¥8,600'` | | `taskRecallLabel` | `taskRecall` | `formatCount(n,'次')` | `'18次'` | | `taskCallbackLabel` | `taskCallback` | `formatCount(n,'次')` | `'14次'` | ### 4.2 维度类型切换(board-coach.ts L218-L222) `onSortChange` 根据 `SORT_TO_DIM` 映射计算 `dimType`,控制 WXML 中四种卡片模板的条件渲染。 ### 4.3 滚动隐藏/显示筛选栏(board-coach.ts L196-L215 `onPageScroll`) 纯前端交互逻辑:累积滚动距离超过阈值(上滑 12px / 下滑 24px)时切换 `filterBarVisible`。 --- ## 五、路由参数 **无。** `onLoad()` 未接收任何 `options` 参数。 --- ## 六、WXML 硬编码文案 | 位置 | 硬编码文案 | 风险 | 建议 | |------|-----------|------|------| | 加载态 | `加载中...` | 🟢 低 | 通用文案,可保留 | | 空状态 | `暂无助教数据` | 🟢 低 | 可保留 | | 错误态 | `加载失败` | 🟢 低 | 可保留 | | 重试按钮 | `点击重试` | 🟢 低 | 可保留 | | Tab-财务 | `财务` | 🟢 低 | 固定 Tab 文案 | | Tab-客户 | `客户` | 🟢 低 | 固定 Tab 文案 | | Tab-助教 | `助教` | 🟢 低 | 固定 Tab 文案 | | 定档维度标签 | `定档` / `折前` | 🟢 低 | 业务术语,可保留 | | 工资维度标签 | `预估` | 🟢 低 | 业务术语 | | 储值维度标签 | `储值` | 🟢 低 | 业务术语 | | 召回维度标签 | `召回` | 🟢 低 | 业务术语 | | 达标标记 | `✅ 已达标` | 🟢 低 | 可保留 | | 工资底部 | `定档` / `折前` | 🟢 低 | 同上 | | 储值底部 | `客户` / `消耗` / `\|` 分隔符 | 🟢 低 | 业务术语 | | 任务底部 | `回访` | 🟢 低 | 业务术语 | | 导航栏标题 | `助教看板`(board-coach.json) | 🟢 低 | 固定页面标题 | --- ## 七、引用组件清单 | 组件 | 来源 | 数据依赖 | |------|------|----------| | `coach-level-tag` | 自定义组件 | 接收 `level` 属性 | | `filter-dropdown` | 自定义组件 | 接收 `label`/`options`/`value`,触发 `change` 事件 | | `ai-float-button` | 自定义组件 | 无数据依赖 | | `board-tab-bar` | 自定义 Tab Bar | 接收 `active="board"` | | `t-loading` / `t-empty` | TDesign 组件 | 无业务数据依赖 | | `dev-fab` | 开发调试组件 | `wx:if="{{false}}"` 已禁用 | --- ## 八、联调 TODO ### 🔴 P0 — 必须完成 - [ ] **替换 `MOCK_COACHES` 为 API 调用**:移除页面内联 Mock 数组,`loadData()` 改为调用后端接口 - 需后端提供:助教列表接口(含排序/技能/时间筛选参数) - 接口需返回:四种维度的全部字段(perf/salary/sv/task) - 错误处理:API 失败时 `setData({ pageState: 'error' })` - [ ] **移除 `setTimeout(400ms)` 模拟延迟**:替换为真实异步请求 - [ ] **`onPullDownRefresh` 改为 API 回调中停止**:`wx.stopPullDownRefresh()` 应在请求完成后调用 ### 🟡 P1 — 建议完成 - [ ] **筛选联动 API**:当前 `onSortChange`/`onSkillChange`/`onTimeChange` 仅更新本地状态,未触发重新请求。联调时需在筛选变更后重新调用 API - [ ] **头像方案确认**:当前使用 `initial`(首字)+ `avatarGradient`(渐变色)模拟头像。确认是否改为真实头像 URL - [ ] **`perfGap` 字段来源确认**:当前为 Mock 字符串(如 `'距升档 13.8h'`),确认由后端计算还是前端根据阈值计算 - [ ] **`topCustomers` 格式确认**:当前含 emoji 亲密度标记(💖/💛),确认 API 返回格式 ### 🟢 P2 — 可后续优化 - [ ] **`SKILL_OPTIONS` 是否需要动态获取**:若门店技能类型可配置,应改为 API 获取 - [ ] **`SORT_OPTIONS` / `TIME_OPTIONS` 是否需要后端控制**:当前写死,若需动态调整需改为配置化 - [ ] **清理 `utils/mock-data.ts` 中的 `CoachCard` 接口**:与页面内联 `CoachItem` 接口不一致,联调完成后统一或移除 - [ ] **`levelClass` 字段**:当前在 Mock 中预计算,联调后应由前端根据 `level` 字段通过 `LEVEL_CLASS` 映射生成