fix: AuditRulesPage白屏修复 + 数据源权限/状态对齐

- AuditRulesPage: rules/stats 空值防御, catch 时设置空数组/null
- instance.add 权限: admin → admin+dba (与后端一致)
- 状态映射: 后端 connected/disconnected/error → 前端在线/离线/异常
- InstancePage 所有状态引用统一使用 getStatusInfo()
This commit is contained in:
logan committed 2026-05-22 21:58:37 +08:00
1 parent f20cd30138
commit 1877522239
3 files changed
+23 -11

No files matched your search

+4 -4
View File
@@ -49,15 +49,15 @@ export default function AuditRulesPage() {
if (filter.severity) params.set('severity', filter.severity);
if (filter.is_enabled !== '') params.set('is_enabled', filter.is_enabled);
const res = await request.get('/audit-rules', { params });
setRules(res.data);
} catch { /* */ } finally { setLoading(false); }
setRules(Array.isArray(res.data) ? res.data : []);
} catch { setRules([]); } finally { setLoading(false); }
}
async function fetchStats() {
try {
const res = await request.get('/audit-rules/stats/summary');
setStats(res.data);
} catch { /* */ }
setStats(res.data || null);
} catch { setStats(null); }
}
async function handleCreate() {
+18 -6
View File
@@ -38,6 +38,18 @@ const envLabel: Record<string, string> = {
production: '生产', staging: '预发', development: '开发',
};
const statusLabel: Record<string, { text: string; online: boolean }> = {
connected: { text: '在线', online: true },
online: { text: '在线', online: true },
disconnected: { text: '离线', online: false },
offline: { text: '离线', online: false },
error: { text: '异常', online: false },
};
function getStatusInfo(status: string) {
return statusLabel[status] || { text: '离线', online: false };
}
export default function InstancePage() {
const { type = 'mysql' } = useParams<{ type: string }>();
const canAdd = useActionPermission('instance.add');
@@ -78,8 +90,8 @@ export default function InstancePage() {
});
const statusCounts = {
online: filtered.filter(i => i.status === 'online').length,
offline: filtered.filter(i => i.status === 'offline').length,
online: filtered.filter(i => getStatusInfo(i.status).online).length,
offline: filtered.filter(i => !getStatusInfo(i.status).online).length,
total: filtered.length,
};
@@ -164,7 +176,7 @@ export default function InstancePage() {
</div>
<div className="flex items-center gap-2">
<span className="px-2 py-0.5 bg-[var(--dg-bg-tertiary)] text-[var(--dg-text-muted)] text-[11px] rounded-md">{envLabel[instance.env] || instance.env}</span>
<div className={`w-2.5 h-2.5 rounded-full ${instance.status === 'online' ? 'bg-green-400 shadow-[0_0_0_3px_rgba(63,185,80,0.2)]' : 'bg-red-400'}`} />
<div className={`w-2.5 h-2.5 rounded-full ${getStatusInfo(instance.status).online ? 'bg-green-400 shadow-[0_0_0_3px_rgba(63,185,80,0.2)]' : 'bg-red-400'}`} />
</div>
</div>
<h3 className="text-base font-semibold mb-1">{instance.name}</h3>
@@ -214,8 +226,8 @@ function InstanceDetail({ instance, onBack, config, canEdit, canDelete, onDelete
</div>
<h1 className="text-2xl font-semibold flex items-center gap-3">
{instance.name}
<span className={`px-2.5 py-1 rounded-full text-xs font-medium ${instance.status === 'online' ? 'bg-green-500/15 text-green-400' : 'bg-red-500/15 text-red-400'}`}>
{instance.status === 'online' ? '在线' : '离线'}
<span className={`px-2.5 py-1 rounded-full text-xs font-medium ${getStatusInfo(instance.status).online ? 'bg-green-500/15 text-green-400' : 'bg-red-500/15 text-red-400'}`}>
{getStatusInfo(instance.status).text}
</span>
</h1>
<p className="text-sm text-[var(--dg-text-secondary)] mt-1">{instance.host}:{instance.port} · {instance.version || '版本未知'}</p>
@@ -264,7 +276,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.status === 'online' ? '在线' : '离线' },
{ label: '状态', value: getStatusInfo(instance.status).text },
{ label: '版本', value: instance.version || '-' },
{ label: '描述', value: instance.description || '-' },
{ label: '创建时间', value: new Date(instance.created_at).toLocaleString() },