feat: 充值/提现页面添加钱包状态检查,优化钱包状态轮询逻辑

- 充值页面: 先检查钱包状态,未就绪时显示"账号审核中..."
- 提现页面: 先检查钱包状态,未就绪时显示"账号审核中..."
- 监控页面: 先从本地存储读取钱包状态,已就绪则跳过轮询
- wallet_status_provider: 先检查本地存储,避免不必要的API调用

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2025-12-21 18:36:44 -08:00
parent 3e352dbcfe
commit 54a225ebf2
4 changed files with 314 additions and 74 deletions

View File

@ -64,6 +64,18 @@ class WalletStatusNotifier extends StateNotifier<WalletStatusState> {
return; return;
} }
//
final isWalletReady = await _secureStorage.read(key: StorageKeys.isWalletReady);
if (isWalletReady == 'true') {
// ready
debugPrint('[WalletStatusProvider] Local storage shows wallet ready, skip polling');
state = state.copyWith(
status: WalletGenerationStatus.ready,
lastChecked: DateTime.now(),
);
return;
}
debugPrint('[WalletStatusProvider] Starting wallet status polling'); debugPrint('[WalletStatusProvider] Starting wallet status polling');
state = state.copyWith(isPolling: true); state = state.copyWith(isPolling: true);

View File

@ -25,6 +25,9 @@ class _DepositUsdtPageState extends ConsumerState<DepositUsdtPage> {
/// ///
String? _accountSequence; String? _accountSequence;
///
bool _isWalletReady = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -58,22 +61,41 @@ class _DepositUsdtPageState extends ConsumerState<DepositUsdtPage> {
_accountSequence = userSerialNum; _accountSequence = userSerialNum;
// wallet-service //
try { try {
final walletService = ref.read(walletServiceProvider); final walletInfo = await accountService.getWalletInfo(userSerialNum);
final walletResponse = await walletService.getMyWallet(); _isWalletReady = walletInfo.isReady;
// USDT debugPrint('[DepositUsdtPage] 钱包状态: ${walletInfo.status}, isReady: $_isWalletReady');
if (mounted) {
setState(() {
_balance = walletResponse.balances.usdt.available.toStringAsFixed(2);
_isLoading = false;
});
}
} catch (e) { } catch (e) {
debugPrint('查询余额失败: $e'); debugPrint('[DepositUsdtPage] 获取钱包状态失败: $e');
_isWalletReady = false;
}
//
if (_isWalletReady) {
try {
final walletService = ref.read(walletServiceProvider);
final walletResponse = await walletService.getMyWallet();
// USDT
if (mounted) {
setState(() {
_balance = walletResponse.balances.usdt.available.toStringAsFixed(2);
_isLoading = false;
});
}
} catch (e) {
debugPrint('查询余额失败: $e');
if (mounted) {
setState(() {
_balance = '0.00';
_isLoading = false;
});
}
}
} else {
//
if (mounted) { if (mounted) {
setState(() { setState(() {
_balance = '0.00';
_isLoading = false; _isLoading = false;
}); });
} }
@ -152,24 +174,94 @@ class _DepositUsdtPageState extends ConsumerState<DepositUsdtPage> {
_buildAppBar(), _buildAppBar(),
// //
Expanded( Expanded(
child: SingleChildScrollView( child: _isLoading
child: Column( ? const Center(
children: [ child: CircularProgressIndicator(
// valueColor: AlwaysStoppedAnimation<Color>(Color(0xFFD4AF37)),
_buildBalanceSection(), ),
const SizedBox(height: 16), )
// : !_isWalletReady
_buildQrCodeCard(), ? _buildWalletNotReadyView()
// : SingleChildScrollView(
_buildWarningText(), child: Column(
], children: [
//
_buildBalanceSection(),
const SizedBox(height: 16),
//
_buildQrCodeCard(),
//
_buildWarningText(),
],
),
),
),
//
if (!_isLoading && _isWalletReady) _buildBottomButton(),
],
),
),
),
);
}
///
Widget _buildWalletNotReadyView() {
return Center(
child: Padding(
padding: const EdgeInsets.all(32),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
width: 48,
height: 48,
child: CircularProgressIndicator(
strokeWidth: 3,
valueColor: AlwaysStoppedAnimation<Color>(Color(0xFFD4AF37)),
),
),
const SizedBox(height: 24),
const Text(
'账号审核中...',
style: TextStyle(
fontSize: 20,
fontFamily: 'Inter',
fontWeight: FontWeight.w600,
color: Color(0xFF5D4037),
),
),
const SizedBox(height: 12),
const Text(
'您的账号正在审核中,审核通过后即可使用充值功能',
style: TextStyle(
fontSize: 14,
fontFamily: 'Inter',
color: Color(0xFF8B5A2B),
),
textAlign: TextAlign.center,
),
const SizedBox(height: 32),
GestureDetector(
onTap: _loadData,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
decoration: BoxDecoration(
color: const Color(0xFFD4AF37),
borderRadius: BorderRadius.circular(8),
),
child: const Text(
'刷新状态',
style: TextStyle(
fontSize: 16,
fontFamily: 'Inter',
fontWeight: FontWeight.w600,
color: Colors.white,
), ),
), ),
), ),
// ),
_buildBottomButton(), ],
],
),
), ),
), ),
); );

