diff --git a/frontend/mobile-app/lib/core/services/wallet_service.dart b/frontend/mobile-app/lib/core/services/wallet_service.dart index ee87072f..bcb4b21c 100644 --- a/frontend/mobile-app/lib/core/services/wallet_service.dart +++ b/frontend/mobile-app/lib/core/services/wallet_service.dart @@ -87,8 +87,10 @@ class RewardsInfo { } /// 计算待领取剩余时间(秒) + /// [2026-03-01] 当 pendingUsdt=0 时(已全部结算),倒计时无意义,返回 0 int get pendingRemainingSeconds { if (pendingExpireAt == null) return 0; + if (pendingUsdt <= 0) return 0; final remaining = pendingExpireAt!.difference(DateTime.now()).inSeconds; return remaining > 0 ? remaining : 0; } 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 7573a58b..bfa53d83 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 @@ -814,7 +814,12 @@ class _ProfilePageState extends ConsumerState { final excludedPplOrderIds = {...pendingPplOrderIds, ...expiredPplOrderIds}; final prePlantingSettleable = prePlantingRewards.settleableRewards .where((r) => !excludedPplOrderIds.contains(r.sourceOrderNo)) - .map((r) => SettleableRewardItem( + .map((r) { + final srcAcct = r.sourceAccountSequence; + final memoSuffix = (srcAcct != null && srcAcct.isNotEmpty) + ? ':来自${srcAcct}的预种' + : ''; + return SettleableRewardItem( id: r.id, rightType: r.rightType, usdtAmount: r.usdtAmount, @@ -823,8 +828,9 @@ class _ProfilePageState extends ConsumerState { claimedAt: null, sourceOrderNo: r.sourceOrderNo, sourceAccountSequence: r.sourceAccountSequence, - memo: '[预种] ${r.memo}', - )) + memo: '[预种] ${r.memo}$memoSuffix', + ); + }) .toList(); settleableRewards = [...settleableRewards, ...prePlantingSettleable]; debugPrint('[ProfilePage] 预种可结算奖励: ${prePlantingSettleable.length} 条 (排除 ${pendingPplOrderIds.length} 条 PENDING, ${expiredPplOrderIds.length} 条 EXPIRED)'); @@ -833,9 +839,25 @@ class _ProfilePageState extends ConsumerState { // wallet-service 的 pending_rewards 表包含正常认种 + 预种的待领取记录, // 但 reward-service 的 /rewards/pending 已经返回了正常认种的待领取记录, // 所以这里只筛选预种的条目(sourceOrderId 以 PPL 开头),避免重复显示。 + // + // [2026-03-01] 构建 sourceOrderNo → sourceAccountSequence 映射, + // 用于在待领取条目中显示来源用户ID(wallet pending_rewards 表不含此字段, + // 但 pre-planting/my-rewards 的分配记录中有)。 + final pplSourceAccountMap = {}; + for (final r in prePlantingRewards.settleableRewards) { + if (r.sourceAccountSequence != null && r.sourceAccountSequence!.isNotEmpty) { + pplSourceAccountMap[r.sourceOrderNo] = r.sourceAccountSequence!; + } + } final prePlantingPending = walletPendingRewards .where((r) => r.isPrePlanting) - .map((r) => PendingRewardItem( + .map((r) { + final sourceAccount = pplSourceAccountMap[r.sourceOrderId]; + final typeName = getAllocationTypeName(r.allocationType); + final memo = sourceAccount != null + ? '[预种] $typeName:来自${sourceAccount}的预种' + : '[预种] $typeName'; + return PendingRewardItem( id: 'wp-${r.id}', rightType: r.allocationType, usdtAmount: r.usdtAmount, @@ -844,8 +866,10 @@ class _ProfilePageState extends ConsumerState { expireAt: r.expireAt, remainingTimeMs: r.expireAt.difference(DateTime.now()).inMilliseconds.clamp(0, 86400000), sourceOrderNo: r.sourceOrderId, - memo: '[预种] ${getAllocationTypeName(r.allocationType)}', - )) + sourceAccountSequence: sourceAccount, + memo: memo, + ); + }) .toList(); final mergedPendingRewards = [...pendingRewards, ...prePlantingPending]; debugPrint('[ProfilePage] 预种待领取奖励: ${prePlantingPending.length} 条');