From 41923ec2e6cb65228d262d0cd3e0d2fbcf5bea9e Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Mon, 27 Oct 2025 11:15:07 +0800 Subject: [PATCH] =?UTF-8?q?feat(translation):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=BF=BB=E8=AF=91=E4=B8=AD=E9=97=B4=E5=B1=82=E4=BD=9C=E4=B8=BA?= =?UTF-8?q?=E7=BB=9F=E4=B8=80=E5=8A=9F=E8=83=BD=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 实现翻译功能中间层页面,提供四种翻译模式的统一入口 添加翻译中间层控制器、视图和绑定 更新路由配置和国际化文本 修改原有翻译功能跳转逻辑使用中间层入口 --- lib/core/translations/language/en_us.dart | 10 + lib/core/translations/language/zh_cn.dart | 10 + .../controllers/explore_controller.dart | 4 +- .../home/controllers/home_controller.dart | 2 +- .../controllers/translation_controller.dart | 4 + .../translation_middleware_binding.dart | 11 + .../translation_middleware_controller.dart | 78 +++++++ .../views/translation_middleware_view.dart | 204 ++++++++++++++++++ lib/routes/app_pages.dart | 9 + lib/routes/app_routes.dart | 3 +- 10 files changed, 331 insertions(+), 4 deletions(-) create mode 100644 lib/modules/translation/middleware/bindings/translation_middleware_binding.dart create mode 100644 lib/modules/translation/middleware/controllers/translation_middleware_controller.dart create mode 100644 lib/modules/translation/middleware/views/translation_middleware_view.dart diff --git a/lib/core/translations/language/en_us.dart b/lib/core/translations/language/en_us.dart index a68fdf01c..e262e13e1 100644 --- a/lib/core/translations/language/en_us.dart +++ b/lib/core/translations/language/en_us.dart @@ -976,6 +976,16 @@ const Map enUS = { "萨摩亚": "Samoa", // 翻译模块 + // 翻译中间层 (translation_middleware_view.dart) + "translationCenter": "Translation Center", // 翻译中心 + "translationCenterDescription": "Select the translation feature you need", // 选择您需要的翻译功能 + "realtimeTranslation": "Realtime Translation", // 实时翻译 + "realtimeTranslationDescription": "Real-time voice translation, supports multiple languages", // 实时语音翻译,支持多种语言 + "translationHistoryTitle": "Translation History", // 翻译历史 + "translationHistoryDescription": "View historical translation records", // 查看历史翻译记录 + "translationStatsTitle": "Translation Statistics", // 翻译统计 + "translationStatsDescription": "View translation usage statistics", // 查看翻译使用统计信息 + // 翻译主页 "translationHistory": "Translation History", "enableRecording": "Enable Recording", diff --git a/lib/core/translations/language/zh_cn.dart b/lib/core/translations/language/zh_cn.dart index 37740085c..6de0eeb54 100644 --- a/lib/core/translations/language/zh_cn.dart +++ b/lib/core/translations/language/zh_cn.dart @@ -896,6 +896,16 @@ const Map zhCN = { "萨摩亚": "萨摩亚", // 翻译模块 + // 翻译中间层 (translation_middleware_view.dart) + "translationCenter": "翻译中心", // 翻译中心 + "translationCenterDescription": "选择您需要的翻译功能", // 选择您需要的翻译功能 + "realtimeTranslation": "实时翻译", // 实时翻译 + "realtimeTranslationDescription": "实时语音翻译,支持多种语言", // 实时语音翻译,支持多种语言 + "translationHistoryTitle": "翻译历史", // 翻译历史 + "translationHistoryDescription": "查看历史翻译记录", // 查看历史翻译记录 + "translationStatsTitle": "翻译统计", // 翻译统计 + "translationStatsDescription": "查看翻译使用统计信息", // 查看翻译使用统计信息 + // 翻译主页 (translation_view.dart) "translationHistory": "翻译历史", "enableRecording": "是否开启录音", diff --git a/lib/modules/explore/controllers/explore_controller.dart b/lib/modules/explore/controllers/explore_controller.dart index e03ed7d1d..ffb276c59 100644 --- a/lib/modules/explore/controllers/explore_controller.dart +++ b/lib/modules/explore/controllers/explore_controller.dart @@ -73,7 +73,7 @@ class ExploreController extends GetxController { iconBgColor: const Color(0xFF4CAF50).withOpacity(0.2), iconColor: const Color(0xFF4CAF50), agentId: 'simultaneous_interpreter', - targetRoute: Routes.translation, + targetRoute: Routes.translationMiddleware, ), // AIFeature( // title: 'conferenceAssistant'.tr, // 商务会议助手 @@ -197,7 +197,7 @@ class ExploreController extends GetxController { 'systemPrompt': agent.systemPrompt, 'welcomeMessage': agent.welcomeMessage, }); - } else if (feature.targetRoute == Routes.translation) { + } else if (feature.targetRoute == Routes.translationMiddleware) { // 跳转到翻译页面 Get.toNamed(feature.targetRoute); } else if (feature.targetRoute == Routes.agent) { diff --git a/lib/modules/home/controllers/home_controller.dart b/lib/modules/home/controllers/home_controller.dart index 7d8aa47af..112974651 100644 --- a/lib/modules/home/controllers/home_controller.dart +++ b/lib/modules/home/controllers/home_controller.dart @@ -185,7 +185,7 @@ class HomeController extends GetxController { } void openTranslation() { - Get.toNamed(Routes.translation); + Get.toNamed(Routes.translationMiddleware); } void exploreAIFeatures() { diff --git a/lib/modules/translation/controllers/translation_controller.dart b/lib/modules/translation/controllers/translation_controller.dart index 37e624063..5543ebacb 100644 --- a/lib/modules/translation/controllers/translation_controller.dart +++ b/lib/modules/translation/controllers/translation_controller.dart @@ -372,6 +372,10 @@ class TranslationController extends GetxController with WidgetsBindingObserver { _timerManager = RecordTimerController(); _historyManager = TranslationHistoryManager(); + // 初始化翻译模式,根据跳转参数 + final mode = Get.arguments?['translationId'] ?? 'simultaneous'; + changeTranslationMode(mode); + // 初始化悬浮窗管理器 _initFloatingWindowManager(); diff --git a/lib/modules/translation/middleware/bindings/translation_middleware_binding.dart b/lib/modules/translation/middleware/bindings/translation_middleware_binding.dart new file mode 100644 index 000000000..8f8662854 --- /dev/null +++ b/lib/modules/translation/middleware/bindings/translation_middleware_binding.dart @@ -0,0 +1,11 @@ +import 'package:get/get.dart'; +import '../controllers/translation_middleware_controller.dart'; + +/// 翻译中间层页面依赖绑定 +class TranslationMiddlewareBinding extends Bindings { + @override + void dependencies() { + // 注册翻译中间层控制器 + Get.lazyPut(() => TranslationMiddlewareController()); + } +} \ No newline at end of file diff --git a/lib/modules/translation/middleware/controllers/translation_middleware_controller.dart b/lib/modules/translation/middleware/controllers/translation_middleware_controller.dart new file mode 100644 index 000000000..5ead3399a --- /dev/null +++ b/lib/modules/translation/middleware/controllers/translation_middleware_controller.dart @@ -0,0 +1,78 @@ +import 'package:get/get.dart'; +import 'package:flutter/material.dart'; +import '../../../../routes/app_routes.dart'; + +/// 翻译中间层控制器 +/// 负责管理翻译功能入口的导航和状态 +class TranslationMiddlewareController extends GetxController { + /// 翻译功能选项列表 + final List translationOptions = [ + TranslationOption( + translationId: 'simultaneous', + title: 'simultaneousTranslation', // 实时翻译 + description: 'realtimeTranslationDescription', // 实时语音翻译,支持多种语言 + icon: Icons.record_voice_over, + iconColor: 0xFF2196F3, // 蓝色 + targetRoute: Routes.translation, + ), + TranslationOption( + translationId: 'call', + title: 'callTranslation', // 电话翻译 + description: 'simultaneousTranslationInfo', // 双向对话翻译,面对面交流 + icon: Icons.call, + iconColor: 0xFF4CAF50, // 绿色 + targetRoute: Routes.translation, + ), + TranslationOption( + translationId: 'faceToFace', + title: 'faceToFaceTranslation', // 面对面翻译 + description: 'faceToFaceTranslationDescription', // 面对面交流,支持多种语言 + icon: Icons.people, + iconColor: 0xFFFF9800, // 橙色 + targetRoute: Routes.translation, + ), + TranslationOption( + translationId: 'audioVideo', + title: 'audioVideoTranslation', // 音频视频翻译 + description: 'audioVideoTranslationDescription', // 支持音频和视频翻译 + icon: Icons.videocam, + iconColor: 0xFF9C27B0, // 紫色 + targetRoute: Routes.translation, + ), + ]; + + /// 导航到指定的翻译功能 + void navigateToTranslationFeature(TranslationOption option) { + Get.toNamed(option.targetRoute, + arguments: {'translationId': option.translationId}); + } + + /// 获取翻译选项的本地化标题 + String getLocalizedTitle(TranslationOption option) { + return option.title.tr; + } + + /// 获取翻译选项的本地化描述 + String getLocalizedDescription(TranslationOption option) { + return option.description.tr; + } +} + +/// 翻译功能选项数据模型 +class TranslationOption { + final String translationId; + final String title; + final String description; + final IconData icon; + final int iconColor; + final String targetRoute; + + TranslationOption({ + required this.translationId, + required this.title, + required this.description, + required this.icon, + required this.iconColor, + required this.targetRoute, + }); +} diff --git a/lib/modules/translation/middleware/views/translation_middleware_view.dart b/lib/modules/translation/middleware/views/translation_middleware_view.dart new file mode 100644 index 000000000..85c580eda --- /dev/null +++ b/lib/modules/translation/middleware/views/translation_middleware_view.dart @@ -0,0 +1,204 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import '../controllers/translation_middleware_controller.dart'; +import '../../../../core/theme/app_colors.dart'; + +/// 翻译中间层视图 +/// 展示四种翻译功能的入口选项 +class TranslationMiddlewareView + extends GetView { + const TranslationMiddlewareView({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(isDarkMode), + body: _buildBody(isDarkMode), + ); + } + + /// 构建应用栏 + PreferredSizeWidget _buildAppBar(bool isDarkMode) { + return AppBar( + backgroundColor: isDarkMode ? AppColors.darkBackground : Colors.white, + elevation: 0, + centerTitle: true, + leading: IconButton( + icon: Icon( + Icons.arrow_back_ios, + color: isDarkMode ? Colors.white : Colors.black, + size: 20.sp, + ), + onPressed: () => Get.back(), + ), + title: Text( + 'translationServices'.tr, // 翻译服务 + style: TextStyle( + fontSize: 20.sp, + fontWeight: FontWeight.bold, + color: isDarkMode ? Colors.white : Colors.black, + ), + ), + ); + } + + /// 构建主体内容 + Widget _buildBody(bool isDarkMode) { + return SafeArea( + child: Padding( + padding: EdgeInsets.all(20.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 页面标题和描述 + // _buildHeader(isDarkMode), + // SizedBox(height: 30.h), + + // 翻译功能选项网格 + Expanded( + child: _buildTranslationOptionsGrid(isDarkMode), + ), + ], + ), + ), + ); + } + + /// 构建页面头部 + Widget _buildHeader(bool isDarkMode) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'chooseTranslationService'.tr, // 选择翻译服务 + style: TextStyle( + fontSize: 24.sp, + fontWeight: FontWeight.bold, + color: isDarkMode ? Colors.white : Colors.black87, + ), + ), + SizedBox(height: 8.h), + Text( + 'translationServiceDescription'.tr, // 选择适合您需求的翻译功能 + style: TextStyle( + fontSize: 16.sp, + color: isDarkMode ? Colors.grey[300] : Colors.grey[600], + height: 1.4, + ), + ), + ], + ); + } + + /// 构建翻译选项网格 + Widget _buildTranslationOptionsGrid(bool isDarkMode) { + return GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 16.w, + mainAxisSpacing: 16.h, + childAspectRatio: 0.85, + ), + itemCount: controller.translationOptions.length, + itemBuilder: (context, index) { + final option = controller.translationOptions[index]; + return _buildTranslationOptionCard(option, isDarkMode); + }, + ); + } + + /// 构建单个翻译选项卡片 + Widget _buildTranslationOptionCard( + TranslationOption option, + bool isDarkMode, + ) { + return GestureDetector( + onTap: () => controller.navigateToTranslationFeature(option), + child: Container( + decoration: BoxDecoration( + color: isDarkMode ? AppColors.cardBackground : Colors.white, + borderRadius: BorderRadius.circular(16.r), + boxShadow: [ + BoxShadow( + color: isDarkMode + ? Colors.black.withOpacity(0.3) + : Colors.grey.withOpacity(0.1), + blurRadius: 8, + offset: const Offset(0, 2), + ), + ], + ), + child: Padding( + padding: EdgeInsets.all(20.w), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // 图标 + Container( + width: 60.w, + height: 60.h, + decoration: BoxDecoration( + color: Color(option.iconColor).withOpacity(0.1), + borderRadius: BorderRadius.circular(16.r), + ), + child: Icon( + option.icon, + size: 32.sp, + color: Color(option.iconColor), + ), + ), + SizedBox(height: 16.h), + + // 标题 + Text( + controller.getLocalizedTitle(option), + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.bold, + color: isDarkMode ? Colors.white : Colors.black87, + ), + textAlign: TextAlign.center, + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + SizedBox(height: 8.h), + + // 描述 + Text( + controller.getLocalizedDescription(option), + style: TextStyle( + fontSize: 12.sp, + color: isDarkMode ? Colors.grey[400] : Colors.grey[600], + height: 1.3, + ), + textAlign: TextAlign.center, + maxLines: 3, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + ), + ); + } + + /// 根据图标名称获取图标数据 + IconData _getIconData(String iconName) { + switch (iconName) { + case 'translate': + return Icons.translate; + case 'people': + return Icons.people; + case 'history': + return Icons.history; + case 'bar_chart': + return Icons.bar_chart; + default: + return Icons.help_outline; + } + } +} diff --git a/lib/routes/app_pages.dart b/lib/routes/app_pages.dart index 6e1082812..234fc6d38 100644 --- a/lib/routes/app_pages.dart +++ b/lib/routes/app_pages.dart @@ -65,6 +65,8 @@ import '../modules/FTFTranslation/bindings/FTFTranslation_binding.dart'; import '../modules/FTFTranslation/views/FTFTranslation_view.dart'; import '../modules/payment/bindings/payment_binding.dart'; import '../modules/payment/views/payment_view.dart'; +import '../modules/translation/middleware/views/translation_middleware_view.dart'; +import '../modules/translation/middleware/bindings/translation_middleware_binding.dart'; abstract class AppPages { static final pages = [ @@ -148,6 +150,13 @@ abstract class AppPages { transition: Transition.rightToLeft, transitionDuration: Duration(milliseconds: 250), ), + GetPage( + name: Routes.translationMiddleware, + page: () => const TranslationMiddlewareView(), + binding: TranslationMiddlewareBinding(), + transition: Transition.rightToLeft, + transitionDuration: Duration(milliseconds: 250), + ), GetPage( name: Routes.translation, page: () => const TranslationView(), diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index f2e78cbf6..da88b0ed7 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -26,6 +26,7 @@ abstract class Routes { static const meetingConnect = '/meeting/connect'; static const meetingRecord = '/meeting/record'; // 语言功能 + static const translationMiddleware = '/translationMiddleware'; // 翻译中间层(统一入口) static const translation = '/translation'; // 实时翻译 static const translationHistory = '/translation/history'; // 翻译历史 static const translationStats = '/translation/stats'; // 翻译统计 @@ -63,7 +64,7 @@ abstract class Routes { static const ble = '/ble'; // ble设备管理 static const qqmusic = '/qqmusic'; - + // 支付相关 static const payment = '/payment'; // 支付测试页面 }