View File

@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import '../../../../core/di/injection_container.dart'; import '../../../../core/di/injection_container.dart';
import '../../../../core/storage/storage_keys.dart';
/// ///
enum MonitorStatus { enum MonitorStatus {
@ -145,9 +146,25 @@ class _MiningPageState extends ConsumerState<MiningPage> {
} }
/// ///
void _startWalletPolling() { Future<void> _startWalletPolling() async {
debugPrint('[MiningPage] 开始轮询钱包生成状态...'); debugPrint('[MiningPage] 开始轮询钱包生成状态...');
//
final secureStorage = ref.read(secureStorageProvider);
final isWalletReady = await secureStorage.read(key: StorageKeys.isWalletReady);
if (isWalletReady == 'true') {
// ready
debugPrint('[MiningPage] 本地存储显示钱包已就绪,无需轮询');
if (mounted) {
setState(() {
_walletStatus = WalletCreationStatus.ready;
});
}
return;
}
// ready
// //
_checkWalletStatus(); _checkWalletStatus();
@ -165,18 +182,23 @@ class _MiningPageState extends ConsumerState<MiningPage> {
if (!mounted) return; if (!mounted) return;
setState(() { if (walletInfo.isReady) {
if (walletInfo.isReady) { //
final secureStorage = ref.read(secureStorageProvider);
await secureStorage.write(key: StorageKeys.isWalletReady, value: 'true');
setState(() {
_walletStatus = WalletCreationStatus.ready; _walletStatus = WalletCreationStatus.ready;
// });
_walletPollingTimer?.cancel(); _walletPollingTimer?.cancel();
debugPrint('[MiningPage] 钱包已就绪,停止轮询'); debugPrint('[MiningPage] 钱包已就绪,停止轮询');
} else { } else {
// ready failedcreating // ready failedcreating
setState(() {
_walletStatus = WalletCreationStatus.creating; _walletStatus = WalletCreationStatus.creating;
debugPrint('[MiningPage] 钱包创建中,继续轮询...'); });
} debugPrint('[MiningPage] 钱包创建中,继续轮询...');
}); }
} catch (e) { } catch (e) {
debugPrint('[MiningPage] 检查钱包状态失败: $e'); debugPrint('[MiningPage] 检查钱包状态失败: $e');
// //

View File

@ -49,6 +49,9 @@ class _WithdrawUsdtPageState extends ConsumerState<WithdrawUsdtPage> {
/// ///
bool _isLoading = true; bool _isLoading = true;
///
bool _isWalletReady = false;
/// ///
final double _feeRate = 0.001; // 0.1% final double _feeRate = 0.001; // 0.1%
@ -73,15 +76,62 @@ class _WithdrawUsdtPageState extends ConsumerState<WithdrawUsdtPage> {
try { try {
debugPrint('[WithdrawUsdtPage] 开始加载钱包数据...'); debugPrint('[WithdrawUsdtPage] 开始加载钱包数据...');
final walletService = ref.read(walletServiceProvider); setState(() {
final wallet = await walletService.getMyWallet(); _isLoading = true;
});
if (mounted) { //
setState(() { final accountService = ref.read(accountServiceProvider);
_usdtBalance = wallet.balances.usdt.available; final userSerialNum = await accountService.getUserSerialNum();
_isLoading = false;
}); if (userSerialNum == null || userSerialNum.isEmpty) {
debugPrint('[WithdrawUsdtPage] USDT 余额: $_usdtBalance'); if (mounted) {
setState(() {
_isLoading = false;
});
}
return;
}
//
try {
final walletInfo = await accountService.getWalletInfo(userSerialNum);
_isWalletReady = walletInfo.isReady;
debugPrint('[WithdrawUsdtPage] 钱包状态: ${walletInfo.status}, isReady: $_isWalletReady');
} catch (e) {
debugPrint('[WithdrawUsdtPage] 获取钱包状态失败: $e');
_isWalletReady = false;
}
//
if (_isWalletReady) {
try {
final walletService = ref.read(walletServiceProvider);
final wallet = await walletService.getMyWallet();
if (mounted) {
setState(() {
_usdtBalance = wallet.balances.usdt.available;
_isLoading = false;
});
debugPrint('[WithdrawUsdtPage] USDT 余额: $_usdtBalance');
}
} catch (e, stackTrace) {
debugPrint('[WithdrawUsdtPage] 加载余额失败: $e');
debugPrint('[WithdrawUsdtPage] 堆栈: $stackTrace');
if (mounted) {
setState(() {
_isLoading = false;
});
}
}
} else {
//
if (mounted) {
setState(() {
_isLoading = false;
});
}
} }
} catch (e, stackTrace) { } catch (e, stackTrace) {
debugPrint('[WithdrawUsdtPage] 加载数据失败: $e'); debugPrint('[WithdrawUsdtPage] 加载数据失败: $e');
@ -317,40 +367,42 @@ class _WithdrawUsdtPageState extends ConsumerState<WithdrawUsdtPage> {
valueColor: AlwaysStoppedAnimation<Color>(Color(0xFFD4AF37)), valueColor: AlwaysStoppedAnimation<Color>(Color(0xFFD4AF37)),
), ),
) )
: SingleChildScrollView( : !_isWalletReady
padding: const EdgeInsets.all(16), ? _buildWalletNotReadyView()
child: Column( : SingleChildScrollView(
crossAxisAlignment: CrossAxisAlignment.start, padding: const EdgeInsets.all(16),
children: [ child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
_buildBalanceCard(), children: [
const SizedBox(height: 24), //
_buildBalanceCard(),
const SizedBox(height: 24),
// //
_buildNetworkSelector(), _buildNetworkSelector(),
const SizedBox(height: 24), const SizedBox(height: 24),
// //
_buildAddressInput(), _buildAddressInput(),
const SizedBox(height: 24), const SizedBox(height: 24),
// //
_buildAmountInput(), _buildAmountInput(),
const SizedBox(height: 16), const SizedBox(height: 16),
// //
_buildFeeInfo(), _buildFeeInfo(),
const SizedBox(height: 32), const SizedBox(height: 32),
// //
_buildSubmitButton(), _buildSubmitButton(),
const SizedBox(height: 16), const SizedBox(height: 16),
// //
_buildNotice(), _buildNotice(),
], ],
), ),
), ),
), ),
], ],
), ),
@ -359,6 +411,68 @@ class _WithdrawUsdtPageState extends ConsumerState<WithdrawUsdtPage> {
); );
} }
///
Widget _buildWalletNotReadyView() {
return Center(
child: Padding(
padding: const EdgeInsets.all(32),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
width: 48,
height: 48,
child: CircularProgressIndicator(
strokeWidth: 3,
valueColor: AlwaysStoppedAnimation<Color>(Color(0xFFD4AF37)),
),
),
const SizedBox(height: 24),
const Text(
'账号审核中...',
style: TextStyle(
fontSize: 20,
fontFamily: 'Inter',
fontWeight: FontWeight.w600,
color: Color(0xFF5D4037),
),
),
const SizedBox(height: 12),
const Text(
'您的账号正在审核中,审核通过后即可使用提取功能',
style: TextStyle(
fontSize: 14,
fontFamily: 'Inter',
color: Color(0xFF8B5A2B),
),
textAlign: TextAlign.center,
),
const SizedBox(height: 32),
GestureDetector(
onTap: _loadWalletData,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
decoration: BoxDecoration(
color: const Color(0xFFD4AF37),
borderRadius: BorderRadius.circular(8),
),
child: const Text(
'刷新状态',
style: TextStyle(
fontSize: 16,
fontFamily: 'Inter',
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
),
),
],
),
),
);
}
/// ///
Widget _buildAppBar() { Widget _buildAppBar() {
return Container( return Container(