Browse Source

feat(usage): 添加翻译使用统计模块,包括视图、控制器和绑定

实现翻译使用统计功能,包含以下主要组件:
1. 翻译统计视图,展示实时和历史使用数据
2. 翻译统计控制器,处理数据加载和业务逻辑
3. 翻译成本控制器,管理成本配置和阈值设置
4. 相关绑定类,用于依赖注入

模块支持查看今日、本周、本月和历史统计数据,包括API调用次数、数据量和成本分析
weicu
lxm 11 months ago
parent
commit
9ec455c799
  1. 8
      lib/modules/usage/bindings/translation_stats_binding.dart
  2. 84
      lib/modules/usage/controllers/translation_cost_controller.dart
  3. 60
      lib/modules/usage/controllers/translation_stats_controller.dart
  4. 53
      lib/modules/usage/views/translation_stats_view.dart
  5. 4
      lib/routes/app_pages.dart

8
lib/modules/translation/bindings/translation_stats_binding.dart → lib/modules/usage/bindings/translation_stats_binding.dart

@ -2,18 +2,12 @@ import 'package:get/get.dart';
import '../controllers/translation_stats_controller.dart';
import '../../../data/services/translation_usage_service.dart';
//翻译统计页面依赖绑定
class TranslationStatsBinding implements Bindings {
@override
void dependencies() {
// 确保服务已注册
if (!Get.isRegistered<TranslationUsageService>()) {
Get.put(TranslationUsageService(), permanent: true);
}
// 注册控制器
Get.lazyPut<TranslationStatsController>(
() => TranslationStatsController(),
);
Get.lazyPut<TranslationStatsController>(() => TranslationStatsController());
}
}

84
lib/modules/translation/controllers/translation_cost_controller.dart → lib/modules/usage/controllers/translation_cost_controller.dart

