{/* ---- Quick Actions ---- */}
{quickActions.map(action => (
))}
{/* ---- Announcements ---- */}
{visibleAnnouncements.length > 0 && (
{visibleAnnouncements.slice(0, 3).map(ann => {
const isExpanded = expandedId === ann.id;
return (
{ann.title}
{ann.publishTime.slice(0, 10)}
{ann.content}
{ann.content.includes('\n') && (
)}
);
})}
)}
{/* ---- Stats Cards ---- */}
{loading ? (
Array.from({ length: 3 }).map((_, i) =>
)
) : (
statsCards.map((s, i) => (
{s.value}
{s.subtitle}
))
)}
{/* ---- My Pending Tickets + Instance Status ---- */}
{/* My Pending Tickets */}
我的待处理
({pendingTickets.length})
查看全部
{pendingTickets.length === 0 ? (
暂无待处理工单
) : (
| 工单号 |
标题 |
数据库 |
状态 |
待处理 |
关联 |
时间 |
操作 |
{pendingTickets.map((ticket: any) => (
| TK-{ticket.id} |
{ticket.title} |
{(ticket.db_type || '').toUpperCase()}
|
{statusMap[ticket.status] || ticket.status}
|
{ticket.pending_info || '-'} |
{ticket.relation}
|
{ticket.create_time} |
|
))}
)}
{/* Instance Status */}
实例状态
{onlineInstances}/{dbInstances.length} 在线
{/* Status Overview */}
{/* Instance List */}
{dbInstances.slice(0, 5).map(inst => {
const health = calcHealthScore(inst);
return (
{inst.name}
{health}
{inst.host}{inst.port ? `:${inst.port}` : ''}
{(inst.qps ?? 0).toLocaleString()} QPS
{inst.connections ?? 0} 连接
);
})}
{/* ---- DataSource Health + Query Stats ---- */}
{/* DataSource Health */}
数据源健康概览
{onlineInstances}/{dbInstances.length} 在线
{/* By Type */}
{(['mysql', 'postgres', 'redis', 'mongo'] as const).map(type => {
const typeInstances = dbInstances.filter(i => i.dbType === type);
const typeOnline = typeInstances.filter(i => i.status === 'online').length;
const iconMap: Record
= { mysql: '/db-logos/mysql.svg', postgres: '/db-logos/postgres.svg', redis: '/db-logos/redis.svg', mongo: '/db-logos/mongo.svg' };
const labelMap: Record = { mysql: 'MySQL', postgres: 'PostgreSQL', redis: 'Redis', mongo: 'MongoDB' };
const allHealthy = typeOnline === typeInstances.length && typeInstances.length > 0;
const someHealthy = typeOnline > 0;
return (
{typeInstances.length}
{labelMap[type]}
{typeOnline}/{typeInstances.length}
);
})}
{/* Attention List */}
{dbInstances.filter(i => i.status === 'warning' || i.status === 'offline').length > 0 && (
需要关注
{dbInstances.filter(i => i.status === 'warning' || i.status === 'offline').slice(0, 3).map(inst => {
const health = calcHealthScore(inst);
return (
{inst.name}
{inst.host}:{inst.port}
{health}分
{inst.status === 'offline' ? '离线' : '告警'}
);
})}
)}
{/* Query Stats */}
查询统计
{(['今日', '本周', '本月'] as const).map((p, i) => (
))}
总查询数
{(queryStats?.total ?? 0).toLocaleString()}
平均耗时
{queryStats?.avg_time ?? 0}ms
{queryStats?.slow_count ?? 0}
查询类型分布
{(queryStats?.type_distribution ?? [
{ label: 'MySQL', count: 0, color: 'bg-[#00758f]' },
{ label: 'PostgreSQL', count: 0, color: 'bg-[#336791]' },
{ label: 'Redis', count: 0, color: 'bg-[#dc382d]' },
{ label: 'MongoDB', count: 0, color: 'bg-[#47a248]' },
]).map((item: any) => {
const total = queryStats?.total || 1;
return (
{item.label}
{item.count}
);
})}
);
}