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;
|
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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
],
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -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 状态(包括 failed、creating)都继续轮询
|
// 非 ready 状态(包括 failed、creating)都继续轮询
|
||||||
|
setState(() {
|
||||||
_walletStatus = WalletCreationStatus.creating;
|
_walletStatus = WalletCreationStatus.creating;
|
||||||
debugPrint('[MiningPage] 钱包创建中,继续轮询...');
|
});
|
||||||
}
|
debugPrint('[MiningPage] 钱包创建中,继续轮询...');
|
||||||
});
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('[MiningPage] 检查钱包状态失败: $e');
|
debugPrint('[MiningPage] 检查钱包状态失败: $e');
|
||||||
// 不改变状态,继续轮询
|
// 不改变状态,继续轮询
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue