实施计划 — 脚本库全局执行进度 + Telegram 通知
日期: 2026-06-08
设计: 2026-06-08-script-exec-global-progress-telegram-design.md
分期概览
| 阶段 |
内容 |
估时 |
依赖 |
| P0 |
后端异步 exec + terminal hook |
1d |
— |
| P1 |
WS script_progress / script_complete |
0.5d |
P0 |
| P2 |
Telegram send_telegram_script_complete |
0.5d |
P0 |
| P3 |
前端全局 SnackbarQueue + Progress + Alert + 声音 |
1d |
P1 |
| P4 |
ScriptsPage 接入 / 移除页内面板 |
0.5d |
P3 |
| P5 |
测试、changelog、audit、部署 |
0.5d |
P0–P4 |
合计:约 3–4 人日(单 Agent 连续实施)。
P0 — 后端:异步执行(关键路径)
涉及文件
步骤
execute_command 创建 DB/Redis 记录后 asyncio.create_task(_run_execution_batches(...))。
- 将现有 batch 循环移入
_run_execution_batches,逻辑不变。
- Task 顶层
try/except:异常时 apply_update(status=failed, terminal=True)。
- API 返回
get_execution_detail(id)(status=running, progress=0/N)。
- 注意:同一 worker 内 task 即可;多 worker 时 Redis live 已是 SSOT(已满足)。
测试
tests/test_script_execution_async.py:mock dispatch,断言 POST /exec 立即返回 & 后台终态。
P1 — WebSocket 进度广播
涉及文件
步骤
- 定义消息 schema(见 design doc)。
- 每批
batch_progress 或每台完成后推送(366 台建议每完成 1 台或每批推送,避免 WS 风暴可 batch 每 5 台)。
- 前端 useWebSocket.ts 解析
script_progress / script_complete。
P2 — Telegram 脚本执行结果
涉及文件
步骤
- 复用
send_telegram_sync_complete 结构与 _notify_enabled。
- 失败明细:查 server repo 取 name;summary 用
sanitize_external_message。
- 超长分片或截断 + 指向 execution #id。
- 单测:mock httpx,断言 HTML 含失败台名。
P3 — 前端全局 UI(Vuetify 4)
涉及文件
| 文件 |
变更 |
| frontend/src/App.vue |
VSnackbarQueue 替换单条 v-snackbar;挂载 ScriptExecProgressHost |
新建 frontend/src/components/script/ScriptExecProgressHost.vue |
Queue item 模板:ProgressLinear chunks + 文案 |
新建 frontend/src/composables/useScriptExecutionQueue.ts |
track / onProgress / onComplete / playSound |
新建 frontend/src/components/script/ScriptExecCompleteAlert.vue |
VAlert closable + 1s leave transition |
frontend/public/notify.mp3 或 assets |
提示音(短、免版权) |
UI 行为
- 进行中:SnackbarQueue 顶部,
location="top",timeout="-1"(手动关闭或完成关闭)。
- 进度条:
v-progress-linear rounded height="6" :model-value="done/total*100" :buffer-value="..." 制造流动感(见 Vuetify chunks 示例)。
- 完成:
- Snackbar queue 项 resolve(Promise API)。
- 显示
VAlert(type=success/warning/error),closable,点击关闭触发 v-fade-transition 1000ms。
new Audio(...).play().catch(() => {})(静默处理自动播放策略拦截)。
- Alert 可点「查看详情」→
router.push('#/scripts') + openExecDetail(id)(通过 event bus 或 query)。
与现有 $snackbar 兼容
- 保留
window.$snackbar 给普通 toast;脚本进度走独立 queue,避免互相覆盖。
P4 — ScriptsPage 接入
涉及文件
步骤
doRun / doQuickExec:POST 成功后 showRun=false,调用 queue.track(id, label, total)。
- 移除
trackedExecs / pollTimer / activeTrackedExecs(逻辑迁至 composable)。
- WS 断线时 composable 降级 3s 轮询直至终态。
P5 — 验证与交付
手动验收
- 生产 10 台脚本:顶部进度 + 完成 Alert + 声音。
- 366 台(或 staging):Telegram 汇总与失败明细。
- 关闭 Telegram 通知设置后无推送。
文档
docs/changelog/2026-06-08-script-exec-global-progress-telegram.md
docs/audit/2026-06-08-script-exec-global-progress-telegram.md
- 更新 AI-HANDOFF-2026-06-08.md
回滚
- 后端:revert commit;进行中的 execution 靠 Redis live 继续,无 schema 迁移。
- 前端:revert + vite build deploy。
风险与对策
| 风险 |
对策 |
| 366 台 WS 消息过多 |
节流:每批或每 5 台推送一次 |
| 浏览器拦截自动播放 |
首次用户手势后解锁;Alert 仍可见 |
| 异步 exec 重复提交 |
可选:同脚本 running 时 confirm(P4+) |
| Telegram 过长 |
截断 + 链接 execution id |
| 多 Tab 重复声音 |
localStorage leader election 或仅 focused tab 播放 |
建议实施顺序(给 Agent)
请先确认设计再写代码(perfect-implementation 纪律)。