Files
Neo-ZQYY/docs/miniprogram-dev/api-audit/task-detail.md

14 KiB
Raw Blame History

task-detail 页面数据来源排查

排查日期2026-03-18 页面路径pages/task-detail/task-detail

概览

分类 数量 说明
Mock 数据 12 个字段 来自 mock-data.tsmockTaskDetails + 页面内联 mock 备注
硬编码数据 18 个字段/数组 维客线索、话术参考、服务记录、服务汇总、手机号、储值等级等
已对接 API 0 个接口 当前无任何真实 API 调用
前端计算/派生 7 个字段 关系等级、Banner 背景、AI 配色、时间标签等
路由参数 1 个 id(任务 ID
WXML 硬编码文案 6 处 建议文案、section 标题等

一、Mock 数据

1.1 来自 mock-data.tsmockTaskDetails

页面通过 import { mockTaskDetails } from '../../utils/mock-data' 引入,在 loadData() 中使用 setTimeout 模拟异步加载。

字段 类型 来源路径 联调替换 API
detail(整体) TaskDetail mockTaskDetails.find(t => t.id === id) || mockTaskDetails[0] GET /api/tasks/{id}
detail.id string TaskDetail.id 同上
detail.customerName string TaskDetail.customerName 同上
detail.customerAvatar string TaskDetail.customerAvatar 同上
detail.taskType TaskType TaskDetail.taskType'callback' | 'priority_recall' | 'relationship' | 'high_priority' 同上
detail.taskTypeLabel string TaskDetail.taskTypeLabel 同上
detail.heartScore number TaskDetail.heartScore 同上
detail.status 'pending' | 'completed' | 'abandoned' TaskDetail.status 同上
detail.aiAnalysis.summary string TaskDetail.aiAnalysis.summary GET /api/tasks/{id}/ai-analysis
detail.aiAnalysis.suggestions string[] TaskDetail.aiAnalysis.suggestions 同上
detail.hobbies string[] TaskDetail.hobbies GET /api/tasks/{id}
detail.deadline string TaskDetail.deadline 同上

mock-data.ts 中 TaskDetail 扩展字段(已定义但页面未直接渲染):

字段 类型 说明
lastVisitDate string? 最后到店日期,页面未使用
lastSpendAmount number? 最后消费金额,页面未使用
callbackReason string? 回访原因,页面未使用
daysAbsent number? 缺席天数,页面未使用
spendTrend 'up' | 'down' | 'flat'? 消费趋势,页面未使用
churnRisk 'high' | 'medium' | 'low'? 流失风险,页面未使用
preferences string[]? 偏好,页面未使用
consumptionHabits string? 消费习惯,页面未使用
socialPreference string? 社交偏好,页面未使用

1.2 页面内联 Mock 备注

loadData() 方法内部硬编码了 5 条 mock 备注(mockNotes 局部变量L107-L113覆盖了 mockTaskDetails 中的 notes 字段:

字段 当前值 联调替换 API
mockNotes[0] '已通过微信联系王先生...'score=10 GET /api/tasks/{id}/notes
mockNotes[1] '王先生最近出差较多...'score=7.5 同上
mockNotes[2] '上次到店时推荐了会员续费活动...'score=6 同上
mockNotes[3] '客户对今天的服务非常满意...'score=9.5 同上
mockNotes[4] '完成高优先召回任务...'score=8 同上

二、硬编码数据

2.1 维客线索(retentionClues

风险:高 — 8 条完整的维客线索数据直接写死在 data 对象中L68-L77应从 API 获取。

索引 tag text摘要 source 所在行 应改为
0 客户基础 '生日 3月15日 · VIP会员 · 注册2年' By:系统 L69 GET /api/tasks/{id}/retention-clues
1 消费习惯 '常来夜场 · 月均4-5次' By:系统 L70 同上
2 消费习惯 '高客单价'(含 desc By:系统 L71 同上
3 玩法偏好 '偏爱中式八球 · 斯诺克进阶中...'(含 desc By:系统 L72 同上
4 重要反馈 '上次提到想练斯诺克走位'(含 desc By:小燕 L73 同上
5 社交偏好 '喜欢带朋友来玩 · 社交型客户'(含 desc By:系统 L74 同上
6 消费习惯 '酒水消费占比高 · 偏好高端酒水'(含 desc By:系统 L75 同上
7 重要反馈 '上次提到想办生日派对'(含 desc By:Lucy L76 同上

注意:mock-data.ts 中已定义 mockRetentionCluesRetentionClue 接口,但页面未使用,而是自行硬编码了不同结构的数据。联调时应统一数据结构。

2.2 话术参考(talkingPoints

风险:高 — 5 条话术直接写死在 data 对象中L80-L86应由 AI 生成或从 API 获取。

索引 内容摘要 所在行 应改为
0 '王哥您好,好久不见!最近店里新到了...' L81 GET /api/tasks/{id}/talking-points 或 AI 生成接口
1 '王哥,最近忙吗?这周末我们有个...' L82 同上
2 '王哥好呀,上次您提到想练练...' L83 同上
3 '王哥,好久没见您了,您的老位置...' L84 同上
4 '王哥您好,我们这个月推出了...' L85 同上

2.3 近期服务记录(serviceRecords

风险:高 — 4 条服务记录直接写死在 data 对象中L91-L96应从 API 获取。

索引 table type income date 所在行 应改为
0 A12号台 基础课 ¥200 2月7日 21:30 L92 GET /api/tasks/{id}/service-records
1 3号台 基础课 ¥160 2月1日 20:30 L93 同上
2 VIP1号房 包厢课 ¥150 1月28日 19:00 L94 同上
3 (空) 充值 ¥80 1月15日 10:00 L95 同上

2.4 服务汇总(serviceSummary

风险:高 — 汇总数据直接写死L90应由后端计算或前端根据服务记录列表聚合。

字段 当前值 所在行 应改为
totalHours 6.0 L90 后端返回或前端聚合 serviceRecords
totalIncome 510 L90 同上
avgIncome 170 L90 同上

2.5 手机号

风险:高 — 手机号硬编码在两处。

位置 当前值 所在行 应改为
WXML 中 phone 显示 '138****5678'(脱敏)/ '13812345678'(明文) wxml L38 detail 对象获取API 返回脱敏版
onCopyPhone() 方法 '13812345678' ts L175 调用 API 获取明文手机号 GET /api/customers/{id}/phone

2.6 储值等级

风险:中 — 直接写死在 data 中。

字段 当前值 所在行 应改为
storageLevel '非常多' ts L101 detail 或客户信息 API 获取

2.7 关系等级初始值

风险:低 — 初始值会被 updateRelationshipDisplay() 覆盖,但仍属于硬编码。

字段 当前值 所在行 说明
relationLevel 'excellent' ts L104 初始值,loadData 后被覆盖
relationLevelText '很好' ts L105 同上
relationColor '#e91e63' ts L106 同上

2.8 任务建议文案

风险:中 — WXML 中硬编码了建议引导文案。

位置 当前值 所在行 应改为
suggestion-intro '该客户已有 15 天未到店,存在流失风险。建议通过微信联系:' wxml L82 detail.aiAnalysis 获取或后端生成

三、已对接 API

当前无任何真实 API 调用。

loadData() 使用 setTimeout + mockTaskDetails 模拟异步请求L128-L155。所有数据操作放弃任务、保存备注、删除备注均为本地 setData 操作,未与后端通信。

涉及的伪操作:

操作 当前实现 需对接 API
加载任务详情 mockTaskDetails.find() GET /api/tasks/{id}
放弃任务 setData({ 'detail.status': 'abandoned' }) POST /api/tasks/{id}/abandon
取消放弃 setData({ 'detail.status': 'pending' }) POST /api/tasks/{id}/cancel-abandon
保存备注 setData({ sortedNotes: [...] }) POST /api/tasks/{id}/notes
删除备注 filter 本地数组 DELETE /api/tasks/{id}/notes/{noteId}

四、前端计算/派生数据

字段 计算逻辑 所在方法 依赖数据
relationLevel heartScore 分段映射:>8.5→excellent, ≥6→good, ≥3.5→normal, <3.5→poor updateRelationshipDisplay() L157 detail.heartScore
relationLevelText 同上分段映射为中文:很好/良好/一般/待发展 同上 同上
relationColor 同上分段映射为颜色值 同上 同上
bannerBgSvg 根据 detail.taskType 映射 SVG 路径 loadData() L133-L142 detail.taskType
sortedNotes mockNotes → 附加 timeLabelformatRelativeTime)→ sortByTimestamp 排序 loadData() L116-L118 mock 备注数据
aiColor 随机从 6 色中选取 onLoad() L124 无(随机)
copiedIndex 复制话术后设为当前索引2 秒后重置为 -1 onCopySpeech() L189 用户交互
pageState 加载状态机loading → normal/empty/error loadData() 数据加载结果
phoneVisible 手机号显示/隐藏切换 onTogglePhone() L173 用户交互
noteModalVisible 备注弹窗显隐 onAddNote()/onNoteConfirm()/onNoteCancel() 用户交互
abandonModalVisible 放弃弹窗显隐 onAbandon()/onAbandonConfirm()/onAbandonCancel() 用户交互
formatServiceDate() 返回值 ISO 日期 → M月D日 HH:mm 中文短格式 页面顶部函数 L55 服务记录日期字符串

五、路由参数

参数 来源 用途 所在行
options.id onLoad(options) 任务 ID用于查找 mock 数据;缺失时回退空字符串 ts L123

六、WXML 中的硬编码文案

文案 位置 类型 说明
'该客户已有 15 天未到店,存在流失风险。建议通过微信联系:' wxml L82 业务数据 应从 AI 分析结果获取
'💡 建议执行' wxml L79 UI 文案 可保留
'💬 话术参考' wxml L89 UI 文案 可保留
'60天内服务记录' wxml L121 UI 文案 "60天"为业务规则,可保留但需确认是否动态
'未找到任务信息' / '加载失败' / '加载中...' wxml L7-L15 状态文案 可保留
'暂无备注' wxml L117 空态文案 可保留

七、引用的工具函数

函数 来源文件 用途
mockTaskDetails utils/mock-data.ts Mock 任务详情数据
TaskDetail, Note utils/mock-data.ts 类型定义
sortByTimestamp utils/sort.ts 备注按时间降序排序
formatRelativeTime utils/time.ts 备注时间 → 相对时间文案
formatMoney utils/money.ts 金额格式化(已 import 但页面 TS 中未直接调用WXML 使用 WXS 版)
fmt.toFixed utils/format.wxs WXML 中数字保留小数
fmt.money utils/format.wxs WXML 中金额格式化
fmt.hours utils/format.wxs WXML 中课时格式化

八、引用的自定义组件

组件 路径 用途
note-modal /components/note-modal/note-modal 备注弹窗
abandon-modal /components/abandon-modal/abandon-modal 放弃任务弹窗
star-rating /components/star-rating/star-rating 星级评分展示
heart-icon /components/heart-icon/heart-icon 爱心图标(关系等级)
ai-inline-icon /components/ai-inline-icon/ai-inline-icon AI 内联图标
ai-title-badge /components/ai-title-badge/ai-title-badge AI 标题徽章
clue-card /components/clue-card/clue-card 维客线索卡片
service-record-card /components/service-record-card/service-record-card 服务记录卡片
dev-fab /components/dev-fab/dev-fab 开发调试浮动按钮JSON 注册但 WXML 未使用)

九、调试面板数据

页面包含一个调试面板(showDebugPanel),用于开发阶段切换任务类型和关系数值。联调前应移除或隐藏。

字段 用途 所在行
showDebugPanel 调试面板显隐 ts L110
debugTaskType 调试用任务类型 ts L111
debugHeartScore 调试用关系数值 ts L112
debugShowExpandBtn 调试用展开按钮开关 ts L113

十、联调 TODO

高优先级(数据完全依赖 Mock/硬编码)

  • 替换 mockTaskDetailsGET /api/tasks/{id} 真实 API 调用
  • 替换页面内联 mock 备注为 GET /api/tasks/{id}/notes API
  • 替换硬编码 retentionClues8 条维客线索)为 GET /api/tasks/{id}/retention-clues API
  • 替换硬编码 talkingPoints5 条话术)为 GET /api/tasks/{id}/talking-points 或 AI 生成接口
  • 替换硬编码 serviceRecords4 条服务记录)为 GET /api/tasks/{id}/service-records?days=60 API
  • 替换硬编码 serviceSummary 为后端返回或前端聚合计算
  • 替换硬编码手机号 '13812345678' / '138****5678' 为 API 返回的客户手机号
  • 替换硬编码 storageLevel: '非常多' 为客户信息 API 返回值

中优先级(操作类接口)

  • onAbandonConfirm 对接 POST /api/tasks/{id}/abandon
  • cancelAbandon 对接 POST /api/tasks/{id}/cancel-abandon
  • onNoteConfirm 对接 POST /api/tasks/{id}/notes
  • onDeleteNote 对接 DELETE /api/tasks/{id}/notes/{noteId}

低优先级(优化项)

  • WXML 中 suggestion-intro 硬编码文案改为从 AI 分析结果动态获取
  • 移除或条件隐藏调试面板(showDebugPanel 相关代码)
  • 统一维客线索数据结构:页面硬编码的 RetentionClue 接口与 mock-data.ts 中定义的不一致
  • formatMoney 已 import 但 TS 中未使用WXML 用 WXS 版),可清理无用 import
  • dev-fab 组件已在 JSON 注册但 WXML 未引用,可清理