task-list 页面数据来源排查
排查日期:2026-03-18
页面路径:pages/task-list/task-list
引用文件:utils/mock-data.ts、utils/money.ts、utils/time.ts、utils/request.ts(未使用)
概览
| 分类 |
数量 |
说明 |
| Mock 数据 |
28 个字段 |
全部任务列表 + 业绩进度卡片均来自 mock |
| 硬编码数据 |
12 个字段 |
用户信息、头像、动画参数、AI 建议文案等 |
| 已对接 API |
0 个接口 |
页面当前无任何真实 API 调用 |
| 前端计算/派生 |
14 个字段 |
enrichTask 派生字段 + 进度条动画计算 |
| 路由参数 |
0 个 |
onLoad 未读取 options |
| WXML 硬编码文案 |
5 处 |
标题、分组标签等 UI 文案 |
一、Mock 数据
1.1 来自 mock-data.ts
1.1.1 mockTasks — 任务列表主数据
| 字段 |
类型 |
说明 |
联调替换 API |
id |
string |
任务 ID |
GET /api/xcx/tasks |
customerName |
string |
客户姓名 |
同上 |
customerAvatar |
string |
客户头像 URL |
同上 |
taskType |
TaskType |
任务类型枚举:callback / priority_recall / relationship / high_priority |
同上 |
taskTypeLabel |
string |
任务类型中文标签 |
同上(或前端根据 taskType 映射) |
deadline |
string |
截止日期 ISO 字符串 |
同上 |
heartScore |
number |
爱心评分 0-10 |
同上 |
hobbies |
string[] |
客户爱好标签 |
同上 |
isPinned |
boolean |
是否置顶 |
同上 |
hasNote |
boolean |
是否有备注 |
同上 |
status |
'pending' | 'completed' | 'abandoned' |
任务状态 |
同上 |
- 导入方式:
import { mockTasks } from '../../utils/mock-data'(task-list.ts L2)
loadData() 中直接展开 mockTasks 并追加了一条内联 mock 任务 task-007(见 1.2 节)
1.1.2 mockPerformance — 绩效概览数据
| 字段 |
类型 |
当前 Mock 值 |
联调替换 API |
monthlyIncome |
number |
12680 |
GET /api/xcx/performance/summary |
incomeChange |
number |
15.3 |
同上 |
currentTier |
string |
'银牌助教' |
同上 |
nextTierGap |
number |
3320 |
同上 |
todayServiceCount |
number |
4 |
同上 |
weekServiceCount |
number |
18 |
同上 |
monthServiceCount |
number |
67 |
同上 |
- 导入方式:
import { mockPerformance } from '../../utils/mock-data'(task-list.ts L2)
- 当前仅用
mockPerformance.currentTier 赋值给 bannerTitle(L233)
1.2 页面内联 Mock
1.2.1 task-007 内联任务(loadData 内,约 L213-L225)
1.2.2 buildPerfData() — 业绩进度卡片构造函数(约 L130-L160)
| 字段 |
Mock 值 |
说明 |
联调替换 API |
nextTierHours |
100 |
下一档位小时数 |
GET /api/xcx/performance/progress |
remainHours |
12.5 |
距下一档剩余小时 |
同上 |
currentTier |
1 |
当前档位序号 |
同上 |
tierProgress |
58 |
当前段内进度% |
同上(或前端计算) |
filledPct |
39.8(87.5/220×100) |
总进度条百分比 |
同上(或前端计算) |
ticks |
buildTicks([0,100,130,160,190,220], 220) |
刻度数组 |
同上(档位节点由接口返回) |
basicHours |
'77.5' |
基础课时 |
同上 |
bonusHours |
'12' |
激励课时 |
同上 |
totalHours |
'87.5' |
总课时 |
同上 |
tierCompleted |
true |
是否达标 |
同上 |
bonusMoney |
'800' |
达标奖金(元) |
同上 |
incomeMonth |
'2月' |
收入月份 |
同上 |
prevMonth |
'1月' |
对比月份 |
同上 |
incomeFormatted |
'6,206' |
预计收入格式化 |
同上 |
incomeTrend |
'↓368' |
收入趋势文案 |
同上 |
incomeTrendDir |
'down' |
趋势方向 |
同上 |
1.2.3 enrichTask() 内联 Mock 逻辑(约 L100-L125)
| 派生字段 |
Mock 算法 |
说明 |
lastVisitDays |
(id.charCodeAt(last) % 15) + 1 |
伪随机天数,联调时应由 API 返回 |
balanceLabel |
formatMoney((id.charCodeAt(last) * 137) % 5000 + 200) |
伪随机余额,联调时应由 API 返回 |
aiSuggestion |
从 5 条硬编码文案中按 id 取模选取 |
联调时应由 AI 接口返回 |
5 条硬编码 AI 建议文案:
'建议推荐斯诺克进阶课程,提升客户粘性'
'客户近期消费下降,建议电话关怀了解原因'
'适合推荐周末球友赛活动,增强社交体验'
'高价值客户,建议维护关系并推荐VIP权益'
'新客户首次体验后未续费,建议跟进意向'
1.2.4 loadData() 中的 600ms 模拟延迟
二、硬编码数据
| 字段 |
当前值 |
应改为 |
风险 |
所在位置 |
userName |
'小燕' |
globalData.userInfo.name 或登录 API |
高 |
data 初始化 |
userRole |
'助教' |
globalData.userInfo.role 或登录 API |
高 |
data 初始化 |
storeName |
'广州朗朗桌球' |
globalData.storeInfo.name 或登录 API |
高 |
data 初始化 |
avatarUrl |
'/assets/images/avatar-coach.png' |
globalData.userInfo.avatar 或登录 API |
中 |
data 初始化 |
DETAIL_ROUTE |
'/pages/task-detail/task-detail' |
保持硬编码(路由常量) |
低 |
常量定义 |
tierNodes |
[0, 100, 130, 160, 190, 220] |
业绩进度 API 返回 |
高 |
buildPerfData() + _applyDebugHours() |
maxHours |
220 |
业绩进度 API 返回 |
高 |
buildPerfData() |
total |
87.5 |
业绩进度 API 返回 |
高 |
buildPerfData() |
aiColor |
随机选取 ['red','orange','yellow','blue','indigo','purple'] |
可保持前端随机(纯 UI) |
低 |
onLoad() / onShow() |
abandonReason |
'客户已转至其他门店' |
API 返回(放弃原因由用户输入) |
中 |
enrichTask() |
suggestions[] |
5 条固定文案 |
AI 建议 API 返回 |
高 |
enrichTask() |
hasMore |
true → 触底后 false |
分页 API 返回 has_next |
中 |
loadData() / onReachBottom() |
三、已对接 API
当前页面无任何真实 API 调用。
utils/request.ts 已导出 request() 函数(支持 token 自动附加、401 刷新重试)
- task-list.ts 未 import
request,所有数据均来自 mock
四、前端计算/派生数据
4.1 任务分组(loadData 内)
| 派生字段 |
计算逻辑 |
依赖源数据 |
pinnedTasks |
enriched.filter(t => t.isPinned && !t.isAbandoned) |
allTasks |
normalTasks |
enriched.filter(t => !t.isPinned && !t.isAbandoned && t.status === 'pending') |
allTasks |
abandonedTasks |
enriched.filter(t => t.isAbandoned) |
allTasks |
taskCount |
pinnedTasks.length + normalTasks.length + abandonedTasks.length |
三组任务 |
pageState |
totalCount > 0 ? 'normal' : 'empty' |
taskCount |
4.2 enrichTask 派生字段
| 派生字段 |
计算逻辑 |
依赖 |
isAbandoned |
task.status === 'abandoned' |
task.status |
deadlineLabel |
formatDeadline(task.deadline).text |
task.deadline + utils/time.ts |
deadlineStyle |
formatDeadline(task.deadline).style |
task.deadline + utils/time.ts |
balanceLabel |
formatMoney(balanceSeedNum) |
Mock 种子值 + utils/money.ts(联调后改为 API 余额) |
4.3 进度条动画计算
| 派生字段 |
计算逻辑 |
依赖 |
filledPct |
Math.min(100, (total / 220) * 100) |
total、maxHours |
clampedSparkPct |
Math.max(0, Math.min(100, filledPct)) |
filledPct |
shineDurMs |
calcShineDur(filledPct) — 基于 SHINE_SPEED 和进度百分比 |
filledPct、SHINE_SPEED |
ticks[] |
buildTicks(tierNodes, maxHours) — 计算每个刻度的 left 百分比位置 |
tierNodes、maxHours |
4.4 调试面板计算(_applyDebugHours)
| 派生字段 |
说明 |
currentTier |
遍历 tiers 数组确定当前档位 |
tierProgress |
当前段内进度百分比 |
remainHours |
nextTierHours - total |
tierCompleted |
total >= 220 |
调试面板仅开发阶段使用,联调时可保留或移除。
五、路由参数
onLoad() 未读取任何 options 参数。页面作为 TabBar 页面,不接收路由参数。
六、WXML 中的硬编码文案
| 文案 |
位置 |
类型 |
说明 |
'今日 客户维护' |
section-header |
UI 文案 |
可保持硬编码,或由 API 返回标题 |
'📌 置顶' |
group-label--pinned |
UI 文案 |
保持硬编码 |
'正常任务' |
group-label--normal |
UI 文案 |
保持硬编码 |
'已放弃' |
group-label--abandoned |
UI 文案 |
保持硬编码 |
'暂无待办任务' |
state-empty |
UI 文案 |
保持硬编码 |
'加载失败,请重试' |
state-error |
UI 文案 |
保持硬编码 |
'没有更多了' |
load-more |
UI 文案 |
保持硬编码 |
'最近到店:{{...}}天前 · 余额:{{...}}' |
card-row-2 |
模板文案 |
保持硬编码(数据部分由变量填充) |
'放弃原因:{{...}}' |
card-row-abandon |
模板文案 |
保持硬编码 |
'基础课 | 激励课 | 全部' |
hours-label |
UI 文案 |
保持硬编码 |
以上均为 UI 展示文案,非业务数据硬编码,联调时无需替换。
七、联调 TODO
高优先(P0 — 页面核心功能)
中优先(P1 — 交互完整性)
低优先(P2 — 可后续处理)
八、依赖组件清单
| 组件 |
路径 |
数据来源 |
perf-progress-bar |
/components/perf-progress-bar/ |
接收 perfData.* 属性(全部 mock) |
heart-icon |
/components/heart-icon/ |
接收 item.heartScore(mock) |
ai-inline-icon |
/components/ai-inline-icon/ |
接收 aiColor(前端随机) |
ai-float-button |
/components/ai-float-button/ |
无数据依赖 |
note-modal |
/components/note-modal/ |
接收 noteTarget.customerName(mock) |
abandon-modal |
/components/abandon-modal/ |
接收 abandonTarget.customerName(mock) |
dev-fab |
/components/dev-fab/ |
无数据依赖(开发工具) |
t-icon |
TDesign 组件 |
无业务数据依赖 |
九、风险总结
| 风险项 |
等级 |
说明 |
| 全页面零 API 调用 |
🔴 高 |
联调时需一次性替换所有数据源,工作量集中 |
| 用户信息硬编码 |
🔴 高 |
userName/userRole/storeName 写死,多用户场景必崩 |
| AI 建议文案固定 |
🔴 高 |
5 条文案轮转,联调时需对接 AI 服务 |
| 业绩进度全量 mock |
🔴 高 |
档位、课时、收入全部硬编码,数值与真实数据无关 |
| 分页未实现 |
🟡 中 |
onReachBottom 仅显示"没有更多了",无真实分页 |
| 操作无持久化 |
🟡 中 |
置顶/放弃/备注仅修改本地 data,刷新即丢失 |
enrichTask 伪随机 |
🟡 中 |
lastVisitDays/balanceLabel 由 id 字符码计算,非真实数据 |