@ -3,25 +3,18 @@ import 'package:flutter/material.dart';
import '../../../data/services/translation_usage_service.dart';
import '../../../core/utils/logger.dart';
/// 翻译成本配置控制器
class TranslationCostController extends GetxController {
// 依赖注入
final TranslationUsageService _usageService = Get.find<TranslationUsageService>();
// 成本配置
final TranslationUsageService _usageService =
Get.find<TranslationUsageService>();
final RxMap<String, double> costConfig = <String, double>{}.obs;
final RxDouble dailyCostThreshold = 10.0.obs;
final RxDouble monthlyCostThreshold = 300.0.obs;
// 表单控制器
final translationCostController = TextEditingController();
final asrCostController = TextEditingController();
final ttsCostController = TextEditingController();
final aiSummaryCostController = TextEditingController();
final dailyThresholdController = TextEditingController();
final monthlyThresholdController = TextEditingController();
// 状态变量
final isLoading = false.obs;
final isSaving = false.obs;
@ -33,7 +26,6 @@ class TranslationCostController extends GetxController {
@override
void onClose() {
// 释放控制器
translationCostController.dispose();
asrCostController.dispose();
ttsCostController.dispose();
@ -43,24 +35,22 @@ class TranslationCostController extends GetxController {
super.onClose();
}
/// 加载当前配置
void _loadCurrentConfig() {
isLoading.value = true;
try {
// 从服务获取当前配置
costConfig.value = Map<String, double>.from(_usageService.costConfig);
dailyCostThreshold.value = _usageService.dailyCostThreshold.value;
monthlyCostThreshold.value = _usageService.monthlyCostThreshold.value;
// 更新表单控制器
translationCostController.text = (costConfig['translation_per_1k_chars'] ?? 0.05).toString();
asrCostController.text = (costConfig['asr_per_minute'] ?? 0.02).toString();
ttsCostController.text = (costConfig['tts_per_1k_chars'] ?? 0.03).toString();
aiSummaryCostController.text = (costConfig['ai_summary_per_request'] ?? 0.01).toString();
translationCostController.text =
(costConfig['translation_per_1k_chars'] ?? 0.05).toString();
asrCostController.text =
(costConfig['asr_per_minute'] ?? 0.02).toString();
ttsCostController.text =
(costConfig['tts_per_1k_chars'] ?? 0.03).toString();
aiSummaryCostController.text =
(costConfig['ai_summary_per_request'] ?? 0.01).toString();
dailyThresholdController.text = dailyCostThreshold.value.toString();
monthlyThresholdController.text = monthlyCostThreshold.value.toString();
Logger.info('成本配置加载完成');
} catch (e) {
Logger.error('加载成本配置失败: $e');
@ -70,44 +60,32 @@ class TranslationCostController extends GetxController {
}
}
/// 保存配置
Future<void> saveConfig() async {
if (isSaving.value) return;
isSaving.value = true;
try {
// 验证输入
if (!_validateInputs()) {
return;
}
// 更新成本配置
final newCostConfig = {
'translation_per_1k_chars': double.parse(translationCostController.text),
'translation_per_1k_chars':
double.parse(translationCostController.text),
'asr_per_minute': double.parse(asrCostController.text),
'tts_per_1k_chars': double.parse(ttsCostController.text),
'ai_summary_per_request': double.parse(aiSummaryCostController.text),
};
final newDailyThreshold = double.parse(dailyThresholdController.text);
final newMonthlyThreshold = double.parse(monthlyThresholdController.text);
// 保存到服务
_usageService.updateCostConfig(newCostConfig);
_usageService.updateThresholds(
dailyThreshold: newDailyThreshold,
monthlyThreshold: newMonthlyThreshold,
);
// 更新本地状态
costConfig.value = newCostConfig;
dailyCostThreshold.value = newDailyThreshold;
monthlyCostThreshold.value = newMonthlyThreshold;
_showSuccessSnackbar('配置保存成功');
Logger.info('成本配置保存成功');
} catch (e) {
Logger.error('保存成本配置失败: $e');
_showErrorSnackbar('保存配置失败');
@ -116,7 +94,6 @@ class TranslationCostController extends GetxController {
}
}
/// 重置为默认配置
void resetToDefault() {
translationCostController.text = '0.05';
asrCostController.text = '0.02';
@ -124,11 +101,9 @@ class TranslationCostController extends GetxController {
aiSummaryCostController.text = '0.01';
dailyThresholdController.text = '10.0';
monthlyThresholdController.text = '300.0';
_showInfoSnackbar('已重置为默认配置,请点击保存生效');
}
/// 验证输入
bool _validateInputs() {
try {
final translationCost = double.parse(translationCostController.text);
@ -137,22 +112,21 @@ class TranslationCostController extends GetxController {
final aiSummaryCost = double.parse(aiSummaryCostController.text);
final dailyThreshold = double.parse(dailyThresholdController.text);
final monthlyThreshold = double.parse(monthlyThresholdController.text);
if (translationCost < 0 || asrCost < 0 || ttsCost < 0 || aiSummaryCost < 0) {
if (translationCost < 0 ||
asrCost < 0 ||
ttsCost < 0 ||
aiSummaryCost < 0) {
_showErrorSnackbar('成本不能为负数');
return false;
}
if (dailyThreshold < 0 || monthlyThreshold < 0) {
_showErrorSnackbar('预警阈值不能为负数');
return false;
}
if (dailyThreshold > monthlyThreshold) {
_showErrorSnackbar('日预警阈值不能大于月预警阈值');
return false;
}
return true;
} catch (e) {
_showErrorSnackbar('请输入有效的数字');
@ -160,13 +134,10 @@ class TranslationCostController extends GetxController {
}
}
/// 计算预估月成本
double calculateEstimatedMonthlyCost() {
try {
final dailyStats = _usageService.todayStats.value;
if (dailyStats.estimatedCost == 0) return 0.0;
// 简单按30天计算
return dailyStats.estimatedCost * 30;
} catch (e) {
Logger.error('计算预估月成本失败: $e');
@ -174,84 +145,69 @@ class TranslationCostController extends GetxController {
}
}
/// 获取成本节约建议
List<String> getCostSavingTips() {
final tips = <String>[];
try {
final dailyStats = _usageService.todayStats.value;
// 基于使用情况给出建议
if (dailyStats.translationApiCalls > 100) {
tips.add('考虑批量翻译以减少API调用次数');
}
if (dailyStats.ttsApiCalls > 50) {
tips.add('可以关闭自动语音播放以节省TTS成本');
}
if (dailyStats.aiSummaryApiCalls > 10) {
tips.add('AI摘要功能按需使用,避免频繁调用');
}
if (dailyStats.effectiveAudioDuration > 3600) { // 超过1小时
if (dailyStats.effectiveAudioDuration > 3600) {
tips.add('长时间录音会增加ASR成本,建议分段录音');
}
if (tips.isEmpty) {
tips.add('您的使用习惯很好,继续保持!');
}
} catch (e) {
Logger.error('获取成本节约建议失败: $e');
tips.add('暂无建议');
}
return tips;
}
/// 显示成功提示
void _showSuccessSnackbar(String message) {
Get.snackbar(
'成功',
message,
snackPosition: SnackPosition.TOP,
backgroundColor: Get.theme.colorScheme.primary.withOpacity(0.1),
backgroundColor: Get.theme.colorScheme.primary.withValues(alpha: 0.1),
colorText: Get.theme.colorScheme.primary,
duration: const Duration(seconds: 3),
);
}
/// 显示错误提示
void _showErrorSnackbar(String message) {
Get.snackbar(
'错误',
message,
snackPosition: SnackPosition.TOP,
backgroundColor: Get.theme.colorScheme.error.withOpacity(0.1),
backgroundColor: Get.theme.colorScheme.error.withValues(alpha: 0.1),
colorText: Get.theme.colorScheme.error,
duration: const Duration(seconds: 3),
);
}
/// 显示信息提示
void _showInfoSnackbar(String message) {
Get.snackbar(
'提示',
message,
snackPosition: SnackPosition.TOP,
backgroundColor: Get.theme.colorScheme.surface.withOpacity(0.9),
backgroundColor: Get.theme.colorScheme.surface.withValues(alpha: 0.9),
colorText: Get.theme.colorScheme.onSurface,
duration: const Duration(seconds: 3),
);
}
/// 格式化成本显示
String formatCost(double cost) {
return '¥${cost.toStringAsFixed(2)}';
}
/// 格式化百分比显示
String formatPercentage(double percentage) {
return '${percentage.toStringAsFixed(1)}%';
}

60
lib/modules/translation/controllers/translation_stats_controller.dart → lib/modules/usage/controllers/translation_stats_controller.dart

@ -1,21 +1,16 @@
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import '../../../data/services/translation_usage_service.dart';
import '../../../data/models/translation_usage_stats.dart';
import '../../../core/utils/logger.dart';
/// 翻译统计页面控制器
class TranslationStatsController extends GetxController {
// 依赖注入
final TranslationUsageService _usageService =
Get.find<TranslationUsageService>();
// 状态变量
final isLoading = false.obs;
final selectedTabIndex = 0.obs; // 0=今日, 1=本周, 2=本月, 3=历史
final selectedTabIndex = 0.obs;
final selectedTimeRange = '今日'.obs;
// 统计数据
final Rx<TranslationUsageStats> todayStats =
TranslationUsageStats.empty('').obs;
final Rx<TranslationUsageStats> weekStats =
@ -25,15 +20,12 @@ class TranslationStatsController extends GetxController {
final RxList<TranslationUsageStats> historyStats =
<TranslationUsageStats>[].obs;
// 实时统计数据
RealtimeUsageStats get realtimeStats => _usageService.realtimeStats.value;
// 成本配置
final RxMap<String, double> costConfig = <String, double>{}.obs;
final RxDouble dailyCostThreshold = 10.0.obs;
final RxDouble monthlyCostThreshold = 300.0.obs;
// 图表数据
final RxList<Map<String, dynamic>> chartData = <Map<String, dynamic>>[].obs;
@override
@ -42,9 +34,7 @@ class TranslationStatsController extends GetxController {
_initializeData();
}
/// 初始化数据
void _initializeData() {
// 监听使用服务的数据变化
ever(_usageService.todayStats, (stats) {
todayStats.value = stats;
_updateChartData();
@ -62,28 +52,21 @@ class TranslationStatsController extends GetxController {
monthlyCostThreshold.value = threshold;
});
// 初始加载数据
loadAllStats();
}
/// 加载所有统计数据
Future<void> loadAllStats() async {
isLoading.value = true;
try {
// 加载今日数据
todayStats.value = _usageService.todayStats.value;
// 加载本周数据
await _loadWeekStats();
// 加载本月数据
await _loadMonthStats();
// 加载历史数据(最近7天)
await _loadHistoryStats();
// 更新图表数据
_updateChartData();
Logger.info('统计数据加载完成');
@ -93,7 +76,8 @@ class TranslationStatsController extends GetxController {
'加载失败',
'统计数据加载失败,请稍后重试',
snackPosition: SnackPosition.TOP,
backgroundColor: Get.theme.colorScheme.error.withOpacity(0.1),
backgroundColor:
Get.theme.colorScheme.error.withValues(alpha: 0.1),
colorText: Get.theme.colorScheme.error,
);
} finally {
@ -101,7 +85,6 @@ class TranslationStatsController extends GetxController {
}
}
/// 加载本周统计数据
Future<void> _loadWeekStats() async {
try {
final now = DateTime.now();
@ -119,7 +102,6 @@ class TranslationStatsController extends GetxController {
}
}
/// 加载本月统计数据
Future<void> _loadMonthStats() async {
try {
final now = DateTime.now();
@ -130,7 +112,6 @@ class TranslationStatsController extends GetxController {
}
}
/// 加载历史统计数据
Future<void> _loadHistoryStats() async {
try {
final endDate = DateTime.now();
@ -141,14 +122,12 @@ class TranslationStatsController extends GetxController {
endDate: endDate,
);
// 按日期排序
historyStats.sort((a, b) => b.date.compareTo(a.date));
} catch (e) {
Logger.error('加载历史统计失败: $e');
}
}
/// 聚合统计数据
TranslationUsageStats _aggregateStats(
List<TranslationUsageStats> statsList, String period) {
if (statsList.isEmpty) {
@ -181,13 +160,11 @@ class TranslationStatsController extends GetxController {
totalSessions += stats.sessionCount;
totalCost += stats.estimatedCost;
// 合并语言对使用统计(使用兼容性getter)
stats.languagePairUsage.forEach((key, value) {
combinedLanguagePairUsage[key] =
(combinedLanguagePairUsage[key] ?? 0) + value;
});
// 合并模式使用统计(使用兼容性getter)
stats.modeUsage.forEach((key, value) {
combinedModeUsage[key] = (combinedModeUsage[key] ?? 0) + value;
});
@ -211,13 +188,11 @@ class TranslationStatsController extends GetxController {
);
}
/// 更新图表数据
void _updateChartData() {
final List<Map<String, dynamic>> data = [];
// 根据选中的时间范围生成图表数据
switch (selectedTabIndex.value) {
case 0: // 今日
case 0:
data.add({
'label': '今日',
'apiCalls': todayStats.value.totalApiCalls,
@ -225,7 +200,7 @@ class TranslationStatsController extends GetxController {
'characters': todayStats.value.totalCharacterCount,
});
break;
case 1: // 本周
case 1:
data.add({
'label': '本周',
'apiCalls': weekStats.value.totalApiCalls,
@ -233,7 +208,7 @@ class TranslationStatsController extends GetxController {
'characters': weekStats.value.totalCharacterCount,
});
break;
case 2: // 本月
case 2:
data.add({
'label': '本月',
'apiCalls': monthStats.value.totalApiCalls,
@ -241,7 +216,7 @@ class TranslationStatsController extends GetxController {
'characters': monthStats.value.totalCharacterCount,
});
break;
case 3: // 历史
case 3:
for (final stats in historyStats.take(7)) {
data.add({
'label': '${stats.date.month}/${stats.date.day}',
@ -256,7 +231,6 @@ class TranslationStatsController extends GetxController {
chartData.value = data;
}
/// 切换时间范围
void switchTimeRange(int index) {
selectedTabIndex.value = index;
@ -278,7 +252,6 @@ class TranslationStatsController extends GetxController {
_updateChartData();
}
/// 获取当前显示的统计数据
TranslationUsageStats get currentStats {
switch (selectedTabIndex.value) {
case 0:
@ -292,32 +265,30 @@ class TranslationStatsController extends GetxController {
}
}
/// 刷新数据
Future<void> refreshData() async {
await loadAllStats();
}
/// 清理过期数据
void cleanupOldData() {
_usageService.cleanupOldData();
Get.snackbar(
'清理完成',
'已清理90天前的过期数据',
snackPosition: SnackPosition.TOP,
backgroundColor: Get.theme.colorScheme.primary.withOpacity(0.1),
backgroundColor:
Get.theme.colorScheme.primary.withValues(alpha: 0.1),
colorText: Get.theme.colorScheme.primary,
);
}
/// 导出统计数据
Future<void> exportStats() async {
try {
// TODO: 实现数据导出功能
Get.snackbar(
'导出功能',
'数据导出功能正在开发中',
snackPosition: SnackPosition.TOP,
backgroundColor: Get.theme.colorScheme.primary.withOpacity(0.1),
backgroundColor:
Get.theme.colorScheme.primary.withValues(alpha: 0.1),
colorText: Get.theme.colorScheme.primary,
);
} catch (e) {
@ -325,27 +296,24 @@ class TranslationStatsController extends GetxController {
}
}
/// 格式化时长显示
String formatDuration(int seconds) {
if (seconds < 60) {
return '${seconds}秒';
return '$seconds秒';
} else if (seconds < 3600) {
final minutes = seconds ~/ 60;
final remainingSeconds = seconds % 60;
return '${minutes}分${remainingSeconds}秒';
return '$minutes分$remainingSeconds秒';
} else {
final hours = seconds ~/ 3600;
final minutes = (seconds % 3600) ~/ 60;
return '${hours}小时${minutes}分';
return '$hours小时$minutes分';
}
}
/// 格式化成本显示
String formatCost(double cost) {
return '¥${cost.toStringAsFixed(2)}';
}
/// 格式化数字显示
String formatNumber(int number) {
if (number < 1000) {
return number.toString();

53
lib/modules/translation/views/translation_stats_view.dart → lib/modules/usage/views/translation_stats_view.dart

@ -4,7 +4,6 @@ import 'package:get/get.dart';
import '../controllers/translation_stats_controller.dart';
import '../../../core/theme/app_colors.dart';
/// 翻译统计页面
class TranslationStatsView extends GetView<TranslationStatsController> {
const TranslationStatsView({Key? key}) : super(key: key);
@ -21,7 +20,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
);
}
/// 构建应用栏
PreferredSizeWidget _buildAppBar(bool isDarkMode) {
return AppBar(
leading: IconButton(
@ -35,7 +33,7 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
backgroundColor: isDarkMode ? AppColors.darkBackground : Colors.white,
elevation: 0.5,
title: Text(
'翻译统计', // translationStats
'翻译统计',
style: TextStyle(
fontSize: 17.sp,
fontWeight: FontWeight.w600,
@ -44,7 +42,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
),
centerTitle: true,
actions: [
// 刷新按钮
IconButton(
icon: Icon(
Icons.refresh,
@ -52,7 +49,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
),
onPressed: controller.refreshData,
),
// 更多操作菜单
PopupMenuButton<String>(
icon: Icon(
Icons.more_vert,
@ -68,12 +64,12 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
break;
}
},
itemBuilder: (context) => [
const PopupMenuItem(
itemBuilder: (context) => const [
PopupMenuItem(
value: 'cleanup',
child: Text('清理过期数据'),
),
const PopupMenuItem(
PopupMenuItem(
value: 'export',
child: Text('导出数据'),
),
@ -83,42 +79,32 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
);
}
/// 构建加载组件
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),
],
),
@ -128,7 +114,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
);
}
/// 构建时间范围选择器
Widget _buildTimeRangeSelector(bool isDarkMode) {
return Container(
margin: EdgeInsets.all(16.w),
@ -137,7 +122,7 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
borderRadius: BorderRadius.circular(12.r),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
color: Colors.black.withValues(alpha: 0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
@ -154,7 +139,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
);
}
/// 构建时间范围标签
Widget _buildTimeRangeTab(String title, int index, bool isDarkMode) {
final isSelected = controller.selectedTabIndex.value == index;
@ -185,7 +169,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
);
}
/// 构建实时统计卡片
Widget _buildRealtimeStatsCard(bool isDarkMode) {
return Container(
padding: EdgeInsets.all(16.w),
@ -194,7 +177,7 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
borderRadius: BorderRadius.circular(12.r),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
color: Colors.black.withValues(alpha: 0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
@ -272,7 +255,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
);
}
/// 构建概览卡片
Widget _buildOverviewCard(bool isDarkMode) {
return Container(
padding: EdgeInsets.all(16.w),
@ -281,7 +263,7 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
borderRadius: BorderRadius.circular(12.r),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
color: Colors.black.withValues(alpha: 0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
@ -358,7 +340,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
);
}
/// 构建统计项
Widget _buildStatItem(
String label, String value, IconData icon, bool isDarkMode) {
return Column(
@ -389,7 +370,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
);
}
/// 构建API调用统计卡片
Widget _buildApiCallsCard(bool isDarkMode) {
return Container(
padding: EdgeInsets.all(16.w),
@ -398,7 +378,7 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
borderRadius: BorderRadius.circular(12.r),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
color: Colors.black.withValues(alpha: 0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
@ -452,7 +432,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
);
}
/// 构建API调用行
Widget _buildApiCallRow(
String label, int count, IconData icon, bool isDarkMode) {
return Row(
@ -484,7 +463,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
);
}
/// 构建数据量统计卡片
Widget _buildDataVolumeCard(bool isDarkMode) {
return Container(
padding: EdgeInsets.all(16.w),
@ -493,7 +471,7 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
borderRadius: BorderRadius.circular(12.r),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
color: Colors.black.withValues(alpha: 0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
@ -575,7 +553,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
);
}
/// 构建成本统计卡片
Widget _buildCostCard(bool isDarkMode) {
return Container(
padding: EdgeInsets.all(16.w),
@ -584,7 +561,7 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
borderRadius: BorderRadius.circular(12.r),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
color: Colors.black.withValues(alpha: 0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
@ -614,11 +591,10 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
SizedBox(height: 16.h),
Obx(() => Column(
children: [
// 当前成本
Container(
padding: EdgeInsets.all(12.w),
decoration: BoxDecoration(
color: AppColors.primary.withOpacity(0.1),
color: AppColors.primary.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(8.r),
),
child: Row(
@ -645,7 +621,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
),
),
SizedBox(height: 12.h),
// 预警阈值
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@ -694,7 +669,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
);
}
/// 构建使用行为统计卡片
Widget _buildUsageBehaviorCard(bool isDarkMode) {
return Container(
padding: EdgeInsets.all(16.w),
@ -703,7 +677,7 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
borderRadius: BorderRadius.circular(12.r),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
color: Colors.black.withValues(alpha: 0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
@ -733,7 +707,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
SizedBox(height: 16.h),
Obx(() => Column(
children: [
// 最常用语言对
_buildUsageBehaviorRow(
'最常用语言对',
controller.currentStats.mostUsedLanguagePair,
@ -741,7 +714,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
isDarkMode,
),
SizedBox(height: 12.h),
// 最常用翻译模式
_buildUsageBehaviorRow(
'最常用模式',
controller.currentStats.mostUsedMode,
@ -755,7 +727,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
);
}
/// 构建使用行为行
Widget _buildUsageBehaviorRow(
String label, String value, IconData icon, bool isDarkMode) {
return Row(

4
lib/routes/app_pages.dart

@ -34,8 +34,8 @@ import '../modules/timbre/views/timbre_view.dart';
import '../modules/translation/views/translation_view.dart';
import '../modules/translation/bindings/translation_binding.dart';
import '../modules/translation/views/translation_history_view.dart';
import '../modules/translation/views/translation_stats_view.dart';
import '../modules/translation/bindings/translation_stats_binding.dart';
import '../modules/usage/views/translation_stats_view.dart';
import '../modules/usage/bindings/translation_stats_binding.dart';
import '../modules/translation/bindings/translation_list_binding.dart';
import '../modules/translation/views/translation_list_view.dart';
import '../modules/translation/bindings/translation_history_binding.dart';

Loading…
Cancel
Save