import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import '../controllers/translation_stats_controller.dart'; import '../../../core/theme/app_colors.dart'; /// 翻译统计页面 class TranslationStatsView extends GetView { const TranslationStatsView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; return Scaffold( backgroundColor: isDarkMode ? AppColors.darkBackground : Colors.grey[50], appBar: _buildAppBar(isDarkMode), body: Obx(() => controller.isLoading.value ? _buildLoadingWidget() : _buildBody(isDarkMode)), ); } /// 构建应用栏 PreferredSizeWidget _buildAppBar(bool isDarkMode) { return AppBar( backgroundColor: isDarkMode ? AppColors.darkBackground : Colors.white, elevation: 0.5, title: Text( '翻译统计', // translationStats style: TextStyle( fontSize: 17.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), centerTitle: true, actions: [ // 刷新按钮 IconButton( icon: Icon( Icons.refresh, color: isDarkMode ? Colors.white : Colors.black, ), onPressed: controller.refreshData, ), // 更多操作菜单 PopupMenuButton( icon: Icon( Icons.more_vert, color: isDarkMode ? Colors.white : Colors.black, ), onSelected: (value) { switch (value) { case 'cleanup': controller.cleanupOldData(); break; case 'export': controller.exportStats(); break; } }, itemBuilder: (context) => [ const PopupMenuItem( value: 'cleanup', child: Text('清理过期数据'), ), const PopupMenuItem( value: 'export', child: Text('导出数据'), ), ], ), ], ); } /// 构建加载组件 Widget _buildLoadingWidget() { return const Center( child: CircularProgressIndicator(), ); } /// 构建主体内容 Widget _buildBody(bool isDarkMode) { return Column( children: [ // 时间范围选择器 _buildTimeRangeSelector(isDarkMode), // 统计内容 Expanded( child: SingleChildScrollView( padding: EdgeInsets.all(16.w), child: Column( children: [ // 实时统计卡片 if (controller.selectedTabIndex.value == 0) _buildRealtimeStatsCard(isDarkMode), SizedBox(height: 16.h), // 概览统计卡片 _buildOverviewCard(isDarkMode), SizedBox(height: 16.h), // API调用统计 _buildApiCallsCard(isDarkMode), SizedBox(height: 16.h), // 数据量统计 _buildDataVolumeCard(isDarkMode), SizedBox(height: 16.h), // 成本统计 _buildCostCard(isDarkMode), SizedBox(height: 16.h), // 使用行为统计 _buildUsageBehaviorCard(isDarkMode), ], ), ), ), ], ); } /// 构建时间范围选择器 Widget _buildTimeRangeSelector(bool isDarkMode) { return Container( margin: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isDarkMode ? AppColors.cardBackground : Colors.white, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Obx(() => Row( children: [ _buildTimeRangeTab('今日', 0, isDarkMode), _buildTimeRangeTab('本周', 1, isDarkMode), _buildTimeRangeTab('本月', 2, isDarkMode), _buildTimeRangeTab('历史', 3, isDarkMode), ], )), ); } /// 构建时间范围标签 Widget _buildTimeRangeTab(String title, int index, bool isDarkMode) { final isSelected = controller.selectedTabIndex.value == index; return Expanded( child: GestureDetector( onTap: () => controller.switchTimeRange(index), child: Container( padding: EdgeInsets.symmetric(vertical: 12.h), decoration: BoxDecoration( color: isSelected ? (isDarkMode ? AppColors.primary : AppColors.primary) : Colors.transparent, borderRadius: BorderRadius.circular(12.r), ), child: Text( title, textAlign: TextAlign.center, style: TextStyle( fontSize: 14.sp, fontWeight: isSelected ? FontWeight.w600 : FontWeight.w400, color: isSelected ? Colors.white : (isDarkMode ? Colors.white70 : Colors.black54), ), ), ), ), ); } /// 构建实时统计卡片 Widget _buildRealtimeStatsCard(bool isDarkMode) { return Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isDarkMode ? AppColors.cardBackground : Colors.white, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.access_time, color: AppColors.primary, size: 20.sp, ), SizedBox(width: 8.w), Text( '当前会话统计', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), ], ), SizedBox(height: 16.h), Obx(() => Row( children: [ Expanded( child: _buildStatItem( '翻译次数', controller.realtimeStats.translationCount.toString(), Icons.translate, isDarkMode, ), ), Expanded( child: _buildStatItem( '会话时长', '${controller.realtimeStats.sessionDurationMinutes}分钟', Icons.timer, isDarkMode, ), ), ], )), SizedBox(height: 12.h), Obx(() => Row( children: [ Expanded( child: _buildStatItem( '字符数', controller.formatNumber( controller.realtimeStats.sourceCharacters + controller.realtimeStats.targetCharacters, ), Icons.text_fields, isDarkMode, ), ), Expanded( child: _buildStatItem( '录音时长', controller.formatDuration(controller.realtimeStats.recordingDuration), Icons.mic, isDarkMode, ), ), ], )), ], ), ); } /// 构建概览卡片 Widget _buildOverviewCard(bool isDarkMode) { return Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isDarkMode ? AppColors.cardBackground : Colors.white, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.dashboard, color: AppColors.primary, size: 20.sp, ), SizedBox(width: 8.w), Obx(() => Text( '${controller.selectedTimeRange.value}概览', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), )), ], ), SizedBox(height: 16.h), Obx(() => Row( children: [ Expanded( child: _buildStatItem( '总调用次数', controller.formatNumber(controller.currentStats.totalApiCalls), Icons.api, isDarkMode, ), ), Expanded( child: _buildStatItem( '预估成本', controller.formatCost(controller.currentStats.estimatedCost), Icons.attach_money, isDarkMode, ), ), ], )), SizedBox(height: 12.h), Obx(() => Row( children: [ Expanded( child: _buildStatItem( '会话数量', controller.currentStats.sessionCount.toString(), Icons.chat, isDarkMode, ), ), Expanded( child: _buildStatItem( '总字符数', controller.formatNumber(controller.currentStats.totalCharacterCount), Icons.text_snippet, isDarkMode, ), ), ], )), ], ), ); } /// 构建统计项 Widget _buildStatItem(String label, String value, IconData icon, bool isDarkMode) { return Column( children: [ Icon( icon, color: AppColors.primary, size: 24.sp, ), SizedBox(height: 8.h), Text( value, style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.bold, color: isDarkMode ? Colors.white : Colors.black, ), ), SizedBox(height: 4.h), Text( label, style: TextStyle( fontSize: 12.sp, color: isDarkMode ? Colors.white70 : Colors.black54, ), ), ], ); } /// 构建API调用统计卡片 Widget _buildApiCallsCard(bool isDarkMode) { return Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isDarkMode ? AppColors.cardBackground : Colors.white, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.api, color: AppColors.primary, size: 20.sp, ), SizedBox(width: 8.w), Text( 'API调用统计', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), ], ), SizedBox(height: 16.h), Obx(() => Column( children: [ _buildApiCallRow('翻译API', controller.currentStats.translationApiCalls, Icons.translate, isDarkMode), SizedBox(height: 12.h), _buildApiCallRow('语音识别', controller.currentStats.asrApiCalls, Icons.mic, isDarkMode), SizedBox(height: 12.h), _buildApiCallRow('语音合成', controller.currentStats.ttsApiCalls, Icons.volume_up, isDarkMode), SizedBox(height: 12.h), _buildApiCallRow('AI摘要', controller.currentStats.aiSummaryApiCalls, Icons.summarize, isDarkMode), ], )), ], ), ); } /// 构建API调用行 Widget _buildApiCallRow(String label, int count, IconData icon, bool isDarkMode) { return Row( children: [ Icon( icon, color: AppColors.primary, size: 18.sp, ), SizedBox(width: 12.w), Expanded( child: Text( label, style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.white : Colors.black, ), ), ), Text( controller.formatNumber(count), style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), ], ); } /// 构建数据量统计卡片 Widget _buildDataVolumeCard(bool isDarkMode) { return Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isDarkMode ? AppColors.cardBackground : Colors.white, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.data_usage, color: AppColors.primary, size: 20.sp, ), SizedBox(width: 8.w), Text( '数据量统计', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), ], ), SizedBox(height: 16.h), Obx(() => Column( children: [ Row( children: [ Expanded( child: _buildStatItem( '源文本字符', controller.formatNumber(controller.currentStats.sourceTextCharacters), Icons.text_fields, isDarkMode, ), ), Expanded( child: _buildStatItem( 'TTS文本字符', controller.formatNumber(controller.currentStats.ttsTextCharacters), Icons.translate, isDarkMode, ), ), ], ), SizedBox(height: 16.h), Row( children: [ Expanded( child: _buildStatItem( '有效音频时长', controller.formatDuration(controller.currentStats.effectiveAudioDuration), Icons.mic, isDarkMode, ), ), Expanded( child: _buildStatItem( '总会话时长', controller.formatDuration(controller.currentStats.totalSessionDuration), Icons.volume_up, isDarkMode, ), ), ], ), ], )), ], ), ); } /// 构建成本统计卡片 Widget _buildCostCard(bool isDarkMode) { return Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isDarkMode ? AppColors.cardBackground : Colors.white, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.attach_money, color: AppColors.primary, size: 20.sp, ), SizedBox(width: 8.w), Text( '成本统计', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), ], ), SizedBox(height: 16.h), Obx(() => Column( children: [ // 当前成本 Container( padding: EdgeInsets.all(12.w), decoration: BoxDecoration( color: AppColors.primary.withOpacity(0.1), borderRadius: BorderRadius.circular(8.r), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '${controller.selectedTimeRange.value}预估成本', style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w500, color: isDarkMode ? Colors.white : Colors.black, ), ), Text( controller.formatCost(controller.currentStats.estimatedCost), style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.bold, color: AppColors.primary, ), ), ], ), ), SizedBox(height: 12.h), // 预警阈值 Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '日成本预警阈值', style: TextStyle( fontSize: 12.sp, color: isDarkMode ? Colors.white70 : Colors.black54, ), ), Text( controller.formatCost(controller.dailyCostThreshold.value), style: TextStyle( fontSize: 12.sp, color: isDarkMode ? Colors.white70 : Colors.black54, ), ), ], ), SizedBox(height: 4.h), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '月成本预警阈值', style: TextStyle( fontSize: 12.sp, color: isDarkMode ? Colors.white70 : Colors.black54, ), ), Text( controller.formatCost(controller.monthlyCostThreshold.value), style: TextStyle( fontSize: 12.sp, color: isDarkMode ? Colors.white70 : Colors.black54, ), ), ], ), ], )), ], ), ); } /// 构建使用行为统计卡片 Widget _buildUsageBehaviorCard(bool isDarkMode) { return Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isDarkMode ? AppColors.cardBackground : Colors.white, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.analytics, color: AppColors.primary, size: 20.sp, ), SizedBox(width: 8.w), Text( '使用行为统计', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), ], ), SizedBox(height: 16.h), Obx(() => Column( children: [ // 最常用语言对 _buildUsageBehaviorRow( '最常用语言对', controller.currentStats.mostUsedLanguagePair, Icons.language, isDarkMode, ), SizedBox(height: 12.h), // 最常用翻译模式 _buildUsageBehaviorRow( '最常用模式', controller.currentStats.mostUsedMode, Icons.settings, isDarkMode, ), ], )), ], ), ); } /// 构建使用行为行 Widget _buildUsageBehaviorRow(String label, String value, IconData icon, bool isDarkMode) { return Row( children: [ Icon( icon, color: AppColors.primary, size: 18.sp, ), SizedBox(width: 12.w), Expanded( child: Text( label, style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.white : Colors.black, ), ), ), Text( value, style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), ], ); } }