Browse Source

Merge branch 'liwei' of https://github.com/deepcloud2048/deep_voice into liwei

newdev_shunjiawei
liwei1dao 11 months ago
parent
commit
db7a50dc68
  1. 19
      lib/modules/usage/controllers/translation_stats_controller.dart
  2. 29
      lib/modules/usage/controllers/usage_controller.dart
  3. 6
      lib/modules/usage/views/aichat_stats_view.dart
  4. 121
      lib/modules/usage/views/meeting_stats_view.dart
  5. 151
      lib/modules/usage/views/translation_stats_view.dart
  6. 32
      lib/modules/usage/views/usage_view.dart

19
lib/modules/usage/controllers/translation_stats_controller.dart

@ -2,6 +2,7 @@ import 'package:get/get.dart';
import '../../../data/services/usage_stats_service.dart';
import '../../../data/models/translation_usage_stats.dart';
import '../../../core/utils/logger.dart';
import 'usage_controller.dart';
class TranslationStatsController extends GetxController {
final UsageStatsService _usageService = Get.find<UsageStatsService>();
@ -297,6 +298,24 @@ class TranslationStatsController extends GetxController {
return '¥${cost.toStringAsFixed(2)}';
}
int _titleTapCount = 0;
int _lastTitleTapTs = 0;
void onTitleTap() {
final now = DateTime.now().millisecondsSinceEpoch;
if (now - _lastTitleTapTs <= 800) {
_titleTapCount++;
} else {
_titleTapCount = 1;
}
_lastTitleTapTs = now;
if (_titleTapCount >= 3) {
_titleTapCount = 0;
final uc = Get.find<UsageController>();
uc.toggleAiChat(!uc.showAiChat.value);
}
}
String formatNumber(int number) {
if (number < 1000) {
return number.toString();

29
lib/modules/usage/controllers/usage_controller.dart

@ -8,15 +8,34 @@ class UsageController extends GetxController {
late PageController pageController;
final RxInt pageIndex = 0.obs;
final List<Widget> pageList = const [
AiChatStatsView(),
TranslationStatsView(),
MeetingStatsView(),
];
final RxBool showAiChat = false.obs;
List<Widget> get pageList => showAiChat.value
? const [
AiChatStatsView(),
TranslationStatsView(),
MeetingStatsView(),
]
: const [
TranslationStatsView(),
MeetingStatsView(),
];
@override
void onInit() {
super.onInit();
pageController = PageController(initialPage: 0);
}
void toggleAiChat(bool enable) {
if (showAiChat.value == enable) return;
showAiChat.value = enable;
final int maxIndex = pageList.length - 1;
if (pageIndex.value > maxIndex) {
pageIndex.value = maxIndex;
pageController.jumpToPage(maxIndex);
} else {
pageController.jumpToPage(pageIndex.value);
}
}
}

6
lib/modules/usage/views/aichat_stats_view.dart

@ -40,6 +40,12 @@ class AiChatStatsView extends GetView<AiChatStatsController> {
}
Widget _buildBody(bool isDarkMode) {
return Column(
children: [_buildIntegralRow(isDarkMode)],
);
}
Widget _buildIntegralRow(bool isDarkMode) {
return Obx(() {
final _ = User.refreshTick.value;
final u = User.instance;

121
lib/modules/usage/views/meeting_stats_view.dart

@ -51,14 +51,13 @@ class MeetingStatsView extends GetView<MeetingStatsController> {
Widget _buildBody(bool isDarkMode) {
return Column(
children: [
_buildIntegralRow(isDarkMode),
_buildTimeRangeSelector(isDarkMode),
Expanded(
child: SingleChildScrollView(
padding: EdgeInsets.all(16.w),
child: Column(
children: [
_buildIntegralCard(isDarkMode),
SizedBox(height: 16.h),
_buildOverviewCard(isDarkMode),
],
),
@ -68,6 +67,51 @@ class MeetingStatsView extends GetView<MeetingStatsController> {
);
}
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(
'会议积分',
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 _buildTimeRangeSelector(bool isDarkMode) {
return Container(
margin: EdgeInsets.all(16.w),
@ -212,77 +256,4 @@ class MeetingStatsView extends GetView<MeetingStatsController> {
],
);
}
Widget _buildIntegralCard(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.withValues(alpha: 0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.stacked_line_chart,
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(() {
final _ = User.refreshTick.value;
final u = User.instance;
return _buildIntegralRow(
'会议',
'${controller.formatNumber(u.meetintegral)}/${controller.formatNumber(u.meettotalintegral)}',
Icons.people,
isDarkMode,
);
}),
],
),
);
}
Widget _buildIntegralRow(
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),
),
],
);
}
}

151
lib/modules/usage/views/translation_stats_view.dart

@ -33,12 +33,15 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
),
backgroundColor: isDarkMode ? AppColors.darkBackground : Colors.white,
elevation: 0.5,
title: Text(
'翻译统计',
style: TextStyle(
fontSize: 17.sp,
fontWeight: FontWeight.w600,
color: isDarkMode ? Colors.white : Colors.black,
title: GestureDetector(
onTap: controller.onTitleTap,
child: Text(
'翻译统计',
style: TextStyle(
fontSize: 17.sp,
fontWeight: FontWeight.w600,
color: isDarkMode ? Colors.white : Colors.black,
),
),
),
centerTitle: true,
@ -89,14 +92,15 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
Widget _buildBody(bool isDarkMode) {
return Column(
children: [
_buildIntegralRow(isDarkMode),
_buildTimeRangeSelector(isDarkMode),
Expanded(
child: SingleChildScrollView(
padding: EdgeInsets.all(16.w),
child: Column(
children: [
_buildIntegralCard(isDarkMode),
SizedBox(height: 16.h),
// _buildIntegralCard(isDarkMode),
// SizedBox(height: 16.h),
if (controller.selectedTabIndex.value == 0)
_buildRealtimeStatsCard(isDarkMode),
SizedBox(height: 16.h),
@ -115,6 +119,51 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
);
}
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.translate, color: AppColors.primary, size: 20.sp),
SizedBox(width: 8.w),
Expanded(
child: Text(
'翻译积分',
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color: isDarkMode ? Colors.white : Colors.black),
),
),
Text(
'${u.tradeintegral}/${u.tradetotalintegral}',
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color: isDarkMode ? Colors.white : Colors.black),
),
],
),
),
);
});
}
Widget _buildTimeRangeSelector(bool isDarkMode) {
return Container(
margin: EdgeInsets.all(16.w),
@ -424,92 +473,6 @@ class TranslationStatsView extends GetView<TranslationStatsController> {
);
}
Widget _buildIntegralCard(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.withValues(alpha: 0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
Icons.stacked_line_chart,
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(() {
final _ = User.refreshTick.value;
final u = User.instance;
return Column(
children: [
_buildIntegralRow(
'翻译',
'${controller.formatNumber(u.tradeintegral)}/${controller.formatNumber(u.tradetotalintegral)}',
Icons.translate,
isDarkMode,
),
],
);
}),
],
),
);
}
Widget _buildIntegralRow(
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,
),
),
],
);
}
Widget _buildApiCallRow(
String label, int count, IconData icon, bool isDarkMode) {
return Row(

32
lib/modules/usage/views/usage_view.dart

@ -7,13 +7,6 @@ import '../controllers/usage_controller.dart';
class UsageView extends GetView<UsageController> {
const UsageView({super.key});
// 1. 将导航栏配置提取为常量,提高可维护性
static const _navItems = [
_NavItem(Icons.chat_bubble_outline, 'AI chat'),
_NavItem(Icons.translate, 'interpretation'),
_NavItem(Icons.people, 'meeting'),
];
// 2. 颜色配置集中管理
Color _getBgColor(bool isDark) =>
isDark ? Colors.black : const Color(0xFFF9FAFB);
@ -28,11 +21,11 @@ class UsageView extends GetView<UsageController> {
return Scaffold(
backgroundColor: isDarkMode ? AppColors.darkBackground : Colors.grey[50],
body: PageView(
physics: const NeverScrollableScrollPhysics(),
controller: controller.pageController,
children: controller.pageList,
),
body: Obx(() => PageView(
physics: const NeverScrollableScrollPhysics(),
controller: controller.pageController,
children: controller.pageList,
)),
bottomNavigationBar: Obx(
() {
final currentIndex = controller.pageIndex.value;
@ -48,7 +41,16 @@ class UsageView extends GetView<UsageController> {
// 3. 添加安全区域适配(针对刘海屏)
child: BottomNavigationBar(
// 4. 使用生成的导航项
items: _navItems
items: (controller.showAiChat.value
? const [
_NavItem(Icons.chat_bubble_outline, 'AI chat'),
_NavItem(Icons.translate, 'interpretation'),
_NavItem(Icons.people, 'meeting'),
]
: const [
_NavItem(Icons.translate, 'interpretation'),
_NavItem(Icons.people, 'meeting'),
])
.map((item) => BottomNavigationBarItem(
icon: Icon(item.icon),
activeIcon: Icon(item.icon,
@ -70,8 +72,8 @@ class UsageView extends GetView<UsageController> {
type: BottomNavigationBarType.fixed,
// 7. 增加图标和文字的间距
iconSize: 22.w, // 响应式图标尺寸
selectedLabelStyle: TextStyle(height: 1.5), // 文字垂直间距
unselectedLabelStyle: TextStyle(height: 1.5),
selectedLabelStyle: TextStyle(height: 1.5.sp), // 文字垂直间距
unselectedLabelStyle: TextStyle(height: 1.5.sp),
),
);
},

Loading…
Cancel
Save