From b1525bdfa6c712f8305b7e675b5ca600e2f8b35e Mon Sep 17 00:00:00 2001 From: hailin Date: Mon, 12 Jan 2026 21:48:31 -0800 Subject: [PATCH] feat(mining-app): improve UX with non-blocking splash and skeleton loading - Optimize splash page: reduce wait to 500ms, refresh token in background - Cache SharedPreferences instance to avoid blocking API requests - Add global 401 handler to auto-redirect to login page - Create shimmer loading components (ShimmerLoading, ShimmerBox, skeletons) - Replace CircularProgressIndicator with skeleton screens across all pages - Add keepAlive + auto-invalidation (5min) to providers to reduce API calls - Fix trading page: invalidate globalStateProvider after trade for data sync Co-Authored-By: Claude Opus 4.5 --- .claude/settings.local.json | 3 +- .../public/drawable-xhdpi/background_1.png | Bin 536 -> 0 bytes .../public/drawable-xhdpi/container_1.png | Bin 0 -> 6701 bytes .../public/drawable-xhdpi/user_avatar.png | Bin 0 -> 5334 bytes .../public/drawable-xxhdpi/background_1.png | Bin 1211 -> 0 bytes .../public/drawable-xxhdpi/container_1.png | Bin 0 -> 15714 bytes .../public/drawable-xxhdpi/user_avatar.png | Bin 0 -> 16633 bytes .../public/drawable-xxxhdpi/background_1.png | Bin 1406 -> 0 bytes .../public/drawable-xxxhdpi/container_1.png | Bin 0 -> 11991 bytes .../public/drawable-xxxhdpi/user_avatar.png | Bin 0 -> 26315 bytes .../admin-web/public/drawable/background.xml | 6 +- .../public/drawable/background_1.xml | 13 + .../public/drawable/background_2.xml | 13 + .../public/drawable/background_3.xml | 13 + .../public/drawable/background_4.xml | 13 + .../public/drawable/background_shadow.xml | 13 + .../public/drawable/background_shadow_1.xml | 13 + .../public/drawable/background_shadow_2.xml | 13 + .../public/drawable/background_shadow_3.xml | 13 + frontend/admin-web/public/drawable/button.xml | 15 +- .../admin-web/public/drawable/button_1.xml | 10 + .../admin-web/public/drawable/container_1.xml | 10 - .../admin-web/public/drawable/container_2.xml | 8 +- .../admin-web/public/drawable/container_3.xml | 12 +- .../admin-web/public/drawable/container_4.xml | 6 +- .../admin-web/public/drawable/container_5.xml | 6 +- .../admin-web/public/drawable/container_6.xml | 6 +- .../admin-web/public/drawable/container_7.xml | 12 +- frontend/admin-web/public/drawable/margin.xml | 10 + .../admin-web/public/drawable/margin_1.xml | 10 + .../lib/core/network/api_client.dart | 32 +- frontend/mining-app/lib/main.dart | 27 +- .../presentation/pages/asset/asset_page.dart | 25 +- .../pages/contribution/contribution_page.dart | 19 +- .../pages/splash/splash_page.dart | 21 +- .../pages/trading/trading_page.dart | 28 +- .../providers/contribution_providers.dart | 27 ++ .../providers/mining_providers.dart | 26 +- .../presentation/widgets/shimmer_loading.dart | 289 ++++++++++++++++++ 39 files changed, 624 insertions(+), 88 deletions(-) delete mode 100644 frontend/admin-web/public/drawable-xhdpi/background_1.png create mode 100644 frontend/admin-web/public/drawable-xhdpi/container_1.png create mode 100644 frontend/admin-web/public/drawable-xhdpi/user_avatar.png delete mode 100644 frontend/admin-web/public/drawable-xxhdpi/background_1.png create mode 100644 frontend/admin-web/public/drawable-xxhdpi/container_1.png create mode 100644 frontend/admin-web/public/drawable-xxhdpi/user_avatar.png delete mode 100644 frontend/admin-web/public/drawable-xxxhdpi/background_1.png create mode 100644 frontend/admin-web/public/drawable-xxxhdpi/container_1.png create mode 100644 frontend/admin-web/public/drawable-xxxhdpi/user_avatar.png create mode 100644 frontend/admin-web/public/drawable/background_1.xml create mode 100644 frontend/admin-web/public/drawable/background_2.xml create mode 100644 frontend/admin-web/public/drawable/background_3.xml create mode 100644 frontend/admin-web/public/drawable/background_4.xml create mode 100644 frontend/admin-web/public/drawable/background_shadow.xml create mode 100644 frontend/admin-web/public/drawable/background_shadow_1.xml create mode 100644 frontend/admin-web/public/drawable/background_shadow_2.xml create mode 100644 frontend/admin-web/public/drawable/background_shadow_3.xml create mode 100644 frontend/admin-web/public/drawable/button_1.xml delete mode 100644 frontend/admin-web/public/drawable/container_1.xml create mode 100644 frontend/admin-web/public/drawable/margin.xml create mode 100644 frontend/admin-web/public/drawable/margin_1.xml create mode 100644 frontend/mining-app/lib/presentation/widgets/shimmer_loading.dart diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 04a89ee5..01a8d219 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -765,7 +765,8 @@ "Bash(git -C \"c:\\\\Users\\\\dong\\\\Desktop\\\\rwadurian\" push)", "Bash(git -C \"c:\\\\Users\\\\dong\\\\Desktop\\\\rwadurian\" add frontend/mining-app/lib/presentation/pages/splash/splash_page.dart frontend/mining-app/lib/presentation/providers/user_providers.dart)", "Bash(git -C \"c:\\\\Users\\\\dong\\\\Desktop\\\\rwadurian\" commit -m \"$\\(cat <<''EOF''\nfix\\(mining-app\\): update splash page theme and fix token refresh\n\n- Update splash_page.dart to orange theme \\(#FF6B00\\) matching other pages\n- Change app name from \"榴莲挖矿\" to \"榴莲生态\"\n- Fix refreshTokenIfNeeded to properly throw on failure instead of\n silently calling logout \\(which caused Riverpod ref errors\\)\n- Clear local storage directly on refresh failure without remote API call\n\nCo-Authored-By: Claude Opus 4.5 \nEOF\n\\)\")", - "Bash(python3 -c \" import sys content = sys.stdin.read\\(\\) old = '''''' done # 清空 processed_cdc_events 表(因为 migration 时可能已经消费了一些消息) # 这是事务性幂等消费的关键:重置 Kafka offset 后必须同时清空幂等记录 log_info \"\"Truncating processed_cdc_events tables to allow re-consumption...\"\" for db in \"\"rwa_contribution\"\" \"\"rwa_auth\"\"; do if run_psql \"\"$db\"\" \"\"TRUNCATE TABLE processed_cdc_events;\"\" 2>/dev/null; then log_success \"\"Truncated processed_cdc_events in $db\"\" else log_warn \"\"Could not truncate processed_cdc_events in $db \\(table may not exist yet\\)\"\" fi done log_step \"\"Step 9/18: Starting 2.0 services...\"\"'''''' new = '''''' done # 清空 processed_cdc_events 表(因为 migration 时可能已经消费了一些消息) # 这是事务性幂等消费的关键:重置 Kafka offset 后必须同时清空幂等记录 log_info \"\"Truncating processed_cdc_events tables to allow re-consumption...\"\" for db in \"\"rwa_contribution\"\" \"\"rwa_auth\"\"; do if run_psql \"\"$db\"\" \"\"TRUNCATE TABLE processed_cdc_events;\"\" 2>/dev/null; then log_success \"\"Truncated processed_cdc_events in $db\"\" else log_warn \"\"Could not truncate processed_cdc_events in $db \\(table may not exist yet\\)\"\" fi done log_step \"\"Step 9/18: Starting 2.0 services...\"\"'''''' print\\(content.replace\\(old, new\\)\\) \")" + "Bash(python3 -c \" import sys content = sys.stdin.read\\(\\) old = '''''' done # 清空 processed_cdc_events 表(因为 migration 时可能已经消费了一些消息) # 这是事务性幂等消费的关键:重置 Kafka offset 后必须同时清空幂等记录 log_info \"\"Truncating processed_cdc_events tables to allow re-consumption...\"\" for db in \"\"rwa_contribution\"\" \"\"rwa_auth\"\"; do if run_psql \"\"$db\"\" \"\"TRUNCATE TABLE processed_cdc_events;\"\" 2>/dev/null; then log_success \"\"Truncated processed_cdc_events in $db\"\" else log_warn \"\"Could not truncate processed_cdc_events in $db \\(table may not exist yet\\)\"\" fi done log_step \"\"Step 9/18: Starting 2.0 services...\"\"'''''' new = '''''' done # 清空 processed_cdc_events 表(因为 migration 时可能已经消费了一些消息) # 这是事务性幂等消费的关键:重置 Kafka offset 后必须同时清空幂等记录 log_info \"\"Truncating processed_cdc_events tables to allow re-consumption...\"\" for db in \"\"rwa_contribution\"\" \"\"rwa_auth\"\"; do if run_psql \"\"$db\"\" \"\"TRUNCATE TABLE processed_cdc_events;\"\" 2>/dev/null; then log_success \"\"Truncated processed_cdc_events in $db\"\" else log_warn \"\"Could not truncate processed_cdc_events in $db \\(table may not exist yet\\)\"\" fi done log_step \"\"Step 9/18: Starting 2.0 services...\"\"'''''' print\\(content.replace\\(old, new\\)\\) \")", + "Bash(git rm:*)" ], "deny": [], "ask": [] diff --git a/frontend/admin-web/public/drawable-xhdpi/background_1.png b/frontend/admin-web/public/drawable-xhdpi/background_1.png deleted file mode 100644 index bc62067f7450a3f4027b10bae17ae4a7eafdfe15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 536 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 literal 0 HcmV?d00001 diff --git a/frontend/admin-web/public/drawable-xhdpi/user_avatar.png b/frontend/admin-web/public/drawable-xhdpi/user_avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..d3a33e64fc505c9039f2d833272cea83ab145929 GIT binary patch literal 5334 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 literal 0 HcmV?d00001 diff --git a/frontend/admin-web/public/drawable-xxhdpi/background_1.png b/frontend/admin-web/public/drawable-xxhdpi/background_1.png deleted file mode 100644 index 700469d49c673cc2a428db10a9298c31a17f86d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1211 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 literal 0 HcmV?d00001 diff --git a/frontend/admin-web/public/drawable-xxhdpi/user_avatar.png b/frontend/admin-web/public/drawable-xxhdpi/user_avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..d9700825e3e4a51fd8333727d4f154c31bd44dfd GIT binary patch literal 16633 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 diff --git a/frontend/admin-web/public/drawable-xxxhdpi/container_1.png b/frontend/admin-web/public/drawable-xxxhdpi/container_1.png new file mode 100644 index 0000000000000000000000000000000000000000..1660db78a48e0259f2e9cd228478e0d30b0034c5 GIT binary patch literal 11991 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 literal 0 HcmV?d00001 diff --git a/frontend/admin-web/public/drawable-xxxhdpi/user_avatar.png b/frontend/admin-web/public/drawable-xxxhdpi/user_avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..a45c03c682e67ca4bc354d37e92fc10f1a2cb200 GIT binary patch literal 26315 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 Su#R#70000 + android:fillColor="#FFFFEDD5" + android:pathData="M0 20c0-11.05 8.95-20 20-20h0c11.05 0 20 8.95 20 20v0c0 11.05-8.95 20-20 20h0c-11.05 0-20-8.95-20-20z"/> + android:pathData="M13.52 24.8l4.41-4.4 2.7 2.73c0.35 0.3 0.9 0.3 1.2-0.04l5.98-6.72c0.28-0.35 0.28-0.86-0.04-1.17-0.3-0.32-0.9-0.32-1.2 0.03l-5.32 5.98-2.73-2.73c-0.36-0.32-0.86-0.32-1.18 0l-5.07 5.07c-0.36 0.36-0.36 0.86 0 1.18l0.07 0.07c0.32 0.36 0.82 0.36 1.18 0Z"/> diff --git a/frontend/admin-web/public/drawable/background_1.xml b/frontend/admin-web/public/drawable/background_1.xml new file mode 100644 index 00000000..c6f43402 --- /dev/null +++ b/frontend/admin-web/public/drawable/background_1.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/frontend/admin-web/public/drawable/background_2.xml b/frontend/admin-web/public/drawable/background_2.xml new file mode 100644 index 00000000..0c0a36f2 --- /dev/null +++ b/frontend/admin-web/public/drawable/background_2.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/frontend/admin-web/public/drawable/background_3.xml b/frontend/admin-web/public/drawable/background_3.xml new file mode 100644 index 00000000..bae275a4 --- /dev/null +++ b/frontend/admin-web/public/drawable/background_3.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/frontend/admin-web/public/drawable/background_4.xml b/frontend/admin-web/public/drawable/background_4.xml new file mode 100644 index 00000000..52bbbfb0 --- /dev/null +++ b/frontend/admin-web/public/drawable/background_4.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/frontend/admin-web/public/drawable/background_shadow.xml b/frontend/admin-web/public/drawable/background_shadow.xml new file mode 100644 index 00000000..8b9bc0cd --- /dev/null +++ b/frontend/admin-web/public/drawable/background_shadow.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/frontend/admin-web/public/drawable/background_shadow_1.xml b/frontend/admin-web/public/drawable/background_shadow_1.xml new file mode 100644 index 00000000..2580ed84 --- /dev/null +++ b/frontend/admin-web/public/drawable/background_shadow_1.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/frontend/admin-web/public/drawable/background_shadow_2.xml b/frontend/admin-web/public/drawable/background_shadow_2.xml new file mode 100644 index 00000000..dea48af2 --- /dev/null +++ b/frontend/admin-web/public/drawable/background_shadow_2.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/frontend/admin-web/public/drawable/background_shadow_3.xml b/frontend/admin-web/public/drawable/background_shadow_3.xml new file mode 100644 index 00000000..f096d87b --- /dev/null +++ b/frontend/admin-web/public/drawable/background_shadow_3.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/frontend/admin-web/public/drawable/button.xml b/frontend/admin-web/public/drawable/button.xml index 05df329a..0edd6f0c 100644 --- a/frontend/admin-web/public/drawable/button.xml +++ b/frontend/admin-web/public/drawable/button.xml @@ -1,10 +1,13 @@ + android:width="36dp" + android:height="36dp" + android:viewportWidth="36" + android:viewportHeight="36"> + android:fillColor="#FFFFFFFF" + android:pathData="M0 18c0-9.94 8.06-18 18-18h0c9.94 0 18 8.06 18 18v0c0 9.94-8.06 18-18 18h0c-9.94 0-18-8.06-18-18z"/> + diff --git a/frontend/admin-web/public/drawable/button_1.xml b/frontend/admin-web/public/drawable/button_1.xml new file mode 100644 index 00000000..c701fe8f --- /dev/null +++ b/frontend/admin-web/public/drawable/button_1.xml @@ -0,0 +1,10 @@ + + + + diff --git a/frontend/admin-web/public/drawable/container_1.xml b/frontend/admin-web/public/drawable/container_1.xml deleted file mode 100644 index d7a14353..00000000 --- a/frontend/admin-web/public/drawable/container_1.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - diff --git a/frontend/admin-web/public/drawable/container_2.xml b/frontend/admin-web/public/drawable/container_2.xml index 2e61b46e..7b29c2a2 100644 --- a/frontend/admin-web/public/drawable/container_2.xml +++ b/frontend/admin-web/public/drawable/container_2.xml @@ -1,10 +1,10 @@ + android:fillColor="#FF4B5563" + android:pathData="M10 18.32c0.9 0 1.68-0.74 1.68-1.64H8.32c0 0.9 0.78 1.64 1.68 1.64Zm5-5V9.18c0-2.58-1.37-4.73-3.75-5.27V3.32c0-0.66-0.55-1.25-1.25-1.25S8.75 2.66 8.75 3.32v0.59C6.37 4.45 5 6.6 5 9.18v4.14L3.32 15v0.82h13.36V15L15 13.32Zm-1.68 0.86H6.68v-5c0-2.07 1.25-3.75 3.32-3.75s3.32 1.68 3.32 3.75v5Z"/> diff --git a/frontend/admin-web/public/drawable/container_3.xml b/frontend/admin-web/public/drawable/container_3.xml index 8506b426..3cc89e15 100644 --- a/frontend/admin-web/public/drawable/container_3.xml +++ b/frontend/admin-web/public/drawable/container_3.xml @@ -1,10 +1,10 @@ + android:width="14dp" + android:height="20dp" + android:viewportWidth="14" + android:viewportHeight="20"> + android:fillColor="#FF10B981" + android:pathData="M9.82 7l0.84 0.84-2.84 2.84-1.91-1.91c-0.22-0.25-0.6-0.25-0.82 0l-3.5 3.5c-0.25 0.22-0.25 0.6 0 0.82 0.21 0.22 0.6 0.22 0.82 0L5.5 10l1.91 1.91c0.22 0.25 0.6 0.25 0.82 0l3.25-3.25 0.85 0.85c0.2 0.16 0.5 0.05 0.5-0.22V6.8c0-0.16-0.12-0.3-0.28-0.3h-2.51C9.79 6.5 9.65 6.83 9.82 7Z"/> diff --git a/frontend/admin-web/public/drawable/container_4.xml b/frontend/admin-web/public/drawable/container_4.xml index 81588103..db32dcdd 100644 --- a/frontend/admin-web/public/drawable/container_4.xml +++ b/frontend/admin-web/public/drawable/container_4.xml @@ -1,10 +1,10 @@ + android:viewportHeight="32"> + android:pathData="M15.98 16.98c3.1-2.8 6-5.43 6-7.68 0-1.83-1.45-3.28-3.28-3.28-1.03 0-2.06 0.46-2.72 1.21-0.65-0.75-1.64-1.21-2.67-1.21-1.87 0-3.33 1.45-3.33 3.28 0 2.25 2.91 4.87 6 7.68Zm-2.67-9c0.42 0 0.9 0.24 1.17 0.57l1.5 1.78 1.55-1.78c0.28-0.33 0.75-0.57 1.17-0.57 0.75 0 1.32 0.57 1.32 1.32 0 1.12-2.07 3.18-4.04 5.01C14.06 12.48 12 10.42 12 9.3c0-0.75 0.56-1.32 1.31-1.32Zm5.67 12h-1.96c0-1.17-0.75-2.25-1.88-2.67l-6.19-2.3H0.98v10.97h6v-1.4l7.04 1.92 7.96-2.48v-1.04c0-1.64-1.3-3-3-3ZM3 24.02v-7.04h2.02v7.04H3Zm10.97 0.37l-6.99-1.92v-5.49h1.64l5.82 2.2c0.33 0.1 0.56 0.43 0.56 0.8 0 0-1.97-0.04-2.3-0.14l-2.39-0.8-0.6 1.93 2.34 0.8c0.51 0.14 1.07 0.23 1.6 0.23h5.33c0.43 0 0.75 0.23 0.94 0.56l-5.95 1.83Z"/> diff --git a/frontend/admin-web/public/drawable/container_5.xml b/frontend/admin-web/public/drawable/container_5.xml index 98773d7f..9486a551 100644 --- a/frontend/admin-web/public/drawable/container_5.xml +++ b/frontend/admin-web/public/drawable/container_5.xml @@ -1,10 +1,10 @@ + android:viewportHeight="32"> + android:pathData="M6.98 15.02L3 19l3.98 3.98v-3h7.04v-1.96H6.98v-3ZM21 13l-3.98-3.98v3H9.98v1.96h7.04v3L21 13Z"/> diff --git a/frontend/admin-web/public/drawable/container_6.xml b/frontend/admin-web/public/drawable/container_6.xml index 89f51a10..e393f05a 100644 --- a/frontend/admin-web/public/drawable/container_6.xml +++ b/frontend/admin-web/public/drawable/container_6.xml @@ -1,10 +1,10 @@ + android:viewportHeight="32"> + android:pathData="M12 10c1.08 0 2.02 0.9 2.02 2.02 0 1.07-0.94 1.96-2.02 1.96s-2.02-0.89-2.02-1.96C9.98 10.89 10.92 10 12 10Zm0 9.98c2.72 0 5.81 1.32 6 2.02H6c0.23-0.7 3.33-2.02 6-2.02Zm0-12c-2.2 0-3.98 1.83-3.98 4.04C8.02 14.22 9.8 16 12 16s3.98-1.78 3.98-3.98S14.2 7.98 12 7.98Zm0 10.04c-2.67 0-8.02 1.3-8.02 3.98v2.02h16.04V22c0-2.67-5.35-3.98-8.02-3.98Z"/> diff --git a/frontend/admin-web/public/drawable/container_7.xml b/frontend/admin-web/public/drawable/container_7.xml index feee424c..2ab9f00e 100644 --- a/frontend/admin-web/public/drawable/container_7.xml +++ b/frontend/admin-web/public/drawable/container_7.xml @@ -1,10 +1,10 @@ + android:width="14dp" + android:height="20dp" + android:viewportWidth="14" + android:viewportHeight="20"> + android:fillColor="#FFD1D5DB" + android:pathData="M3.64 14.81l1.04 1.01L10.5 10 4.68 4.18l-1.04 1L8.42 10l-4.78 4.81Z"/> diff --git a/frontend/admin-web/public/drawable/margin.xml b/frontend/admin-web/public/drawable/margin.xml new file mode 100644 index 00000000..84585c0a --- /dev/null +++ b/frontend/admin-web/public/drawable/margin.xml @@ -0,0 +1,10 @@ + + + + diff --git a/frontend/admin-web/public/drawable/margin_1.xml b/frontend/admin-web/public/drawable/margin_1.xml new file mode 100644 index 00000000..fde00eed --- /dev/null +++ b/frontend/admin-web/public/drawable/margin_1.xml @@ -0,0 +1,10 @@ + + + + diff --git a/frontend/mining-app/lib/core/network/api_client.dart b/frontend/mining-app/lib/core/network/api_client.dart index 8d3bcee0..70202f29 100644 --- a/frontend/mining-app/lib/core/network/api_client.dart +++ b/frontend/mining-app/lib/core/network/api_client.dart @@ -6,6 +6,13 @@ import '../error/exceptions.dart'; class ApiClient { final Dio dio; + // 缓存 SharedPreferences 实例,避免每次请求都阻塞读取 + static SharedPreferences? _prefsCache; + static Future? _prefsFuture; + + // 全局回调,用于处理 401 跳转登录 + static void Function()? onUnauthorized; + ApiClient({required this.dio}) { dio.options = BaseOptions( baseUrl: AppConstants.baseUrl, @@ -20,17 +27,38 @@ class ApiClient { // 添加请求拦截器,自动注入 token dio.interceptors.add(InterceptorsWrapper( onRequest: (options, handler) async { - // 每次请求都从存储中读取最新的 token,确保登录后立即生效 - final prefs = await SharedPreferences.getInstance(); + // 使用缓存的 SharedPreferences 实例,避免阻塞 + final prefs = await _getPrefs(); final token = prefs.getString('access_token'); if (token != null && token.isNotEmpty) { options.headers['Authorization'] = 'Bearer $token'; } handler.next(options); }, + onError: (error, handler) { + // 全局处理 401 错误 + if (error.response?.statusCode == 401) { + onUnauthorized?.call(); + } + handler.next(error); + }, )); } + // 获取缓存的 SharedPreferences 实例 + static Future _getPrefs() async { + if (_prefsCache != null) return _prefsCache!; + _prefsFuture ??= SharedPreferences.getInstance(); + _prefsCache = await _prefsFuture; + return _prefsCache!; + } + + // 清除缓存(登录/登出时调用) + static void clearPrefsCache() { + _prefsCache = null; + _prefsFuture = null; + } + Future get( String path, { Map? queryParameters, diff --git a/frontend/mining-app/lib/main.dart b/frontend/mining-app/lib/main.dart index b0b8cb0a..d68b8702 100644 --- a/frontend/mining-app/lib/main.dart +++ b/frontend/mining-app/lib/main.dart @@ -4,6 +4,9 @@ import 'package:hive_flutter/hive_flutter.dart'; import 'core/di/injection.dart'; import 'core/router/app_router.dart'; import 'core/constants/app_colors.dart'; +import 'core/network/api_client.dart'; +import 'core/router/routes.dart'; +import 'presentation/providers/user_providers.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -17,11 +20,31 @@ void main() async { runApp(const ProviderScope(child: MiningApp())); } -class MiningApp extends ConsumerWidget { +class MiningApp extends ConsumerStatefulWidget { const MiningApp({super.key}); @override - Widget build(BuildContext context, WidgetRef ref) { + ConsumerState createState() => _MiningAppState(); +} + +class _MiningAppState extends ConsumerState { + @override + void initState() { + super.initState(); + // 设置 401 全局处理回调 + ApiClient.onUnauthorized = _handleUnauthorized; + } + + void _handleUnauthorized() { + // 清除用户状态 + ref.read(userNotifierProvider.notifier).logout(); + // 跳转到登录页 + final router = ref.read(appRouterProvider); + router.go(Routes.login); + } + + @override + Widget build(BuildContext context) { final router = ref.watch(appRouterProvider); return MaterialApp.router( diff --git a/frontend/mining-app/lib/presentation/pages/asset/asset_page.dart b/frontend/mining-app/lib/presentation/pages/asset/asset_page.dart index 9033e3c7..6fb55b98 100644 --- a/frontend/mining-app/lib/presentation/pages/asset/asset_page.dart +++ b/frontend/mining-app/lib/presentation/pages/asset/asset_page.dart @@ -4,6 +4,7 @@ import '../../../core/constants/app_colors.dart'; import '../../../core/utils/format_utils.dart'; import '../../providers/user_providers.dart'; import '../../providers/mining_providers.dart'; +import '../../widgets/shimmer_loading.dart'; class AssetPage extends ConsumerWidget { const AssetPage({super.key}); @@ -14,7 +15,6 @@ class AssetPage extends ConsumerWidget { static const Color _grayText = Color(0xFF6B7280); static const Color _darkText = Color(0xFF1F2937); static const Color _bgGray = Color(0xFFF3F4F6); - static const Color _lightGray = Color(0xFFF9FAFB); static const Color _riverBed = Color(0xFF4B5563); static const Color _serenade = Color(0xFFFFF7ED); static const Color _feta = Color(0xFFF0FDF4); @@ -64,7 +64,7 @@ class AssetPage extends ConsumerWidget { // 资产列表 accountAsync.when( data: (account) => _buildAssetList(account), - loading: () => _buildLoadingCard(), + loading: () => _buildAssetListSkeleton(), error: (_, __) => const SizedBox.shrink(), ), const SizedBox(height: 24), @@ -74,7 +74,7 @@ class AssetPage extends ConsumerWidget { // 账户列表 accountAsync.when( data: (account) => _buildAccountList(account), - loading: () => _buildLoadingCard(), + loading: () => _buildAssetListSkeleton(), error: (_, __) => const SizedBox.shrink(), ), const SizedBox(height: 100), @@ -767,13 +767,18 @@ class AssetPage extends ConsumerWidget { } Widget _buildLoadingCard() { - return Container( - padding: const EdgeInsets.all(32), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(16), - ), - child: const Center(child: CircularProgressIndicator()), + return const AssetCardSkeleton(); + } + + Widget _buildAssetListSkeleton() { + return Column( + children: const [ + AssetItemSkeleton(), + SizedBox(height: 16), + AssetItemSkeleton(), + SizedBox(height: 16), + AssetItemSkeleton(), + ], ); } diff --git a/frontend/mining-app/lib/presentation/pages/contribution/contribution_page.dart b/frontend/mining-app/lib/presentation/pages/contribution/contribution_page.dart index 535214bf..541d0617 100644 --- a/frontend/mining-app/lib/presentation/pages/contribution/contribution_page.dart +++ b/frontend/mining-app/lib/presentation/pages/contribution/contribution_page.dart @@ -7,6 +7,7 @@ import '../../../domain/entities/contribution.dart'; import '../../../domain/entities/contribution_record.dart'; import '../../providers/user_providers.dart'; import '../../providers/contribution_providers.dart'; +import '../../widgets/shimmer_loading.dart'; class ContributionPage extends ConsumerWidget { const ContributionPage({super.key}); @@ -75,7 +76,7 @@ class ContributionPage extends ConsumerWidget { ], ); }, - loading: () => const Center(child: CircularProgressIndicator()), + loading: () => const PageSkeleton(), error: (error, _) => Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -382,12 +383,16 @@ class ContributionPage extends ConsumerWidget { }).toList(), ); }, - loading: () => const Padding( - padding: EdgeInsets.symmetric(vertical: 20), - child: SizedBox( - width: 24, - height: 24, - child: CircularProgressIndicator(strokeWidth: 2), + loading: () => Padding( + padding: const EdgeInsets.symmetric(vertical: 20), + child: ShimmerLoading( + child: Column( + children: const [ + ShimmerBox(height: 48), + SizedBox(height: 12), + ShimmerBox(height: 48), + ], + ), ), ), error: (error, _) => Padding( diff --git a/frontend/mining-app/lib/presentation/pages/splash/splash_page.dart b/frontend/mining-app/lib/presentation/pages/splash/splash_page.dart index 4463565b..6d9f4e69 100644 --- a/frontend/mining-app/lib/presentation/pages/splash/splash_page.dart +++ b/frontend/mining-app/lib/presentation/pages/splash/splash_page.dart @@ -25,28 +25,21 @@ class _SplashPageState extends ConsumerState { } Future _initialize() async { - await Future.delayed(const Duration(seconds: 2)); + // 最多等 500ms 展示品牌,然后立即跳转,不阻塞用户 + await Future.delayed(const Duration(milliseconds: 500)); if (!mounted) return; - // 检查用户登录状态 final userState = ref.read(userNotifierProvider); if (userState.isLoggedIn) { - // 已登录,尝试刷新token - try { - await ref.read(userNotifierProvider.notifier).refreshTokenIfNeeded(); - if (mounted) { - context.go(Routes.contribution); - } - } catch (e) { - // token刷新失败,跳转到登录页 - if (mounted) { - context.go(Routes.login); - } + // 立即跳转,不等待 token 刷新 + if (mounted) { + context.go(Routes.contribution); } + // 后台刷新 token,失败了由 API 拦截器处理 401 + ref.read(userNotifierProvider.notifier).refreshTokenIfNeeded(); } else { - // 未登录,跳转到登录页 context.go(Routes.login); } } diff --git a/frontend/mining-app/lib/presentation/pages/trading/trading_page.dart b/frontend/mining-app/lib/presentation/pages/trading/trading_page.dart index f138d068..09272d0d 100644 --- a/frontend/mining-app/lib/presentation/pages/trading/trading_page.dart +++ b/frontend/mining-app/lib/presentation/pages/trading/trading_page.dart @@ -5,6 +5,7 @@ import '../../../core/utils/format_utils.dart'; import '../../providers/mining_providers.dart'; import '../../providers/user_providers.dart'; import '../../providers/trading_providers.dart'; +import '../../widgets/shimmer_loading.dart'; class TradingPage extends ConsumerStatefulWidget { const TradingPage({super.key}); @@ -767,14 +768,25 @@ class _TradingPageState extends ConsumerState { } Widget _buildLoadingCard() { - return Container( - margin: const EdgeInsets.all(16), - padding: const EdgeInsets.all(32), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(16), + return ShimmerLoading( + child: Container( + margin: const EdgeInsets.all(16), + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + ShimmerBox(width: 100, height: 16), + SizedBox(height: 12), + ShimmerBox(width: 150, height: 28), + SizedBox(height: 8), + ShimmerBox(width: 80, height: 14), + ], + ), ), - child: const Center(child: CircularProgressIndicator()), ); } @@ -830,7 +842,9 @@ class _TradingPageState extends ConsumerState { ); if (success) { _amountController.clear(); + // 交易成功后刷新所有相关数据 ref.invalidate(shareAccountProvider(accountSequence)); + ref.invalidate(globalStateProvider); } } } diff --git a/frontend/mining-app/lib/presentation/providers/contribution_providers.dart b/frontend/mining-app/lib/presentation/providers/contribution_providers.dart index 87a26685..ab17eaa6 100644 --- a/frontend/mining-app/lib/presentation/providers/contribution_providers.dart +++ b/frontend/mining-app/lib/presentation/providers/contribution_providers.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../domain/entities/contribution.dart'; import '../../domain/entities/contribution_record.dart'; @@ -15,8 +16,21 @@ final contributionRepositoryProvider = Provider((ref) { final contributionProvider = FutureProvider.family( (ref, accountSequence) async { + // 空字符串不请求 + if (accountSequence.isEmpty) return null; + final useCase = ref.watch(getUserContributionUseCaseProvider); final result = await useCase(accountSequence); + + // 保持 provider 活跃,避免重复请求 + ref.keepAlive(); + + // 5 分钟后自动失效 + final timer = Timer(const Duration(minutes: 5), () { + ref.invalidateSelf(); + }); + ref.onDispose(() => timer.cancel()); + return result.fold( (failure) => throw Exception(failure.message), (contribution) => contribution, @@ -52,12 +66,25 @@ class ContributionRecordsParams { /// 贡献值记录 Provider final contributionRecordsProvider = FutureProvider.family( (ref, params) async { + // 空字符串不请求 + if (params.accountSequence.isEmpty) return null; + final repository = ref.watch(contributionRepositoryProvider); final result = await repository.getContributionRecords( params.accountSequence, page: params.page, pageSize: params.pageSize, ); + + // 保持 provider 活跃 + ref.keepAlive(); + + // 5 分钟后自动失效 + final timer = Timer(const Duration(minutes: 5), () { + ref.invalidateSelf(); + }); + ref.onDispose(() => timer.cancel()); + return result.fold( (failure) => throw Exception(failure.message), (records) => records, diff --git a/frontend/mining-app/lib/presentation/providers/mining_providers.dart b/frontend/mining-app/lib/presentation/providers/mining_providers.dart index d518c81a..26ab9ec7 100644 --- a/frontend/mining-app/lib/presentation/providers/mining_providers.dart +++ b/frontend/mining-app/lib/presentation/providers/mining_providers.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../domain/entities/share_account.dart'; import '../../domain/entities/global_state.dart'; @@ -14,11 +15,24 @@ final getGlobalStateUseCaseProvider = Provider((ref) { return getIt(); }); -// State Providers +// State Providers - 使用 keepAlive 缓存数据,避免重复请求 final shareAccountProvider = FutureProvider.family( (ref, accountSequence) async { + // 空字符串不请求 + if (accountSequence.isEmpty) return null; + final useCase = ref.watch(getShareAccountUseCaseProvider); final result = await useCase(accountSequence); + + // 保持 provider 活跃,避免每次 rebuild 都重新请求 + ref.keepAlive(); + + // 5 分钟后自动失效,允许刷新 + final timer = Timer(const Duration(minutes: 5), () { + ref.invalidateSelf(); + }); + ref.onDispose(() => timer.cancel()); + return result.fold( (failure) => throw Exception(failure.message), (account) => account, @@ -29,6 +43,16 @@ final shareAccountProvider = FutureProvider.family( final globalStateProvider = FutureProvider((ref) async { final useCase = ref.watch(getGlobalStateUseCaseProvider); final result = await useCase(); + + // 保持 provider 活跃 + ref.keepAlive(); + + // 5 分钟后自动失效 + final timer = Timer(const Duration(minutes: 5), () { + ref.invalidateSelf(); + }); + ref.onDispose(() => timer.cancel()); + return result.fold( (failure) => throw Exception(failure.message), (state) => state, diff --git a/frontend/mining-app/lib/presentation/widgets/shimmer_loading.dart b/frontend/mining-app/lib/presentation/widgets/shimmer_loading.dart new file mode 100644 index 00000000..44ba8939 --- /dev/null +++ b/frontend/mining-app/lib/presentation/widgets/shimmer_loading.dart @@ -0,0 +1,289 @@ +import 'package:flutter/material.dart'; + +/// 骨架屏加载组件 - 提供更好的加载体验 +class ShimmerLoading extends StatefulWidget { + final Widget child; + final bool isLoading; + + const ShimmerLoading({ + super.key, + required this.child, + this.isLoading = true, + }); + + @override + State createState() => _ShimmerLoadingState(); +} + +class _ShimmerLoadingState extends State + with SingleTickerProviderStateMixin { + late AnimationController _controller; + late Animation _animation; + + @override + void initState() { + super.initState(); + _controller = AnimationController( + duration: const Duration(milliseconds: 1500), + vsync: this, + )..repeat(); + _animation = Tween(begin: -2, end: 2).animate( + CurvedAnimation(parent: _controller, curve: Curves.easeInOutSine), + ); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + if (!widget.isLoading) return widget.child; + + return AnimatedBuilder( + animation: _animation, + builder: (context, child) { + return ShaderMask( + shaderCallback: (bounds) { + return LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: const [ + Color(0xFFEBEBF4), + Color(0xFFF4F4F4), + Color(0xFFEBEBF4), + ], + stops: [ + _animation.value - 1, + _animation.value, + _animation.value + 1, + ].map((e) => e.clamp(0.0, 1.0)).toList(), + ).createShader(bounds); + }, + blendMode: BlendMode.srcATop, + child: widget.child, + ); + }, + ); + } +} + +/// 骨架屏占位框 +class ShimmerBox extends StatelessWidget { + final double? width; + final double height; + final double borderRadius; + + const ShimmerBox({ + super.key, + this.width, + required this.height, + this.borderRadius = 8, + }); + + @override + Widget build(BuildContext context) { + return Container( + width: width, + height: height, + decoration: BoxDecoration( + color: const Color(0xFFE5E7EB), + borderRadius: BorderRadius.circular(borderRadius), + ), + ); + } +} + +/// 资产卡片骨架屏 +class AssetCardSkeleton extends StatelessWidget { + const AssetCardSkeleton({super.key}); + + @override + Widget build(BuildContext context) { + return ShimmerLoading( + child: Container( + margin: const EdgeInsets.all(16), + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.04), + blurRadius: 30, + offset: const Offset(0, 8), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const ShimmerBox(width: 80, height: 16), + const SizedBox(height: 12), + const ShimmerBox(width: 180, height: 36), + const SizedBox(height: 8), + const ShimmerBox(width: 120, height: 14), + const SizedBox(height: 12), + const ShimmerBox(width: 100, height: 24, borderRadius: 12), + ], + ), + ), + ); + } +} + +/// 资产项目骨架屏 +class AssetItemSkeleton extends StatelessWidget { + const AssetItemSkeleton({super.key}); + + @override + Widget build(BuildContext context) { + return ShimmerLoading( + child: Container( + padding: const EdgeInsets.all(16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 2, + offset: const Offset(0, 1), + ), + ], + ), + child: Row( + children: [ + const ShimmerBox(width: 40, height: 40, borderRadius: 20), + const SizedBox(width: 12), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const ShimmerBox(width: 60, height: 16), + const SizedBox(height: 8), + const ShimmerBox(width: 100, height: 20), + const SizedBox(height: 4), + const ShimmerBox(width: 80, height: 12), + ], + ), + ), + const ShimmerBox(width: 14, height: 20), + ], + ), + ), + ); + } +} + +/// 收益统计骨架屏 +class EarningsStatsSkeleton extends StatelessWidget { + const EarningsStatsSkeleton({super.key}); + + @override + Widget build(BuildContext context) { + return ShimmerLoading( + child: Container( + padding: const EdgeInsets.all(20), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.05), + blurRadius: 2, + offset: const Offset(0, 1), + ), + ], + ), + child: Column( + children: [ + Row( + children: [ + Container( + width: 4, + height: 20, + decoration: BoxDecoration( + color: const Color(0xFFE5E7EB), + borderRadius: BorderRadius.circular(2), + ), + ), + const SizedBox(width: 8), + const ShimmerBox(width: 60, height: 16), + ], + ), + const SizedBox(height: 16), + Row( + children: [ + Expanded( + child: Column( + children: const [ + ShimmerBox(width: 50, height: 12), + SizedBox(height: 8), + ShimmerBox(width: 70, height: 16), + ], + ), + ), + Container( + width: 1, + height: 40, + color: const Color(0xFFE5E7EB), + ), + Expanded( + child: Column( + children: const [ + ShimmerBox(width: 50, height: 12), + SizedBox(height: 8), + ShimmerBox(width: 70, height: 16), + ], + ), + ), + Container( + width: 1, + height: 40, + color: const Color(0xFFE5E7EB), + ), + Expanded( + child: Column( + children: const [ + ShimmerBox(width: 50, height: 12), + SizedBox(height: 8), + ShimmerBox(width: 70, height: 16), + ], + ), + ), + ], + ), + ], + ), + ), + ); + } +} + +/// 页面骨架屏 +class PageSkeleton extends StatelessWidget { + const PageSkeleton({super.key}); + + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + children: const [ + AssetCardSkeleton(), + SizedBox(height: 24), + AssetItemSkeleton(), + SizedBox(height: 16), + AssetItemSkeleton(), + SizedBox(height: 16), + AssetItemSkeleton(), + SizedBox(height: 24), + EarningsStatsSkeleton(), + ], + ), + ); + } +}