真源职责:移动端(及预留多端)如何实现 06 旅程与 07 呈现。
代码根:/src(Taro 4 + React 18 + 微信小程序)
呈现:07-product-presentation.md
故事:06-user-stories-journeys.md
参数:10-interaction-spec.md
后端:11-technical-spec.md
| 项 | 选型 | 说明 |
|---|
| 框架 | Taro 4.2 + React 18 | 见 package.json |
| 目标端 | 微信小程序(主) | build:weapp |
| 次端 | H5 可调试 | dev:h5 |
| 样式 | Sass + CSS 变量 | styles/tokens.scss motion.scss |
| UI 库 | taro-ui 可选 | 主路径尽量自研轻组件 |
| 状态 | React Context AppProvider | MVP 足够;勿过早上重型状态库 |
| 存储 | 本地 storage 封装 | services/storage.ts |
| AI | mockAgent 规则引擎 | 可替换远程沉淀 API |
| 约束 | 目标 |
|---|
| 捕获反馈 | 感知 ≤2s(mock 可模拟阶段) |
| 包体 | 主包控制;精灵 png/webp 按需 |
| 首屏 | 打开即捕获,无重引导 |
| 减少动态 | 尊重系统设置 |
| 不做 | 日历页、四象限页、原生复杂手势依赖隐藏入口 |
为什么不是五 Tab: 列表/日历/我的会把产品拉回传统 Todo,破坏「只回来一步」。
| path | 标题文案建议 | 职责 |
|---|
pages/capture/index | 捕获 | 零字段闪念;M1/M2 |
pages/focus/index | 聚焦 | WIP=1;M3/M4 |
pages/review/index | 复盘 | M5 |
未来扩展(非 MVP 路由):线程详情、设置、账本导出——从复盘/状态条二级进入,不进 Tab。
| 层 | 实现 |
|---|
| TabBar | 配置图标 assets/tab/*;选中色 primary |
| Toast | ToastHost 挂 App |
| Remembered | RememberedFx 全局叠加 M4 |
| Provider | AppProvider 包裹 |
├── StatusStrip (visible 受下拉控制)
│ ├── AgentStatusLayer (phase, text, toneState)
│ ├── SpriteStatus (idle-breath | capture-task | freeze-task)
└── CaptureBar (text|voice|plus, busy, idleSlow)
| 本地 UI 状态 | 来源 |
|---|
stripVisible | 下拉 dy>48 |
idleSlow | 10s timer → B2 |
agent.phase | Provider:idle/receiving/judging/done |
currentNext | 用于 hint CAP-F11 |
| 用户事件 | handler | 故事 |
|---|
| 提交文字/语音/图 | capture(text, source) | US-C01/C02 |
| 下拉 | 显示 StatusStrip 3–3.5s | US-C05 |
| 任意 touch | resetIdle | B1 |
| 态 | UI |
|---|
| 空 | CAP-F0/F1 文案,无列表 |
| busy | CaptureBar disabled |
| 失败 | Toast「没记下,请重试」 |
- M1:phase 流转 + 文案阶段
- M2:toneState + reason 文案
│ ├── SpriteStatus next-step
│ └── JellyButton → switchTab capture
└── actions: complete split snooze important
| UI | API | 故事 |
|---|
| 完成✓ | completeCurrent | F03 |
| 拆小 | splitCurrent + Remembered | R01 M4 |
| 稍后 | snoozeCurrent | R02 |
| 🔥 | markImportant | R03 |
| 目标 | 现状 | 优先级 |
|---|
| PendingConfirmCard FOC-F2 | 无独立组件;pending 进 next 混用 | P0 |
| 稍后时段 chips | 可能一键 snooze | P1 |
| 原文展开 | 部分无 | P1 |
| 完成 celebrate 精灵 | 资产有,页未接 | P1 |
├── SpriteStatus sleep-shutdown
| UI | API |
|---|
| 上午别推 | setPreference({ noPushAm }, remembered) |
| 收到 | switchTab capture |
| 目标 | 现状 |
|---|
| 日终推送进页 | 未接系统推送 |
| 动态「接住」等与全状态 | stats 字段已有,展示四项 OK |
| 组件 | 职责 | 07 关联 | 状态 |
|---|
CaptureBar | 文字/语音/+ 面板 | 捕获条状态机 | 已有,可增强 Undo 出口 |
AgentStatusLayer | 判断文案+微光 | B3 | 已有 |
StatusStrip | 今日统计 | 下拉条 | 已有 |
SpriteStatus | 帧动画精灵 | 4.4 绑定 | 已有 |
ActionCard | 一步+操作 | FOC-F1 | 已有 |
JellyButton | 果冻主按钮 | B 果冻 | 已有 |
RememberedFx | 记下了 | B4 M4 | 已有 |
ThinkingDots | 思考点 | B3 | 已有 |
ToastHost | Toast | 全局 | 已有 |
| 组件 | 职责 | 故事/帧 | Phase |
|---|
UndoChip | 接住后 5s 撤销 | US-C08 CAP-F13 | 1 |
PendingConfirmCard | 一问+短按钮 | US-F05 FOC-F2 | 1 |
ReasonBanner | 可复用 reason 展示 | M2 | 1 |
SnoozeSheet | 傍晚/明天/下周 | US-R02 | 2 |
FragmentOrigin | 原文折叠 | US-F06 | 2 |
DeliveryHint | 「下午再回来」 | 排程可见性 | 2 |
CaptureBar
onCapture: (text: string, source: 'text'|'voice'|'image') => void
AgentStatusLayer
phase: 'idle'|'receiving'|'judging'|'done'
toneState?: FragmentState // 映射状态色
ActionCard
item: Fragment // action, reason, content, state
RememberedFx
// 由 Provider remembered: { title, subtitle } 驱动
FragmentState = raw | next_step | waiting | merged | snoozed
| frozen | pending | archived | done
Fragment { id, content, source, state, reason?, action?, createdAt, updatedAt }
PreferenceMap { splitFirst?, noPushAm?, conservativeTone?, preferImportant?, notes? }
DailyStats { date, caught, merged, frozen, waiting, done, snoozed, pending, archived }
AgentPhase = idle | receiving | judging | done
| 字段 | 用途 | UI 暴露 |
|---|
urgency / importance | 内部启发 | 否 |
threadId | 归并 | 可选文案 |
deliverAt | 调度 | 仅文案「稍后」 |
suppressUntil | 今天别推 | 否 |
| 方法 | 说明 |
|---|
capture | 已有:阶段 timer + judgeFragment |
completeCurrent | 已有 |
splitCurrent | 已有 + remembered |
snoozeCurrent | 已有;增强时段 |
markImportant | 已有 |
setPreference | 已有 |
undoLastCapture | 新增 C08 |
confirmPending(id, choice) | 新增 F05 |
archive(id) | 新增 R04 |
loadSnapshot / saveSnapshot:fragments + preferences + stats
- 日切:stats.date !== todayKey → emptyStats
capture → 立即 receiving UI → 异步/定时 judge → done
undoLastCapture → 删除 last id + 回滚 stats(若可)
| 规则 | state | 对应 US |
|---|
| URL/资料 | merged | S01 |
| 等待 | waiting | S03 |
| 灵感 | frozen | S02 |
| 客户+截止 | pending | S05 |
| 客户沟通 | next_step | S04 |
| 默认 | next_step + toNextStep/split | S04 |
| prefs.splitFirst | shrinkAction | R01 |
增强清单:
- 输出
stages[] 与 07 文案完全一致
- 多意图语音:返回 primary action + side states(需模型支持多 fragment)
- 记录 heuristic 不进 UI
| 时机 | 强度 |
|---|
| 接住/按钮 | light |
| 完成/记下了 | medium |
- 接口形状对齐 11:
POST /fragments
- mock 与 remote 策略模式
| 07 态 | 实现位置 | 要点 |
|---|
| B1 idle-breathe | CaptureBar / JellyButton breathe | 3s scale |
| B2 rest-slow | idleSlow prop | 5s |
| B3 judging-glow | AgentStatusLayer + phase timers | ≤3s stages |
| B4 confirm-ripple | RememberedFx | 波纹+文案 |
| 背景微光 | page-capture__glow | 8s 径向 |
| 果冻 | JellyButton | 0.34,1.56,0.64,1 |
| count-up | review useCountUp | 已有 |
| reduced-motion | motion.scss media | 需补全关呼吸 |
Token:styles/tokens.scss 与 07§3 对齐(已基本一致)。
| US | 07 帧 | 页面 | 组件 | 埋点 |
|---|
| C01 | CAP-F3–6 | capture | CaptureBar, AgentStatus | capture_submit |
| C02 | CAP-F9–4 | capture | CaptureBar voice | capture_voice_* |
| C08 | CAP-F13 | capture | UndoChip | capture_undo |
| S01 | CAP-F5 | capture | AgentStatus tone=merged | sediment_result |
| D02 F01 | FOC-F1 | focus | ActionCard | delivery_show |
| R01 | FOC-F4 B4 | focus | ActionCard, RememberedFx | delivery_action=split |
| V01 | REV-F1 | review | stats | review_open |
| V03 | REV-F3 | review | JellyButton pref | preference_write |
高光验收自动化(建议):
| M | 手工 | 半自动 |
|---|
| M1 | 提交见阶段文案 | timer mock 快进 |
| M2 | reason 含不新增 | unit judgeFragment URL |
| M3 | 仅一卡 | query next_step length≤1 |
| M4 | 拆小见记下了 | remembered non-null |
| M5 | 复盘无「未完成」 | copy lint |
| 层 | 范围 |
|---|
| Unit | judgeFragment 各规则;splitSmaller;todayKey |
| Component | CaptureBar 提交;ActionCard 四按钮回调 |
| e2e(可选) | 最小:捕获→聚焦有下一步 |
现有:__tests__/index.test.js — 需扩展 agent 单测。
- 主按钮可聚焦文案
- reason 变化
aria-live(小程序能力内尽量)
- 减少动态
| 项 | 验收 |
|---|
| 阶段文案与 B3 | 与 07 时间轴一致 |
| UndoChip | C08 |
| reason 状态色 | M2 |
| 无强制跳转 | C04 |
| 项 | 验收 |
|---|
| WIP=1 硬约束 | D02 |
| PendingConfirmCard | F05 |
| 拆小 Remembered | M4 |
| SnoozeSheet | R02 |
| 项 | 验收 |
|---|
| 文案无羞辱 | V01 |
| 上午别推 | V03 |
| 空态 REV-F0 | JRN-08 |
- 埋点字典落地
- reduced-motion
- remote sediment 接口
- 多端预留(不进主包)
| 能力 | src 现状 | 目标 | 差距 |
|---|
| 三 Tab 页 | ✅ | ✅ | 小 |
| 捕获文字/语音 mock | ✅ | ✅ | 文案/Undo |
| Agent 阶段 UI | ✅ | ✅ | 对齐 07 用词 |
| 状态规则引擎 | ✅ 基础 | 多意图/侧态 | 中 |
| 聚焦单卡+四按钮 | ✅ | ✅ | 待定卡、时段 |
| 记下了 Fx | ✅ | ✅ | — |
| 复盘四计数 | ✅ | ✅ | 推送入口 |
| 呼吸 idleSlow | ✅ | ✅ | reduced-motion |
| 撤销捕获 | ❌ | ✅ | 缺 |
| Pending 专用 UI | ❌ | ✅ | 缺 |
| 排程 job 模型 | ❌ 即时 next | deliverAt | 中 |
| 四象限 UI | ❌(正确) | 禁止 | 保持 |
| 日历页 | ❌(正确) | 禁止 | 保持 |
| 埋点 | ❌ | 字典 | 缺 |
| 单测 agent | 弱 | 强 | 中 |
pages/{capture,focus,review}/
components/{PascalCase}/index.tsx|scss
services/{mockAgent,storage,haptics}.ts
styles/{tokens,motion}.scss
| 规范 | 要求 |
|---|
| 命名 | 组件 Pascal;scss BEM block__elem--mod |
| 颜色 | 只用 CSS 变量,禁随意 hex 散落 |
| 文案 | 对用户句来自 07 声线;禁开发者黑话 |
| PR | 关联 US-ID 或帧 ID |
- Eisenhower 矩阵页面
- 日历 time-block
- 桌面 Tauri 实现(可另库;契约同捕获原则)
- 自动发微信
- 重型状态管理迁移(无证据前不)
- 对齐
mockAgent stages 文案 → 07
- 实现
undoLastCapture + UndoChip
currentNext 过滤保证 WIP=1
- Pending 态走
PendingConfirmCard
- 单测:URL→merged;拆小偏好
- 演示脚本:JRN-03 + M1–M5 录屏
| 日期 | 说明 |
|---|
| 2026-07-11 | 商业级前端架构首版:契约、差距、追溯、路线图 |