From 6c3152bbaa2dfde637e4c0f6f63c8d3342dd08d4 Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Tue, 8 Jul 2025 20:24:58 +0800 Subject: [PATCH] =?UTF-8?q?refactor(i18n):=20=E9=87=8D=E6=9E=84=E5=9B=BD?= =?UTF-8?q?=E9=99=85=E5=8C=96=E5=AD=97=E7=AC=A6=E4=B8=B2=E5=B9=B6=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E7=BF=BB=E8=AF=91=E9=94=AE=E5=91=BD=E5=90=8D=E8=A7=84?= =?UTF-8?q?=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将硬编码的中文字符串替换为国际化翻译键 统一翻译键命名规范,按模块分类组织 添加缺失的英文翻译字符串 优化部分翻译键的命名以更好表达用途 --- lib/core/translations/language/en_us.dart | 199 +++++++++++++++++- lib/core/translations/language/zh_cn.dart | 176 +++++++++++++++- .../agent/controllers/agent_controller.dart | 42 ++-- .../message_action_controller.dart | 52 +++-- lib/modules/agent/views/agent_view.dart | 78 +++---- lib/modules/agent/views/message_bubble.dart | 2 +- lib/modules/agent/views/music_card.dart | 10 +- lib/modules/agent/views/navigation_card.dart | 87 ++++---- lib/modules/agent/views/weather_card.dart | 72 ++++--- .../agent/widgets/full_screen_editor.dart | 5 +- .../common/widgets/version_update_dialog.dart | 18 +- .../ota_upgrade/views/ota_upgrade_view.dart | 4 +- .../controllers/pairing_controller.dart | 73 ++++--- lib/modules/pairing/views/pairing_view.dart | 7 +- .../controllers/profile_controller.dart | 85 ++++---- 15 files changed, 645 insertions(+), 265 deletions(-) diff --git a/lib/core/translations/language/en_us.dart b/lib/core/translations/language/en_us.dart index 7448fec5e..bc3259891 100644 --- a/lib/core/translations/language/en_us.dart +++ b/lib/core/translations/language/en_us.dart @@ -253,12 +253,123 @@ const Map enUS = { "deviceNotBoundYet": "Device not bound yet", // 还未绑定设备 "unbind": "Unbind", // 解绑 - // 聊天页 +// Agent模块 + //Agent View + "XiaoYan": "XiaoYan", "clearChatHistory": "Clear Chat History", "online": "Online", "inputMessage": "Type a message...", "imListening": "Listening...", "canStartTalking": "You may start speaking", + "addQuestionAboutImage": "Add questions or descriptions about the image...", + "summarizeImageContent": "Summarize image content", + "extractImageText": "Extract image text", + "translateImageText": "Translate image text", + "recording": "Recording...", + "holdToSpeak": "Hold to speak", + "takePhoto": "Take Photo", + "photoAlbum": "Photo Album", + "makeCall": "Make Call", + "aiVoiceCall": "AI Voice Call", + "inCall": "In call...", + "aiReplying": "AI is replying...", + "waitingToStart": "Waiting to start...", + "clickToStartCall": "Click to start call", + "listeningToYou": "Listening to you...", + "processing": "Processing...", + "loadMoreMessages": "Load more messages...", + "loadFailedClickRetry": "Load failed, click to retry", + "swipeUpForMore": "Swipe up for more", + + // Agent Controller + 'welcomeMessage': 'Hello! I\'m **XiaoYan**, I can help you:\n\n' + '• Answer questions and provide information\n\n' + '• Real-time voice translation\n\n' + '• Recommend music and podcasts\n\n' + '• Voice memos and reminders\n\n' + '• Control headset functions\n\n' + 'What can I help you with?', + 'microphonePermission': 'Microphone', + 'voiceRecognitionPermissionText': + 'Voice recognition requires microphone access.', + 'voiceTranslationPermissionText': + 'Voice recognition and translation require microphone access.', + 'phoneCallPermissionText': + 'Phone call function requires microphone access for voice calls.', + 'permissionDeniedText': + 'You have permanently denied microphone permission, please go to system settings to enable it.', + 'startVoiceInput': 'Start voice input', + 'startPhoneCallMode': 'Start phone call mode, begin voice input', + + //Agent 全屏编辑器 + 'fullScreenEditorHint': 'Type your message here...', // 全屏编辑器输入提示 + 'characterCount': '{count} characters', // 字符计数显示 + + // 消息长按操作 + 'copy': 'Copy', + 'copySuccess': 'Copy successful', + 'report': 'Report', + 'submitSuccess': 'Submit successful', + 'submitFailed': 'Submit failed', + 'reportSubmitted': 'Report submitted, we will process it as soon as possible', + //'networkError': 'Network error, please try again later', + 'harmfulUnsafe': 'Harmful/Unsafe', + 'pornographicVulgar': 'Pornographic/Vulgar', + 'misleadingAttack': 'Misleading/Attack', + 'illegalCriminal': 'Illegal/Criminal', + 'privacyRelated': 'Privacy Related', + 'copyrightViolation': 'Infringement of my copyright, reputation rights, etc.', + 'other': 'Other', + 'reportDescriptionHint': + 'We want to know the reason for your report, you can describe the problem you encountered.', + //'submit': 'Submit', + + //Message_bubble + 'generatedByAi': 'Generated by AI', + + //music_card + 'recommendedMusic': 'Here are some recommended music:', + 'playlist': 'Playlist', + 'moreMusic': 'More music', + +//导航卡片 navigation_card + 'kilometers': ' km', // 公里单位 + 'meters': ' m', // 米单位 + 'hours': ' hours', // 小时单位 + 'minutes': ' minutes', // 分钟单位 + 'seconds': ' seconds', // 秒单位 + 'navigating': 'Navigating', // 导航状态 + 'currentLocation': 'Current Location', // 当前位置 + 'approximate': 'About ', // 大约 + 'enterRoad': ' enter ', // 进入道路 + "driving": "Driving", + "walking": "Walking", + "bicycling": "Cycling", + "tsransit": "Transit", + + //天气卡片 weather_card + 'weatherQuery': 'Weather Query:', + 'highest': 'High', + 'lowest': 'Low', + 'futureForecast': 'Future Forecast', + 'hotWeatherTip': + 'Hot weather today, please pay attention to heat prevention and cooling, drink more water to avoid heat stroke', + 'coldWeatherTip': + 'Low temperature today, please keep warm when going out and be careful of catching cold', + 'rainyWeatherTip': + 'Rainy today, please bring rain gear when going out and pay attention to travel safety', + 'snowyWeatherTip': + 'Snowy today, roads are slippery, please pay attention to safety and keep warm', + 'foggyWeatherTip': + 'Foggy and hazy today, low visibility, please wear a mask when going out', + 'windyWeatherTip': + 'Strong wind today, please pay attention to safety when going out and secure items', + 'sunnyWeatherTip': + 'Sunny with strong UV rays today, please protect yourself from the sun when going out', + 'temperatureDifferenceTip': + 'Large temperature difference between day and night today, please adjust clothing accordingly', + 'comfortableWeatherTip': + 'Pleasant weather today, perfect for outdoor activities', // 编辑个人信息页 "editProfile": "Edit Profile", @@ -275,6 +386,38 @@ const Map enUS = { 'deleteAccountTips': 'Are you sure you want to permanently delete your account? This action cannot be undone.', + //Profile 错误信息 + 'networkConnectionFailed': + 'Network connection failed, please check network settings and try again', + 'serverTemporarilyUnavailable': + 'Server temporarily unavailable, please try again later', + 'loginExpiredPleaseRelogin': 'Login expired, please log in again', + 'noPermissionForThisOperation': 'No permission to perform this operation', + 'requestedResourceNotFound': 'Requested resource not found', + 'imageProcessingFailedPleaseReselect': + 'Image processing failed, please select image again', + 'operationFailedPleaseRetry': 'Operation failed, please try again', + 'serverReturnedError': 'Server returned error', + 'serverError': 'Server error', + 'networkConnectionFailedCheckSettings': + 'Network connection failed, please check network settings', + 'serverInternalErrorRetryLater': + 'Server internal error, please try again later', + +//Profile 用户交互 +//'error': 'Error', +//'success': 'Success', + 'imageCompressionFailed': 'Image compression failed', + 'avatarUpdateFailed': 'Avatar update failed', + 'usernameCannotBeEmpty': 'Username cannot be empty', + 'saveSuccess': 'Save Success', + 'personalInfoUpdated': 'Personal information updated', + 'saveFailed': 'Save Failed', + 'loggedOut': 'Logged out', + 'logoutFailedRetry': 'Logout failed, please try again', + 'accountPermanentlyDeleted': 'Account permanently deleted', + 'deleteAccountFailedRetry': 'Delete account failed, please try again', + // 权限管理页面 'getPermissionStatusFailed': 'Failed to get permission status', 'communicationPermissions': 'Communication Permissions', @@ -315,6 +458,17 @@ const Map enUS = { 'You have permanently denied {permission} permission, please go to app settings to enable it', 'goToSettings': 'Go to Settings', + // 版本更新对话框 + 'newVersionFound': 'New Version Found', // 版本更新对话框标题 + 'remindLater': 'Remind Later', // 稍后提醒按钮 + 'updateNow': 'Update Now', // 立即更新按钮 + 'checkUpdate': 'Check Update', // 检查更新按钮 + 'updateFailed': 'Update Failed', // 更新失败提示 + 'cannotOpenAppStore': + 'Cannot open app store, please update manually', // 无法打开应用商店提示 + 'updateErrorRetry': + 'Error occurred during update, please try again later', // 更新错误重试提示 + // 国家列表 "邮箱": "Email", "中国": "China", @@ -423,12 +577,6 @@ const Map enUS = { "斐济": "Fiji", "所罗门群岛": "Solomon Islands", - // 导航 - "driving": "Driving", - "walking": "Walking", - "bicycling": "Cycling", - "tsransit": "Transit", - // 翻译模块 // 翻译主页 "translationHistory": "Translation History", @@ -500,6 +648,7 @@ const Map enUS = { "confirmBinding": "Confirm Binding", "associatingDevice": "Associating device...", "goToBluetoothSettings": "Go to Bluetooth Settings", + 'bluetooth': 'Bluetooth', // 配对状态文本 "readyToPair": "Ready to pair", @@ -525,6 +674,38 @@ const Map enUS = { "Authorization failed, please check authorization code", "pairingFailedRetry": "Pairing failed, please retry", +//配对控制器相关 + //'connectDevice': 'Connect Device', + 'pleaseEnableBluetooth': 'Please enable Bluetooth', + 'deviceDisconnected': 'Device disconnected', + 'readyToStartPairing': 'Ready to start pairing', + 'checkingEnvironment': 'Checking environment...', + 'ensureHeadsetOnAndPairingMode': + 'Please ensure headset is on and in pairing mode', + //'goToBluetoothSettings': 'Go to Bluetooth Settings', + //'verifyingDevice': 'Verifying device...', + //'confirmBinding': 'Confirm Binding', + //'associatingDevice': 'Associating device...', + 'establishingSecureConnection': 'Establishing secure connection...', + 'needManualBindingAuthCode': 'Manual binding authorization code required...', + 'pairingSuccessful': 'Pairing successful!', + 'enableBluetooth': 'Enable Bluetooth', + 'grantPermissions': 'Grant Permissions', + 'retryAssociation': 'Retry Association', + 'retryAuthorization': 'Retry Authorization', + 'pleaseGrantNecessaryPermissions': 'Please grant necessary permissions', + 'checkFailedRetry': 'Check failed, please retry', + 'pleaseConnectDeepSoundDevice': 'Please connect DeepSound device', + 'verificationFailedRetry': 'Verification failed, please retry', + 'invalidDeviceAddress': 'Invalid device address', + 'bleDeviceAssociationFailed': 'BLE device association failed', + 'deviceAssociationFailedRetry': 'Device association failed, please retry', + 'bleConnectionTimeoutRetry': 'BLE connection timeout, please retry', + 'blePairingStartupFailed': 'BLE pairing startup failed', + 'bleConnectionFailed': 'BLE connection failed', + 'deviceAuthorizationFailedCheckCode': + 'Device authorization failed, please check authorization code', + // 用户反馈页 "feedback": "Feedback", 'feedbackInfo': 'Provide feedback or suggestions', @@ -544,13 +725,13 @@ const Map enUS = { "unknownDevice": "Unknown Device", "currentFirmwareVersion": "Current Firmware Version", "latestFirmwareVersion": "Latest Firmware Version", - "newVersionFound": "New Version Found", + "ota_newVersionFound": "New Version Found", "latestVersion": "Latest Version", "gettingDeviceInfo": "Getting device information...", "keepDeviceConnected": "Please keep device connected", "connectionFailed": "Connection Failed", "retryConnection": "Retry Connection", - "updateNow": "Update Now", + "ota_updateNow": "Update Now", "keepConnectedDontClose": "Please keep device connected, do not close the app", "doNotDisconnect": "Do not disconnect", diff --git a/lib/core/translations/language/zh_cn.dart b/lib/core/translations/language/zh_cn.dart index 7579205c8..5d2abdd84 100644 --- a/lib/core/translations/language/zh_cn.dart +++ b/lib/core/translations/language/zh_cn.dart @@ -245,12 +245,109 @@ const Map zhCN = { "deviceNotBoundYet": "还未绑定设备", "unbind": "解绑", - // 聊天页 +//Agent 模块 + // agent View + "XiaoYan": "小言", "clearChatHistory": "清空聊天记录", "online": "在线", "inputMessage": "输入消息...", "imListening": "正在聆听...", "canStartTalking": "你可以开始说话", + "addQuestionAboutImage": "添加对图片的问题或描述...", + "summarizeImageContent": "总结图片内容", + "extractImageText": "抽取图像文字", + "translateImageText": "翻译图像文字", + "recording": "正在录音...", + "holdToSpeak": "按住说话", + "takePhoto": "拍照", + "photoAlbum": "相册", + "makeCall": "打电话", + "aiVoiceCall": "AI语音通话", + "inCall": "正在通话中...", + "aiReplying": "AI正在回复...", + "waitingToStart": "等待开始...", + "clickToStartCall": "点击开始通话", + "listeningToYou": "正在听您说话...", + "processing": "正在处理...", + "loadMoreMessages": "加载更多消息...", + "loadFailedClickRetry": "加载失败,点击重试", + "swipeUpForMore": "向上滑动查看更多", + + // Agent controller + 'welcomeMessage': '你好!我是**小言**,我能帮你:\n\n' + '• 答问题和提供信息\n\n' + '• 实时语音翻译\n\n' + '• 推荐音乐和播客\n\n' + '• 语音备忘录和提醒\n\n' + '• 控制耳机功能\n\n' + '有什么我可以帮你的吗?', + 'microphonePermission': '麦克风', + 'voiceRecognitionPermissionText': '语音识别功能需要访问麦克风。', + 'voiceTranslationPermissionText': '语音识别与翻译功能需要访问麦克风。', + 'phoneCallPermissionText': '打电话功能需要访问麦克风进行语音通话。', + 'permissionDeniedText': '您已永久拒绝麦克风权限,请前往系统设置开启权限。', + 'startVoiceInput': '开始语音输入', + 'startPhoneCallMode': '开始打电话模式,开始语音输入', + + // Agent 全屏编辑器 + 'fullScreenEditorHint': '在这里输入你的消息...', // 全屏编辑器输入提示 + 'characterCount': '{count} 字符', // 字符计数显示 + + // 消息长按操作 + 'copy': '复制', + 'copySuccess': '复制成功', + 'report': '举报', + 'submitSuccess': '提交成功', + 'submitFailed': '提交失败', + 'reportSubmitted': '举报已提交,我们会尽快处理', + //'networkError': '网络错误,请稍后重试', + 'harmfulUnsafe': '有害/不安全', + 'pornographicVulgar': '色情低俗', + 'misleadingAttack': '误导攻击', + 'illegalCriminal': '违法犯罪', + 'privacyRelated': '隐私相关', + 'copyrightViolation': '侵犯我的著作权、名誉权等', + 'other': '其他', + 'reportDescriptionHint': '我们想知道你举报的原因,你可以描述你遇到的问题。', + //'submit': '提交', + + //Message_bubble + 'generatedByAi': '由AI生成', + + //音乐卡片 music_card + 'recommendedMusic': '以下是一些推荐的音乐:', + 'playlist': '播放列表', + 'moreMusic': '更多音乐', + + //导航卡片 navigation_card + 'kilometers': '公里', // 公里单位 + 'meters': '米', // 米单位 + 'hours': '小时', // 小时单位 + 'minutes': '分钟', // 分钟单位 + 'seconds': '秒', // 秒单位 + 'navigating': '导航中', // 导航状态 + 'currentLocation': '当前位置', // 当前位置 + 'approximate': '约', // 大约 + 'enterRoad': '进入', // 进入道路 + "driving": "驾车", + "walking": "步行", + "bicycling": "骑行", + "tsransit": "公交", + + //天气卡片 weather_card + 'weatherQuery': '查询天气情况:', + 'highest': '最高', + 'lowest': '最低', + 'futureForecast': '未来预报', + 'hotWeatherTip': '今日高温炎热,请注意防暑降温,多喝水避免中暑', + 'coldWeatherTip': '今日气温较低,外出请注意保暖,小心感冒', + 'rainyWeatherTip': '今日有雨,外出请携带雨具,注意出行安全', + 'snowyWeatherTip': '今日有雪,路面湿滑请注意安全,做好保暖措施', + 'foggyWeatherTip': '今日有雾霾,能见度较低,外出请佩戴口罩', + 'windyWeatherTip': '今日风力较大,外出请注意安全,固定好物品', + 'sunnyWeatherTip': '今日阳光充足紫外线较强,外出请做好防晒', + 'temperatureDifferenceTip': '今日昼夜温差较大,请适时增减衣物', + 'comfortableWeatherTip': '今日天气适宜,是外出活动的好时光', //编辑个人信息页 "editProfile": "编辑个人信息", @@ -266,6 +363,33 @@ const Map zhCN = { 'deleteAccount': '注销账号', 'deleteAccountTips': '确定要永久删除您的账号吗?此操作不可撤销', + // Profile 错误信息 + 'networkConnectionFailed': '网络连接失败,请检查网络设置后重试', + 'serverTemporarilyUnavailable': '服务器暂时无法响应,请稍后重试', + 'loginExpiredPleaseRelogin': '登录已过期,请重新登录', + 'noPermissionForThisOperation': '没有权限执行此操作', + 'requestedResourceNotFound': '请求的资源不存在', + 'imageProcessingFailedPleaseReselect': '图片处理失败,请重新选择图片', + 'operationFailedPleaseRetry': '操作失败,请重试', + 'serverReturnedError': '服务器返回错误', + 'serverError': '服务器错误', + 'networkConnectionFailedCheckSettings': '网络连接失败,请检查网络设置', + 'serverInternalErrorRetryLater': '服务器内部错误,请稍后重试', + +// Profile 用户交互 +//'error': '错误', +//'success': '成功', + 'imageCompressionFailed': '图片压缩失败', + 'avatarUpdateFailed': '头像更新失败', + 'usernameCannotBeEmpty': '用户名不能为空', + 'saveSuccess': '保存成功', + 'personalInfoUpdated': '个人信息已更新', + 'saveFailed': '保存失败', + 'loggedOut': '已退出登录', + 'logoutFailedRetry': '退出登录失败,请重试', + 'accountPermanentlyDeleted': '账号已被永久删除', + 'deleteAccountFailedRetry': '删除账号失败,请重试', + // 权限管理页面 'getPermissionStatusFailed': '获取权限状态失败', 'communicationPermissions': '通讯权限', @@ -298,6 +422,15 @@ const Map zhCN = { 'permanentDenialText': '您已永久拒绝{permission}权限,请前往应用设置开启', 'goToSettings': '去设置', + // 版本更新对话框 + 'newVersionFound': '发现新版本', // 版本更新对话框标题 + 'remindLater': '稍后提醒', // 稍后提醒按钮 + 'updateNow': '立即更新', // 立即更新按钮 + 'checkUpdate': '检查更新', // 检查更新按钮 + 'updateFailed': '更新失败', // 更新失败提示 + 'cannotOpenAppStore': '无法打开应用商店,请手动前往应用商店更新', // 无法打开应用商店提示 + 'updateErrorRetry': '更新过程中发生错误,请稍后重试', // 更新错误重试提示 + //国家列表 "邮箱": "邮箱", "中国": "中国", @@ -406,12 +539,6 @@ const Map zhCN = { "斐济": "斐济", "所罗门群岛": "所罗门群岛", - // 导航 - "driving": "驾车", - "walking": "步行", - "bicycling": "骑行", - "tsransit": "公交", - // 翻译模块 // 翻译主页 (translation_view.dart) "translationHistory": "翻译历史", @@ -478,6 +605,7 @@ const Map zhCN = { "confirmBinding": "确认绑定", "associatingDevice": "正在关联设备...", "goToBluetoothSettings": "前往蓝牙设置", + 'bluetooth': '蓝牙', // 配对状态文本 "readyToPair": "准备开始配对", @@ -497,6 +625,36 @@ const Map zhCN = { "authorizationFailedCheckCode": "授权失败,请检查授权码是否正确", "pairingFailedRetry": "配对失败,请重试", + // 配对控制器相关 + //'connectDevice': '连接设备', + 'pleaseEnableBluetooth': '请开启蓝牙', + 'deviceDisconnected': '设备已断开', + 'readyToStartPairing': '准备开始配对', + 'checkingEnvironment': '正在检查环境...', + 'ensureHeadsetOnAndPairingMode': '请确保耳机已开启并进入配对模式', + //'goToBluetoothSettings': '前往蓝牙设置', + //'verifyingDevice': '正在验证设备...', + //'confirmBinding': '确认绑定', + //'associatingDevice': '正在关联设备...', + 'establishingSecureConnection': '正在建立安全连接...', + 'needManualBindingAuthCode': '需要手动绑定授权码...', + 'pairingSuccessful': '配对成功!', + 'enableBluetooth': '开启蓝牙', + 'grantPermissions': '授予权限', + 'retryAssociation': '重新关联', + 'retryAuthorization': '重新授权', + 'pleaseGrantNecessaryPermissions': '请授予必要权限', + 'checkFailedRetry': '检查失败,请重试', + 'pleaseConnectDeepSoundDevice': '请连接 DeepSound 设备', + 'verificationFailedRetry': '验证失败,请重试', + 'invalidDeviceAddress': '设备地址无效', + 'bleDeviceAssociationFailed': 'BLE设备关联失败', + 'deviceAssociationFailedRetry': '设备关联失败,请重试', + 'bleConnectionTimeoutRetry': 'BLE连接超时,请重试', + 'blePairingStartupFailed': 'BLE配对启动失败', + 'bleConnectionFailed': 'BLE连接失败', + 'deviceAuthorizationFailedCheckCode': '设备授权失败,请检查授权码', + //用户反馈页 "feedback": "用户反馈", 'feedbackInfo': '提供反馈或建议', @@ -515,13 +673,13 @@ const Map zhCN = { "unknownDevice": "未知设备", "currentFirmwareVersion": "当前固件版本", "latestFirmwareVersion": "最新固件版本", - "newVersionFound": "发现新版本", + "ota_newVersionFound": "发现新版本", "latestVersion": "已是最新版本", "gettingDeviceInfo": "正在获取设备信息...", "keepDeviceConnected": "请保持设备连接", "connectionFailed": "连接失败", "retryConnection": "重试连接", - "updateNow": "立即更新", + "ota_updateNow": "立即更新", "keepConnectedDontClose": "请保持设备连接,不要关闭应用", "doNotDisconnect": "请勿断开连接", "charging": "充电中", diff --git a/lib/modules/agent/controllers/agent_controller.dart b/lib/modules/agent/controllers/agent_controller.dart index 0192f079f..c2b9e4291 100644 --- a/lib/modules/agent/controllers/agent_controller.dart +++ b/lib/modules/agent/controllers/agent_controller.dart @@ -447,13 +447,7 @@ class AgentController extends GetxController { void _addWelcomeMessage() { messages.add(Message( isUser: false, - text: '你好!我是**小言**,我能帮你:\n\n' - '• 答问题和提供信息\n\n' - '• 实时语音翻译\n\n' - '• 推荐音乐和播客\n\n' - '• 语音备忘录和提醒\n\n' - '• 控制耳机功能\n\n' - '有什么我可以帮你的吗?', + text: 'welcomeMessage'.tr, // 你好!我是**小言**,我能帮你: )); } @@ -983,11 +977,11 @@ class AgentController extends GetxController { final hasPermission = await PermissionUtil.instance.requestPermission( // context: Get.context!, permissionType: Permission.microphone, - permissionName: '麦克风', - explanationText: '语音识别功能需要访问麦克风。', - permanentDenialText: '您已永久拒绝麦克风权限,请前往系统设置开启权限。', - settingsButtonText: '去设置', - cancelButtonText: '取消', + permissionName: 'microphonePermission'.tr, // 麦克风 + explanationText: 'voiceRecognitionPermissionText'.tr, // 语音识别功能需要访问麦克风。 + permanentDenialText: 'permissionDeniedText'.tr, // 您已永久拒绝麦克风权限,请前往系统设置开启权限。 + settingsButtonText: 'goToSettings'.tr, // 去设置 + cancelButtonText: 'cancel'.tr, // 取消 ); if (!hasPermission) { return; // 权限未获取,保持文本模式 @@ -1011,15 +1005,15 @@ class AgentController extends GetxController { // 开始语音输入 Future startVoiceInput() async { if (isListening.value) return; - print("开始语音输入"); // 检查麦克风权限 + print('startVoiceInput'.tr); // 开始语音输入 final hasPermission = await PermissionUtil.instance.requestPermission( // context: Get.context!, permissionType: Permission.microphone, - permissionName: '麦克风', - explanationText: '语音识别与翻译功能需要访问麦克风。', - permanentDenialText: '您已永久拒绝麦克风权限,请前往系统设置开启权限。', - settingsButtonText: '去设置', - cancelButtonText: '取消', + permissionName: 'microphonePermission'.tr, // 麦克风 + explanationText: 'voiceTranslationPermissionText'.tr, // 语音识别与翻译功能需要访问麦克风。 + permanentDenialText: 'permissionDeniedText'.tr, // 您已永久拒绝麦克风权限,请前往系统设置开启权限。 + settingsButtonText: 'goToSettings'.tr, // 去设置 + cancelButtonText: 'cancel'.tr, // 取消 ); if (!hasPermission) { isTextInputMode.value = true; // 如果没有权限,切回文本模式 @@ -1286,11 +1280,11 @@ class AgentController extends GetxController { // 检查麦克风权限 final hasPermission = await PermissionUtil.instance.requestPermission( permissionType: Permission.microphone, - permissionName: '麦克风', - explanationText: '打电话功能需要访问麦克风进行语音通话。', - permanentDenialText: '您已永久拒绝麦克风权限,请前往系统设置开启权限。', - settingsButtonText: '去设置', - cancelButtonText: '取消', + permissionName: 'microphonePermission'.tr, // 麦克风 + explanationText: 'phoneCallPermissionText'.tr, // 打电话功能需要访问麦克风进行语音通话。 + permanentDenialText: 'permissionDeniedText'.tr, // 您已永久拒绝麦克风权限,请前往系统设置开启权限。 + settingsButtonText: 'goToSettings'.tr, // 去设置 + cancelButtonText: 'cancel'.tr, // 取消 ); if (!hasPermission) { @@ -1305,7 +1299,7 @@ class AgentController extends GetxController { // 打电话模式不使用按住说话模式,而是持续语音输入 //isPushToTalkMode.value = false; // 开始语音识别 - print("开始打电话模式,开始语音输入"); + print('startPhoneCallMode'.tr); // 开始打电话模式,开始语音输入 await AgentService.audioContinue(); } } diff --git a/lib/modules/agent/controllers/message_action_controller.dart b/lib/modules/agent/controllers/message_action_controller.dart index 00efd5963..cd717ec1e 100644 --- a/lib/modules/agent/controllers/message_action_controller.dart +++ b/lib/modules/agent/controllers/message_action_controller.dart @@ -28,9 +28,10 @@ class MessageActionController extends GetxController { ) { // 触发触觉反馈 Haptics.vibrate(HapticsType.success); - + // 计算弹出菜单位置 - RenderBox? renderBox = Overlay.of(context).context.findRenderObject() as RenderBox; + RenderBox? renderBox = + Overlay.of(context).context.findRenderObject() as RenderBox; final RelativeRect position = RelativeRect.fromRect( Rect.fromLTRB( details.globalPosition.dx, @@ -67,7 +68,7 @@ class MessageActionController extends GetxController { size: 20.w, color: isDarkMode ? Colors.white : Colors.black87, ), - '复制', + 'copy'.tr, // 复制 isDarkMode ? Colors.white : Colors.black87, () => _copyMessage(message), ), @@ -95,7 +96,7 @@ class MessageActionController extends GetxController { size: 20.w, color: isDarkMode ? Colors.red[700] : Colors.red, ), - '举报'.tr, + 'report'.tr, //举报 isDarkMode ? Colors.red[700]! : Colors.red, () => _showReportForm(context, isDarkMode, message), ), @@ -138,7 +139,7 @@ class MessageActionController extends GetxController { Clipboard.setData(ClipboardData(text: message.text)).then((_) { Get.snackbar( 'success'.tr, - '复制成功', + 'copySuccess'.tr, // 复制成功 backgroundColor: Colors.blue.withOpacity(0.8), colorText: Colors.white, ); @@ -205,7 +206,7 @@ class MessageActionController extends GetxController { try { // 调用API提交举报 var response = await Api.reportAiContent(reportData); - + if (response != null) { print('提交举报响应: $response'); } @@ -220,8 +221,8 @@ class MessageActionController extends GetxController { // 显示成功通知 Get.snackbar( - '提交成功', - '举报已提交,我们会尽快处理', + 'submitSuccess'.tr, // 提交成功 + 'reportSubmitted'.tr, // 举报已提交,我们会尽快处理 backgroundColor: Colors.green.withOpacity(0.8), colorText: Colors.white, duration: const Duration(seconds: 2), @@ -229,8 +230,8 @@ class MessageActionController extends GetxController { } catch (e) { // 显示错误通知 Get.snackbar( - '提交失败', - '网络错误,请稍后重试', + 'submitFailed'.tr, // 提交失败 + 'networkError'.tr, // 网络错误,请稍后重试 backgroundColor: Colors.red.withOpacity(0.8), colorText: Colors.white, duration: const Duration(seconds: 2), @@ -242,7 +243,8 @@ class MessageActionController extends GetxController { /// 举报表单组件 class _ReportForm extends StatelessWidget { final bool isDarkMode; - final MessageActionController controller = Get.find(); + final MessageActionController controller = + Get.find(); _ReportForm({required this.isDarkMode}); @@ -262,7 +264,7 @@ class _ReportForm extends StatelessWidget { children: [ Center( child: Text( - '举报', + 'report'.tr, // 举报 style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.bold, @@ -300,13 +302,20 @@ class _ReportForm extends StatelessWidget { spacing: 8.w, runSpacing: 8.h, children: [ - _buildReportChip('有害/不安全', isDarkMode, controller), - _buildReportChip('色情低俗', isDarkMode, controller), - _buildReportChip('误导攻击', isDarkMode, controller), - _buildReportChip('违法犯罪', isDarkMode, controller), - _buildReportChip('隐私相关', isDarkMode, controller), - _buildReportChip('侵犯我的著作权、名誉权等', isDarkMode, controller), - _buildReportChip('其他', isDarkMode, controller), + _buildReportChip( + 'harmfulUnsafe'.tr, isDarkMode, controller), // 有害/不安全 + _buildReportChip('pornographicVulgar'.tr, isDarkMode, + controller), // 色情低俗 + _buildReportChip('misleadingAttack'.tr, isDarkMode, + controller), // 误导攻击 + _buildReportChip( + 'illegalCriminal'.tr, isDarkMode, controller), // 违法犯罪 + _buildReportChip( + 'privacyRelated'.tr, isDarkMode, controller), // 隐私相关 + _buildReportChip('copyrightViolation'.tr, isDarkMode, + controller), // 侵犯我的著作权、名誉权等 + _buildReportChip( + 'other'.tr, isDarkMode, controller), // 其他 ], ); }, @@ -328,7 +337,8 @@ class _ReportForm extends StatelessWidget { color: isDarkMode ? Colors.white : Colors.black, ), decoration: InputDecoration( - hintText: '我们想知道你举报的原因,你可以描述你遇到的问题。', + hintText: + 'reportDescriptionHint'.tr, // 我们想知道你举报的原因,你可以描述你遇到的问题。 hintStyle: TextStyle( color: isDarkMode ? Colors.white70 : Colors.black54, fontSize: 14.sp, @@ -350,7 +360,7 @@ class _ReportForm extends StatelessWidget { borderRadius: BorderRadius.circular(8.r), ), ), - child: Text('提交'), + child: Text('submit'.tr), // 提交 onPressed: () => controller.submitReport(), ), diff --git a/lib/modules/agent/views/agent_view.dart b/lib/modules/agent/views/agent_view.dart index 703aded40..b93eb2fbf 100644 --- a/lib/modules/agent/views/agent_view.dart +++ b/lib/modules/agent/views/agent_view.dart @@ -92,7 +92,7 @@ class _AgentViewState extends State with WidgetsBindingObserver { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '小言'.tr, + 'XiaoYan'.tr, style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, @@ -111,7 +111,7 @@ class _AgentViewState extends State with WidgetsBindingObserver { ), const SizedBox(width: 4), Text( - '在线'.tr, + 'online'.tr, style: TextStyle( fontSize: 12, color: Colors.green, @@ -171,7 +171,7 @@ class _AgentViewState extends State with WidgetsBindingObserver { children: [ Icon(Icons.delete_outline, color: primaryColor, size: 20), const SizedBox(width: 8), - Text('清除聊天记录'.tr, style: TextStyle(fontSize: 14)), + Text('clearChatHistory'.tr, style: TextStyle(fontSize: 14)), ], ), onTap: () => Future.delayed( @@ -200,10 +200,12 @@ class _AgentViewState extends State with WidgetsBindingObserver { reverse: true, padding: const EdgeInsets.symmetric( vertical: 16, horizontal: 16), - itemCount: controller.messages.length + (controller.hasMoreMessages.value ? 1 : 0), + itemCount: controller.messages.length + + (controller.hasMoreMessages.value ? 1 : 0), itemBuilder: (context, index) { // 如果是最后一项且有更多消息,显示加载指示器 - if (index == controller.messages.length && controller.hasMoreMessages.value) { + if (index == controller.messages.length && + controller.hasMoreMessages.value) { return _buildLoadMoreIndicator(); } @@ -305,20 +307,20 @@ class _AgentViewState extends State with WidgetsBindingObserver { children: [ _buildPromptChip( context: context, - label: '总结图片内容'.tr, + label: 'summarizeImageContent'.tr,//总结图片内容 onTap: () => controller.summarizeImage(), ), const SizedBox(width: 8), _buildPromptChip( context: context, - label: '抽取图像文字'.tr, + label: 'extractImageText'.tr,//抽取图像文字 onTap: () => controller.extractTextFromImage(), ), const SizedBox(width: 8), _buildPromptChip( context: context, - label: '翻译图像文字'.tr, + label: 'translateImageText'.tr,//翻译图像文字 onTap: () => controller.translateImageText(), ), @@ -440,8 +442,10 @@ class _AgentViewState extends State with WidgetsBindingObserver { ), decoration: InputDecoration( hintText: isImageActive - ? '添加对图片的问题或描述...' - : '输入消息...', + ? 'addQuestionAboutImage' + .tr // 添加对图片的问题或描述... + : 'inputMessage' + .tr, // 输入消息... hintStyle: TextStyle( color: Colors.grey[500], fontSize: 15, @@ -576,8 +580,10 @@ class _AgentViewState extends State with WidgetsBindingObserver { const SizedBox(width: 6), Text( isPushToTalkActive - ? '正在录音...' - : '按住说话', + ? 'recording' + .tr // 正在录音... + : 'holdToSpeak' + .tr, // 按住说话 style: TextStyle( fontSize: 14, fontWeight: @@ -735,7 +741,7 @@ class _AgentViewState extends State with WidgetsBindingObserver { _buildPlusOptionButton( context: context, icon: Icons.camera_alt, - label: '拍照', + label: 'takePhoto'.tr, // 拍照 onTap: () async { //controller.collapsePlusOptions(); await controller.takePhoto(); @@ -746,7 +752,7 @@ class _AgentViewState extends State with WidgetsBindingObserver { _buildPlusOptionButton( context: context, icon: Icons.photo_library, - label: '相册', + label: 'photoAlbum'.tr, // 相册 onTap: () async { //controller.collapsePlusOptions(); await controller.pickImage(); @@ -768,7 +774,7 @@ class _AgentViewState extends State with WidgetsBindingObserver { _buildPlusOptionButton( context: context, icon: Icons.phone, - label: '打电话', + label: 'makeCall'.tr, // 打电话 onTap: () { // 启动打电话模式 controller.startPhoneCall(); @@ -945,7 +951,7 @@ class _AgentViewState extends State with WidgetsBindingObserver { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - 'AI语音通话', + 'aiVoiceCall'.tr, // AI语音通话 style: TextStyle( fontSize: 18, fontWeight: FontWeight.w600, @@ -954,10 +960,10 @@ class _AgentViewState extends State with WidgetsBindingObserver { ), Obx(() { final status = controller.isListening.value - ? '正在通话中...' + ? 'inCall'.tr // 正在通话中... : controller.isSpeaking.value - ? 'AI正在回复...' - : '等待开始...'; + ? 'aiReplying'.tr // AI正在回复... + : 'waitingToStart'.tr; // 等待开始... return Text( status, style: TextStyle( @@ -1010,13 +1016,13 @@ class _AgentViewState extends State with WidgetsBindingObserver { // 状态文字 Obx(() { - String statusText = '点击开始通话'; + String statusText = 'clickToStartCall'.tr; // 点击开始通话 if (controller.isListening.value) { - statusText = '正在听您说话...'; + statusText = 'listeningToYou'.tr; // 正在听您说话... } else if (controller.isSpeaking.value) { - statusText = 'AI正在回复...'; + statusText = 'aiReplying'.tr; // AI正在回复... } else if (controller.isProcessing.value) { - statusText = '正在处理...'; + statusText = 'processing'.tr; // 正在处理... } return Text( @@ -1135,21 +1141,21 @@ class _AgentViewState extends State with WidgetsBindingObserver { // 正在加载状态 return Container( padding: const EdgeInsets.symmetric(vertical: 16), - child: const Center( + child: Center( child: Row( mainAxisSize: MainAxisSize.min, children: [ - SizedBox( + const SizedBox( width: 16, height: 16, child: CircularProgressIndicator( strokeWidth: 2, ), ), - SizedBox(width: 8), + const SizedBox(width: 8), Text( - '加载更多消息...', - style: TextStyle( + 'loadMoreMessages'.tr, // 加载更多消息... + style: const TextStyle( fontSize: 14, color: Colors.grey, ), @@ -1165,18 +1171,18 @@ class _AgentViewState extends State with WidgetsBindingObserver { child: Center( child: GestureDetector( onTap: () => controller.loadMoreMessages(), - child: const Row( + child: Row( mainAxisSize: MainAxisSize.min, children: [ - Icon( + const Icon( Icons.refresh, size: 16, color: Colors.grey, ), - SizedBox(width: 8), + const SizedBox(width: 8), Text( - '加载失败,点击重试', - style: TextStyle( + 'loadFailedClickRetry'.tr, // 加载失败,点击重试 + style: const TextStyle( fontSize: 14, color: Colors.grey, ), @@ -1190,10 +1196,10 @@ class _AgentViewState extends State with WidgetsBindingObserver { // 默认状态(有更多消息但未加载) return Container( padding: const EdgeInsets.symmetric(vertical: 8), - child: const Center( + child: Center( child: Text( - '向上滑动查看更多', - style: TextStyle( + 'swipeUpForMore'.tr, // 向上滑动查看更多 + style: const TextStyle( fontSize: 12, color: Colors.grey, ), diff --git a/lib/modules/agent/views/message_bubble.dart b/lib/modules/agent/views/message_bubble.dart index 51f7cf8e2..8fb2532ee 100644 --- a/lib/modules/agent/views/message_bubble.dart +++ b/lib/modules/agent/views/message_bubble.dart @@ -110,7 +110,7 @@ class MessageBubble extends GetView { Padding( padding: const EdgeInsets.only(left: 8), child: Text( - "由AI生成".tr, + "generatedByAi".tr,// 由AI生成 style: TextStyle( fontSize: 8, color: Colors.blue[600], diff --git a/lib/modules/agent/views/music_card.dart b/lib/modules/agent/views/music_card.dart index 761d66580..4da822412 100644 --- a/lib/modules/agent/views/music_card.dart +++ b/lib/modules/agent/views/music_card.dart @@ -67,7 +67,9 @@ Widget buildMusicItem(BuildContext context, int id, String name, String url, style: TextStyle( fontSize: 13.sp, fontWeight: FontWeight.w500, - color: isDarkMode ? Colors.white.withValues(alpha: 0.9) : Colors.grey[800], + color: isDarkMode + ? Colors.white.withValues(alpha: 0.9) + : Colors.grey[800], ), overflow: TextOverflow.ellipsis, ), @@ -146,7 +148,7 @@ Widget buildMusicContent( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '以下是一些推荐的音乐:', + 'recommendedMusic'.tr, //以下是一些推荐的音乐: style: TextStyle( color: isDarkMode ? Colors.white.withValues(alpha: 0.9) : Colors.black87, @@ -184,7 +186,7 @@ Widget buildMusicContent( ), const SizedBox(width: 6), Text( - '播放列表'.tr, + 'playList'.tr, //播放列表 style: TextStyle( fontSize: 13, fontWeight: FontWeight.w600, @@ -235,7 +237,7 @@ Widget buildMusicContent( tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), child: Text( - '查看更多推荐', + 'moreMusic'.tr, //更多音乐, style: TextStyle( fontSize: 12, color: Theme.of(context).primaryColor, diff --git a/lib/modules/agent/views/navigation_card.dart b/lib/modules/agent/views/navigation_card.dart index e5769785c..2d2d0e2a4 100644 --- a/lib/modules/agent/views/navigation_card.dart +++ b/lib/modules/agent/views/navigation_card.dart @@ -9,9 +9,9 @@ String formatDistance(String distanceStr) { if (distance >= 1000) { final km = distance / 1000; - return '${km.toStringAsFixed(1)} 公里'; + return '${km.toStringAsFixed(1)} KM'; } else { - return '${distance.toStringAsFixed(0)} 米'; + return '${distance.toStringAsFixed(0)} M'; } } @@ -24,9 +24,10 @@ String formatDuration(String secondsStr) { int seconds = duration.inSeconds.remainder(60); List parts = []; - if (hours > 0) parts.add('$hours小时'); - if (minutes > 0) parts.add('$minutes分钟'); - if (seconds > 0 || parts.isEmpty) parts.add('$seconds秒'); + if (hours > 0) parts.add('$hours${'hours'.tr}'); // 小时 + if (minutes > 0) parts.add('$minutes${'minutes'.tr}'); // 分钟 + //不需要秒 + //if (seconds > 0 || parts.isEmpty) parts.add('$seconds${'seconds'.tr}'); // 秒 return parts.join(''); } @@ -126,7 +127,7 @@ Widget navigationCard( ), SizedBox(width: 4.w), Text( - '导航中', + 'navigating'.tr, // 导航中 style: TextStyle( color: Colors.white, fontSize: 12.sp, @@ -190,24 +191,24 @@ Widget navigationCard( : Colors.grey, size: 20.sp, ), - SizedBox(height: 4.h), - Text( - (mode["ntype"] as String).tr, - textAlign: TextAlign.center, - style: TextStyle( - color: isEnabled - ? (isSelected - ? Theme.of(context).primaryColor - : (isDarkMode - ? Colors.white70 - : Colors.black87)) - : Colors.grey, - fontSize: 11.sp, - fontWeight: isSelected - ? FontWeight.w600 - : FontWeight.w400, - ), - ), + // SizedBox(height: 4.h), + // Text( + // (mode["ntype"] as String).tr, + // textAlign: TextAlign.center, + // style: TextStyle( + // color: isEnabled + // ? (isSelected + // ? Theme.of(context).primaryColor + // : (isDarkMode + // ? Colors.white70 + // : Colors.black87)) + // : Colors.grey, + // fontSize: 11.sp, + // fontWeight: isSelected + // ? FontWeight.w600 + // : FontWeight.w400, + // ), + // ), ], ), ), @@ -237,26 +238,25 @@ Widget navigationCard( size: 16.sp, color: Theme.of(context).primaryColor, ), - SizedBox(width: 6.w), - // 当前位置文本 - Text( - '当前位置', - style: TextStyle( - fontSize: 14.sp, - fontWeight: FontWeight.w500, - color: isDarkMode - ? Colors.white70 - : Colors.black54, - ), - ), + // SizedBox(width: 6.w), + // // 当前位置文本 + // Text( + // 'currentLocation'.tr, // 当前位置 + // style: TextStyle( + // fontSize: 14.sp, + // fontWeight: FontWeight.w500, + // color: isDarkMode + // ? Colors.white70 + // : Colors.black54, + // ), + // ), SizedBox(width: 8.w), // 箭头图标 Icon( Icons.arrow_forward, size: 16.sp, - color: isDarkMode - ? Colors.white54 - : Colors.black45, + color: + isDarkMode ? Colors.white54 : Colors.black45, ), SizedBox(width: 8.w), // 目的地图标 @@ -319,7 +319,7 @@ Widget navigationCard( ), SizedBox(width: 4.w), Text( - '约${formatDuration(modes[currentIndex]["duration"])}', + '${'approximate'.tr}${formatDuration(modes[currentIndex]["duration"])}', // 约 style: TextStyle( fontSize: 14.sp, color: Theme.of(context).primaryColor, @@ -343,7 +343,7 @@ Widget navigationCard( borderRadius: BorderRadius.circular(6.r), ), child: Text( - "${navigation["distanceText"]}进入${navigation["nextRoad"]}", + "${navigation["distanceText"]}${'enterRoad'.tr}${navigation["nextRoad"]}", // 进入 style: TextStyle( fontSize: 12.sp, color: Theme.of(context).primaryColor, @@ -372,9 +372,8 @@ Widget navigationCard( borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( - color: Theme.of(context) - .primaryColor - .withOpacity(0.3), + color: + Theme.of(context).primaryColor.withOpacity(0.3), blurRadius: 8, offset: const Offset(0, 2), ), diff --git a/lib/modules/agent/views/weather_card.dart b/lib/modules/agent/views/weather_card.dart index 8f422601b..33c5df9e9 100644 --- a/lib/modules/agent/views/weather_card.dart +++ b/lib/modules/agent/views/weather_card.dart @@ -1,6 +1,7 @@ import 'package:common_utils/common_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:get/get.dart'; /// 构建天气内容卡片 Widget buildWeatherContent(BuildContext context, String city, @@ -11,9 +12,10 @@ Widget buildWeatherContent(BuildContext context, String city, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '查询天气情况:', + 'weatherQuery'.tr, // 翻译键代表的中文文本内容:查询天气情况: style: TextStyle( - color: isDarkMode ? Colors.white.withValues(alpha: 0.9) : Colors.black87, + color: + isDarkMode ? Colors.white.withValues(alpha: 0.9) : Colors.black87, fontSize: 14.sp, height: 1.4, fontWeight: FontWeight.w400, @@ -55,8 +57,8 @@ Widget buildWeatherContent(BuildContext context, String city, children: [ Text( "${city} ${now["date"]}", - style: const TextStyle( - fontSize: 16, + style: TextStyle( + fontSize: 16.sp, fontWeight: FontWeight.w600, color: Colors.white, ), @@ -85,14 +87,14 @@ Widget buildWeatherContent(BuildContext context, String city, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '最高: ${now["daytemp"]}°', + '${'highest'.tr}: ${now["daytemp"]}°', // 翻译键代表的中文文本内容:最高 style: TextStyle( fontSize: 12.sp, color: Colors.white.withValues(alpha: 0.9), ), ), Text( - '最低: ${now["nighttemp"]}°', + '${'lowest'.tr}: ${now["nighttemp"]}°', // 翻译键代表的中文文本内容:最低 style: TextStyle( fontSize: 12.sp, color: Colors.white.withValues(alpha: 0.9), @@ -118,7 +120,7 @@ Widget buildWeatherContent(BuildContext context, String city, ), SizedBox(height: 16.h), Text( - '未来预报', + 'futureForecast'.tr, // 翻译键代表的中文文本内容:未来预报 style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w600, @@ -156,7 +158,8 @@ Widget buildWeatherContent(BuildContext context, String city, } /// 构建智能天气提示 -Widget _buildWeatherTip(BuildContext context, Map now, bool isDarkMode) { +Widget _buildWeatherTip( + BuildContext context, Map now, bool isDarkMode) { final weatherTip = _generateWeatherTip(now); return Container( @@ -205,72 +208,79 @@ WeatherTip _generateWeatherTip(Map now) { // 高温提示 (>= 35°C) if (dayTemp >= 35) { - return const WeatherTip( + return WeatherTip( icon: Icons.local_fire_department, - message: '今日高温炎热,请注意防暑降温,多喝水避免中暑', + message: 'hotWeatherTip'.tr, // 翻译键代表的中文文本内容:今日高温炎热,请注意防暑降温,多喝水避免中暑 ); } // 低温提示 (<= 5°C) if (dayTemp <= 5) { - return const WeatherTip( + return WeatherTip( icon: Icons.ac_unit, - message: '今日气温较低,外出请注意保暖,小心感冒', + message: 'coldWeatherTip'.tr, // 翻译键代表的中文文本内容:今日气温较低,外出请注意保暖,小心感冒 ); } // 雨天提示 - if (dayWeather.contains('雨') || ['阵雨', '雷阵雨', '小雨', '中雨', '大雨', '暴雨'].any((rain) => dayWeather.contains(rain))) { - return const WeatherTip( + if (dayWeather.contains('雨') || + ['阵雨', '雷阵雨', '小雨', '中雨', '大雨', '暴雨'] + .any((rain) => dayWeather.contains(rain))) { + return WeatherTip( icon: Icons.umbrella, - message: '今日有雨,外出请携带雨具,注意出行安全', + message: 'rainyWeatherTip'.tr, // 翻译键代表的中文文本内容:今日有雨,外出请携带雨具,注意出行安全 ); } // 雪天提示 - if (dayWeather.contains('雪') || ['阵雪', '小雪', '中雪', '大雪', '暴雪'].any((snow) => dayWeather.contains(snow))) { - return const WeatherTip( + if (dayWeather.contains('雪') || + ['阵雪', '小雪', '中雪', '大雪', '暴雪'].any((snow) => dayWeather.contains(snow))) { + return WeatherTip( icon: Icons.ac_unit, - message: '今日有雪,路面湿滑请注意安全,做好保暖措施', + message: 'snowyWeatherTip'.tr, // 翻译键代表的中文文本内容:今日有雪,路面湿滑请注意安全,做好保暖措施 ); } // 雾霾提示 - if (dayWeather.contains('雾') || dayWeather.contains('霾') || ['雾', '浓雾', '霾', '中度霾', '重度霾'].any((fog) => dayWeather.contains(fog))) { - return const WeatherTip( + if (dayWeather.contains('雾') || + dayWeather.contains('霾') || + ['雾', '浓雾', '霾', '中度霾', '重度霾'].any((fog) => dayWeather.contains(fog))) { + return WeatherTip( icon: Icons.blur_on, - message: '今日有雾霾,能见度较低,外出请佩戴口罩', + message: 'foggyWeatherTip'.tr, // 翻译键代表的中文文本内容:今日有雾霾,能见度较低,外出请佩戴口罩 ); } // 大风提示 - if (dayWeather.contains('风') || ['大风', '强风', '疾风', '烈风'].any((wind) => dayWeather.contains(wind))) { - return const WeatherTip( + if (dayWeather.contains('风') || + ['大风', '强风', '疾风', '烈风'].any((wind) => dayWeather.contains(wind))) { + return WeatherTip( icon: Icons.air, - message: '今日风力较大,外出请注意安全,固定好物品', + message: 'windyWeatherTip'.tr, // 翻译键代表的中文文本内容:今日风力较大,外出请注意安全,固定好物品 ); } // 晴天紫外线提示 (温度 >= 25°C) - if (['晴', '少云', '晴间多云'].any((sunny) => dayWeather.contains(sunny)) && dayTemp >= 25) { - return const WeatherTip( + if (['晴', '少云', '晴间多云'].any((sunny) => dayWeather.contains(sunny)) && + dayTemp >= 25) { + return WeatherTip( icon: Icons.wb_sunny, - message: '今日阳光充足紫外线较强,外出请做好防晒', + message: 'sunnyWeatherTip'.tr, // 翻译键代表的中文文本内容:今日阳光充足紫外线较强,外出请做好防晒 ); } // 温差大提示 (>= 10°C) if ((dayTemp - nightTemp).abs() >= 10) { - return const WeatherTip( + return WeatherTip( icon: Icons.thermostat, - message: '今日昼夜温差较大,请适时增减衣物', + message: 'temperatureDifferenceTip'.tr, // 翻译键代表的中文文本内容:今日昼夜温差较大,请适时增减衣物 ); } // 默认舒适天气提示 - return const WeatherTip( + return WeatherTip( icon: Icons.wb_sunny_outlined, - message: '今日天气适宜,是外出活动的好时光', + message: 'comfortableWeatherTip'.tr, // 翻译键代表的中文文本内容:今日天气适宜,是外出活动的好时光 ); } diff --git a/lib/modules/agent/widgets/full_screen_editor.dart b/lib/modules/agent/widgets/full_screen_editor.dart index 902067c54..94c2bbd04 100644 --- a/lib/modules/agent/widgets/full_screen_editor.dart +++ b/lib/modules/agent/widgets/full_screen_editor.dart @@ -72,7 +72,7 @@ class _FullScreenEditorState extends State { height: 1.5, ), decoration: InputDecoration( - hintText: '在这里输入你的消息...', + hintText: 'fullScreenEditorHint'.tr, // 在这里输入你的消息... hintStyle: TextStyle( color: isDarkMode ? Colors.white54 : Colors.grey[500], fontSize: 16.sp, @@ -106,7 +106,8 @@ class _FullScreenEditorState extends State { valueListenable: _textController, builder: (context, value, child) { return Text( - '${value.text.length} 字符', + 'characterCount'.tr.replaceAll('{count}', + '${value.text.length}'), // ${value.text.length} 字符 style: TextStyle( color: isDarkMode ? Colors.white60 diff --git a/lib/modules/common/widgets/version_update_dialog.dart b/lib/modules/common/widgets/version_update_dialog.dart index cb0a59f03..d8375a604 100644 --- a/lib/modules/common/widgets/version_update_dialog.dart +++ b/lib/modules/common/widgets/version_update_dialog.dart @@ -70,7 +70,7 @@ class VersionUpdateDialog extends StatelessWidget { // 标题 Text( - '发现新版本', + 'newVersionFound'.tr, // 发现新版本 style: TextStyle( fontSize: 20.sp, fontWeight: FontWeight.bold, @@ -135,7 +135,7 @@ class VersionUpdateDialog extends StatelessWidget { ), ), child: Text( - '稍后提醒', + 'remindLater'.tr, // 稍后提醒 style: TextStyle( fontSize: 16.sp, color: @@ -185,11 +185,11 @@ class VersionUpdateDialog extends StatelessWidget { String _getUpdateButtonText() { switch (updateInfo.updateType) { case UpdateType.force: - return '立即更新'; + return 'updateNow'.tr; // 立即更新 case UpdateType.optional: - return '立即更新'; + return 'updateNow'.tr; // 立即更新 default: - return '检查更新'; + return 'checkUpdate'.tr; // 检查更新 } } @@ -212,8 +212,8 @@ class VersionUpdateDialog extends StatelessWidget { if (!success) { Get.snackbar( - '更新失败', - '无法打开应用商店,请手动前往应用商店更新', + 'updateFailed'.tr, // 更新失败 + 'cannotOpenAppStore'.tr, // 无法打开应用商店,请手动前往应用商店更新 snackPosition: SnackPosition.TOP, backgroundColor: Colors.red.withOpacity(0.8), colorText: Colors.white, @@ -226,8 +226,8 @@ class VersionUpdateDialog extends StatelessWidget { } Get.snackbar( - '更新失败', - '更新过程中发生错误,请稍后重试', + 'updateFailed'.tr, // 更新失败 + 'updateErrorRetry'.tr, // 更新过程中发生错误,请稍后重试 snackPosition: SnackPosition.TOP, backgroundColor: Colors.red.withOpacity(0.8), colorText: Colors.white, diff --git a/lib/modules/ota_upgrade/views/ota_upgrade_view.dart b/lib/modules/ota_upgrade/views/ota_upgrade_view.dart index ca7215fc1..c2d8ab091 100644 --- a/lib/modules/ota_upgrade/views/ota_upgrade_view.dart +++ b/lib/modules/ota_upgrade/views/ota_upgrade_view.dart @@ -501,7 +501,7 @@ class OtaUpgradeView extends GetView { ), SizedBox(width: 6.w), Text( - 'newVersionFound'.tr, // 发现新版本 + 'ota_newVersionFound'.tr, // 发现新版本 style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w500, @@ -835,7 +835,7 @@ class OtaUpgradeView extends GetView { ), label: Text( controller.isUpdateAvailable.value - ? 'updateNow'.tr + ? 'ota_updateNow'.tr : 'latestVersion'.tr, // 立即更新 : 已是最新版本 style: TextStyle( fontSize: 16.sp, diff --git a/lib/modules/pairing/controllers/pairing_controller.dart b/lib/modules/pairing/controllers/pairing_controller.dart index 20eb21cdf..1021749ac 100644 --- a/lib/modules/pairing/controllers/pairing_controller.dart +++ b/lib/modules/pairing/controllers/pairing_controller.dart @@ -70,8 +70,8 @@ class PairingController extends GetxController { // 增加临时跳过绑定按钮状态 final showSkipBindingButton = false.obs; // 新增临时跳过绑定按钮 - final connectButtonText = '连接设备'.obs; - final retryButtonText = '重试'.obs; + final connectButtonText = 'connectDevice'.tr.obs; //连接设备 + final retryButtonText = 'retry'.tr.obs; final deviceCode = ''.obs; // ========== 监听器管理 ========== @@ -168,8 +168,7 @@ class PairingController extends GetxController { /// 处理蓝牙开关状态变化 void _handleBluetoothStateChange(String state) { if (state == 'off') { - // 蓝牙关闭,进入错误状态 - _setError(ErrorType.bluetoothOff, '请开启蓝牙'); + _setError(ErrorType.bluetoothOff, 'pleaseEnableBluetooth'.tr); } else if (state == 'on' && _errorType.value == ErrorType.bluetoothOff) { // 蓝牙重新开启,恢复流程 Logger.i(_tag, '检测到蓝牙已开启,自动恢复配对流程'); @@ -210,7 +209,7 @@ class PairingController extends GetxController { case PairingState.completed: if (device == null) { // 设备断开,返回等待连接状态 - _setError(ErrorType.noClassicDevice, '设备已断开'); + _setError(ErrorType.noClassicDevice, 'deviceDisconnected'.tr); //设备已断开 } break; @@ -260,34 +259,33 @@ class PairingController extends GetxController { showRetryChectButton.value = false; switch (state) { case PairingState.idle: - statusText.value = '准备开始配对'; + statusText.value = 'readyToStartPairing'.tr; break; case PairingState.checking: - statusText.value = '正在检查环境...'; + statusText.value = 'checkingEnvironment'.tr; isLoading.value = true; break; case PairingState.waitingClassic: - statusText.value = '请确保耳机已开启并进入配对模式'; + statusText.value = 'ensureHeadsetOnAndPairingMode'.tr; showConnectButton.value = true; showSkipButton.value = true; - - connectButtonText.value = '前往蓝牙设置'; + connectButtonText.value = 'goToBluetoothSettings'.tr; break; case PairingState.verifying: - statusText.value = '正在验证设备...'; + statusText.value = 'verifyingDevice'.tr; isLoading.value = true; break; case PairingState.binding: - statusText.value = '确认绑定'; + statusText.value = 'confirmBinding'.tr; isLoading.value = true; showBindButton.value = true; showRetryChectButton.value = true; break; case PairingState.associating: - statusText.value = '正在关联设备...'; + statusText.value = 'associatingDevice'.tr; isLoading.value = true; // 延迟执行关联,确保状态已更新 Future.delayed(const Duration(milliseconds: 200), () { @@ -296,7 +294,7 @@ class PairingController extends GetxController { break; case PairingState.waitingBle: - statusText.value = '正在建立安全连接...'; + statusText.value = 'establishingSecureConnection'.tr; isLoading.value = true; // 延迟一下再调用,给BLE管理器时间更新状态 Future.delayed(const Duration(milliseconds: 200), () { @@ -304,14 +302,14 @@ class PairingController extends GetxController { }); break; case PairingState.manualbinding: - statusText.value = '需要手动绑定授权码...'; + statusText.value = 'needManualBindingAuthCode'.tr; isLoading.value = false; showAutoCodeInput.value = true; // showSkipButton.value = true; showSkipBindingButton.value = true; // 显示临时跳过绑定按钮 break; case PairingState.completed: - statusText.value = '配对成功!'; + statusText.value = 'pairingSuccessful'.tr; isLoading.value = false; _navigateToHome(); break; @@ -325,27 +323,27 @@ class PairingController extends GetxController { switch (_errorType.value) { case ErrorType.bluetoothOff: showConnectButton.value = true; - connectButtonText.value = '开启蓝牙'; + connectButtonText.value = 'enableBluetooth'.tr; //开启蓝牙 break; case ErrorType.noClassicDevice: showConnectButton.value = true; - connectButtonText.value = '前往蓝牙设置'; + connectButtonText.value = 'goToBluetoothSettings'.tr; //前往蓝牙设备 break; case ErrorType.noPermission: showRetryButton.value = true; - retryButtonText.value = '授予权限'; + retryButtonText.value = 'grantPermissions'.tr; //授予权限 break; case ErrorType.associationFailed: showRetryButton.value = true; - retryButtonText.value = '重新关联'; + retryButtonText.value = 'retryAssociation'.tr; //重新关联 break; case ErrorType.authnFailed: showRetryButton.value = true; - retryButtonText.value = '重新授权'; + retryButtonText.value = 'retryAuthorization'.tr; //重新授权 break; default: showRetryButton.value = true; - retryButtonText.value = '重试'; + retryButtonText.value = 'retry'.tr; //重试 break; } break; @@ -380,13 +378,13 @@ class PairingController extends GetxController { try { // 1. 检查蓝牙状态 if (_bluetoothManager.bluetoothState == 'off') { - _setError(ErrorType.bluetoothOff, '请开启蓝牙'); + _setError(ErrorType.bluetoothOff, 'pleaseEnableBluetooth'.tr); return; } // 2. 检查权限 if (!await _checkPermissions()) { - _setError(ErrorType.noPermission, '请授予必要权限'); + _setError(ErrorType.noPermission, 'pleaseGrantNecessaryPermissions'.tr); return; } @@ -406,7 +404,7 @@ class PairingController extends GetxController { await _verifyDevice(classicDevice); } catch (e) { Logger.e(_tag, '状态检查失败: $e'); - _setError(ErrorType.networkError, '检查失败,请重试'); + _setError(ErrorType.networkError, 'checkFailedRetry'.tr); } } @@ -452,12 +450,13 @@ class PairingController extends GetxController { //验证失败 进入手动授权 _transition(PairingState.manualbinding); } else { - _setError(ErrorType.deviceNotMatch, '请连接 DeepSound 设备'); + _setError(ErrorType.deviceNotMatch, + 'pleaseConnectDeepSoundDevice'.tr); //请连接DeepSound设备 } } } catch (e) { Logger.e(_tag, '设备验证异常: $e'); - _setError(ErrorType.networkError, '验证失败,请重试'); + _setError(ErrorType.networkError, 'verificationFailedRetry'.tr); //验证失败请重试 } } @@ -496,7 +495,8 @@ class PairingController extends GetxController { void _startDeviceAssociation() async { try { if (_verifiedDeviceAddress == null) { - _setError(ErrorType.associationFailed, '设备地址无效'); + _setError( + ErrorType.associationFailed, 'invalidDeviceAddress'.tr); //无效的设备地址 return; } @@ -513,11 +513,13 @@ class PairingController extends GetxController { // 关联成功后,转到等待BLE连接状态 _transition(PairingState.waitingBle); } else { - _setError(ErrorType.associationFailed, 'BLE设备关联失败'); + _setError(ErrorType.associationFailed, + 'bleDeviceAssociationFailed'.tr); //BLE设备关联失败 } } catch (e) { Logger.e(_tag, 'BLE设备关联异常: $e'); - _setError(ErrorType.associationFailed, '设备关联失败,请重试'); + _setError(ErrorType.associationFailed, + 'deviceAssociationFailedRetry'.tr); //设备关联失败,请重试 } } @@ -528,7 +530,8 @@ class PairingController extends GetxController { _bleTimeoutTimer?.cancel(); _bleTimeoutTimer = Timer(const Duration(seconds: 30), () { if (_currentState.value == PairingState.waitingBle) { - _setError(ErrorType.bleTimeout, 'BLE连接超时,请重试'); + _setError(ErrorType.bleTimeout, + 'bleConnectionTimeoutRetry'.tr); //BLE连接超时,请重试 } }); @@ -549,12 +552,13 @@ class PairingController extends GetxController { final success = await _bleManager.registerBackgroundScan( macAddress: _verifiedDeviceAddress); if (!success && _currentState.value == PairingState.waitingBle) { - _setError(ErrorType.bleTimeout, 'BLE配对启动失败'); + _setError( + ErrorType.bleTimeout, 'blePairingStartupFailed'.tr); //BLE配对启动失败 } } } catch (e) { Logger.e(_tag, 'BLE连接失败: $e'); - _setError(ErrorType.bleTimeout, 'BLE连接失败'); + _setError(ErrorType.bleTimeout, 'bleConnectionFailed'.tr); //BLE连接失败 } } @@ -665,7 +669,8 @@ class PairingController extends GetxController { _verifyDevice(_currentClassicDevice!); } else { Logger.e(_tag, '手动绑定失败!'); - _setError(ErrorType.authnFailed, '设备授权失败,请检查授权码'); + _setError(ErrorType.authnFailed, + 'deviceAuthorizationFailedCheckCode'.tr); //设备授权失败,请检查授权码 } } diff --git a/lib/modules/pairing/views/pairing_view.dart b/lib/modules/pairing/views/pairing_view.dart index e2c57a222..4b5046eb4 100644 --- a/lib/modules/pairing/views/pairing_view.dart +++ b/lib/modules/pairing/views/pairing_view.dart @@ -328,7 +328,8 @@ class PairingView extends GetView { case ErrorType.noPermission: return 'lackPermissions'.tr; // 缺少蓝牙权限 case ErrorType.noClassicDevice: - return 'connectDeepSoundViaSystemBluetooth'.tr; // 请先通过系统蓝牙连接DeapSound设备 + return 'connectDeepSoundViaSystemBluetooth' + .tr; // 请先通过系统蓝牙连接DeapSound设备 case ErrorType.deviceNotMatch: return 'ensureConnectedDeepSoundDevice'.tr; // 请确保连接的是DeapSound设备 case ErrorType.deviceBound: @@ -424,9 +425,9 @@ class PairingView extends GetView { // 获取连接按钮图标 IconData _getConnectButtonIcon() { final buttonText = controller.connectButtonText.value; - if (buttonText.contains('蓝牙')) { + if (buttonText.contains('bluetooth'.tr)) { return Icons.bluetooth; - } else if (buttonText.contains('设置')) { + } else if (buttonText.contains('settings'.tr)) { return Icons.settings; } return Icons.bluetooth_searching; diff --git a/lib/modules/profile/controllers/profile_controller.dart b/lib/modules/profile/controllers/profile_controller.dart index 2480174d3..07ccad2d5 100644 --- a/lib/modules/profile/controllers/profile_controller.dart +++ b/lib/modules/profile/controllers/profile_controller.dart @@ -50,22 +50,22 @@ class ProfileController extends GetxController { errorStr.contains('socket') || errorStr.contains('timeout') || errorStr.contains('connection')) { - return '网络连接失败,请检查网络设置后重试'; + return 'networkConnectionFailed'.tr; //网络连接失败 } else if (errorStr.contains('server') || - errorStr.contains('500') || - errorStr.contains('502') || - errorStr.contains('503')) { - return '服务器暂时无法响应,请稍后重试'; + errorStr.contains('500') || + errorStr.contains('502') || + errorStr.contains('503')) { + return 'serverTemporarilyUnavailable'.tr; //服务器暂时不可用 } else if (errorStr.contains('401') || errorStr.contains('unauthorized')) { - return '登录已过期,请重新登录'; + return 'loginExpiredPleaseRelogin'.tr; //登录过期,请重新登录 } else if (errorStr.contains('403') || errorStr.contains('forbidden')) { - return '没有权限执行此操作'; + return 'noPermissionForThisOperation'.tr; //没有权限执行此操作 } else if (errorStr.contains('404')) { - return '请求的资源不存在'; + return 'requestedResourceNotFound'.tr; //请求的资源不存在 } else if (errorStr.contains('file') || errorStr.contains('image')) { - return '图片处理失败,请重新选择图片'; + return 'imageProcessingFailedPleaseReselect'.tr; //图片处理失败,请重新选择图片 } else { - return '操作失败,请重试'; + return 'operationFailedPleaseRetry'.tr; //操作失败,请重试 } } @@ -236,9 +236,11 @@ class ProfileController extends GetxController { if (response != null && response is Map) { // 检查响应是否包含错误 if (response.containsKey('error') || response.containsKey('msg')) { - final errorMsg = response['error'] ?? response['msg'] ?? '服务器返回错误'; + final errorMsg = response['error'] ?? + response['msg'] ?? + 'serverReturnedError'.tr; //服务器返回错误 Logger().e('服务器返回错误: $errorMsg'); - throw Exception('服务器错误: $errorMsg'); + throw Exception('${'serverError'.tr}: $errorMsg'); //服务器错误 } Logger().d('更新成功: $response'); @@ -252,7 +254,8 @@ class ProfileController extends GetxController { }); // 如果服务器返回了新的头像URL,下载并保存到本地 - if (response['avatar'] != null && response['avatar'].toString().isNotEmpty) { + if (response['avatar'] != null && + response['avatar'].toString().isNotEmpty) { final serverAvatar = response['avatar'].toString(); if (serverAvatar.startsWith('http')) { // 异步下载新头像,不阻塞当前流程 @@ -272,10 +275,12 @@ class ProfileController extends GetxController { if (e.toString().contains('SocketException') || e.toString().contains('TimeoutException') || e.toString().contains('network')) { - throw Exception('network: 网络连接失败,请检查网络设置'); + throw Exception( + 'network: ${'networkConnectionFailedCheckSettings'.tr}'); //网络连接失败,请检查网络设置 } else if (e.toString().contains('500') || - e.toString().contains('server')) { - throw Exception('server: 服务器内部错误,请稍后重试'); + e.toString().contains('server')) { + throw Exception( + 'server: ${'serverInternalErrorRetryLater'.tr}'); //服务器内部错误,请稍后重试 } else { throw Exception('unknown: ${e.toString()}'); } @@ -350,7 +355,8 @@ class ProfileController extends GetxController { _originalName = userInfo.value.name; _originalAvatar = userInfo.value.avatar; _originalLocalAvatar = localAvatar.value; - Logger().d('已保存原始状态 - 名称: $_originalName, 头像: $_originalAvatar, 本地头像: $_originalLocalAvatar'); + Logger().d( + '已保存原始状态 - 名称: $_originalName, 头像: $_originalAvatar, 本地头像: $_originalLocalAvatar'); } // 回滚到原始状态 @@ -377,7 +383,8 @@ class ProfileController extends GetxController { Logger().e('回滚状态同步到本地存储失败: $e'); } - Logger().d('已回滚到原始状态 - 名称: $_originalName, 头像: $_originalAvatar, 本地头像: $_originalLocalAvatar'); + Logger().d( + '已回滚到原始状态 - 名称: $_originalName, 头像: $_originalAvatar, 本地头像: $_originalLocalAvatar'); } // 开始编辑昵称(内联编辑) @@ -509,7 +516,7 @@ class ProfileController extends GetxController { ); if (compressedImage == null) { - Get.snackbar('错误', '图片压缩失败'); + Get.snackbar('error'.tr, 'imageCompressionFailed'.tr); //图片压缩失败 return; } @@ -535,10 +542,12 @@ class ProfileController extends GetxController { } catch (e) { Logger().e('更新头像失败: $e'); final errorMessage = _getErrorMessage(e); - Get.snackbar('头像更新失败', errorMessage, + Get.snackbar( + 'avatarUpdateFailed'.tr, + errorMessage, duration: const Duration(seconds: 3), snackPosition: SnackPosition.TOP, - ); + ); //头像更新失败 // 发生错误时回滚状态 await _rollbackToOriginalState(); } @@ -549,7 +558,7 @@ class ProfileController extends GetxController { Future updateUserNameAndAvatar(String name) async { if (name.trim().isEmpty) { Logger().e('无效名称: $name'); - Get.snackbar('错误', '用户名不能为空'); + Get.snackbar('error'.tr, 'usernameCannotBeEmpty'.tr); //用户名不能为空 return; } @@ -582,8 +591,8 @@ class ProfileController extends GetxController { // 显示成功提示 Get.snackbar( - '保存成功', - '个人信息已更新', + 'saveSuccess'.tr, + 'personalInfoUpdated'.tr, duration: const Duration(seconds: 3), snackPosition: SnackPosition.TOP, backgroundColor: Colors.green.withOpacity(0.1), @@ -596,7 +605,7 @@ class ProfileController extends GetxController { borderRadius: 8, isDismissible: true, forwardAnimationCurve: Curves.easeOutBack, - ); + ); //个人信息更新成功 Logger().d('成功提示已显示'); @@ -604,12 +613,12 @@ class ProfileController extends GetxController { Future.delayed(const Duration(milliseconds: 100), () { if (Get.context != null) { ScaffoldMessenger.of(Get.context!).showSnackBar( - const SnackBar( + SnackBar( content: Row( children: [ Icon(Icons.check_circle, color: Colors.white), SizedBox(width: 8), - Text('个人信息已更新'), + Text('personalInfoUpdated'.tr), ], ), backgroundColor: Colors.green, @@ -619,7 +628,6 @@ class ProfileController extends GetxController { ); } }); - } catch (e) { Logger().e('更新用户名和头像错误: $e'); @@ -628,10 +636,12 @@ class ProfileController extends GetxController { // 显示错误提示 final errorMessage = _getErrorMessage(e); - Get.snackbar('保存失败', errorMessage, + Get.snackbar( + 'saveFailed'.tr, + errorMessage, duration: const Duration(seconds: 4), snackPosition: SnackPosition.TOP, - ); + ); //保存失败 } finally { // 隐藏加载状态 isUpdating.value = false; @@ -655,7 +665,7 @@ class ProfileController extends GetxController { if (result.success) { // 先显示成功提示 - Get.snackbar('成功', result.message ?? '已退出登录'); + Get.snackbar('success'.tr, result.message ?? 'loggedOut'.tr); //已退出登录 Logger().d('退出登录成功'); // 然后导航到登录页面 @@ -663,7 +673,8 @@ class ProfileController extends GetxController { await Get.offAllNamed(Routes.login); } } else { - Get.snackbar('错误', result.errorMessage ?? '退出登录失败,请重试'); + Get.snackbar('error'.tr, + result.errorMessage ?? 'logoutFailedRetry'.tr); //退出登录失败,请重试 Logger().e('退出登录失败: ${result.errorMessage}'); } } catch (e) { @@ -671,7 +682,7 @@ class ProfileController extends GetxController { if (Get.isDialogOpen ?? false) { Get.back(); } - Get.snackbar('错误', '退出登录失败,请重试'); + Get.snackbar('error'.tr, 'logoutFailedRetry'.tr); //退出登录失败,请重试 Logger().e('退出登录错误: $e'); } } @@ -693,7 +704,8 @@ class ProfileController extends GetxController { if (result.success) { // 先显示成功提示 - Get.snackbar('成功', result.message ?? '账号已被永久删除'); + Get.snackbar('success'.tr, + result.message ?? 'accountPermanentlyDeleted'.tr); //账号已被永久删除 Logger().d('账号删除成功'); // 然后导航到登录页面 @@ -701,7 +713,8 @@ class ProfileController extends GetxController { await Get.offAllNamed(Routes.login); } } else { - Get.snackbar('错误', result.errorMessage ?? '删除账号失败,请重试'); + Get.snackbar('error'.tr, + result.errorMessage ?? 'deleteAccountFailedRetry'.tr); //删除账号失败,请重试 Logger().e('删除账号失败: ${result.errorMessage}'); } } catch (e) { @@ -709,7 +722,7 @@ class ProfileController extends GetxController { if (Get.isDialogOpen ?? false) { Get.back(); } - Get.snackbar('错误', '删除账号失败,请重试'); + Get.snackbar('error'.tr, 'deleteAccountFailedRetry'.tr); //删除账号失败,请重试 Logger().e('删除账号失败: $e'); } }