diff --git a/frontend/mobile-app/lib/features/profile/presentation/pages/profile_page.dart b/frontend/mobile-app/lib/features/profile/presentation/pages/profile_page.dart index bfa53d83..8ac76f1b 100644 --- a/frontend/mobile-app/lib/features/profile/presentation/pages/profile_page.dart +++ b/frontend/mobile-app/lib/features/profile/presentation/pages/profile_page.dart @@ -801,39 +801,52 @@ class _ProfilePageState extends ConsumerState { // [2026-03-01] 合并预种可结算奖励到列表中 // pre-planting/my-rewards 返回所有分配记录(不区分状态), - // 但部分条目可能实际处于 PENDING 状态(用户未认种时)。 - // 需要排除 PENDING 和 EXPIRED 状态的条目,只保留真正可结算的。 - final pendingPplOrderIds = walletPendingRewards - .where((r) => r.isPrePlanting) - .map((r) => r.sourceOrderId) - .toSet(); - final expiredPplOrderIds = expiredRewards - .where((r) => r.sourceOrderId.startsWith('PPL')) - .map((r) => r.sourceOrderId) - .toSet(); - final excludedPplOrderIds = {...pendingPplOrderIds, ...expiredPplOrderIds}; - final prePlantingSettleable = prePlantingRewards.settleableRewards - .where((r) => !excludedPplOrderIds.contains(r.sourceOrderNo)) - .map((r) { - final srcAcct = r.sourceAccountSequence; - final memoSuffix = (srcAcct != null && srcAcct.isNotEmpty) - ? ':来自${srcAcct}的预种' - : ''; - return SettleableRewardItem( - id: r.id, - rightType: r.rightType, - usdtAmount: r.usdtAmount, - hashpowerAmount: r.hashpowerAmount, - createdAt: r.createdAt, - claimedAt: null, - sourceOrderNo: r.sourceOrderNo, - sourceAccountSequence: r.sourceAccountSequence, - memo: '[预种] ${r.memo}$memoSuffix', - ); - }) - .toList(); + // 需要排除 PENDING、EXPIRED 和已结算到余额的条目,只保留真正可结算的。 + // + // 策略:以 wallet 的 settleableUsdt 为权威来源。 + // 如果 settleableUsdt=0(已全部结算到余额),直接跳过,不显示任何预种可结算条目。 + // 如果 settleableUsdt>0,排除 PENDING + EXPIRED 的条目后, + // 按金额截断,确保展示总额不超过 wallet 实际可结算金额。 + final walletSettleableUsdt = walletInfo.rewards.settleableUsdt; + List prePlantingSettleable = []; + + if (walletSettleableUsdt > 0) { + final pendingPplOrderIds = walletPendingRewards + .where((r) => r.isPrePlanting) + .map((r) => r.sourceOrderId) + .toSet(); + final expiredPplOrderIds = expiredRewards + .where((r) => r.sourceOrderId.startsWith('PPL')) + .map((r) => r.sourceOrderId) + .toSet(); + final excludedPplOrderIds = {...pendingPplOrderIds, ...expiredPplOrderIds}; + + double accumulatedUsdt = 0; + for (final r in prePlantingRewards.settleableRewards) { + if (excludedPplOrderIds.contains(r.sourceOrderNo)) continue; + if (accumulatedUsdt + r.usdtAmount > walletSettleableUsdt + 0.01) break; + accumulatedUsdt += r.usdtAmount; + + final srcAcct = r.sourceAccountSequence; + final memoSuffix = (srcAcct != null && srcAcct.isNotEmpty) + ? ':来自${srcAcct}的预种' + : ''; + prePlantingSettleable.add(SettleableRewardItem( + id: r.id, + rightType: r.rightType, + usdtAmount: r.usdtAmount, + hashpowerAmount: r.hashpowerAmount, + createdAt: r.createdAt, + claimedAt: null, + sourceOrderNo: r.sourceOrderNo, + sourceAccountSequence: r.sourceAccountSequence, + memo: '[预种] ${r.memo}$memoSuffix', + )); + } + } + settleableRewards = [...settleableRewards, ...prePlantingSettleable]; - debugPrint('[ProfilePage] 预种可结算奖励: ${prePlantingSettleable.length} 条 (排除 ${pendingPplOrderIds.length} 条 PENDING, ${expiredPplOrderIds.length} 条 EXPIRED)'); + debugPrint('[ProfilePage] 预种可结算奖励: ${prePlantingSettleable.length} 条 (walletSettleableUsdt=$walletSettleableUsdt)'); // [2026-03-01] 合并预种待领取奖励到列表中 // wallet-service 的 pending_rewards 表包含正常认种 + 预种的待领取记录,