+
+
+ -
+ 确认下发已确认
+
+ -
+ 已下发{{ commandProgress.step >= 2 ? '等待应答' : '…' }}
+
+ -
+
+ {{ commandProgress.status === 'acked' ? '已确认' : (COMMAND_STATUS[commandProgress.status]?.name || '执行结果') }}
+ {{ commandProgress.error || commandProgress.result || '…' }}
+
+
+
+```
+
+注意:模板里若不能直接用 `COMMAND_STATUS`,改成 computed `commandProgressTerminalLabel`。
+
+- [ ] **Step 3: 增加样式**
+
+`prototype.css` 追加:
+
+```css
+.command-progress-float {
+ position: absolute;
+ right: 18px;
+ bottom: 56px;
+ z-index: 36;
+ width: 280px;
+ padding: 12px 12px 10px;
+ border: 1px solid var(--line);
+ border-radius: 8px;
+ background: rgba(255,255,255,.96);
+ box-shadow: 0 10px 28px rgba(20, 34, 48, .18);
+ color: #334553;
+}
+.command-progress-float > header {
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ gap: 8px;
+ margin-bottom: 10px;
+}
+.command-progress-float > header strong { display: block; font-size: 13px; }
+.command-progress-float > header small { color: var(--muted); font-size: 11px; }
+.command-progress-float ol { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }
+.command-progress-float li {
+ display: grid;
+ grid-template-columns: 14px 1fr auto;
+ align-items: center;
+ gap: 8px;
+ min-height: 28px;
+ color: #7b8792;
+ font-size: 12px;
+}
+.command-progress-float li i {
+ width: 10px; height: 10px; border-radius: 50%;
+ border: 1.5px solid #c0CAD3; background: #fff;
+}
+.command-progress-float li.active { color: #1f5f9f; font-weight: 600; }
+.command-progress-float li.active i { border-color: #2d82da; background: #2d82da; }
+.command-progress-float li.done { color: #2f6b4f; }
+.command-progress-float li.done i { border-color: #2f9d6a; background: #2f9d6a; }
+.command-progress-float li.fail { color: #a53e45; }
+.command-progress-float li.fail i { border-color: #c8454b; background: #c8454b; }
+.command-progress-float li em { font-style: normal; color: var(--muted); font-size: 11px; }
+```
+
+- [ ] **Step 4: Commit**
+
+```bash
+git add src/views/MonitorView/MonitorView.vue src/styles/prototype.css
+git commit -m "feat: 增加指令进度浮窗与按钮状态文案"
+```
+
+---
+
+### Task 4: 浏览器冒烟
+
+**Steps:**
+
+- [ ] **Step 1: 启动前端,mock 指令接口**
+
+对监控页:
+
+1. 登录进 `/monitor`,选中在线机巢。
+2. 拦截:
+ - `POST /api/v1/docks/:id/command` → `{ code:200, data:{ id: 1001, status:'sent', ttlMs:30000, commandType:'dock.open' } }`
+ - 前 2 次 `GET /api/v1/commands/1001` → `status:'sent'`
+ - 之后 → `status:'acked', ackResultCode:'OK'`
+3. 点击「打开舱门」或「一键起飞」并确认。
+
+- [ ] **Step 2: 验收清单**
+
+1. 浮窗出现,步骤 1 完成 → 步骤 2「已下发/等待应答」→ 步骤 3「已确认/执行成功」。
+2. 对应按钮 `small` 变为「状态:已下发」再变「状态:已确认」。
+3. 终态约 5s 后浮窗自动关闭;期间可手动关。
+4. Escape 可关闭浮窗。
+5. 连续点另一条指令:浮窗切换到新指令。
+6. 离线设备:仅 toast,不出现成功浮窗。
+
+- [ ] **Step 3: Commit 验收说明(若有小修)**
+
+若冒烟中修了样式/边界,单独 commit:
+
+```bash
+git add -A
+git commit -m "fix: 指令进度浮窗冒烟问题"
+```
+
+---
+
+## 覆盖对照(spec)
+
+| Spec 要求 | Task |
+|-----------|------|
+| 下发后浮窗 + 三步状态 | Task 2/3 |
+| 轮询 `/v1/commands/:id` 1.5s,TTL+5s | Task 2 |
+| 按钮 small 同步 | Task 3 |
+| 终态 5s 自动关 / 手动关 / Escape | Task 2/3 |
+| 同设备新指令替换跟踪 | Task 2 `startCommandProgress` |
+| 403/404/连续失败 | Task 2 `pollCommandOnce` |
+| 不改后端协议 | 全程 |
+
+## 执行注意
+
+- 不要改 `devicesStore.sendCommand` 的返回值语义(已返回 cmd)。
+- 不要引入 WebSocket。
+- 工作流子步骤(开门/归中)不在本计划范围。