跳转至

P1.UA21R1.F6-transfer-popup-frontend · TransferModulePopup 双击悬浮窗(对标 FftModulePopup + Smaart 4 chart)

Worker:ClaudeA · 前端 (frontend_vue3) / 预计:0.8d / 优先级:P1 / 状态:ready(建议 blocked-by F1-R1 但文件正交) 隔离:🧵 文件隔离(同 worktree 同 branch · ADR-21-R1 fork 4 · 与 F2-R1 / F4-R1 文件正交可并行)


🔍 触发与解锁链

触发 状态 影响
用户 10:24 反馈点 1 "phase 和 transfer 功能要和当前已经是先的 fft module 对标;当前是双击直接悬浮弹窗 fft 窗体"
ADR-21-R1 §3.4-R1 Transfer 双路径 路径 A(主):双击 mini-node → TransferModulePopup;路径 B(辅助):右 dock(F2-R1 cleanup 后保留)
FFT popup 范式标杆已就位 components/popups/FftModulePopup.vue 374 行 + props/emits 契约 + usePopupModuleManager
LinkEditor 双击协议骨架已存在 行 129 onModuleDoubleClick · transfer mini-node 仅需补路由
F5 transfer 算法层 zombie eb84bab typeId 0x100E0005 + GCC-PHAT + frame schema MeterFrame_Transfer 已锁(ADR-12 §3.3)· popup 直接消费
F6 zombie 已落 useTransferFrame composable 50834d7 已抽 useTransferFrame(双 endpoint ref + measure)· popup 复用 · dock cleanup 时 F2-R1 一起处理

→ 本 R1 hotfix 是 popup 新建 + Smaart 4 chart 主入口迁移 · 工时 0.8d(略多于 F4-R1 因含 4 chart + ref/measure 双 selector + 6 控件)· 与 F2-R1 / F4-R1 可并行 · 用户实测核心:transfer mini-node 双击 → TransferModulePopup ≤ 200ms · Smaart 4 chart 渲染(Mag / Phase / Coherence / Delay)


任务定义(基于 ADR-AIOS-21-R1 §3.4-R1)

实施 ADR-21-R1 §3.4-R1 Transfer Module 路径 A(双击悬浮窗主入口):

  • 新建 TransferModulePopup.vue:对标 FftModulePopup.vue · props {config: TransferModuleConfig, x, y, zIndex} + emits {close, bringToFront, move} · template macOS 风格 header + ref/measure 双 selector(顶部)+ Smaart 4 chart 区(Mag dB / Phase wrapped [-π,π] / Coherence threshold 0.7 / Delay finder GCC-PHAT 自动锁定)+ 6 控件(fftSize / averaging / windowFunction / coherenceThreshold / delayCompensation / delayMs)
  • 复用 F6 50834d7 useTransferFrame composable:双 endpoint(ref + measure)WS 订阅 · popup 内调用 · 不重复实现
  • LinkEditor onModuleDoubleClick 加 transfer 路由:同 F4-R1 模式 · 函数体内补:若 module.moduleId === 'transfer-module' 或 typeId 0x100E0005 → 调 usePopupModuleManager.openModulePopup('transfer-module', module.instanceId, x, y)
  • usePopupModuleManager 注册 transfer-module:moduleId → popup component 映射加 transfer-module: TransferModulePopup
  • 不动:F5 eb84bab 算法层(typeId / GCC-PHAT / frame schema)· F2-R1 dock 路径(DrawerDockTransfer 由 F2-R1 cleanup)· LinkEditor 行 353/1610 onSubgraphNodeDblClick · F6 useTransferFrame composable 内部实现

严守保留(零回归):F5 transfer 算法层 + frame schema(ADR-12 §3.3 MeterFrame_Transfer)+ F6 useTransferFrame composable + LinkEditor 现有双击协议骨架 + usePopupModuleManager 现有 API · 不破坏 FFT/RMS/Scope popup 现有行为。


完整 prompt(直接复制粘贴 worker 终端)

