import 'package:get/get.dart'; import '../../../data/services/usage_stats_service.dart'; import '../../../data/models/meeting_usage_stats.dart'; import '../../../core/utils/logger.dart'; class MeetingStatsController extends GetxController { final UsageStatsService _usageService = Get.find(); final isLoading = false.obs; final selectedTabIndex = 0.obs; final selectedTimeRange = 'today'.tr.obs; // 今日 final Rx todayStats = MeetingAsrHistoryStats( userId: '', allAsrCalls: 0, allAudioSeconds: 0, allAudioFileBytes: 0, allTranscriptBytes: 0, ).obs; final Rx historyStats = MeetingAsrHistoryStats( userId: '', allAsrCalls: 0, allAudioSeconds: 0, allAudioFileBytes: 0, allTranscriptBytes: 0, ).obs; final RxList historyDaily = [].obs; final Rx todayStorageStats = MeetingStorageHistoryStats( userId: '', allStorageUploads: 0, allStorageBytes: 0, allTransferBytes: 0, ).obs; final Rx historyStorageStats = MeetingStorageHistoryStats( userId: '', allStorageUploads: 0, allStorageBytes: 0, allTransferBytes: 0, ).obs; final Rx rangeStart = Rx(null); final Rx rangeEnd = Rx(null); final Rx rangeStats = MeetingAsrHistoryStats( userId: '', allAsrCalls: 0, allAudioSeconds: 0, allAudioFileBytes: 0, allTranscriptBytes: 0, ).obs; final Rx rangeStorageStats = MeetingStorageHistoryStats( userId: '', allStorageUploads: 0, allStorageBytes: 0, allTransferBytes: 0, ).obs; @override void onInit() { super.onInit(); loadAllStats(); } Future loadAllStats() async { isLoading.value = true; try { final now = DateTime.now(); final todayList = await _usageService.getMeetingHistoryStats( startDate: DateTime(now.year, now.month, now.day), endDate: DateTime(now.year, now.month, now.day), ); todayStats.value = _usageService.aggregateMeetingStats(todayList); final historyStart = now.subtract(const Duration(days: 7)); historyDaily.value = await _usageService.getMeetingHistoryStats( startDate: DateTime(historyStart.year, historyStart.month, historyStart.day), endDate: DateTime(now.year, now.month, now.day), ); historyStats.value = _usageService.aggregateMeetingStats(historyDaily.value); final todayStorageDaily = await _usageService.getMeetingStorageHistoryStats( startDate: DateTime(now.year, now.month, now.day), endDate: DateTime(now.year, now.month, now.day), ); todayStorageStats.value = _usageService.aggregateMeetingStorageStats(todayStorageDaily); final historyStorageDaily = await _usageService.getMeetingStorageHistoryStats( startDate: DateTime(historyStart.year, historyStart.month, historyStart.day), endDate: DateTime(now.year, now.month, now.day), ); historyStorageStats.value = _usageService.aggregateMeetingStorageStats(historyStorageDaily); if (rangeStart.value != null && rangeEnd.value != null) { final customAsrDaily = await _usageService.getMeetingHistoryStats( startDate: DateTime(rangeStart.value!.year, rangeStart.value!.month, rangeStart.value!.day), endDate: DateTime( rangeEnd.value!.year, rangeEnd.value!.month, rangeEnd.value!.day), ); rangeStats.value = _usageService.aggregateMeetingStats(customAsrDaily); final customStorageDaily = await _usageService.getMeetingStorageHistoryStats( startDate: DateTime(rangeStart.value!.year, rangeStart.value!.month, rangeStart.value!.day), endDate: DateTime( rangeEnd.value!.year, rangeEnd.value!.month, rangeEnd.value!.day), ); rangeStorageStats.value = _usageService.aggregateMeetingStorageStats(customStorageDaily); } else { rangeStats.value = historyStats.value; rangeStorageStats.value = historyStorageStats.value; } Logger.info('会议统计数据加载完成'); } catch (e) { Logger.error('加载会议统计数据失败: $e'); } finally { isLoading.value = false; } } void switchTimeRange(int index) { selectedTabIndex.value = index; switch (index) { case 0: selectedTimeRange.value = 'today'.tr; // 今日 break; case 1: selectedTimeRange.value = 'history'.tr; // 历史 break; default: selectedTimeRange.value = 'today'.tr; // 今日 break; } } MeetingAsrHistoryStats get currentStats { switch (selectedTabIndex.value) { case 0: return todayStats.value; case 1: return rangeStats.value; default: return todayStats.value; } } String formatDuration(int seconds) { if (seconds < 60) { return '$seconds${'seconds'.tr}'; // 秒 } else if (seconds < 3600) { final minutes = seconds ~/ 60; final remainingSeconds = seconds % 60; return '$minutes${'minutes'.tr}$remainingSeconds${'seconds'.tr}'; // 分钟秒 } else { final hours = seconds ~/ 3600; final minutes = (seconds % 3600) ~/ 60; return '$hours${'hours'.tr}$minutes${'minutes'.tr}'; // 小时分钟 } } String formatBytes(int bytes) { if (bytes < 1024) return '$bytes B'; final kb = bytes / 1024; if (kb < 1024) return '${kb.toStringAsFixed(1)} KB'; final mb = kb / 1024; if (mb < 1024) return '${mb.toStringAsFixed(1)} MB'; final gb = mb / 1024; return '${gb.toStringAsFixed(1)} GB'; } String formatNumber(int number) { if (number < 1000) return number.toString(); if (number < 1000000) return '${(number / 1000).toStringAsFixed(1)}K'; return '${(number / 1000000).toStringAsFixed(1)}M'; } Future refreshData() async { await loadAllStats(); } Future setCustomRangeDates(DateTime start, DateTime end) async { rangeStart.value = start; rangeEnd.value = end; isLoading.value = true; try { final asrDaily = await _usageService.getMeetingHistoryStats( startDate: DateTime(start.year, start.month, start.day), endDate: DateTime(end.year, end.month, end.day), ); rangeStats.value = _usageService.aggregateMeetingStats(asrDaily); final storageDaily = await _usageService.getMeetingStorageHistoryStats( startDate: DateTime(start.year, start.month, start.day), endDate: DateTime(end.year, end.month, end.day), ); rangeStorageStats.value = _usageService.aggregateMeetingStorageStats(storageDaily); } catch (e) { Logger.error('设置自定义日期范围失败: $e'); } finally { isLoading.value = false; } } String formatDate(DateTime d) { final y = d.year.toString(); final m = d.month.toString().padLeft(2, '0'); final day = d.day.toString().padLeft(2, '0'); return '$y-$m-$day'; } }