fix(frontend): 修复资产页面1秒实时刷新问题
- 使用 mining-service 的 perSecondEarning 替代 assetGrowthPerSecond - 添加 _timerStarted 标志防止定时器重复启动 - 修复页面进入时定时器可能未启动的问题 - 下拉刷新时同步刷新 shareAccountProvider - 正确显示每秒增长值 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
5c633b9979
commit
d8dd38e91b
|
|
@ -7,6 +7,7 @@ import '../../../core/utils/format_utils.dart';
|
|||
import '../../../domain/entities/asset_display.dart';
|
||||
import '../../providers/user_providers.dart';
|
||||
import '../../providers/asset_providers.dart';
|
||||
import '../../providers/mining_providers.dart';
|
||||
import '../../widgets/shimmer_loading.dart';
|
||||
|
||||
class AssetPage extends ConsumerStatefulWidget {
|
||||
|
|
@ -36,6 +37,7 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
|||
double _initialShareBalance = 0;
|
||||
double _growthPerSecond = 0;
|
||||
String? _lastAccountSequence;
|
||||
bool _timerStarted = false;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
|
|
@ -43,13 +45,18 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
|||
super.dispose();
|
||||
}
|
||||
|
||||
/// 启动定时器
|
||||
void _startTimer(AssetDisplay asset) {
|
||||
/// 启动定时器(使用外部传入的每秒增长值)
|
||||
void _startTimerWithGrowth(AssetDisplay asset, String perSecondEarning) {
|
||||
// 防止重复启动
|
||||
if (_timerStarted && _refreshTimer != null) return;
|
||||
|
||||
_refreshTimer?.cancel();
|
||||
_elapsedSeconds = 0;
|
||||
_initialDisplayValue = double.tryParse(asset.displayAssetValue) ?? 0;
|
||||
_initialShareBalance = double.tryParse(asset.shareBalance) ?? 0;
|
||||
_growthPerSecond = AssetValueCalculator.calculateGrowthPerSecond(asset.assetGrowthPerSecond);
|
||||
// 使用传入的每秒增长值(来自 mining-service)
|
||||
_growthPerSecond = double.tryParse(perSecondEarning) ?? 0;
|
||||
_timerStarted = true;
|
||||
|
||||
_refreshTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
||||
if (mounted) {
|
||||
|
|
@ -63,7 +70,9 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
|||
/// 重置定时器(刷新时调用)
|
||||
void _resetTimer() {
|
||||
_refreshTimer?.cancel();
|
||||
_refreshTimer = null;
|
||||
_elapsedSeconds = 0;
|
||||
_timerStarted = false;
|
||||
}
|
||||
|
||||
/// 计算当前实时资产显示值
|
||||
|
|
@ -84,18 +93,37 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
|||
final accountSequence = user.accountSequence ?? '';
|
||||
// 使用 public API,不依赖 JWT token
|
||||
final assetAsync = ref.watch(accountAssetProvider(accountSequence));
|
||||
// 从 mining-service 获取每秒收益
|
||||
final shareAccountAsync = ref.watch(shareAccountProvider(accountSequence));
|
||||
|
||||
// 提取数据和加载状态
|
||||
final isLoading = assetAsync.isLoading || accountSequence.isEmpty;
|
||||
final asset = assetAsync.valueOrNull;
|
||||
final shareAccount = shareAccountAsync.valueOrNull;
|
||||
|
||||
// 获取每秒收益(优先使用 mining-service 的数据)
|
||||
final perSecondEarning = shareAccount?.perSecondEarning ?? '0';
|
||||
final hasValidGrowth = (double.tryParse(perSecondEarning) ?? 0) > 0;
|
||||
|
||||
// 当数据加载完成时启动定时器
|
||||
if (asset != null && (_lastAsset == null || _lastAccountSequence != accountSequence)) {
|
||||
_lastAccountSequence = accountSequence;
|
||||
_lastAsset = asset;
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_startTimer(asset);
|
||||
});
|
||||
if (asset != null && hasValidGrowth) {
|
||||
// 账户切换或首次加载时重置并启动定时器
|
||||
if (_lastAccountSequence != accountSequence) {
|
||||
_lastAccountSequence = accountSequence;
|
||||
_lastAsset = asset;
|
||||
_resetTimer();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted) _startTimerWithGrowth(asset, perSecondEarning);
|
||||
});
|
||||
} else if (!_timerStarted) {
|
||||
// 定时器未启动时启动(例如页面刚进入)
|
||||
_lastAsset = asset;
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted) _startTimerWithGrowth(asset, perSecondEarning);
|
||||
});
|
||||
} else {
|
||||
_lastAsset = asset;
|
||||
}
|
||||
} else if (asset != null) {
|
||||
_lastAsset = asset;
|
||||
}
|
||||
|
|
@ -111,6 +139,7 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
|||
_resetTimer();
|
||||
_lastAsset = null;
|
||||
ref.invalidate(accountAssetProvider(accountSequence));
|
||||
ref.invalidate(shareAccountProvider(accountSequence));
|
||||
},
|
||||
child: SingleChildScrollView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
|
|
@ -127,13 +156,13 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
|||
children: [
|
||||
const SizedBox(height: 8),
|
||||
// 总资产卡片 - 始终显示,数字部分闪烁,实时刷新
|
||||
_buildTotalAssetCard(asset, isLoading, _currentDisplayValue),
|
||||
_buildTotalAssetCard(asset, isLoading, _currentDisplayValue, perSecondEarning),
|
||||
const SizedBox(height: 24),
|
||||
// 快捷操作按钮
|
||||
_buildQuickActions(context),
|
||||
const SizedBox(height: 24),
|
||||
// 资产列表 - 始终显示,数字部分闪烁,实时刷新
|
||||
_buildAssetList(asset, isLoading, _currentShareBalance),
|
||||
_buildAssetList(asset, isLoading, _currentShareBalance, perSecondEarning),
|
||||
const SizedBox(height: 24),
|
||||
// 交易统计
|
||||
_buildEarningsCard(asset, isLoading),
|
||||
|
|
@ -172,11 +201,9 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
|||
);
|
||||
}
|
||||
|
||||
Widget _buildTotalAssetCard(AssetDisplay? asset, bool isLoading, double currentDisplayValue) {
|
||||
// 计算每秒增长
|
||||
final growthPerSecond = asset != null
|
||||
? AssetValueCalculator.calculateGrowthPerSecond(asset.assetGrowthPerSecond)
|
||||
: 0.0;
|
||||
Widget _buildTotalAssetCard(AssetDisplay? asset, bool isLoading, double currentDisplayValue, String perSecondEarning) {
|
||||
// 使用传入的每秒增长值(来自 mining-service)
|
||||
final growthPerSecond = double.tryParse(perSecondEarning) ?? 0.0;
|
||||
|
||||
// 使用实时计算的资产值(如果有)
|
||||
final displayValue = asset != null && currentDisplayValue > 0
|
||||
|
|
@ -372,7 +399,7 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
|||
);
|
||||
}
|
||||
|
||||
Widget _buildAssetList(AssetDisplay? asset, bool isLoading, double currentShareBalance) {
|
||||
Widget _buildAssetList(AssetDisplay? asset, bool isLoading, double currentShareBalance, String perSecondEarning) {
|
||||
// 使用实时积分股余额
|
||||
final shareBalance = asset != null && currentShareBalance > 0
|
||||
? currentShareBalance
|
||||
|
|
@ -395,7 +422,7 @@ class _AssetPageState extends ConsumerState<AssetPage> {
|
|||
? '¥${formatAmount((shareBalance * currentPrice).toString())}'
|
||||
: null,
|
||||
tag: asset != null ? '含倍数资产: ${formatCompact(multipliedAsset.toString())}' : null,
|
||||
growthText: asset != null ? '每秒 +${formatDecimal(asset.assetGrowthPerSecond, 8)}' : null,
|
||||
growthText: asset != null ? '每秒 +${formatDecimal(perSecondEarning, 8)}' : null,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
// 积分值(现金余额)
|
||||
|
|
|
|||
Loading…
Reference in New Issue