library; import 'package:flutter/material.dart'; import '../../../constants/app_constants.dart'; class ServerInfoDialog { static Future show(BuildContext context, {Map? data}) { final server = data?['server'] as Map?; final network = data?['network'] as Map?; final timestamp = data?['timestamp'] as Map?; final load = server?['load'] as Map?; final latency = network?['latency'] as List?; final serverResponseTime = network?['server_response_time']; return showDialog( context: context, builder: (BuildContext context) { return Dialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), child: Container( constraints: const BoxConstraints(maxWidth: 340), child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: AppConstants.primaryColor, borderRadius: const BorderRadius.vertical( top: Radius.circular(16), ), ), child: Row( children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(8), ), child: const Icon( Icons.cloud_outlined, color: Colors.white, size: 20, ), ), const SizedBox(width: 12), const Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '广州 server-ls', style: TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold, ), ), SizedBox(height: 2), Text( '服务器信息', style: TextStyle( color: Colors.white70, fontSize: 12, ), ), ], ), ), ], ), ), Padding( padding: const EdgeInsets.all(20), child: Column( children: [ _buildInfoCard( icon: Icons.schedule, iconColor: const Color(0xFF007AFF), title: '服务器时间', content: timestamp?['datetime'] ?? '--', ), const SizedBox(height: 12), _buildInfoCard( icon: Icons.speed, iconColor: const Color(0xFF34C759), title: '服务器负载', content: '1分钟: ${_formatLoad(load?['1min'])}\n5分钟: ${_formatLoad(load?['5min'])}\n15分钟: ${_formatLoad(load?['15min'])}', ), const SizedBox(height: 12), _buildInfoCard( icon: Icons.bolt, iconColor: const Color(0xFFFF9500), title: '服务器响应', content: '${serverResponseTime ?? '--'} ms', trailing: _buildResponseTimeIndicator( serverResponseTime, ), ), if (latency != null && latency.isNotEmpty) ...[ const SizedBox(height: 16), Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: const Color(0xFFF2F2F7), borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.public, size: 16, color: Colors.grey[600], ), const SizedBox(width: 8), Text( '网络延迟', style: TextStyle( fontWeight: FontWeight.w600, fontSize: 14, color: Colors.grey[700], ), ), ], ), const SizedBox(height: 12), ...latency.map((item) { final host = item['host'] as String?; final ip = item['ip'] as String?; final lat = item['latency']; final status = item['status'] as String?; final isOnline = status == 'online'; return Padding( padding: const EdgeInsets.only(bottom: 8), child: Row( children: [ Container( width: 8, height: 8, decoration: BoxDecoration( color: isOnline ? const Color(0xFF34C759) : const Color(0xFFFF3B30), shape: BoxShape.circle, ), ), const SizedBox(width: 8), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( host ?? '--', style: const TextStyle( fontSize: 13, fontWeight: FontWeight.w500, ), ), Text( ip ?? '--', style: TextStyle( fontSize: 11, color: Colors.grey[500], ), ), ], ), ), Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 4, ), decoration: BoxDecoration( color: isOnline ? const Color( 0xFF34C759, ).withValues(alpha: 0.1) : const Color( 0xFFFF3B30, ).withValues(alpha: 0.1), borderRadius: BorderRadius.circular( 8, ), ), child: Text( isOnline ? '$lat ms' : '离线', style: TextStyle( fontSize: 12, fontWeight: FontWeight.w500, color: isOnline ? const Color(0xFF34C759) : const Color(0xFFFF3B30), ), ), ), ], ), ); }), ], ), ), ], ], ), ), Padding( padding: const EdgeInsets.fromLTRB(20, 0, 20, 20), child: SizedBox( width: double.infinity, child: TextButton( onPressed: () => Navigator.of(context).pop(), style: TextButton.styleFrom( backgroundColor: const Color(0xFFF2F2F7), padding: const EdgeInsets.symmetric(vertical: 14), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), child: const Text( '关闭', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w500, color: Color(0xFF007AFF), ), ), ), ), ), ], ), ), ); }, ); } static Widget _buildInfoCard({ required IconData icon, required Color iconColor, required String title, required String content, Widget? trailing, }) { return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: const Color(0xFFF2F2F7), borderRadius: BorderRadius.circular(12), ), child: Row( children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: iconColor.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(8), ), child: Icon(icon, color: iconColor, size: 18), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: TextStyle(fontSize: 12, color: Colors.grey[600]), ), const SizedBox(height: 2), Text( content, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w500, ), ), ], ), ), if (trailing != null) trailing, ], ), ); } static String _formatLoad(dynamic value) { if (value == null) return '--'; double? loadValue; if (value is num) { loadValue = value.toDouble(); } else if (value is String) { loadValue = double.tryParse(value); } if (loadValue == null) return '--'; final percentage = (loadValue * 100).round(); return '$percentage%'; } static Widget _buildResponseTimeIndicator(dynamic responseTime) { int? time; if (responseTime is int) { time = responseTime; } else if (responseTime is String) { time = int.tryParse(responseTime); } if (time == null) { return const SizedBox.shrink(); } Color color; String label; if (time < 100) { color = const Color(0xFF34C759); label = '极快'; } else if (time < 300) { color = const Color(0xFF34C759); label = '快速'; } else if (time < 500) { color = const Color(0xFFFF9500); label = '正常'; } else { color = const Color(0xFFFF3B30); label = '较慢'; } return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: color.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(8), ), child: Text( label, style: TextStyle( fontSize: 12, fontWeight: FontWeight.w500, color: color, ), ), ); } }