diff --git a/backend/services/wallet-service/src/application/services/wallet-application.service.ts b/backend/services/wallet-service/src/application/services/wallet-application.service.ts index b7d6e03f..a46b404e 100644 --- a/backend/services/wallet-service/src/application/services/wallet-application.service.ts +++ b/backend/services/wallet-service/src/application/services/wallet-application.service.ts @@ -2450,6 +2450,33 @@ export class WalletApplicationService { }); } + // 4. 为每笔 pending reward 创建 REWARD_TO_SETTLEABLE 流水(保留来源信息,供"分享收益"筛选) + // 注意:payloadJson.convertedFromPending = true 用于统计时排除(避免与 REWARD_PENDING 双重计算) + for (const reward of pendingRewards) { + if (reward.usdtAmount.value <= 0) continue; + // 查找原始 REWARD_PENDING 流水,获取来源信息 + const originalEntry = await tx.ledgerEntry.findFirst({ + where: { + accountSequence, + entryType: LedgerEntryType.REWARD_PENDING, + refOrderId: reward.sourceOrderId, + }, + }); + const originalPayload = (originalEntry?.payloadJson as Record) || {}; + await tx.ledgerEntry.create({ + data: { + accountSequence, + userId: walletRecord.userId, + entryType: LedgerEntryType.REWARD_TO_SETTLEABLE, + amount: reward.usdtAmount.value, + assetType: 'USDT', + refOrderId: reward.sourceOrderId, + memo: originalEntry?.memo?.replace('待领取', '可结算') || `[预种] ${reward.allocationType} | 可结算`, + payloadJson: { ...originalPayload, convertedFromPending: true }, + }, + }); + } + this.logger.log(`[settleUserPendingRewards] Transaction committed: ${pendingRewards.length} rewards settled for ${accountSequence}`); } else { this.logger.warn(`[settleUserPendingRewards] Wallet not found for ${accountSequence}, skipping wallet update`); @@ -2698,9 +2725,12 @@ export class WalletApplicationService { // 只计算非临时性流水的收支统计 // 兼容历史数据:老的批量转换记录 entry_type 仍为 REWARD_TO_SETTLEABLE, - // 通过 memo 中 "pending rewards settled" 识别并排除 + // 通过 memo 中 "pending rewards settled" 或 payloadJson.convertedFromPending 识别并排除 const isExcluded = excludeFromStats.has(entry.entryType) || - (entry.entryType === 'REWARD_TO_SETTLEABLE' && entry.memo?.includes('pending rewards settled')); + (entry.entryType === 'REWARD_TO_SETTLEABLE' && ( + entry.memo?.includes('pending rewards settled') || + (entry.payloadJson as Record)?.convertedFromPending === true + )); if (!isExcluded) { if (amount > 0) { totalIncome += amount; @@ -2797,7 +2827,10 @@ export class WalletApplicationService { // 只计算非临时性流水的收支统计(兼容历史批量转换数据) const isExcluded = excludeFromStats.has(entry.entryType) || - (entry.entryType === 'REWARD_TO_SETTLEABLE' && entry.memo?.includes('pending rewards settled')); + (entry.entryType === 'REWARD_TO_SETTLEABLE' && ( + entry.memo?.includes('pending rewards settled') || + (entry.payloadJson as Record)?.convertedFromPending === true + )); if (!isExcluded) { if (amount > 0) { existing.income += amount;