[U-thread]   P1.UA21R1.F6-transfer-popup-frontend
[部门]       前端 (frontend_vue3) · 推荐 skill: vuejs-typescript-best-practices
[Worker CWD] d:/work/25_claude/workspace/AlgoDepartment/04_development/
[Occupies]   P1.K-xilink-popup(写 · transfer popup 新建)+ P1.K-xilink-canvas(读 · LinkEditor 双击协议)
[隔离]       🧵 文件隔离 · 与 F2-R1 / F4-R1 文件正交可并行 · 不动 stages/xitest/* / xitune/* / xiforge/* · 不动 dsp_algo/* · 不动 backend_csharp/*
[优先级]     P1 · 0.8d · ADR-21-R1 fork 4 · popup 新建型 hotfix(含 Smaart 4 chart 主入口迁移)
[ADR]        d:/work/25_claude/workspace/AlgoDepartment/06_docs/site-build/docs/08-implementation/40-aios/ADR/ADR-AIOS-21-R1-dock-three-selectors-and-popup-entries.md(必读 §3.4-R1 Transfer 双路径 + §4.2 F6-R1 行)
[业务行为契约引用] ADR-21-R1 §3.4-R1 ① 双路径契约(props/emits 对标 FftModulePopup) + ② 收敛判据(双击 ≤ 200ms · Smaart 4 chart popup vs dock 一致 · popup ↔ dock 独立) + 用户原话 6/15 10:24 verbatim

[参考文档](绝对路径)
  - ADR 主文档:d:/.../docs/08-implementation/40-aios/ADR/ADR-AIOS-21-R1-dock-three-selectors-and-popup-entries.md
  - 父 ADR:d:/.../docs/08-implementation/40-aios/ADR/ADR-AIOS-21-xilink-dock-and-analysis-modules.md(已 partially-superseded · §3.4 算法部分保留)
  - F6 supersede 标本:d:/.../docs/08-implementation/40-aios/prompts/done/ADR-AIOS-21/P1.A21.F6-transfer-module-frontend--50834d7.md(看 DrawerDockTransfer + Smaart 4 chart + 6 控件实装)
  - F5 zombie 标本(算法层保留):d:/.../docs/08-implementation/40-aios/prompts/done/ADR-AIOS-21/P_dsp.A21.F5-transfer-module-algorithm--eb84bab.md(看 GCC-PHAT + typeId 0x100E0005)
  - **FFT popup 范式标杆**(对标必读):d:/.../04_development/frontend_vue3/src/components/popups/FftModulePopup.vue(374 行 · 完整对标骨架)
  - F4-R1 兄弟 fork(同期可参考):d:/.../docs/08-implementation/40-aios/prompts/active/P1.UA21R1.F4-phase-popup-frontend.md(phase popup 同模式 · 共享 LinkEditor 双击补路由模式)
  - 全局管理器:d:/.../04_development/frontend_vue3/src/composables/usePopupModuleManager.ts
  - 现状必读:
    · frontend_vue3/src/components/popups/FftModulePopup.vue(全文 · template + script + style 完整对标)
    · frontend_vue3/src/composables/useTransferFrame.ts(F6 50834d7 抽离 · 双 endpoint ref/measure · popup 复用)
    · frontend_vue3/src/stages/xilink/drawers/DrawerDockTransfer.vue(F6 50834d7 · Smaart 4 chart 子组件 + 6 控件 · popup 移过来)
    · frontend_vue3/src/stages/xilink/drawers/transfer/TransferMagChart.vue(若存在 · F6 4 chart 子组件)
    · frontend_vue3/src/stages/xilink/drawers/transfer/TransferPhaseChart.vue(若存在)
    · frontend_vue3/src/stages/xilink/drawers/transfer/TransferCoherenceChart.vue(若存在)
    · frontend_vue3/src/stages/xilink/drawers/transfer/TransferDelayChart.vue(若存在)
    · frontend_vue3/src/composables/usePopupModuleManager.ts(全文)
    · frontend_vue3/src/stages/xilink/LinkEditor.vue(行 120-160 + 行 1500-1640 · onModuleDoubleClick 现有实现)

【背景】
用户 10:24 原话第 1 点:"phase 和 transfer 功能要和当前已经是先的 fft module 对标;当前是双击直接悬浮弹窗 fft 窗体"
- 现状(F6 50834d7 落地后):xilink 链路 transfer mini-node 仅有 dock 入口(DrawerDockTransfer + Smaart 4 chart + 6 控件)· 没有双击 popup 路径
- ADR-21 起草时漏写"对标 FFT popup 双击"协议 · ADR-21-R1 §3.4-R1 修订加双路径 · Smaart 4 chart 主入口迁移到 popup
- F6 50834d7 已抽 useTransferFrame composable(双 endpoint ref + measure)· popup 复用
- 4 chart 子组件(TransferMag/Phase/Coherence/Delay)F6 已落 · popup 复用 SFC
- 本 fork 工时略多于 F4-R1(0.5d vs 0.8d)因含 4 chart 主入口迁移 + ref/measure 双 selector + 6 控件 UI

【执行步骤】

Step 0 · 真值核查(必跑 · 0.15d)
- git status / git pull origin xistudio --no-rebase
- read frontend_vue3/src/components/popups/FftModulePopup.vue 全文(374 行 · 对标范式)
- read frontend_vue3/src/composables/useTransferFrame.ts 全文(F6 50834d7 抽离 · 看双 endpoint API · popup 复用接口)
- read frontend_vue3/src/stages/xilink/drawers/DrawerDockTransfer.vue 全文(看 Smaart 4 chart 装配 + 6 控件 + ref/measure 双 selector)
- read 4 chart 子组件(TransferMag/Phase/Coherence/Delay · 路径 stages/xilink/drawers/transfer/* 或 components/charts/)
- read frontend_vue3/src/composables/usePopupModuleManager.ts(API 签名)
- read frontend_vue3/src/stages/xilink/LinkEditor.vue 行 120-160 + 1500-1640(onModuleDoubleClick 现有实现)
- grep -r "transfer_v1\|transferModule\|transfer-module" frontend_vue3/src(看 transfer-module 注册位置)
- 输出真值核查到 commit body:
  · FftModulePopup props/emits 完整签名(给 TransferModulePopup 对齐)
  · useTransferFrame 双 endpoint API(给 popup 复用)
  · 4 chart 子组件路径 + props/emits(popup 装配)
  · 6 控件清单(fftSize/averaging/windowFunction/coherenceThreshold/delayCompensation/delayMs · 从 dock 移到 popup)
  · transfer-module typeId 0x100E0005 + moduleId 字符串(LinkEditor 双击判定)

Step 1 · 新建 TransferModulePopup.vue(0.4d · 含 4 chart + 6 控件 + ref/measure 双 selector)
- 新建 frontend_vue3/src/components/popups/TransferModulePopup.vue
- 严格对标 FftModulePopup.vue 骨架:
  · props: `{ config: TransferModuleConfig, x: number, y: number, zIndex: number }`
  · emits: `{ close: [], bringToFront: [], move: [x: number, y: number] }`
  · template:macOS 风格 header(交通灯 ⊗ + 拖拽 + 标题 "Transfer Function") + 主区(ref/measure 双 selector 顶部 + Smaart 4 chart 网格 + 6 控件底部)
  · ref/measure 双 selector:沿用 F1-R1 后 3 类节点(input/output/log_module)+ ch index 选择
  · Smaart 4 chart 网格(2x2 或 1x4):
    - Mag chart:dB 频响 · 横轴 Hz log
    - Phase chart:wrapped 相位 [-π, π]
    - Coherence chart:0~1 · threshold 0.7 标红区域
    - Delay finder chart:GCC-PHAT 锁定 ms
  · 6 控件区:fftSize 下拉 · averaging 下拉 · windowFunction 下拉 · coherenceThreshold slider · delayCompensation 切换 · delayMs 输入(manual 模式)
  · 默认尺寸:800×500(略大于 FftModulePopup 因 4 chart)· resizable
  · macOS 风格 + theme-aware(对齐 ADR-12 §2.11 第 9 项 design-token)
- script:
  · 调 useTransferFrame(F6 50834d7 抽离)· 双 endpoint 订阅 ref + measure
  · 4 chart 装配(复用 F6 已落子组件 · 不重写 chart 渲染)
  · 6 控件双向绑定 useTransferFrame 内部 state
  · 5s timeout fallback(沿用 ADR-21-R1 §3.4-R1 ③ 失败回退)

Step 2 · usePopupModuleManager 注册 transfer-module(0.05d)
- 编辑 frontend_vue3/src/composables/usePopupModuleManager.ts(若需扩)
- moduleId → popup component 映射加:`transfer-module: defineAsyncComponent(() => import('@/components/popups/TransferModulePopup.vue'))`

Step 3 · LinkEditor 补 transfer 双击路由(0.1d · 同 F4-R1 模式)
- 编辑 frontend_vue3/src/stages/xilink/LinkEditor.vue
- 沿用 F4-R1 已 patch 的 onModuleDoubleClick switch case 模式(若 F4-R1 已 zombie)
- 加 transfer 路由:若 `module.moduleId === 'transfer-module'` 或 typeId 0x100E0005 → 调 `usePopupModuleManager.openModulePopup('transfer-module', module.instanceId, $event.clientX, $event.clientY)`
- 不动行 353/1610 子图协议

Step 4 · vitest 单测(0.15d)
- 新增 frontend_vue3/tests/components/TransferModulePopup.test.ts(≥ 6 case):
  · case 1:渲染 props {config, x, y, zIndex} · template 顶级 div 含正确 style
  · case 2:close 按钮 click · emit 'close'
  · case 3:header mousedown.capture · emit 'bringToFront'
  · case 4:ref/measure 双 selector 切换(input/output/log_module 各组合)· 验 useTransferFrame 重订阅
  · case 5:Smaart 4 chart 子组件全装配(Mag/Phase/Coherence/Delay)· 验 4 个 dom 节点存在
  · case 6:6 控件双向绑定(fftSize 切换 · averaging 切换等)· 验 config 同步更新

Step 5 · build + test + 手动 e2e(0.1d)
- cd frontend_vue3
- npm run typecheck(零错误)
- npm run test:unit(基线 +6 case 全绿 · 已知 3 fail 不增)
- 手动 e2e(浏览器):
  · npm run dev
  · 进 P1-xilink stage · 加载链路含 transfer-module 节点(typeId 0x100E0005)+ source + sink + log_module
  · 双击 transfer mini-node → TransferModulePopup 浮现 ≤ 200ms · 默认位置不超 viewport
  · ref selector 选 source ch1 · measure selector 选 sink ch1 · 启动 averaging
  · 等 3s 收敛 · 验 Smaart 4 chart 渲染:
    - Mag chart 显 -3dB@1kHz(fixture)
    - Phase chart wrapped 在 [-π, π]
    - Coherence > 0.95(直连场景)
    - Delay finder 锁定 4ms ± 0.1ms
  · 切 measure ch2 · 看右声道差异
  · 切 6 控件(fftSize/averaging 等)· 验 chart 同步刷新
  · 拖拽 popup header · 验位置变更
  · 关 popup · 验消失 · transfer mini-node 链路状态保持
  · popup ↔ dock 独立性测试:同时打开 popup + dock · ref/measure 选择独立

Step 6 · commit + push(0.05d)
- git add frontend_vue3/src/components/popups/TransferModulePopup.vue(新建) \
          frontend_vue3/src/composables/usePopupModuleManager.ts(若改) \
          frontend_vue3/src/stages/xilink/LinkEditor.vue \
          frontend_vue3/src/stores/moduleLibrary.ts(若改) \
          frontend_vue3/tests/components/TransferModulePopup.test.ts
- git commit subject + trailer 见下
- git push origin xistudio
- 反馈 Cline-AIOS:zombie hash + 浏览器实测截图(双击 → popup + Smaart 4 chart 渲染)+ 6 控件操作截图

【验收】

形式合规:
- [ ] npm run typecheck 零错误
- [ ] npm run test:unit 全绿(基线 +6 case · 已知 3 fail 不增)
- [ ] 仅修动 4-5 文件(1 新建 popup + 1-2 改 LinkEditor/manager + 1 tests)
- [ ] 不破坏 FftModulePopup / RMSMeterModulePopup / ScopeModulePopup / PhaseModulePopup(F4-R1 zombie 后)现有行为
- [ ] 不破坏 LinkEditor 行 353/1610 子图双击协议
- [ ] 不动 dock 路径(F2-R1 范畴)· 不动 dsp_algo F5 算法层

业务行为契约(端到端真值 · 必跑):
- [ ] **双击 transfer mini-node → TransferModulePopup 浮现 ≤ 200ms**(ADR-21-R1 §3.4-R1 ② 关键判据)
- [ ] popup props/emits 严格对标 FftModulePopup
- [ ] **Smaart 4 chart 主入口迁移到 popup**:Mag / Phase / Coherence / Delay 4 chart 渲染正确(ref=source ch1 + measure=sink ch1 + 4ms delay fixture)
- [ ] ref/measure 双 selector 沿用 F1-R1 后 3 类节点 + ch index
- [ ] 6 控件(fftSize/averaging/windowFunction/coherenceThreshold/delayCompensation/delayMs)在 popup 内可用
- [ ] popup ↔ dock 状态独立(同时打开互不影响)
- [ ] 5s timeout fallback 在 mock WS 永不响应时触发

【commit】
subject:`feat(P1.UA21R1.F6-transfer-popup-frontend): 新建 TransferModulePopup 双击悬浮窗 + Smaart 4 chart 主入口迁移 · ADR-21-R1 §3.4-R1`

trailer(必须精确):
[step=6/6] [pid=P1] [uid=UA21R1.F6-transfer-popup-frontend] [occupies=P1.K-xilink-popup+P1.K-xilink-canvas]
[files=frontend_vue3/src/components/popups/TransferModulePopup.vue, src/composables/usePopupModuleManager.ts, src/stages/xilink/LinkEditor.vue, src/stores/moduleLibrary.ts, tests/components/TransferModulePopup.test.ts]
[isolation] file(同 worktree 同 branch · 与 F2-R1/F4-R1 文件正交)
[adr] ADR-AIOS-21-R1 §3.4-R1 + §4.2 F6-R1
[derived_from] supersede F6 50834d7 部分(加 popup + Smaart 4 chart 主入口迁移 · DrawerDockTransfer 由 F2-R1 cleanup · 不删)
[parent_zombie] eb84bab(F5 算法层 · 复用 GCC-PHAT)+ 50834d7(F6 frontend · 复用 useTransferFrame + 4 chart 子组件)
[truth-check] FftModulePopup 范式对标点=<行号> · useTransferFrame 双 endpoint API=<签名> · 4 chart 子组件路径=<具体> · transfer typeId=0x100E0005
[acceptance] 双击 mini-node → popup ≤ 200ms + Smaart 4 chart + ref/measure 双 selector + 6 控件 + popup/dock 独立

【禁止】
1. ❌ 不动 backend_csharp/ / dsp_algo/ / contracts/
2. ❌ 不动 F5 eb84bab 算法层(typeId / GCC-PHAT / frame schema)
3. ❌ 不重写 F6 50834d7 useTransferFrame composable(沿用即可)
4. ❌ 不重写 F6 4 chart 子组件(TransferMag/Phase/Coherence/Delay · 仅 popup 内装配复用)
5. ❌ 不动 dock 路径(DrawerDockTransfer 由 F2-R1 cleanup · 本 fork 仅 popup)
6. ❌ 不动 LinkEditor 行 353/1610 子图双击协议
7. ❌ 不破坏 FftModulePopup / RMSMeterModulePopup / ScopeModulePopup / PhaseModulePopup(F4-R1)现有行为
8. ❌ 不在 popup 内做数学计算(L3 前端零数学 · GCC-PHAT 在 dsp_algo F5)
9. ❌ 硬编码 hex 颜色(对齐 ADR-12 §2.11 第 9 项 · design-token)
10. ❌ commit message 缺三元组 trailer 任一字段

解锁链(本任务 zombie 后)

  • ✅ transfer 双路径全打通(popup 主入口 + F2-R1 cleanup 后 dock 辅助入口)
  • ✅ 配合 F1-R1 + F2-R1 + F4-R1 全 zombie → P_e2e.A21R1.F7 e2e ready
  • 🏆 用户实测"transfer 双击 → 浮动窗 + Smaart 4 chart"对标 FFT 范式达成

风险评估

风险 缓解
⚠️ Smaart 4 chart + 6 控件 + ref/measure 双 selector 工时密度大 0.8d 预算 · F6 50834d7 已落 4 chart 子组件 + useTransferFrame · 复用度高
⚠️ 4 chart 子组件路径(F6 50834d7 落地 · stages/xilink/drawers/transfer/ 或 components/charts/transfer/) Step 0 真值核查必明确路径 + props/emits · popup 装配时不重写
⚠️ ref/measure 双 selector 在 popup 内布局占空间(顶部) 默认尺寸 800×500(略大于 FftModulePopup 600×380)· resizable
⚠️ 与 F4-R1 共改 LinkEditor onModuleDoubleClick · git pull 冲突 等 F4-R1 zombie 后 pull · 在已 patch 的 switch case 内加 transfer case
⚠️ useTransferFrame 双 endpoint(ref + measure)在 popup 与 dock 双端使用 · store 隔离 F6 50834d7 useTransferFrame 应已支持多 instance · popup 与 dock 各起 1 instance · store key 不同
⚠️ popup 默认位置策略 沿用 usePopupModuleManager · 不自创
⚠️ 与 F2-R1 / F4-R1 同 ClaudeA worker 并行 git pull 串行 commit · 文件正交时 git pull --no-rebase 自动合并

历史

时间 事件 hash
2026-06-15 11:30 ADR-21-R1 v0.1 proposed · 起本 R1 hotfix(F6-R1 · ready 状态等用户 accept ADR-21-R1 + start)
(待) dispatched
(待) zombie