Browse Source

refactor(i18n): 重构国际化字符串并统一翻译键命名规范

将硬编码的中文字符串替换为国际化翻译键
统一翻译键命名规范,按模块分类组织
添加缺失的英文翻译字符串
优化部分翻译键的命名以更好表达用途
newdev_shunjiawei
lxm 1 year ago
parent
commit
6c3152bbaa
  1. 199
      lib/core/translations/language/en_us.dart
  2. 176
      lib/core/translations/language/zh_cn.dart
  3. 42
      lib/modules/agent/controllers/agent_controller.dart
  4. 52
      lib/modules/agent/controllers/message_action_controller.dart
  5. 78
      lib/modules/agent/views/agent_view.dart
  6. 2
      lib/modules/agent/views/message_bubble.dart
  7. 10
      lib/modules/agent/views/music_card.dart
  8. 87
      lib/modules/agent/views/navigation_card.dart
  9. 72
      lib/modules/agent/views/weather_card.dart
  10. 5
      lib/modules/agent/widgets/full_screen_editor.dart
  11. 18
      lib/modules/common/widgets/version_update_dialog.dart
  12. 4
      lib/modules/ota_upgrade/views/ota_upgrade_view.dart
  13. 73
      lib/modules/pairing/controllers/pairing_controller.dart
  14. 7
      lib/modules/pairing/views/pairing_view.dart
  15. 85
      lib/modules/profile/controllers/profile_controller.dart

199
lib/core/translations/language/en_us.dart

@ -253,12 +253,123 @@ const Map<String, String> 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<String, String> 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<String, String> 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<String, String> enUS = {
"斐济": "Fiji",
"所罗门群岛": "Solomon Islands",
// 导航
"driving": "Driving",
"walking": "Walking",
"bicycling": "Cycling",
"tsransit": "Transit",
// 翻译模块
// 翻译主页
"translationHistory": "Translation History",
@ -500,6 +648,7 @@ const Map<String, String> enUS = {
"confirmBinding": "Confirm Binding",
"associatingDevice": "Associating device...",
"goToBluetoothSettings": "Go to Bluetooth Settings",
'bluetooth': 'Bluetooth',
// 配对状态文本
"readyToPair": "Ready to pair",
@ -525,6 +674,38 @@ const Map<String, String> 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<String, String> 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",

176
lib/core/translations/language/zh_cn.dart

@ -245,12 +245,109 @@ const Map<String, String> 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<String, String> 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<String, String> zhCN = {
'permanentDenialText': '您已永久拒绝{permission}权限,请前往应用设置开启',
'goToSettings': '去设置',
// 版本更新对话框
'newVersionFound': '发现新版本', // 版本更新对话框标题
'remindLater': '稍后提醒', // 稍后提醒按钮
'updateNow': '立即更新', // 立即更新按钮
'checkUpdate': '检查更新', // 检查更新按钮
'updateFailed': '更新失败', // 更新失败提示
'cannotOpenAppStore': '无法打开应用商店,请手动前往应用商店更新', // 无法打开应用商店提示
'updateErrorRetry': '更新过程中发生错误,请稍后重试', // 更新错误重试提示
//国家列表
"邮箱": "邮箱",
"中国": "中国",
@ -406,12 +539,6 @@ const Map<String, String> zhCN = {
"斐济": "斐济",
"所罗门群岛": "所罗门群岛",
// 导航
"driving": "驾车",
"walking": "步行",
"bicycling": "骑行",
"tsransit": "公交",
// 翻译模块
// 翻译主页 (translation_view.dart)
"translationHistory": "翻译历史",
@ -478,6 +605,7 @@ const Map<String, String> zhCN = {
"confirmBinding": "确认绑定",
"associatingDevice": "正在关联设备...",
"goToBluetoothSettings": "前往蓝牙设置",
'bluetooth': '蓝牙',
// 配对状态文本
"readyToPair": "准备开始配对",
@ -497,6 +625,36 @@ const Map<String, String> 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<String, String> zhCN = {
"unknownDevice": "未知设备",
"currentFirmwareVersion": "当前固件版本",
"latestFirmwareVersion": "最新固件版本",
"newVersionFound": "发现新版本",
"ota_newVersionFound": "发现新版本",
"latestVersion": "已是最新版本",
"gettingDeviceInfo": "正在获取设备信息...",
"keepDeviceConnected": "请保持设备连接",
"connectionFailed": "连接失败",
"retryConnection": "重试连接",
"updateNow": "立即更新",
"ota_updateNow": "立即更新",
"keepConnectedDontClose": "请保持设备连接,不要关闭应用",
"doNotDisconnect": "请勿断开连接",
"charging": "充电中",

42
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<void> 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();
}
}

52
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<MessageActionController>();
final MessageActionController controller =
Get.find<MessageActionController>();
_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(),
),

78
lib/modules/agent/views/agent_view.dart

@ -92,7 +92,7 @@ class _AgentViewState extends State<AgentView> 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<AgentView> 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<AgentView> 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<AgentView> 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<AgentView> 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<AgentView> 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<AgentView> 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<AgentView> 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<AgentView> 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<AgentView> with WidgetsBindingObserver {
_buildPlusOptionButton(
context: context,
icon: Icons.phone,
label: '打电话',
label: 'makeCall'.tr, // 打电话
onTap: () {
// 启动打电话模式
controller.startPhoneCall();
@ -945,7 +951,7 @@ class _AgentViewState extends State<AgentView> 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<AgentView> 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<AgentView> 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<AgentView> 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<AgentView> 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<AgentView> 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,
),

2
lib/modules/agent/views/message_bubble.dart

@ -110,7 +110,7 @@ class MessageBubble extends GetView<AgentController> {
Padding(
padding: const EdgeInsets.only(left: 8),
child: Text(
"由AI生成".tr,
"generatedByAi".tr,// 由AI生成
style: TextStyle(
fontSize: 8,
color: Colors.blue[600],

10
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,

87
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<String> 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),
),

72
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<String, dynamic> now, bool isDarkMode) {
Widget _buildWeatherTip(
BuildContext context, Map<String, dynamic> now, bool isDarkMode) {
final weatherTip = _generateWeatherTip(now);
return Container(
@ -205,72 +208,79 @@ WeatherTip _generateWeatherTip(Map<String, dynamic> 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, // 翻译键代表的中文文本内容:今日天气适宜,是外出活动的好时光
);
}

5
lib/modules/agent/widgets/full_screen_editor.dart

@ -72,7 +72,7 @@ class _FullScreenEditorState extends State<FullScreenEditor> {
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<FullScreenEditor> {
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

18
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,

4
lib/modules/ota_upgrade/views/ota_upgrade_view.dart

@ -501,7 +501,7 @@ class OtaUpgradeView extends GetView<OtaUpgradeController> {
),
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<OtaUpgradeController> {
),
label: Text(
controller.isUpdateAvailable.value
? 'updateNow'.tr
? 'ota_updateNow'.tr
: 'latestVersion'.tr, // 立即更新 : 已是最新版本
style: TextStyle(
fontSize: 16.sp,

73
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); //设备授权失败,请检查授权码
}
}

7
lib/modules/pairing/views/pairing_view.dart

@ -328,7 +328,8 @@ class PairingView extends GetView<PairingController> {
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<PairingController> {
// 获取连接按钮图标
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;

85
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<String, dynamic>) {
// 检查响应是否包含错误
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<void> 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');
}
}

Loading…
Cancel
Save