|
|
|
@ -24,6 +24,14 @@ class TranslationStatsView extends GetView<TranslationStatsController> { |
|
|
|
/// 构建应用栏 |
|
|
|
PreferredSizeWidget _buildAppBar(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( |
|
|
|
@ -136,20 +144,20 @@ class TranslationStatsView extends GetView<TranslationStatsController> { |
|
|
|
], |
|
|
|
), |
|
|
|
child: Obx(() => Row( |
|
|
|
children: [ |
|
|
|
_buildTimeRangeTab('今日', 0, isDarkMode), |
|
|
|
_buildTimeRangeTab('本周', 1, isDarkMode), |
|
|
|
_buildTimeRangeTab('本月', 2, isDarkMode), |
|
|
|
_buildTimeRangeTab('历史', 3, isDarkMode), |
|
|
|
], |
|
|
|
)), |
|
|
|
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), |
|
|
|
@ -215,49 +223,50 @@ class TranslationStatsView extends GetView<TranslationStatsController> { |
|
|
|
), |
|
|
|
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, |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
)), |
|
|
|
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, |
|
|
|
children: [ |
|
|
|
Expanded( |
|
|
|
child: _buildStatItem( |
|
|
|
'字符数', |
|
|
|
controller.formatNumber( |
|
|
|
controller.realtimeStats.sourceCharacters + |
|
|
|
controller.realtimeStats.targetCharacters, |
|
|
|
), |
|
|
|
Icons.text_fields, |
|
|
|
isDarkMode, |
|
|
|
), |
|
|
|
), |
|
|
|
Icons.text_fields, |
|
|
|
isDarkMode, |
|
|
|
), |
|
|
|
), |
|
|
|
Expanded( |
|
|
|
child: _buildStatItem( |
|
|
|
'录音时长', |
|
|
|
controller.formatDuration(controller.realtimeStats.recordingDuration), |
|
|
|
Icons.mic, |
|
|
|
isDarkMode, |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
)), |
|
|
|
Expanded( |
|
|
|
child: _buildStatItem( |
|
|
|
'录音时长', |
|
|
|
controller.formatDuration( |
|
|
|
controller.realtimeStats.recordingDuration), |
|
|
|
Icons.mic, |
|
|
|
isDarkMode, |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
)), |
|
|
|
], |
|
|
|
), |
|
|
|
); |
|
|
|
@ -290,64 +299,68 @@ class TranslationStatsView extends GetView<TranslationStatsController> { |
|
|
|
), |
|
|
|
SizedBox(width: 8.w), |
|
|
|
Obx(() => Text( |
|
|
|
'${controller.selectedTimeRange.value}概览', |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 16.sp, |
|
|
|
fontWeight: FontWeight.w600, |
|
|
|
color: isDarkMode ? Colors.white : Colors.black, |
|
|
|
), |
|
|
|
)), |
|
|
|
'${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, |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
)), |
|
|
|
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, |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
)), |
|
|
|
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) { |
|
|
|
Widget _buildStatItem( |
|
|
|
String label, String value, IconData icon, bool isDarkMode) { |
|
|
|
return Column( |
|
|
|
children: [ |
|
|
|
Icon( |
|
|
|
@ -414,23 +427,34 @@ class TranslationStatsView extends GetView<TranslationStatsController> { |
|
|
|
), |
|
|
|
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), |
|
|
|
], |
|
|
|
)), |
|
|
|
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) { |
|
|
|
Widget _buildApiCallRow( |
|
|
|
String label, int count, IconData icon, bool isDarkMode) { |
|
|
|
return Row( |
|
|
|
children: [ |
|
|
|
Icon( |
|
|
|
@ -498,50 +522,54 @@ class TranslationStatsView extends GetView<TranslationStatsController> { |
|
|
|
), |
|
|
|
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, |
|
|
|
), |
|
|
|
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, |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
Expanded( |
|
|
|
child: _buildStatItem( |
|
|
|
'总会话时长', |
|
|
|
controller.formatDuration(controller.currentStats.totalSessionDuration), |
|
|
|
Icons.volume_up, |
|
|
|
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, |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
], |
|
|
|
)), |
|
|
|
)), |
|
|
|
], |
|
|
|
), |
|
|
|
); |
|
|
|
@ -585,79 +613,82 @@ 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), |
|
|
|
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, |
|
|
|
// 当前成本 |
|
|
|
Container( |
|
|
|
padding: EdgeInsets.all(12.w), |
|
|
|
decoration: BoxDecoration( |
|
|
|
color: AppColors.primary.withOpacity(0.1), |
|
|
|
borderRadius: BorderRadius.circular(8.r), |
|
|
|
), |
|
|
|
), |
|
|
|
Text( |
|
|
|
controller.formatCost(controller.dailyCostThreshold.value), |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 12.sp, |
|
|
|
color: isDarkMode ? Colors.white70 : Colors.black54, |
|
|
|
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: 4.h), |
|
|
|
Row( |
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|
|
|
children: [ |
|
|
|
Text( |
|
|
|
'月成本预警阈值', |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 12.sp, |
|
|
|
color: isDarkMode ? Colors.white70 : Colors.black54, |
|
|
|
), |
|
|
|
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, |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
Text( |
|
|
|
controller.formatCost(controller.monthlyCostThreshold.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, |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
], |
|
|
|
)), |
|
|
|
)), |
|
|
|
], |
|
|
|
), |
|
|
|
); |
|
|
|
@ -701,31 +732,32 @@ class TranslationStatsView extends GetView<TranslationStatsController> { |
|
|
|
), |
|
|
|
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, |
|
|
|
), |
|
|
|
], |
|
|
|
)), |
|
|
|
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) { |
|
|
|
Widget _buildUsageBehaviorRow( |
|
|
|
String label, String value, IconData icon, bool isDarkMode) { |
|
|
|
return Row( |
|
|
|
children: [ |
|
|
|
Icon( |
|
|
|
|