From 8e52535dd95046506e692f76c4ef3d6a01d51ca4 Mon Sep 17 00:00:00 2001 From: hailin Date: Sun, 1 Mar 2026 09:48:34 -0800 Subject: [PATCH] =?UTF-8?q?feat(mobile):=20=E9=A2=84=E7=A7=8D=E6=98=8E?= =?UTF-8?q?=E7=BB=86=E6=98=BE=E7=A4=BA=E6=9D=A5=E6=BA=90=E7=94=A8=E6=88=B7?= =?UTF-8?q?ID=20+=20=E4=BF=AE=E5=A4=8D=E7=A9=BA=E5=BE=85=E9=A2=86=E5=8F=96?= =?UTF-8?q?=E5=80=92=E8=AE=A1=E6=97=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 预种待领取/可结算明细的 memo 中追加来源用户(如"来自D26022600016的预种") 2. 修复 pendingUsdt=0 时倒计时仍然显示的问题(pending_expire_at 未清除时兜底) Co-Authored-By: Claude Opus 4.6 --- .../lib/core/services/wallet_service.dart | 2 ++ .../presentation/pages/profile_page.dart | 36 +++++++++++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) 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} 条');