Initial commit: SQL audit platform v0.1.0
FastAPI backend with auth, user, instance, ticket, query, dashboard APIs. React + TypeScript frontend with mock data UI (10 pages). SQLite + async SQLAlchemy, JWT auth, role-based access control. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
commit
439155c92e
290 files changed
+61950
No files matched your search
@@ -0,0 +1,314 @@
|
||||
import type { Ticket, DBInstance, QueryAudit, AuditRule, Workflow, NotificationChannel, Role, User, DataPermission, PermissionNode, DashboardStats } from '@/types';
|
||||
|
||||
export const dashboardStats: DashboardStats = {
|
||||
todayTickets: 128,
|
||||
todayTicketsTrend: 12,
|
||||
pendingApproval: 23,
|
||||
pendingTrend: -5,
|
||||
queryAuditCount: 15234,
|
||||
queryTrend: 8,
|
||||
slowQueries: 47,
|
||||
slowQueryTrend: -12,
|
||||
};
|
||||
|
||||
export const menuSections = [
|
||||
{ id: 'overview', label: '概览' },
|
||||
{ id: 'datasource', label: '数据源' },
|
||||
{ id: 'ticket', label: '工单管理' },
|
||||
{ id: 'permission', label: '权限管理' },
|
||||
{ id: 'system', label: '系统配置' },
|
||||
{ id: 'config', label: '配置平台' },
|
||||
];
|
||||
|
||||
export const menuItems = [
|
||||
{ id: 'dashboard', label: '仪表盘', icon: 'LayoutDashboard', section: 'overview', roles: ['admin', 'dba', 'developer', 'guest'] },
|
||||
{ id: 'mysql', label: 'MySQL', icon: 'Database', section: 'datasource', roles: ['admin', 'dba'] },
|
||||
{ id: 'postgres', label: 'PostgreSQL', icon: 'Server', section: 'datasource', roles: ['admin', 'dba'] },
|
||||
{ id: 'redis', label: 'Redis', icon: 'Zap', section: 'datasource', roles: ['admin', 'dba'] },
|
||||
{ id: 'mongo', label: 'MongoDB', icon: 'Leaf', section: 'datasource', roles: ['admin', 'dba'] },
|
||||
{ id: 'tickets', label: '数据变更', icon: 'ClipboardList', section: 'ticket', roles: ['admin', 'dba', 'developer'] },
|
||||
{ id: 'queries', label: '查询审计', icon: 'Search', section: 'ticket', roles: ['admin', 'dba', 'developer', 'guest'] },
|
||||
{ id: 'roles', label: '角色权限', icon: 'UserCog', section: 'permission', roles: ['admin'] },
|
||||
{ id: 'users', label: '用户管理', icon: 'Users', section: 'permission', roles: ['admin'] },
|
||||
{ id: 'data-permission', label: '数据权限', icon: 'Lock', section: 'permission', roles: ['admin', 'dba'] },
|
||||
{ id: 'audit-rules', label: '审核规则', icon: 'Shield', section: 'system', roles: ['admin', 'dba'] },
|
||||
{ id: 'workflow', label: '审批流程', icon: 'GitBranch', section: 'system', roles: ['admin', 'dba'] },
|
||||
{ id: 'auto-task', label: '自动任务', icon: 'Clock', section: 'system', roles: ['admin'] },
|
||||
{ id: 'announcement', label: '公告管理', icon: 'Megaphone', section: 'system', roles: ['admin'] },
|
||||
{ id: 'config-platform', label: '配置平台', icon: 'Settings', section: 'config', roles: ['admin'] },
|
||||
];
|
||||
|
||||
export const currentUser = {
|
||||
id: 1,
|
||||
username: 'admin',
|
||||
email: 'admin@company.com',
|
||||
role: 'admin' as 'admin' | 'dba' | 'developer' | 'guest',
|
||||
roleName: '超级管理员',
|
||||
avatar: 'A',
|
||||
permissions: menuItems.map(m => m.id),
|
||||
};
|
||||
|
||||
export const dbInstances: DBInstance[] = [
|
||||
{ id: 1, name: '生产主库', host: '192.168.1.10', port: 3306, status: 'online', dbType: 'mysql', version: '8.0.35', env: 'prod', connections: 245, qps: 3250, latency: 2.5, cpu: 45, memory: 68, disk: 72, uptime: '120天', tags: ['主库', '核心'] },
|
||||
{ id: 2, name: '生产从库-01', host: '192.168.1.11', port: 3306, status: 'online', dbType: 'mysql', version: '8.0.35', env: 'prod', connections: 189, qps: 2800, latency: 3.1, cpu: 38, memory: 55, disk: 65, uptime: '120天', tags: ['从库'] },
|
||||
{ id: 3, name: '生产从库-02', host: '192.168.1.12', port: 3306, status: 'online', dbType: 'mysql', version: '8.0.35', env: 'prod', connections: 192, qps: 2750, latency: 2.8, cpu: 40, memory: 58, disk: 68, uptime: '120天', tags: ['从库'] },
|
||||
{ id: 4, name: '测试库', host: '192.168.2.10', port: 3306, status: 'warning', dbType: 'mysql', version: '8.0.33', env: 'test', connections: 45, qps: 120, latency: 15.2, cpu: 82, memory: 90, disk: 45, uptime: '30天', tags: ['测试'] },
|
||||
{ id: 5, name: '开发库', host: '192.168.3.10', port: 3306, status: 'online', dbType: 'mysql', version: '8.0.33', env: 'dev', connections: 23, qps: 80, latency: 1.2, cpu: 15, memory: 30, disk: 25, uptime: '15天', tags: ['开发'] },
|
||||
{ id: 6, name: '归档库', host: '192.168.1.50', port: 3306, status: 'offline', dbType: 'mysql', version: '8.0.30', env: 'prod', connections: 0, qps: 0, latency: 0, cpu: 0, memory: 0, disk: 88, uptime: '-', tags: ['归档'] },
|
||||
{ id: 7, name: 'PG 主库', host: '192.168.1.20', port: 5432, status: 'online', dbType: 'postgres', version: '15.4', env: 'prod', connections: 156, qps: 2100, latency: 1.8, cpu: 35, memory: 60, disk: 55, uptime: '200天', tags: ['主库'] },
|
||||
{ id: 8, name: 'PG 分析库', host: '192.168.1.21', port: 5432, status: 'warning', dbType: 'postgres', version: '15.4', env: 'prod', connections: 89, qps: 980, latency: 8.5, cpu: 78, memory: 85, disk: 70, uptime: '200天', tags: ['分析'] },
|
||||
{ id: 9, name: 'Redis 集群-01', host: '192.168.1.30', port: 6379, status: 'online', dbType: 'redis', version: '7.2.3', env: 'prod', connections: 1200, qps: 45000, latency: 0.5, cpu: 25, memory: 75, disk: 10, uptime: '90天', tags: ['集群'] },
|
||||
{ id: 10, name: 'Redis 集群-02', host: '192.168.1.31', port: 6379, status: 'online', dbType: 'redis', version: '7.2.3', env: 'prod', connections: 1150, qps: 42000, latency: 0.6, cpu: 28, memory: 72, disk: 10, uptime: '90天', tags: ['集群'] },
|
||||
{ id: 11, name: 'MongoDB 分片-01', host: '192.168.1.40', port: 27017, status: 'online', dbType: 'mongo', version: '7.0.4', env: 'prod', connections: 340, qps: 1800, latency: 3.2, cpu: 42, memory: 65, disk: 60, uptime: '60天', tags: ['分片'] },
|
||||
];
|
||||
|
||||
export const tickets: Ticket[] = [
|
||||
{
|
||||
id: 'TK-20240115-001', title: '更新用户状态字段', dbType: 'mysql', instance: '生产主库', applicant: '张三', status: 'pending', priority: 'high',
|
||||
sql: 'UPDATE users SET status = \'active\', updated_at = NOW() WHERE id IN (1001, 1002, 1003) AND status != \'active\';',
|
||||
rollbackSql: "-- 基于 Binlog ROW 格式逆向生成的回滚语句\n-- 使用主键精确定位恢复旧值\nUPDATE users SET status = 'inactive', updated_at = NOW() WHERE id IN (1001, 1002, 1003);\n\n-- 备选:从备份库恢复\n-- UPDATE users u JOIN $_$Inception_backup_information$_$ b ON u.id = b.pk_value\n-- SET u.status = b.old_status WHERE b.opid_time = '20240115093025';",
|
||||
reason: '批量激活过期用户账号', createTime: '2024-01-15 09:30:00', updateTime: '2024-01-15 09:30:00',
|
||||
auditScore: 92, auditResults: [
|
||||
{ rule: '禁止无 WHERE 条件的 UPDATE/DELETE', level: 'success', description: 'WHERE 条件存在,符合规范' },
|
||||
{ rule: '大表变更警告', level: 'warning', description: '目标表 users 数据量超过 100 万行', suggestion: '建议分批执行,每次不超过 1000 条' },
|
||||
{ rule: 'SQL 语法检查', level: 'success', description: '语法正确' },
|
||||
],
|
||||
workflowSteps: [
|
||||
{ name: '提交', status: 'completed', time: '09:30', assignee: '张三' },
|
||||
{ name: '一级审批', status: 'completed', time: '10:15', assignee: '李四' },
|
||||
{ name: '二级审批', status: 'active', assignee: '王五' },
|
||||
{ name: '执行', status: 'pending' },
|
||||
],
|
||||
approvalRecords: [
|
||||
{ step: 1, approver: '张三', action: 'approve', comment: '提交工单', time: '2024-01-15 09:30:25' },
|
||||
{ step: 2, approver: '李四', action: 'approve', comment: 'SQL 符合规范,影响范围可控,同意执行', time: '2024-01-15 10:15:38' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'TK-20240115-002', title: '清理过期日志数据', dbType: 'postgres', instance: '日志库', applicant: '李四', status: 'reviewing', priority: 'medium',
|
||||
sql: 'DELETE FROM system_logs WHERE created_at < DATE_TRUNC(\'month\', NOW() - INTERVAL \'3 months\');',
|
||||
rollbackSql: '-- DDL 回滚支持有限,建议先备份再执行\n-- 已从备份库 system_logs_bak 恢复数据\n-- INSERT INTO system_logs SELECT * FROM system_logs_bak WHERE created_at < DATE_TRUNC(\'month\', NOW() - INTERVAL \'3 months\');',
|
||||
reason: '清理3个月前的系统日志,释放磁盘空间', createTime: '2024-01-15 10:15:00', updateTime: '2024-01-15 10:15:00',
|
||||
auditScore: 85, auditResults: [
|
||||
{ rule: 'DELETE 操作检查', level: 'warning', description: 'DELETE 操作影响行数可能较大', suggestion: '建议先 SELECT COUNT(*) 确认影响范围' },
|
||||
{ rule: '备份检查', level: 'success', description: '已确认数据已备份' },
|
||||
],
|
||||
workflowSteps: [
|
||||
{ name: '提交', status: 'completed', time: '10:15', assignee: '李四' },
|
||||
{ name: '一级审批', status: 'active', assignee: '张三' },
|
||||
{ name: '执行', status: 'pending' },
|
||||
],
|
||||
approvalRecords: [
|
||||
{ step: 1, approver: '李四', action: 'approve', comment: '提交工单', time: '2024-01-15 10:15:00' },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'TK-20240115-003', title: 'Redis 缓存预热', dbType: 'redis', instance: 'Redis集群', applicant: '王五', status: 'pending', priority: 'low',
|
||||
sql: 'MSET user:1001:profile \'{"name":"张三","level":5}\' user:1002:profile \'{"name":"李四","level":3}\'',
|
||||
reason: '大促前预热用户缓存数据', createTime: '2024-01-15 11:00:00', updateTime: '2024-01-15 11:00:00',
|
||||
auditScore: 98, auditResults: [
|
||||
{ rule: 'Redis 命令检查', level: 'success', description: 'MSET 命令安全' },
|
||||
{ rule: '数据大小检查', level: 'success', description: '单条数据小于 1MB' },
|
||||
],
|
||||
},
|
||||
{ id: 'TK-20240114-005', title: '用户表添加索引', dbType: 'mysql', instance: '生产主库', applicant: '赵六', status: 'approved', priority: 'high', sql: 'ALTER TABLE users ADD INDEX idx_phone (phone);', reason: '优化手机号查询性能', createTime: '2024-01-14 14:20:00', updateTime: '2024-01-14 16:30:00' },
|
||||
{ id: 'TK-20240114-006', title: '订单数据归档', dbType: 'mysql', instance: '归档库', applicant: '钱七', status: 'executing', priority: 'medium', sql: 'INSERT INTO orders_archive SELECT * FROM orders WHERE created_at < "2023-06-01";', rollbackSql: '-- 从归档表删除已归档的数据\nDELETE FROM orders_archive WHERE created_at < "2023-06-01";', reason: '归档半年前的订单数据', createTime: '2024-01-14 15:30:00', updateTime: '2024-01-15 09:00:00' },
|
||||
{ id: 'TK-20240114-007', title: '配置表更新', dbType: 'redis', instance: 'Redis集群', applicant: '孙八', status: 'success', priority: 'low', sql: 'HSET app:config feature_flag new_feature enabled', reason: '开启新功能开关', createTime: '2024-01-14 16:00:00', updateTime: '2024-01-14 16:05:00' },
|
||||
{ id: 'TK-20240114-008', title: '订单表索引优化', dbType: 'mysql', instance: '生产主库', applicant: '周九', status: 'failed', priority: 'high', sql: 'ALTER TABLE orders ADD INDEX idx_created_at (created_at, status);', reason: '优化订单查询', createTime: '2024-01-14 16:45:00', updateTime: '2024-01-14 17:00:00' },
|
||||
{ id: 'TK-20240113-001', title: '用户权限调整', dbType: 'postgres', instance: '权限库', applicant: '吴十', status: 'rejected', priority: 'medium', sql: 'UPDATE user_roles SET role = \'admin\' WHERE user_id = 456;', reason: '调整用户权限', createTime: '2024-01-13 09:00:00', updateTime: '2024-01-13 11:30:00' },
|
||||
];
|
||||
|
||||
export const queryAudits: QueryAudit[] = [
|
||||
{ id: 'Q-20240115-001', sql: 'SELECT u.id, u.name, u.email, u.phone, u.status, u.created_at FROM users u WHERE u.status = "active" ORDER BY u.created_at DESC LIMIT 100', sqlPreview: 'SELECT u.id, u.name, u.email...', dbType: 'mysql', instance: '生产主库', user: '张三', executeTime: 125, rowCount: 100, scanRows: 50000, affectedRows: 0, status: 'success', hasSensitive: true, timestamp: '2024-01-15 10:30:25', clientIp: '192.168.10.50', source: 'Web Console', resultColumns: [{ prop: 'id', label: 'ID' }, { prop: 'name', label: '姓名' }, { prop: 'email', label: '邮箱', sensitive: true }, { prop: 'phone', label: '电话', sensitive: true }, { prop: 'status', label: '状态' }, { prop: 'created_at', label: '创建时间' }], resultSet: [{ id: 1001, name: '张三', email: 'zhang***@email.com', phone: '138****8888', status: 'active', created_at: '2024-01-15' }, { id: 1002, name: '李四', email: 'li***@email.com', phone: '139****9999', status: 'active', created_at: '2024-01-14' }, { id: 1003, name: '王五', email: 'wang***@email.com', phone: '137****7777', status: 'active', created_at: '2024-01-13' }] },
|
||||
{ id: 'Q-20240115-002', sql: 'SELECT COUNT(*) as total, DATE(created_at) as date FROM orders WHERE created_at > "2024-01-01" GROUP BY DATE(created_at)', sqlPreview: 'SELECT COUNT(*) as total...', dbType: 'mysql', instance: '生产主库', user: '李四', executeTime: 2500, rowCount: 15, scanRows: 1000000, affectedRows: 0, status: 'slow', hasSensitive: false, timestamp: '2024-01-15 10:28:15', clientIp: '192.168.10.51', source: 'API' },
|
||||
{ id: 'Q-20240115-003', sql: 'UPDATE users SET last_login = NOW(), login_ip = "192.168.10.50" WHERE id = 123', sqlPreview: 'UPDATE users SET...', dbType: 'mysql', instance: '生产主库', user: '系统', executeTime: 45, rowCount: 0, scanRows: 1, affectedRows: 1, status: 'success', hasSensitive: false, timestamp: '2024-01-15 10:25:08', clientIp: '192.168.1.100', source: 'Application' },
|
||||
{ id: 'Q-20240115-004', sql: 'SELECT * FROM user_profiles WHERE user_id = 456', sqlPreview: 'SELECT * FROM user_profiles...', dbType: 'postgres', instance: 'PG 分析库', user: '赵六', executeTime: 89, rowCount: 5, scanRows: 100, affectedRows: 0, status: 'success', hasSensitive: true, timestamp: '2024-01-15 10:20:33', clientIp: '192.168.10.52', source: 'Web Console', resultColumns: [{ prop: 'user_id', label: '用户ID' }, { prop: 'id_card', label: '身份证号', sensitive: true }, { prop: 'address', label: '地址', sensitive: true }], resultSet: [{ user_id: 456, id_card: '310***********1234', address: '上海市***区***路***号' }] },
|
||||
{ id: 'Q-20240115-005', sql: 'DELETE FROM temp_logs WHERE created_at < "2024-01-01"', sqlPreview: 'DELETE FROM temp_logs...', dbType: 'mysql', instance: '测试库', user: '钱七', executeTime: 5000, rowCount: 0, scanRows: 500000, affectedRows: 0, status: 'failed', hasSensitive: false, timestamp: '2024-01-15 10:15:42', clientIp: '192.168.10.53', source: 'CLI' },
|
||||
{ id: 'Q-20240115-006', sql: 'GET user:session:123', sqlPreview: 'GET user:session:123', dbType: 'redis', instance: 'Redis集群-01', user: '孙八', executeTime: 2, rowCount: 1, scanRows: 1, affectedRows: 0, status: 'success', hasSensitive: false, timestamp: '2024-01-15 10:10:18', clientIp: '192.168.10.54', source: 'Application' },
|
||||
{ id: 'Q-20240115-007', sql: 'SELECT o.id, o.order_no, u.name, o.amount, o.status, o.created_at FROM orders o JOIN users u ON o.user_id = u.id WHERE o.created_at > DATE_SUB(NOW(), INTERVAL 7 DAY) ORDER BY o.created_at DESC LIMIT 50', sqlPreview: 'SELECT o.id, o.order_no, u.name...', dbType: 'mysql', instance: '生产主库', user: '周九', executeTime: 3200, rowCount: 50, scanRows: 800000, affectedRows: 0, status: 'slow', hasSensitive: true, timestamp: '2024-01-15 10:05:22', clientIp: '192.168.10.55', source: 'Web Console', resultColumns: [{ prop: 'id', label: 'ID' }, { prop: 'order_no', label: '订单号' }, { prop: 'name', label: '用户名' }, { prop: 'amount', label: '金额' }, { prop: 'status', label: '状态' }], resultSet: [{ id: 50001, order_no: 'ORD-20240115-001', name: '张三', amount: '¥1,299.00', status: '已支付' }, { id: 50002, order_no: 'ORD-20240115-002', name: '李四', amount: '¥2,599.00', status: '待发货' }] },
|
||||
{ id: 'Q-20240115-008', sql: 'db.collection("logs").find({ created_at: { $gte: new Date("2024-01-01") } }).limit(100)', sqlPreview: 'db.collection("logs").find...', dbType: 'mongo', instance: 'MongoDB 分片-01', user: '吴十', executeTime: 156, rowCount: 100, scanRows: 50000, affectedRows: 0, status: 'success', hasSensitive: false, timestamp: '2024-01-15 09:55:10', clientIp: '192.168.10.56', source: 'DataGrip' },
|
||||
];
|
||||
|
||||
export const auditRules: AuditRule[] = [
|
||||
{ id: 'R000', name: '表必须有主键(回滚依赖)', level: 'error', dbTypes: ['mysql'], description: '操作的表必须包含主键,否则无法生成精确的回滚语句。回滚依赖主键定位修改的行。', enabled: true, category: '回滚' },
|
||||
{ id: 'R001', name: '禁止无 WHERE 条件的 UPDATE/DELETE', level: 'error', dbTypes: ['mysql', 'postgres'], description: 'UPDATE 和 DELETE 语句必须包含 WHERE 条件,防止误操作全表数据', enabled: true, category: '安全性' },
|
||||
{ id: 'R002', name: '禁止 SELECT * 查询', level: 'warning', dbTypes: ['mysql', 'postgres'], description: 'SELECT 语句应明确指定字段名,避免不必要的数据传输', enabled: true, category: '性能' },
|
||||
{ id: 'R003', name: '大表变更警告(>100万行)', level: 'warning', dbTypes: ['mysql', 'postgres'], description: '影响超过 100 万行的变更需要额外审批,建议使用 pt-online-schema-change', enabled: true, category: '性能' },
|
||||
{ id: 'R004', name: '禁止 DROP TABLE/DATABASE', level: 'error', dbTypes: ['mysql', 'postgres', 'mongo'], description: '禁止执行 DROP TABLE/DATABASE 操作,防止数据丢失', enabled: true, category: '安全性' },
|
||||
{ id: 'R005', name: 'SQL 注入风险检测', level: 'error', dbTypes: ['mysql', 'postgres', 'redis'], description: '检测潜在的 SQL 注入风险,包括拼接字符串等', enabled: true, category: '安全性' },
|
||||
{ id: 'R006', name: '索引使用检查', level: 'info', dbTypes: ['mysql', 'postgres'], description: '检查查询是否使用了索引,避免全表扫描', enabled: false, category: '性能' },
|
||||
{ id: 'R007', name: '禁止 TRUNCATE TABLE', level: 'error', dbTypes: ['mysql', 'postgres'], description: 'TRUNCATE 操作会清空整表数据且无法回滚', enabled: true, category: '安全性' },
|
||||
{ id: 'R008', name: '字段类型变更警告', level: 'warning', dbTypes: ['mysql', 'postgres'], description: 'ALTER TABLE 修改字段类型可能导致数据截断', enabled: true, category: '数据完整性' },
|
||||
{ id: 'R009', name: '外键约束检查', level: 'info', dbTypes: ['mysql', 'postgres'], description: '建议重要关联表添加外键约束保证数据一致性', enabled: false, category: '数据完整性' },
|
||||
{ id: 'R010', name: 'Redis 大键检测(>1MB)', level: 'warning', dbTypes: ['redis'], description: '检测到 Redis 大键,可能影响性能', enabled: true, category: '性能' },
|
||||
{ id: 'R011', name: 'Binlog ROW 格式检查', level: 'error', dbTypes: ['mysql'], description: 'MySQL 必须开启 Binlog 且格式为 ROW,否则无法生成回滚语句', enabled: true, category: '回滚' },
|
||||
{ id: 'R012', name: '禁止 DML 与 DDL 混合操作', level: 'error', dbTypes: ['mysql'], description: '同一工单中不能同时包含 DML 和 DDL 语句,避免表结构变化导致备份解析出错', enabled: true, category: '回滚' },
|
||||
{ id: 'R013', name: '回滚权限检查', level: 'error', dbTypes: ['mysql'], description: '执行回滚的数据库账号需有 REPLICATION SLAVE 和 REPLICATION CLIENT 权限', enabled: true, category: '回滚' },
|
||||
{ id: 'R014', name: 'DDL 回滚限制警告', level: 'warning', dbTypes: ['mysql'], description: 'DROP/TRUNCATE 等 DDL 操作回滚仅能重建表结构,无法恢复原有数据', enabled: true, category: '回滚' },
|
||||
{ id: 'R015', name: '影响行数限制(<10000)', level: 'warning', dbTypes: ['mysql', 'postgres'], description: '单次操作影响行数建议不超过 10000 行,过大的事务可能导致回滚困难和性能问题', enabled: true, category: '回滚' },
|
||||
];
|
||||
|
||||
export const workflows: Workflow[] = [
|
||||
{ id: 1, name: '生产环境变更流程', dbTypes: ['mysql', 'postgres', 'redis'], steps: 3, mode: 'all', description: '需要 DBA 和架构师双重审批,适用于所有生产环境变更', enabled: true, conditions: ['影响行数>1000', '执行时间>1s'] },
|
||||
{ id: 2, name: '测试环境变更流程', dbTypes: ['mysql', 'postgres', 'redis', 'mongo'], steps: 1, mode: 'any', description: '仅需一级审批,适用于测试环境', enabled: true },
|
||||
{ id: 3, name: '紧急变更流程', dbTypes: ['mysql', 'postgres'], steps: 2, mode: 'any', description: 'P0/P1 故障时的快速审批通道,30分钟内完成', enabled: true, conditions: ['故障等级>P1'] },
|
||||
{ id: 4, name: '数据查询流程', dbTypes: ['mysql', 'postgres'], steps: 1, mode: 'any', description: '敏感数据查询审批,需数据负责人审批', enabled: false },
|
||||
{ id: 5, name: 'DDL 变更流程', dbTypes: ['mysql', 'postgres'], steps: 2, mode: 'all', description: '表结构变更专用流程,需架构师评审', enabled: true, conditions: ['涉及DDL操作'] },
|
||||
];
|
||||
|
||||
export const notificationChannels: NotificationChannel[] = [
|
||||
{ id: 1, name: '飞书', type: 'feishu', icon: 'Send', description: '通过飞书自定义机器人发送通知', enabled: true, webhook: 'https://open.feishu.cn/open-apis/bot/v2/hook/xxx', events: ['ticket_created', 'ticket_approved', 'ticket_rejected', 'ticket_executed', 'ticket_failed'] },
|
||||
{ id: 2, name: '钉钉', type: 'dingtalk', icon: 'Bell', description: '通过钉钉群机器人发送通知', enabled: true, webhook: 'https://oapi.dingtalk.com/robot/send?access_token=xxx', events: ['ticket_created', 'ticket_approved', 'ticket_failed'] },
|
||||
{ id: 3, name: '企业微信', type: 'wechat', icon: 'MessageSquare', description: '通过企业微信Webhook发送通知', enabled: false, webhook: '', events: ['ticket_created', 'ticket_executed'] },
|
||||
{ id: 4, name: 'Telegram', type: 'telegram', icon: 'Navigation', description: '通过 Telegram Bot 发送通知', enabled: false, webhook: '', events: ['ticket_failed'] },
|
||||
{ id: 5, name: '邮件通知', type: 'email', icon: 'Mail', description: '通过 SMTP 邮件发送通知', enabled: true, events: ['ticket_created', 'ticket_approved', 'ticket_rejected', 'ticket_executed'] },
|
||||
];
|
||||
|
||||
export const roles: Role[] = [
|
||||
{ id: 'admin', name: '超级管理员', description: '拥有系统的所有权限,包括用户管理、系统配置等', icon: 'Crown', iconClass: 'text-purple-400 bg-purple-400/10', userCount: 2, permissionCount: 56, permissions: ['dashboard', 'mysql', 'postgres', 'redis', 'mongo', 'tickets', 'queries', 'roles', 'users', 'data-permission', 'audit-rules', 'workflow', 'auto-task', 'announcement', 'config-platform', 'notifications'] },
|
||||
{ id: 'dba', name: '数据库管理员', description: '负责数据库运维、工单审批和 SQL 审核', icon: 'Database', iconClass: 'text-blue-400 bg-blue-400/10', userCount: 5, permissionCount: 32, permissions: ['dashboard', 'mysql', 'postgres', 'redis', 'tickets', 'queries', 'data-permission', 'audit-rules', 'workflow'] },
|
||||
{ id: 'developer', name: '开发人员', description: '可以提交变更工单和执行数据查询', icon: 'Code', iconClass: 'text-green-400 bg-green-400/10', userCount: 28, permissionCount: 12, permissions: ['dashboard', 'tickets', 'queries'] },
|
||||
{ id: 'guest', name: '访客', description: '仅可查看,无法执行任何操作', icon: 'Eye', iconClass: 'text-gray-400 bg-gray-400/10', userCount: 8, permissionCount: 4, permissions: ['dashboard', 'queries'] },
|
||||
];
|
||||
|
||||
export const users: User[] = [
|
||||
{ id: 1, username: 'admin', email: 'admin@company.com', role: 'admin', roleName: '超级管理员', department: '运维部', lastLogin: '2024-01-15 09:30:00', status: 'active', avatar: 'A' },
|
||||
{ id: 2, username: 'zhangsan', email: 'zhangsan@company.com', role: 'dba', roleName: '数据库管理员', department: 'DBA组', lastLogin: '2024-01-15 08:45:00', status: 'active', avatar: '张' },
|
||||
{ id: 3, username: 'lisi', email: 'lisi@company.com', role: 'dba', roleName: '数据库管理员', department: 'DBA组', lastLogin: '2024-01-14 18:20:00', status: 'active', avatar: '李' },
|
||||
{ id: 4, username: 'wangwu', email: 'wangwu@company.com', role: 'developer', roleName: '开发人员', department: '研发部', lastLogin: '2024-01-15 10:15:00', status: 'active', avatar: '王' },
|
||||
{ id: 5, username: 'zhaoliu', email: 'zhaoliu@company.com', role: 'developer', roleName: '开发人员', department: '研发部', lastLogin: '2024-01-14 16:30:00', status: 'disabled', avatar: '赵' },
|
||||
{ id: 6, username: 'qianqi', email: 'qianqi@company.com', role: 'developer', roleName: '开发人员', department: '产品部', lastLogin: '2024-01-14 14:20:00', status: 'active', avatar: '钱' },
|
||||
{ id: 7, username: 'sunba', email: 'sunba@company.com', role: 'guest', roleName: '访客', department: '测试部', lastLogin: '2024-01-13 11:00:00', status: 'active', avatar: '孙' },
|
||||
];
|
||||
|
||||
export const dataPermissions: DataPermission[] = [
|
||||
{ id: 1, user: 'zhangsan', instance: '生产主库 (MySQL)', database: 'user_db', table: 'users', columns: '*', rowFilter: '', operations: ['SELECT', 'INSERT', 'UPDATE'] },
|
||||
{ id: 2, user: 'lisi', instance: '生产主库 (MySQL)', database: 'order_db', table: 'orders', columns: 'id,order_no,amount,status,created_at', rowFilter: 'created_at > DATE_SUB(NOW(), INTERVAL 30 DAY)', operations: ['SELECT'] },
|
||||
{ id: 3, user: 'wangwu', instance: '测试库 (MySQL)', database: 'test_db', table: '*', columns: '*', rowFilter: '', operations: ['SELECT', 'INSERT', 'UPDATE', 'DELETE'] },
|
||||
{ id: 4, user: 'zhangsan', instance: 'PG 主库', database: 'analytics', table: 'user_behavior', columns: 'user_id,event_type,page_url,timestamp', rowFilter: '', operations: ['SELECT'] },
|
||||
{ id: 5, user: 'admin', instance: 'Redis集群-01', database: '0', table: '*', columns: '*', rowFilter: '', operations: ['GET', 'SET', 'DEL', 'EXPIRE'] },
|
||||
];
|
||||
|
||||
export const permissionTreeData: PermissionNode[] = [
|
||||
{ id: 'dashboard', label: '仪表盘(查看统计、图表)' },
|
||||
{ id: 'datasource', label: '数据源管理', children: [
|
||||
{ id: 'mysql', label: 'MySQL 实例(查看、添加、编辑、删除)' },
|
||||
{ id: 'postgres', label: 'PostgreSQL 实例(查看、添加、编辑、删除)' },
|
||||
{ id: 'redis', label: 'Redis 实例(查看、添加、编辑、删除)' },
|
||||
{ id: 'mongo', label: 'MongoDB 实例(查看、添加、编辑、删除)' },
|
||||
]},
|
||||
{ id: 'tickets', label: '数据变更工单(创建、查看、审批、执行)', children: [
|
||||
{ id: 'ticket_create', label: '创建工单' },
|
||||
{ id: 'ticket_approve', label: '审批工单' },
|
||||
{ id: 'ticket_execute', label: '执行工单' },
|
||||
{ id: 'ticket_rollback', label: '回滚工单' },
|
||||
]},
|
||||
{ id: 'queries', label: '查询审计(查看日志、新建查询、导出)', children: [
|
||||
{ id: 'query_create', label: '执行查询' },
|
||||
{ id: 'query_export', label: '导出结果' },
|
||||
{ id: 'query_view_all', label: '查看全部用户查询' },
|
||||
]},
|
||||
{ id: 'permission', label: '权限管理', children: [
|
||||
{ id: 'roles', label: '角色权限(创建、编辑、分配权限)' },
|
||||
{ id: 'users', label: '用户管理(创建、编辑、禁用)' },
|
||||
{ id: 'data-permission', label: '数据权限(配置表级、字段级、行级权限)' },
|
||||
]},
|
||||
{ id: 'system', label: '系统配置', children: [
|
||||
{ id: 'audit-rules', label: '审核规则(启用/禁用、添加规则)' },
|
||||
{ id: 'workflow', label: '审批流程(创建、编辑流程模板)' },
|
||||
{ id: 'auto-task', label: '自动任务' },
|
||||
{ id: 'announcement', label: '公告管理' },
|
||||
]},
|
||||
{ id: 'config', label: '配置平台', children: [
|
||||
{ id: 'config-platform', label: '全局配置(消息推送/LDAP/查询限制/工单规则)' },
|
||||
{ id: 'notifications', label: '通知渠道(配置 Webhook、测试)' },
|
||||
]},
|
||||
];
|
||||
|
||||
export const statusMap: Record<string, string> = {
|
||||
pending: '待审批',
|
||||
reviewing: '审批中',
|
||||
approved: '已通过',
|
||||
rejected: '已拒绝',
|
||||
executing: '执行中',
|
||||
success: '执行成功',
|
||||
failed: '执行失败',
|
||||
rollback: '已回滚',
|
||||
};
|
||||
|
||||
export const statusColorMap: Record<string, string> = {
|
||||
pending: 'bg-yellow-500/15 text-yellow-500',
|
||||
reviewing: 'bg-blue-500/15 text-blue-400',
|
||||
approved: 'bg-green-500/15 text-green-400',
|
||||
rejected: 'bg-red-500/15 text-red-400',
|
||||
executing: 'bg-purple-500/15 text-purple-400',
|
||||
success: 'bg-green-500/15 text-green-400',
|
||||
failed: 'bg-red-500/15 text-red-400',
|
||||
rollback: 'bg-orange-500/15 text-orange-400',
|
||||
};
|
||||
|
||||
export const dbTypeColorMap: Record<string, string> = {
|
||||
mysql: 'bg-[rgba(0,117,143,0.15)] text-[#26a69a]',
|
||||
postgres: 'bg-[rgba(51,103,145,0.15)] text-[#42a5f5]',
|
||||
redis: 'bg-[rgba(220,50,32,0.15)] text-[#ef5350]',
|
||||
mongo: 'bg-[rgba(71,162,72,0.15)] text-[#66bb6a]',
|
||||
};
|
||||
|
||||
export interface Announcement {
|
||||
id: string;
|
||||
title: string;
|
||||
content: string;
|
||||
priority: 'urgent' | 'high' | 'normal' | 'low';
|
||||
pinned: boolean;
|
||||
enabled: boolean;
|
||||
author: string;
|
||||
publishTime: string;
|
||||
expireTime: string;
|
||||
readCount: number;
|
||||
targetRoles: string[];
|
||||
}
|
||||
|
||||
export const announcements: Announcement[] = [
|
||||
{
|
||||
id: 'ann-1', title: '【系统维护】本周日凌晨 2:00-4:00 数据库升级维护',
|
||||
content: '计划于本周日(2024年1月21日)凌晨 2:00-4:00 进行数据库版本升级,期间以下服务将不可用:\n1. 数据变更工单提交和审批\n2. 在线 SQL 查询\n3. 数据导出功能\n\n请提前安排工作,避免在维护时段提交重要工单。如有紧急情况,请联系 DBA 团队。',
|
||||
priority: 'urgent', pinned: true, enabled: true, author: 'admin',
|
||||
publishTime: '2024-01-15 10:00:00', expireTime: '2024-01-22 00:00:00',
|
||||
readCount: 156, targetRoles: ['admin', 'dba', 'developer', 'guest'],
|
||||
},
|
||||
{
|
||||
id: 'ann-2', title: '【安全提醒】禁止使用 SELECT * 查询生产数据库',
|
||||
content: '为加强数据安全,即日起严禁使用 SELECT * 查询生产环境数据库。所有查询必须明确指定所需字段名。\n\n审核规则已更新(规则编号 R002),违规查询将被自动拦截并记录审计日志。',
|
||||
priority: 'high', pinned: true, enabled: true, author: 'admin',
|
||||
publishTime: '2024-01-14 09:00:00', expireTime: '2024-02-14 00:00:00',
|
||||
readCount: 234, targetRoles: ['admin', 'dba', 'developer'],
|
||||
},
|
||||
{
|
||||
id: 'ann-3', title: '【新功能】SQL 变更自动回滚功能已上线',
|
||||
content: 'SQL 变更工单现已支持自动回滚功能。对于 UPDATE 和 DELETE 操作,系统会自动:\n1. 基于 Binlog ROW 格式生成逆向回滚语句\n2. 执行前备份受影响数据\n3. 提供一键回滚入口(执行后 72 小时内有效)\n\n使用要求:\n- MySQL 必须开启 Binlog ROW 格式\n- 操作表必须有主键\n- 单次操作影响行数不超过 10,000 行',
|
||||
priority: 'normal', pinned: false, enabled: true, author: 'zhangsan',
|
||||
publishTime: '2024-01-13 14:00:00', expireTime: '2024-04-13 00:00:00',
|
||||
readCount: 89, targetRoles: ['admin', 'dba', 'developer'],
|
||||
},
|
||||
{
|
||||
id: 'ann-4', title: '【培训通知】SQL 审核规范培训 - 1月25日',
|
||||
content: '时间:2024年1月25日 14:00-16:00\n地点:会议室 A\n讲师:DBA 团队负责人\n\n培训内容:\n1. SQL 变更工单提交流程\n2. 审核规则详解\n3. 回滚操作最佳实践\n4. 常见问题排查\n\n请相关人员准时参加。',
|
||||
priority: 'normal', pinned: false, enabled: true, author: 'lisi',
|
||||
publishTime: '2024-01-12 10:00:00', expireTime: '2024-01-26 00:00:00',
|
||||
readCount: 67, targetRoles: ['developer'],
|
||||
},
|
||||
{
|
||||
id: 'ann-sql-1', title: '【规范】SQL 变更工单提交流程',
|
||||
content: '1. 登录 Web-Lite 平台,进入「数据变更」页面\n2. 点击「新建工单」,填写标题和变更原因\n3. 选择目标数据库类型和实例\n4. 在 SQL 编辑器中输入变更语句\n5. 系统自动审核并评分,确认无误后提交\n6. 等待 DBA 审批通过后执行\n\n注意:生产环境变更必须提供回滚 SQL!',
|
||||
priority: 'high', pinned: true, enabled: true, author: 'admin',
|
||||
publishTime: '2024-01-10 08:00:00', expireTime: '2025-12-31 00:00:00',
|
||||
readCount: 512, targetRoles: ['admin', 'dba', 'developer'],
|
||||
},
|
||||
{
|
||||
id: 'ann-sql-2', title: '【注意事项】SQL 操作安全规范',
|
||||
content: '禁止事项:\n- 禁止不带 WHERE 条件的 UPDATE/DELETE\n- 禁止在生产环境执行 DROP/TRUNCATE\n- 禁止在业务高峰期(10:00-12:00, 14:00-16:00)执行大表变更\n\n必须遵守:\n- 所有变更必须通过工单审批\n- 影响超过 10,000 行的变更需额外审批\n- DDL 和 DML 不可混在同一工单中\n- 执行前确认备份和回滚方案',
|
||||
priority: 'urgent', pinned: true, enabled: true, author: 'admin',
|
||||
publishTime: '2024-01-08 08:00:00', expireTime: '2025-12-31 00:00:00',
|
||||
readCount: 689, targetRoles: ['admin', 'dba', 'developer', 'guest'],
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,6 @@
|
||||
import { clsx, type ClassValue } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
Reference in new issue
Block a user