18 文件 ~35 处 UI 硬编码中文→t()/i18n.t() 调用: - agent-utils.ts timeAgo() 秒前/分钟前/小时前 - utils.ts formatDistanceToNow() 分钟前/小时前/天前 - request.ts 响应解析失败错误消息 - ActiveSessionsPanel/HistorySessionsPanel RDP 在线/历史会话标签 - MetricsExplorer 清除/已选/最近1小时 - HostMonitor 当前主机 subtitle - AIAnalysisResult 证据链 (新增 useTranslation hook) - capacity-predict.ts 容量预测摘要模板 - ApprovalResourcePage 阿里云/腾讯云/华为云 - ApprovalPermissionPage 堡垒机 - site-monitor/helpers.ts 频率/时间/证书天数格式化 - site-monitor/analytics.ts 证书剩余/检查失败/延迟波动事件 - middleware-monitor MwTargetChartsPanel/MwTrendChart/helpers.ts - snmp-monitor SnmpMetricTrendChart/SnmpDeviceChartsPanel - host-monitor/utils.ts 图表点数标签 + PortPolicyDialog 系统进程说明 新增 34 翻译键 (common.duration.secAgo/hourAgo/dayAgo + common.selected/ responseParseError/rdpActiveSessions/rdpHistorySessions/rdpSessionCount/ evidenceChain/last1Hour/currentHost + monitor.lbl 10键 + monitor.siteMonitor 8键 + approval.provider 3键 + approval.permType 1键 + monitor.portPolicyDialog.systemProcessDesc + aiops.capacity.summary) zh/en 7813→7847 对齐; tsc -b=0, npm build✓ (17.31s), ESLint=0/43/any=0, go build=0, 17/17 测试通过
144 KiB
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=40, unused=6, console=1, tsc -b=0 errors, tsc --noEmit=0 errorsany 类型 + 218 处未使用变量
已完成里程碑 (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-any1076 → 937 → 837 → 40
方案:
- 建立
frontend/src/types/后端响应类型定义库(~1550 行) - 按模块定义接口:
types/kubernetes.ts/types/server.ts/types/pipeline.ts/types/monitor.ts等 - 逐步将
any替换为具体接口类型 - 清理 218 处
no-unused-vars - 移除 93 处
console.*(特别是api.ts:280泄露 token 的调试日志) - 配置 CI
tsc --noEmit零错误门禁
验收标准:
types/目录覆盖所有后端响应结构(~1550 行,含 6 个运行时记录类型)any类型从 1026 处降至 < 50 处 — 40 处npx tsc --noEmit零错误- ESLint
no-unused-vars降至 < 20 处 — 6 处 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: 多集群对比)
验收标准:
- 拆分后单文件不超过 800 行(最大 k8s_workload.go 696 行)
- 所有路由不变,API 响应不变(425 条路由,26 个核心端点回归测试全通过)
go build零错误- 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)
验收标准:
- 拆分后单文件不超过 300 行(kubernetes.ts 409 行为例外:78 方法单一模块不可再分)
- 所有 import 路径正确(97 个文件 import @/services/api 全部通过 index.ts 解析)
npm run build零错误- 31 个 API 对象 + 3 个类型定义全部保留
P1 — 功能补全
目标:消除前端 mock 桩,补全监控模块缺失的后端。
F1: 告警静默规则 [done]
问题: alertCenterApi.silence 硬编码返回 {success:true}
方案:
- 后端新增
alert_silences表 + CRUD API - 告警引擎评估时检查静默规则(匹配 namespace/label/时间窗)
- 前端 AlertCenter 新增「静默规则」Tab
验收标准:
- 可创建/查看/删除静默规则
- 静默期间告警引擎不触发通知(
isSilenced集成在 alert_engine.go) - 静默到期自动恢复(onetime/daily/weekly 三种模式)
F2: 审计日志导出 [done]
问题: 后端 audit.go 导出功能仅返回 JSON(TODO)
方案:
- 实现 CSV 导出(stdlib
encoding/csv,带 UTF-8 BOM,Excel 可直接打开) - 前端
http.download触发浏览器下载,传递当前筛选参数
验收标准:
- 可导出为 CSV 格式(带 UTF-8 BOM,Excel 直接打开无乱码)
- 支持按模块/操作类型/用户/时间范围筛选导出
- 导出限制 10000 条防内存溢出
- JSON 格式向后兼容(format=json)
F3: 前端 RBAC 按钮级控制 [done]
问题: 后端 RBAC 完善,但前端无按钮级权限控制
方案:
- 后端新增
GET /user/permissions端点返回当前用户权限码;Login 响应附带permissions数组 - 封装
<HasPermission permission="xxx">组件 +usePermission()hook - Sidebar 菜单按权限过滤(每个菜单项带
permission字段) - 服务器管理/系统管理等关键页面的增删改按钮按权限显隐
- admin 用户 permissions=
["*"]通配符,所有按钮可见
验收标准:
- 不同角色看到不同菜单(viewer 只看到 7 个只读菜单,admin 看到全部)
- 无权限按钮自动隐藏(viewer 看不到「添加服务器」「删除」按钮)
- 权限变更后实时生效(登录即获取最新权限,刷新页面自动拉取)
- admin 通配符
["*"]短路逻辑 - 页面刷新后自动拉取权限(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 - ✅
ListNodeshandler 改用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
验收标准:
- code 路由覆盖所有资源列举场景(7 条 all-NS code 路由)
- ID 路由保留向后兼容(标注 Deprecated,功能不变)
go build零错误npm run build零错误,tsc -b零错误- 16/16 API 测试通过(7 新路由 + 3 旧路由兼容 + 6 回归)
- code 路由与 ID 路由返回相同数据(nodes=2, pods=24, deployments=15)
A2: 告警引擎分布式安全 [done]
问题: 告警引擎用 goroutine + 30s ticker 常驻,多副本会重复告警
方案: Redis 分布式锁(SetNX 原子抢锁),每轮 ticker 先抢锁,60s TTL 防死锁。单实例/redka 模式自动 fallback 为无锁直行。
验收标准:
- Cache 接口新增
SetNX方法(go-redis 原子 / redka check-then-set 单副本安全) - 多副本部署时仅 Leader 副本执行告警检查(SetNX 分布式锁 + 实例 ID 校验)
- Leader 崩溃后锁自动过期(60s TTL),其他副本自动接管
- Redis 故障时 fail-open(不阻断告警)
GET /alerts/engine/status状态监控端点(is_leader / instance_id / lock_holder)- 本地/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变量
验收标准:
- 所有 6 个 WebSocket handler 共享同一个 WSManager 实例
/api/v1/ws/stats返回 total + by_type + by_user + by_type_user/api/v1/ws/connections返回活跃连接列表(含 uptime_sec)- 连接打开→注册成功,关闭→注销成功(E2E 验证)
- 心跳 ping/pong 生效(30s ping + 60s pong timeout)
- 多连接并发注册正常
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
验收标准:
@tanstack/react-virtual已安装并集成- Pod 列表支持 1000+ Pod 虚拟滚动渲染(只渲染可见行 + overscan)
- 事件列表移除 maxRows 限制,万级事件流畅渲染
- 审计日志列表虚拟滚动(时间/用户/模块/操作/资源/IP/结果/详情)
- 会话命令列表虚拟滚动
npm run build零错误,tsc --noEmit零错误- 17/17 集成测试通过
- 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 + 测试连接)
- ✅ 所有功能内建(搜索/排序/分页/选择/导出/列可见性),无需在各页面重复实现
验收标准:
DataTable<T>组件封装排序/搜索/分页/导出/列自定义/行选择tsc -b零错误,npm run build零错误(✓ built in 18.05s)- 迁移的页面功能不变(CRUD/搜索/选择/排序/导出全部保留)
- ESLint any=43(<50),4 个迁移文件零 ESLint 错误
- 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 文件中注册
验收标准:
react-i18next+i18next已安装并集成zh-CN.json+en-US.json翻译文件就绪(120+ 键)- 语言切换器在 Header 和 Login 页面可用
- 侧边栏菜单 42+ 项全量国际化
- 语言选择持久化(localStorage)
- HTML lang 属性自动同步
tsc -b零错误,npm run build零错误- 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 完全对齐
验收标准:
k8s命名空间翻译键覆盖所有迁移组件的 UI 文案 — 184 键- 迁移的组件中 JSX children / 属性文案零硬编码中文(剩余 CJK 仅为注释)
tsc --noEmit零错误,npm run build零错误(✓ built in 17.81s)- 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 同步更新
验收标准:
- 镜像从 282MB 降至 107MB(目标 < 150MB ✅,降幅 62%)
go build零错误- 17/17 集成测试通过
- 前端正常服务(embed 模式)
- git/docker 确认不在镜像中(
which git/which docker返回失败) - kubectl 确认在镜像中(
which kubectl返回/usr/local/bin/kubectl) - 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 字段供前端区分)
验收标准:
- 可创建
type="log"告警规则,绑定 Loki/ES 数据源 + 查询表达式 - 引擎周期性执行日志查询,结果 >0 触发告警事件(防重复 + 静默检查)
- 日志告警可自动恢复(查询结果归零 → resolved + 恢复通知)
- 日志数据源支持 none/basic/bearer/custom 四种认证方式
AlertEngine注入LogDSHandler不破坏分布式锁(is_leader/distributed 正常)- 前端「从查询创建告警」真实调用后端 API(非 mock)
go build零错误npm run build零错误(✓ built in 18.57s)- 17/17 集成回归测试通过
- 引擎无 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 调用(对接/tracesREST API) - ✅ 前端新增
trace-datasource.ts— 链路追踪数据源管理 API(CRUD + 测试连接 + 设默认)
验收标准:
traceApi不再是 mock 桩,3 个方法全部对接真实后端- 无数据源时返回 demo 数据(6 条 Trace/5 个服务/5 个 Span),UI 功能完整
- 配置 Jaeger 数据源后代理转发真实查询
- 可创建/查看/编辑/删除链路追踪数据源
- 可设默认数据源
- 可测试数据源连接(调用
/api/services验证) go build零错误npm run build零错误(✓ built in 17.78s)- 17/17 集成回归测试通过
已完成 (2026-06-27):
- ✅ 后端新增
monitor_custom_dashboards表 +CustomDashboard模型(面板配置存 JSON) - ✅ 后端新增
controller/custom_dashboard.go— CRUD + 设默认(6 个路由) - ✅ 前端
dashboardApi从 mock 桩改为真实 HTTP 调用(对接/custom-dashboardsREST API) - ✅ 前端
prometheusProxyApi新增query/queryRange方法(对接已有后端代理) - ✅
GrafanaPanelContent从随机 mock 数据改为执行 PromQL 查询,用 Recharts 渲染真实图表 - ✅ 支持 4 种面板类型: graph(折线图 LineChart)/ stat(数值)/ gauge(仪表盘 SVG)/ table(表格)
- ✅ 面板自动 30s 刷新 + loading/error 状态处理 + 自动发现默认 Prometheus 数据源
验收标准:
- 可创建/查看/编辑/删除自定义仪表盘
- 仪表盘面板可执行 PromQL 查询并渲染真实数据(非 mock)
- 支持 graph(折线图)/ stat(数值)/ gauge(仪表盘)/ table(表格)四种面板类型
- 仪表盘可设为默认
go build零错误npm run build零错误(✓ built in 18.01s)- 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 层对接 —
middlewareMonitorApi8 个方法 (list/create/update/delete/test/collectNow/getMetrics) - ✅ FK 约束修复 — monitor_targets.host_group_id FK 约束改为 NULL(中间件目标不属于主机组)
验收标准:
- 可创建/查看/编辑/删除 Redis/MySQL 中间件监控目标
- 可测试连接(返回成功/失败 + 采集到的指标数)
- 后台每 30s 自动采集指标(Redis 12 项 + MySQL 12 项)
- 采集状态自动更新(online/offline)
- 指标历史可查询(支持按指标名/时间范围筛选)
go build零错误npm run build零错误(✓ built in 19.08s)- 17/17 集成回归测试通过(零回归)
- Redis 连接成功(99% 命中率,12 项指标)
- 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 |
| Q16 | 前端巨型组件拆分(RdpDialog 642L→442L,提取 types + rdpp-utils + RdpDialogHeader) | P0 | done |
| Q17 | 前端巨型组件拆分(DeploymentEditService 627L→394L,提取 types + ServiceCreateForm + IngressCreateForm + ServiceListItem + IngressListItem) | P0 | done |
| Q18 | 前端巨型组件拆分(TraceManager 605L→331L,提取 types + trace-helpers + SpanTreeNode + TraceDetailDialog + SpanDetailDialog,修复 SpanTreeNode 内联定义反模式) | P0 | done |
| Q19 | 前端巨型组件拆分(GrafanaDashboard 624L→78L,提取 types + datasource-toolbar + BatchDeployDialog + AgentTab + ExternalDatasourceTab,DRY 合并 Zabbix/Prometheus Tab,移除文件级 eslint-disable,类型安全升级 any→具体接口) | P0 | done |
| Q20 | 前端巨型组件拆分(TopologyView 596L→472L,提取 types + TopologyCanvas + NodeDetailDialog + EditNodeDialog,移除文件级 eslint-disable,any→具体接口类型) | P0 | done |
| Q21 | 前端巨型组件拆分(DeploymentEditAdvanced 590L→289L,提取 types(parser+builder 纯函数) + UpdateStrategyCard/TolerationsCard/PodMiscCard/PodSecurityCard/HostSettingsCard) | P0 | done |
| Q22 | 前端巨型组件拆分(WorkloadViewPage 572L→348L,提取 types(parseWorkloadStats 纯函数) + shared-components(StatCard/LabelBadges/ContainerInfo) + UpdateStrategySelectorCards + PodInstancesTable + ScaleDialog) | P0 | done |
| Q23 | 前端巨型组件拆分(CloudAccountManager 572L→308L,提取 cloud-account/types(AccountFormData/AccountStats + 6 个纯函数) + AccountCard(178L) + AccountFormDialog(162L)) | P0 | done |
| Q24 | 前端巨型组件拆分(ExcelServerImport 560L→385L,提取 excel-import/types(6 个 CSV 纯函数) + StepIndicator + PreviewTable) | P0 | done |
| Q25 | 前端巨型组件拆分(PipelineCreateDialog 559L→498L,提取 pipeline-create/types(PRESETS/DEFAULT_TARGET) + AdvancedSettingsPanel(172L 受控展开面板)) | P0 | done |
| Q26 | 前端巨型组件拆分(PodLogsViewer 553L→331L,提取 pod-logs-viewer/types(highlightKeyword 纯函数) + LogsHeader + ControlBar + LogContentArea + BottomStatusBar) | P0 | done |
| Q27 | 前端巨型组件拆分(HostMonitor 547L→224L (-59%),提取 host-monitor/tabs/ 8 个文件 (BasicTab + DiskTab + NetworkTab + PortMonitorTab + ProcessTable + FDUsageCard + ContextSwitchCard + ProcessTab),TABS 常量数组提取为模块级,PCT_REF_LINES 常量提升到 types.ts,端口/进程数组类型 JsonData→JsonData[] 类型安全升级) | P0 | done |
| Q28 | 前端巨型组件拆分(KubernetesClusterDetail 547L→130L (-76%),提取 cluster-detail/ 8 个文件 (types(computeClusterMetrics/buildTrendData 纯函数) + OverviewTab + NodesTab + PodsTab + DeploymentsTab + ServicesTab + IngressesTab + EventsTab)) | P0 | done |
| Q29 | 前端巨型组件拆分(AlertCenter 542L→312L (-42%),提取 4 个受控组件 (AlertsToolbar 89L 筛选工具栏 + AlertsTab 149L 告警列表表格+分页 + ContactsTab 87L 联系人卡片网格 + ContactGroupsTab 88L 联系组卡片网格),客户端搜索过滤逻辑移入 AlertsTab,删除确认逻辑下沉到子组件) | P0 | done |
| Q30 | 前端巨型组件拆分(CloudBilling 534L→295L (-45%),提取 cloud-billing/ 3 个文件 (OverviewTab 110L 概览统计:同步信息+成本告警横幅+趋势图+厂商分布 + RecordsTab 146L 成本记录表格+RecordsFilterToolbar筛选工具栏 + AlertRulesTab 91L 预警规则卡片网格)) | P0 | done |
| Q31 | 前端巨型组件拆分(PromDsFormDialog 528L→294L (-44%),提取 6 个文件 (CollapsibleSection 42L 通用折叠包装器 DRY 3 个重复折叠模式 + AuthSection 107L 认证折叠 + HeadersSection 64L 自定义Headers + AlertingSection 58L 告警折叠 + MiscSection 47L 杂项折叠 + TestResultBanner 32L 测试结果横幅),3 个折叠区块全部使用共享 CollapsibleSection 消除重复 JSX)) | P0 | done |
| Q32 | 前端巨型组件拆分(AuditOperationsTab 527L→275L (-48%),提取 audit-operations/ 3 个文件 (types 43L normalizeLog 纯函数+AuditStatistics 接口 + LogDetailDialog 85L 详情弹窗+DetailRow + StatisticsDialog 108L 统计弹窗+StatCard),清除死代码 useConfirm/_confirm/_handleShowStats/statsOpen/statistics/statsLoading,ESLint errors=0/any=0,tsc -b=0,npm build✓,go build=0,17/17 测试通过) | P0 | done |
| Q33 | 前端巨型组件拆分(DashboardRecent 518L→25L (-95%),提取 dashboard-recent/ 7 个文件 (types 48L + shared-components(StatusDot/SeverityBadge) 35L + AlertMessagesCard 72L + CertificateExpiryCard 99L + ReleaseHistoryCard 99L + OpsOverviewCard 77L + KubernetesClusterCard 97L),主文件改为 barrel re-export 保持向后兼容,tsc -b=0,npm build✓,ESLint=0/0/0,go build=0,17/17 测试通过) | P0 | done |
| Q34 | 前端巨型组件拆分(AIOpsAssistant 505L→288L (-43%),提取 aiops-assistant/ 5 个文件 (types 39L Message/QuickAction/defaultConfig/fmtTime + context-loaders.ts 69L loadAlerts/loadMetrics/loadReport 3 个平台数据加载纯函数 + quick-actions.tsx 17L + ChatMessage 47L 消息气泡(含 streaming/thinking/error 状态) + AssistantSidebar 76L 快捷操作+能力卡片),tsc -b=0,npm build✓,ESLint=0/0/0,go build=0,17/17 测试通过) | P0 | done |
| Q35 | 前端巨型组件拆分(AgentCLI 521L→399L (-23%),提取 agent-cli/ 2 个文件 (event-handler.ts 149L createWsEventHandler 工厂函数封装 8 种 WS 事件分发+高危命令确认 + ChatInputArea.tsx 44L 受控输入区组件),导出 ConfirmOptions 接口供跨模块引用,tsc -b=0,npm build✓,ESLint=0/66/0,go build=0,17/17 测试通过。最后一个 ≥500L 业务组件拆分完成,剩余最大业务组件 UnifiedQueryPanel 529L(已从 682L 拆分)) | P0 | done |
| Q36 | 前端巨型工具文件拆分(predictUtils.ts 716L→49L barrel re-export (-93%),提取 predict-types.ts 140L 类型+常量 + capacity-predict.ts 194L 容量预测函数(linearRegression+computePredictions+buildCapacityInsightPrompt) + cost-predict.ts 434L 云成本预测函数(computeCostPredictions+buildCostInsightPrompt),3 个消费者 import 路径无需修改,tsc -b=0,npm build✓ (17.26s),ESLint=0/66/0,go build=0,17/17 测试通过) | P0 | done |
| U15 | ApiAccessKeySection i18n 迁移(清理 56 个 apiaccesskey.s{hash} 乱码键为语义化 user.apiKey.* 键 + 组件全量接入 useTranslation,UI 中文 57→0,zh/en 7556=7556 对齐,零 hash 键残留) | P3 | done |
| Q37 | 前端巨型工具文件拆分(k8s-yaml-utils.ts 504L→451L + k8s-helpers.ts 67L 新文件,提取 7 个通用工具函数 parseScalar/STATUS_COLORS/statusColor/aggregateByImage/formatK8sTime/elapsedSeconds/formatDuration,barrel re-export 保持 8 个消费者零修改) | P0 | done |
| Q38 | 前端巨型组件拆分(UnifiedQueryPanel 529L→353L (-33%),提取 unified-query/useLogQueryEngine.ts 295L 查询执行引擎 Hook + useLogExport.ts 62L 导出/复制 Hook,全项目最后一个 ≥500L 业务组件清零) | P0 | done |
| U17 | K8s 残余组件 i18n 补全(NodeDetailPage 16 处硬编码中文清零 + 8 个 hash 键替换为语义化 k8s.nodeDetail.* 键 + DeploymentWorkload 12 处 toast/confirm 硬编码中文清零,zh/en 7564→7597 +33 键对齐) | P3 | done |
| U19 | i18n hash 键清理(删除 866 个死 hash 键 + 重命名 21 个高频 live hash 键为语义化键名,zh/en 7597→6731 keys 对齐,文件 328KB→276KB (-16%),tsc -b=0,npm build✓,ESLint=0/66/0,17/17 测试通过) | P3 | done |
| U20 | ESLint static-components 清零 + CredDetailDialog 内联组件修复 + i18n 批量迁移损坏修复(CredDetailDialog.tsx Field 内联组件提取为模块级 CredField — 23 处 react-hooks/static-components 警告清零;修复 8 处被批量正则损坏的 i18n.t() 调用(i18n.t('>名称:</span>') 等 → 语义化键);6 处硬编码中文清零;新增 deploy.cred.sensitiveWarn 键;ESLint warnings 66→43 (-35%),tsc -b=0,npm build✓ (17.29s),17/17 测试通过) |
P3 | done |
| U23 | Task 模块 i18n 治理(CronJobManager + CronJobFormDialog + ScriptManager + RemoteExecPage 4 文件 — import i18n 全局调用 → useTranslation() hook;42 处 phantom key (i18n.t('Chinese text') → 语义化 task.cronJob.*/task.scriptList.*/task.remoteExec.* 键);28 个孤儿 hash 键清理 (cronjobformdial.s*/remoteexecpaget.s*/systemtaskspanel.s*);50+ 处硬编码 JSX 中文 → t() 调用;zh/en 6825→6886 +61 键对齐,tsc -b=0,npm build✓ (17.46s),ESLint=0/45/0,go build=0,17/17 测试通过) |
P3 | done |
| U24 | Monitor 模块 i18n hook 迁移(26 个 .tsx 文件从 import i18n 全局 → useTranslation() hook + 89 个 phantom 中文文本键 → monitor.lbl.* 语义化键;299 处 i18n.t() 调用 → 74 处保留(模块级/.ts 工具文件) + 225 处迁移到 t() hook;1 个 .ts 工具文件 helpers.ts 中文文本键替换为语义化键;zh/en 6886→6975 +89 键对齐,tsc -b=0,npm build✓ (17.16s),ESLint=0/53/0,go build=0,Docker healthy) |
P3 | done |
| U26 | Kubernetes 模块 phantom key 大规模清理(32 个 .tsx/.ts 文件,171 个中文 phantom key → 8 个残留(均为 ANSI 转义码/JSX 表达式误匹配),163 个成功替换为 k8s.* 语义化键;新增 19 个子命名空间(nsResource/nsOverview/deploymentWorkload/deploymentView/workloadView/controlBar/clusterOverview/nodes/podLogs/podExec/pvc/configMap/secret/service/ingress/nsMgmt/editContainers/capacityPage/podFile)+ 扩展 8 个已有子命名空间;zh/en 6990→7185 +195 键对齐,k8s 命名空间 65 子命名空间/940 键,tsc -b=0,npm build✓ (17.59s),ESLint=0/53/0,go build=0,17/17 测试通过) | P3 | done |
| U27 | 多模块 phantom key 批量清理(Cloud/Deploy/Agent/Monitor/System 5 模块 25 个文件,180 个中文 phantom key → 51 个残留,129 个成功替换为语义化键;新增 12 个子命名空间(cloud.platform/deploy.buildNodes/deploy.rbac.policy/deploy.stage/deploy.target/deploy.userGroup/agent.alerts/agent.monitor/agent.alertHelper/agent.ruleDialog/monitor.alertRulesTab/system.ldapMgmt 等);硬编码 JSX 中文(刷新/添加/启用/禁用/Master内置/执行器/标签等) → i18n.t() 调用;zh/en 7185→7294 +109 键对齐,tsc -b=0,npm build✓ (16.31s),ESLint=0/0/0,go build=0,17/17 测试通过) | P3 | done |
| U30 | i18n 批量转换损坏调用修复(8 处损坏的 i18n.t() 调用修复 — DeploymentEditContainers.tsx:85 toast description 损坏 / DeploymentEditStorage.tsx:175,202 !manifest 空状态+数据卷副标题损坏 / AgentRuleDialog.tsx:111,157,183,195 DialogDescription+操作符/端口/持续时间 Label 损坏 / LogFieldSidebar.tsx:68 搜索 placeholder 损坏。损坏原因: 早期批量正则 i18n 转换将模板表达式/JSX 碎片错误包裹进 i18n.t() 调用。新增 6 个语义化键(agent.ruleDialog.description/operator/port/duration + kubernetes.storage.volumeDesc + monitor.lbl.searchFields),zh/en 7375→7381 +6 键对齐,tsc -b=0,npm build✓ (17.99s),ESLint=0/53/0,go build=0,17/17 测试通过) | P3 | done |
| U31 | AIOps Agent CLI 组件 i18n 修复(AgentCLI + AgentCLIToolbar + AgentCLIHistory + AgentCLIEmptyState + ChatInputArea + agent-cli-constants.ts 6 文件 — Q7/Q35 拆分后丢失的 i18n 集成全部修复,新增 aiops.cli.* 命名空间 100 翻译键(8 子分类: toolbar/safety/tips/error/info/viewMode/placeholder/history/empty/input),SAFETY_MODES+TIPS_HOST+TIPS_KUBERNETES 常量数组改为 getSafetyModes(t)/getTipsHost(t)/getTipsKubernetes(t) 接收 TFunction 参数的工厂函数,全部 UI 硬编码中文清零,zh/en 7381→7481 +100 键对齐,tsc -b=0,npm build✓ (18.21s),ESLint=0/53/0,go build=0,17/17 测试通过) |
P3 | done |
| U32 | 全量 hash key 清理 + React Hooks 警告修复(151 个 hash-style flat key (s+hex 后缀) 全部重命名为语义化 nested key — monitor 58/kubernetes 42/aiops 17/agent 12/cloud 13/pipeline 6/system 3;58 个源文件 147 处 t()/i18n.t() 调用更新;3 个命名空间冲突修复(monitor.hostMonitor/agent.agentMonitor/aiops.aiAnalysisResult 原 string → .title 子键);React Hooks 警告 53→43 (-10): exhaustive-deps 4→0 + preserve-manual-memoization 5→0 + 变量遮蔽修复(filter(t)→filter(tg));zh/en 7480=7480 完全对齐 0 hash key 残留;tsc -b=0,npm build✓ (17.59s),ESLint=0/43/any=0,go build=0,17/17 测试通过) | P3 | done |
| U33 | K8s 资源编辑器 + Pod 日志/Metrics i18n 补全(resource-visual-editors/ 5 文件: ConfigMap/Secret/Service/Ingress/PvcEditor 按钮文案+帮助文本+访问模式+IngressClass 提示全部 i18n;pod-logs-viewer/ 3 文件: ControlBar 导出/刷新/实时/停止+LogContentArea 加载中+LogsHeader 标题;PodLogsViewer 6 处错误消息+DialogTitle/Description;PodMetricsPage subtitle+表头+所有命名空间;17 处 toast description 模板字面量中文→i18n.t() 插值 (DeploymentEditAdvanced/Containers/Storage/View/Detail/Service/ResourceVisualEditor/NamespaceResourcePage/ClusterOverviewPage);5 处 confirm description (DeploymentView/EditService/Detail/WorkloadViewPage/MiddlewareMonitor/SiteMonitor/HealthProbeSection);5 处 subtitle 模板字面量 (PodMetricsPage/CapacityPage/EventsPage/KubernetesNodes/ClusterOverviewPage);新增 k8s.rve 14键+k8s.toast 18键+k8s.podMetrics 4键+k8s.podLogs 13键 共 49 翻译键;zh/en 7481→7524 +43 对齐;tsc -b=0,npm build✓ (17.76s),ESLint=0/43/any=0,go build=0,17/17 测试通过) | P3 | done |
| U34 | System & User 模块 i18n 清理(ProfilePage + ResetPasswordDialog + SystemRolesTab + LdapManagementSection 4 文件 — ProfilePage 从零接入 useTranslation + ResetPasswordDialog 从零接入 useTranslation + SystemRolesTab 权限分组标签(云资源/自动化/审批/审计)+toast+confirm description+角色计数+空状态+权限列表计数+编码标签+尾部文案全部 i18n + LdapManagementSection 验证按钮+根OU标签+创建按钮+导入按钮+编辑用户描述全部 i18n;新增 user.profile.* 14键+user.resetPwd.* 11键+system.* 16键 共 41 翻译键;UI 硬编码中文 ProfilePage 15→0 + ResetPasswordDialog 11→0 + SystemRolesTab 12→0 + LdapManagementSection 8→0;zh/en 7524→7565 +41 对齐;tsc -b=0, npm build✓ (16.05s), ESLint=0/43/any=0, go build=0, 17/17 测试通过) | P3 | done |
| U35 | Deploy + Task 模块残余 JSX 硬编码中文清理(PipelineRunPanel 12处 + CronJobTable 12处 + ExecutionHistoryDialog 10处 + ScrollButtons 2处 — 新增 deploy.runStatus.* 12键 + task.cronJobCol.* 14键 + task.execHistory.* 14键 + deploy.credCol.* 9键 + common.scrollToTop/scrollToBottom/success/failed/total 5键 共 54 翻译键;zh/en 7565→7616 +51 对齐;tsc -b=0, npm build✓ (17.02s), ESLint=0/43/any=0, go build=0, 17/17 测试通过) | P3 | done |
| U36 | 全量 JSX 属性 + toast 硬编码中文清零(20 文件 30 处→0: TerminalLoadingOverlay/copy-button/AppRelease/DeployCredentials/PipelineManager/WorkspaceTermDialog/CredFormDialog/JobRoleCreateDialog/PipelineCreateDialog/AdvancedSettingsPanel/ServerForm/LdapManagementSection/LiveMonitorDialog/SystemManager/ActiveSessionsPanel/HistorySessionsPanel/AlertRulesTab/PrometheusDatasourceManager/SNMPMonitor/PredictiveCapacityTab — 23 JSX 属性 + 7 toast 调用全量清零, copy-button 从 import i18n→useTranslation hook, 4 组件新增 useTranslation hook;新增 25 翻译键;zh/en 7616→7640 +24 对齐;tsc -b=0, npm build✓ (17.25s), ESLint=0/43/any=0, go build=0, 17/17 测试通过) | P3 | done |
| U38 | i18n phantom CTK 清理 — 模板字面量 + JSX 属性残余中文清零(13 文件 16 处→0: LogsHeader "行"suffix + analyzerHelpers "当前值" + DeploymentEditStorage 2 toast description + WorkloadViewPage 2 toast description + ServerFileBrowser confirm + LogDatasourcePage toast + LogAlertsPanel confirm + DeployTargetFields JSX hint + UserGroupsManager 3 处 confirm/desc + BuildNodesManager JSX "(可选)" + useLdapManagement confirm — 新增 14 语义化翻译键 (common.lineSuffix/currentValue/memberCount/fillIfMultiContainer/confirmDeleteType + k8s.editStorage.*Desc + k8s.workloadView.restartSentDesc + k8s.workloads.scaleSuccessDesc + aiops.reachable + monitor.deleteRuleConfirmDesc + deploy.rbac.deleteGroupDesc + pipeline.removeMemberDesc + system.ldapMgmt.deleteEntryDesc),zh/en 7737→7751 +14 对齐;tsc -b=0, npm build✓ (16.86s), ESLint=0/43/any=0, go build=0, 17/17 测试通过) | P3 | done |
| U39 | 残余 JSX 属性/模板字面量中文清零(10 文件 14 处→0: DualLineChart subtitle 接收/发送 + NetworkTab 5处 unit="个" + FDUsageCard subtitle 当前 + NamespaceOverviewPage/NamespaceManagementPage subtitle + CreateHPADialog title+text 命名空间 + LogFieldSidebar title 个值 + LiveMonitorDialog title 全屏/退出全屏 + ExecutionHistoryDialog title 成功/失败 + LdapSettingsTab className 成功检查→ldapTestSuccess boolean 状态替代字符串匹配 — 新增 11 翻译键, zh/en 7751→7762 对齐;tsc -b=0, npm build✓ (16.94s), ESLint=0/0/any=0, go build=0, 17/17 测试通过) | P3 | done |
| U40 | Monitor + Agent 子组件残余硬编码中文 i18n 补全(14 文件 ~50 处→0: ContextSwitchCard CTX/IRQ/次 + ProcessTable agentWaitData/cpuUsagePercent + FDUsageCard fdHandles + PortMonitorTab 黑名单/白名单/策略配置/暂无端口数据 + PortPolicyDialog 白名单全量上报/黑名单仅上报选中/端口列表/逗号分隔/白名单无需配置/已输入端口 + HostTimeRangePicker 时间范围/自定义/取消/应用 + DualLineChart 接收/发送 (i18n.t→useTranslation hook) + ZoomableAreaChart 暂无数据 + SiteResultsPanel 选择任务/次/可用率/立即拨测/SSL证书预警/到期/剩余/阈值/天 + MiddlewareMonitor Redis单机集群/上次更新/添加平台默认/暂无实例 + SiteMonitor subtitle + SNMPMonitor 标题/采集间隔/IP地址/OID模板/SNMP版本/确认/暂无设备/采集指标/暂无指标 + HealthProbeSection TCP目标地址/TCP端口 + AgentAlerts Agent告警/刷新/未恢复/已恢复/恢复/新建规则/创建第一条规则 — 新增 monitor.lbl 46 语义化翻译键 + agent.alerts 6 键, zh/en 7762→7814 对齐;tsc -b=0, npm build✓ (16.88s), ESLint=0/43/any=0, go build=0, 17/17 测试通过) | P3 | done |
| U41 | i18n 残余硬编码中文清零 — 工具函数 + 审计RDP标签 + AIOps分析 + Monitor残余 + 审批选项(18 文件 ~35 处→0: agent-utils.ts timeAgo 秒前/分钟前/小时前 + utils.ts formatDistanceToNow 分钟前/小时前/天前 + request.ts 响应解析失败 + ActiveSessionsPanel RDP在线会话 + HistorySessionsPanel RDP历史会话/RDP会话共N条 + MetricsExplorer 清除/已选/最近1小时 + HostMonitor 当前主机 + AIAnalysisResult 证据链(useTranslation hook) + capacity-predict.ts 容量预测摘要模板 + ApprovalResourcePage 阿里云/腾讯云/华为云 + ApprovalPermissionPage 堡垒机 + site-monitor/helpers.ts 推荐频率/秒/分钟/小时/天 + site-monitor/analytics.ts 证书剩余/失败/延迟波动 + middleware-monitor/MwTargetChartsPanel 选择实例/已用/集群节点/慢查询 + MwTrendChart 暂无趋势数据 + middleware-monitor/helpers.ts 相对时间 + snmp-monitor/SnmpMetricTrendChart 暂无趋势数据等待采集 + SnmpDeviceChartsPanel 点击设备/可观测/刷新/暂无指标 + host-monitor/utils.ts 图表点数 + PortPolicyDialog 系统进程端口说明 — 新增 common.duration.secAgo/hourAgo/dayAgo + common.selected/responseParseError/rdpActiveSessions/rdpHistorySessions/rdpSessionCount/evidenceChain/last1Hour/currentHost + monitor.lbl 10键 + monitor.siteMonitor 8键 + approval.provider 3键 + approval.permType 1键 + monitor.portPolicyDialog.systemProcessDesc + aiops.capacity.summary 共 34 翻译键, zh/en 7813→7847 对齐;tsc -b=0, npm build✓ (17.31s), ESLint=0/43/any=0, go build=0, 17/17 测试通过) | P3 | done |
| U37 | 全量 JSX 文本节点硬编码中文清零(65 文件 151 处→0: MiddlewareMonitor/SiteMonitor/SNMPMonitor/HealthProbeSection/ContextSwitchCard/ProcessTable/PortMonitorTab/MwTargetChartsPanel/MiddlewareDialog/ChartRangeHint/SnmpDeviceChartsPanel/AlertRulesTab/LogClusterPanel/LogDatasourcePage/LogQueryToolbar/LogAlertsPanel/PrometheusDatasourceManager/PodMetricsPage/CapacityPage/NamespaceManagementPage/NamespaceResourcePage/DeploymentEditService/EventsPage/DeploymentDetail/ClusterOverviewPage/DeploymentEditContainers/DeploymentEditStorage/WorkloadViewPage/BottomStatusBar/UpdateStrategySelectorCards/PodInstancesTable/shared-components/UpdateStrategyCard/TolerationsCard/HostSettingsCard/IngressListItem/ServiceListItem/ServiceCreateForm/IngressCreateForm/CreateHPADialog/DeployCredentials/DeployRBAC/UserGroupsManager/BuildNodesManager/DeployTargetFields/PipelineCreateDialog/CredFormDialog/WorkspaceTermDialog/AgentAlerts/AgentRuleDialog/LiveMonitorDialog/RoleFormDialog/CronJobViewDialog/TerminalOutput/AIAnalysisResult/AIPredictiveAnalytics/PredictiveCostTab/PredictiveCapacityTab/ActiveSessionsPanel/HistorySessionsPanel/TerminalDialog/ServerFileBrowser/PodFileBrowser/SiteResultsPanel/SiteProtocolPieChart — 151 JSX 文本节点中文全部替换为 t()/i18n.t() 调用;新增 common.* 98 翻译键 (selectedCount/itemsCount/newValue/namespaceLabel/containerLabel/replicasLabel/minReplicas/maxReplicas/createNamespace/noNamespace/unknownResource/exportYaml/loadTrend/loadCapacity/predicted/threshold/hostSettings/addVolume/addMount/createService/createIngress/editAction/updateStrategy/selectAndLabel/historyVersion/fileBrowser/scale/back/createHpa/allNamespaces/certLabel/observable/deviceList/addDevice/addMonitor/collectNow/addTask/addProbe/restoreFull/contextSwitch/processTop/listenPorts/terminalRealtime/auditWebssh/buildTerminal/fileBrowse/newDir/loadDeployment/notLinked/selectedPerms/none/hasLabel/deleteNamespace/deleteNamespaceWarn/allResources/notFoundDeploy/nodeList/fileLabel/addCustom/newInstanceService/newInstanceIngress/totalContainers/workContainers/loadingEllipsis/volumeClaimTemplates/containerTemplate/passwordOptional/updated/page/perPage/clusterMode/totalLogs/countLabel/percentage/queryTime/addDatasource/newPermission/newEnv/envLabel/displayName/newUserGroup/auditTrace/predictValue/confidence/predictMonthEnd/noCapacityData/securityMode/standardRdp/domainLabel/noRdpActive/noRdpHistory/buffer/matched/podLogs/createHpaTitle/password/events/total);37 文件已有 import i18n→i18n.t() 模式, 2 文件新增 import i18n;zh/en 7640→3526 namespace-flat +98 键对齐;tsc -b=0, npm build✓ (17.96s), ESLint=0/43/any=0, go build=0, 17/17 测试通过) | P3 | done |
Q31: 前端巨型组件拆分 — PromDsFormDialog [done]
问题: PromDsFormDialog.tsx(528 行)是 Q30 拆分后项目最大的监控业务组件之一,包含 Prometheus 数据源添加/编辑弹窗的全部逻辑:表单状态管理(8 个 useState + form 对象)、初始化 effect、保存/测试连接业务逻辑、以及 8 个内联 JSX 区块(Name&Default ~23 行 / HTTP 设置 ~29 行 / Auth 折叠 ~97 行 / Custom HTTP Headers ~38 行 / Alerting 折叠 ~40 行 / 采集与查询 ~32 行 / HTTP Method ~12 行 / Misc 折叠 ~35 行 / 测试结果横幅 ~18 行)。其中 3 个折叠区块(Auth/Alerting/Misc)各自重复实现了相同的折叠 header+展开/折叠 UI 模式(按钮 + ChevronUp/Down 图标 + children 容器)。单文件过大导致维护困难。
已完成 (2026-07-09):
将 5 个内容区块和 1 个共享折叠包装器提取为 prometheus-ds/ 目录下的独立文件(该目录此前已有 types.ts + helpers.ts):
| 新文件 | 行数 | 职责 |
|---|---|---|
CollapsibleSection.tsx |
42 | 通用可折叠区块包装器(按钮 header + icon + title + ChevronUp/Down 切换 + children 容器),DRY 消除 Auth/Alerting/Misc 三处重复的折叠 UI 模式 |
AuthSection.tsx |
107 | Auth 认证折叠区块(Basic auth 开关+用户名密码 / With Credentials / TLS Client Auth+CA Cert 文本域 / Skip TLS Verify / Forward OAuth Identity 提示),受控组件接收 form + updateForm + open + onToggle |
HeadersSection.tsx |
64 | Custom HTTP Headers 区块(标题栏+Add header 按钮 + header/value 键值对 Input 行增删改 + 空状态提示),受控组件接收 headers + onAdd/onRemove/onUpdate |
AlertingSection.tsx |
58 | Alerting 告警折叠区块(Manage alerts 开关 + Alertmanager 数据源 Select 下拉,过滤自身),受控组件接收 form + updateForm + sources + editingId + open + onToggle |
MiscSection.tsx |
47 | Misc 杂项折叠区块(Disable metrics lookup 开关 + Custom query parameters Input),受控组件接收 form + updateForm + open + onToggle |
TestResultBanner.tsx |
32 | 连接测试结果横幅(成功绿色 CheckCircle / 失败红色 XCircle + target_count 徽章),纯展示组件接收 result(null 时不渲染) |
主文件 PromDsFormDialog.tsx 从 528 行降至 294 行(-44%),仅保留:8 个 useState 声明(form/headers/showAuth/showTLS/showAlerting/showMisc/testing/testResult)、初始化 useEffect、updateForm/addHeader/removeHeader/updateHeader 回调、handleSave/handleTestConnection 业务逻辑、Dialog 外壳(header + Name&Default + HTTP 设置 + 5 个子组件编排 + 采集与查询 + HTTP Method + Footer 按钮)。
关键改进:
- DRY 折叠模式: 原 Auth/Alerting/Misc 三个折叠区块各自重复了相同的折叠 header(button + icon + title + ChevronUp/Down + 展开 children 容器)共约 30 行重复 JSX。提取为共享
CollapsibleSection组件后,三个 Section 组件只需传入 icon/title/open/onToggle + children 即可,消除全部重复。 - 受控组件架构: 5 个子组件全部为受控展示组件(接收 form/headers 状态 + updateForm/onToggle 回调 props),无独立状态。所有状态管理保留在主组件,拆分为纯机械操作(移动 JSX + 添加 props 透传),零逻辑变更。
- updateForm 泛型化: 原
updateForm(field, value)函数参数类型为keyof PromDsForm+PromDsForm[keyof PromDsForm](宽松联合类型)。提取到子组件时改为<K extends keyof PromDsForm>(field: K, value: PromDsForm[K])泛型约束,使子组件调用updateForm('basic_auth', v)时 v 自动推断为 boolean,类型安全更好。
验收标准:
- PromDsFormDialog.tsx 从 528 行降至 294 行(-44%)
- 6 个提取的文件全部 < 108 行(最大 AuthSection 107 行,最小 TestResultBanner 32 行)
tsc -b零错误npm run build零错误(✓ built in 17.65s)- ESLint errors 保持 0(prometheus-ds/ 目录零 errors/warnings)
- ESLint warnings 保持 65(无新增)
- 全局 ESLint any 保持 0
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy,前端页面正常服务
- Prometheus 数据源弹窗功能不变(Name/Default/HTTP/Auth折叠/Custom Headers/Alerting折叠/采集与查询/HTTP Method/Misc折叠/测试连接/保存全部正常)
Q30: 前端巨型组件拆分 — CloudBilling [done]
问题: CloudBilling.tsx(534 行)是 Q29 拆分后项目最大的云管理业务组件之一,包含云账单管理页面的全部逻辑:3 个 Tab(概览统计/成本记录/预警规则)、状态管理(~15 个 useState)、数据加载(loadStats/loadRecords/loadRules)、业务逻辑(同步账单/删除/切换规则)、以及 3 个 Tab 的完整内联 JSX(概览 ~93 行含同步信息横幅+成本告警横幅+趋势图+厂商分布堆叠条形图+明细网格 / 记录 ~62 行含筛选工具栏+表格 / 预警 ~60 行含规则卡片网格)。单文件过大导致维护困难。
已完成 (2026-07-09):
将 3 个 Tab 内容区提取为 cloud-billing/ 子目录下的独立文件:
| 新文件 | 行数 | 职责 |
|---|---|---|
OverviewTab.tsx |
110 | 概览统计 Tab(同步信息横幅 + 成本告警横幅 + 30 天趋势图 + 云厂商分布堆叠条形图+明细网格),受控展示组件接收 stats + statsLoading,内部用 useTranslation + formatCurrency + TrendChart + providerLabels/providerHex/ProviderDot |
RecordsTab.tsx |
146 | 成本记录 Tab(含 RecordsFilterToolbar 导出组件: 云厂商下拉+日期范围+查询按钮 + RecordsTab 表格组件: 表头+表体+加载/空状态),RecordsFilterToolbar 接收 7 个 props(filter 值+setter+onQuery),RecordsTab 接收 records/loading + onEdit/onDelete/onAdd 回调 |
AlertRulesTab.tsx |
91 | 预警规则 Tab(规则卡片网格: 名称+启用 Switch+厂商+指标+阈值+最近触发时间+编辑/删除按钮 + 加载/空状态),受控展示组件接收 rules/loading + onEdit/onDelete/onToggle/onAdd 回调 |
主文件 CloudBilling.tsx 从 534 行降至 295 行(-45%),仅保留:~15 个 useState 状态声明、数据加载(loadStats/loadRecords/loadRules useCallback + useEffect 触发)、业务逻辑(handleSyncYesterday 账单同步 + handleDeleteRecord/handleDeleteRule 带 useConfirm 二次确认 + handleToggleRule)、openAdd/openEdit 回调、pageTabs 配置、PageShell 布局(StatStrip 统计条 + actions 按钮组 + RecordsFilterToolbar 条件传入 toolbar + 3 个 Tab 子组件编排 + 2 个 Dialog 挂载)。
关键改进:
- 筛选工具栏提取: 原
recordsToolbar内联 JSX(27 行: Select 下拉+2 个 date Input+查询 Button)提取为RecordsFilterToolbar独立组件,主组件通过 7 个 props(filter 值+setter+onQuery)控制,零逻辑变更。 - 受控组件架构: 3 个 Tab 子组件全部为受控展示组件(接收数据 + 回调 props),无独立状态。所有状态管理保留在主组件,拆分为纯机械操作(移动 JSX + 添加 props 透传),零逻辑变更。
验收标准:
- CloudBilling.tsx 从 534 行降至 295 行(-45%)
- 3 个提取的文件全部 < 150 行(最大 RecordsTab 146 行含 toolbar+table 双导出)
tsc -b零错误npm run build零错误(✓ built in 17.81s)- ESLint errors 保持 0(CloudBilling + cloud-billing/ 目录零 errors/warnings)
- ESLint warnings 保持 65(无新增)
- 全局 ESLint any 保持 0
go build零错误- 17/17 集成回归测试通过(零回归)
- 云账单页功能不变(3 个 Tab:概览统计趋势图+厂商分布/成本记录筛选+表格/预警规则卡片+开关全部正常)
Q29: 前端巨型组件拆分 — AlertCenter [done]
问题: AlertCenter.tsx(542 行)是 Q28 拆分后项目最大的核心业务组件之一(排除 UI 库 sidebar/data-table),包含告警中心主页面的全部编排逻辑:6 个 Tab(告警列表/告警规则/指标目录/报警联系人/报警联系组/通知策略)、~20 个 useState 状态管理、TanStack Query hooks(useAlerts/useUnifiedAlertRules/useMetricCatalog/useAlertMutations)、告警操作(确认/解决/静默)、联系人/联系组 CRUD、以及 4 块大段内联 JSX(筛选工具栏 ~56 行 + 告警列表表格+分页 ~110 行 + 联系人卡片网格 ~48 行 + 联系组卡片网格 ~48 行)。单文件过大导致维护困难。
已完成 (2026-07-09):
将筛选工具栏、告警列表表格、联系人 Tab、联系组 Tab 提取为 alert-center/ 目录下的独立文件:
| 新文件 | 行数 | 职责 |
|---|---|---|
AlertsToolbar.tsx |
89 | 告警筛选工具栏(搜索框 + 严重级别/状态/来源 3 个 Select 下拉 + 总数 + 刷新按钮),受控展示组件接收 9 个 props(searchQuery/onSearchChange + 3 筛选值 + onFilterChange + total/fetchingAlerts/onRefresh) |
AlertsTab.tsx |
149 | 告警列表 Tab(Card + 表格表头 + loading/空状态 + 告警行渲染(标题/描述/标签徽章/严重级别 Badge/状态 Badge/来源/持续时间/操作按钮)+ 分页控件),受控组件接收 11 个 props(alerts/loading/searchQuery/nowMs/total/totalPages/page + 4 回调) |
ContactsTab.tsx |
87 | 报警联系人 Tab(空状态 + 卡片网格,每张卡片含名称/手机/邮箱/渠道类型徽章/Webhook URL + 编辑/删除按钮 + useConfirm 二次确认),受控展示组件接收 contacts + onEdit + onDelete 回调 |
ContactGroupsTab.tsx |
88 | 报警联系组 Tab(空状态 + 卡片网格,每张卡片含组名/人数徽章/备注/成员名称徽章列表 + 编辑/删除按钮 + useConfirm 二次确认),受控展示组件接收 contactGroups/contacts(用于解析成员名)+ onEdit + onDelete 回调 |
主文件 AlertCenter.tsx 从 542 行降至 312 行(-42%),仅保留:~20 个 useState 状态声明、TanStack Query hooks 编排、alertParams useMemo、fetchContacts/fetchContactGroups 数据加载、告警操作(handleAcknowledge/handleResolve/handleSilence/handleQuickSetup)、告警规则删除(handleDeleteAgentRule/handleDeleteMonitorRule)、handleFilterChange、pageTabs 配置、nowMs、PageShell 布局(StatStrip + 6 Tab 条件渲染分发 + actions 按钮组)、4 个 Dialog 挂载(AlertDetailDialog/AlertSilenceDialog/ContactDialog/ContactGroupDialog)。
关键改进:
- 客户端搜索逻辑下沉: 原
alerts.filter(alert => { ... searchQuery ... })内联在主组件 JSX 的.map()前,提取到AlertsTab组件内部作为filteredAlerts派生值,主组件不再感知搜索过滤逻辑。 - 删除确认逻辑下沉: 原 ContactsTab/ContactGroupsTab 的删除按钮内联
useConfirm+alertApi.deleteContact+toast+fetchContacts逻辑,提取到子组件内部,主组件只需传入onDelete(id)async 回调。 - 受控组件架构: 4 个子组件全部为受控展示组件(接收状态 + 回调 props),无独立状态。所有状态管理保留在主组件,拆分为纯机械操作(移动 JSX + 添加 props 透传),零逻辑变更。
验收标准:
- AlertCenter.tsx 从 542 行降至 312 行(-42%)
- 4 个提取的文件全部 < 150 行(最大 AlertsTab 149 行)
tsc -b零错误npm run build零错误(✓ built in 18.71s)- ESLint errors 保持 0(5 个文件零 errors/warnings)
- ESLint warnings 保持 65(无新增)
- 全局 ESLint any 保持 0
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy,前端页面正常加载(HTTP 200)
- 告警中心页功能不变(6 个 Tab:告警列表筛选+表格+分页/告警规则/指标目录/报警联系人/报警联系组/通知策略全部正常)
Q28: 前端巨型组件拆分 — KubernetesClusterDetail [done]
问题: KubernetesClusterDetail.tsx(547 行)是 Q27 拆分后项目最大的业务组件之一,包含集群详情页面的全部逻辑:5 个资源状态 useState、集群 metrics 聚合计算(computeClusterMetrics ~23 行)、趋势数据构造(buildTrendData ~13 行)、Promise.all 加载 5 类资源、以及 7 个 Tab 的全部内联 JSX(概览 Tab 含 Recharts AreaChart 资源趋势图 + 资源分布 4 卡片 ~100 行 / 节点表格 ~62 行 / Pod 表格 ~53 行 / Deployment 表格 ~42 行 / Service 表格 ~51 行 / Ingress 表格 ~47 行 / 事件 mock 列表 ~30 行)。单文件过大导致维护困难、代码导航低效。
已完成 (2026-07-09):
将类型/纯函数和 7 个 Tab 内容区提取为 cluster-detail/ 子目录下的独立文件:
| 新文件 | 行数 | 职责 |
|---|---|---|
types.ts |
60 | ClusterMetrics/TrendPoint 接口 + computeClusterMetrics(nodes) 纯函数(从节点 metrics 聚合集群级 CPU/内存使用率)+ buildTrendData(metrics, t) 纯函数(构造 5 点趋势数据避免单点光点效果) |
OverviewTab.tsx |
129 | 概览 Tab(Recharts AreaChart CPU/内存双线趋势图 + 刷新按钮 + 资源分布 4 卡片网格 Pod/Service/Deployment/Node),受控展示组件接收 cluster + trendData + metrics + onRefresh |
NodesTab.tsx |
69 | 节点表格(名称/角色徽章/状态徽章/CPU/内存/Pod 数/OS 7 列 + 空状态),受控展示组件接收 nodes |
PodsTab.tsx |
60 | Pod 表格(名称/命名空间/状态徽章/重启次数/CPU/内存/节点 7 列 + 空状态),受控展示组件接收 pods |
DeploymentsTab.tsx |
49 | Deployment 表格(名称/命名空间/副本数/可用副本/镜像/创建时间 6 列 + 空状态 + 可用率颜色),受控展示组件接收 deployments |
ServicesTab.tsx |
58 | Service 表格(名称/命名空间/类型徽章/ClusterIP/端口/选择器 6 列 + 空状态),受控展示组件接收 services |
IngressesTab.tsx |
54 | Ingress 表格(名称/命名空间/Hosts/Backend/TLS 徽章 5 列 + 空状态),受控展示组件接收 ingresses |
EventsTab.tsx |
41 | 事件列表(5 条 demo 事件 + Normal/Warning 类型徽章 + 时间),纯展示组件无 props(事件数据提取为模块级 DEMO_EVENTS 常量) |
主文件 KubernetesClusterDetail.tsx 从 547 行降至 130 行(-76%),仅保留:5 个资源 useState、useMemo 调用纯函数(computeClusterMetrics + buildTrendData 一行替代 ~36 行计算逻辑)、loadClusterDetail 数据加载(Promise.all 5 资源 + toArray 归一化)、useEffect 触发、Card 外壳 + CardHeader(集群名/版本/节点数/创建时间 + 关闭按钮)、TabsList(7 TabsTrigger 含计数徽章)、以及 7 个子组件编排(OverviewTab + NodesTab + PodsTab + DeploymentsTab + ServicesTab + IngressesTab + EventsTab)。
关键改进:
- 纯函数提取: 原 ~23 行 clusterMetrics 聚合计算逻辑(遍历节点、解析 cpu_usage_m/mem_usage_mi、计算百分比、加权平均)和 ~13 行 trendData 构造逻辑,分别提取为
computeClusterMetrics(nodes)和buildTrendData(metrics, t)两个模块级纯函数。主组件的 useMemo 从 ~36 行降至 2 行调用。 - Demo 事件数据提取: 原 5 条内联事件对象数组(每次 render 重建 + 内联时间插值计算)提取为模块级
DEMO_EVENTS常量 +MIN_AGOS常量,消除重复创建。
验收标准:
- KubernetesClusterDetail.tsx 从 547 行降至 130 行(-76%)
- 8 个提取的文件全部 < 130 行(最大 OverviewTab 129 行,最小 EventsTab 41 行)
tsc -b零错误npm run build零错误(✓ built in 18.18s)- ESLint errors 保持 0(KubernetesClusterDetail + cluster-detail/ 目录零 errors/warnings)
- ESLint warnings 保持 65(无新增)
- 全局 ESLint any 保持 0
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy,前端页面正常加载(HTTP 200)
- 集群详情页功能不变(7 个 Tab:概览趋势图/节点/Pod/Deployment/Service/Ingress/事件全部正常)
Q27: 前端巨型组件拆分 — HostMonitor [done]
问题: HostMonitor.tsx(547 行)是 Q26 拆分后项目最大的前端业务组件之一,包含主机监控详情页面的全部逻辑:7 个 Tab(基础监控/磁盘/网络/端口/进程/系统信息/健康探针)、~15 个 useState/useRef 状态管理、react-query 数据加载、端口策略 CRUD、以及 5 个 Tab 的内联 JSX(基础监控 6 MetricChartCard / 磁盘 5 MetricChartCard / 网络 8 MetricChartCard+DualLineChart / 端口监听表格+策略配置 / 进程 TOP 表格+FD 趋势图+CTX/IRQ 卡片)。虽然部分子组件已提取(MetricChartCard/DualLineChart/HealthProbeSection/SystemInfoSection/HostCoreMetricsStrip),但 Tab 内容区仍全部内联。单文件过大导致维护困难。
已完成 (2026-07-09):
将 5 个 Tab 内容区提取为 host-monitor/tabs/ 子目录下的独立文件:
| 新文件 | 行数 | 职责 |
|---|---|---|
BasicTab.tsx |
35 | 基础监控 Tab(CPU/IO等待/内存/可用内存/Swap/系统负载 6 个 MetricChartCard),受控组件接收 metrics + latest + currentVal + aggType + pctRefLines |
DiskTab.tsx |
42 | 磁盘监控 Tab(磁盘使用/Inode/IO读写/IO繁忙度 5 个 MetricChartCard),受控组件接收 metrics + latest + currentVal + aggType + pctRefLines + diskIOInfo |
NetworkTab.tsx |
51 | 网络监控 Tab(TCP EST/TW/CW/总连接 4 MetricChartCard + DualLineChart 网卡带宽 + 接收/发送错误 2 MetricChartCard),受控组件接收 metrics + netInfo + currentVal + aggType |
PortMonitorTab.tsx |
73 | 端口监控 Tab(策略配置按钮 + 白名单/黑名单徽章 + 监听端口表格),受控组件接收 portInfo + portPolicyMode + portWhitelist + onOpenPortPolicy |
ProcessTable.tsx |
86 | 进程 TOP 表格(CMD/PID/内存%/CPU%/FDs 5 列 + 复制命令按钮 + clipboard API try/catch),纯展示组件接收 processTop |
FDUsageCard.tsx |
79 | FD 文件句柄卡片(已分配/Max/使用率 3 项指标 + ZoomableAreaChart 趋势图 + ChartToolbar 缩放控制),受控组件接收 fdInfo + fdMetrics + aggType + fdChartRef + fdChartZoomed + setFdChartZoomed |
ContextSwitchCard.tsx |
55 | 上下文切换/中断卡片(CTX/IRQ 大数字卡片 + CTX/IRQ 比例条),纯展示组件接收 csInfo |
ProcessTab.tsx |
39 | 进程监控 Tab 编排器(ProcessTable + FDUsageCard + ContextSwitchCard 两列布局),接收全部进程 Tab props 并分发 |
主文件 HostMonitor.tsx 从 547 行降至 224 行(-59%),仅保留:状态管理(selectedHost/activeTab/timeRange/aggType/portPolicy 4 state + fdChartRef/fdChartZoomed 2 ref)、react-query 数据加载(useHostList/useHostHistory/usePortPolicy)、useEffect(portPolicy 同步 + hosts 自动选择)、handleSavePortPolicy 回调、useMemo 派生数据(history/spaMinutes/actualDataSpan/latest/metrics)、JSON 解析(netInfo/portInfo/diskIOInfo/swapInfo/processTop/fdInfo/csInfo/heartbeatInfo)、currentVal 闭包函数、toolbar JSX、TABS 常量数组、monitorBody Tabs 骨架(7 TabsContent 分发到子组件)、dialogs JSX、embedded/full 渲染分支。
关键改进:
- TABS 常量提取: 原 7 个 Tab 的 id/label/icon 定义内联在
monitorBodyJSX 的.map()数组中(每次 render 重建),提取为模块级TABS常量数组,消除重复创建。 - PCT_REF_LINES 常量提升: 原
pctRefLines在组件函数体内定义(每次 render 重建),提升到types.ts作为模块级导出常量PCT_REF_LINES,同时定义RefLine接口供 Tab 组件类型约束。 - 类型安全升级:
portInfo和processTop从JsonData(单个对象)改为JsonData[](对象数组),并加as unknown as JsonData[]类型断言解决parseJSON返回类型与数组类型不兼容的 TS2345 错误。
验收标准:
- HostMonitor.tsx 从 547 行降至 224 行(-59%)
- 8 个提取的文件全部 < 90 行(最大 ProcessTable 86 行,ProcessTab 编排器仅 39 行)
tsc -b零错误npm run build零错误(✓ built in 17.64s)- ESLint errors 保持 0(HostMonitor + host-monitor/tabs/ 目录零 errors/warnings)
- ESLint warnings 保持 65(无新增)
- 全局 ESLint any 保持 0
go build零错误- 17/17 集成回归测试通过(零回归)
- 主机监控详情页功能不变(7 个 Tab 全部正常:基础监控/磁盘/网络/端口/进程/系统信息/健康探针)
Q26: 前端巨型组件拆分 — PodLogsViewer [done]
问题: PodLogsViewer.tsx(553 行)是 Q25 拆分后项目最大的 K8s 业务组件之一,包含 Pod 日志查看器的全部逻辑:~25 个 useState/useRef 状态管理、fetch ReadableStream 实时流式日志(tail -f 效果)、10000 行环形缓冲、一次性日志拉取、关键字过滤+高亮渲染、多容器选择、行数限制、previous 日志、时间范围筛选、下载导出、暂停/继续、全屏切换、以及 4 个内联 JSX 区块(头部工具栏/控制栏/日志内容区/底部状态条)。单文件过大导致维护困难。
已完成 (2026-07-09):
将类型/常量/纯函数、头部工具栏、控制栏、日志内容区、底部状态条提取为 pod-logs-viewer/ 子目录下的独立文件:
| 新文件 | 行数 | 职责 |
|---|---|---|
types.tsx |
57 | PodLogsViewerProps/LogLine 接口 + RING_BUFFER_MAX/TAIL_OPTIONS 常量 + highlightKeyword(text, keyword) 关键字高亮纯函数(返回 ReactNode,用 <mark> 包裹匹配片段) |
LogsHeader.tsx |
66 | 头部工具栏(状态指示灯 streaming/paused/idle + ScrollText 图标 + Pod 名称 + 行数统计 + 全屏/关闭按钮),接收 11 个 props 的受控展示组件 |
ControlBar.tsx |
178 | 控制栏(容器选择 + 行数限制 + previous 切换 + sinceTime 时间 + 关键字过滤 + 下载 + 刷新 + 实时流/暂停/停止按钮),接收 23 个 props 的受控展示组件 |
LogContentArea.tsx |
64 | 日志内容可滚动区(空状态 + 加载状态 + 关键字高亮行渲染 + onScroll 自动滚动检测),接收 9 个 props 的受控展示组件 |
BottomStatusBar.tsx |
42 | 底部状态条(缓冲计数 + 匹配数 + 容器/previous 标签 + 自动滚动开关),接收 8 个 props 的受控展示组件 |
主文件 PodLogsViewer.tsx 从 553 行降至 331 行(-40%),仅保留:状态管理(fullscreen/container/tailLines/previous/sinceTime/keyword/autoScroll/streaming/paused/loading + lines + 7 个 ref)、refs 同步 effects、环形缓冲 appendLines、stopStream/fetchLogs/startStream 回调、自动拉取/参数变化 effects、handleClose/handleDownload 回调、filteredLines useMemo、以及 Dialog 外壳 + 5 个子组件编排。
关键改进:
- 纯函数提取: 原
renderLine(line)内联函数(25 行关键字高亮 JSX 拆分逻辑)提取为highlightKeyword(text, keyword)模块级纯函数,消除每次 render 重建闭包。 - 类型安全: catch 块从
e?.message改为e instanceof Error ? e.message : String(e)类型安全访问;e?.name === 'AbortError'改为(e as { name?: string })?.name === 'AbortError'。 - 受控组件架构: 5 个子组件全部为受控展示组件(接收状态 + setter/回调 props),无独立状态。所有状态管理和流式逻辑保留在主组件,拆分为纯机械操作(移动 JSX + 添加 props 透传),零逻辑变更。
验收标准:
- PodLogsViewer.tsx 从 553 行降至 331 行(-40%)
- 5 个提取的文件全部 < 180 行(最大 ControlBar 178 行)
tsc -b零错误npm run build零错误(✓ built in 17.34s)- ESLint errors 保持 0(PodLogsViewer + pod-logs-viewer/ 目录零 errors/warnings)
- ESLint warnings 保持 65(无新增)
- 全局 ESLint any 保持 0
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy,前端页面正常加载(HTTP 200)
- Pod 日志查看器功能不变(容器选择/行数限制/previous/sinceTime/关键字过滤+高亮/下载/刷新/实时流/暂停继续/全屏切换全部正常)
Q22: 前端巨型组件拆分 — WorkloadViewPage [done]
问题: WorkloadViewPage.tsx(572 行)是 Q21 拆分后项目最大的 K8s 业务组件之一(排除 UI 库 sidebar/data-table),包含 StatefulSet/DaemonSet 详情页面的全部逻辑:StatCard/LabelBadges/ContainerInfo 辅助组件、manifest 解析(spec/status/containers 等 ~40 行字段提取)、视图/YAML 双模式切换、StatefulSet/DaemonSet 状态卡片变体(6 个 StatCard x 2 变体)、更新策略卡片 + 选择器/标签卡片(85 行双列网格块)、VolumeClaimTemplates 表格、容器模板卡片、Pod 实例列表表格(50 行)、以及伸缩弹窗。单文件过大导致维护困难。
已完成 (2026-07-08):
将类型/解析纯函数、共享展示组件、更新策略+选择器卡片、Pod 实例表格、伸缩弹窗提取为 workload-view/ 子目录下的独立文件:
| 新文件 | 行数 | 职责 |
|---|---|---|
types.ts |
87 | WorkloadKind/ViewMode 类型 + WorkloadStats 接口 + parseWorkloadStats(manifest, kind) 纯函数(提取 replicas/readyReplicas/desiredScheduled/numberReady/updateStrategy/vcts/selectorLabels/labels/annotations/containers/initContainers 等 ~20 个字段) |
shared-components.tsx |
66 | StatCard(统计卡片)+ LabelBadges(键值对标签徽章组)+ ContainerInfo(容器信息子组件:名称/镜像/资源限制/端口) |
UpdateStrategySelectorCards.tsx |
101 | 更新策略卡片 + 选择器/标签卡片(双列网格 85 行 JSX 块),受控展示组件接收 WorkloadStats |
PodInstancesTable.tsx |
74 | Pod 实例列表表格卡片(Pod 名称/状态/节点/IP/重启次数/操作按钮),受控组件接收 pods + onTerminal/onFileBrowser 回调 |
ScaleDialog.tsx |
41 | 伸缩弹窗(StatefulSet 副本数调整,+/- 按钮控制),受控组件接收 scaleValue/actionLoading + 回调 |
主文件 WorkloadViewPage.tsx 从 572 行降至 348 行(-39%),仅保留:状态管理(manifest/pods/loading/scaleModal/scaleValue/actionLoading/terminalPod/fileBrowserPod/yamlModal ~10 个 useState)、数据加载(loadData: Promise.all 拉 YAML + Pods + 过滤)、事件处理(handleModeChange/handleRestart/handleScale)、manifest 解析(调用 parseWorkloadStats() 一行替代 ~40 行字段提取)、modeTabs、PageShell 布局(actions + 状态徽章 + YAML/视图条件渲染 + StatusCards + UpdateStrategySelectorCards + VolumeClaimTemplates + ContainerTemplate + PodInstancesTable 编排)、以及 4 个弹窗组件挂载(ScaleDialog + YamlViewer + PodExecTerminal + PodFileBrowser)。
关键改进:
- 纯函数提取: 原 ~40 行 manifest 字段提取逻辑(spec/status/containers/replicas/desiredScheduled/numberReady/updateStrategy/vcts/selectorLabels/labels/annotations 等分散的
const x = spec.x ?? 0赋值)提取为parseWorkloadStats(manifest, kind)纯函数,主组件从 ~40 行降至 1 行调用 + 解构。 - 类型安全:
catch (e) { e?.message }改为catch (e) { e instanceof Error ? e.message : String(e) }类型安全访问。动态字段使用JsonData类型(Record<string, any>别名)兼容嵌套属性访问,避免Record<string, unknown>属性访问报错。
验收标准:
- WorkloadViewPage.tsx 从 572 行降至 348 行(-39%)
- 5 个提取的文件全部 < 105 行(最大 UpdateStrategySelectorCards 101 行)
tsc -b零错误npm run build零错误(✓ built in 16.96s)- ESLint errors 保持 0(WorkloadViewPage + workload-view/ 目录零 errors/warnings)
- ESLint warnings 保持 65(无新增)
- 全局 ESLint any 保持 0
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy,前端页面正常加载(HTTP 200)
- StatefulSet/DaemonSet 详情页功能不变(状态卡片/更新策略/选择器标签/VolumeClaimTemplates/容器模板/Pod 实例列表/伸缩弹窗/重启/终端/文件浏览器全部正常)
Q21: 前端巨型组件拆分 — DeploymentEditAdvanced [done]
问题: DeploymentEditAdvanced.tsx(590 行)是 Q20 拆分后项目最大的 K8s 业务组件之一(排除 UI 库 sidebar/data-table),包含 Deployment 编辑器「高级设置」Tab 的全部逻辑:~30 个 useState、大段 useEffect manifest 解析(106 行)、大段 save 序列化函数(121 行)、以及 5 个内联 Card JSX 区块(更新策略/历史版本、容忍 Tolerations、Pod 级别杂项、Pod 安全上下文、主机命名空间设置)。单文件过大导致维护困难、代码导航低效。
已完成 (2026-07-08):
将类型/parser/builder 纯函数和 5 个内联 Card 提取为 deployment-edit-advanced/ 子目录下的独立文件(该目录此前已有 SchedulingSection + DnsHostSection 两个组件):
| 新文件 | 行数 | 职责 |
|---|---|---|
types.ts |
279 | Toleration/HostAlias/DnsOption/NodeInfo/AdvancedState 接口 + parseAdvancedManifest()(manifest→state 纯函数)+ buildAdvancedManifest()(state→manifest 纯函数) |
UpdateStrategyCard.tsx |
90 | 更新策略 + 历史版本/进度卡片(RollingUpdate/Recreate 单选 + maxSurge/maxUnavailable + revisionHistoryLimit/progressDeadlineSeconds),受控组件接收 9 个 props |
TolerationsCard.tsx |
61 | 容忍 (Tolerations) CRUD 卡片(key/operator/value/effect/tolerationSeconds 表格行 + 增删改),受控组件接收 4 个 props |
PodMiscCard.tsx |
73 | Pod 级别杂项卡片(dnsPolicy/restartPolicy/schedulerName/terminationGracePeriodSeconds/serviceAccountName),受控组件接收 10 个 props |
PodSecurityCard.tsx |
57 | Pod 安全上下文卡片(fsGroup/runAsUser/runAsGroup/runAsNonRoot),受控组件接收 8 个 props |
HostSettingsCard.tsx |
54 | 主机命名空间设置卡片(hostNetwork/hostIPC/hostPID/shareProcessNamespace),受控组件接收 8 个 props |
主文件 DeploymentEditAdvanced.tsx 从 590 行降至 289 行(-51%),仅保留:~30 个 useState 声明、useEffect(调用 parseAdvancedManifest() 解析 manifest + 加载集群节点列表 API)、labelSelector/toleration CRUD 辅助函数、save 函数(构建 AdvancedState 对象 → 调用 buildAdvancedManifest() → API 提交 + toast)、loading/empty 状态、以及 8 个子组件编排(UpdateStrategyCard + TolerationsCard + SchedulingSection + PodMiscCard + PodSecurityCard + HostSettingsCard + DnsHostSection + 操作栏)。
关键改进:
- 纯函数提取: 原 useEffect 中的 106 行 manifest 解析逻辑和 save 函数中的 121 行 manifest 序列化逻辑,提取为
parseAdvancedManifest(manifest): AdvancedState和buildAdvancedManifest(rawManifest, state): object两个纯函数。主组件的 useEffect 从 ~106 行降至 ~40 行(调用纯函数 + 逐字段 setState + 节点加载副作用),save 函数从 ~121 行降至 ~15 行(构建 state 对象 + 调用纯函数 + API 提交)。 - 类型安全: Toleration/HostAlias/DnsOption/NodeInfo 接口替代了之前分散的内联类型,AdvancedState 聚合接口使 parser/builder 函数签名清晰。catch 块从
e?.message改为e instanceof Error ? e.message : String(e)类型安全访问。 - SchedulingSection 类型复用: types.ts 从 SchedulingSection re-export
ScheduleMode/LabelSelectorEntry/ClusterNodeOption,保持单一来源。
验收标准:
- DeploymentEditAdvanced.tsx 从 590 行降至 289 行(-51%)
- 6 个提取的文件全部 < 280 行(最大 types.ts 279 行含纯函数,Card 组件全部 < 91 行)
tsc -b零错误npm run build零错误(✓ built in 17.36s)- ESLint errors 保持 0(DeploymentEditAdvanced + deployment-edit-advanced/ 目录零 errors/warnings)
- ESLint warnings 保持 65(无新增)
- 全局 ESLint any 保持 0
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy,前端页面正常加载(HTTP 200)
- Deployment 高级设置 Tab 功能不变(更新策略/历史版本/容忍/调度/Pod 杂项/安全上下文/主机设置/DNS+hostAliases 全部正常)
Q20: 前端巨型组件拆分 — TopologyView [done]
问题: TopologyView.tsx(596 行)是 Q19 拆分后项目最大的 K8s 业务组件之一(排除 UI 库 sidebar/data-table),包含架构拓扑页面的全部逻辑:集群加载、拓扑数据构建(Promise.all 拉取 5 种资源 + buildTopology)、已保存布局合并、节点过滤、SVG 画布渲染(defs/marker/edges/nodes 绘制 + 拖拽 + 连线模式)、编辑模式操作(新增/编辑/删除节点 + 创建/删除连线)、保存/重置布局、节点详情弹窗(基本信息网格 + 关联连线列表)、新增/编辑节点弹窗。文件顶部有 eslint-disable @typescript-eslint/no-explicit-any,多处 any 类型(clusters/c/cluster/v/node.data)。单文件过大导致维护困难。
已完成 (2026-07-08):
将类型定义、SVG 画布渲染、节点详情弹窗、新增/编辑节点弹窗提取为 topology-view/ 子目录下的独立文件:
| 新文件 | 行数 | 职责 |
|---|---|---|
types.ts |
33 | ClusterInfo/EditFormState/DragOffset/SvgPoint 接口(替代 clusters: any[] 等 any 类型) |
TopologyCanvas.tsx |
94 | SVG 拓扑画布渲染(defs pattern/marker + 层级行标签 + edges 连线 + nodes 节点圆+图标+名称),受控组件接收 18 个 props(svgRef/canvasW/canvasH/nodes/edges/filteredNodes/visibleIds/editMode/connectMode/connectSource/selectedNode/draggingId + 6 回调) |
NodeDetailDialog.tsx |
93 | 节点详情弹窗(renderNodeDetailFields 基本信息 grid-cols-2 + 关联连线列表 →/← + 编辑模式操作按钮),接收 node/edges/nodes/editMode + 3 回调 |
EditNodeDialog.tsx |
65 | 新增/编辑节点弹窗(名称 Input + 类型 Select + 备注 Textarea),接收 open/editingNode/editForm/setEditForm/onSave |
主文件 TopologyView.tsx 从 596 行降至 472 行(-21%),仅保留:状态管理(clusters/topology/editMode/connectMode/editForm 等 20+ 个 useState)、数据加载(loadClusters/loadSavedLayout/loadTopology + Promise.all 5 资源拉取 + 布局合并)、拖拽处理(getSvgPoint/handleNodeMouseDown/handleMouseMove/handleMouseUp)、节点点击(区分普通/编辑/连线模式)、编辑操作(handleAddNode/handleEditNode/handleSaveNode/handleDeleteNode/handleDeleteEdge)、布局保存/重置、画布尺寸计算、filterToolbar、编辑模式工具栏、Canvas+NodeList 双栏布局、以及 3 个子组件编排。
关键改进:
- 移除文件级
eslint-disable:clusters: any[]→ClusterInfo[];(cluster as any).code→cluster.code(ClusterInfo 接口含 code 字段);v: any→v: unknown+ toArray 返回unknown[];(node.data as Record<string, any>)→Record<string, unknown>。全局 ESLint any 保持 0。 - SVG 渲染提取: 原
renderTopology()内联函数(60 行)提取为TopologyCanvas独立组件,消除内联函数每次 render 重建的性能隐患。
验收标准:
- TopologyView.tsx 从 596 行降至 472 行(-21%)
- 4 个提取的文件全部 < 95 行(最大 TopologyCanvas 94 行)
tsc -b零错误npm run build零错误(✓ built in 17.89s)- ESLint errors 保持 0(topology-view/ 目录零 warnings)
- ESLint warnings 保持 65(无新增)
- 全局 ESLint any 保持 0(移除文件级 eslint-disable)
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy,前端页面正常加载(HTTP 200)
- 架构拓扑页功能不变(SVG 画布/节点拖拽/编辑模式/连线/保存布局/节点列表/详情弹窗全部正常)
Q19: 前端巨型组件拆分 — GrafanaDashboard [done]
问题: GrafanaDashboard.tsx(624 行)是 Q18 拆分后项目最大的核心业务组件之一(排除 UI 库 sidebar/data-table),包含监控大屏页面的全部逻辑:Tab 配置、Agent 主机监控表格(状态管理 + 排序 + 分页 + 选择 + 批量部署/卸载 + Agent 安装向导)、批量部署对话框(模式切换 + 主机列表 + 凭据输入 + 警告确认)、数据源工具栏、Zabbix Tab、Prometheus Tab(两者逻辑近乎重复)、以及主组件编排。文件顶部有 eslint-disable @typescript-eslint/no-explicit-any,多处 any 类型。单文件过大导致维护困难。
已完成 (2026-07-08):
将类型/常量、数据源工具栏、批量部署对话框、Agent Tab、外部数据源通用 Tab 提取为 grafana-dashboard/ 子目录下的独立文件:
| 新文件 | 行数 | 职责 |
|---|---|---|
types.ts |
60 | AgentHost/SortField/MonitorDatasource/BatchCreds/WizardServer/TabId 接口 + DEFAULT_BATCH_CREDS 常量 |
datasource-toolbar.tsx |
49 | normalizeDatasourceList(后端响应归一化+排序)+ DatasourceToolbar 组件(数据源下拉+刷新) |
BatchDeployDialog.tsx |
273 | 批量部署 Agent 对话框(安装/升级模式切换 + 主机列表表格 + 凭据输入 + 警告确认 + 我已知悉勾选),12 个 props 的受控组件 |
AgentTab.tsx |
486 | Agent 主机监控 Tab(状态管理 + fetch + 排序/分页/选择 + 批量卸载 + 安装向卫集成 + BatchDeployDialog 集成 + 主机表格渲染) |
ExternalDatasourceTab.tsx |
78 | 外部数据源通用 Tab(fetcher + loading + empty + children render-prop),DRY 合并 Zabbix/Prometheus 两个近乎重复的组件 |
主文件 GrafanaDashboard.tsx 从 624 行降至 78 行(-87%),仅保留:getTabs 配置、ZabbixTab/PrometheusTab 薄包装(用 ExternalDatasourceTab + render-prop)、GrafanaDashboard 主组件编排(PageShell + 全屏切换 + Tab 分发)。
关键改进:
- DRY 合并: 原 ZabbixTab 和 PrometheusTab 各 30 行,逻辑近乎完全重复(仅 API/标签/渲染组件不同)。合并为 ExternalDatasourceTab 通用组件 + render-prop 模式,消除重复代码。
- 类型安全升级: 移除文件顶部的
/* eslint-disable @typescript-eslint/no-explicit-any */。wizardServer: any→WizardServer | null;ds: any→MonitorDatasource | null;catch (e: any)→catch (e)+e instanceof Error类型守卫;排序函数let va: any→string | number。全局 ESLint any 保持 0。 - 命名规范化: 数据源工具栏 prop
activeId→activeID(避免与 HTMLid混淆),normalizeDatasourceList参数r: any→r: unknown+ 类型断言。
提取原则: types 为纯数据/类型(零 React 依赖);datasource-toolbar 为共享工具+组件(被 ExternalDatasourceTab 和主文件引用);BatchDeployDialog 为受控展示组件(接收 12 个 props,零独立状态);AgentTab 为自包含业务组件(内部管理全部 Agent 监控状态 + 集成 AgentWizard + BatchDeployDialog);ExternalDatasourceTab 为通用容器组件(fetcher render-prop 模式)。零逻辑变更。
验收标准:
- GrafanaDashboard.tsx 从 624 行降至 78 行(-87%)
- 5 个提取的文件全部 < 490 行(最大 AgentTab 486 行,聚焦单一职责)
tsc -b零错误npm run build零错误(✓ built in 17.56s)- ESLint errors 保持 0(grafana-dashboard/ 目录零 errors,仅 1 个 react-refresh 架构性 warning)
- ESLint warnings 从 64 增至 65(+1 datasource-toolbar react-refresh/only-export-components,符合既有模式)
- 全局 ESLint any 保持 0(移除文件级 eslint-disable)
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy,前端页面正常加载(HTTP 200)
- 监控大屏页功能不变(Agent/Zabbix/Prometheus 三 Tab + 主机表格 + 排序/分页/选择 + 批量部署/卸载 + 安装向导全部正常)
- DRY 合并 ZabbixTab/PrometheusTab 为 ExternalDatasourceTab 通用组件
Q18: 前端巨型组件拆分 — TraceManager [done]
问题: TraceManager.tsx(605 行)是 Q17 拆分后项目最大的核心业务组件之一(排除 UI 库 sidebar/data-table),包含链路追踪管理页面的全部逻辑:类型定义(Trace/Span/SpanLog/ServiceMetrics)、状态徽章/Kind 图标/状态颜色/耗时格式化等工具函数、Span 树构建、SpanTreeNode 递归组件内联定义(每次父组件 render 重新创建组件函数,性能反模式)、Traces/Services/Metrics 三个 Tab 的完整 JSX、Trace 详情弹窗(Span 树可视化)、Span 详情弹窗(基本信息+标签+日志)。单文件过大导致维护困难。
已完成 (2026-07-08):
将类型/工具函数、共享 JSX 辅助、递归 Span 树组件、两个详情弹窗提取为 trace-manager/ 子目录下的独立文件:
| 新文件 | 行数 | 职责 |
|---|---|---|
types.ts |
90 | Trace/Span/SpanLog/ServiceMetrics 接口 + formatDuration/getStatusColor/buildSpanTree 纯函数 |
trace-helpers.tsx |
44 | getStatusBadge(状态徽章)+ getKindIcon(Span kind 图标)共享 JSX 辅助,接收 TFunction 参数 |
SpanTreeNode.tsx |
71 | 递归 Span 树节点组件(展开/折叠 + 时间轴宽度 + 状态色 + 点击选中 Span),接收 span/level/totalDuration/onSelectSpan props |
TraceDetailDialog.tsx |
80 | Trace 详情弹窗(服务/操作/总耗时/状态摘要 + ScrollArea 内 Span 树可视化) |
SpanDetailDialog.tsx |
91 | Span 详情弹窗(基本信息网格 + 标签键值对 + 日志列表) |
主文件 TraceManager.tsx 从 605 行降至 331 行(-45%),仅保留:状态管理(traces/services/loading/搜索/筛选/时间范围/activeTab/selectedTrace/selectedSpan/弹窗开关)、数据加载(fetchData/fetchTraces/fetchServices/fetchTraceDetail)、派生数据(filteredTraces/serviceNames)、handleSelectSpan 回调、pageTabs、tracesToolbar(搜索+服务/状态/时间筛选+刷新)、PageShell 布局(StatStrip 统计条 + Traces 表格 + Services 表格 + Metrics 卡片)、以及 TraceDetailDialog + SpanDetailDialog 两个弹窗组件的编排。
关键改进: 原 SpanTreeNode 定义在主组件函数体内(const SpanTreeNode: React.FC = (...) 内联),每次父组件 render 都会创建新的组件函数引用 → React 无法复用,整个 Span 子树重渲染。提取为模块级独立组件后,组件引用稳定,避免不必要的子树重渲染。
提取原则: types 为纯数据/类型(零 React 依赖);trace-helpers 为共享 JSX 辅助(getStatusBadge/getKindIcon 返回 ReactNode,接收 TFunction 以支持 i18n);SpanTreeNode 为独立递归组件(模块级定义,接收 4 个 props);TraceDetailDialog/SpanDetailDialog 为受控展示组件(接收 open/onOpenChange/数据 props,内部用 useTranslation)。零逻辑变更。
验收标准:
- TraceManager.tsx 从 605 行降至 331 行(-45%)
- 5 个提取的文件全部 < 95 行(最大 SpanDetailDialog 91 行)
tsc -b零错误npm run build零错误(✓ built in 18.23s)- ESLint errors 保持 0(trace-manager/ 目录零 warnings)
- ESLint warnings 保持 64(无新增)
- 全局 ESLint any 保持 0
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy,前端页面正常加载(HTTP 200),traces API 返回 200
- 链路追踪管理页功能不变(Traces/Services/Metrics 三 Tab + Trace 详情 Span 树 + Span 详情标签/日志全部正常)
- SpanTreeNode 内联定义反模式已修复(提取为模块级稳定组件引用)
Q17: 前端巨型组件拆分 — DeploymentEditService [done]
问题: DeploymentEditService.tsx(627 行)是 Q16 拆分后项目最大的核心业务组件之一(排除 UI 库 sidebar/data-table),包含 Deployment 编辑器「服务/应用路由」Tab 的全部逻辑:类型定义 + 端口预设常量、多端口 Service 创建表单(端口增删改 + 快速预设 + NodePort/ClusterIP 类型切换 + selector 预览)、Ingress 创建表单、Service/Ingress 列表卡片渲染(selector 关联高亮 + 端口/路由规则展示)、数据加载(Promise.all 拉取关联 Service/Ingress 并解析为摘要)、manifest 构建(createService/createIngress)、删除确认、以及可视化编辑器挂载。单文件过大导致维护困难。
已完成 (2026-07-08):
将类型/常量、创建表单、列表卡片提取为 deployment-edit-service/ 子目录下的独立文件:
| 新文件 | 行数 | 职责 |
|---|---|---|
types.ts |
78 | SvcPort/SvcSummary/IngBackend/IngPath/IngRule/IngSummary 接口 + SvcPortFormItem/SvcFormState/IngFormState 表单状态类型 + PORT_PRESETS 端口预设常量 + toArray 后端响应归一化辅助 |
ServiceCreateForm.tsx |
147 | 创建 Service 表单(基本信息 + 快速预设按钮 + 多端口配置行 + selector 预览),受控组件接收 svcForm/setSvcForm,内部管理 addPort/updatePort/removePort 端口操作 |
IngressCreateForm.tsx |
61 | 创建 Ingress 表单(名称/ingressClass/host/path/svcPort),受控组件接收 ingForm/setIngForm |
ServiceListItem.tsx |
52 | 单个 Service 卡片(关联高亮 + ClusterIP + 端口标签 + selector),纯展示组件接收 svc + matched + onEdit/onDelete |
IngressListItem.tsx |
49 | 单个 Ingress 卡片(关联高亮 + 路由规则 host→path→backend),纯展示组件接收 ing + matched + onEdit/onDelete |
主文件 DeploymentEditService.tsx 从 627 行降至 394 行(-37%),仅保留:状态管理(loading/services/ingresses/selectorLabels/visualEditor/showCreate/svcForm/ingForm)、数据加载(load + Promise.all + 摘要解析)、selectorMatches 关联判定、派生数据(matchedSvcs/matchedSvcNames/matchedIngs)、manifest 构建与 API 调用(createService/createIngress/deleteResource)、loading 骨架、Selector 提示卡片、Services/Ingresses 卡片外壳(header + 空状态 + 列表编排 + 表单挂载)、ResourceVisualEditor 挂载、取消按钮。
提取原则: types 为纯数据/类型(零 React 依赖);ServiceCreateForm 为受控表单组件(接收 svcForm + setSvcForm,内部封装端口增删改逻辑);IngressCreateForm 为受控表单组件;ServiceListItem/IngressListItem 为纯展示组件(接收数据 + matched 状态 + 回调)。零逻辑变更。类型安全方面,SvcPort.targetPort 和 IngBackend.port 保持 unknown 类型(与后端动态值一致),列表渲染处用 String() 包裹(与原 any 渲染结果一致),移除了原文件顶部的文件级 eslint-disable @typescript-eslint/no-explicit-any。
验收标准:
- DeploymentEditService.tsx 从 627 行降至 394 行(-37%)
- 5 个提取的文件全部 < 150 行(最大 ServiceCreateForm 147 行)
tsc -b零错误npm run build零错误(✓ built in 16.86s)- ESLint errors 保持 0(拆分目录零 errors/warnings,清理 1 个冗余 disable 指令)
- ESLint warnings 保持 64(无新增)
- 全局 ESLint any 保持 0
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy
- Deployment 服务/路由编辑 Tab 功能不变(Service/Ingress 列表关联高亮、创建表单多端口配置、编辑/删除、可视化编辑器全部正常)
Q16: 前端巨型组件拆分 — RdpDialog [done]
问题: RdpDialog.tsx(642 行)是 Q15 拆分后项目最大的核心业务组件之一(排除 UI 库 sidebar/data-table),包含 RDP 远程桌面弹窗的全部逻辑:接口定义 + 分辨率常量、视口计算纯函数(clampRdpSize/calcRdpViewport)、位图绘制/二进制帧解析纯函数(paintBitmap/parseRawFrame)、修饰键状态工具、WebSocket 连接生命周期、鼠标/键盘事件处理、帧绘制(bitmap/rawFrame 双通道)、以及内联的顶部标题栏 JSX(连接状态指示 + 工具弹窗 + 全屏/关闭按钮)。单文件过大导致维护困难。
已完成 (2026-07-08):
将类型/常量、纯函数、标题栏组件提取为 rdp-dialog/ 子目录下的独立文件:
| 新文件 | 行数 | 职责 |
|---|---|---|
types.ts |
55 | RdpDialogProps/RdpFrame/RdpStats/RdpRawFrame/KeyModifierState 接口 + 分辨率常量(RDP_DEFAULT_WIDTH 等 9 个) |
rdp-utils.ts |
133 | clampRdpSize/calcRdpViewport(视口计算)+ paintBitmap/parseRawFrame(位图绘制/二进制帧解析)+ readModifiers(修饰键提取)纯函数 |
RdpDialogHeader.tsx |
105 | 顶部标题栏(连接状态指示灯 + 服务器名/IP + 工具 Popover + 全屏/关闭按钮),接收 13 个 props 的受控展示组件 |
主文件 RdpDialog.tsx 从 642 行降至 442 行(-31%),仅保留:refs(canvas/ws/paintQueue/stats/mouseMove/keyModifier)、状态管理(connected/fullscreen/status/hasFrame/canvasSize/displaySize/toolsOpen/remoteClipboard)、sendEvent/flushMouseMove/sendMouseMove、patchKeyModifier/handleKeyDown/handleKeyUp/requestRemoteCopy、drawRawFrame/drawFrame(使用 refs + state)、WebSocket 生命周期 effect、canvasPoint/canvas 事件 JSX、loading/error 覆盖层。
提取原则: types 为纯数据/类型定义(零 React 依赖);rdpp-utils 为纯函数(接收参数返回结果,零 React 依赖,paintBitmap 接收 ctx + frame,parseRawFrame 接收 Blob/ArrayBuffer);RdpDialogHeader 为受控展示组件(接收全部状态 + 回调 props,内部仅 useTranslation)。零逻辑变更。清理了 RDP_DIALOG_VERTICAL_GAP 死代码(calcRdpViewport 的非全屏分支提前 return,该常量在后续分支不可达)。
验收标准:
- RdpDialog.tsx 从 642 行降至 442 行(-31%)
- 3 个提取的文件全部 < 135 行(最大 rdpp-utils 133 行)
tsc -b零错误npm run build零错误(✓ built in 15.78s)- ESLint errors 保持 0(清理 1 个 unused import: RDP_DIALOG_VERTICAL_GAP)
- ESLint warnings 保持 64(无新增)
- 全局 ESLint any 保持 0
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy
- RDP 远程桌面弹窗功能不变(WebSocket 连接/帧绘制/鼠标键盘/剪贴板同步/文件下载/全屏切换全部正常)
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 获取标签)。零逻辑变更。
验收标准:
- ApprovalWorkflowPage.tsx 从 705 行降至 167 行(-76%)
- 4 个提取的文件全部 < 275 行(最大 WorkflowEditorModal 272 行)
tsc -b零错误npm run build零错误(✓ built in 16.99s)- ESLint errors 保持 0(approval-workflow/ 目录零 warnings)
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy
- 审批工作流配置页功能不变(列表/新建/编辑/删除/启用停用/设默认/展开详情全部正常)
U12: 工程质量回归修复(ESLint errors + React Hooks 关键规则)[done]
问题: 远程 i18n 全量改造 + 堡垒机功能合并(a9513c2 + e0d652d)后引入两类工程质量回归:
- 8 个 ESLint errors(构建质量门禁阻断)— i18n 迁移引入了未使用的
const { t } = useTranslation()(代码实际用全局i18n.t())+cnimport 未使用 + 终端回放正则no-control-regex - 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 — 移除未使用的
cnimport - ✅ 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 静态性要求
验收标准:
- ESLint errors 从 8 降至 0
- React Hooks 6 大关键规则从 82 降至 0(恢复 U7 治理水平)
tsc -b零错误npm run build零错误(✓ built in 18.04s)go build零错误- 17/17 集成回归测试通过(零回归)
- 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 帧写入(客户端断开时正常)
验收标准:
- controller/ + middleware/ 层所有 DB 写入操作(Create/Update/Updates)零
_ =静默忽略 - 修复 2 处 Go 变量名遮蔽陷阱(
log := model.AuditLog{}→auditLog) go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy
状态标记规则
pending → in_progress → done / blocked
每个模块完成后:
- 更新本文件状态
- 更新 PROJECT_EVALUATION.md 对应行
- 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 等复用),无需新增
验收标准:
/host-dashboard路由可访问,HostMonitorDashboard 组件渲染- 侧边栏「监控告警 → 主机大屏」菜单项可见,权限
agent:monitor过滤 - 面包屑显示「主机大屏」
tsc -b零错误npm run build零错误(✓ built in 17.50s)- ESLint errors=0(无新增)
- zh/en 翻译键对齐(7556 = 7556)
- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy
- 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),无需抑制。
验收标准:
- ESLint "Unused eslint-disable directive" 从 6 降至 0
- ESLint errors 保持 0(无新增)
- ESLint warnings 从 65 降至 59(减少 6)
tsc -b零错误npm run build零错误(✓ built in 16.93s)- 17/17 集成回归测试通过(零回归)
- 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),零逻辑变更。
验收标准:
- ResourceVisualEditor.tsx 从 882 行降至 282 行(-68%)
- 5 个提取的编辑器文件全部 < 220 行
tsc -b零错误npm run build零错误(✓ built in 16.11s)- ESLint errors 保持 0(清理 11 个 unused import)
- ESLint warnings 保持 59(无新增)
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy
- 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)。零逻辑变更。
验收标准:
- AgentCLI.tsx 从 814 行降至 521 行(-36%)
- 4 个提取的文件全部 < 300 行(最大 AgentCLIToolbar 281 行)
tsc -b零错误npm run build零错误(✓ built in 16.95s)- ESLint errors 保持 0(清理 6 个 unused 变量/import)
- ESLint warnings 保持 59(无新增)
go build零错误- 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} 展开传递,零逻辑变更。
验收标准:
- SystemSettingsTab.tsx 从 754 行降至 173 行(-77%)
- 3 个提取的子 Tab 文件全部 < 310 行(最大 SecuritySettingsTab 309 行)
tsc -b零错误npm run build零错误(✓ built in 17.71s)- ESLint errors 保持 0(无新增)
- ESLint warnings 保持 59(无新增)
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy
- 系统设置页 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)。零逻辑变更。
验收标准:
- NamespaceResourcePage.tsx 从 719 行降至 300 行(-58%)
- 2 个提取的文件全部 < 325 行(namespace-resource-config 321 行 + PodDetailDialog 144 行)
tsc -b零错误npm run build零错误(✓ built in 15.88s)- ESLint errors 保持 0(清理 4 个 unused import: Table/TableBody/TableHead/TableHeader)
- ESLint warnings 保持 59(5 个 react-refresh/only-export-components 符合既有模式)
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy
- 命名空间资源列表页 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 计算阶段状态)。零逻辑变更。
验收标准:
- PipelineRunDetail.tsx 从 678 行降至 273 行(-60%)
- 4 个提取的文件全部 < 185 行(最大 LogConsole 183 行)
tsc -b零错误npm run build零错误(✓ built in 17.39s)- ESLint errors 保持 0(清理 1 个 unused var + 2 个冗余 disable 指令)
- ESLint warnings 保持 59(无新增)
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy
- 流水线运行详情页功能不变(阶段进度条/执行记录表/日志 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 共用)。零逻辑变更。
验收标准:
- CloudServerImport.tsx 从 699 行降至 404 行(-42%)
- 6 个提取的文件全部 < 180 行(最大 DiscoverImportStep 176 行)
tsc -b零错误npm run build零错误(✓ built in 16.56s)- ESLint errors 保持 0(拆分文件零 warnings)
- ESLint warnings 保持 64(无新增)
- 全局 ESLint any 保持 0(移除文件级 eslint-disable)
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy,前端页面正常加载(HTTP 200)
- 云服务器导入向导功能不变(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 为三态纯展示组件。零逻辑变更。
验收标准:
- UnifiedQueryPanel.tsx 从 682 行降至 529 行(-22%)
- 7 个提取的文件全部 < 115 行(最大 SecondaryToolbar 112 行)
tsc -b零错误npm run build零错误(✓ built in 17.57s)- ESLint errors 保持 0(UnifiedQueryPanel + unified-query/ 目录零 errors/warnings)
- ESLint warnings 保持 64(无新增)
- 全局 ESLint any 保持 0
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy,前端页面正常加载(HTTP 200)
- 日志中心查询面板功能不变(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)。
验收标准:
- ServerManager.tsx 从 652 行降至 442 行(-32%)
- 2 个提取的文件全部 < 270 行(最大 ServerTableSection 265 行)
tsc -b零错误npm run build零错误(✓ built in 16.40s)- ESLint errors 保持 0(3 个文件零 errors/warnings)
- ESLint warnings 保持 64(无新增)
- 全局 ESLint any 保持 0
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy,前端页面正常加载(HTTP 200)
- 服务器管理页功能不变(列表/搜索/筛选/分页/选择/批量删除/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)。零逻辑变更。
验收标准:
- PipelineEditor.tsx 从 676 行降至 406 行(-40%)
- 6 个提取的文件全部 < 180 行(最大 RunsHistoryTab 177 行)
tsc -b零错误npm run build零错误(✓ built in 16.35s)- ESLint errors 保持 0(清理 1 个 unused import: Loader2)
- ESLint warnings 保持 64(无新增)
- 全局 ESLint any 保持 0
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy,前端页面正常加载(HTTP 200)
- 流水线编辑器页功能不变(流程配置/触发器/变量/发布记录/成员管理 5 个 Tab 全部正常)
Q38: 前端巨型组件拆分 — UnifiedQueryPanel [done]
问题: UnifiedQueryPanel.tsx(529 行)是全项目最后一个 ≥500 行的业务组件(排除 UI 库 sidebar.tsx 690L / data-table.tsx 656L),包含日志查询面板的全部逻辑:~40 个 useState 状态管理、查询执行(Loki/ES 分支 + 直方图加载 + 派生数据 + 历史记录)、加载更多(分页游标)、Live Tail 实时追踪(3s interval + 去重 + 截断)、导出/复制、以及 6 个 useEffect(URL bootstrap/sync、Loki 标签名、ES mapping、Live Tail、自动运行)。虽然 UI 子组件已提取(Q13: 682L→529L),但核心业务逻辑仍全部内联。
已完成 (2026-07-10):
将查询执行逻辑和导出/复制逻辑提取为 unified-query/ 子目录下的自定义 Hooks:
| 新文件 | 行数 | 职责 |
|---|---|---|
useLogQueryEngine.ts |
295 | 日志查询执行引擎 Hook — 封装查询状态机:loading/entries/statTable/clusters/histogramData/totalCount/queryTime/hasMore/loadingMore/liveTail/hasQueried + fetchHistogram/handleRun/handleLoadMore/runLiveTailTick + Live Tail useEffect(3s interval),接收 effEngine/query/currentSource/esIndex/queryLimit/timeRange/setTimeRange/toast/t 作为 opts |
useLogExport.ts |
62 | 日志导出/复制 Hook — formatEntryLine + handleExportLogs(Blob 下载) + handleCopyLogs(clipboard),接收 effEngine/toast/t 作为 opts |
主文件从 529 行降至 353 行(-33%),全项目无 ≥500 行业务组件。
关键改进: 项目首次使用 custom Hook 提取模式进行组件拆分。useLogQueryEngine 封装了完整的查询状态机(执行/加载更多/直方图/Live Tail),主组件通过 opts 传入依赖。原 timeIsoParams useCallback 消除(4 处使用改为直接内联),export/callback 从闭包捕获改为参数传入使 Hook 可复用。
验收标准:
- UnifiedQueryPanel.tsx 从 529 行降至 353 行(-33%),全项目无 ≥500 行业务组件
tsc -b零错误npm run build零错误(✓ built in 16.69s)- ESLint errors 保持 0,warnings 保持 66
- 全局 ESLint any 保持 0,unused-vars 保持 0
go build零错误- 17/17 集成回归测试通过(零回归)
- Docker 部署 healthy,前端页面正常加载(HTTP 200)
U24: Monitor 模块 i18n hook 迁移 [done]
问题: src/pages/monitor/ 目录下 26 个 .tsx 文件仍使用全局 import i18n from '@/i18n' + i18n.t('Chinese text') 模式(phantom key 问题 — 中文文本作为 i18n key,在 zh-CN locale 下「恰好工作」(返回 key 本身),但切换 en-US 时仍显示中文文本而非英文翻译)。这是 U17-U23 i18n 治理系列中最后一个大规模 phantom key 模块,涉及 299 处 i18n.t() 调用和 89 个唯一 phantom 中文文本键。
已完成 (2026-07-11):
- 新增
monitor.lbl翻译子命名空间 — 89 个语义化翻译键覆盖 5 个子模块(HostMonitor/MiddlewareMonitor/SiteMonitor/SNMPMonitor/Shared) - .tsx 文件 hook 迁移 — 26 个文件从
import i18n→useTranslation()hook + phantom 中文文本键 →monitor.lbl.*语义化键 - 模块级代码保留
i18n.t()— TABS 常量/METRIC_CATEGORIES 等模块级代码保留i18n.t()+ 语义化键 - .ts 工具文件 — helpers.ts 中文文本键替换为语义化键(保留
i18n.t()因 .ts 无法用 hook)
验收标准:
monitor.lbl命名空间 89 个语义化键,zh/en 完全对齐(6975 = 6975)- 26 个 .tsx 文件迁移到
useTranslation()hook - 299 处
i18n.t()→ 74 保留 + 225 迁移到t()hook tsc -b零错误npm run build零错误(✓ built in 17.16s)- ESLint errors=0,any=0,unused=0
go build零错误- Docker 部署 healthy
U31: AIOps Agent CLI 组件 i18n 修复 [done]
问题: AIOps Agent CLI 组件群(AgentCLI + AgentCLIToolbar + AgentCLIHistory + AgentCLIEmptyState + ChatInputArea + agent-cli-constants.ts)在 Q7/Q35 组件拆分后丢失了 U8 (v0.105) 的 i18n 集成——6 个文件中 ~66 行 UI 硬编码中文文本未接入 useTranslation() hook,切换 en-US 时仍显示中文。
根因: U8 (v0.105) 在原始 AgentCLI.tsx (814L) 上完成了 216 处中文清零。但后续 Q7 (v0.111) 将 AgentCLI 拆分为 AgentCLIToolbar/AgentCLIEmptyState/ScrollButtons + agent-cli-constants.ts,Q35 (v0.124) 又拆出 agent-cli/event-handler.ts + ChatInputArea.tsx。拆分过程中提取的文件未保留 i18n 集成,硬编码中文回归。
已完成 (2026-07-12):
- 新增
aiops.cli.*翻译命名空间 — 100 个翻译键,8 个子分类 (toolbar/safety/tips/error/info/viewMode/placeholder/history/empty/input) - 常量数组改为工厂函数 —
SAFETY_MODES/TIPS_HOST/TIPS_KUBERNETES从静态导出常量改为getSafetyModes(t)/getTipsHost(t)/getTipsKubernetes(t)接收TFunction参数的工厂函数(符合项目"工具文件收 TFunction 参数"约定) - 6 个组件文件迁移:
AgentCLI.tsx— subtitle/toast/error/placeholder/viewMode 共 22 处中文 → t() 调用AgentCLIToolbar.tsx— 模式/目标选择/Pod/安全模式/历史/状态徽章/核心能力共 28 处 → t()AgentCLIHistory.tsx— toast/confirm/label/status 共 16 处 → t()AgentCLIEmptyState.tsx— 空状态文案 8 处 → t()ChatInputArea.tsx— hint/stop/execute 3 处 → t()agent-cli-constants.ts— SAFETY_MODES 3 模式 × 4 字段 + TIPS 2 × 4 × 2 字段全部通过工厂函数 → t()
验收标准:
aiops.cli.*命名空间 100 个语义化键,zh/en 完全对齐(7481 = 7481)- 6 个文件全部 UI 硬编码中文清零(剩余 CJK 仅为注释)
tsc -b零错误npm run build零错误(✓ built in 18.21s)- ESLint errors=0,any=0,unused=0,warnings=53(无新增)
go build零错误- 17/17 集成回归测试通过
- Docker 部署 healthy