From 1877522239e0816a402f2b71452a307a99ca65e4 Mon Sep 17 00:00:00 2001 From: logan Date: Fri, 22 May 2026 21:58:37 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20AuditRulesPage=E7=99=BD=E5=B1=8F?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20+=20=E6=95=B0=E6=8D=AE=E6=BA=90=E6=9D=83?= =?UTF-8?q?=E9=99=90/=E7=8A=B6=E6=80=81=E5=AF=B9=E9=BD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - AuditRulesPage: rules/stats 空值防御, catch 时设置空数组/null - instance.add 权限: admin → admin+dba (与后端一致) - 状态映射: 后端 connected/disconnected/error → 前端在线/离线/异常 - InstancePage 所有状态引用统一使用 getStatusInfo() --- frontend/src/hooks/useAuth.tsx | 2 +- frontend/src/pages/AuditRulesPage.tsx | 8 ++++---- frontend/src/pages/InstancePage.tsx | 24 ++++++++++++++++++------ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/frontend/src/hooks/useAuth.tsx b/frontend/src/hooks/useAuth.tsx index 74a33fb..9524caf 100644 --- a/frontend/src/hooks/useAuth.tsx +++ b/frontend/src/hooks/useAuth.tsx @@ -62,7 +62,7 @@ export const actionPermissionMap: Record = { 'ticket.delete': ['admin'], 'query.create': ['admin', 'dba', 'developer'], 'query.export': ['admin', 'dba', 'developer'], - 'instance.add': ['admin'], + 'instance.add': ['admin', 'dba'], 'instance.edit': ['admin', 'dba'], 'instance.delete': ['admin'], 'user.manage': ['admin'], diff --git a/frontend/src/pages/AuditRulesPage.tsx b/frontend/src/pages/AuditRulesPage.tsx index 7260f29..b024bf3 100644 --- a/frontend/src/pages/AuditRulesPage.tsx +++ b/frontend/src/pages/AuditRulesPage.tsx @@ -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() { diff --git a/frontend/src/pages/InstancePage.tsx b/frontend/src/pages/InstancePage.tsx index 918fb99..96b032b 100644 --- a/frontend/src/pages/InstancePage.tsx +++ b/frontend/src/pages/InstancePage.tsx @@ -38,6 +38,18 @@ const envLabel: Record = { production: '生产', staging: '预发', development: '开发', }; +const statusLabel: Record = { + 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() {
{envLabel[instance.env] || instance.env} -
+

{instance.name}

@@ -214,8 +226,8 @@ function InstanceDetail({ instance, onBack, config, canEdit, canDelete, onDelete

{instance.name} - - {instance.status === 'online' ? '在线' : '离线'} + + {getStatusInfo(instance.status).text}

{instance.host}:{instance.port} · {instance.version || '版本未知'}

@@ -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() },