import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:kaer_with_panels/app/widgets/kr_app_text_style.dart'; import '../controllers/kr_statistics_controller.dart'; import 'package:fl_chart/fl_chart.dart'; import 'package:kaer_with_panels/app/localization/app_translations.dart'; import 'package:easy_refresh/easy_refresh.dart'; class KRStatisticsView extends GetView { const KRStatisticsView({super.key}); @override Widget build(BuildContext context) { return Scaffold( extendBodyBehindAppBar: true, backgroundColor: Theme.of(context).primaryColor , appBar: AppBar( backgroundColor: Colors.transparent, elevation: 0, title: Align( alignment: Alignment.centerLeft, child: Text( AppTranslations.kr_statistics.title, style: KrAppTextStyle( color: Theme.of(context).textTheme.bodyMedium?.color, fontSize: 16, fontWeight: FontWeight.w500, ), ), ), ), body: Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Color.fromRGBO(23, 151, 255, 0.15), // 渐变开始颜色 Color.fromRGBO(23, 151, 255, 0.05), // 中间过渡颜色 // 非渐变色区域 ], stops: [0.0, 0.28], // 调整渐变结束位置 ), ), child: EasyRefresh( controller: controller.refreshController, onRefresh: controller.kr_onRefresh, header: DeliveryHeader( triggerOffset: 50.0, springRebound: true, ), child: SingleChildScrollView( padding: EdgeInsets.zero, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // SizedBox(height: kToolbarHeight + 20.w), _kr_buildStatusGrid(context), _kr_buildWeeklyChart(context), _kr_buildConnectionRecords(context), ], ), ), ), ), ); } // 构建状态网格 Widget _kr_buildStatusGrid(BuildContext context) { // 根据平台调整卡片高度比例 - 优化桌面版本高度 final double aspectRatio = GetPlatform.isDesktop ? 165 / 38 : 165 / 82; return Container( padding: EdgeInsets.all(16.r), child: GridView.count( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), crossAxisCount: 2, mainAxisSpacing: 12.h, crossAxisSpacing: 12.w, childAspectRatio: aspectRatio, // 使用优化后的高度比例 children: [ Obx(() => _kr_buildStatusCard( context, AppTranslations.kr_statistics.vpnStatus, controller.kr_vpnStatus.value, Icons.link, isError: true, vpnStatusColor: controller.kr_vpnStatus.value == '已连接' ? const Color(0xFF67C23A) : controller.kr_vpnStatus.value == '连接中...' ? const Color(0xFFE6A23C) : const Color(0xFFF56C6C), )), Obx(() => _kr_buildStatusCard( context, AppTranslations.kr_statistics.ipAddress, controller.kr_ipAddress.value, Icons.language, )), Obx(() => _kr_buildStatusCard( context, AppTranslations.kr_statistics.connectionTime, controller.kr_connectTime.value, Icons.access_time, )), Obx(() => _kr_buildStatusCard( context, AppTranslations.kr_statistics.protocol, controller.kr_protocol.value, Icons.description_outlined, )), ], ), ); } // 构建状态卡片 Widget _kr_buildStatusCard(BuildContext context, String title, String value, IconData icon, {bool isError = false, Color? vpnStatusColor}) { return Container( padding: EdgeInsets.all(16.r), decoration: BoxDecoration( color: Theme.of(context).cardColor, borderRadius: BorderRadius.circular(12.r), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( icon, color: vpnStatusColor ?? (isError ? Colors.red : Colors.blue), size: 20.w, ), SizedBox(width: 8.w), Expanded( child: FittedBox( fit: BoxFit.scaleDown, alignment: Alignment.centerLeft, child: Text( title, style: KrAppTextStyle( fontSize: 12, fontWeight: FontWeight.w500, color: Theme.of(context).textTheme.bodyMedium?.color, ), ), ), ), ], ), SizedBox(height: 8.w), Text( value, style: KrAppTextStyle( fontSize: 14, color: vpnStatusColor ?? (isError ? Colors.red : Theme.of(context).textTheme.bodySmall?.color), ), ), ], ), ); } // 构建每周图表 Widget _kr_buildWeeklyChart(BuildContext context) { return Container( margin: EdgeInsets.all(16.r), padding: EdgeInsets.fromLTRB(0, 16.r, 16.r, 16.r), decoration: BoxDecoration( color: Theme.of(context).cardColor, borderRadius: BorderRadius.circular(12.r), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.only(left: 16.r), child: Text( AppTranslations.kr_statistics.weeklyProtectionTime, style: KrAppTextStyle( fontSize: 14, color: Theme.of(context).textTheme.bodyMedium?.color, fontWeight: FontWeight.w500, ), ), ), SizedBox(height: 16.w), SizedBox( height: 200.w, child: Obx(() => LineChart( LineChartData( gridData: FlGridData(show: false), titlesData: FlTitlesData( leftTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, reservedSize: 40, interval: 5, getTitlesWidget: (value, meta) { return Padding( padding: EdgeInsets.only(left: 16.w), child: Text( value.toInt().toString(), style: KrAppTextStyle( color: Theme.of(context).textTheme.bodySmall?.color, fontSize: 12, ), ), ); }, ), ), bottomTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, interval: 1, reservedSize: 30, getTitlesWidget: (value, meta) { final titles = controller.kr_getAdjustedWeekTitles(); int index = value.toInt(); if (index >= 0 && index < titles.length) { return Text( titles[index], style: KrAppTextStyle( color: Theme.of(context).textTheme.bodySmall?.color, fontSize: 10, ), maxLines: 2, overflow: TextOverflow.ellipsis, ); } return const Text(''); }, ), ), rightTitles: AxisTitles( sideTitles: SideTitles(showTitles: false), ), topTitles: AxisTitles( sideTitles: SideTitles(showTitles: false), ), ), borderData: FlBorderData(show: false), minX: 0, maxX: 6, minY: 0, maxY: 20, lineBarsData: [ LineChartBarData( spots: controller.kr_weeklyData.asMap().entries.map((e) { return FlSpot(e.key.toDouble(), e.value); }).toList(), isCurved: true, color: Colors.blue, barWidth: 2, isStrokeCapRound: true, dotData: FlDotData(show: false), belowBarData: BarAreaData( show: true, gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Colors.blue.withOpacity(0.2), Colors.blue.withOpacity(0.05), ], ), ), ), ], ), )), ), ], ), ); } // 构建连接记录 Widget _kr_buildConnectionRecords(BuildContext context) { return Container( margin: EdgeInsets.all(16.r), child: Column( children: [ Row( children: [ Expanded( child: Obx(() => _kr_buildRecordCard(context, AppTranslations.kr_statistics.currentStreak, AppTranslations.kr_statistics.days(controller.kr_currentStreak.value))), ), SizedBox(width: 16.w), Expanded( child: Obx(() => _kr_buildRecordCard(context, AppTranslations.kr_statistics.highestStreak, AppTranslations.kr_statistics.days(controller.kr_highestStreak.value))), ), ], ), SizedBox(height: 16.w), Obx(() => _kr_buildLongestConnection(context)), ], ), ); } // 构建记录卡片 Widget _kr_buildRecordCard(BuildContext context, String title, String value) { return Container( padding: EdgeInsets.all(16.r), decoration: BoxDecoration( color: Theme.of(context).cardColor, borderRadius: BorderRadius.circular(12.r), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: KrAppTextStyle( fontSize: 12, color: Theme.of(context).textTheme.bodySmall?.color, ), ), SizedBox(height: 8.w), Text( value, style: KrAppTextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: Theme.of(context).textTheme.bodyMedium?.color, ), ), ], ), ); } // 构建最长连接时间 Widget _kr_buildLongestConnection(BuildContext context) { return Container( padding: EdgeInsets.all(16.r), decoration: BoxDecoration( color: Theme.of(context).cardColor, borderRadius: BorderRadius.circular(12.r), ), child: Row( children: [ Container( width: 40.w, height: 40.w, decoration: BoxDecoration( color: Colors.blue.withOpacity(0.1), shape: BoxShape.circle, ), child: Icon( Icons.access_time, color: Colors.blue, size: 24.w, ), ), SizedBox(width: 16.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( AppTranslations.kr_statistics.longestConnection, style: KrAppTextStyle( fontSize: 12, color: Theme.of(context).textTheme.bodySmall?.color, ), ), Text( AppTranslations.kr_statistics.days(controller.kr_longestConnection.value), style: KrAppTextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: Theme.of(context).textTheme.bodyMedium?.color, ), ), ], ), ), ], ), ); } }