feat: Redis cluster support + version auto-detect + metrics API

This commit is contained in:
logan committed 2026-05-30 01:44:58 +08:00
1 parent 8384006ae9
commit 3af65f2350
10 files changed
+485 -66

No files matched your search

+1
View File
@@ -11,4 +11,5 @@ export const instanceApi = {
testNewConnection: (data: any) => request.post<any, any>('/instances/test-connection', data),
listDatabases: (id: number) => request.get<any, string[]>(`/instances/${id}/databases`),
listTables: (id: number, db: string) => request.get<any, any[]>(`/instances/${id}/databases/${db}/tables`),
metrics: (id: number) => request.get<any, any>(`/instances/${id}/metrics`),
};
+15 -6
View File
@@ -31,6 +31,7 @@ interface InstanceItem {
description: string | null;
status: string;
version: string | null;
cluster_mode?: boolean;
created_at: string;
connections?: number;
qps?: number;
@@ -728,6 +729,14 @@ function InstanceDetail({ instance, onBack, config, canEdit, canDelete, onDelete
}) {
const [testing, setTesting] = useState(false);
const [testResult, setTestResult] = useState<{ success: boolean; message: string; version?: string } | null>(null);
const [metrics, setMetrics] = useState<{ connections: number; qps: number; latency: number; uptime: string } | null>(null);
useEffect(() => {
instanceApi.metrics(instance.id).then(res => {
setMetrics({ connections: res.connections ?? 0, qps: res.qps ?? 0, latency: res.latency ?? 0, uptime: res.uptime ?? '-' });
}).catch(() => {});
}, [instance.id]);
const health = calcHealthScore(instance);
const info = getStatusInfo(instance.status);
const DetailIcon = config.icon;
@@ -768,7 +777,7 @@ function InstanceDetail({ instance, onBack, config, canEdit, canDelete, onDelete
{info.text}
</span>
</h1>
<p className="text-sm text-[var(--dg-text-secondary)]">{instance.host}:{instance.port} · {instance.version || '版本未知'}</p>
<p className="text-sm text-[var(--dg-text-secondary)]">{instance.host}:{instance.port} · {instance.version || '版本未知'}{instance.cluster_mode ? ' · 集群' : ''}</p>
</div>
</div>
</div>
@@ -881,10 +890,10 @@ function InstanceDetail({ instance, onBack, config, canEdit, canDelete, onDelete
<CardContent className="p-5">
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
{[
{ label: '连接数', value: instance.connections ?? 0, unit: '', icon: Users, color: 'text-blue-400', bg: 'bg-blue-400/10' },
{ label: 'QPS', value: instance.qps ?? 0, unit: '/s', icon: Activity, color: 'text-green-400', bg: 'bg-green-400/10' },
{ label: '延迟', value: instance.latency ?? 0, unit: 'ms', icon: Signal, color: 'text-orange-400', bg: 'bg-orange-400/10' },
{ label: '运行时间', value: '-', unit: '', icon: HardDrive, color: 'text-purple-400', bg: 'bg-purple-400/10' },
{ label: '连接数', value: instance.connections ?? metrics?.connections ?? 0, unit: '', icon: Users, color: 'text-blue-400', bg: 'bg-blue-400/10' },
{ label: 'QPS', value: instance.qps ?? metrics?.qps ?? 0, unit: '/s', icon: Activity, color: 'text-green-400', bg: 'bg-green-400/10' },
{ label: '延迟', value: instance.latency ?? metrics?.latency ?? 0, unit: 'ms', icon: Signal, color: 'text-orange-400', bg: 'bg-orange-400/10' },
{ label: '运行时间', value: metrics?.uptime ?? '-', unit: '', icon: HardDrive, color: 'text-purple-400', bg: 'bg-purple-400/10' },
].map(m => (
<div key={m.label} className="p-3 rounded-lg bg-[var(--dg-bg-tertiary)] text-center">
<div className={`w-8 h-8 rounded-lg ${m.bg} flex items-center justify-center mx-auto mb-2`}>
@@ -911,7 +920,7 @@ function InstanceDetail({ instance, onBack, config, canEdit, canDelete, onDelete
{ label: '用户名', value: instance.username },
{ label: '默认数据库', value: instance.database || '-' },
{ label: '运行环境', value: envLabel[instance.env] || instance.env },
{ label: '版本', value: instance.version || '-' },
{ label: '版本', value: `${instance.version || '-'}${instance.cluster_mode ? ' (集群)' : ''}` },
{ label: '创建时间', value: new Date(instance.created_at).toLocaleString() },
].map(item => (
<div key={item.label} className="flex justify-between py-1.5 border-b border-[var(--dg-border-light)] last:border-0">