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:
parent
3e352dbcfe
commit
54a225ebf2
|
|
@ -64,6 +64,18 @@ class WalletStatusNotifier extends StateNotifier<WalletStatusState> {
|
|||
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');
|
||||
state = state.copyWith(isPolling: true);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@ class _DepositUsdtPageState extends ConsumerState<DepositUsdtPage> {
|
|||
/// 用户账户序列号(作为充值地址显示)
|
||||
String? _accountSequence;
|
||||
|
||||
/// 钱包是否已就绪
|
||||
bool _isWalletReady = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
|
@ -58,22 +61,41 @@ class _DepositUsdtPageState extends ConsumerState<DepositUsdtPage> {
|
|||
|
||||
_accountSequence = userSerialNum;
|
||||
|
||||
// 从 wallet-service 查询钱包余额
|
||||
// 检查钱包状态
|
||||
try {
|
||||
final walletService = ref.read(walletServiceProvider);
|
||||
final walletResponse = await walletService.getMyWallet();
|
||||
// 显示 USDT 可用余额
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_balance = walletResponse.balances.usdt.available.toStringAsFixed(2);
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
final walletInfo = await accountService.getWalletInfo(userSerialNum);
|
||||
_isWalletReady = walletInfo.isReady;
|
||||
debugPrint('[DepositUsdtPage] 钱包状态: ${walletInfo.status}, isReady: $_isWalletReady');
|
||||
} 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) {
|
||||
setState(() {
|
||||
_balance = '0.00';
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
|
|
@ -152,24 +174,94 @@ class _DepositUsdtPageState extends ConsumerState<DepositUsdtPage> {
|
|||
_buildAppBar(),
|
||||
// 内容区域
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
// 余额显示
|
||||
_buildBalanceSection(),
|
||||
const SizedBox(height: 16),
|
||||
// 二维码卡片
|
||||
_buildQrCodeCard(),
|
||||
// 警告提示
|
||||
_buildWarningText(),
|
||||
],
|
||||
child: _isLoading
|
||||
? const Center(
|
||||
child: CircularProgressIndicator(
|
||||
valueColor: AlwaysStoppedAnimation<Color>(Color(0xFFD4AF37)),
|
||||
),
|
||||
)
|
||||
: !_isWalletReady
|
||||
? _buildWalletNotReadyView()
|
||||
: SingleChildScrollView(
|
||||
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(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import '../../../../core/di/injection_container.dart';
|
||||
import '../../../../core/storage/storage_keys.dart';
|
||||
|
||||
/// 监控状态枚举
|
||||
enum MonitorStatus {
|
||||
|
|
@ -145,9 +146,25 @@ class _MiningPageState extends ConsumerState<MiningPage> {
|
|||
}
|
||||
|
||||
/// 开始轮询钱包生成状态
|
||||
void _startWalletPolling() {
|
||||
Future<void> _startWalletPolling() async {
|
||||
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();
|
||||
|
||||
|
|
@ -165,18 +182,23 @@ class _MiningPageState extends ConsumerState<MiningPage> {
|
|||
|
||||
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;
|
||||
// 钱包已就绪,停止轮询
|
||||
_walletPollingTimer?.cancel();
|
||||
debugPrint('[MiningPage] 钱包已就绪,停止轮询');
|
||||
} else {
|
||||
// 非 ready 状态(包括 failed、creating)都继续轮询
|
||||
});
|
||||
_walletPollingTimer?.cancel();
|
||||
debugPrint('[MiningPage] 钱包已就绪,停止轮询');
|
||||
} else {
|
||||
// 非 ready 状态(包括 failed、creating)都继续轮询
|
||||
setState(() {
|
||||
_walletStatus = WalletCreationStatus.creating;
|
||||
debugPrint('[MiningPage] 钱包创建中,继续轮询...');
|
||||
}
|
||||
});
|
||||
});
|
||||
debugPrint('[MiningPage] 钱包创建中,继续轮询...');
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('[MiningPage] 检查钱包状态失败: $e');
|
||||
// 不改变状态,继续轮询
|
||||
|
|
|
|||
|
|
@ -49,6 +49,9 @@ class _WithdrawUsdtPageState extends ConsumerState<WithdrawUsdtPage> {
|
|||
/// 是否正在加载
|
||||
bool _isLoading = true;
|
||||
|
||||
/// 钱包是否已就绪
|
||||
bool _isWalletReady = false;
|
||||
|
||||
/// 手续费率
|
||||
final double _feeRate = 0.001; // 0.1%
|
||||
|
||||
|
|
@ -73,15 +76,62 @@ class _WithdrawUsdtPageState extends ConsumerState<WithdrawUsdtPage> {
|
|||
try {
|
||||
debugPrint('[WithdrawUsdtPage] 开始加载钱包数据...');
|
||||
|
||||
final walletService = ref.read(walletServiceProvider);
|
||||
final wallet = await walletService.getMyWallet();
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_usdtBalance = wallet.balances.usdt.available;
|
||||
_isLoading = false;
|
||||
});
|
||||
debugPrint('[WithdrawUsdtPage] USDT 余额: $_usdtBalance');
|
||||
// 获取用户账户序列号
|
||||
final accountService = ref.read(accountServiceProvider);
|
||||
final userSerialNum = await accountService.getUserSerialNum();
|
||||
|
||||
if (userSerialNum == null || userSerialNum.isEmpty) {
|
||||
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) {
|
||||
debugPrint('[WithdrawUsdtPage] 加载数据失败: $e');
|
||||
|
|
@ -317,40 +367,42 @@ class _WithdrawUsdtPageState extends ConsumerState<WithdrawUsdtPage> {
|
|||
valueColor: AlwaysStoppedAnimation<Color>(Color(0xFFD4AF37)),
|
||||
),
|
||||
)
|
||||
: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 余额卡片
|
||||
_buildBalanceCard(),
|
||||
const SizedBox(height: 24),
|
||||
: !_isWalletReady
|
||||
? _buildWalletNotReadyView()
|
||||
: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 余额卡片
|
||||
_buildBalanceCard(),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// 网络选择
|
||||
_buildNetworkSelector(),
|
||||
const SizedBox(height: 24),
|
||||
// 网络选择
|
||||
_buildNetworkSelector(),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// 提款地址
|
||||
_buildAddressInput(),
|
||||
const SizedBox(height: 24),
|
||||
// 提款地址
|
||||
_buildAddressInput(),
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// 提款金额
|
||||
_buildAmountInput(),
|
||||
const SizedBox(height: 16),
|
||||
// 提款金额
|
||||
_buildAmountInput(),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// 手续费信息
|
||||
_buildFeeInfo(),
|
||||
const SizedBox(height: 32),
|
||||
// 手续费信息
|
||||
_buildFeeInfo(),
|
||||
const SizedBox(height: 32),
|
||||
|
||||
// 提交按钮
|
||||
_buildSubmitButton(),
|
||||
const SizedBox(height: 16),
|
||||
// 提交按钮
|
||||
_buildSubmitButton(),
|
||||
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() {
|
||||
return Container(
|
||||
|
|
|
|||
Loading…
Reference in New Issue