建立项目级标杆文档 docs/_overview/ 作为产品全景索引, 解决"PRD 零碎、文档膨胀、跨子系统调研无入口"的问题。 主要内容: - 00-index 总索引 + 维护协议 + 与 CLAUDE.md 关系 - 01-product-overview 产品全景脑图(6 角色 / 6 子系统 / 数据流 / 7 业务概念 / 8+1 AI 矩阵 / 22 术语) - 02a-miniprogram-page-matrix 小程序 21 页业务指纹 - 02b-adminweb-page-matrix admin-web 19 路由业务指纹 - 03-test-spec 测试规范 (L1-L5 分层 + 走查模板 + 75-95 case 估算) - 04-doc-conflicts 39 条冲突索引(P0×8 / P1×13 / P2×13 + 5 子项) - 04a/b/c-conflicts-*-detail 业务故事卡(7 字段:关联/逻辑/影响/选项/判定) - 05-orphan-pages-cleanup admin-web 6 孤儿页面处置(1 归档 + 4 保留) - WAVES-MASTER-PLAN.md 全 Wave 主计划(0-5,共 22-32 工作日) - WAVE-1-KICKOFF.md Wave 1 实施 kickoff - GLOBAL-DECISION-DASHBOARD.md 全局决策仪表板 反馈调研产物: - 04a-feedback/ P0 两轮反馈(8+8 项决策 + D-1/2/3 + F-1/2 子代理产出) - 04b-feedback/ P1 两轮反馈(13+1+5 项 + E-1/2/3/4 + G-1/2 子代理产出) - 04c-feedback/ P2 反馈(13 项 + 5 子项 + H-1/2/3 子代理产出) - NEO-DECISIONS-LOG 累积决策记录 关键追加发现 8 处 D Bug(原蓝本 0): - P0-3 看板沙箱接入(Wave 1 W1-T1) - P0-5 致命 1 (4 处 fdw_etl 残留, 已修 commit17f045a) - P0-5 致命 2 (JWT aud 缺失, 已修 commit17f045a) - P0-6 clearAllTasks 守卫 (Wave 3) - P0-8 DBViewer 黑名单漏 (已修 commit17f045a) - P1-3 task-detail 跳转传 task_id 而非 customer_id - P2-7 board-finance 隐式 null - 2 个独立 Bug (page_context.created_at + ClueCategory 字典) 参考: docs/_overview/00-index.md
24 KiB
24 KiB
小程序跨页传值规范性深度调研(P1-3 + P1-4 触发)
日期: 2026-05-04 触发: Neo 在 04b P1-3 + P1-4 反馈"同意初步判断,但谨慎起见,要从页面和产品设计出发,对业务进行理解的情况下,深入调研这个问题(尤其整个 APP 页面与角色的传值规范性方面)" 范围: 小程序 21 页全部跨页跳转 + 角色权限相关传值 + 公共组件 ai-float-button / board-tab-bar 调研口径: 只读不改, 单文档产出 状态机考量: 仅 5 类跳转 API:
wx.navigateTo/wx.redirectTo/wx.switchTab/wx.reLaunch/wx.navigateBack
一、跳转矩阵全表
下表覆盖小程序 21 页全部 wx.navigateTo / wx.redirectTo / wx.switchTab / wx.reLaunch 调用(wx.navigateBack 仅在"目标页期望"列出现)。
代号约定:
id默认指资源主键(taskId / customerId / coachId / historyId, 视目标页而定)--表示无参数(空 URL)- onLoad 期望字段以代码实际读取为准
| # | 源页 | 跳转方法 | 目标页 | 参数 key:value | 目标页 onLoad 期望字段 | 是否一致 | 问题类型 |
|---|---|---|---|---|---|---|---|
| 1 | login | reLaunch | task-list / board-finance / my-profile (动态首页) | -- | -- | 一致 | -- |
| 2 | login | reLaunch | reviewing | -- | -- | 一致 | -- |
| 3 | login | reLaunch | apply | -- | -- | 一致 | -- |
| 4 | login | reLaunch | no-permission | -- | -- | 一致 | -- |
| 5 | apply | reLaunch | login (兜底) | -- | -- | 一致 | -- |
| 6 | apply | reLaunch | reviewing | -- | -- | 一致 | -- |
| 7 | apply | reLaunch | no-permission | -- | -- | 一致 | -- |
| 8 | apply | reLaunch | <动态首页 by getRoleHome> | -- | -- | 一致 | -- |
| 9 | apply | navigateBack(fail→reLaunch login) | 上一页 / login | -- | -- | 一致 | -- |
| 10 | reviewing | reLaunch | <动态首页> / no-permission / apply / login | siteCode + role + phone + employeeNumber (cancel 重申请) | apply.onLoad 解 4 字段 | 一致 | -- |
| 11 | no-permission | reLaunch | login | -- | -- | 一致 | -- |
| 12 | no-permission | reLaunch | <动态首页> | -- | -- | 一致 | -- |
| 13 | no-permission | reLaunch | apply | siteCode + role + phone + employeeNumber | apply.onLoad 同上 | 一致 | -- |
| 14 | no-permission | reLaunch | reviewing | -- | -- | 一致 | -- |
| 15 | task-list | navigateTo | task-detail | id=<task.id> | id 或 memberId | 一致 | -- |
| 16 | task-list | navigateTo | performance | -- | scrollToBottom 可选 | 一致 | -- |
| 17 | task-list | navigateTo | performance | scrollToBottom=1 | scrollToBottom 解析 '1' | 一致 | -- |
| 18 | task-list | navigateTo | chat | taskId=<task.id> | taskId 分支 | 一致 | -- |
| 19 | my-profile | navigateTo (utils/router.navigateTo) | chat-history / performance / notes | -- | -- | 一致 | -- |
| 20 | my-profile | reLaunch | login | -- | -- | 一致 | -- |
| 21 | task-detail | navigateBack | 上一页 | -- | -- | 一致 | -- |
| 22 | task-detail | navigateTo | chat | taskId=<detail.id> | taskId 分支(contextType=task) | 一致 | -- |
| 23 | task-detail | navigateTo | customer-service-records | customerId=<detail.customerId 或 fallback 到 detail.id> | customerId 或 id | 不一致(B) | P1-3 |
| 24 | performance | navigateBack(fail→switchTab task-list) | 上一页 / 任务 tab | -- | -- | 一致 | -- |
| 25 | performance | navigateTo | performance-records | -- | -- | 一致 | -- |
| 26 | performance | navigateTo | task-detail | memberId=<member.memberId> | id 或 memberId | 一致(2026-03-25 修复) | 历史 P1-4 |
| 27 | performance | navigateTo | task-detail | id=<rec.taskId> 或 memberId=<rec.memberId> | id 或 memberId | 一致 | -- |
| 28 | performance | navigateTo | performance-records | -- | -- | 一致 | -- |
| 29 | performance-records | navigateBack(fail→switchTab) | 上一页 | -- | -- | 一致 | -- |
| 30 | performance-records | navigateTo | task-detail | memberId=<row.memberId> | id 或 memberId | 一致 | -- |
| 31 | board-finance | switchTab/redirectTo | board-finance / board-customer / board-coach | -- | -- | 一致 | -- |
| 32 | board-customer | switchTab/redirectTo | 同上 | -- | -- | 一致 | -- |
| 33 | board-customer | navigateTo | customer-detail | id=<row.id> | id 或 customerId | 一致 | -- |
| 34 | board-coach | switchTab/redirectTo | 同上 | -- | -- | 一致 | -- |
| 35 | board-coach | navigateTo | coach-detail | id=<row.id> | id (仅) | 一致 | -- |
| 36 | customer-detail | navigateTo | customer-records | customerId=<detail.id> | customerId 或 id | 一致 | D(命名/语义混乱) P1-10 |
| 37 | customer-detail | navigateTo | chat | customerId=<detail.id> | customerId 分支 | 一致 | -- |
| 38 | customer-records | -- | (无下游跳转) | -- | -- | -- | -- |
| 39 | customer-service-records | navigateBack | 上一页 | -- | -- | 一致 | -- |
| 40 | coach-detail | navigateTo | customer-detail | id= (3 个不同入口: 最近服务客户/收藏客户/常客) | id 或 customerId | 一致 | -- |
| 41 | coach-detail | navigateTo | coach-service-records | coachId= | coachId(必填,缺失则退回) | 一致 | -- |
| 42 | coach-detail | navigateTo | chat | coachId= | coachId 分支 | 一致 | -- |
| 43 | coach-service-records | navigateBack(fail→switchTab board-finance) | 上一页 / 看板 | -- | -- | 一致 | -- |
| 44 | coach-service-records | navigateTo | customer-detail | id= | id 或 customerId | 一致(memberId<=0 拦截) | 关联 P1-12 |
| 45 | chat | navigateBack | 上一页 | -- | -- | 一致 | -- |
| 46 | chat | navigateTo | <动态 link>(消息内可点链接) | -- | -- | 取决于 link 内容 | D(无校验) |
| 47 | chat-history | navigateBack | 上一页 | -- | -- | 一致 | -- |
| 48 | chat-history | navigateTo | chat | historyId=<row.id> | historyId 分支 | 一致 | -- |
| 49 | dev-tools | reLaunch | <任意页 by dataset.url> | (跟随 url 拼接) | -- | 一致 | -- |
| 50 | ai-float-button(组件,被 6 页引用) | navigateTo | chat | sourcePage / pageFilters / customerId(可选) | sourcePage 分支(看板类) | 一致 | -- |
| 51 | board-tab-bar(组件) | switchTab | task-list / board-finance / my-profile | -- | -- | 一致 | -- |
| 52 | dev-fab(组件) | navigateTo | dev-tools | -- | -- | 一致 | -- |
| 53 | notes | navigateBack | 上一页 | -- | -- | 一致 | -- |
合计: 53 条跳转(合并重复入口后), 其中 2 条不一致 / 命名混乱(行 23、36), 1 条无校验(行 46)。
二、规范性问题清单(按严重度)
P0 级(语义错位,功能不通)
问题 P0-1: task-detail → customer-service-records 传 detail.id 当 customerId 用 (即 P1-3 后半段)
- 源页:
pages/task-detail/task-detail.tsL437-441 - 目标页:
pages/customer-service-records/customer-service-records.ts - 现状:
当 TASK-2 响应未返回
const customerId = (this.data.detail as any)?.customerId || this.data.detail?.id || '' wx.navigateTo({ url: `/pages/customer-service-records/customer-service-records?customerId=${customerId}` })customerId字段时, fallback 拿detail.id(taskId), 把 taskId 当作 customerId 拼到 URL. - 目标页 onLoad:
const id = options?.customerId || options?.id || '', 拿到的是 taskId, 后续按 taskId 调fetchCustomerServiceRecords必然返回空或错乱. - 期望: TASK-2 响应里加
customer_id/member_id字段, 前端不再用 fallback. - 修复方案:
- 后端:
GET /api/xcx/tasks/{id}响应增加customerId(JOIN dim_member); - 前端: 删除
|| this.data.detail?.id的 fallback, 拿不到 customerId 时显式 toast"客户信息缺失".
- 后端:
问题 P0-2: chat 多入口路由当前实现一致性不足 (P1-11)
- 源页: 3 入口
task-detail→chat?taskId=(已正确, 走 contextType=task)customer-detail→chat?customerId=(已正确, contextType=customer)coach-detail→chat?coachId=(已正确, contextType=coach)chat-history→chat?historyId=(走历史 chatId)task-list 上下文菜单"问问助手"→chat?taskId=(已正确)ai-float-button→chat?sourcePage=...&pageFilters=...&customerId=...(看板类入口)
- 目标页 onLoad: 已经根据
historyId / taskId / customerId / coachId / sourcePage / 无参6 分支处理 - 现状评估: 与 04b P1-11 描述存在偏差 — chat.ts L214-263 已经做了 6 分支, P1-11 描述的"loadMessages 仅用 customerId"已不适用(代码已演进)
- 残留风险:
- 后端接口侧:
fetchChatMessagesByContext(contextType, contextId)是否后端已支持 4 种 contextType(task / customer / coach / general / board-*) 待验证 general/board-*几个 contextType 的 chatId 派生策略是否后端已实现待与后端核对
- 后端接口侧:
- 修复方案: 与后端核对
GET /api/xcx/chat/messages?contextType=...&contextId=...是否已上线全部 contextType 路由 - 建议判定: 降为 P1(前端代码已修, 后端契约待补)
P1 级(命名/语义混乱, 功能可走通但易踩坑)
问题 P1-1: customer-detail "消费记录"卡片绑定的方法名是 onViewServiceRecords 但实际跳消费记录页 (P1-10 的根因)
- 源页:
customer-detail.wxmlL177-181<!-- 消费记录 --> <view class="card-header" bindtap="onViewServiceRecords"> <text class="section-title title-orange">消费记录</text> </view> - 处理:
onViewServiceRecords实际跳customer-records(消费视角), 名字写成"Service"完全是误导. - 影响: 看代码读不出真实跳转目标; 改 bug 时容易跳错页面.
- 期望: 方法名改为
onViewConsumptionRecords/goConsumptionRecords, 与文案"消费记录"一致. - 修复方案: 简单重命名(WXML + TS), 不影响功能.
- 与 P1-10 关系: 04b P1-10 询问"查看消费记录跳哪个目标页", 答案是 customer-records(消费记录页, 2026-03-29 新建), 现状已正确, 但 方法命名误导.
问题 P1-2: task-detail.onLoad fallback 优先级模糊
- 现状:
onLoad({ id?, memberId? })同时支持两种语义, 但是当 url 里 同时 出现?id=xxx&memberId=yyy时 优先使用 id 走 loadData, 不走 memberId. - 入口分布: 5 个入口都只传一个键, 故无实际冲突, 但接口边界模糊(若未来其他页传两个键, 行为不直观).
- 期望: 显式声明"id 优先, 仅 id 缺失时才用 memberId", 在文档里写清楚.
问题 P1-3: 字段命名风格不统一 (camelCase vs lowercase)
- 全局清单(纯 URL key, 不含值):
id(单字母 / 没有所属命名空间) → 使用面: 大量(task-list, board-customer, board-coach, coach-service-records, customer-records, customer-service-records 等都用)customerId/coachId/taskId/historyId/memberId/siteCode/employeeNumber/sourcePage/pageFilters/scrollToBottom/phone/role/timeDimension/areaFilter/dimension/typeFilter/projectFilter
- 风格: 以 camelCase 为主. 问题:
id缺乏所属语义: 同一个id在 task-list 是 taskId, 在 board-customer 是 customerId, 在 board-coach 是 coachId. 排查时容易看 url 看错.- 混用
id与customerId: customer-records / customer-service-records / customer-detail 三页的 onLoad 都做了options?.customerId || options?.id兼容, 这种"二选一"兼容是历史污渍.
- 期望: 统一约定"目标页接收明确语义键(taskId / customerId / coachId), 不再接受裸
id"; 兼容期保留id || customerId的回退, 但所有 navigateTo 调用方迁移到明确键.
问题 P1-4: 字段类型(string vs number)隐式不一致
- url 参数本质是 string, 但有些目标页直接
Number()转换(如 coach-service-records.onLoad), 有些直接用 string(如 customer-records 把 id 写入 setData 用作 string). - 现状:
- coach-service-records:
Number(options?.coachId)后判断Finite && >0, 否则退回(已正确) - customer-detail / customer-records / customer-service-records / coach-detail: 全部用 string, 后端调用时再做转换
- task-detail.loadByMember:
String(detail.id)显式转换
- coach-service-records:
- 期望: URL 参数全部按 string 处理, 调后端时转换由 service 层做; 业务侧不要混用.
P2 级(兜底缺失 / 体验问题)
问题 P2-1: 多数目标页缺少必填字段缺失时的 toast / fallback
- 现状: 仅
coach-service-records在 coachId 缺失时有wx.showToast('缺少助教标识') + setTimeout navigateBack的兜底. - 其他页(customer-detail / customer-records / customer-service-records / customer-detail / coach-detail / task-detail / chat)在拿不到必填字段时, 大多数走"setData empty / pageState='empty'"或者直接调后端拿空响应, 不会 toast 提醒.
- 期望: 关键详情页(customer-detail / coach-detail / task-detail / customer-service-records / coach-service-records / customer-records / chat) 全部加必填字段缺失 toast.
问题 P2-2: chat 内嵌消息 link 跳转无安全校验
- chat.ts L552-556:
wx.navigateTo({ url: link })— link 来自 AI 回复消息中的可点链接, 无白名单校验. - 风险:
- link 若指向 tabBar 页面会失败(navigateTo 不能去 tab 页)
- link 包含恶意构造参数时无防护
- 期望: 增加白名单(只允许
/pages/...前缀 + 已知页面路径), navigateTo 失败时降级 switchTab.
问题 P2-3: dev-tools.ts 的 reLaunch 跳"任意页"无白名单校验
- dev-tools.ts L156-158:
const url = "/" + e.currentTarget.dataset.url; wx.reLaunch({ url })— 来自 dataset, 调试页可接受, 但生产编译要确保 dev-tools 入口被关闭(已有wx:if="{{false}}"隐藏 dev-fab).
问题 P2-4: customer-detail 跳 customer-records 时 banner 字段重复加载
- customer-detail 已有完整客户信息, customer-records.onLoad 只接 customerId, 然后再调
fetchCustomerConsumptionRecords重新拉 banner. - 后果: 多一次接口往返, 但跳转后用户在 customer-records 看到的 banner 数据是新 fetch 的, 与 customer-detail 一致性不强.
- 期望: 后端响应里 banner 字段(name/avatar/storage)由 customer-records 自己拉(已是现状), 不需要前端透传; 若考虑性能, 可走 globalData 暂存上一页客户对象, 但这是优化项.
角色相关传值问题清单(独立维度)
问题 R-1: 跳转链路中没有携带角色信息
- 现状: 所有 navigateTo / redirectTo 调用 都不带 role 参数. 目标页通过
checkPageAccess(pageRoute)在 onShow 调auth-guard模块从 globalData(后端 fetchMe 返回)读取角色和权限码. - 这是合理设计: URL 不应携带角色, 角色应来自后端权威源.
- 但意味着: 如果后端 permissions 与页面预期角色不匹配(例如散客访问助教页), 由 auth-guard 拦截并跳 no-permission, 不靠 URL 角色.
问题 R-2: site_id(门店 ID)切换不影响传值
- site_id 不出现在任何 URL 参数里, 后端通过 JWT +
app.current_site_id会话变量过滤. 这是 RLS 双 schema 设计, 跨店切换由后端处理, 前端 URL 不感知, 正确无问题.
问题 R-3: 散客模式(P1-12)的判断分散
- 当前
coach-service-records用Number(options?.coachId) > 0判合法,performance.onCustomerTap用mid <= 0判散客拦截. - 散客约定不统一(NULL / 0 / -1 / <=0 都有兼容代码), 这是 P1-12 的范畴, 与传值规范同源.
- 期望: 散客统一约定 + 跳转拦截统一抽到 utils 函数(如
isScattered(memberId)).
三、传值规范建议
3.1 字段命名规范
强制约定:
- URL 参数键统一使用 camelCase(已是事实标准, 文档化)
- 禁止使用裸
id, 必须带语义前缀:taskId/customerId/coachId/historyId/memberId/noteId/recordId - 兼容期
id || customerId的双键兼容保留 6 个月, 之后强制只接受语义键
3.2 参数 key 命名约定(全集 + 语义)
| key | 含义 | 类型 | 来源 / 出现页 |
|---|---|---|---|
taskId |
任务 id | string(数字字符串) | task-list / chat / task-detail / performance |
customerId |
客户(会员) id, 等价 memberId | string | task-detail / customer-detail / customer-records / customer-service-records / chat |
coachId |
助教 id | string | coach-detail / coach-service-records / chat |
historyId |
对话历史 chatId | string | chat-history / chat |
memberId |
会员 id (与 customerId 同义) | string(数字字符串) | performance / performance-records / task-detail / coach-service-records |
siteCode |
门店编码(申请预填) | string(URI 编码) | reviewing → apply / no-permission → apply |
employeeNumber |
员工号(申请预填) | string(URI 编码) | 同上 |
phone |
手机号(申请预填) | string(URI 编码) | 同上 |
role |
角色(申请预填) | string(URI 编码) | 同上 |
sourcePage |
AI 上下文来源页 | string(枚举) | ai-float-button → chat |
pageFilters |
AI 看板筛选参数集 | string(URI + JSON) | ai-float-button → chat |
scrollToBottom |
业绩页滚到底部标记 | string('1' / 缺省) | task-list → performance |
timeDimension 等单键过滤 |
旧入口兼容 | string | ai-float-button → chat(回退路径) |
统一约定:
customerId与memberId同义(后端 dim_member.id), 但小程序前端两套用法都存在. 期望: 跨页 URL 统一customerId, 内部页面 data 里可以叫memberId(看后端字段名). 迁移历史 url 期memberId兼容期 6 个月, 之后只接customerId.
3.3 目标页 onLoad 必填字段校验模式
推荐模板(以 coach-service-records 为标杆):
onLoad(options: Record<string, string | undefined>) {
const requiredId = Number(options?.coachId)
const validId = Number.isFinite(requiredId) && requiredId > 0 ? requiredId : 0
if (validId === 0) {
wx.showToast({ title: '缺少助教标识', icon: 'none' })
setTimeout(() => wx.navigateBack({
fail: () => wx.switchTab({ url: '/pages/board-finance/board-finance' })
}), 1000)
return
}
this.setData({ coachId: validId })
this.loadData(validId)
}
所有详情页应遵循这个模板:
- 把
options?.<key>提取出来做类型/合法性校验 - 缺失时明确 toast(中文文案 + icon='none')
- setTimeout 后 navigateBack(并提供 fail 兜底, 防止从分享链接首页直入)
- 合法时再 setData + 触发数据加载
3.4 跨角色 / 跨店传值约定
- 角色: 不通过 URL 携带, 由 auth-guard 从 globalData / fetchMe 读取
- 门店: 不通过 URL 携带, 由 JWT + 后端 RLS 处理
- 散客判断: 在跳转源头拦截(
memberId <= 0一律不跳, toast"未知客户不提供查看详情"), 等待 P1-12 决策后将判断函数集中到utils/customer.ts(待新建)
四、修复方案分组
必修(P0): 后端补字段 + 前端去 fallback
| 项 | 模块 | 改动 | 工作量 |
|---|---|---|---|
| F1 | 后端 TASK-2 | GET /api/xcx/tasks/{id} 响应增加 customerId(JOIN dim_member 由 task.member_id 派生) |
小 |
| F2 | 前端 task-detail | 删除 `customerId = detail?.customerId | |
| F3 | 后端 chat by-context | 验证 GET /api/xcx/chat/messages?contextType=task/customer/coach/general/board-*&contextId= 已支持全部 contextType |
中 |
应修(P1): 字段命名/类型统一 + 命名重构
| 项 | 模块 | 改动 | 工作量 |
|---|---|---|---|
| F4 | customer-detail.ts + customer-detail.wxml | onViewServiceRecords 重命名为 onViewConsumptionRecords, WXML bindtap 同步 |
极小 |
| F5 | board-customer / board-coach | 跳 customer-detail / coach-detail 时, 把 ?id= 改为 ?customerId= / ?coachId=(语义化), 目标页保留兼容期 |
小 |
| F6 | task-list | 跳 task-detail 时, ?id= 改为 ?taskId=(目标页兼容期保留 id) |
小 |
| F7 | coach-service-records | 跳 customer-detail 时, ?id=${memberId} 改为 ?customerId=${memberId} |
极小 |
| F8 | docs(SPEC) | 制定"小程序跨页传值规范"SPEC, 见 §五.建议 | 中 |
可修(P2): 兜底补全 + 安全加固
| 项 | 模块 | 改动 | 工作量 |
|---|---|---|---|
| F9 | customer-detail / coach-detail / task-detail / customer-records / customer-service-records / coach-service-records / chat | 必填字段缺失统一加 toast + 退回上一页 | 中 |
| F10 | chat 消息 link 跳转 | 增加白名单(/pages/ 前缀 + 已知页面集), 失败降级 switchTab |
小 |
| F11 | utils/customer.ts | 新建 isScattered(memberId) 函数, 统一散客判断, 等 P1-12 决策后填实现 |
小 |
已确认无需修(误报或已修)
- performance → task-detail 传 customerName 而非 task_id (P1-4): 已于 2026-03-25 修复, 现
onCustomerTap传memberId,onRecordTap优先传taskIdfallbackmemberId. 04b P1-4 描述已过时, 应在 04b 反馈中标注"已修复". - chat.loadMessages 仅用 customerId (P1-11): 已于多次迭代修复, 现 chat.onLoad 走 6 分支(historyId / taskId / customerId / coachId / sourcePage / 无参), 04b P1-11 描述已过时, 仅后端契约待核对.
五、给 Neo 的决策清单
决策 D1: 是否同意"必修"清单全部进 Wave 1-3?
子项:
- D1a: F1 + F2(后端 TASK-2 补 customerId, 前端去 fallback) — 是否进 Wave 1?
- D1b: F3(后端 chat by-context 全 contextType 验证) — 是否单独立项核对后端实现?
决策 D2: 是否同意"应修"清单的命名重构?
子项:
- D2a: F4(customer-detail 方法名重命名) — 极小工作量, 建议直接合并到 P0 修复 PR
- D2b: F5 + F6 + F7(URL 参数从裸
id迁移到语义键) — 涉及 4 页, 建议在 Wave 2 单独立项, 跨页协调 - D2c: F8(SPEC 化) — 是否新建
docs/miniprogram-dev/spec/cross-page-params-spec.md?
决策 D3: 是否同意"可修"清单的优先级排序?
子项:
- D3a: F9(必填字段 toast 兜底) — 7 个页面, 中等工作量, 体验提升明显
- D3b: F10(chat link 白名单) — 安全加固, 轻量
- D3c: F11(散客判断集中) — 等 P1-12 决策后再做
决策 D4: P1-4 与 P1-11 在 04b 文档中的状态更新
- 是否同意将 P1-4 标注"已修复(2026-03-25), 仅文档过时"?
- 是否同意将 P1-11 标注"前端已修(6 分支), 后端契约待核对"?
决策 D5: 是否制定独立 SPEC
建议新建 docs/miniprogram-dev/spec/cross-page-params-spec.md, 内容包含:
- §3.1-3.4 的命名规范、key 全集、onLoad 模板、跨角色约定
- 历史兼容期(双键)的退役时间表
- 测试矩阵(每个跳转的合法/缺失/类型错路径)
六、调研附录
6.1 调研覆盖度
- 21 页 100% 覆盖(login / apply / reviewing / no-permission / task-list / board-finance / my-profile / task-detail / notes / performance / performance-records / board-customer / board-coach / customer-detail / customer-service-records / customer-records / coach-detail / coach-service-records / chat / chat-history / dev-tools)
- 公共组件 ai-float-button / board-tab-bar / dev-fab 100% 覆盖
- utils/router.ts / utils/auth-guard.ts(getRoleHome / checkPageAccess) 已查
- 共抓取 53 条跳转(去重前约 70 条), 含组件触发跳转
6.2 调研口径限制
- 仅调研代码现状, 未跑实际跳转流程验证
- 未深入后端 API 契约 — F3(chat by-context) 待与后端核对
- 未涉及 H5 原型 / demo-miniprogram(MOCK 标杆禁改) — 设计参考另议
6.3 与 04b 已知问题对照
| 04b 问题 | 调研结论 | 后续动作 |
|---|---|---|
| P1-3 (task-detail → chat / customer-service-records 传 detail.id) | chat 路径已修, customer-service-records 路径仍是 fallback bug | F1+F2 必修 |
| P1-4 (performance → task-detail 传 customerName) | 已于 2026-03-25 修, 04b 描述过时 | 仅更新 04b 状态 |
| P1-10 (customer-detail "查看消费记录"跳哪) | 跳 customer-records(消费记录页, 现状正确), 但方法名 onViewServiceRecords 误导 | F4 重命名 |
| P1-11 (chat 多入口 / loadMessages 仅用 customerId) | 前端已 6 分支, 后端契约待核 | F3 待核对 |
| P1-12 (散客 memberId 取值约定) | 与 R-3 / F11 同源 | 等 Neo 决策 + 抽函数 |
本调研结论与 Neo 反馈的"初步判断不变"一致: 同意必修后端补 task_id / customer_id 字段 + 前端改跳转参数, 且额外发现 P1-1(命名误导)、P1-3(裸 id 不规范)等若干非 P1-3/P1-4 问题, 建议一并制定 SPEC 系统化解决.