From 573e58c89b5105a5d5f7d85aed66d51d6d7c2f36 Mon Sep 17 00:00:00 2001 From: hailin Date: Tue, 6 Jan 2026 03:49:31 -0800 Subject: [PATCH] =?UTF-8?q?fix(wallet-service):=20=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E5=A5=96=E5=8A=B1=E5=88=86=E9=85=8D=E5=88=B0=20settleable=5Fus?= =?UTF-8?q?dt=EF=BC=8C=E4=B8=8E=20reward-service=20=E4=BF=9D=E6=8C=81?= =?UTF-8?q?=E4=B8=80=E8=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题原因: wallet-service 对不同类型奖励的分配方式不一致: - SHARE_RIGHT: 正确使用 addSettleableReward() → settleable_usdt - CITY_TEAM_RIGHT/COMMUNITY_RIGHT: 错误使用 addAvailableBalance() → usdt_available 这导致 reward-service 记录的 SETTLEABLE 奖励总额与 wallet-service 的 settleable_usdt 字段不匹配。用户 D25122700024 的案例中: - reward-service: 3条奖励共 4464 USDT (SHARE_RIGHT 3600 + CITY_TEAM_RIGHT 288 + COMMUNITY_RIGHT 576) - wallet-service: settleable_usdt = 3600 (仅 SHARE_RIGHT) 差额 864 USDT 被错误地放入了 usdt_available 修复内容: 1. allocateCommunityRight: 改用 addSettleableReward() 替代 addAvailableBalance() 2. allocateToRegionAccount: 改用 addSettleableReward() 替代 addAvailableBalance() 3. 流水类型统一使用 REWARD_TO_SETTLEABLE 替代 SYSTEM_ALLOCATION 4. 日志和备注更新以反映新的分配方式 设计原则: - reward-service 是奖励的权威来源 - wallet-service 应跟随 reward-service 的设计 - 所有奖励都应进入 settleable_usdt,用户主动结算后才转入 usdt_available 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../services/wallet-application.service.ts | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) 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 795f0423..854d823c 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 @@ -1198,19 +1198,21 @@ export class WalletApplicationService { } const amount = Money.USDT(allocation.amount); - wallet.addAvailableBalance(amount); + // 所有奖励都应该进入可结算余额 (settleable_usdt),与 reward-service 保持一致 + // 用户需要主动点击"结算"才能将 settleable_usdt 转入 usdt_available + wallet.addSettleableReward(amount, Hashpower.create(0)); await this.walletRepo.save(wallet); - // 记录流水 + // 记录流水 - 使用 REWARD_TO_SETTLEABLE 类型,与 SHARE_RIGHT 保持一致 const ledgerEntry = LedgerEntry.create({ accountSequence: wallet.accountSequence, userId: wallet.userId, - entryType: LedgerEntryType.SYSTEM_ALLOCATION, + entryType: LedgerEntryType.REWARD_TO_SETTLEABLE, amount, refOrderId: orderId, memo: isUserAccount - ? `${allocation.allocationType} - community authorization allocation` - : `${allocation.allocationType} - headquarters community allocation`, + ? `${allocation.allocationType} - community authorization allocation (settleable)` + : `${allocation.allocationType} - headquarters community allocation (settleable)`, payloadJson: { allocationType: allocation.allocationType, metadata: allocation.metadata, @@ -1221,7 +1223,7 @@ export class WalletApplicationService { await this.walletCacheService.invalidateWallet(wallet.userId.value); this.logger.debug( - `Allocated ${allocation.amount} USDT to ${isUserAccount ? 'community user' : 'headquarters'} ${wallet.accountSequence} for ${allocation.allocationType}`, + `Allocated ${allocation.amount} USDT to ${isUserAccount ? 'community user' : 'headquarters'} ${wallet.accountSequence} for ${allocation.allocationType} (settleable)`, ); } @@ -1260,17 +1262,19 @@ export class WalletApplicationService { } const amount = Money.USDT(allocation.amount); - wallet.addAvailableBalance(amount); + // 所有奖励都应该进入可结算余额 (settleable_usdt),与 reward-service 保持一致 + // 用户需要主动点击"结算"才能将 settleable_usdt 转入 usdt_available + wallet.addSettleableReward(amount, Hashpower.create(0)); await this.walletRepo.save(wallet); - // 记录流水 + // 记录流水 - 使用 REWARD_TO_SETTLEABLE 类型,与 SHARE_RIGHT 保持一致 const ledgerEntry = LedgerEntry.create({ accountSequence: wallet.accountSequence, userId: wallet.userId, - entryType: LedgerEntryType.SYSTEM_ALLOCATION, + entryType: LedgerEntryType.REWARD_TO_SETTLEABLE, amount, refOrderId: orderId, - memo: `${allocation.allocationType} - region account allocation`, + memo: `${allocation.allocationType} - region account allocation (settleable)`, payloadJson: { allocationType: allocation.allocationType, metadata: allocation.metadata, @@ -1281,7 +1285,7 @@ export class WalletApplicationService { await this.walletCacheService.invalidateWallet(wallet.userId.value); this.logger.debug( - `Allocated ${allocation.amount} USDT to region account ${targetId} for ${allocation.allocationType} (direct)`, + `Allocated ${allocation.amount} USDT to region account ${targetId} for ${allocation.allocationType} (settleable)`, ); }