diff --git a/client/lib/l10n/app_text.dart b/client/lib/l10n/app_text.dart index 0b7599c..842a5bd 100644 --- a/client/lib/l10n/app_text.dart +++ b/client/lib/l10n/app_text.dart @@ -473,7 +473,6 @@ abstract class AppText { String get updateCheckFailed; // 检查失败(网络异常) // ── 套餐选择 ── - String get choosePlan; String get freePlan; String get proPlan; String get teamPlan; diff --git a/client/lib/l10n/strings_en.dart b/client/lib/l10n/strings_en.dart index 3dbbf8e..eb4b2ac 100644 --- a/client/lib/l10n/strings_en.dart +++ b/client/lib/l10n/strings_en.dart @@ -250,8 +250,6 @@ class StringsEn extends AppText { @override String get updateCheckFailed => 'Update check failed, try again later'; - @override - String get choosePlan => 'Choose plan'; @override String get freePlan => 'Free'; @override diff --git a/client/lib/l10n/strings_es.dart b/client/lib/l10n/strings_es.dart index 95050ea..d25615b 100644 --- a/client/lib/l10n/strings_es.dart +++ b/client/lib/l10n/strings_es.dart @@ -250,8 +250,6 @@ class StringsEs extends AppText { @override String get updateCheckFailed => 'Falló la búsqueda de actualizaciones, inténtalo más tarde'; - @override - String get choosePlan => 'Elegir plan'; @override String get freePlan => 'Gratis'; @override diff --git a/client/lib/l10n/strings_ja.dart b/client/lib/l10n/strings_ja.dart index 6bde2d9..9163703 100644 --- a/client/lib/l10n/strings_ja.dart +++ b/client/lib/l10n/strings_ja.dart @@ -250,8 +250,6 @@ class StringsJa extends AppText { @override String get updateCheckFailed => 'アップデートの確認に失敗しました。後でもう一度お試しください'; - @override - String get choosePlan => 'プランを選択'; @override String get freePlan => '無料'; @override diff --git a/client/lib/l10n/strings_ko.dart b/client/lib/l10n/strings_ko.dart index f02e44c..dc3fd0d 100644 --- a/client/lib/l10n/strings_ko.dart +++ b/client/lib/l10n/strings_ko.dart @@ -250,8 +250,6 @@ class StringsKo extends AppText { @override String get updateCheckFailed => '업데이트 확인에 실패했습니다. 잠시 후 다시 시도하세요'; - @override - String get choosePlan => '요금제 선택'; @override String get freePlan => '무료'; @override diff --git a/client/lib/l10n/strings_ru.dart b/client/lib/l10n/strings_ru.dart index 4e254c8..9ee33ac 100644 --- a/client/lib/l10n/strings_ru.dart +++ b/client/lib/l10n/strings_ru.dart @@ -250,8 +250,6 @@ class StringsRu extends AppText { @override String get updateCheckFailed => 'Не удалось проверить обновления, попробуйте позже'; - @override - String get choosePlan => 'Выбор тарифа'; @override String get freePlan => 'Бесплатный'; @override diff --git a/client/lib/l10n/strings_zh.dart b/client/lib/l10n/strings_zh.dart index c05af4c..b1f0327 100644 --- a/client/lib/l10n/strings_zh.dart +++ b/client/lib/l10n/strings_zh.dart @@ -249,8 +249,6 @@ class StringsZh extends AppText { @override String get updateCheckFailed => '检查更新失败,请稍后重试'; - @override - String get choosePlan => '选择套餐'; @override String get freePlan => '免费版'; @override diff --git a/client/lib/shell/desktop_shell.dart b/client/lib/shell/desktop_shell.dart index 94b031a..7c6370d 100644 --- a/client/lib/shell/desktop_shell.dart +++ b/client/lib/shell/desktop_shell.dart @@ -49,7 +49,6 @@ class DesktopShell extends ConsumerWidget { NavView.account: t.tabMe, NavView.contact: t.contactTitle, NavView.settings: t.settingsTitle, - NavView.plans: t.choosePlan, NavView.redeem: t.redeemTitle, NavView.devices: t.myDevices, NavView.purchase: t.purchaseTitle, @@ -76,9 +75,6 @@ class DesktopShell extends ConsumerWidget { case NavView.settings: return const SettingsPage(); // 账户下钻子页(内容区,顶栏带返回) - case NavView.plans: - // 只有 pro 走 pay v2 购买通道;team 等仍走既有兑换/联系人工流程。 - return PlansScreen(t: t, embedded: true, onChoose: (code) => go(code == 'pro' ? NavView.purchase : NavView.redeem)); case NavView.redeem: return RedeemScreen(t: t, embedded: true); case NavView.devices: diff --git a/client/lib/state/navigation_provider.dart b/client/lib/state/navigation_provider.dart index bed5534..cd9ba5e 100644 --- a/client/lib/state/navigation_provider.dart +++ b/client/lib/state/navigation_provider.dart @@ -3,11 +3,11 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; /// 一级视图 + 账户子页。 /// desktop 侧栏暴露 6 个一级项(connect..settings);mobile/tablet 取前 4 项, -/// contact/settings 在 mobile 走账户子页。plans/redeem 是 account 的下钻页。 -enum NavView { connect, servers, stats, account, contact, settings, plans, redeem, devices, purchase, payment, orders, invite, notifications } +/// contact/settings 在 mobile 走账户子页。redeem 是 account 的下钻页。 +enum NavView { connect, servers, stats, account, contact, settings, redeem, devices, purchase, payment, orders, invite, notifications } /// 账户下钻子页(desktop 在内容区切换、顶栏带返回;mobile/tablet 走全屏 push)。 -const Set kAccountSubViews = {NavView.plans, NavView.redeem, NavView.devices, NavView.purchase, NavView.payment, NavView.orders, NavView.invite}; +const Set kAccountSubViews = {NavView.redeem, NavView.devices, NavView.purchase, NavView.payment, NavView.orders, NavView.invite}; /// 当前视图。 final navViewProvider = StateProvider((ref) => NavView.connect); diff --git a/client/lib/widgets/account_screens.dart b/client/lib/widgets/account_screens.dart index 3079469..583efcd 100644 --- a/client/lib/widgets/account_screens.dart +++ b/client/lib/widgets/account_screens.dart @@ -20,7 +20,6 @@ import '../services/auth_api.dart'; import '../state/account_providers.dart'; import 'pangolin_button.dart'; import 'pangolin_icons.dart'; -import 'plan_card.dart'; /// 通用:带返回箭头的子页骨架。embedded=true 时只返回内容(desktop 内容区下钻, /// 返回/标题由外层 shell 顶栏提供),否则整页 Scaffold(mobile/tablet 全屏 push)。 @@ -67,66 +66,6 @@ class SettingsScreen extends StatelessWidget { } } -/// ── 套餐选择 ── (价格/额度来自 GET /v1/plans;当前档由 me.plan 判定; -/// 功能清单仍取 l10n,后端无此字段) -class PlansScreen extends ConsumerWidget { - const PlansScreen({super.key, required this.t, this.onChoose, this.onBack, this.embedded = false}); - final AppText t; - final ValueChanged? onChoose; - final VoidCallback? onBack; - final bool embedded; - - List _feats(String code) => switch (code) { - 'free' => t.featsFree, - 'pro' => t.featsPro, - 'team' => t.featsTeam, - _ => const [], - }; - - // 套餐名是 UI 文案(后端 plans 表无名称列),按 code 取 l10n。 - String _name(String code) => switch (code) { - 'free' => t.freePlan, - 'pro' => t.proPlan, - 'team' => t.teamPlan, - _ => code, - }; - - @override - Widget build(BuildContext context, WidgetRef ref) { - final c = context.pangolin; - final plansAsync = ref.watch(plansProvider); - final myPlan = ref.watch(meProvider).valueOrNull?.plan ?? 'free'; - - Widget body() => plansAsync.when( - loading: () => const Center(child: Padding(padding: EdgeInsets.all(40), child: CircularProgressIndicator())), - error: (_, __) => Center( - child: Padding(padding: const EdgeInsets.all(40), child: Text(t.lang.loadFailedRetry, style: PangolinText.body.copyWith(color: c.fg3)))), - data: (plans) => ListView( - padding: const EdgeInsets.fromLTRB(20, 14, 20, 24), - children: [ - for (final p in plans) - Padding( - padding: EdgeInsets.only(bottom: 14, top: p.code == 'pro' ? 12 : 0), - child: PlanCard( - name: _name(p.code), - price: p.priceLabel(), - period: t.perMonth, - features: _feats(p.code), - ctaLabel: p.code == myPlan ? t.current : (p.code == 'team' ? t.choose : t.upgrade), - featured: p.code == 'pro', - isCurrent: p.code == myPlan, - popularLabel: p.code == 'pro' ? t.mostPopular : null, - onPressed: () => onChoose?.call(p.code), - ), - ), - ], - ), - ); - - return _SubScaffold(title: t.choosePlan, onBack: onBack, embedded: embedded, child: body()); - } -} - /// ── 设备管理 ── (真实 GET /v1/me/devices;移除 = DELETE。本机高亮待 P6 设备 id) class DevicesScreen extends ConsumerWidget { const DevicesScreen({super.key, required this.t, this.onBack, this.embedded = false}); diff --git a/client/test/golden/desktop_pages_golden_test.dart b/client/test/golden/desktop_pages_golden_test.dart index 53385c9..a5db857 100644 --- a/client/test/golden/desktop_pages_golden_test.dart +++ b/client/test/golden/desktop_pages_golden_test.dart @@ -70,7 +70,6 @@ void main() { testWidgets('desktop 联系页', (t) => _shoot(t, NavView.contact, 'desktop_contact')); testWidgets('desktop 设置页', (t) => _shoot(t, NavView.settings, 'desktop_settings')); // 账户下钻子页(内容区 + 顶栏返回) - testWidgets('desktop 套餐选择', (t) => _shoot(t, NavView.plans, 'desktop_plans')); testWidgets('desktop 兑换购买', (t) => _shoot(t, NavView.redeem, 'desktop_redeem')); testWidgets('desktop 设备管理', (t) => _shoot(t, NavView.devices, 'desktop_devices')); } diff --git a/client/test/golden/goldens/desktop_plans.png b/client/test/golden/goldens/desktop_plans.png deleted file mode 100644 index c7dcea1..0000000 Binary files a/client/test/golden/goldens/desktop_plans.png and /dev/null differ