fix: AuditLogsPage暗色主题适配(20处) + 权限项前后端对齐(18→9项)
AuditLogsPage 暗色主题 P0 修复: - ACTION_COLORS: bg-blue-100→bg-blue-500/15, text-blue-800→text-blue-400 等 8 项 - 表格容器: bg-white→dg-card, bg-gray-50→bg-[var(--dg-bg-tertiary)] - 所有 text-gray-* → --dg-text-* 变量 - 所有 bg-gray-* → --dg-bg-* 变量 - 分隔线: divide-gray-100→divide-[var(--dg-border)] - 分页按钮: 全部改用 dg 变量 - grep 验证: 零残留硬编码亮色 InstanceGroupPage 权限项对齐: - 前端权限项从 18 个精简到 9 个,与后端 PERMISSION_ACTIONS 一致 - 查询: query:select, query:write - 工单: ticket:create, ticket:approve, ticket:execute - DDL: ddl:execute - 运维: slowlog:view, backup:manage, instance:detail
This commit is contained in:
1 parent
583e891619
commit
dba161265c
2 files changed
+33
-47
No files matched your search
@@ -20,14 +20,14 @@ interface AuditLogResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ACTION_COLORS: Record<string, string> = {
|
const ACTION_COLORS: Record<string, string> = {
|
||||||
CREATE_TICKET: 'bg-blue-100 text-blue-800',
|
CREATE_TICKET: 'bg-blue-500/15 text-blue-400',
|
||||||
REVIEW_TICKET: 'bg-yellow-100 text-yellow-800',
|
REVIEW_TICKET: 'bg-yellow-500/15 text-yellow-400',
|
||||||
EXECUTE_TICKET: 'bg-green-100 text-green-800',
|
EXECUTE_TICKET: 'bg-green-500/15 text-green-400',
|
||||||
CREATE_INSTANCE: 'bg-purple-100 text-purple-800',
|
CREATE_INSTANCE: 'bg-purple-500/15 text-purple-400',
|
||||||
DELETE_INSTANCE: 'bg-red-100 text-red-800',
|
DELETE_INSTANCE: 'bg-red-500/15 text-red-400',
|
||||||
CREATE_USER: 'bg-indigo-100 text-indigo-800',
|
CREATE_USER: 'bg-indigo-500/15 text-indigo-400',
|
||||||
DELETE_USER: 'bg-red-100 text-red-800',
|
DELETE_USER: 'bg-red-500/15 text-red-400',
|
||||||
QUERY: 'bg-cyan-100 text-cyan-800',
|
QUERY: 'bg-cyan-500/15 text-cyan-400',
|
||||||
};
|
};
|
||||||
|
|
||||||
const TARGET_ICONS: Record<string, string> = {
|
const TARGET_ICONS: Record<string, string> = {
|
||||||
@@ -75,8 +75,8 @@ export default function AuditLogsPage() {
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<h2 className="text-xl font-semibold text-gray-800">审计日志</h2>
|
<h2 className="text-xl font-semibold text-[var(--dg-text-primary)]">审计日志</h2>
|
||||||
<span className="text-sm text-gray-500">共 {total} 条记录</span>
|
<span className="text-sm text-[var(--dg-text-muted)]">共 {total} 条记录</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Filters */}
|
{/* Filters */}
|
||||||
@@ -88,7 +88,7 @@ export default function AuditLogsPage() {
|
|||||||
className={`px-3 py-1 text-xs rounded-full transition-colors ${
|
className={`px-3 py-1 text-xs rounded-full transition-colors ${
|
||||||
filterAction === action
|
filterAction === action
|
||||||
? 'bg-blue-600 text-white'
|
? 'bg-blue-600 text-white'
|
||||||
: 'bg-gray-100 text-gray-600 hover:bg-gray-200'
|
: 'bg-[var(--dg-bg-tertiary)] text-[var(--dg-text-secondary)] hover:bg-[var(--dg-bg-hover)]'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{action || '全部'}
|
{action || '全部'}
|
||||||
@@ -97,36 +97,36 @@ export default function AuditLogsPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Table */}
|
{/* Table */}
|
||||||
<div className="bg-white rounded-lg shadow-sm overflow-hidden">
|
<div className="dg-card rounded-lg overflow-hidden">
|
||||||
<table className="w-full text-sm">
|
<table className="w-full text-sm">
|
||||||
<thead>
|
<thead>
|
||||||
<tr className="bg-gray-50 text-gray-600">
|
<tr className="bg-[var(--dg-bg-tertiary)] text-[var(--dg-text-secondary)]">
|
||||||
<th className="px-4 py-3 text-left font-medium">操作</th>
|
<th className="px-4 py-3 text-left font-medium">操作</th>
|
||||||
<th className="px-4 py-3 text-left font-medium">目标</th>
|
<th className="px-4 py-3 text-left font-medium">目标</th>
|
||||||
<th className="px-4 py-3 text-left font-medium">详情</th>
|
<th className="px-4 py-3 text-left font-medium">详情</th>
|
||||||
<th className="px-4 py-3 text-left font-medium">时间</th>
|
<th className="px-4 py-3 text-left font-medium">时间</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="divide-y divide-gray-100">
|
<tbody className="divide-y divide-[var(--dg-border)]">
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<tr><td colSpan={4} className="px-4 py-8 text-center text-gray-400">加载中...</td></tr>
|
<tr><td colSpan={4} className="px-4 py-8 text-center text-[var(--dg-text-muted)]">加载中...</td></tr>
|
||||||
) : logs.length === 0 ? (
|
) : logs.length === 0 ? (
|
||||||
<tr><td colSpan={4} className="px-4 py-8 text-center text-gray-400">暂无审计日志</td></tr>
|
<tr><td colSpan={4} className="px-4 py-8 text-center text-[var(--dg-text-muted)]">暂无审计日志</td></tr>
|
||||||
) : (
|
) : (
|
||||||
logs.map(log => (
|
logs.map(log => (
|
||||||
<tr key={log.id} className="hover:bg-gray-50 transition-colors">
|
<tr key={log.id} className="hover:bg-[var(--dg-bg-hover)] transition-colors">
|
||||||
<td className="px-4 py-3">
|
<td className="px-4 py-3">
|
||||||
<span className={`inline-block px-2 py-0.5 rounded text-xs font-medium ${ACTION_COLORS[log.action] || 'bg-gray-100 text-gray-600'}`}>
|
<span className={`inline-block px-2 py-0.5 rounded text-xs font-medium ${ACTION_COLORS[log.action] || 'bg-[var(--dg-bg-tertiary)] text-[var(--dg-text-secondary)]'}`}>
|
||||||
{log.action}
|
{log.action}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-3">
|
<td className="px-4 py-3">
|
||||||
<span className="mr-1">{TARGET_ICONS[log.target_type] || '📌'}</span>
|
<span className="mr-1">{TARGET_ICONS[log.target_type] || '📌'}</span>
|
||||||
<span className="text-gray-600">{log.target_type}</span>
|
<span className="text-[var(--dg-text-secondary)]">{log.target_type}</span>
|
||||||
{log.target_id && <span className="text-gray-400 ml-1">#{log.target_id}</span>}
|
{log.target_id && <span className="text-[var(--dg-text-muted)] ml-1">#{log.target_id}</span>}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-3 text-gray-500 max-w-md truncate">{log.detail || '-'}</td>
|
<td className="px-4 py-3 text-[var(--dg-text-muted)] max-w-md truncate">{log.detail || '-'}</td>
|
||||||
<td className="px-4 py-3 text-gray-400 whitespace-nowrap">{formatDate(log.created_at)}</td>
|
<td className="px-4 py-3 text-[var(--dg-text-muted)] whitespace-nowrap">{formatDate(log.created_at)}</td>
|
||||||
</tr>
|
</tr>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
@@ -140,15 +140,15 @@ export default function AuditLogsPage() {
|
|||||||
<button
|
<button
|
||||||
onClick={() => setPage(p => Math.max(1, p - 1))}
|
onClick={() => setPage(p => Math.max(1, p - 1))}
|
||||||
disabled={page <= 1}
|
disabled={page <= 1}
|
||||||
className="px-3 py-1 rounded bg-gray-100 text-gray-600 disabled:opacity-50"
|
className="px-3 py-1 rounded bg-[var(--dg-bg-tertiary)] text-[var(--dg-text-secondary)] disabled:opacity-50"
|
||||||
>
|
>
|
||||||
上一页
|
上一页
|
||||||
</button>
|
</button>
|
||||||
<span className="px-3 py-1 text-gray-500">{page} / {totalPages}</span>
|
<span className="px-3 py-1 text-[var(--dg-text-muted)]">{page} / {totalPages}</span>
|
||||||
<button
|
<button
|
||||||
onClick={() => setPage(p => Math.min(totalPages, p + 1))}
|
onClick={() => setPage(p => Math.min(totalPages, p + 1))}
|
||||||
disabled={page >= totalPages}
|
disabled={page >= totalPages}
|
||||||
className="px-3 py-1 rounded bg-gray-100 text-gray-600 disabled:opacity-50"
|
className="px-3 py-1 rounded bg-[var(--dg-bg-tertiary)] text-[var(--dg-text-secondary)] disabled:opacity-50"
|
||||||
>
|
>
|
||||||
下一页
|
下一页
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -6,25 +6,13 @@ import { instanceApi } from '@/api/instance';
|
|||||||
import { userApi } from '@/api/user';
|
import { userApi } from '@/api/user';
|
||||||
import { useActionPermission } from '@/hooks/useAuth';
|
import { useActionPermission } from '@/hooks/useAuth';
|
||||||
|
|
||||||
// 权限预设
|
// 权限项 — 与后端 PERMISSION_ACTIONS 保持一致
|
||||||
var PERMISSION_CATEGORIES = [
|
var PERMISSION_CATEGORIES = [
|
||||||
{
|
{
|
||||||
label: '查询权限',
|
label: '查询权限',
|
||||||
items: [
|
items: [
|
||||||
{ code: 'query:select', name: 'SELECT 查询' },
|
{ code: 'query:select', name: 'SELECT 查询' },
|
||||||
{ code: 'query:insert', name: 'INSERT 插入' },
|
{ code: 'query:write', name: '写入操作 (INSERT/UPDATE/DELETE)' },
|
||||||
{ code: 'query:update', name: 'UPDATE 更新' },
|
|
||||||
{ code: 'query:delete', name: 'DELETE 删除' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'DDL 权限',
|
|
||||||
items: [
|
|
||||||
{ code: 'ddl:create_table', name: '创建表' },
|
|
||||||
{ code: 'ddl:alter_table', name: '修改表' },
|
|
||||||
{ code: 'ddl:drop_table', name: '删除表' },
|
|
||||||
{ code: 'ddl:create_index', name: '创建索引' },
|
|
||||||
{ code: 'ddl:drop_index', name: '删除索引' },
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -32,23 +20,21 @@ var PERMISSION_CATEGORIES = [
|
|||||||
items: [
|
items: [
|
||||||
{ code: 'ticket:create', name: '创建工单' },
|
{ code: 'ticket:create', name: '创建工单' },
|
||||||
{ code: 'ticket:approve', name: '审批工单' },
|
{ code: 'ticket:approve', name: '审批工单' },
|
||||||
{ code: 'ticket:reject', name: '拒绝工单' },
|
|
||||||
{ code: 'ticket:execute', name: '执行工单' },
|
{ code: 'ticket:execute', name: '执行工单' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '数据操作',
|
label: 'DDL 权限',
|
||||||
items: [
|
items: [
|
||||||
{ code: 'export:data', name: '导出数据' },
|
{ code: 'ddl:execute', name: 'DDL 执行' },
|
||||||
{ code: 'import:data', name: '导入数据' },
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '管理权限',
|
label: '运维权限',
|
||||||
items: [
|
items: [
|
||||||
{ code: 'instance:connect', name: '连接实例' },
|
{ code: 'slowlog:view', name: '查看慢日志' },
|
||||||
{ code: 'instance:view_slow_query', name: '查看慢查询' },
|
{ code: 'backup:manage', name: '备份管理' },
|
||||||
{ code: 'instance:kill_process', name: '终止进程' },
|
{ code: 'instance:detail', name: '实例详情' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
Reference in new issue
Block a user