fix: AuditRulesPage白屏修复 + 数据源权限/状态对齐
- AuditRulesPage: rules/stats 空值防御, catch 时设置空数组/null - instance.add 权限: admin → admin+dba (与后端一致) - 状态映射: 后端 connected/disconnected/error → 前端在线/离线/异常 - InstancePage 所有状态引用统一使用 getStatusInfo()
This commit is contained in:
1 parent
f20cd30138
commit
1877522239
3 files changed
+23
-11
No files matched your search
@@ -62,7 +62,7 @@ export const actionPermissionMap: Record<string, UserRole[]> = {
|
|||||||
'ticket.delete': ['admin'],
|
'ticket.delete': ['admin'],
|
||||||
'query.create': ['admin', 'dba', 'developer'],
|
'query.create': ['admin', 'dba', 'developer'],
|
||||||
'query.export': ['admin', 'dba', 'developer'],
|
'query.export': ['admin', 'dba', 'developer'],
|
||||||
'instance.add': ['admin'],
|
'instance.add': ['admin', 'dba'],
|
||||||
'instance.edit': ['admin', 'dba'],
|
'instance.edit': ['admin', 'dba'],
|
||||||
'instance.delete': ['admin'],
|
'instance.delete': ['admin'],
|
||||||
'user.manage': ['admin'],
|
'user.manage': ['admin'],
|
||||||
|
|||||||
@@ -49,15 +49,15 @@ export default function AuditRulesPage() {
|
|||||||
if (filter.severity) params.set('severity', filter.severity);
|
if (filter.severity) params.set('severity', filter.severity);
|
||||||
if (filter.is_enabled !== '') params.set('is_enabled', filter.is_enabled);
|
if (filter.is_enabled !== '') params.set('is_enabled', filter.is_enabled);
|
||||||
const res = await request.get('/audit-rules', { params });
|
const res = await request.get('/audit-rules', { params });
|
||||||
setRules(res.data);
|
setRules(Array.isArray(res.data) ? res.data : []);
|
||||||
} catch { /* */ } finally { setLoading(false); }
|
} catch { setRules([]); } finally { setLoading(false); }
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchStats() {
|
async function fetchStats() {
|
||||||
try {
|
try {
|
||||||
const res = await request.get('/audit-rules/stats/summary');
|
const res = await request.get('/audit-rules/stats/summary');
|
||||||
setStats(res.data);
|
setStats(res.data || null);
|
||||||
} catch { /* */ }
|
} catch { setStats(null); }
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleCreate() {
|
async function handleCreate() {
|
||||||
|
|||||||
@@ -38,6 +38,18 @@ const envLabel: Record<string, string> = {
|
|||||||
production: '生产', staging: '预发', development: '开发',
|
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() {
|
export default function InstancePage() {
|
||||||
const { type = 'mysql' } = useParams<{ type: string }>();
|
const { type = 'mysql' } = useParams<{ type: string }>();
|
||||||
const canAdd = useActionPermission('instance.add');
|
const canAdd = useActionPermission('instance.add');
|
||||||
@@ -78,8 +90,8 @@ export default function InstancePage() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const statusCounts = {
|
const statusCounts = {
|
||||||
online: filtered.filter(i => i.status === 'online').length,
|
online: filtered.filter(i => getStatusInfo(i.status).online).length,
|
||||||
offline: filtered.filter(i => i.status === 'offline').length,
|
offline: filtered.filter(i => !getStatusInfo(i.status).online).length,
|
||||||
total: filtered.length,
|
total: filtered.length,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -164,7 +176,7 @@ export default function InstancePage() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<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>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
<h3 className="text-base font-semibold mb-1">{instance.name}</h3>
|
<h3 className="text-base font-semibold mb-1">{instance.name}</h3>
|
||||||
@@ -214,8 +226,8 @@ function InstanceDetail({ instance, onBack, config, canEdit, canDelete, onDelete
|
|||||||
</div>
|
</div>
|
||||||
<h1 className="text-2xl font-semibold flex items-center gap-3">
|
<h1 className="text-2xl font-semibold flex items-center gap-3">
|
||||||
{instance.name}
|
{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'}`}>
|
<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'}`}>
|
||||||
{instance.status === 'online' ? '在线' : '离线'}
|
{getStatusInfo(instance.status).text}
|
||||||
</span>
|
</span>
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-sm text-[var(--dg-text-secondary)] mt-1">{instance.host}:{instance.port} · {instance.version || '版本未知'}</p>
|
<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.username },
|
||||||
{ label: '默认数据库', value: instance.database || '-' },
|
{ label: '默认数据库', value: instance.database || '-' },
|
||||||
{ label: '运行环境', value: envLabel[instance.env] || instance.env },
|
{ 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.version || '-' },
|
||||||
{ label: '描述', value: instance.description || '-' },
|
{ label: '描述', value: instance.description || '-' },
|
||||||
{ label: '创建时间', value: new Date(instance.created_at).toLocaleString() },
|
{ label: '创建时间', value: new Date(instance.created_at).toLocaleString() },
|
||||||
|
|||||||
Reference in new issue
Block a user