From 3a8ff649218ff463975354c2848aca36d76da9e1 Mon Sep 17 00:00:00 2001 From: wangjia <809946525@qq.com> Date: Mon, 13 Jul 2026 09:56:22 +0800 Subject: [PATCH] =?UTF-8?q?fix(client):=20=E5=AE=A1=E8=AE=A1=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E2=80=94=E2=80=94device=5Flimit=20=E7=9B=B8=E5=AF=B9?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E8=B5=B0=20relativeTime=20=E5=8D=95=E6=BA=90?= =?UTF-8?q?+=E8=A3=B8=20Icons=20=E6=8D=A2=20PangolinIcons+Payment=20onDone?= =?UTF-8?q?=20=E4=B8=89=E5=A4=84=E6=8E=A5=E9=80=9A+=E5=86=85=E8=81=94?= =?UTF-8?q?=E5=8F=8C=E8=AF=AD=E6=96=87=E6=A1=88=E6=94=B6=E8=BF=9B=20AppTex?= =?UTF-8?q?t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/lib/l10n/app_text.dart | 3 +++ client/lib/l10n/strings_en.dart | 6 +++++ client/lib/l10n/strings_es.dart | 6 +++++ client/lib/l10n/strings_ja.dart | 6 +++++ client/lib/l10n/strings_ko.dart | 6 +++++ client/lib/l10n/strings_ru.dart | 6 +++++ client/lib/l10n/strings_zh.dart | 6 +++++ client/lib/screens/account_page.dart | 9 +++---- client/lib/screens/device_limit_screen.dart | 26 ++++++++------------- client/lib/screens/orders_page.dart | 12 +++++++++- client/lib/screens/payment_page.dart | 7 +++--- client/lib/screens/purchase_page.dart | 8 +++---- client/lib/widgets/update_dialog.dart | 2 +- 13 files changed, 73 insertions(+), 30 deletions(-) diff --git a/client/lib/l10n/app_text.dart b/client/lib/l10n/app_text.dart index 59dbbb0..493d81c 100644 --- a/client/lib/l10n/app_text.dart +++ b/client/lib/l10n/app_text.dart @@ -565,6 +565,9 @@ abstract class AppText { String get switchPayMethod; // 换一种支付方式 / Switch payment method String get cancelOrder; // 取消订单 / Cancel order String get qrNotSupported; + String get orderCreateFailed; // 下单失败,请稍后重试 / Failed to create order, please retry(errorZh/En 为空时兜底) + String get payUnsupportedRenderType; // 暂不支持,请换支付方式 / Unsupported, switch payment method + String get payNoActiveOrder; // 暂无进行中的订单 / No active order // ── 支付渠道 switch + 订单 ── String get payChannel; diff --git a/client/lib/l10n/strings_en.dart b/client/lib/l10n/strings_en.dart index 94befe1..0722292 100644 --- a/client/lib/l10n/strings_en.dart +++ b/client/lib/l10n/strings_en.dart @@ -427,6 +427,12 @@ class StringsEn extends AppText { String get cancelOrder => 'Cancel order'; @override String get qrNotSupported => 'Copy and open in Alipay'; + @override + String get orderCreateFailed => 'Failed to create order, please retry'; + @override + String get payUnsupportedRenderType => 'Unsupported, switch payment method'; + @override + String get payNoActiveOrder => 'No active order'; // ── 支付渠道 switch + 订单 ── @override diff --git a/client/lib/l10n/strings_es.dart b/client/lib/l10n/strings_es.dart index 3691752..fe0eb13 100644 --- a/client/lib/l10n/strings_es.dart +++ b/client/lib/l10n/strings_es.dart @@ -428,6 +428,12 @@ class StringsEs extends AppText { String get cancelOrder => 'Cancelar pedido'; @override String get qrNotSupported => 'Copia el contenido y ábrelo en Alipay'; + @override + String get orderCreateFailed => 'Error al crear el pedido, inténtalo de nuevo más tarde'; + @override + String get payUnsupportedRenderType => 'No compatible, cambia el método de pago'; + @override + String get payNoActiveOrder => 'No hay pedidos activos'; // ── 支付渠道 switch + 订单 ── @override diff --git a/client/lib/l10n/strings_ja.dart b/client/lib/l10n/strings_ja.dart index dedbabe..eb66607 100644 --- a/client/lib/l10n/strings_ja.dart +++ b/client/lib/l10n/strings_ja.dart @@ -428,6 +428,12 @@ class StringsJa extends AppText { String get cancelOrder => '注文をキャンセル'; @override String get qrNotSupported => '内容をコピーしてAlipayで開いてください'; + @override + String get orderCreateFailed => '注文の作成に失敗しました。しばらくして再試行してください'; + @override + String get payUnsupportedRenderType => '未対応です。支払い方法を変更してください'; + @override + String get payNoActiveOrder => '進行中の注文はありません'; // ── 支付渠道 switch + 订单 ── @override diff --git a/client/lib/l10n/strings_ko.dart b/client/lib/l10n/strings_ko.dart index d5463e3..1ab07cc 100644 --- a/client/lib/l10n/strings_ko.dart +++ b/client/lib/l10n/strings_ko.dart @@ -428,6 +428,12 @@ class StringsKo extends AppText { String get cancelOrder => '주문 취소'; @override String get qrNotSupported => '내용을 복사해 Alipay에서 여세요'; + @override + String get orderCreateFailed => '주문 생성에 실패했습니다. 잠시 후 다시 시도하세요'; + @override + String get payUnsupportedRenderType => '지원되지 않습니다. 결제 방법을 변경하세요'; + @override + String get payNoActiveOrder => '진행 중인 주문이 없습니다'; // ── 支付渠道 switch + 订单 ── @override diff --git a/client/lib/l10n/strings_ru.dart b/client/lib/l10n/strings_ru.dart index 64093ce..746be16 100644 --- a/client/lib/l10n/strings_ru.dart +++ b/client/lib/l10n/strings_ru.dart @@ -428,6 +428,12 @@ class StringsRu extends AppText { String get cancelOrder => 'Отменить заказ'; @override String get qrNotSupported => 'Скопируйте и откройте в Alipay'; + @override + String get orderCreateFailed => 'Не удалось создать заказ, повторите попытку позже'; + @override + String get payUnsupportedRenderType => 'Не поддерживается, смените способ оплаты'; + @override + String get payNoActiveOrder => 'Нет активных заказов'; // ── 支付渠道 switch + 订单 ── @override diff --git a/client/lib/l10n/strings_zh.dart b/client/lib/l10n/strings_zh.dart index 2a165d9..eaab549 100644 --- a/client/lib/l10n/strings_zh.dart +++ b/client/lib/l10n/strings_zh.dart @@ -421,6 +421,12 @@ class StringsZh extends AppText { String get cancelOrder => '取消订单'; @override String get qrNotSupported => '请复制内容后在支付宝内打开'; + @override + String get orderCreateFailed => '下单失败,请稍后重试'; + @override + String get payUnsupportedRenderType => '暂不支持,请换支付方式'; + @override + String get payNoActiveOrder => '暂无进行中的订单'; // ── 支付渠道 switch + 订单 ── @override diff --git a/client/lib/screens/account_page.dart b/client/lib/screens/account_page.dart index 651e211..614c961 100644 --- a/client/lib/screens/account_page.dart +++ b/client/lib/screens/account_page.dart @@ -64,8 +64,8 @@ class AccountPage extends ConsumerWidget { NavView.purchase, PurchaseScreen( t: t, - onOrderCreated: () => Navigator.of(context) - .push(MaterialPageRoute(builder: (_) => PaymentScreen(t: t))), + onOrderCreated: () => Navigator.of(context).push(MaterialPageRoute( + builder: (_) => PaymentScreen(t: t, onDone: () => Navigator.of(context).pop()))), ), ), ), @@ -87,8 +87,9 @@ class AccountPage extends ConsumerWidget { NavView.purchase, PurchaseScreen( t: t, - onOrderCreated: () => Navigator.of(context) - .push(MaterialPageRoute(builder: (_) => PaymentScreen(t: t))), + onOrderCreated: () => Navigator.of(context).push(MaterialPageRoute( + builder: (_) => + PaymentScreen(t: t, onDone: () => Navigator.of(context).pop()))), ), )), Divider(height: 1, color: c.border), diff --git a/client/lib/screens/device_limit_screen.dart b/client/lib/screens/device_limit_screen.dart index 6be3240..c5a6854 100644 --- a/client/lib/screens/device_limit_screen.dart +++ b/client/lib/screens/device_limit_screen.dart @@ -12,6 +12,7 @@ import '../services/auth_api.dart'; import '../services/device_identity.dart'; import '../state/account_providers.dart'; import '../state/auth_provider.dart'; +import '../widgets/pangolin_icons.dart'; class DeviceLimitScreen extends ConsumerStatefulWidget { const DeviceLimitScreen({super.key, required this.t, required this.limit}); @@ -84,7 +85,7 @@ class _DeviceLimitScreenState extends ConsumerState { crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const SizedBox(height: 32), - Icon(Icons.devices_other_rounded, size: 40, color: c.accent), + Icon(PangolinIcons.monitorSmartphone, size: 40, color: c.accent), const SizedBox(height: 14), Text(t.deviceLimitTitle, textAlign: TextAlign.center, @@ -97,7 +98,7 @@ class _DeviceLimitScreenState extends ConsumerState { if (removableCount > 0) OutlinedButton.icon( onPressed: _busyUuid != null ? null : () => _removeOldest(devices, currentId), - icon: const Icon(Icons.history_rounded, size: 18), + icon: const Icon(PangolinIcons.clock, size: 18), label: Text(t.deviceLimitRemoveOldest), style: OutlinedButton.styleFrom( foregroundColor: c.accent, @@ -136,7 +137,9 @@ class _DeviceLimitScreenState extends ConsumerState { final busy = _busyUuid == d.uuid; final sub = d.online ? t.devOnline - : (d.lastSeen != null ? '${t.devLastOnline} ${_rel(d.lastSeen!)}' : t.devOffline); + : (d.lastSeen != null + ? '${t.devLastOnline} ${t.lang.relativeTime(DateTime.now().difference(d.lastSeen!.toLocal()))}' + : t.devOffline); return Container( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 12), decoration: BoxDecoration( @@ -184,18 +187,9 @@ class _DeviceLimitScreenState extends ConsumerState { } static IconData _platformIcon(DevicePlatform p) => switch (p) { - DevicePlatform.ios || DevicePlatform.android => Icons.smartphone_rounded, - DevicePlatform.windows || DevicePlatform.linux => Icons.computer_rounded, - DevicePlatform.macos => Icons.laptop_mac_rounded, - DevicePlatform.unknown => Icons.devices_other_rounded, + DevicePlatform.ios || DevicePlatform.android => PangolinIcons.smartphone, + DevicePlatform.windows || DevicePlatform.linux => PangolinIcons.monitor, + DevicePlatform.macos => PangolinIcons.laptop, + DevicePlatform.unknown => PangolinIcons.monitorSmartphone, }; - - // 相对时间(粗粒度):x 分钟/小时/天前。 - static String _rel(DateTime t) { - final d = DateTime.now().toUtc().difference(t.toUtc()); - if (d.inMinutes < 1) return '刚刚'; - if (d.inMinutes < 60) return '${d.inMinutes} 分钟前'; - if (d.inHours < 24) return '${d.inHours} 小时前'; - return '${d.inDays} 天前'; - } } diff --git a/client/lib/screens/orders_page.dart b/client/lib/screens/orders_page.dart index 137f1b6..e3b743f 100644 --- a/client/lib/screens/orders_page.dart +++ b/client/lib/screens/orders_page.dart @@ -252,7 +252,17 @@ class _OrderDetailView extends ConsumerWidget { builder: (_) => PurchaseScreen( t: t, onOrderCreated: () => Navigator.of(context).push( - MaterialPageRoute(builder: (_) => PaymentScreen(t: t)), + MaterialPageRoute( + builder: (_) => PaymentScreen( + t: t, + onDone: () { + Navigator.of(context).pop(); + // 支付页「完成/取消」回到订单详情:失效列表 + 本单详情,拉新状态。 + ref.invalidate(ordersProvider); + ref.invalidate(orderDetailProvider(order.orderNo)); + }, + ), + ), ), ), )); diff --git a/client/lib/screens/payment_page.dart b/client/lib/screens/payment_page.dart index b455770..a623b90 100644 --- a/client/lib/screens/payment_page.dart +++ b/client/lib/screens/payment_page.dart @@ -209,8 +209,9 @@ class _PaymentScreenState extends ConsumerState { Text(t.qrNotSupported, style: PangolinText.caption.copyWith(color: c.fg3)), ])); default: - renderBody = _card(c, child: Text('${session.renderType}: ${_zh ? "暂不支持,请换支付方式" : "Unsupported, switch method"}', - style: PangolinText.body.copyWith(color: c.fg2))); + renderBody = _card(c, + child: Text('${session.renderType}: ${t.payUnsupportedRenderType}', + style: PangolinText.body.copyWith(color: c.fg2))); } return ListView(padding: const EdgeInsets.fromLTRB(20, 14, 20, 24), children: [ @@ -306,7 +307,7 @@ class _PaymentScreenState extends ConsumerState { PaymentPhase.succeeded => _succeeded(context, s), PaymentPhase.failed => _failed(context, ref, s), PaymentPhase.idle => Center( - child: Text(_zh ? '暂无进行中的订单' : 'No active order', + child: Text(t.payNoActiveOrder, style: PangolinText.body.copyWith(color: c.fg3))), }; diff --git a/client/lib/screens/purchase_page.dart b/client/lib/screens/purchase_page.dart index f230c38..b04c70c 100644 --- a/client/lib/screens/purchase_page.dart +++ b/client/lib/screens/purchase_page.dart @@ -38,6 +38,7 @@ class PurchaseScreen extends ConsumerStatefulWidget { class _PurchaseScreenState extends ConsumerState { AppText get t => widget.t; + bool get _zh => t.lang == AppLang.zh; // 支付渠道:默认 USDT·加密货币。切换即刷新套餐卡显价币种。 PayChannel _channel = PayChannel.usdt; @@ -59,9 +60,7 @@ class _PurchaseScreenState extends ConsumerState { // 下单失败给可见 toast,别让用户以为「点了没反应」。 showPangolinToast( context, - t.lang == AppLang.zh - ? (st.errorZh ?? '下单失败,请稍后重试') - : (st.errorEn ?? 'Failed to create order, please retry'), + (_zh ? st.errorZh : st.errorEn) ?? t.orderCreateFailed, ); } } @@ -77,8 +76,7 @@ class _PurchaseScreenState extends ConsumerState { error: (_, __) => Center( child: Padding( padding: const EdgeInsets.all(40), - child: Text(t.lang == AppLang.zh ? '加载失败,请重试' : 'Failed to load, retry', - style: PangolinText.body.copyWith(color: c.fg3)), + child: Text(t.lang.loadFailedRetry, style: PangolinText.body.copyWith(color: c.fg3)), ), ), data: (items) { diff --git a/client/lib/widgets/update_dialog.dart b/client/lib/widgets/update_dialog.dart index 6e89ef4..e28ad31 100644 --- a/client/lib/widgets/update_dialog.dart +++ b/client/lib/widgets/update_dialog.dart @@ -126,7 +126,7 @@ class UpdateBanner extends ConsumerWidget { IconButton( onPressed: () => ref.read(dismissedUpdateVersionProvider.notifier).state = info.latestVersion, - icon: Icon(Icons.close, size: 18, color: c.fg3), + icon: Icon(PangolinIcons.x, size: 18, color: c.fg3), padding: EdgeInsets.zero, constraints: const BoxConstraints(minWidth: 36, minHeight: 36), tooltip: t.updateLater,