fix(wallet): settleUserPendingRewards 补创建 REWARD_TO_SETTLEABLE 流水

转换 PENDING→SETTLEABLE 时,为每笔奖励创建带来源信息的
REWARD_TO_SETTLEABLE 流水,解决"分享收益"筛选缺失问题。
统计排除逻辑同步更新,通过 convertedFromPending 标记避免双重计算。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-03-01 11:15:19 -08:00
parent fda79304c6
commit 28cf0b7769
1 changed files with 36 additions and 3 deletions

View File

@ -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<string, unknown>) || {};
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<string, unknown>)?.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<string, unknown>)?.convertedFromPending === true
));
if (!isExcluded) {
if (amount > 0) {
existing.income += amount;