# Changelog: Vuetify 前端审计修复

**日期**: 2026-05-31
**主题**: 5个严重问题修复 + DRY 重构 + 类型安全

## 变更摘要

### 1. 提取 useSnackbar composable（DRY 重构）
- **新建** `src/composables/useSnackbar.ts` — 统一 snackbar 包装函数
- **新建** `src/types/global.d.ts` — `Window.$snackbar` 全局类型声明
- **修改 8 个页面** — 删除各自重复的 `function snackbar(...)` 定义，改为 `import { useSnackbar }`
- **修改** `App.vue` — `(window as any).$snackbar` → `window.$snackbar`
- **修改** `useWebSocket.ts` — 同上

### 2. API client FormData 支持（🔴 严重 #1 + 🟠 #12）
- **修改** `src/api/index.ts`:
  - `body instanceof FormData` 时不设 `Content-Type`（浏览器自动加 boundary）
  - 新增 `http.upload()` 方法
- **修改** `FilesPage.vue` `doUpload()`:
  - `fetch('/api/sync/upload')` → `http.upload('/sync/upload', form)`
  - 修复：文件上传现在自动携带 JWT Authorization header

### 3. 修复 6 个静默 catch 块（🔴 严重 #3）
- `FilesPage.vue` — `loadServers()` / `browse()` catch 加 snackbar 错误提示
- `SettingsPage.vue` — `loadSettings()` / `loadAllowlist()` catch 加 snackbar 错误提示
- `DashboardPage.vue` — `loadStats()` / `loadServers()` catch 加 snackbar 错误提示

### 4. SettingsPage API Key 密码验证对话框（🔴 严重 #2）
- **新增** `<v-dialog>` 密码输入对话框（与 TOTP Disable 对话框模式一致）
- `revealApiKey()` → 先弹密码对话框 → `doRevealApiKey()` 用真实密码调用后端
- 修复：不再发送空密码 `{ password: '' }` 绕过 re-auth 保护

### 5. DashboardPage 数据补全（🔴 严重 #5）
- **新增** `loadAlerts()` — 从 `GET /alert-history/?limit=5` 加载告警历史
- **新增** `loadSummary()` — 从 `GET /servers/?per_page=500` 计算:
  - Agent 覆盖率（有 agent_version 的服务器比例）
  - CPU 平均值（从 system_info.cpu_usage）
  - 内存平均值（从 system_info.mem_usage）
- **新增** WebSocket 实时刷新 — 监听 ws.alerts 变化自动刷新 stats + alerts

### 6. 消除 as any 类型断言（🔴 严重 #4）
- **新建** `src/types/api.ts` — 14 个 API 响应 interface:
  - `PaginatedResponse<T>`, `SettingsResponse`, `AllowlistResponse`, `BrowseResponse`
  - `FileEntry`, `ServerApiItem`, `AlertLogItem`, `AlertStatsResponse`
  - `CommandLogItem`, `RetryItem`, `ScriptItem`, `PushItem`, `ScheduleItem`, `AuditItem`
- **修改 12 个页面** — 所有 `(res as any).items` 改为 `http.get<PaginatedResponse<T>>()`
- **结果**: `as any` 从 33 个降到 0 个（src/ 目录完全清零）

## 涉及文件

| 文件 | 操作 |
|------|------|
| `src/composables/useSnackbar.ts` | 新建 |
| `src/types/global.d.ts` | 新建 |
| `src/types/api.ts` | 新建 |
| `src/api/index.ts` | 修改 |
| `src/App.vue` | 修改 |
| `src/composables/useWebSocket.ts` | 修改 |
| `src/pages/FilesPage.vue` | 修改 |
| `src/pages/SettingsPage.vue` | 修改 |
| `src/pages/DashboardPage.vue` | 修改 |
| `src/pages/CredentialsPage.vue` | 修改 |
| `src/pages/RetriesPage.vue` | 修改 |
| `src/pages/PushPage.vue` | 修改 |
| `src/pages/ScriptsPage.vue` | 修改 |
| `src/pages/SchedulesPage.vue` | 修改 |
| `src/pages/ServersPage.vue` | 修改 |
| `src/pages/CommandsPage.vue` | 修改 |
| `src/pages/AlertsPage.vue` | 修改 |
| `src/pages/AuditPage.vue` | 修改 |
| `src/pages/TerminalPage.vue` | 修改 |

## 验证

- ✅ `vue-tsc --noEmit` — TypeScript 零错误
- ✅ `vite build` — 生产构建通过 (1.53s, Monaco 懒加载)
- ✅ 开发服务器正常启动

---

## Phase 2: Composables + UX + 核心功能 (同日)

### Composables 提取 (Step 7)
- **新建** `src/composables/useServerList.ts` — 5 个页面复用
- **新建** `src/composables/useServerPagination.ts` — ServersPage/DashboardPage 复用
- **新建** `src/utils/status.ts` — statusChipColor/statusLabel/formatRelativeTime

### 表单验证 + 空状态 + Loading (Step 8)
- **新建** `src/utils/validation.ts` — 8 个验证规则工厂
- **12 个空状态** — 9 个文件的 v-data-table 加 `<template #no-data>`
- **14 个表单字段** — SettingsPage/ServersPage/ScriptsPage/SchedulesPage/CredentialsPage 加 `:rules`
- **~20 个 loading 态** — ScriptsPage/SettingsPage/CredentialsPage/SchedulesPage/FilesPage

### 核心功能补全 (Step 9)
- ✅ Servers 批量操作（多选 + 健康检查 + 批量删除）
- ✅ Servers CSV 导出
- ✅ Servers 详情面板（系统信息 + 同步日志 tab）
- ✅ Push 同步模式（增量/全量/校验和 + 警告提示）
- ✅ Push ZIP 拖拽上传
- ✅ Push WebSocket 实时进度（逐服务器状态 + 进度条）
- ✅ Scripts 快捷执行面板（临时命令 + Ctrl+Enter）
- ✅ Scripts 执行状态追踪（5s 自动轮询 + 停止按钮）
- ✅ Files Monaco 编辑器（全屏 + 语法高亮 + Ctrl+S 保存 + 主题切换）
- ✅ Dashboard WebSocket 实时刷新（watch alerts）

### 新建文件总计
- `src/composables/useSnackbar.ts`
- `src/composables/useServerList.ts`
- `src/composables/useServerPagination.ts`
- `src/types/global.d.ts`
- `src/types/api.ts`
- `src/utils/status.ts`
- `src/utils/validation.ts`
- `src/components/MonacoEditor.vue`

## 动机

审计发现 5 个严重问题（安全漏洞 + 数据错误）和大量 DRY 违规/类型安全问题，需要在对接真实 API 数据之前修复。

## 是否需迁移/重启

- 不需要数据库迁移
- 不需要后端重启（纯前端修改）
- 需要重新构建前端：`cd frontend && npx vite build`

## 验证方式

1. TypeScript: `cd frontend && npx vue-tsc --noEmit`
2. 构建: `cd frontend && npx vite build`
3. 功能验证:
   - FilesPage 上传 → 携带 JWT（不再 401）
   - SettingsPage API Key → 弹出密码输入对话框
   - Dashboard → 告警历史有数据、Agent 覆盖率/CPU/内存有值
   - 所有页面 snackbar 错误提示正常
