/** * 数据源域纯工具函数:状态/环境映射、列表筛选与健康分计算。 * 用途:供 InstancePage 及 features/datasource/components 下各组件共享,无副作用、不依赖 React。 * 已知限制:健康分为客户端按指标阈值估算的结果,并非后端权威评分。 */ import type { InstanceItem } from './types'; /** 各数据库类型默认端口 */ export const DB_DEFAULT_PORTS: Record = { mysql: 3306, postgres: 5432, redis: 6379, mongo: 27017, }; /** 环境展示名 */ export const envLabel: Record = { production: '生产', staging: '预发', development: '开发', test: '测试', testing: '测试', uat: 'UAT', }; /** 环境徽标配色 */ export const envColor: Record = { production: 'bg-red-500/10 text-red-400 border-red-500/20', staging: 'bg-yellow-500/10 text-yellow-400 border-yellow-500/20', development: 'bg-green-500/10 text-green-400 border-green-500/20', test: 'bg-blue-500/10 text-blue-400 border-blue-500/20', testing: 'bg-blue-500/10 text-blue-400 border-blue-500/20', uat: 'bg-cyan-500/10 text-cyan-400 border-cyan-500/20', }; /** 状态展示信息(在线/离线/异常文案) */ const statusLabel: Record = { connected: { text: '在线', online: true }, online: { text: '在线', online: true }, active: { text: '在线', online: true }, disconnected: { text: '离线', online: false }, offline: { text: '离线', online: false }, error: { text: '异常', online: false }, }; /** 取状态展示信息,未知状态回退「未知」 */ export function getStatusInfo(status: string) { return statusLabel[status] || { text: '未知', online: false }; } /** 是否离线状态 */ export function isOfflineStatus(status: string): boolean { return status === 'offline' || status === 'disconnected'; } /** 状态筛选匹配(online/offline 归并为一类) */ export function matchesStatusFilter(status: string, filterStatus: string): boolean { if (!filterStatus) return true; const info = getStatusInfo(status); if (filterStatus === 'online') return info.online; if (filterStatus === 'offline') return isOfflineStatus(status); return status === filterStatus; } /** 环境筛选匹配(test/testing 归并为一类) */ export function matchesEnvFilter(env: string, filterEnv: string): boolean { if (!filterEnv) return true; if (filterEnv === 'test') return env === 'test' || env === 'testing'; return env === filterEnv; } /** 计算实例健康分(0-100) */ export function calcHealthScore(inst: InstanceItem): number { if (inst.status === 'offline' || inst.status === 'disconnected' || inst.status === 'error') return 0; let score = 100; const cpu = inst.cpu ?? 0; const memory = inst.memory ?? 0; const latency = inst.latency ?? 0; const disk = inst.disk ?? 0; if (cpu > 80) score -= 25; else if (cpu > 60) score -= 10; if (memory > 85) score -= 20; else if (memory > 70) score -= 10; if (latency > 10) score -= 20; else if (latency > 5) score -= 10; if (disk > 80) score -= 15; return Math.max(0, score); } /** 健康分文字配色 */ export function healthColor(score: number): string { if (score >= 90) return 'text-green-400'; if (score >= 70) return 'text-yellow-400'; if (score >= 50) return 'text-orange-400'; return 'text-red-400'; } /** 健康分背景配色 */ export function healthBg(score: number): string { if (score >= 90) return 'bg-green-500/15'; if (score >= 70) return 'bg-yellow-500/15'; if (score >= 50) return 'bg-orange-500/15'; return 'bg-red-500/15'; } /** 健康分档位文案 */ export function healthLabel(score: number): string { if (score >= 90) return '健康'; if (score >= 70) return '良好'; if (score >= 50) return '一般'; return '危险'; } /** 列表筛选:按类型/状态/环境/关键字过滤,与页面原过滤逻辑一致 */ export function filterInstances( instances: InstanceItem[], criteria: { activeType: string; filterStatus: string; filterEnv: string; searchQuery: string }, ): InstanceItem[] { const { activeType, filterStatus, filterEnv, searchQuery } = criteria; return instances.filter(i => { if (activeType !== 'all' && (activeType === 'postgres' ? !['postgres', 'postgresql', 'pg'].includes(i.db_type) : i.db_type !== activeType)) return false; if (!matchesStatusFilter(i.status, filterStatus)) return false; if (!matchesEnvFilter(i.env, filterEnv)) return false; if (searchQuery && !i.name.toLowerCase().includes(searchQuery.toLowerCase()) && !i.host.includes(searchQuery)) return false; return true; }); }