feat: 全站 PageShell 设计系统与专业 UI 统一

- 新增 PageShell/PageTabs/ContentPanel/PageLoading/PageEmpty 页面骨架
- index.css 设计令牌文档化,布局令牌与纯色主按钮(去除渐变粉彩)
- 全站路由页接入 PageShell,云账单三 Tab 为标杆
- 主题体系:跟随系统 + 主流/开发者分组,新增 Dracula/Tokyo Night,One Dark 暖灰差异化
- 登录页/侧栏/顶栏去渐变光球,企业克制风
- 修复 AIAlertAnalyzer JSX 与构建依赖导入问题
This commit is contained in:
Logan committed 2026-07-01 12:45:38 +08:00
1 parent 1acb0c49af
commit e363ded445
213 files changed
+7148 -6818

No files matched your search

@@ -43,21 +43,21 @@ export function AlertEventsTab({
switch (severity) {
case 'critical':
return (
<Badge variant="outline" className="border-red-500/30 text-red-400 bg-red-500/10">
<Badge variant="outline" className="border-red-500/30 dg-text-red bg-red-500/10">
<AlertTriangle className="h-3 w-3 mr-1" />
严重
</Badge>
);
case 'warning':
return (
<Badge variant="outline" className="border-amber-500/30 text-amber-400 bg-amber-500/10">
<Badge variant="outline" className="border-amber-500/30 dg-text-yellow bg-amber-500/10">
<AlertTriangle className="h-3 w-3 mr-1" />
警告
</Badge>
);
case 'info':
return (
<Badge variant="outline" className="border-blue-500/30 text-blue-400 bg-blue-500/10">
<Badge variant="outline" className="border-blue-500/30 dg-text-blue bg-blue-500/10">
<Bell className="h-3 w-3 mr-1" />
提示
</Badge>
@@ -71,13 +71,13 @@ export function AlertEventsTab({
switch (status) {
case 'firing':
return (
<Badge variant="outline" className="border-red-500/30 text-red-400 bg-red-500/10 animate-pulse">
<Badge variant="outline" className="border-red-500/30 dg-text-red bg-red-500/10 animate-pulse">
触发中
</Badge>
);
case 'resolved':
return (
<Badge variant="outline" className="border-emerald-500/30 text-emerald-400 bg-emerald-500/10">
<Badge variant="outline" className="border-emerald-500/30 dg-text-green bg-emerald-500/10">
已恢复
</Badge>
);
@@ -100,18 +100,18 @@ export function AlertEventsTab({
{/* Filters */}
<div className="flex items-center gap-3 flex-wrap">
<div className="relative w-64">
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-slate-500" />
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 dg-text-muted" />
<Input
placeholder="搜索告警名称或目标..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="pl-9 h-9 bg-slate-800/50 border-slate-700 text-slate-200 placeholder:text-slate-500"
className="pl-9 h-9 dg-input"
/>
</div>
<select
value={severityFilter}
onChange={(e) => setSeverityFilter(e.target.value)}
className="h-9 px-3 rounded-md bg-slate-800/50 border border-slate-700 text-slate-200 text-sm"
className="h-9 px-3 rounded-md bg-[var(--dg-bg-tertiary)]/50 border border-[var(--dg-border)] text-[var(--dg-text-primary)] text-sm"
>
<option value="all">全部级别</option>
<option value="critical">严重</option>
@@ -121,7 +121,7 @@ export function AlertEventsTab({
<select
value={statusFilter}
onChange={(e) => setStatusFilter(e.target.value)}
className="h-9 px-3 rounded-md bg-slate-800/50 border border-slate-700 text-slate-200 text-sm"
className="h-9 px-3 rounded-md bg-[var(--dg-bg-tertiary)]/50 border border-[var(--dg-border)] text-[var(--dg-text-primary)] text-sm"
>
<option value="all">全部状态</option>
<option value="firing">触发中</option>
@@ -130,50 +130,50 @@ export function AlertEventsTab({
</div>
{/* Events Table */}
<Card className="bg-slate-900 border-slate-800">
<Card className="dg-card">
<CardContent className="p-0">
<div className="border-t border-slate-800">
<div className="border-t border-[var(--dg-border)]">
<Table>
<TableHeader>
<TableRow className="border-slate-800 hover:bg-transparent">
<TableHead className="text-slate-400">级别</TableHead>
<TableHead className="text-slate-400">告警名称</TableHead>
<TableHead className="text-slate-400">状态</TableHead>
<TableHead className="text-slate-400">目标</TableHead>
<TableHead className="text-slate-400">当前值</TableHead>
<TableHead className="text-slate-400">阈值</TableHead>
<TableHead className="text-slate-400">开始时间</TableHead>
<TableHead className="text-slate-400 text-right">操作</TableHead>
<TableRow className="border-[var(--dg-border)] hover:bg-transparent">
<TableHead className="dg-text-secondary">级别</TableHead>
<TableHead className="dg-text-secondary">告警名称</TableHead>
<TableHead className="dg-text-secondary">状态</TableHead>
<TableHead className="dg-text-secondary">目标</TableHead>
<TableHead className="dg-text-secondary">当前值</TableHead>
<TableHead className="dg-text-secondary">阈值</TableHead>
<TableHead className="dg-text-secondary">开始时间</TableHead>
<TableHead className="dg-text-secondary text-right">操作</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{loading ? (
<TableRow className="border-slate-800">
<TableCell colSpan={8} className="text-center text-slate-500 py-8">
<TableRow className="border-[var(--dg-border)]">
<TableCell colSpan={8} className="text-center dg-text-muted py-8">
<Loader2 className="h-5 w-5 animate-spin inline mr-2" />
加载中...
</TableCell>
</TableRow>
) : filteredEvents.map((event) => (
<TableRow key={event.id} className="border-slate-800 hover:bg-slate-800/50">
<TableRow key={event.id} className="border-[var(--dg-border)] hover:bg-[var(--dg-bg-hover)]">
<TableCell>{getSeverityBadge(event.severity)}</TableCell>
<TableCell>
<span className="text-sm font-medium text-slate-200">
<span className="text-sm font-medium text-[var(--dg-text-primary)]">
{(event.rule && event.rule.name) || event.message}
</span>
</TableCell>
<TableCell>{getStatusBadge(event.status)}</TableCell>
<TableCell className="max-w-[160px]">
<span className="text-sm text-slate-300 block truncate" title={event.target}>{event.target}</span>
<span className="text-sm text-[var(--dg-text-secondary)] block truncate" title={event.target}>{event.target}</span>
</TableCell>
<TableCell>
<span className="text-sm text-slate-300">{typeof event.value === 'number' ? event.value.toFixed(1) : event.value}</span>
<span className="text-sm text-[var(--dg-text-secondary)]">{typeof event.value === 'number' ? event.value.toFixed(1) : event.value}</span>
</TableCell>
<TableCell>
<span className="text-sm text-slate-500">{event.threshold}</span>
<span className="text-sm dg-text-muted">{event.threshold}</span>
</TableCell>
<TableCell>
<span className="text-sm text-slate-400">
<span className="text-sm dg-text-secondary">
{event.created_at ? new Date(event.created_at).toLocaleString() : '--'}
</span>
</TableCell>
@@ -183,7 +183,7 @@ export function AlertEventsTab({
<Button
variant="ghost"
size="sm"
className="h-8 text-slate-400 hover:text-emerald-400"
className="h-8 dg-text-secondary hover:dg-text-green"
onClick={() => handleAcknowledge(event.id)}
>
<CheckCircle className="h-4 w-4 mr-1" />