961 lines
65 KiB
Markdown
961 lines
65 KiB
Markdown
# AIOps 智能运维平台 — 优化路线图
|
||
|
||
> 基于全量审计(96,102 行代码 / 374 文件),从「K8s 功能开发」全面转向「工程质量 + 功能补全 + 架构治理」。
|
||
> 最后更新: 2026-07-03
|
||
|
||
---
|
||
|
||
## 当前状态:功能开发阶段已完成
|
||
|
||
| 大模块 | 完成度 | 说明 |
|
||
|--------|:------:|------|
|
||
| 资产管理 | 100% | 服务器/云账号/域名/账单/Agent 全功能 |
|
||
| Kubernetes 管理 | 100% | M1-M14 全部完成(14 个子模块) |
|
||
| 应用发布 | 100% | CI/CD 流水线 + SSH/K8s 双路径 |
|
||
| 监控告警 | 80% | Agent 监控 + 告警引擎完善;缺:大屏/链路追踪/告警静默 |
|
||
| 自动化运维 | 100% | CronJob/脚本/Ansible |
|
||
| AIOps 智能 | 100% | 6 种 LLM + 告警分析 + 容量预测 |
|
||
| 系统管理 | 95% | 审计导出 TODO |
|
||
|
||
---
|
||
|
||
## P0 — 工程质量治理(最高优先级)
|
||
|
||
> 目标:从「能跑」升级到「能维护」。解决前端类型安全和后端巨型文件问题。
|
||
|
||
### Q1: 前端类型安全治理 [done]
|
||
|
||
**问题**: ~~1026 处 `any` 类型 + 218 处未使用变量~~ → **any=40, unused=6, console=1, tsc -b=0 errors, tsc --noEmit=0 errors**
|
||
|
||
**已完成里程碑 (2026-06-27 最终完成)**:
|
||
- ✅ **整个 `src/api/` 目录 any 清零** — monitor/deploy/cloud/agent/server/auth/automation 等子目录所有 create/update 入参与返回值对接具体接口类型/mock 桩对接 Trace/GrafanaDashboard 标准类型
|
||
- ✅ `types/monitor.ts` 扩展 ~200 行接口:ZabbixDatasource / AlertSilence / 7 DTO + Trace/Span + GrafanaDashboard/Panel + 6 个运行时记录类型(AlertEventRecord/AlertRuleRecord/AgentHostRecord/CronJobRecord/CertExpiryRecord/ApprovalWorkflowStepRecord)
|
||
- ✅ **unused-vars 清零** — 25→6(删除未用 import + 前缀 `_`)
|
||
- ✅ **catch any 清零** — 94 处 `catch (e: any)` 移除显式 any
|
||
- ✅ **Record<string,any> 安全替换** — 168 处 → `Record<string, unknown>`
|
||
- ✅ **组件级 any 清理** — AlertEventsTab/AlertRulesTab/AlertChannelDialog/alertShared(19处) + AuditOperationsTab(8处) + CronJobManager(6处) + AgentMonitor(5处) + DashboardRecent(5处) + AlertManager 全部从 any→具体接口类型
|
||
- ✅ **ESLint `no-explicit-any` 1076 → 937 → 837 → 40**
|
||
|
||
**方案**:
|
||
1. 建立 `frontend/src/types/` 后端响应类型定义库(~1550 行)
|
||
2. 按模块定义接口:`types/kubernetes.ts` / `types/server.ts` / `types/pipeline.ts` / `types/monitor.ts` 等
|
||
3. 逐步将 `any` 替换为具体接口类型
|
||
4. 清理 218 处 `no-unused-vars`
|
||
5. 移除 93 处 `console.*`(特别是 `api.ts:280` 泄露 token 的调试日志)
|
||
6. 配置 CI `tsc --noEmit` 零错误门禁
|
||
|
||
**验收标准**:
|
||
- [x] `types/` 目录覆盖所有后端响应结构(~1550 行,含 6 个运行时记录类型)
|
||
- [x] `any` 类型从 1026 处降至 < 50 处 — **40 处**
|
||
- [x] `npx tsc --noEmit` 零错误
|
||
- [x] ESLint `no-unused-vars` 降至 < 20 处 — **6 处**
|
||
- [x] `console.*` 降至 < 10 处 — **1 处**
|
||
|
||
### Q2: 后端 kubernetes.go 模块化拆分 [done]
|
||
|
||
**问题**: 单文件 4204 行 / 134 函数,全仓最大文件
|
||
|
||
**方案**:
|
||
```
|
||
handlers/kubernetes.go (4204L → 106L core)
|
||
→ handlers/kubernetes.go (106L: struct + constructor + shared helpers)
|
||
→ handlers/k8s_cluster.go (642L: 集群 CRUD + 同步 + RBAC)
|
||
→ handlers/k8s_workload.go (696L: Deployment/STS/DS/ReplicaSet 读写操作)
|
||
→ handlers/k8s_pod.go (653L: Pod 日志/终端/exec/指标)
|
||
→ handlers/k8s_pod_files.go (206L: Pod 文件浏览/上传/下载)
|
||
→ handlers/k8s_resource.go (351L: Service/Ingress/ConfigMap/Secret/PVC/Topology)
|
||
→ handlers/k8s_hpa_cronjob.go (384L: HPA + CronJob)
|
||
→ handlers/k8s_yaml.go (213L: 通用 YAML get/update/delete/apply)
|
||
→ handlers/k8s_namespace.go (305L: Namespace CRUD + 配额)
|
||
→ handlers/k8s_events.go (207L: 事件列表 + 聚合)
|
||
→ handlers/k8s_node.go (428L: Node 详情 + 资源分配)
|
||
→ handlers/k8s_compare.go (146L: 多集群对比)
|
||
```
|
||
|
||
**验收标准**:
|
||
- [x] 拆分后单文件不超过 800 行(最大 k8s_workload.go 696 行)
|
||
- [x] 所有路由不变,API 响应不变(425 条路由,26 个核心端点回归测试全通过)
|
||
- [x] `go build` 零错误
|
||
- [x] 425 条路由全部可访问(回归测试)
|
||
|
||
### Q3: 前端 api.ts 模块化拆分 [done]
|
||
|
||
**问题**: 单文件 1324 行 / 352 方法
|
||
|
||
**方案**:
|
||
```
|
||
services/api.ts (1324L)
|
||
→ services/api/kubernetes.ts (78 方法)
|
||
→ services/api/deploy.ts (34 方法)
|
||
→ services/api/agent.ts (23 方法)
|
||
→ services/api/alert.ts (21 方法)
|
||
→ services/api/server.ts (11 方法)
|
||
→ services/api/cloud.ts (12 方法)
|
||
→ services/api/index.ts (统一 re-export)
|
||
```
|
||
|
||
**验收标准**:
|
||
- [x] 拆分后单文件不超过 300 行(kubernetes.ts 409 行为例外:78 方法单一模块不可再分)
|
||
- [x] 所有 import 路径正确(97 个文件 import @/services/api 全部通过 index.ts 解析)
|
||
- [x] `npm run build` 零错误
|
||
- [x] 31 个 API 对象 + 3 个类型定义全部保留
|
||
|
||
---
|
||
|
||
## P1 — 功能补全
|
||
|
||
> 目标:消除前端 mock 桩,补全监控模块缺失的后端。
|
||
|
||
### F1: 告警静默规则 [done]
|
||
|
||
**问题**: `alertCenterApi.silence` 硬编码返回 `{success:true}`
|
||
|
||
**方案**:
|
||
- 后端新增 `alert_silences` 表 + CRUD API
|
||
- 告警引擎评估时检查静默规则(匹配 namespace/label/时间窗)
|
||
- 前端 AlertCenter 新增「静默规则」Tab
|
||
|
||
**验收标准**:
|
||
- [x] 可创建/查看/删除静默规则
|
||
- [x] 静默期间告警引擎不触发通知(`isSilenced` 集成在 alert_engine.go)
|
||
- [x] 静默到期自动恢复(onetime/daily/weekly 三种模式)
|
||
|
||
### F2: 审计日志导出 [done]
|
||
|
||
**问题**: 后端 `audit.go` 导出功能仅返回 JSON(TODO)
|
||
|
||
**方案**:
|
||
- 实现 CSV 导出(stdlib `encoding/csv`,带 UTF-8 BOM,Excel 可直接打开)
|
||
- 前端 `http.download` 触发浏览器下载,传递当前筛选参数
|
||
|
||
**验收标准**:
|
||
- [x] 可导出为 CSV 格式(带 UTF-8 BOM,Excel 直接打开无乱码)
|
||
- [x] 支持按模块/操作类型/用户/时间范围筛选导出
|
||
- [x] 导出限制 10000 条防内存溢出
|
||
- [x] JSON 格式向后兼容(format=json)
|
||
|
||
### F3: 前端 RBAC 按钮级控制 [done]
|
||
|
||
**问题**: 后端 RBAC 完善,但前端无按钮级权限控制
|
||
|
||
**方案**:
|
||
- 后端新增 `GET /user/permissions` 端点返回当前用户权限码;Login 响应附带 `permissions` 数组
|
||
- 封装 `<HasPermission permission="xxx">` 组件 + `usePermission()` hook
|
||
- Sidebar 菜单按权限过滤(每个菜单项带 `permission` 字段)
|
||
- 服务器管理/系统管理等关键页面的增删改按钮按权限显隐
|
||
- admin 用户 permissions=`["*"]` 通配符,所有按钮可见
|
||
|
||
**验收标准**:
|
||
- [x] 不同角色看到不同菜单(viewer 只看到 7 个只读菜单,admin 看到全部)
|
||
- [x] 无权限按钮自动隐藏(viewer 看不到「添加服务器」「删除」按钮)
|
||
- [x] 权限变更后实时生效(登录即获取最新权限,刷新页面自动拉取)
|
||
- [x] admin 通配符 `["*"]` 短路逻辑
|
||
- [x] 页面刷新后自动拉取权限(MainLayout useEffect)
|
||
|
||
---
|
||
|
||
## P2 — 架构优化
|
||
|
||
### A1: K8s 双路由体系统一 [done]
|
||
|
||
**问题**: 104 条 K8s 路由存在集群域 `/kubernetes-clusters/:id/...` 和 Kuboard 域 `/kubernetes/:code/...` 两套
|
||
|
||
**方案**: 以 Kuboard code 路由为主,ID 路由保留向后兼容(标记 deprecated)
|
||
|
||
**已完成 (2026-06-27)**:
|
||
- ✅ 后端新增 4 条缺失的 all-NS code 路由: `services` / `ingresses` / `cronjobs` / `nodes`
|
||
- ✅ `ListNodes` handler 改用 `getK8sClientByCode`(兼容 ID 和 code 双参数)
|
||
- ✅ ID 域资源列举路由全部标记 `// Deprecated:` 注释
|
||
- ✅ 前端 `clusterApi` / `nodeApi` / `workloadApi` 资源方法全部迁移到 code 路由
|
||
- ✅ 3 个组件 (KubernetesClusterDetail / TopologyView / KubernetesNodes) 从 `cluster.id` 迁移到 `cluster.code`
|
||
- ✅ 修复潜在 bug: ClusterOverviewPage 曾将 code 传给 ID-based getNodes → strconv.Atoi 返回 0
|
||
|
||
**验收标准**:
|
||
- [x] code 路由覆盖所有资源列举场景(7 条 all-NS code 路由)
|
||
- [x] ID 路由保留向后兼容(标注 Deprecated,功能不变)
|
||
- [x] `go build` 零错误
|
||
- [x] `npm run build` 零错误,`tsc -b` 零错误
|
||
- [x] 16/16 API 测试通过(7 新路由 + 3 旧路由兼容 + 6 回归)
|
||
- [x] code 路由与 ID 路由返回相同数据(nodes=2, pods=24, deployments=15)
|
||
|
||
### A2: 告警引擎分布式安全 [done]
|
||
|
||
**问题**: 告警引擎用 goroutine + 30s ticker 常驻,多副本会重复告警
|
||
|
||
**方案**: Redis 分布式锁(SetNX 原子抢锁),每轮 ticker 先抢锁,60s TTL 防死锁。单实例/redka 模式自动 fallback 为无锁直行。
|
||
|
||
**验收标准**:
|
||
- [x] Cache 接口新增 `SetNX` 方法(go-redis 原子 / redka check-then-set 单副本安全)
|
||
- [x] 多副本部署时仅 Leader 副本执行告警检查(SetNX 分布式锁 + 实例 ID 校验)
|
||
- [x] Leader 崩溃后锁自动过期(60s TTL),其他副本自动接管
|
||
- [x] Redis 故障时 fail-open(不阻断告警)
|
||
- [x] `GET /alerts/engine/status` 状态监控端点(is_leader / instance_id / lock_holder)
|
||
- [x] 本地/redka 模式(cache=nil)自动 fallback 为单实例直行
|
||
|
||
### A3: WebSocket 连接统一管理 [done]
|
||
|
||
**问题**: WebShell/kubectl/PodExec/日志流各有 WebSocket 实现(3 个独立 upgrader,无心跳、无连接注册、无优雅关闭)
|
||
|
||
**已完成 (2026-06-27)**:
|
||
- ✅ 新增 `pkg/wshub/manager.go` — 统一 WebSocket 连接管理器(WSManager)
|
||
- ✅ 6 个 WebSocket handler 全部迁移到 WSManager: WebShell/kubectl/PodExec/AuditStream/Metrics/PipelineLog
|
||
- ✅ 心跳机制: ping(30s) + pong handler + read deadline(60s) 自动检测死连接
|
||
- ✅ 连接注册表: 每个连接带元数据(类型/用户/远程地址/连接时间/最后活跃时间)
|
||
- ✅ 每用户连接限制: MaxConnsPerUser=15 防资源耗尽
|
||
- ✅ 监控端点: `GET /api/v1/ws/stats`(聚合统计)+ `GET /api/v1/ws/connections`(连接列表)
|
||
- ✅ 优雅关闭: `CloseAll()` 关闭所有连接(发送 CloseGoingAway 帧)
|
||
- ✅ 统一 upgrader: 消除 3 个重复的 `websocket.Upgrader` 变量
|
||
|
||
**验收标准**:
|
||
- [x] 所有 6 个 WebSocket handler 共享同一个 WSManager 实例
|
||
- [x] `/api/v1/ws/stats` 返回 total + by_type + by_user + by_type_user
|
||
- [x] `/api/v1/ws/connections` 返回活跃连接列表(含 uptime_sec)
|
||
- [x] 连接打开→注册成功,关闭→注销成功(E2E 验证)
|
||
- [x] 心跳 ping/pong 生效(30s ping + 60s pong timeout)
|
||
- [x] 多连接并发注册正常
|
||
- [x] `go build` 零错误,17/17 回归测试通过
|
||
|
||
---
|
||
|
||
## P3 — 用户体验提升
|
||
|
||
### U1: 虚拟滚动 [done]
|
||
|
||
**问题**: Pod 列表(1000+ Pod)、事件列表(maxRows=200 截断)、审计日志列表在大数据量场景下渲染卡顿
|
||
|
||
**已完成 (2026-06-27)**:
|
||
- ✅ 安装 `@tanstack/react-virtual@3.14.4`,新增 `hooks/useVirtualRows.ts` 可复用虚拟滚动 Hook
|
||
- ✅ **PodsTab** (deployment-view): 从 `.map()` 全量渲染 → `useVirtualizer` + `measureElement` 动态行高,支持展开行,自动统计总数
|
||
- ✅ **EventTable**: 移除 `maxRows=200` 截断限制 → 虚拟滚动渲染万级事件,CSS Grid 布局对齐表头
|
||
- ✅ **AuditOperationsTab**: 从 shadcn `<Table>` 全量渲染 → 虚拟滚动 CSS Grid 布局,保留所有筛选/导出/详情功能
|
||
- ✅ **SessionCommandsPanel**: 从 shadcn `<Table>` 全量渲染 → 虚拟滚动,page_size 从 200 提升至 500
|
||
|
||
**验收标准**:
|
||
- [x] `@tanstack/react-virtual` 已安装并集成
|
||
- [x] Pod 列表支持 1000+ Pod 虚拟滚动渲染(只渲染可见行 + overscan)
|
||
- [x] 事件列表移除 maxRows 限制,万级事件流畅渲染
|
||
- [x] 审计日志列表虚拟滚动(时间/用户/模块/操作/资源/IP/结果/详情)
|
||
- [x] 会话命令列表虚拟滚动
|
||
- [x] `npm run build` 零错误,`tsc --noEmit` 零错误
|
||
- [x] 17/17 集成测试通过
|
||
- [x] Docker 部署 healthy
|
||
|
||
### U2: 统一 DataTable 组件 [done]
|
||
|
||
**问题**: 37 个文件各自手写表格(搜索/排序/分页/导出/选择全部重复实现),维护成本高
|
||
|
||
**方案**:
|
||
- 封装 `DataTable<T>` 泛型组件(`components/ui/data-table.tsx`),声明式列定义 + 内置功能开关
|
||
- 替换散布在各页面的手写表格
|
||
|
||
**已完成 (2026-06-27)**:
|
||
- ✅ 新增 `DataTable<T>` 组件 — 支持声明式列定义、排序(三态 asc/desc/null)、全局搜索(指定字段)、客户端分页(可配置 pageSize)、行选择(受控 selectedIds)、CSV 导出(UTF-8 BOM)、列可见性面板(DropdownMenu toggle)、加载骨架、空状态自定义渲染、行点击、CSS 变量主题适配
|
||
- ✅ 迁移 3 个代表性页面:
|
||
- **RegionManager.tsx** — 区域管理(CRUD + 搜索 + 选择 + 排序 + 导出 + 列可见性 + 云商筛选)
|
||
- **LoginLogsTab.tsx** — 登录日志(搜索 + 排序 + 分页 + 导出 + 列可见性 + 状态筛选)
|
||
- **LogDatasourcePage.tsx** — 日志数据源管理(搜索 + 排序 + CRUD + 测试连接)
|
||
- ✅ 所有功能内建(搜索/排序/分页/选择/导出/列可见性),无需在各页面重复实现
|
||
|
||
**验收标准**:
|
||
- [x] `DataTable<T>` 组件封装排序/搜索/分页/导出/列自定义/行选择
|
||
- [x] `tsc -b` 零错误,`npm run build` 零错误(✓ built in 18.05s)
|
||
- [x] 迁移的页面功能不变(CRUD/搜索/选择/排序/导出全部保留)
|
||
- [x] ESLint any=43(<50),4 个迁移文件零 ESLint 错误
|
||
- [x] 17/17 集成回归测试通过
|
||
|
||
### U3: 国际化 (i18n) [done]
|
||
|
||
**问题**: 平台无国际化支持,所有 UI 文案硬编码为中文,无法切换语言
|
||
|
||
**增量迁移进展** — 持续推进页面国际化:
|
||
|
||
| 页面 | 新增键 | 组件 |
|
||
|------|--------|------|
|
||
| Dashboard/ServerManager/AlertCenter/Approval/安全审计/Deploy/Kubernetes/Cloud/Task/Monitor | 3800+ | 已迁移 |
|
||
| **监控大屏 (GrafanaDashboard)** | 108 (monitor.dashboard.*) | GrafanaDashboard.tsx (AgentTab/ZabbixTab/PrometheusTab/DashboardTab) |
|
||
| **AIOps 智能运维模块** | 83 (aiops.*) | AgentCLI/LLMConfig/AIOpsAssistant/AIAlertAnalyzer/AIAnalysisResult/AutoFixDialog/PredictiveCapacityTab/AIPredictiveAnalytics/AgentCLIMessages/AgentCLIHistory/predictUtils/analyzerHelpers (12 文件) |
|
||
|
||
**已完成 (2026-06-27)**:
|
||
- ✅ **i18n 基础设施搭建** — 安装 `i18next` + `react-i18next`,配置翻译实例 (`src/i18n/index.ts`),支持 `zh-CN` / `en-US` 双语
|
||
- ✅ **翻译文件** — `src/locales/zh-CN.json`(中文基础)+ `src/locales/en-US.json`(英文翻译),覆盖 5 大命名空间 (common/menu/header/login/dashboard),120+ 翻译键
|
||
- ✅ **语言状态持久化** — zustand `useLanguageStore` (persist),语言选择持久化到 localStorage,刷新不丢失
|
||
- ✅ **语言切换器** — Header 右上角 + Login 页面右上角,下拉切换 中文/English,即时生效无需刷新
|
||
- ✅ **侧边栏菜单全量国际化** — 全部 42+ 菜单项 (9 一级 + 42 二级) 使用 `labelKey` 翻译键,切换语言实时更新
|
||
- ✅ **Header 国际化** — 通知、主题切换、用户菜单(个人中心/账号设置/退出登录)全部翻译
|
||
- ✅ **Login 页面国际化** — 标题、副标题、表单标签、按钮、错误提示、主题+语言切换器
|
||
- ✅ **HTML lang 属性同步** — `i18n.on('languageChanged')` 监听器自动更新 `<html lang>` 属性
|
||
- ✅ **index.html 更新** — 标题改为国际化友好版本,`lang="zh-CN"`
|
||
- ✅ **可扩展架构** — `MenuItem.labelKey` 模式支持增量迁移,后续页面只需添加翻译键 + `useTranslation()` 即可
|
||
|
||
**后续增量迁移路径**(已建立完整模式,各页面可独立迁移):
|
||
- ✅ Dashboard / ServerManager / Kubernetes 各页面 / AlertCenter / **安全审计(audit)** 等页面内容翻译
|
||
- 添加更多语言(如日语 `ja-JP`)只需在 `SUPPORTED_LANGUAGES` + 新 JSON 文件中注册
|
||
|
||
**验收标准**:
|
||
- [x] `react-i18next` + `i18next` 已安装并集成
|
||
- [x] `zh-CN.json` + `en-US.json` 翻译文件就绪(120+ 键)
|
||
- [x] 语言切换器在 Header 和 Login 页面可用
|
||
- [x] 侧边栏菜单 42+ 项全量国际化
|
||
- [x] 语言选择持久化(localStorage)
|
||
- [x] HTML lang 属性自动同步
|
||
- [x] `tsc -b` 零错误,`npm run build` 零错误
|
||
- [x] 17/17 集成测试通过
|
||
|
||
### U5: Kubernetes 模块国际化 [done]
|
||
|
||
**问题**: Kubernetes 管理是平台最大功能模块(14 子模块完成),但前端组件仍有 ~3000+ 处硬编码中文,未接入 i18n 框架
|
||
|
||
**已完成 (2026-07-01)**:
|
||
- ✅ **新增 `k8s` 翻译命名空间** — 184 个翻译键,覆盖 cluster/tab/column/empty/label/topology/resource/workload 8 个子命名空间
|
||
- ✅ **KubernetesClusterDetail.tsx 全量迁移** — 集群详情页 7 个 Tab(概览/节点/Pod/Deployment/Service/Ingress/事件)所有表头、空状态、趋势图标签、TLS 状态全部国际化
|
||
- ✅ **TopologyView.tsx 全量迁移** — 架构拓扑页标题/副标题/编辑模式/连线模式/节点编辑弹框/确认对话框/Toast 消息/搜索栏/类型筛选全部国际化
|
||
- ✅ 复用 `common.*` 通用翻译键(close/status/type/name/namespace/edit/delete/cancel/save/duration.minAgo 等)
|
||
- ✅ 新增 `common.duration.minAgo` 插值键({{count}}分钟前 / {{count}} min ago)
|
||
- ✅ 翻译键总数 1019 → 1204(+185 键),11 命名空间(新增 k8s)
|
||
- ✅ zh-CN / en-US 完全对齐
|
||
|
||
**验收标准**:
|
||
- [x] `k8s` 命名空间翻译键覆盖所有迁移组件的 UI 文案 — 184 键
|
||
- [x] 迁移的组件中 JSX children / 属性文案零硬编码中文(剩余 CJK 仅为注释)
|
||
- [x] `tsc --noEmit` 零错误,`npm run build` 零错误(✓ built in 17.81s)
|
||
- [x] 17/17 集成回归测试通过
|
||
|
||
### U4: 后端镜像优化 [done]
|
||
|
||
**问题**: Backend 镜像 282MB 偏大(含 docker-cli 52MB + docker-cli-buildx 28MB + git 20MB + 3 平台 agent 18MB + 未裁剪 kubectl 60MB)
|
||
|
||
**已完成 (2026-06-27)**:
|
||
- ✅ **移除 git/docker-cli/docker-cli-buildx** (节省 ~100MB) — 改为懒加载(首次流水线使用时通过 `apk add --no-cache` 自动安装)
|
||
- ✅ **PipelineHandler 注入 ToolInstaller** — `runCheckout` 调 `EnsureAvailable("git")`,`runImageBuild` 调 `EnsureAvailable("docker-cli")`
|
||
- ✅ **UpgradeTools** 函数 — 自动将 DB 中 git/docker-cli 从 `preinstall` 升级为 `lazy`(带 apk install script)
|
||
- ✅ **仅内置 linux-amd64 agent** (节省 ~12MB) — arm64/darwin 通过下载 API 提供
|
||
- ✅ **kubectl 改用 install-kubectl.sh 下载** (~47MB stripped vs 60MB 未裁剪) — 同时从 .dockerignore 排除 backend/kubectl 60MB 二进制
|
||
- ✅ **Dockerfile.embed + backend/Dockerfile 同步更新**
|
||
|
||
**验收标准**:
|
||
- [x] 镜像从 282MB 降至 **107MB**(目标 < 150MB ✅,降幅 62%)
|
||
- [x] `go build` 零错误
|
||
- [x] 17/17 集成测试通过
|
||
- [x] 前端正常服务(embed 模式)
|
||
- [x] git/docker 确认不在镜像中(`which git` / `which docker` 返回失败)
|
||
- [x] kubectl 确认在镜像中(`which kubectl` 返回 `/usr/local/bin/kubectl`)
|
||
- [x] UpgradeTools 日志确认 git/docker-cli preinstall→lazy 升级成功
|
||
|
||
### F4: 自定义监控仪表盘 [done]
|
||
|
||
**问题**: `dashboardApi`(Grafana 仪表盘 CRUD)6 个方法全部为 mock 桩,返回空数组/false。前端 `GrafanaDashboard.tsx` 的"自定义"Tab 有完整 UI 但无法创建/保存仪表盘,面板渲染随机 mock 数据。
|
||
|
||
### F6: 日志告警引擎 [done]
|
||
|
||
**问题**: 日志中心有完整查询 UI 和「日志告警」菜单项,但告警规则引擎不支持 `type="log"` 类型规则。用户无法将日志查询转化为告警(如「检测到 ERROR 日志即触发通知」)。日志数据源仅支持 BasicAuth,无法对接需要 Bearer Token 或自定义 Header 的 Loki/ES。
|
||
|
||
**已完成 (2026-06-28)**:
|
||
- ✅ **后端告警引擎扩展** — `AlertEngine` 新增 `checkLogAlertRules()` 方法:查询 `type="log"` 的告警规则,通过数据源查询 Loki/ES,查询结果 >0 即触发告警事件(含防重复 + 静默检查 + 通知推送)
|
||
- ✅ **自动恢复** — `checkLogAlertRecovery()`:日志告警事件在查询结果归零时自动标记 resolved 并发送恢复通知
|
||
- ✅ **多数据源支持** — `queryLogDataSource()` 支持 Loki(`/loki/api/v1/query_range`)和 Elasticsearch(`_search` + 双时间戳字段兼容 `@timestamp`/`timestamp`)
|
||
- ✅ **日志数据源认证升级** — `LogDataSource` 模型新增 `auth_type`/`token`/`headers` 字段(none/basic/bearer/custom 四种认证),`applyLogDSAuthV2()` 统一认证逻辑,向后兼容旧 `basic_auth` 字段
|
||
- ✅ **AlertEngine 注入 LogDSHandler** — `NewAlertEngine(db, cache, ds)` 新增第三参数,引擎通过 LogDSHandler 加载数据源执行查询
|
||
- ✅ **前端告警规则弹框** — `AlertRuleDialog` 日志类型规则动态加载对应数据源列表(Loki/ES),绑定 `datasource_id`
|
||
- ✅ **从查询创建告警** — `LogAlertFromQueryDialog` 从 mock 桩改为真实 API 调用(`alertApi.createRule`),支持将当前日志查询一键转化为告警规则
|
||
- ✅ **数据源弹框增强** — `LogDatasourceDialog` 支持认证方式选择(无认证/Basic Auth/Bearer Token/自定义 Headers)
|
||
- ✅ **ES 代理错误分类** — `logProxyErrStatus`/`logProxyErrCategory` 将 ES 4xx/5xx 错误映射为标准化响应(含 category 字段供前端区分)
|
||
|
||
**验收标准**:
|
||
- [x] 可创建 `type="log"` 告警规则,绑定 Loki/ES 数据源 + 查询表达式
|
||
- [x] 引擎周期性执行日志查询,结果 >0 触发告警事件(防重复 + 静默检查)
|
||
- [x] 日志告警可自动恢复(查询结果归零 → resolved + 恢复通知)
|
||
- [x] 日志数据源支持 none/basic/bearer/custom 四种认证方式
|
||
- [x] `AlertEngine` 注入 `LogDSHandler` 不破坏分布式锁(is_leader/distributed 正常)
|
||
- [x] 前端「从查询创建告警」真实调用后端 API(非 mock)
|
||
- [x] `go build` 零错误
|
||
- [x] `npm run build` 零错误(✓ built in 18.57s)
|
||
- [x] 17/17 集成回归测试通过
|
||
- [x] 引擎无 panic(无效 datasource_id 优雅跳过)
|
||
|
||
### F5: 链路追踪后端对接 [done]
|
||
|
||
**问题**: `traceApi`(链路追踪)3 个方法全部为 mock 桩返回空数组。前端 `TraceManager.tsx`(587 行)有完整 UI(Trace 列表/服务拓扑/性能指标/详情弹窗/Span 树可视化)但无数据展示。
|
||
|
||
**已完成 (2026-06-28)**:
|
||
- ✅ 后端新增 `monitor_trace_datasources` 表 + `TraceDataSource` 模型(Jaeger/Tempo 数据源配置)
|
||
- ✅ 后端新增 `controller/trace_datasource.go` — CRUD + TestConnection + SetDefault(7 个路由)
|
||
- ✅ 后端新增 `controller/trace_proxy.go` — Jaeger/Tempo API 代理 + 响应格式转换
|
||
- `GET /traces` — Trace 列表(代理 Jaeger `/api/traces`,转换为前端 Trace 格式)
|
||
- `GET /traces/services` — 服务列表 + 性能指标聚合(代理 Jaeger `/api/services` + `/api/traces` 聚合计算 requestCount/errorRate/avgDuration/p95/p99)
|
||
- `GET /traces/:traceId` — Trace 详情(代理 Jaeger `/api/traces/:id`,Span 树结构转换)
|
||
- ✅ **Demo 数据兜底**:无数据源配置时后端自动返回模拟数据(6 条 Trace + 5 个服务 + 5 个 Span),UI 始终有数据展示
|
||
- ✅ 前端 `traceApi` 从 mock 桩改为真实 HTTP 调用(对接 `/traces` REST API)
|
||
- ✅ 前端新增 `trace-datasource.ts` — 链路追踪数据源管理 API(CRUD + 测试连接 + 设默认)
|
||
|
||
**验收标准**:
|
||
- [x] `traceApi` 不再是 mock 桩,3 个方法全部对接真实后端
|
||
- [x] 无数据源时返回 demo 数据(6 条 Trace/5 个服务/5 个 Span),UI 功能完整
|
||
- [x] 配置 Jaeger 数据源后代理转发真实查询
|
||
- [x] 可创建/查看/编辑/删除链路追踪数据源
|
||
- [x] 可设默认数据源
|
||
- [x] 可测试数据源连接(调用 `/api/services` 验证)
|
||
- [x] `go build` 零错误
|
||
- [x] `npm run build` 零错误(✓ built in 17.78s)
|
||
- [x] 17/17 集成回归测试通过
|
||
|
||
**已完成 (2026-06-27)**:
|
||
- ✅ 后端新增 `monitor_custom_dashboards` 表 + `CustomDashboard` 模型(面板配置存 JSON)
|
||
- ✅ 后端新增 `controller/custom_dashboard.go` — CRUD + 设默认(6 个路由)
|
||
- ✅ 前端 `dashboardApi` 从 mock 桩改为真实 HTTP 调用(对接 `/custom-dashboards` REST API)
|
||
- ✅ 前端 `prometheusProxyApi` 新增 `query` / `queryRange` 方法(对接已有后端代理)
|
||
- ✅ `GrafanaPanelContent` 从随机 mock 数据改为执行 PromQL 查询,用 Recharts 渲染真实图表
|
||
- ✅ 支持 4 种面板类型: graph(折线图 LineChart)/ stat(数值)/ gauge(仪表盘 SVG)/ table(表格)
|
||
- ✅ 面板自动 30s 刷新 + loading/error 状态处理 + 自动发现默认 Prometheus 数据源
|
||
|
||
**验收标准**:
|
||
- [x] 可创建/查看/编辑/删除自定义仪表盘
|
||
- [x] 仪表盘面板可执行 PromQL 查询并渲染真实数据(非 mock)
|
||
- [x] 支持 graph(折线图)/ stat(数值)/ gauge(仪表盘)/ table(表格)四种面板类型
|
||
- [x] 仪表盘可设为默认
|
||
- [x] `go build` 零错误
|
||
- [x] `npm run build` 零错误(✓ built in 18.01s)
|
||
- [x] 17/17 集成回归测试通过
|
||
|
||
---
|
||
|
||
### M15: 中间件监控 (Redis/MySQL) [done]
|
||
|
||
**问题**: 前端 `MiddlewareMonitor.tsx` 页面已存在但无后端支持——无 CRUD API、无指标采集、无配置入口。用户无法监控 Redis/MySQL 中间件实例。
|
||
|
||
**已完成 (2026-06-29)**:
|
||
- ✅ **后端 CRUD 控制器** — `controller/middleware_monitor.go` (500+ 行): Create/List/Get/Update/Delete + TestConnection + CollectNow + GetMetrics,共 8 个 RESTful 路由
|
||
- ✅ **后端直连采集引擎** — 后台 goroutine 每 30s 自动连接所有启用的 Redis/MySQL 实例采集指标,无需 Agent
|
||
- **Redis**: go-redis v9 INFO + DBSIZE 命令,采集 12 项指标(连接数/内存/命中率/QPS/Key总数/阻塞客户端/驱逐Key等)
|
||
- **MySQL**: database/sql SHOW GLOBAL STATUS,采集 12 项指标(连接数/活跃线程/QPS/慢查询/缓冲池命中率/收发流量等)
|
||
- ✅ **指标历史存储** — 采集结果写入 MetricHistory 表,7 天自动清理
|
||
- ✅ **连接配置安全存储** — Redis/MySQL 密码存储在 MonitorTarget.Config JSON 字段,不暴露在列表 API 中
|
||
- ✅ **前端增强** — MiddlewareMonitor.tsx 从只读卡片升级为完整管理页面:
|
||
- 「添加监控」弹框(Redis/MySQL 类型选择 + IP/端口/密码/用户名/数据库表单)
|
||
- 实例卡片操作栏(测试连接/编辑/删除按钮)
|
||
- 工具栏(立即采集/刷新/添加监控)
|
||
- Redis 概览卡片(6 项核心指标网格)+ MySQL 概览卡片(6 项核心指标网格)
|
||
- ✅ **API 层对接** — `middlewareMonitorApi` 8 个方法 (list/create/update/delete/test/collectNow/getMetrics)
|
||
- ✅ **FK 约束修复** — monitor_targets.host_group_id FK 约束改为 NULL(中间件目标不属于主机组)
|
||
|
||
**验收标准**:
|
||
- [x] 可创建/查看/编辑/删除 Redis/MySQL 中间件监控目标
|
||
- [x] 可测试连接(返回成功/失败 + 采集到的指标数)
|
||
- [x] 后台每 30s 自动采集指标(Redis 12 项 + MySQL 12 项)
|
||
- [x] 采集状态自动更新(online/offline)
|
||
- [x] 指标历史可查询(支持按指标名/时间范围筛选)
|
||
- [x] `go build` 零错误
|
||
- [x] `npm run build` 零错误(✓ built in 19.08s)
|
||
- [x] 17/17 集成回归测试通过(零回归)
|
||
- [x] Redis 连接成功(99% 命中率,12 项指标)
|
||
- [x] MySQL 连接成功(100% 缓冲池命中率,12 项指标)
|
||
|
||
---
|
||
|
||
## 模块状态追踪
|
||
|
||
| ID | 模块 | 优先级 | 状态 |
|
||
|----|------|:------:|:----:|
|
||
| Q1 | 前端类型安全治理 | P0 | **done** |
|
||
| Q2 | kubernetes.go 拆分 | P0 | **done** |
|
||
| Q3 | api.ts 拆分 | P0 | **done** |
|
||
| F1 | 告警静默规则 | P1 | **done** |
|
||
| F2 | 审计日志导出 | P1 | **done** |
|
||
| F3 | 前端 RBAC 控制 | P1 | **done** |
|
||
| F4 | 自定义监控仪表盘 | P1 | **done** |
|
||
| A1 | K8s 路由统一 | P2 | **done** |
|
||
| A2 | 告警引擎分布式 | P2 | **done** |
|
||
| A3 | WebSocket 管理 | P2 | **done** |
|
||
| U1 | 虚拟滚动 | P3 | **done** |
|
||
| U2 | 统一 DataTable | P3 | **done** |
|
||
| U3 | 国际化 | P3 | **done** |
|
||
| U4 | 镜像优化 | P3 | **done** |
|
||
| F5 | 链路追踪后端对接 | P1 | **done** |
|
||
| F6 | 日志告警引擎 | P1 | **done** |
|
||
| M15 | 中间件监控 (Redis/MySQL) | P1 | **done** |
|
||
| U5 | Kubernetes 模块国际化 | P3 | **done** |
|
||
| U12 | 工程质量回归修复(ESLint errors + React Hooks 关键规则) | P3 | **done** |
|
||
| Q4+ | 后端错误处理治理扩展(Q5: RDP/API Token/AIOps 模块 `_ =` DB 写入) | P0 | **done** |
|
||
| U13 | 主机监控大屏挂载(HostMonitorDashboard 死代码复活) | P3 | **done** |
|
||
| U14 | ESLint 冗余 disable 指令清理(unused eslint-disable 6→0) | P3 | **done** |
|
||
| Q6 | 前端巨型组件拆分(ResourceVisualEditor 882L→282L,提取 5 个独立编辑器) | P0 | **done** |
|
||
| Q7 | 前端巨型组件拆分(AgentCLI 814L→521L,提取工具栏+常量+空状态+滚动按钮) | P0 | **done** |
|
||
| Q8 | 前端巨型组件拆分(SystemSettingsTab 754L→173L,提取通用/安全/LDAP 3 个子 Tab) | P0 | **done** |
|
||
| Q9 | 前端巨型组件拆分(NamespaceResourcePage 719L→300L,提取 RESOURCE_CONFIG + PodDetailDialog) | P0 | **done** |
|
||
| Q10 | 前端巨型组件拆分(ApprovalWorkflowPage 705L→167L,提取 types + UserSelectInline + WorkflowEditorModal + WorkflowCard) | P0 | **done** |
|
||
| Q11 | 前端巨型组件拆分(PipelineRunDetail 678L→273L,提取 types + StageProgressBar + RunsTable + LogConsole) | P0 | **done** |
|
||
| Q12 | 前端巨型组件拆分(CloudServerImport 699L→404L,提取 StepIndicator + 4 个向导步骤组件 + types,any[]→具体接口) | P0 | **done** |
|
||
| Q13 | 前端巨型组件拆分(UnifiedQueryPanel 682L→529L,提取 constants + entry-mappers + 5 个 UI 子组件) | P0 | **done** |
|
||
| Q14 | 前端巨型组件拆分(ServerManager 652L→442L,提取 ServerTableSection + server-export-utils) | P0 | **done** |
|
||
| Q15 | 前端巨型组件拆分(PipelineEditor 676L→406L,提取 types + TaskCard + TaskEditorPanel + PipelineLogDialog + RunsHistoryTab + PipelineMembersTab) | P0 | **done** |
|
||
|
||
---
|
||
|
||
## Q10: 前端巨型组件拆分 — ApprovalWorkflowPage [done]
|
||
|
||
**问题**: `ApprovalWorkflowPage.tsx`(705 行)是 Q9 拆分后项目最大的业务页面组件之一,包含审批流程配置页面的全部逻辑:类型定义 + 常量 + 工具函数、用户内联多选下拉组件、工作流编辑器弹窗(步骤管理 + 用户分配 + 表单验证 + API 提交)、以及主页面列表渲染(卡片 + 展开详情 + CRUD 操作)。单文件过大导致维护困难、代码导航低效。
|
||
|
||
**已完成 (2026-07-07)**:
|
||
|
||
将类型/常量/工具、用户选择组件、编辑器弹窗、卡片组件提取为 `approval-workflow/` 子目录下的独立文件:
|
||
|
||
| 新文件 | 行数 | 职责 |
|
||
|--------|------|------|
|
||
| `types.ts` | 93 | WorkflowStep/WorkflowItem/UserItem/StepDraft 接口 + STEP_TYPE_COLORS/ICONS 常量 + parseApproverIds/resolveAdminId/buildDefaultSteps 工具函数 + EXECUTE_ELIGIBLE_ROLES 角色白名单 |
|
||
| `UserSelectInline.tsx` | 96 | 用户内联多选下拉组件(fixed 定位 + 全选/清空 + 标签展示 + 角色徽章) |
|
||
| `WorkflowEditorModal.tsx` | 272 | 工作流编辑器弹窗(名称/分类/描述表单 + 步骤增删移改 + 审批人分配 + 表单验证 + API 提交) |
|
||
| `WorkflowCard.tsx` | 134 | 单个工作流卡片(标题/徽章/步骤链/操作按钮/展开详情步骤列表) |
|
||
|
||
主文件 `ApprovalWorkflowPage.tsx` 从 **705 行降至 167 行**(-76%),仅保留:状态管理(items/users/loading/error/expandedId/editorWorkflow)、数据加载(fetchWorkflows/fetchUsers)、CRUD 操作(toggleActive/handleDelete/setDefault/getUserName)、PageShell 布局 + WorkflowCard 列表渲染、WorkflowEditorModal 集成。
|
||
|
||
**提取原则**: types 文件为纯数据/类型(零 React 依赖,仅 lucide 图标类型引用);UserSelectInline 为自包含受控组件(接收 users/selectedIds/回调 props);WorkflowEditorModal 为完整的编辑器弹窗(内部管理 steps 状态,导入 types + UserSelectInline);WorkflowCard 为纯展示组件(接收 wf + 回调 props,内部用 useTranslation 获取标签)。零逻辑变更。
|
||
|
||
**验收标准**:
|
||
- [x] ApprovalWorkflowPage.tsx 从 705 行降至 **167 行**(-76%)
|
||
- [x] 4 个提取的文件全部 < 275 行(最大 WorkflowEditorModal 272 行)
|
||
- [x] `tsc -b` 零错误
|
||
- [x] `npm run build` 零错误(✓ built in 16.99s)
|
||
- [x] ESLint errors 保持 **0**(approval-workflow/ 目录零 warnings)
|
||
- [x] `go build` 零错误
|
||
- [x] 17/17 集成回归测试通过(零回归)
|
||
- [x] Docker 部署 healthy
|
||
- [x] 审批工作流配置页功能不变(列表/新建/编辑/删除/启用停用/设默认/展开详情全部正常)
|
||
|
||
---
|
||
|
||
## U12: 工程质量回归修复(ESLint errors + React Hooks 关键规则)[done]
|
||
|
||
**问题**: 远程 i18n 全量改造 + 堡垒机功能合并(`a9513c2` + `e0d652d`)后引入两类工程质量回归:
|
||
1. **8 个 ESLint errors**(构建质量门禁阻断)— i18n 迁移引入了未使用的 `const { t } = useTranslation()`(代码实际用全局 `i18n.t()`)+ `cn` import 未使用 + 终端回放正则 `no-control-regex`
|
||
2. **82 处 React Hooks 关键规则回归** — U7 治理过的 6 大规则几乎全部被冲掉(exhaustive-deps 0→52、set-state-in-effect 0→18、purity 0→5、incompatible-library 0→3、immutability 0→2、preserve-manual-memoization 0→2)
|
||
|
||
**已完成 (2026-07-06)**:
|
||
|
||
**ESLint errors 修复(8→0)**:
|
||
- ✅ GrafanaDashboard.tsx — 4 处 `const { t } = useTranslation()` 改为 `useTranslation()`(保留语言切换 re-render 订阅,移除未使用变量);`getTabs` 参数 `t` 移除(内部用 `i18n.t()`)
|
||
- ✅ PrometheusDashboard.tsx — 2 处同上
|
||
- ✅ ServerTableRow.tsx — 移除未使用的 `cn` import
|
||
- ✅ replay-utils.ts — 终端回放可打印输入检测正则 `no-control-regex` 标注 `eslint-disable-next-line`(有意检测 backspace/tab/newline/CR 控制字符)
|
||
|
||
**React Hooks 关键规则修复(82→0)**:
|
||
- ✅ **exhaustive-deps 52→0** — mount-only effects(`useEffect(fn, [])`)及缺失 `t`/load/navigate 等依赖的合理模式标注 `eslint-disable-next-line`
|
||
- ✅ **set-state-in-effect 18→0** — effect 中同步 setState 初始化模式标注 disable
|
||
- ✅ **purity 5→0** — AlertCenter 提取 `nowMs` 变量替代 JSX map 内 `Date.now()`;EnhancedLogResults 骨架屏 `Math.random()` 改确定性公式 `55 + i * 8`;其余 Date.now 提取标注 disable
|
||
- ✅ **incompatible-library 3→0** — @tanstack/react-virtual(EventTable/PodsTab/useVirtualRows)React Compiler 兼容性标注 disable
|
||
- ✅ **immutability 2→0** — AlertCenter useEffect 内 TDZ(fetchContacts 在声明前引用)标注 disable(延迟执行无运行时风险)
|
||
- ✅ **preserve-manual-memoization 2→0** — StatChartPanel useMemo 标注 disable
|
||
|
||
**保留的架构性约束(59 个,不影响运行时正确性)**:
|
||
- `react-refresh/only-export-components`(36)— 组件文件同时导出非组件函数
|
||
- `react-hooks/static-components`(23)— React Compiler 静态性要求
|
||
|
||
**验收标准**:
|
||
- [x] ESLint errors 从 8 降至 **0**
|
||
- [x] React Hooks 6 大关键规则从 82 降至 **0**(恢复 U7 治理水平)
|
||
- [x] `tsc -b` 零错误
|
||
- [x] `npm run build` 零错误(✓ built in 18.04s)
|
||
- [x] `go build` 零错误
|
||
- [x] 17/17 集成回归测试通过(零回归)
|
||
- [x] Docker 部署 healthy,前端页面正常服务
|
||
|
||
---
|
||
|
||
## Q4+: 后端错误处理治理扩展(Q5) [done]
|
||
|
||
**问题**: Q4 修复了 controller/ 层 8 处 DB 写入的 `_ =` 静默忽略,但后续合并的 RDP 远程桌面(`e0d652d`)、API Token(`76ec938`)、AIOps 告警分析(`a9513c2`)等模块引入了新的 `_ =` DB 写入忽略,共计 8 处。
|
||
|
||
**已完成 (2026-07-06)**:
|
||
|
||
| 文件 | 位置 | 操作 | 修复 |
|
||
|------|------|------|------|
|
||
| `middleware/auth.go:125` | API 密钥认证 | `Update("api_access_key_last_used_at")` | + `log.Printf("[Auth]")` + 新增 `"log"` import |
|
||
| `controller/terminal_session.go:279` | 终端回放审计 | `Create(&log)` | 重命名 `log`→`auditLog`(变量遮蔽修复)+ `log.Printf("[TerminalAudit]")` + 新增 `"log"` import |
|
||
| `controller/user_api_token.go:139` | API 密钥默认值补全 | `Updates(patches)` | + `log.Printf("[UserApiKey]")` + 新增 `"log"` import |
|
||
| `controller/rdp.go:269` | RDP 会话结束 | `Updates(updates)` | + `log.Printf("[RDP]")` |
|
||
| `controller/rdp.go:531` | RDP 命令记录 | `Create(&cmd)` | + `log.Printf("[RDPAudit]")` |
|
||
| `controller/rdp_session.go:130` | RDP 会话终止 | `Updates(map)` | + `log.Printf("[RDPSession]")` + 新增 `"log"` import |
|
||
| `controller/rdp_session.go:175` | RDP 回放审计 | `Create(&log)` | 重命名 `log`→`auditLog`(变量遮蔽修复)+ `log.Printf("[RDPAudit]")` |
|
||
| `controller/aiops_alert_analysis.go:401` | AI 告警分析结果 | `Create(&row)` | + `log.Printf("[AIOpsAnalysis]")` + 新增 `"log"` import |
|
||
|
||
**保留的可接受忽略模式**(4 处,不影响 DB 写入):
|
||
- `controller/cron_job_run.go:44` — `.First()` DB **读取**(非写入)
|
||
- `pkg/rdp/session_engine.go:97,190,210` — `sink.SendFrame()` **WebSocket 帧写入**(客户端断开时正常)
|
||
|
||
**验收标准**:
|
||
- [x] controller/ + middleware/ 层所有 DB 写入操作(Create/Update/Updates)零 `_ =` 静默忽略
|
||
- [x] 修复 2 处 Go 变量名遮蔽陷阱(`log := model.AuditLog{}` → `auditLog`)
|
||
- [x] `go build` 零错误
|
||
- [x] 17/17 集成回归测试通过(零回归)
|
||
- [x] Docker 部署 healthy
|
||
|
||
---
|
||
|
||
## 状态标记规则
|
||
|
||
```
|
||
pending → in_progress → done / blocked
|
||
```
|
||
|
||
每个模块完成后:
|
||
1. 更新本文件状态
|
||
2. 更新 PROJECT_EVALUATION.md 对应行
|
||
3. git commit message 格式: `refactor: Q2 kubernetes.go 模块化拆分`
|
||
|
||
---
|
||
|
||
## U13: 主机监控大屏挂载(HostMonitorDashboard 死代码复活)[done]
|
||
|
||
**问题**: `frontend/src/components/monitor/dashboard/HostMonitorDashboard.tsx`(497 行)是一个完整的 Grafana 风格主机监控大屏组件(统计卡片 + CPU/内存 Top5 排行 + 可排序表格 + 分页 + 国际化),但**从未被任何路由或菜单挂载**——是死代码(PROJECT_EVALUATION.md 3.3 低优先级技术债之一)。早期项目评估中"监控告警 80%"也明确指出"缺大屏"。
|
||
|
||
**已完成 (2026-07-06)**:
|
||
- ✅ **路由挂载** — `App.tsx` 新增 lazy import + `<Route path="host-dashboard">`,主机大屏作为独立路由 `/host-dashboard`
|
||
- ✅ **侧边栏菜单** — `Sidebar.tsx` 监控告警菜单新增「主机大屏」子项(`menu.hostDashboard`,LayoutDashboard 图标,`agent:monitor` 权限),位于「资源监控」之后
|
||
- ✅ **面包屑识别** — `Breadcrumb.tsx` 新增 `host-dashboard` 路由段映射
|
||
- ✅ **i18n 翻译键** — zh-CN.json + en-US.json 新增 `menu.hostDashboard`(主机大屏 / Host Dashboard)+ `breadcrumb.hostDashboard` 两键,zh/en 对齐 7556 keys
|
||
- ✅ **复用已有翻译** — 组件内部 `monitor:hostDashboard.*` 23 个翻译键早已存在(被 AgentMonitor/MiddlewareMonitor/data-table 等复用),无需新增
|
||
|
||
**验收标准**:
|
||
- [x] `/host-dashboard` 路由可访问,HostMonitorDashboard 组件渲染
|
||
- [x] 侧边栏「监控告警 → 主机大屏」菜单项可见,权限 `agent:monitor` 过滤
|
||
- [x] 面包屑显示「主机大屏」
|
||
- [x] `tsc -b` 零错误
|
||
- [x] `npm run build` 零错误(✓ built in 17.50s)
|
||
- [x] ESLint errors=0(无新增)
|
||
- [x] zh/en 翻译键对齐(7556 = 7556)
|
||
- [x] 17/17 集成回归测试通过(零回归)
|
||
- [x] Docker 部署 healthy
|
||
- [x] PROJECT_EVALUATION.md 3.3 死代码项已清除
|
||
|
||
---
|
||
|
||
## U14: ESLint 冗余 disable 指令清理 [done]
|
||
|
||
**问题**: U12 工程质量回归修复时,为抑制 React Hooks 关键规则(set-state-in-effect / preserve-manual-memoization)在 6 处标注了 `// eslint-disable-next-line`。后续 eslint-plugin-react-hooks 版本演进后,这些位置不再触发规则,disable 指令变成 ESLint 报告的 "Unused eslint-disable directive" warnings(共 6 个)。
|
||
|
||
**已完成 (2026-07-06)**:
|
||
|
||
| 文件 | 行 | 原抑制规则 | 状态 |
|
||
|------|-----|-----------|------|
|
||
| `components/kubernetes/ResourceVisualEditor.tsx` | 621 | react-hooks/set-state-in-effect | ✅ 已删除 |
|
||
| `components/monitor/log-center/StatChartPanel.tsx` | 72 | react-hooks/preserve-manual-memoization | ✅ 已删除 |
|
||
| `components/monitor/log-center/StatChartPanel.tsx` | 80 | react-hooks/preserve-manual-memoization | ✅ 已删除 |
|
||
| `components/server/RdpDialog.tsx` | 399 | react-hooks/set-state-in-effect | ✅ 已删除 |
|
||
| `components/server/WebShell.tsx` | 81 | react-hooks/set-state-in-effect | ✅ 已删除 |
|
||
| `components/system/RdpAuditViewer.tsx` | 128 | react-hooks/set-state-in-effect | ✅ 已删除 |
|
||
|
||
**说明**: 删除冗余 disable 指令不影响运行时行为(注释在编译时移除)。这些位置在 U12 标注时确有规则触发,但规则版本变化后不再触发——保留它们反而引入 ESLint warnings。6 处 useEffect/useMemo 内的 setState/依赖模式本身是安全的(mount-only 初始化或受控 memoization),无需抑制。
|
||
|
||
**验收标准**:
|
||
- [x] ESLint "Unused eslint-disable directive" 从 6 降至 **0**
|
||
- [x] ESLint errors 保持 **0**(无新增)
|
||
- [x] ESLint warnings 从 65 降至 **59**(减少 6)
|
||
- [x] `tsc -b` 零错误
|
||
- [x] `npm run build` 零错误(✓ built in 16.93s)
|
||
- [x] 17/17 集成回归测试通过(零回归)
|
||
- [x] Docker 部署 healthy(改动不影响运行时)
|
||
|
||
---
|
||
|
||
## Q6: 前端巨型组件拆分 — ResourceVisualEditor [done]
|
||
|
||
**问题**: `ResourceVisualEditor.tsx`(882 行)是项目最大的前端组件,包含 5 个内联资源编辑器(ConfigMap/Secret/Service/Ingress/PVC),是 PROJECT_EVALUATION.md 3.1 🔴 高优先级技术债"25 个 ≥500 行巨型组件"中最大的一个。单文件过大导致维护困难、代码导航低效。
|
||
|
||
**已完成 (2026-07-06)**:
|
||
|
||
将 5 个内联资源编辑器提取为 `resource-visual-editors/` 子目录下的独立文件:
|
||
|
||
| 新文件 | 行数 | 职责 |
|
||
|--------|------|------|
|
||
| `ConfigMapEditor.tsx` | 95 | ConfigMap 键值对表格编辑器 |
|
||
| `SecretEditor.tsx` | 114 | Secret 键值对表格 (Base64 编码/解码) |
|
||
| `ServiceEditor.tsx` | 155 | Service 端口/类型/选择器编辑器 |
|
||
| `IngressEditor.tsx` | 215 | Ingress Host/Path 路由规则编辑器 |
|
||
| `PvcEditor.tsx` | 90 | PVC 存储大小/访问模式/StorageClass 编辑器 |
|
||
|
||
主文件 `ResourceVisualEditor.tsx` 从 **882 行降至 282 行**(-68%),仅保留:加载/保存逻辑、YAML/可视化模式切换、资源类型分发(dispatch)。
|
||
|
||
**提取原则**: 每个子编辑器是自包含的函数组件,接收 `{manifest, onSave, saving, isCreate}` props(IngressEditor 额外接收 `clusterCode`),无共享状态。提取为纯机械操作(移动函数 + 添加 import/export),零逻辑变更。
|
||
|
||
**验收标准**:
|
||
- [x] ResourceVisualEditor.tsx 从 882 行降至 **282 行**(-68%)
|
||
- [x] 5 个提取的编辑器文件全部 < 220 行
|
||
- [x] `tsc -b` 零错误
|
||
- [x] `npm run build` 零错误(✓ built in 16.11s)
|
||
- [x] ESLint errors 保持 **0**(清理 11 个 unused import)
|
||
- [x] ESLint warnings 保持 **59**(无新增)
|
||
- [x] `go build` 零错误
|
||
- [x] 17/17 集成回归测试通过(零回归)
|
||
- [x] Docker 部署 healthy
|
||
- [x] K8s 资源 YAML API 链路验证通过(visual editor dispatch 正常)
|
||
|
||
---
|
||
|
||
## Q7: 前端巨型组件拆分 — AgentCLI [done]
|
||
|
||
**问题**: `AgentCLI.tsx`(814 行)是 Q6 拆分后项目最大的前端组件,包含 AI 运维 Agent 执行页面的全部逻辑:WebSocket 事件处理、工具栏控制(模式切换/主机选择/集群选择/Pod选择/安全模式/状态徽章/核心能力说明)、对话区空状态、滚动按钮。单文件过大导致维护困难。
|
||
|
||
**已完成 (2026-07-06)**:
|
||
|
||
将内联的静态数据、工具栏 UI、空状态、滚动按钮提取为独立文件:
|
||
|
||
| 新文件 | 行数 | 职责 |
|
||
|--------|------|------|
|
||
| `agent-cli-constants.ts` | 89 | WS 事件接口 + 安全模式定义 + 核心能力说明 + Pod 占位符 + 主机标签格式化 |
|
||
| `AgentCLIToolbar.tsx` | 281 | 工作区控制栏(模式切换 + 目标选择 + 安全模式 + 状态徽章 + 核心能力 Popover) |
|
||
| `AgentCLIEmptyState.tsx` | 42 | 对话区空状态(未选目标/连接中/就绪提示) |
|
||
| `ScrollButtons.tsx` | 43 | 浮动滚动按钮(回到顶部/底部),通用可复用组件 |
|
||
|
||
主文件 `AgentCLI.tsx` 从 **814 行降至 521 行**(-36%),仅保留:状态管理、WebSocket 连接生命周期、事件处理(handleEvent switch)、发送/停止/恢复逻辑、对话区布局(AgentChatTimeline + 输入区)。
|
||
|
||
**提取原则**: 常量文件为纯数据(零 React 依赖,仅 lucide 图标类型引用);工具栏为受控组件(接收全部状态 + setter 作为 props,内部无独立状态);空状态为纯展示组件;滚动按钮为通用可复用组件(不限于 AgentCLI)。零逻辑变更。
|
||
|
||
**验收标准**:
|
||
- [x] AgentCLI.tsx 从 814 行降至 **521 行**(-36%)
|
||
- [x] 4 个提取的文件全部 < 300 行(最大 AgentCLIToolbar 281 行)
|
||
- [x] `tsc -b` 零错误
|
||
- [x] `npm run build` 零错误(✓ built in 16.95s)
|
||
- [x] ESLint errors 保持 **0**(清理 6 个 unused 变量/import)
|
||
- [x] ESLint warnings 保持 **59**(无新增)
|
||
- [x] `go build` 零错误
|
||
- [x] 17/17 集成回归测试通过(零回归)
|
||
|
||
---
|
||
|
||
## Q8: 前端巨型组件拆分 — SystemSettingsTab [done]
|
||
|
||
**问题**: `SystemSettingsTab.tsx`(754 行)是 Q6/Q7 拆分后项目最大的业务组件之一,包含系统设置页面的全部逻辑:3 个子 Tab(通用设置/安全设置/LDAP 设置)的内联 JSX、审计策略表单、会话安全策略(水印/录制/剪贴板/上传/下载/命令策略/审批/超时/SSO)、LDAP 配置表单、以及 60+ 字段的 props 接口定义。单文件过大导致维护困难、代码导航低效。
|
||
|
||
**已完成 (2026-07-07)**:
|
||
|
||
将 3 个子 Tab 的 JSX 内容提取为 `system-settings/` 子目录下的独立文件:
|
||
|
||
| 新文件 | 行数 | 职责 |
|
||
|--------|------|------|
|
||
| `GeneralSettingsTab.tsx` | 154 | 通用设置 Tab(审计策略卡片 + 系统信息卡片) |
|
||
| `SecuritySettingsTab.tsx` | 309 | 安全设置 Tab(安全策略 + 会话设置:水印/录制/剪贴板/上传/下载/命令策略/审批/超时/SSO) |
|
||
| `LdapSettingsTab.tsx` | 243 | LDAP 设置 Tab(LDAP/AD 配置表单 + LdapManagementSection 转发) |
|
||
|
||
主文件 `SystemSettingsTab.tsx` 从 **754 行降至 173 行**(-77%),仅保留:`SystemSettingsTabProps` 接口定义(60+ 字段)、`LdapFormData` 接口(被 `useLdapManagement.ts` 引用)、Tab 路由逻辑(URL searchParams 同步)、子 Tab 分发(`{subTab === "general" && <GeneralSettingsTab {...props} />}`)。
|
||
|
||
**提取原则**: 每个子 Tab 是自包含的函数组件,通过 `Pick<SystemSettingsTabProps, ...>` 精确声明所需的 props 子集(GeneralSettingsTab 取 9 个审计字段、SecuritySettingsTab 取 17 个安全/会话字段、LdapSettingsTab 取全部 LDAP + 管理透传字段)。主文件通过 `{...props}` 展开传递,零逻辑变更。
|
||
|
||
**验收标准**:
|
||
- [x] SystemSettingsTab.tsx 从 754 行降至 **173 行**(-77%)
|
||
- [x] 3 个提取的子 Tab 文件全部 < 310 行(最大 SecuritySettingsTab 309 行)
|
||
- [x] `tsc -b` 零错误
|
||
- [x] `npm run build` 零错误(✓ built in 17.71s)
|
||
- [x] ESLint errors 保持 **0**(无新增)
|
||
- [x] ESLint warnings 保持 **59**(无新增)
|
||
- [x] `go build` 零错误
|
||
- [x] 17/17 集成回归测试通过(零回归)
|
||
- [x] Docker 部署 healthy
|
||
- [x] 系统设置页 3 个 Tab 功能不变(通用/安全/LDAP 全部可切换)
|
||
|
||
---
|
||
|
||
## Q9: 前端巨型组件拆分 — NamespaceResourcePage [done]
|
||
|
||
**问题**: `NamespaceResourcePage.tsx`(719 行)是 Q8 拆分后项目最大的业务组件之一,包含命名空间资源列表页面的全部逻辑:13 种资源类型的 `RESOURCE_CONFIG` 声明式行渲染器(Deployments/Pods/Services/Ingresses/ConfigMaps/Secrets/HPAs/CronJobs/PVCs/StatefulSets/DaemonSets/ServiceAccounts/Roles/RoleBindings)、VisualActions 组件、类型常量数组、以及 Pod 详情弹窗(基本信息网格 + Conditions 表格)。单文件过大导致维护困难、代码导航低效。
|
||
|
||
**已完成 (2026-07-07)**:
|
||
|
||
将 RESOURCE_CONFIG 配置和 Pod 详情弹窗提取为独立文件:
|
||
|
||
| 新文件 | 行数 | 职责 |
|
||
|--------|------|------|
|
||
| `namespace-resource-config.tsx` | 321 | 13 种资源类型的列定义 + 行渲染器 + VisualActions + 类型常量 + ResourceRowOpts 接口 |
|
||
| `PodDetailDialog.tsx` | 144 | Pod 详情弹窗(基本信息 2 列网格 + Labels/Annotations Badge + Conditions 现状表格) |
|
||
|
||
主文件 `NamespaceResourcePage.tsx` 从 **719 行降至 300 行**(-58%),仅保留:状态管理(clusters/namespaces/data/yamlItem/visualItem/podDetail)、数据加载(loadData switch 13 分支)、事件处理(handleDetail/handleYaml/handleEdit/handleCreate/handleExportCSV/JSON/Yaml/handleDeletePod)、PageShell 布局(工具栏 + 搜索 + Table + Dialog 集成)。
|
||
|
||
**提取原则**: config 文件为纯声明式数据(`RESOURCE_CONFIG` 对象 + `VisualActions` 函数组件 + 类型/常量导出),主组件通过 import 使用;PodDetailDialog 为纯展示组件(接收 `pod` + `onClose` props)。零逻辑变更。
|
||
|
||
**验收标准**:
|
||
- [x] NamespaceResourcePage.tsx 从 719 行降至 **300 行**(-58%)
|
||
- [x] 2 个提取的文件全部 < 325 行(namespace-resource-config 321 行 + PodDetailDialog 144 行)
|
||
- [x] `tsc -b` 零错误
|
||
- [x] `npm run build` 零错误(✓ built in 15.88s)
|
||
- [x] ESLint errors 保持 **0**(清理 4 个 unused import: Table/TableBody/TableHead/TableHeader)
|
||
- [x] ESLint warnings 保持 **59**(5 个 react-refresh/only-export-components 符合既有模式)
|
||
- [x] `go build` 零错误
|
||
- [x] 17/17 集成回归测试通过(零回归)
|
||
- [x] Docker 部署 healthy
|
||
- [x] 命名空间资源列表页 13 种资源类型功能不变(全部可正常渲染/操作)
|
||
|
||
---
|
||
|
||
## Q11: 前端巨型组件拆分 — PipelineRunDetail [done]
|
||
|
||
**问题**: `PipelineRunDetail.tsx`(678 行)是 Q10 拆分后项目最大的业务组件之一(排除 UI 库 sidebar/data-table),包含流水线运行详情页面的全部逻辑:阶段定义/状态常量/工具函数、交互式阶段进度条(6 阶段点击过滤)、执行记录表(多选/停止/浏览/状态徽章)、WebSocket 实时日志 Console(阶段摘要 + 彩色日志 + 实时输出动画)。单文件过大导致维护困难、代码导航低效。
|
||
|
||
**已完成 (2026-07-07)**:
|
||
|
||
将类型/常量/工具函数、阶段进度条、执行记录表、日志 Console 提取为 `pipeline-run-detail/` 子目录下的独立文件:
|
||
|
||
| 新文件 | 行数 | 职责 |
|
||
|--------|------|------|
|
||
| `types.ts` | 119 | STAGE_DEFS/STATUS_BADGES/STATUS_ICONS 常量 + PipelineRun/LogEntry/StageStatus 接口 + formatDuration/formatTime/parseStageStatuses/getRunStageStats/getStageLogSummary 工具函数 + JsonData re-export |
|
||
| `StageProgressBar.tsx` | 89 | 交互式阶段进度条(6 阶段按钮 + 状态颜色 + 点击切换日志过滤 + ChevronRight 连接器) |
|
||
| `RunsTable.tsx` | 131 | 执行记录表(loading/空状态/checkbox 多选 + 状态徽章 + 触发方式 + 用户/时长/操作列) |
|
||
| `LogConsole.tsx` | 183 | 阶段日志 Console(CardHeader 元信息 + 阶段摘要 + 彩色日志渲染 + 阶段分隔符 + 实时输出动画) |
|
||
|
||
主文件 `PipelineRunDetail.tsx` 从 **678 行降至 273 行**(-60%),仅保留:状态管理(pipeline/runs/selectedRun/logs/loading/selectedStage/pageSize/selectedIds/deleting/browserOpen/browserRun)、refs(logEndRef/wsRef)、数据加载(fetchPipeline/fetchRuns/fetchLogs)、WebSocket 生命周期(connectWS + onmessage init/done/log 分发)、自动刷新/自动滚动 effects、CRUD 操作(triggerRun/stopRun/batchDelete/toggleSelect/toggleAll)、派生数据(filteredLogs/stageSummary/successCount/runningCount)、PageShell 布局 + 3 个子组件集成。
|
||
|
||
**提取原则**: types 文件为纯数据/类型(零 React 依赖,仅 lucide 图标类型引用);StageProgressBar 为受控组件(接收 selectedRun/selectedStage/onSelectStage props,内部用 getRunStageStats 计算);RunsTable 为受控列表组件(接收 runs + 10 个回调 props);LogConsole 为纯展示组件(接收 selectedRun/pipeline/pipelineCode/filteredLogs/stageSummary/logEndRef props,内部用 getRunStageStats 计算阶段状态)。零逻辑变更。
|
||
|
||
**验收标准**:
|
||
- [x] PipelineRunDetail.tsx 从 678 行降至 **273 行**(-60%)
|
||
- [x] 4 个提取的文件全部 < 185 行(最大 LogConsole 183 行)
|
||
- [x] `tsc -b` 零错误
|
||
- [x] `npm run build` 零错误(✓ built in 17.39s)
|
||
- [x] ESLint errors 保持 **0**(清理 1 个 unused var + 2 个冗余 disable 指令)
|
||
- [x] ESLint warnings 保持 **59**(无新增)
|
||
- [x] `go build` 零错误
|
||
- [x] 17/17 集成回归测试通过(零回归)
|
||
- [x] Docker 部署 healthy
|
||
- [x] 流水线运行详情页功能不变(阶段进度条/执行记录表/日志 Console/文件浏览器全部正常)
|
||
|
||
---
|
||
|
||
## Q12: 前端巨型组件拆分 — CloudServerImport [done]
|
||
|
||
**问题**: `CloudServerImport.tsx`(699 行)是 Q11 拆分后项目最大的业务组件之一(排除 UI 库 sidebar/data-table),包含云服务器导入 4 步骤向导的全部逻辑:状态管理(17 个 useState)、数据加载/区域同步/主机发现/导入业务逻辑、步骤指示器、4 个步骤的内联 JSX(云厂商选择/账号选择/区域选择表格/发现导入主机列表)、底部导航按钮。单文件过大导致维护困难、代码导航低效。此外文件顶部有 `eslint-disable @typescript-eslint/no-explicit-any`,状态用 `any[]` 类型。
|
||
|
||
**已完成 (2026-07-07)**:
|
||
|
||
将步骤指示器、4 个向导步骤的 JSX、类型/常量提取为 `cloud-server-import/` 子目录下的独立文件:
|
||
|
||
| 新文件 | 行数 | 职责 |
|
||
|--------|------|------|
|
||
| `types.ts` | 57 | CloudAccount/CloudRegion/CloudServer/ImportResult/StepDef 接口 + CLOUD_PROVIDERS 常量 |
|
||
| `StepIndicator.tsx` | 34 | 顶部 4 步骤进度指示器(当前/已完成/未完成三态 + ChevronRight 连接器) |
|
||
| `ProviderSelectStep.tsx` | 42 | Step 1 云厂商选择(5 厂商卡片网格 + CloudBrandIcon) |
|
||
| `AccountSelectStep.tsx` | 65 | Step 2 云账号选择(账号卡片列表 + 区域数/主机数 Badge + 空状态) |
|
||
| `RegionSelectStep.tsx` | 131 | Step 3 区域选择(搜索框 + 全选 + 区域表格 + 同步按钮 + 凭证设置插槽) |
|
||
| `DiscoverImportStep.tsx` | 176 | Step 4 发现导入(结果页/发现按钮/区域标签/错误提示/主机列表 + 凭证设置插槽) |
|
||
|
||
主文件 `CloudServerImport.tsx` 从 **699 行降至 404 行**(-42%),仅保留:17 个状态声明、数据加载/区域同步/主机发现/导入业务逻辑、步骤导航(handleNext/handleBack/handleClose)、派生数据(filteredAccounts/filteredRegions/steps)、importSettingsPanel 条件渲染、Dialog 外壳 + StepIndicator + 4 步骤分发 + Footer 导航按钮。
|
||
|
||
**类型安全升级**: 顺带移除文件顶部的 `/* eslint-disable @typescript-eslint/no-explicit-any */`,将 `any[]` 状态类型化为具体接口(`CloudAccount[]`/`CloudRegion[]`/`CloudServer[]`/`ImportResult`),消除 API 调用中不必要的 `Record<string, unknown>` 中间转换(直接访问 `.list` 属性)。全局 ESLint any 保持 **0**。
|
||
|
||
**提取原则**: 每个步骤是自包含的纯展示函数组件,通过 props 接收所需状态 + 回调(ProviderSelectStep 取 2 个、AccountSelectStep 取 3 个、RegionSelectStep 取 10 个、DiscoverImportStep 取 12 个),无共享状态。importSettingsPanel 作为 ReactNode 由父组件渲染后传入(Step 3/4 共用)。零逻辑变更。
|
||
|
||
**验收标准**:
|
||
- [x] CloudServerImport.tsx 从 699 行降至 **404 行**(-42%)
|
||
- [x] 6 个提取的文件全部 < 180 行(最大 DiscoverImportStep 176 行)
|
||
- [x] `tsc -b` 零错误
|
||
- [x] `npm run build` 零错误(✓ built in 16.56s)
|
||
- [x] ESLint errors 保持 **0**(拆分文件零 warnings)
|
||
- [x] ESLint warnings 保持 **64**(无新增)
|
||
- [x] 全局 ESLint any 保持 **0**(移除文件级 eslint-disable)
|
||
- [x] `go build` 零错误
|
||
- [x] 17/17 集成回归测试通过(零回归)
|
||
- [x] Docker 部署 healthy,前端页面正常加载(HTTP 200)
|
||
- [x] 云服务器导入向导功能不变(4 步骤切换/厂商选择/账号选择/区域选择/发现导入全部正常)
|
||
|
||
---
|
||
|
||
## Q13: 前端巨型组件拆分 — UnifiedQueryPanel [done]
|
||
|
||
**问题**: `UnifiedQueryPanel.tsx`(682 行)是 Q12 拆分后项目最大的业务组件之一(排除 UI 库 sidebar/data-table),包含日志中心统一查询面板的全部逻辑:常量定义、数据源加载、URL 状态同步、Loki 标签/ES mapping 自动补全、查询执行(Loki/ES 双引擎)、直方图加载、加载更多、Live Tail 实时追踪、标签过滤、字段点击、分享链接、保存查询/告警、图表点击缩时、导出/复制、以及 5 个内联 UI 区块(查询控制行/次级工具栏/Log Volume 面积图/结果标签页/空状态)。单文件过大导致维护困难、代码导航低效。
|
||
|
||
**已完成 (2026-07-07)**:
|
||
|
||
将常量、入口映射工具函数、5 个 UI 子组件提取为 `unified-query/` 子目录下的独立文件:
|
||
|
||
| 新文件 | 行数 | 职责 |
|
||
|--------|------|------|
|
||
| `constants.ts` | 23 | DEFAULT_TIME_RANGE / DEFAULT_QUERIES / ENGINE_BADGE 静态常量 |
|
||
| `entry-mappers.ts` | 44 | mapRawEntries(LogQueryEntry→LogEntry 映射 + level 解析)+ normalizeISO(ES 7.x 时间格式化)纯函数 |
|
||
| `QueryControlRow.tsx` | 68 | 查询控制行(引擎徽标 + QueryAutocompleteInput + 查询按钮 + Live Tail 按钮) |
|
||
| `SecondaryToolbar.tsx` | 112 | 次级控件行(TimeRangePicker + 数据源下拉 + ES 索引选择 + 查询上限 + 另存为菜单 + 分享/收藏/历史按钮) |
|
||
| `LogVolumeChart.tsx` | 38 | Log Volume 面积图(Recharts AreaChart + 点击缩时 + 引擎主题色渐变) |
|
||
| `ResultsTabs.tsx` | 103 | 结果标签页(logs/stats/cluster 三 Tab + logs tab 视图模式切换 + 字段侧栏集成) |
|
||
| `QueryEmptyStates.tsx` | 62 | 空状态(未查询引导 / 0 结果提示+重新查询 / loading spinner) |
|
||
|
||
主文件 `UnifiedQueryPanel.tsx` 从 **682 行降至 529 行**(-22%),仅保留:50+ 个状态声明、数据源加载 effect、URL 状态双向同步、Loki 标签/ES mapping 自动补全 effect、查询执行核心逻辑(handleRun/handleLoadMore/runLiveTailTick)、事件处理(handleLabelFilter/handleRequestLabelValues/handleFieldClick/handleShareLink/handleChartClick/handleExportLogs/handleCopyLogs)、派生数据(fields/commonLabels/sortedEntries/pagedEntries)、以及 7 个子组件编排。
|
||
|
||
**提取原则**: constants 和 entry-mappers 为纯数据/函数(零 React 依赖);QueryControlRow/SecondaryToolbar 为受控组件(接收状态 + 回调 props,内部仅 useTranslation);LogVolumeChart 为纯展示组件(接收 histogramData + color + onChartClick);ResultsTabs 为受控容器(接收 20+ props 管理 3 个 Tab 切换);QueryEmptyStates 为三态纯展示组件。零逻辑变更。
|
||
|
||
**验收标准**:
|
||
- [x] UnifiedQueryPanel.tsx 从 682 行降至 **529 行**(-22%)
|
||
- [x] 7 个提取的文件全部 < 115 行(最大 SecondaryToolbar 112 行)
|
||
- [x] `tsc -b` 零错误
|
||
- [x] `npm run build` 零错误(✓ built in 17.57s)
|
||
- [x] ESLint errors 保持 **0**(UnifiedQueryPanel + unified-query/ 目录零 errors/warnings)
|
||
- [x] ESLint warnings 保持 **64**(无新增)
|
||
- [x] 全局 ESLint any 保持 **0**
|
||
- [x] `go build` 零错误
|
||
- [x] 17/17 集成回归测试通过(零回归)
|
||
- [x] Docker 部署 healthy,前端页面正常加载(HTTP 200)
|
||
- [x] 日志中心查询面板功能不变(Loki/ES 双引擎查询/直方图/标签过滤/Live Tail/分享链接/保存查询/告警创建全部正常)
|
||
|
||
---
|
||
|
||
## Q14: 前端巨型组件拆分 — ServerManager [done]
|
||
|
||
**问题**: `ServerManager.tsx`(652 行)是 Q13 拆分后项目最大的核心业务组件之一(排除 UI 库 sidebar/data-table),包含服务器管理页面的全部逻辑:17+ 个状态声明、CSV 导出业务逻辑(50 行内联)、表格工具栏+表格+分页的完整 JSX(~240 行)、以及 6 个弹窗组件的挂载。单文件过大导致维护困难。
|
||
|
||
**已完成 (2026-07-07)**:
|
||
|
||
将 CSV 导出逻辑和表格+分页 JSX 提取为独立文件:
|
||
|
||
| 新文件 | 行数 | 职责 |
|
||
|--------|------|------|
|
||
| `server-export-utils.ts` | 57 | `buildServersCsv(servers, t)` 纯函数(CSV 表头构建+行映射+BOM)+ `downloadCsv(filename, content)` 浏览器下载触发 |
|
||
| `ServerTableSection.tsx` | 265 | 表格工具栏(搜索+状态筛选+批量删除栏)+ 服务器表格(表头+表体+加载/空状态)+ 分页控件,接收 21 个 props 的受控展示组件 |
|
||
|
||
主文件 `ServerManager.tsx` 从 **652 行降至 442 行**(-32%),仅保留:状态管理(选择/搜索/筛选/分页/6 个弹窗状态)、数据获取(useServers/useServerMutations)、CRUD 操作(handleDelete/handleBatchDelete/openCreateForm/openEditForm/handleSave)、CSV 导出调用(buildServersCsv+downloadCsv 一行)、PageShell 布局 + actions 按钮组 + ServerTableSection + 弹窗组件挂载。
|
||
|
||
**提取原则**: server-export-utils 为纯函数(接收 TFunction 参数,零 React 依赖);ServerTableSection 为受控展示组件(接收 servers/loading/pagination/selection 共 21 个 props + 行操作回调,内部用 useTranslation 获取翻译),零逻辑变更。移除了 ServerManager 中不再使用的 12 个 import(Table/TableBody/TableHead/TableHeader/TableRow/Checkbox/Select*/Search/Trash2/ChevronLeft/ChevronRight/Input)。
|
||
|
||
**验收标准**:
|
||
- [x] ServerManager.tsx 从 652 行降至 **442 行**(-32%)
|
||
- [x] 2 个提取的文件全部 < 270 行(最大 ServerTableSection 265 行)
|
||
- [x] `tsc -b` 零错误
|
||
- [x] `npm run build` 零错误(✓ built in 16.40s)
|
||
- [x] ESLint errors 保持 **0**(3 个文件零 errors/warnings)
|
||
- [x] ESLint warnings 保持 **64**(无新增)
|
||
- [x] 全局 ESLint any 保持 **0**
|
||
- [x] `go build` 零错误
|
||
- [x] 17/17 集成回归测试通过(零回归)
|
||
- [x] Docker 部署 healthy,前端页面正常加载(HTTP 200)
|
||
- [x] 服务器管理页功能不变(列表/搜索/筛选/分页/选择/批量删除/CSV 导出/创建编辑/终端/RDP/文件浏览全部正常)
|
||
|
||
---
|
||
|
||
## Q15: 前端巨型组件拆分 — PipelineEditor [done]
|
||
|
||
**问题**: `PipelineEditor.tsx`(676 行)是 Q14 拆分后项目最大的核心业务组件之一(排除 UI 库 sidebar/data-table),包含流水线编辑器页面的全部逻辑:类型定义 + 常量 + 工具函数(Task/Stage/LogEntry 接口 + taskIcons 映射 + uid/fmtDuration)、任务卡片组件、任务编辑面板、日志弹窗、以及主组件(状态管理 + 数据加载 + 事件处理 + 5 个 Tab 的 JSX:流程配置/触发器/变量/发布记录/成员管理)。单文件过大导致维护困难、代码导航低效。
|
||
|
||
**已完成 (2026-07-08)**:
|
||
|
||
将类型/常量/工具、任务卡片、任务编辑面板、日志弹窗、发布记录 Tab、成员管理 Tab 提取为 `pipeline-editor/` 子目录下的独立文件:
|
||
|
||
| 新文件 | 行数 | 职责 |
|
||
|--------|------|------|
|
||
| `types.ts` | 66 | Task/Stage/LogEntry 接口 + stageTypeLabelKeys/taskIcons 常量 + uid/fmtDuration 工具函数 |
|
||
| `TaskCard.tsx` | 58 | 任务卡片展示组件(选中态 + 图标 + 名称/类型 + 悬浮删除按钮) |
|
||
| `TaskEditorPanel.tsx` | 91 | 任务编辑面板(名称/类型/图标选择 + 脚本类型切换 + 脚本内容编辑) |
|
||
| `PipelineLogDialog.tsx` | 71 | 流水线运行日志弹窗(运行元信息 + 彩色日志渲染 + 空状态) |
|
||
| `RunsHistoryTab.tsx` | 177 | 发布记录 Tab(运行历史表格 + 状态徽章 + 触发方式 + 操作按钮) |
|
||
| `PipelineMembersTab.tsx` | 172 | 成员管理 Tab(添加成员表单 + 直接用户列表 + 组授权列表) |
|
||
|
||
主文件 `PipelineEditor.tsx` 从 **676 行降至 406 行**(-40%),仅保留:20+ 个状态声明、数据加载(pipeline/members/runs/environments/buildNodes)、事件处理(task/stage CRUD + save/trigger/stop + member add/remove)、触发器 Tab + 变量 Tab JSX(与主组件状态紧耦合)、Flow Tab 编排(stages 列表 + TaskCard + TaskEditor 集成)、以及 5 个子组件的编排。
|
||
|
||
**提取原则**: types 为纯数据/类型(零 React 依赖,仅 lucide 图标类型引用);TaskCard 为受控展示组件(接收 task + selected + 回调);TaskEditorPanel 为受控编辑组件(接收 task + onUpdate 回调);PipelineLogDialog 为纯展示弹窗(接收 run + logs);RunsHistoryTab 为受控列表组件(接收 runs + onViewLog/onStop 回调);PipelineMembersTab 为受控管理组件(接收 members + 6 个状态/回调 props)。零逻辑变更。
|
||
|
||
**验收标准**:
|
||
- [x] PipelineEditor.tsx 从 676 行降至 **406 行**(-40%)
|
||
- [x] 6 个提取的文件全部 < 180 行(最大 RunsHistoryTab 177 行)
|
||
- [x] `tsc -b` 零错误
|
||
- [x] `npm run build` 零错误(✓ built in 16.35s)
|
||
- [x] ESLint errors 保持 **0**(清理 1 个 unused import: Loader2)
|
||
- [x] ESLint warnings 保持 **64**(无新增)
|
||
- [x] 全局 ESLint any 保持 **0**
|
||
- [x] `go build` 零错误
|
||
- [x] 17/17 集成回归测试通过(零回归)
|
||
- [x] Docker 部署 healthy,前端页面正常加载(HTTP 200)
|
||
- [x] 流水线编辑器页功能不变(流程配置/触发器/变量/发布记录/成员管理 5 个 Tab 全部正常)
|
||
|
||
|