135 lines
5.8 KiB
Markdown
135 lines
5.8 KiB
Markdown
# 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 错误提示正常
|