refactor(frontend): api/components/pages 目录架构统一对齐菜单域 + 日志中心修复

1. 目录架构统一(API = components = 菜单域,一域一目录 + barrel)
   - log/ 提为独立顶层域(日志中心在菜单中与监控中心平级,不再塞在 monitor/)
   - task/ 拆分原 automation.ts → cron-job / script / remote-exec
   - aiops/ 合并 ai.ts + agentCli.ts → assistant + agent-cli
   - agent/ approval/ audit/ 提升为域目录
   - auth 拆分:authApi(认证自服务) + system/user.ts(userApi+ldapApi 管理端)
   - components/automation → components/task,菜单"自动化运维"→"作业任务"
   - pages/ 按域分子目录(approval/audit/monitor),删孤儿 AuditPage.tsx
   - 所有 API 符号名不变,组件经 @/api 聚合引用,运行时行为零变化

2. Loki 查询无返回修复:aiops 容器 DNS 解析外网域名失败
   (宿主机 systemd-resolved 转发链路异常),docker-compose 显式配 dns 上游

3. ES 查询框布局:工具栏单行挤 7 控件(ES 多 150px 索引框),拆两行——
   查询输入独占一行(+查询按钮),次级控件换行 flex-wrap

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
attackerandClaude committed 2026-06-28 06:06:48 +00:00
1 parent da01cbb119
commit c0ee8e4ddd
74 files changed
+229 -216

No files matched your search

@@ -0,0 +1,69 @@
// 监控中心 — 4个监控标签页的容器
import { useState } from 'react';
import { cn } from '@/lib/utils';
import { Cpu, Database, Radio, Globe } from 'lucide-react';
import { HostMonitor } from './HostMonitor';
import { MiddlewareMonitor } from './MiddlewareMonitor';
import { SNMPMonitor } from './SNMPMonitor';
import { SiteMonitor } from './SiteMonitor';
type TabId = 'host' | 'middleware' | 'snmp' | 'site';
interface Tab {
id: TabId;
name: string;
icon: React.ElementType;
description: string;
}
const tabs: Tab[] = [
{ id: 'host', name: '主机监控', icon: Cpu, description: 'CPU / 内存 / 磁盘 / 网络 / 磁盘IO' },
{ id: 'middleware', name: '中间件监控', icon: Database, description: 'Redis / MySQL 指标采集' },
{ id: 'snmp', name: 'SNMP 监控', icon: Radio, description: '网络设备 / 服务器硬件 (OID 模板)' },
{ id: 'site', name: '站点拨测', icon: Globe, description: 'HTTP / PING / DNS / TCP / WS 拨测' },
];
export function MonitorCenter() {
const [activeTab, setActiveTab] = useState<TabId>('host');
return (
<div className="space-y-6">
<div>
<h1 className="text-2xl font-bold text-[var(--dg-text-primary)]">监控中心</h1>
<p className="text-sm text-[var(--dg-text-muted)] mt-1">全面的基础设施与应用监控</p>
</div>
{/* Tab Bar */}
<div className="flex gap-1 bg-[var(--dg-bg-secondary)] p-1 rounded-lg border border-[var(--dg-border)]">
{tabs.map((tab) => (
<button
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={cn(
'flex-1 flex items-center justify-center gap-2 px-4 py-2.5 rounded-md text-sm font-medium transition-all',
activeTab === tab.id
? 'bg-[var(--dg-bg-tertiary)] text-[var(--dg-text-primary)] shadow-sm'
: 'text-[var(--dg-text-muted)] hover:text-[var(--dg-text-secondary)]'
)}
>
<tab.icon className="h-4 w-4" />
<span className="hidden sm:inline">{tab.name}</span>
</button>
))}
</div>
{/* Tab Description */}
<p className="text-sm text-[var(--dg-text-muted)] -mt-4">
{tabs.find(t => t.id === activeTab)?.description}
</p>
{/* Tab Content */}
<div className="min-h-[400px]">
{activeTab === 'host' && <HostMonitor />}
{activeTab === 'middleware' && <MiddlewareMonitor />}
{activeTab === 'snmp' && <SNMPMonitor />}
{activeTab === 'site' && <SiteMonitor />}
</div>
</div>
);
}