From f0832ccfcb4a70a4502e3b0ce15d77b12705fe11 Mon Sep 17 00:00:00 2001 From: wangjia <809946525@qq.com> Date: Sun, 28 Jun 2026 21:12:24 +0800 Subject: [PATCH] =?UTF-8?q?fix(client):=20=E4=BF=AE=20pro=20=E4=BC=9A?= =?UTF-8?q?=E5=91=98=E5=90=AF=E5=8A=A8=E9=97=AA=E5=B9=BF=E5=91=8A/?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E9=97=AA=200=20=E2=80=94=20=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E9=97=A8=E8=A6=86=E7=9B=96=20auth=20=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E7=AA=97=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 之前 meLoadingProvider=isLoading&&!hasValue 漏了两段:启动时 auth 异步读 token 期间 isLoggedIn=false → me 同步返回免费默认(广告);token 到后 me 拉真实值时 hasValue 已是免费默认 → !hasValue 不成立、仍不转圈。改为: - meLoadingProvider:auth.isLoading 时转圈;未登录不转;已登录看 me.isLoading - 统计页 loading:auth.isLoading || usageProvider.isLoading 未登录(确定访客)/golden(settle 后)不转圈,golden 不受影响。 Co-Authored-By: Claude Opus 4.8 --- client/lib/screens/stats_page.dart | 6 ++++-- client/lib/state/app_providers.dart | 13 +++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/client/lib/screens/stats_page.dart b/client/lib/screens/stats_page.dart index 49f28df..f7649ee 100644 --- a/client/lib/screens/stats_page.dart +++ b/client/lib/screens/stats_page.dart @@ -7,6 +7,7 @@ import '../models/usage_point.dart'; import '../pangolin_theme.dart'; import '../state/account_providers.dart'; import '../state/app_providers.dart'; +import '../state/auth_provider.dart'; import '../widgets/app_top_bar.dart'; import '../widgets/pangolin_icons.dart'; import '../widgets/period_card.dart'; @@ -22,8 +23,9 @@ class StatsPage extends ConsumerWidget { final t = ref.watch(appTextProvider); final usageAsync = ref.watch(usageProvider(30)); final usage = usageAsync.valueOrNull ?? const []; - // 加载中且无缓存 → 整页转圈(先拉数据再渲染,不闪默认 0)。 - final loading = usageAsync.isLoading && !usageAsync.hasValue; + // 先拉数据再渲染(不闪默认 0):auth 还在读 token,或已登录但 usage 还在拉 → 整页转圈。 + // (auth 加载期 isLoggedIn=false → usage 会同步返回空,故必须并上 auth.isLoading。) + final loading = ref.watch(authProvider).isLoading || usageAsync.isLoading; // 周期聚合:取最后 N 天的点求和。最后一点即今日(避开 UTC/本地日期换算)。 (int down, int up, int min) sumLast(int days) { diff --git a/client/lib/state/app_providers.dart b/client/lib/state/app_providers.dart index c2b3895..3300fd0 100644 --- a/client/lib/state/app_providers.dart +++ b/client/lib/state/app_providers.dart @@ -6,6 +6,7 @@ import '../l10n/app_text.dart'; import '../l10n/strings_en.dart'; import '../l10n/strings_zh.dart'; import 'account_providers.dart'; +import 'auth_provider.dart'; /// 当前语言(单显)。设置/账户页段控切换。 final localeProvider = StateProvider((ref) => AppLang.zh); @@ -26,9 +27,13 @@ final isFreePlanProvider = Provider((ref) { return me?.isFree ?? true; }); -/// 账户聚合是否仍在「首拉」(加载中且无缓存)。连接页/统计页据此先转圈再渲染, -/// 避免免费默认态闪一下(广告/0)再跳成真实数据。 +/// 账户状态是否还没就绪——连接页据此先转圈再渲染,避免「先闪免费广告再跳会员」。 +/// 覆盖两段窗口:① auth 还在从存储读 token(此时 isLoggedIn=false,me 会同步返回 +/// 免费默认,故必须看 auth.isLoading);② 已登录但 me 还在拉真实值(此时 me 可能已有 +/// 过期免费默认值,故看 me.isLoading 而非 !hasValue)。未登录(确定访客)不转圈。 final meLoadingProvider = Provider((ref) { - final me = ref.watch(meProvider); - return me.isLoading && !me.hasValue; + final auth = ref.watch(authProvider); + if (auth.isLoading) return true; + if (!auth.isLoggedIn) return false; + return ref.watch(meProvider).isLoading; });