import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import '../../../core/theme/app_colors.dart'; import '../controllers/meeting_stats_controller.dart'; import '../../../data/models/user_Info.dart'; import '../../../data/models/meeting_usage_stats.dart'; class MeetingStatsView extends GetView { const MeetingStatsView({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(context, isDarkMode), body: Obx(() => controller.isLoading.value ? const Center(child: CircularProgressIndicator()) : _buildBody(isDarkMode)), ); } PreferredSizeWidget _buildAppBar(BuildContext context, bool isDarkMode) { return AppBar( leading: IconButton( icon: Icon(Icons.arrow_back_ios, color: isDarkMode ? Colors.white : Colors.black, size: 20.sp), onPressed: () => Get.back(), ), backgroundColor: isDarkMode ? AppColors.darkBackground : Colors.white, elevation: 0.5, title: Text( 'meetingStats'.tr, // 会议统计 style: TextStyle( fontSize: 17.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black), ), centerTitle: true, actions: [ IconButton( icon: Icon(Icons.date_range, color: isDarkMode ? Colors.white : Colors.black), onPressed: () async { final now = DateTime.now(); final initialStart = controller.rangeStart.value ?? DateTime(now.year, now.month, now.day); final initialEnd = controller.rangeEnd.value ?? DateTime(now.year, now.month, now.day); final picked = await showDateRangePicker( context: context, firstDate: DateTime(now.year - 1), lastDate: DateTime(now.year + 1), initialDateRange: DateTimeRange(start: initialStart, end: initialEnd), ); if (picked != null) { await controller.setCustomRangeDates(picked.start, picked.end); } }, ), IconButton( icon: Icon(Icons.refresh, color: isDarkMode ? Colors.white : Colors.black), onPressed: controller.refreshData, ), ], ); } Widget _buildBody(bool isDarkMode) { final hasRange = controller.rangeStart.value != null && controller.rangeEnd.value != null; final historyTitle = hasRange ? "${'history'.tr} (${controller.formatDate(controller.rangeStart.value!)} ~ ${controller.formatDate(controller.rangeEnd.value!)})" : 'history'.tr; return Column( children: [ _buildIntegralRow(isDarkMode), Expanded( child: SingleChildScrollView( padding: EdgeInsets.all(16.w), child: Column( children: [ _buildOverviewCard( 'today'.tr, // 今日 isDarkMode, controller.todayStats.value, controller.todayStorageStats.value, ), SizedBox(height: 16.h), _buildOverviewCard( historyTitle, isDarkMode, controller.rangeStats.value, controller.rangeStorageStats.value, ), ], ), ), ), ], ); } Widget _buildIntegralRow(bool isDarkMode) { return Obx(() { final _ = User.refreshTick.value; final u = User.instance; return Padding( padding: EdgeInsets.all(16.w), child: Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( color: isDarkMode ? AppColors.cardBackground : Colors.white, borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.05), blurRadius: 10, offset: const Offset(0, 2)), ], ), child: Row( children: [ Icon(Icons.people, color: AppColors.primary, size: 20.sp), SizedBox(width: 8.w), Expanded( child: Text( 'remainingQuota'.tr, style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black), ), ), Text( '${u.meetintegral}/${u.meettotalintegral}', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black), ), ], ), ), ); }); } Widget _buildOverviewCard( String title, bool isDarkMode, MeetingAsrHistoryStats asrStats, MeetingStorageHistoryStats storageStats, ) { 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.withValues(alpha: 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), Text( '$title${'overview'.tr}', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black), ), ], ), SizedBox(height: 16.h), Row( children: [ Expanded( child: _buildStatItem( 'asrApiCalls'.tr, // ASR调用次数 controller.formatNumber(asrStats.allAsrCalls), Icons.api, isDarkMode)), Expanded( child: _buildStatItem( 'totalAudioDuration'.tr, // 音频总时长 controller.formatDuration(asrStats.allAudioSeconds), Icons.mic, isDarkMode)), ], ), SizedBox(height: 12.h), Row( children: [ Expanded( child: _buildStatItem( 'audioFileSize'.tr, // 音频文件大小 controller.formatBytes(asrStats.allAudioFileBytes), Icons.folder, isDarkMode)), Expanded( child: _buildStatItem( 'transcriptBytes'.tr, // 转写字节 controller.formatNumber(asrStats.allTranscriptBytes), Icons.text_snippet, isDarkMode)), ], ), SizedBox(height: 12.h), Row( children: [ Expanded( child: _buildStatItem( 'storageUploads'.tr, // 对象存储上传次数 controller.formatNumber(storageStats.allStorageUploads), Icons.cloud_upload, isDarkMode)), Expanded( child: _buildStatItem( 'storageBytes'.tr, // 对象存储总大小 controller.formatBytes(storageStats.allStorageBytes), Icons.cloud, 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), ), ], ); } }