diff --git a/.gitignore b/.gitignore index 61024af15..da0b68625 100644 --- a/.gitignore +++ b/.gitignore @@ -222,4 +222,5 @@ fastlane/readme.md .trae/rules/project_rules.md .augment/rules/imported/project_rules.md .kiro/ +.qoder/ ios/Runner.xcodeproj/project.pbxproj diff --git a/lib/core/translations/language/en_us.dart b/lib/core/translations/language/en_us.dart index e84efcb9d..d39444e27 100644 --- a/lib/core/translations/language/en_us.dart +++ b/lib/core/translations/language/en_us.dart @@ -241,6 +241,69 @@ const Map enUS = { 'totalQuota': 'Total Quota', 'remaining': 'Remaining', 'featureDescription': 'Feature Description', + 'paymentSuccess': 'Payment successful', + 'paymentFailed': 'Payment failed', + 'gotIt': 'Got it', + 'paymentFailedTryAgain': 'Payment failed. Please try again.', + 'selectPaymentMethod': 'Select payment method', + 'wechatPay': 'WeChat Pay', + 'alipayPay': 'Alipay', + 'paypalPay': 'PayPal', + 'appleIap': 'Apple IAP', + 'googleIap': 'Google IAP', + 'wechatOrderCreateFailed': 'Failed to create WeChat order', + 'alipayOrderCreateFailed': 'Failed to create Alipay order', + 'appleOrderCreateFailed': 'Failed to create Apple order', + 'googleOrderCreateFailed': 'Failed to create Google order', + 'paypalOrderCreateFailed': 'Failed to create PayPal order', + 'paymentException': 'Payment exception', + 'paymentLaunchFailed': 'Payment launch failed', + 'paymentExceptionWithError': 'Payment exception: @error', + 'paymentProcessingCheckLater': + 'Your order is being processed. Please check later.', + 'paymentResultQueryException': 'Failed to query payment result: @error', + 'orderConfirmedQuotaRefreshed': + 'Order confirmed. Your quota has been refreshed.', + 'paymentCompletedConfirming': 'Payment completed. Confirming…', + 'paymentCancelled': 'Payment cancelled', + 'paypalOpenedCompleteInBrowser': + 'PayPal opened. Please complete the payment in your browser.', + 'paypalOpenFailed': 'Unable to open PayPal payment page', + 'paymentTestTitle': 'Payment Test', + 'paymentTestOrderInfo': 'Test Order Info', + 'paymentTestProductId': 'Product ID', + 'paymentTestProductDescription': 'Product description', + 'paymentTestWechatDescription': 'WeChat payment test', + 'paymentTestAlipayDescription': 'Alipay payment test', + 'paymentTestAmount': 'Amount', + 'paymentTestSelectAmount': 'Select test amount', + 'paying': 'Paying...', + 'wechatPayWithAmount': 'WeChat Pay ¥@amount', + 'alipayPayWithAmount': 'Alipay ¥@amount', + 'paymentStatusTitle': 'Payment status', + 'errorInfoWithMessage': 'Error: @message', + 'retest': 'Retest', + 'paymentTestInstructionsTitle': 'Instructions', + 'paymentTestInstructionsContent': + '1. Select a test amount (recommended: ¥0.01)\n' + '2. Tap the "WeChat Pay" button\n' + '3. The app will invoke the WeChat Pay SDK\n' + '4. Complete the payment in WeChat\n' + '5. Return to the app to view the result\n\n' + 'Note: This is a test environment. No real charge will occur.', + 'startingWechatPayment': 'Starting WeChat Pay...', + 'startingAlipayPayment': 'Starting Alipay...', + 'wechatPaymentSuccess': 'WeChat Pay successful!', + 'wechatPaymentFailed': 'WeChat Pay failed', + 'wechatPaymentLaunchFailed': 'Failed to launch WeChat Pay', + 'cannotLaunchWechatPayment': 'Unable to launch WeChat Pay', + 'wechatPaymentException': 'WeChat Pay exception', + 'wechatPaymentTestCompleted': 'WeChat Pay test completed', + 'alipayPaymentSuccess': 'Alipay successful!', + 'alipayPaymentFailed': 'Alipay failed', + 'alipayPaymentLaunchFailed': 'Failed to launch Alipay', + 'cannotLaunchAlipayPayment': 'Unable to launch Alipay', + 'alipayPaymentException': 'Alipay exception', // AI 功能卡片 'musicAndRecommendation': 'Music & Recommendation', 'navigationAndRoutes': 'Navigation & Routes', diff --git a/lib/core/translations/language/zh_cn.dart b/lib/core/translations/language/zh_cn.dart index fa073ac5e..72c634ae7 100644 --- a/lib/core/translations/language/zh_cn.dart +++ b/lib/core/translations/language/zh_cn.dart @@ -232,6 +232,65 @@ const Map zhCN = { 'totalQuota': '总额度', 'remaining': '剩余', 'featureDescription': '功能说明', + 'paymentSuccess': '支付成功', + 'paymentFailed': '支付失败', + 'gotIt': '知道了', + 'paymentFailedTryAgain': '支付失败,请重试', + 'selectPaymentMethod': '选择支付方式', + 'wechatPay': '微信支付', + 'alipayPay': '支付宝支付', + 'paypalPay': 'PayPal', + 'appleIap': 'Apple 内购', + 'googleIap': 'Google 内购', + 'wechatOrderCreateFailed': '创建微信订单失败', + 'alipayOrderCreateFailed': '创建支付宝订单失败', + 'appleOrderCreateFailed': '创建 Apple 订单失败', + 'googleOrderCreateFailed': '创建 Google 订单失败', + 'paypalOrderCreateFailed': '创建 PayPal 订单失败', + 'paymentException': '支付异常', + 'paymentLaunchFailed': '支付启动失败', + 'paymentExceptionWithError': '支付异常: @error', + 'paymentProcessingCheckLater': '订单处理中,请稍后查看。', + 'paymentResultQueryException': '查询支付结果异常: @error', + 'orderConfirmedQuotaRefreshed': '订单已确认,额度已刷新', + 'paymentCompletedConfirming': '支付完成,正在确认', + 'paymentCancelled': '已取消支付', + 'paypalOpenedCompleteInBrowser': '已打开 PayPal,请在浏览器完成支付', + 'paypalOpenFailed': '无法打开 PayPal 支付页面', + 'paymentTestTitle': '支付测试', + 'paymentTestOrderInfo': '测试订单信息', + 'paymentTestProductId': '商品ID', + 'paymentTestProductDescription': '商品描述', + 'paymentTestWechatDescription': '微信支付测试', + 'paymentTestAlipayDescription': '支付宝支付测试', + 'paymentTestAmount': '支付金额', + 'paymentTestSelectAmount': '选择测试金额', + 'paying': '支付中...', + 'wechatPayWithAmount': '微信支付 ¥@amount', + 'alipayPayWithAmount': '支付宝支付 ¥@amount', + 'paymentStatusTitle': '支付状态', + 'errorInfoWithMessage': '错误信息: @message', + 'retest': '重新测试', + 'paymentTestInstructionsTitle': '使用说明', + 'paymentTestInstructionsContent': '1. 选择测试金额(建议使用0.01元进行测试)\n' + '2. 点击"发起微信支付"按钮\n' + '3. 系统将调用微信支付SDK\n' + '4. 在微信中完成支付流程\n' + '5. 返回应用查看支付结果\n\n' + '注意:这是测试环境,实际不会产生真实扣费', + 'startingWechatPayment': '正在发起微信支付...', + 'startingAlipayPayment': '正在发起支付宝支付...', + 'wechatPaymentSuccess': '微信支付成功!', + 'wechatPaymentFailed': '微信支付失败', + 'wechatPaymentLaunchFailed': '微信支付启动失败', + 'cannotLaunchWechatPayment': '无法启动微信支付', + 'wechatPaymentException': '微信支付异常', + 'wechatPaymentTestCompleted': '微信支付测试完成', + 'alipayPaymentSuccess': '支付宝支付成功!', + 'alipayPaymentFailed': '支付宝支付失败', + 'alipayPaymentLaunchFailed': '支付宝支付启动失败', + 'cannotLaunchAlipayPayment': '无法启动支付宝支付', + 'alipayPaymentException': '支付宝支付异常', // AI 功能卡片 'musicAndRecommendation': '听歌与推荐', 'navigationAndRoutes': '导航与路线', diff --git a/lib/core/translations/language/zh_hk.dart b/lib/core/translations/language/zh_hk.dart index 266839b4d..dc672f675 100644 --- a/lib/core/translations/language/zh_hk.dart +++ b/lib/core/translations/language/zh_hk.dart @@ -232,6 +232,65 @@ const Map zhHK = { 'totalQuota': '總額度', 'remaining': '剩餘', 'featureDescription': '功能說明', + 'paymentSuccess': '付款成功', + 'paymentFailed': '付款失敗', + 'gotIt': '知道了', + 'paymentFailedTryAgain': '付款失敗,請重試', + 'selectPaymentMethod': '選擇付款方式', + 'wechatPay': '微信支付', + 'alipayPay': '支付寶', + 'paypalPay': 'PayPal', + 'appleIap': 'Apple 內購', + 'googleIap': 'Google 內購', + 'wechatOrderCreateFailed': '建立微信訂單失敗', + 'alipayOrderCreateFailed': '建立支付寶訂單失敗', + 'appleOrderCreateFailed': '建立 Apple 訂單失敗', + 'googleOrderCreateFailed': '建立 Google 訂單失敗', + 'paypalOrderCreateFailed': '建立 PayPal 訂單失敗', + 'paymentException': '付款異常', + 'paymentLaunchFailed': '付款啟動失敗', + 'paymentExceptionWithError': '付款異常: @error', + 'paymentProcessingCheckLater': '訂單處理中,請稍後查看。', + 'paymentResultQueryException': '查詢付款結果異常: @error', + 'orderConfirmedQuotaRefreshed': '訂單已確認,額度已更新', + 'paymentCompletedConfirming': '付款完成,正在確認', + 'paymentCancelled': '已取消付款', + 'paypalOpenedCompleteInBrowser': '已開啟 PayPal,請在瀏覽器完成付款', + 'paypalOpenFailed': '無法開啟 PayPal 付款頁面', + 'paymentTestTitle': '付款測試', + 'paymentTestOrderInfo': '測試訂單資訊', + 'paymentTestProductId': '商品ID', + 'paymentTestProductDescription': '商品描述', + 'paymentTestWechatDescription': '微信支付測試', + 'paymentTestAlipayDescription': '支付寶支付測試', + 'paymentTestAmount': '付款金額', + 'paymentTestSelectAmount': '選擇測試金額', + 'paying': '付款中...', + 'wechatPayWithAmount': '微信支付 ¥@amount', + 'alipayPayWithAmount': '支付寶 ¥@amount', + 'paymentStatusTitle': '付款狀態', + 'errorInfoWithMessage': '錯誤資訊: @message', + 'retest': '重新測試', + 'paymentTestInstructionsTitle': '使用說明', + 'paymentTestInstructionsContent': '1. 選擇測試金額(建議使用0.01元進行測試)\n' + '2. 點擊「微信支付」按鈕\n' + '3. 系統將呼叫微信支付 SDK\n' + '4. 在微信中完成付款流程\n' + '5. 返回應用查看付款結果\n\n' + '注意:這是測試環境,不會產生真實扣費', + 'startingWechatPayment': '正在發起微信支付...', + 'startingAlipayPayment': '正在發起支付寶支付...', + 'wechatPaymentSuccess': '微信支付成功!', + 'wechatPaymentFailed': '微信支付失敗', + 'wechatPaymentLaunchFailed': '微信支付啟動失敗', + 'cannotLaunchWechatPayment': '無法啟動微信支付', + 'wechatPaymentException': '微信支付異常', + 'wechatPaymentTestCompleted': '微信支付測試完成', + 'alipayPaymentSuccess': '支付寶支付成功!', + 'alipayPaymentFailed': '支付寶支付失敗', + 'alipayPaymentLaunchFailed': '支付寶支付啟動失敗', + 'cannotLaunchAlipayPayment': '無法啟動支付寶支付', + 'alipayPaymentException': '支付寶支付異常', // AI 功能卡片 'musicAndRecommendation': '聽歌與推薦', 'navigationAndRoutes': '導航與路線', diff --git a/lib/core/translations/language/zh_tw.dart b/lib/core/translations/language/zh_tw.dart index d755b1a07..cefe53f35 100644 --- a/lib/core/translations/language/zh_tw.dart +++ b/lib/core/translations/language/zh_tw.dart @@ -232,6 +232,65 @@ const Map zhTW = { 'totalQuota': '總額度', 'remaining': '剩餘', 'featureDescription': '功能說明', + 'paymentSuccess': '付款成功', + 'paymentFailed': '付款失敗', + 'gotIt': '知道了', + 'paymentFailedTryAgain': '付款失敗,請重試', + 'selectPaymentMethod': '選擇付款方式', + 'wechatPay': '微信支付', + 'alipayPay': '支付寶', + 'paypalPay': 'PayPal', + 'appleIap': 'Apple 內購', + 'googleIap': 'Google 內購', + 'wechatOrderCreateFailed': '建立微信訂單失敗', + 'alipayOrderCreateFailed': '建立支付寶訂單失敗', + 'appleOrderCreateFailed': '建立 Apple 訂單失敗', + 'googleOrderCreateFailed': '建立 Google 訂單失敗', + 'paypalOrderCreateFailed': '建立 PayPal 訂單失敗', + 'paymentException': '付款異常', + 'paymentLaunchFailed': '付款啟動失敗', + 'paymentExceptionWithError': '付款異常: @error', + 'paymentProcessingCheckLater': '訂單處理中,請稍後查看。', + 'paymentResultQueryException': '查詢付款結果異常: @error', + 'orderConfirmedQuotaRefreshed': '訂單已確認,額度已更新', + 'paymentCompletedConfirming': '付款完成,正在確認', + 'paymentCancelled': '已取消付款', + 'paypalOpenedCompleteInBrowser': '已開啟 PayPal,請在瀏覽器完成付款', + 'paypalOpenFailed': '無法開啟 PayPal 付款頁面', + 'paymentTestTitle': '付款測試', + 'paymentTestOrderInfo': '測試訂單資訊', + 'paymentTestProductId': '商品ID', + 'paymentTestProductDescription': '商品描述', + 'paymentTestWechatDescription': '微信支付測試', + 'paymentTestAlipayDescription': '支付寶支付測試', + 'paymentTestAmount': '付款金額', + 'paymentTestSelectAmount': '選擇測試金額', + 'paying': '付款中...', + 'wechatPayWithAmount': '微信支付 ¥@amount', + 'alipayPayWithAmount': '支付寶 ¥@amount', + 'paymentStatusTitle': '付款狀態', + 'errorInfoWithMessage': '錯誤資訊: @message', + 'retest': '重新測試', + 'paymentTestInstructionsTitle': '使用說明', + 'paymentTestInstructionsContent': '1. 選擇測試金額(建議使用0.01元進行測試)\n' + '2. 點擊「微信支付」按鈕\n' + '3. 系統將呼叫微信支付 SDK\n' + '4. 在微信中完成付款流程\n' + '5. 返回應用查看付款結果\n\n' + '注意:這是測試環境,不會產生真實扣費', + 'startingWechatPayment': '正在發起微信支付...', + 'startingAlipayPayment': '正在發起支付寶支付...', + 'wechatPaymentSuccess': '微信支付成功!', + 'wechatPaymentFailed': '微信支付失敗', + 'wechatPaymentLaunchFailed': '微信支付啟動失敗', + 'cannotLaunchWechatPayment': '無法啟動微信支付', + 'wechatPaymentException': '微信支付異常', + 'wechatPaymentTestCompleted': '微信支付測試完成', + 'alipayPaymentSuccess': '支付寶支付成功!', + 'alipayPaymentFailed': '支付寶支付失敗', + 'alipayPaymentLaunchFailed': '支付寶支付啟動失敗', + 'cannotLaunchAlipayPayment': '無法啟動支付寶支付', + 'alipayPaymentException': '支付寶支付異常', // AI 功能卡片 'musicAndRecommendation': '聽歌與推薦', 'navigationAndRoutes': '導航與路線', diff --git a/lib/modules/goods/controllers/goods_base_controller.dart b/lib/modules/goods/controllers/goods_base_controller.dart index 14a779abc..f7aee8219 100644 --- a/lib/modules/goods/controllers/goods_base_controller.dart +++ b/lib/modules/goods/controllers/goods_base_controller.dart @@ -26,7 +26,7 @@ abstract class GoodsBaseController extends GetxController { @override void onInit() { super.onInit(); - _init(); + _init(); // 初始化商品列表 // 处理冷启动场景:如果 App 通过深链直接启动 _handleInitialDeepLink(); } @@ -42,10 +42,10 @@ abstract class GoodsBaseController extends GetxController { Future _init() async { loading.value = true; - error.value = ''; + error.value = ''; // 重置错误信息 try { - final list = await fetchProducts(); - items.assignAll(list); + final list = await fetchProducts(); // 获取商品列表 + items.assignAll(list); // 更新商品列表 // iOS 环境下,在页面加载后批量查询当前商品的 IAP 详情,便于排查 StoreKit 可用商品 await _debugQueryIapProductsIfIos(); } catch (e) { @@ -84,21 +84,22 @@ abstract class GoodsBaseController extends GetxController { /// 统一入口:根据后端配置决定是否弹出支付方式选择面板 Future purchase(DBGoods item) async { - // 读取渠道配置 + // 1. 获取可用的支付方式 final enabled = _getEnabledPayMethods(); - // 无配置或多个渠道:弹出选择面板 + // 2. 无配置或多个渠道:弹出选择面板 _PayMethod? method; if (enabled.length != 1) { method = await _showPayMethodSheet(enabled); if (method == null) return; } else { - // 仅一个渠道:直接走对应支付 + // 3. 仅一个渠道:直接走对应支付 method = enabled.first; } + // 4. 根据选择的支付方式执行支付 bool ok = false; - String failMsg = '支付失败,请重试'; + String failMsg = 'paymentFailedTryAgain'.tr; // 支付失败,请重试 isPaying.value = true; _startPayingTimeout(); if (method == _PayMethod.wechat) { @@ -122,9 +123,9 @@ abstract class GoodsBaseController extends GetxController { if (!success) failMsg = msg ?? failMsg; }); } - + // 5. 处理失败结果 if (!ok) { - Get.snackbar('提示', failMsg, + Get.snackbar('tip'.tr, failMsg, snackPosition: SnackPosition.BOTTOM, margin: const EdgeInsets.all(12)); } @@ -133,8 +134,10 @@ abstract class GoodsBaseController extends GetxController { /// 解析后端 paychannels 并结合平台过滤可用支付方式 List<_PayMethod> _getEnabledPayMethods() { try { + //1. 获取后端配置的支付渠道 final paychannels = VersionUpdateService.to.cachedAppInfo?.paychannels ?? ''; + print('[Pay] 后端配置的支付渠道: $paychannels'); final raw = paychannels .split(',') .map((e) => e.trim().toLowerCase()) @@ -230,7 +233,7 @@ abstract class GoodsBaseController extends GetxController { crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - '选择支付方式', + 'selectPaymentMethod'.tr, // 选择支付方式 style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, @@ -266,7 +269,7 @@ abstract class GoodsBaseController extends GetxController { ), const SizedBox(height: 8), Text( - '微信支付', + 'wechatPay'.tr, // 微信支付 style: TextStyle( fontSize: 13, color: isDark ? Colors.white : Colors.black, @@ -300,7 +303,7 @@ abstract class GoodsBaseController extends GetxController { ), const SizedBox(height: 8), Text( - '支付宝', + 'alipayPay'.tr, // 支付宝 style: TextStyle( fontSize: 13, color: isDark ? Colors.white : Colors.black, @@ -336,7 +339,7 @@ abstract class GoodsBaseController extends GetxController { ), const SizedBox(height: 8), Text( - 'PayPal', + 'paypalPay'.tr, // PayPal style: TextStyle( fontSize: 13, color: isDark ? Colors.white : Colors.black, @@ -372,7 +375,7 @@ abstract class GoodsBaseController extends GetxController { ), const SizedBox(height: 8), Text( - 'Apple 内购', + 'appleIap'.tr, // Apple 内购 style: TextStyle( fontSize: 13, color: isDark ? Colors.white : Colors.black, @@ -408,7 +411,7 @@ abstract class GoodsBaseController extends GetxController { ), const SizedBox(height: 8), Text( - 'Google 内购', + 'googleIap'.tr, // Google 内购 style: TextStyle( fontSize: 13, color: isDark ? Colors.white : Colors.black, @@ -445,7 +448,7 @@ abstract class GoodsBaseController extends GetxController { notifyUrl: '$serverUrl/api/home/pay_wechatnotify', ); if (paymentData == null) { - onResult?.call(false, '创建微信订单失败'); + onResult?.call(false, 'wechatOrderCreateFailed'.tr); // 创建微信订单失败 isPaying.value = false; _cancelPayingTimeout(); return false; @@ -465,7 +468,7 @@ abstract class GoodsBaseController extends GetxController { } else { isPaying.value = false; _cancelPayingTimeout(); - _showPayResultDialog(false, msg ?? '支付失败'); + _showPayResultDialog(false, msg ?? 'paymentFailed'.tr); // 支付失败 } }, ); @@ -482,7 +485,7 @@ abstract class GoodsBaseController extends GetxController { notifyUrl: 'https://api.ideapsound.com/api/home/pay_alipaynotify', ); if (orderInfo == null) { - onResult?.call(false, '创建支付宝订单失败'); + onResult?.call(false, 'alipayOrderCreateFailed'.tr); // 创建支付宝订单失败 isPaying.value = false; _cancelPayingTimeout(); return false; @@ -500,7 +503,7 @@ abstract class GoodsBaseController extends GetxController { } else { isPaying.value = false; _cancelPayingTimeout(); - _showPayResultDialog(false, msg ?? '支付失败'); + _showPayResultDialog(false, msg ?? 'paymentFailed'.tr); // 支付失败 } }, ); @@ -517,7 +520,7 @@ abstract class GoodsBaseController extends GetxController { amount: item.price, ); if (orderId == null || orderId.isEmpty) { - onResult?.call(false, '创建 Apple 订单失败'); + onResult?.call(false, 'appleOrderCreateFailed'.tr); // 创建 Apple 订单失败 isPaying.value = false; _cancelPayingTimeout(); return false; @@ -547,7 +550,7 @@ abstract class GoodsBaseController extends GetxController { isPaying.value = false; _cancelPayingTimeout(); } else { - Get.snackbar('提示', msg, + Get.snackbar('tip'.tr, msg, snackPosition: SnackPosition.BOTTOM, margin: const EdgeInsets.all(12)); } @@ -555,7 +558,10 @@ abstract class GoodsBaseController extends GetxController { }, ); } catch (e) { - onResult?.call(false, 'Apple 内购异常: $e'); + onResult?.call( + false, + 'paymentExceptionWithError' + .trParams({'error': e.toString()})); // 支付异常: @error isPaying.value = false; _cancelPayingTimeout(); return false; @@ -573,7 +579,7 @@ abstract class GoodsBaseController extends GetxController { amount: item.price, ); if (orderId == null || orderId.isEmpty) { - onResult?.call(false, '创建 Google 订单失败'); + onResult?.call(false, 'googleOrderCreateFailed'.tr); // 创建 Google 订单失败 isPaying.value = false; _cancelPayingTimeout(); return false; @@ -602,7 +608,7 @@ abstract class GoodsBaseController extends GetxController { isPaying.value = false; _cancelPayingTimeout(); } else { - Get.snackbar('提示', msg, + Get.snackbar('tip'.tr, msg, snackPosition: SnackPosition.BOTTOM, margin: const EdgeInsets.all(12)); } @@ -610,7 +616,10 @@ abstract class GoodsBaseController extends GetxController { }, ); } catch (e) { - onResult?.call(false, 'Google 内购异常: $e'); + onResult?.call( + false, + 'paymentExceptionWithError' + .trParams({'error': e.toString()})); // 支付异常: @error isPaying.value = false; _cancelPayingTimeout(); return false; @@ -641,11 +650,12 @@ abstract class GoodsBaseController extends GetxController { }) async { // 若无法获取订单号,直接弹成功提示但提醒稍后刷新 if (orderId == null || orderId.isEmpty) { - _showPayResultDialog(true, '${channel}支付成功,订单处理中,请稍后查看。'); + _showPayResultDialog( + true, 'paymentProcessingCheckLater'.tr); // 订单处理中,请稍后查看 return; } - String message = initialMessage ?? '${channel}支付成功'; + String message = initialMessage ?? 'paymentSuccess'.tr; // 支付成功 bool success = false; try { // 简单轮询回查,避免回调延迟 @@ -677,7 +687,8 @@ abstract class GoodsBaseController extends GetxController { } catch (_) {} } } catch (e) { - message = '查询支付结果异常: $e'; + message = 'paymentResultQueryException' + .trParams({'error': e.toString()}); // 查询支付结果异常: @error } _showPayResultDialog(success, message); } @@ -695,7 +706,7 @@ abstract class GoodsBaseController extends GetxController { if (orderStatus == 1 && user != null) { User.instance.updateUserInfo(user); _payService.setVipExptime(User.instance.vipexptime); - Get.snackbar('提示', '订单已确认,额度已刷新', + Get.snackbar('tip'.tr, 'orderConfirmedQuotaRefreshed'.tr, snackPosition: SnackPosition.BOTTOM, margin: const EdgeInsets.all(12)); return; @@ -718,6 +729,8 @@ abstract class GoodsBaseController extends GetxController { final context = Get.context; final isDark = context != null && Theme.of(context).brightness == Brightness.dark; + final titleText = + success ? 'paymentSuccess'.tr : 'paymentFailed'.tr; // 支付成功/支付失败 Get.dialog( Dialog( insetPadding: const EdgeInsets.symmetric(horizontal: 24, vertical: 24), @@ -753,7 +766,7 @@ abstract class GoodsBaseController extends GetxController { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - success ? '支付成功' : '支付失败', + titleText, style: TextStyle( fontSize: 18, fontWeight: FontWeight.w700, @@ -781,7 +794,7 @@ abstract class GoodsBaseController extends GetxController { children: [ TextButton( onPressed: () => Get.back(), - child: const Text('知道了'), + child: Text('gotIt'.tr), // 知道了 ), ], ), @@ -817,7 +830,7 @@ abstract class GoodsBaseController extends GetxController { notifyUrl: 'https://api.ideapsound.com/api/home/pay_paypalnotify', ); if (approvalUrl == null) { - onResult?.call(false, '创建 PayPal 订单失败'); + onResult?.call(false, 'paypalOrderCreateFailed'.tr); // 创建 PayPal 订单失败 isPaying.value = false; _cancelPayingTimeout(); return false; @@ -846,14 +859,14 @@ abstract class GoodsBaseController extends GetxController { await _confirmOrderAndShow( orderId, channel: 'PayPal', - initialMessage: '支付完成,正在确认', + initialMessage: 'paymentCompletedConfirming'.tr, // 支付完成,正在确认 retries: 1, intervalMs: 0, ); } else if (path == '/cancel') { isPaying.value = false; _cancelPayingTimeout(); - _showPayResultDialog(false, '已取消支付'); + _showPayResultDialog(false, 'paymentCancelled'.tr); // 已取消支付 } // 一次性监听,处理后即取消 _deeplinkSub?.cancel(); @@ -871,12 +884,13 @@ abstract class GoodsBaseController extends GetxController { if (success) { // 仅提示已打开授权页面,不在此处回查与弹窗,等待深链回跳后再处理 print('[PayPal] 已打开授权页面,等待回跳后再确认。orderId: $orderId'); - Get.snackbar('提示', msg ?? '已打开 PayPal,请在浏览器完成支付', + Get.snackbar('tip'.tr, msg ?? 'paypalOpenedCompleteInBrowser'.tr, snackPosition: SnackPosition.BOTTOM, margin: const EdgeInsets.all(12)); } else { // 无法打开授权页才提示失败 - _showPayResultDialog(false, msg ?? '无法打开 PayPal 支付页面'); + _showPayResultDialog( + false, msg ?? 'paypalOpenFailed'.tr); // 无法打开 PayPal 支付页面 } }, ); @@ -899,13 +913,13 @@ abstract class GoodsBaseController extends GetxController { await _confirmOrderAndShow( orderId, channel: 'PayPal', - initialMessage: '支付完成,正在确认', + initialMessage: 'paymentCompletedConfirming'.tr, // 支付完成,正在确认 retries: 1, intervalMs: 0, ); } } else if (uri.path == '/cancel') { - _showPayResultDialog(false, '已取消支付'); + _showPayResultDialog(false, 'paymentCancelled'.tr); // 已取消支付 } } } catch (_) { diff --git a/lib/modules/payment/controllers/payment_controller.dart b/lib/modules/payment/controllers/payment_controller.dart index 886a8d7f4..be852a8ca 100644 --- a/lib/modules/payment/controllers/payment_controller.dart +++ b/lib/modules/payment/controllers/payment_controller.dart @@ -27,32 +27,32 @@ class PaymentController extends GetxController { Future testWechatPayment() async { try { isLoading.value = true; - paymentStatus.value = '正在发起微信支付...'; + paymentStatus.value = 'startingWechatPayment'.tr; // 正在发起微信支付... errorMessage.value = ''; // 调用支付服务,使用回调处理结果 final launched = await _payService.processWechatPayment( productId: testProductId.value, amount: (testAmount.value * 100).toInt(), // 转换为分 - description: '微信支付测试', + description: 'paymentTestWechatDescription'.tr, // 微信支付测试 onResult: (success, message) { // 支付结果回调 isLoading.value = false; if (success) { - paymentStatus.value = '微信支付成功!'; + paymentStatus.value = 'wechatPaymentSuccess'.tr; // 微信支付成功! errorMessage.value = ''; Get.snackbar( - '支付成功', - message ?? '微信支付测试完成', + 'paymentSuccess'.tr, // 支付成功 + message ?? 'wechatPaymentTestCompleted'.tr, // 微信支付测试完成 snackPosition: SnackPosition.TOP, ); } else { - paymentStatus.value = '微信支付失败'; - errorMessage.value = message ?? '未知错误'; + paymentStatus.value = 'wechatPaymentFailed'.tr; // 微信支付失败 + errorMessage.value = message ?? 'unknownError'.tr; // 未知错误 Get.snackbar( - '支付失败', - message ?? '未知错误', + 'paymentFailed'.tr, // 支付失败 + message ?? 'unknownError'.tr, // 未知错误 snackPosition: SnackPosition.TOP, ); } @@ -62,15 +62,15 @@ class PaymentController extends GetxController { if (!launched) { // 如果支付没有成功启动 isLoading.value = false; - paymentStatus.value = '微信支付启动失败'; - errorMessage.value = '无法启动微信支付'; - Get.snackbar('支付启动失败', '无法启动微信支付'); + paymentStatus.value = 'wechatPaymentLaunchFailed'.tr; // 微信支付启动失败 + errorMessage.value = 'cannotLaunchWechatPayment'.tr; // 无法启动微信支付 + Get.snackbar('paymentLaunchFailed'.tr, 'cannotLaunchWechatPayment'.tr); } } catch (e) { isLoading.value = false; - paymentStatus.value = '微信支付异常'; + paymentStatus.value = 'wechatPaymentException'.tr; // 微信支付异常 errorMessage.value = e.toString(); - Get.snackbar('支付异常', e.toString()); + Get.snackbar('paymentException'.tr, e.toString()); // 支付异常 } } @@ -78,24 +78,24 @@ class PaymentController extends GetxController { Future testAlipayPayment() async { try { isLoading.value = true; - paymentStatus.value = '正在发起支付宝支付...'; + paymentStatus.value = 'startingAlipayPayment'.tr; // 正在发起支付宝支付... errorMessage.value = ''; // 调用支付宝支付服务 final launched = await _payService.processAlipayPayment( productId: testProductId.value, // 这里传递的是产品ID amount: (testAmount.value * 100).toInt(), // 转换为分 - description: '支付宝支付测试', + description: 'paymentTestAlipayDescription'.tr, // 支付宝支付测试 onResult: (success, message) { // 支付结果回调 isLoading.value = false; if (success) { - paymentStatus.value = '支付宝支付成功!'; + paymentStatus.value = 'alipayPaymentSuccess'.tr; // 支付宝支付成功! errorMessage.value = ''; } else { - paymentStatus.value = '支付宝支付失败'; - errorMessage.value = message; + paymentStatus.value = 'alipayPaymentFailed'.tr; // 支付宝支付失败 + errorMessage.value = message ?? 'unknownError'.tr; // 未知错误 } }, ); @@ -103,15 +103,15 @@ class PaymentController extends GetxController { if (!launched) { // 如果支付没有成功启动 isLoading.value = false; - paymentStatus.value = '支付宝支付启动失败'; - errorMessage.value = '无法启动支付宝支付'; - Get.snackbar('支付启动失败', '无法启动支付宝支付'); + paymentStatus.value = 'alipayPaymentLaunchFailed'.tr; // 支付宝支付启动失败 + errorMessage.value = 'cannotLaunchAlipayPayment'.tr; // 无法启动支付宝支付 + Get.snackbar('paymentLaunchFailed'.tr, 'cannotLaunchAlipayPayment'.tr); } } catch (e) { isLoading.value = false; - paymentStatus.value = '支付宝支付异常'; + paymentStatus.value = 'alipayPaymentException'.tr; // 支付宝支付异常 errorMessage.value = e.toString(); - Get.snackbar('支付异常', e.toString()); + Get.snackbar('paymentException'.tr, e.toString()); // 支付异常 } } diff --git a/lib/modules/payment/views/payment_view.dart b/lib/modules/payment/views/payment_view.dart index c7014ebf7..d0dedd7ff 100644 --- a/lib/modules/payment/views/payment_view.dart +++ b/lib/modules/payment/views/payment_view.dart @@ -16,7 +16,7 @@ class PaymentView extends GetView { backgroundColor: isDarkMode ? Colors.black : Colors.white, elevation: 0.5, title: Text( - '支付测试', + 'paymentTestTitle'.tr, // 支付测试 style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.w600, @@ -76,7 +76,7 @@ class PaymentView extends GetView { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '测试订单信息', + 'paymentTestOrderInfo'.tr, // 测试订单信息 style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, @@ -85,12 +85,17 @@ class PaymentView extends GetView { ), SizedBox(height: 12.h), Obx(() => _buildInfoRow( - '商品ID', controller.testProductId.value, isDarkMode)), + 'paymentTestProductId'.tr, // 商品ID + controller.testProductId.value, + isDarkMode)), SizedBox(height: 8.h), - _buildInfoRow('商品描述', '微信支付测试', isDarkMode), + _buildInfoRow( + 'paymentTestProductDescription'.tr, // 商品描述 + 'paymentTestWechatDescription'.tr, // 微信支付测试 + isDarkMode), SizedBox(height: 8.h), Obx(() => _buildInfoRow( - '支付金额', + 'paymentTestAmount'.tr, // 支付金额 '¥${controller.testAmount.value.toStringAsFixed(2)}', isDarkMode)), ], @@ -147,7 +152,7 @@ class PaymentView extends GetView { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '选择测试金额', + 'paymentTestSelectAmount'.tr, // 选择测试金额 style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, @@ -209,7 +214,7 @@ class PaymentView extends GetView { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '选择支付方式', + 'selectPaymentMethod'.tr, // 选择支付方式 style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, @@ -222,7 +227,7 @@ class PaymentView extends GetView { children: [ _buildPaymentMethodOption( method: 1, - title: '微信支付', + title: 'wechatPay'.tr, // 微信支付 icon: Icons.wechat, iconColor: Colors.green, isDarkMode: isDarkMode, @@ -230,7 +235,7 @@ class PaymentView extends GetView { SizedBox(height: 12.h), _buildPaymentMethodOption( method: 2, - title: '支付宝支付', + title: 'alipayPay'.tr, // 支付宝支付 icon: Icons.account_balance_wallet, iconColor: Colors.blue, isDarkMode: isDarkMode, @@ -320,7 +325,7 @@ class PaymentView extends GetView { ), elevation: 2, ), - child: controller.isLoading.value + child: controller.isLoading.value ? Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -335,7 +340,7 @@ class PaymentView extends GetView { ), SizedBox(width: 12.w), Text( - '支付中...', + 'paying'.tr, // 支付中... style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, @@ -357,8 +362,16 @@ class PaymentView extends GetView { SizedBox(width: 8.w), Text( controller.selectedPaymentMethod.value == 1 - ? '微信支付 ¥${controller.testAmount.value.toStringAsFixed(2)}' - : '支付宝支付 ¥${controller.testAmount.value.toStringAsFixed(2)}', + ? 'wechatPayWithAmount'.trParams({ + 'amount': + controller.testAmount.value.toStringAsFixed( + 2) + }) // 微信支付 ¥@amount + : 'alipayPayWithAmount'.trParams({ + 'amount': + controller.testAmount.value.toStringAsFixed( + 2) + }), // 支付宝支付 ¥@amount style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, @@ -404,7 +417,7 @@ class PaymentView extends GetView { ), SizedBox(width: 8.w), Text( - '支付状态', + 'paymentStatusTitle'.tr, // 支付状态 style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, @@ -424,7 +437,8 @@ class PaymentView extends GetView { if (controller.errorMessage.value.isNotEmpty) ...[ SizedBox(height: 8.h), Text( - '错误信息: ${controller.errorMessage.value}', + 'errorInfoWithMessage'.trParams( + {'message': controller.errorMessage.value}), // 错误信息: @message style: TextStyle( fontSize: 12.sp, color: Colors.red[600], @@ -442,7 +456,7 @@ class PaymentView extends GetView { ), ), child: Text( - '重新测试', + 'retest'.tr, // 重新测试 style: TextStyle( color: isError ? Colors.red[600] : Colors.green[600], ), @@ -479,7 +493,7 @@ class PaymentView extends GetView { ), SizedBox(width: 8.w), Text( - '使用说明', + 'paymentTestInstructionsTitle'.tr, // 使用说明 style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, @@ -490,12 +504,7 @@ class PaymentView extends GetView { ), SizedBox(height: 12.h), Text( - '1. 选择测试金额(建议使用0.01元进行测试)\n' - '2. 点击"发起微信支付"按钮\n' - '3. 系统将调用微信支付SDK\n' - '4. 在微信中完成支付流程\n' - '5. 返回应用查看支付结果\n\n' - '注意:这是测试环境,实际不会产生真实扣费', + 'paymentTestInstructionsContent'.tr, // 1. 选择测试金额(建议使用0.01元进行测试)... style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.grey[300] : Colors.grey[700],