From e4389a57331f6f30c1674e585841ccedff28563a Mon Sep 17 00:00:00 2001 From: hailin Date: Sat, 13 Dec 2025 04:51:34 -0800 Subject: [PATCH] =?UTF-8?q?fix(wallet-service):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=B5=84=E9=87=91=E5=88=86=E9=85=8D=E9=80=BB=E8=BE=91=20-=20?= =?UTF-8?q?=E5=8C=BA=E5=88=86=E7=9B=B4=E6=8E=A5=E5=88=B0=E8=B4=A6=E5=92=8C?= =?UTF-8?q?=E5=BE=85=E9=A2=86=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - SHARE_RIGHT (分享权益): 写入 pending_rewards 表,24小时待领取 - PROVINCE_TEAM_RIGHT/PROVINCE_AREA_RIGHT/CITY_TEAM_RIGHT/CITY_AREA_RIGHT: 直接到账 - COMMUNITY_RIGHT (社区权益): 进入总部社区账户 S0000000001,直接到账 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../services/wallet-application.service.ts | 142 ++++++++++++++---- 1 file changed, 115 insertions(+), 27 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 57ae2961..2b9b5958 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 @@ -619,41 +619,40 @@ export class WalletApplicationService { * 分配资金到用户钱包 * 支持用户账户 (D+日期+序号) 和系统账户 (S+序号, 7+省代码, 6+市代码, 9+省代码, 8+市代码) * - * 新方案:使用 pending_rewards 表逐笔追踪待领取奖励 + * 分配规则: + * - SHARE_RIGHT (分享权益): 写入 pending_rewards 表,24小时待领取 + * - PROVINCE_TEAM_RIGHT, PROVINCE_AREA_RIGHT, CITY_TEAM_RIGHT, CITY_AREA_RIGHT: 直接到账 + * - COMMUNITY_RIGHT (社区权益): 进入总部社区账户 S0000000001,直接到账 */ private async allocateToUserWallet( allocation: FundAllocationItem, orderId: string, ): Promise { - // targetId 是 accountSequence - // - 用户账户: D2512120001 - // - 固定系统账户: S0000000001 (userId: -1 to -100, 由migration seed创建) - // - 省团队账户: 7440000 (7 + provinceCode, userId = 7440000) - // - 市团队账户: 6440100 (6 + cityCode, userId = 6440100) - // - 省区域账户: 9440000 (9 + provinceCode, userId = 9440000) - // - 市区域账户: 8440100 (8 + cityCode, userId = 8440100) + const amount = Money.USDT(allocation.amount); + const allocationType = allocation.allocationType; - // 为系统账户生成 userId (用于数据库约束) - let systemUserId = BigInt(0); - const targetId = allocation.targetId; - if (targetId.startsWith('9') || targetId.startsWith('8') || targetId.startsWith('7') || targetId.startsWith('6')) { - // 区域/团队账户: 9440000, 8440100, 7440000, 6440100 -> userId = accountSequence - systemUserId = BigInt(targetId); - } else if (targetId.startsWith('S')) { - // 固定系统账户: S0000000001 -> userId = -1 (负数,由seed创建,直接查找) - const numPart = targetId.slice(1); - systemUserId = BigInt(-parseInt(numPart, 10)); - } - - // 使用 getOrCreate 自动创建不存在的账户(仅用于区域/团队账户的动态创建) - // 固定系统账户(S开头)应该已由migration seed创建 - const wallet = await this.walletRepo.getOrCreate(targetId, systemUserId); - if (!wallet) { - this.logger.warn(`Failed to get or create wallet for accountSequence ${allocation.targetId}`); + // 社区权益直接进入总部社区账户 S0000000001 + if (allocationType === 'COMMUNITY_RIGHT') { + await this.allocateToHeadquartersCommunity(allocation, orderId); return; } - const amount = Money.USDT(allocation.amount); + // 省市团队/区域权益直接到账 + if (['PROVINCE_TEAM_RIGHT', 'PROVINCE_AREA_RIGHT', 'CITY_TEAM_RIGHT', 'CITY_AREA_RIGHT'].includes(allocationType)) { + await this.allocateToRegionAccount(allocation, orderId); + return; + } + + // 分享权益 (SHARE_RIGHT) - 写入 pending_rewards 表待领取 + // targetId 是 accountSequence (用户账户: D2512120001) + const targetId = allocation.targetId; + + // 用户账户 D 开头,userId 从 targetId 解析不出来,需要查询 + const wallet = await this.walletRepo.findByAccountSequence(targetId); + if (!wallet) { + this.logger.warn(`Failed to find wallet for accountSequence ${targetId}`); + return; + } // 添加待领取奖励(24小时后过期)- 写入 pending_rewards 表 const expireAt = new Date(Date.now() + 24 * 60 * 60 * 1000); @@ -688,7 +687,96 @@ export class WalletApplicationService { await this.walletCacheService.invalidateWallet(wallet.userId.value); this.logger.debug( - `Allocated ${allocation.amount} USDT to user ${allocation.targetId} for ${allocation.allocationType}`, + `Allocated ${allocation.amount} USDT to user ${allocation.targetId} for ${allocation.allocationType} (pending)`, + ); + } + + /** + * 社区权益直接进入总部社区账户 S0000000001 + */ + private async allocateToHeadquartersCommunity( + allocation: FundAllocationItem, + orderId: string, + ): Promise { + const headquartersAccountSequence = 'S0000000001'; + const wallet = await this.walletRepo.findByAccountSequence(headquartersAccountSequence); + if (!wallet) { + this.logger.error(`Headquarters community account not found: ${headquartersAccountSequence}`); + return; + } + + const amount = Money.USDT(allocation.amount); + wallet.addAvailableBalance(amount); + await this.walletRepo.save(wallet); + + // 记录流水 + const ledgerEntry = LedgerEntry.create({ + accountSequence: wallet.accountSequence, + userId: wallet.userId, + entryType: LedgerEntryType.SYSTEM_ALLOCATION, + amount, + refOrderId: orderId, + memo: `${allocation.allocationType} - headquarters community allocation`, + payloadJson: { + allocationType: allocation.allocationType, + metadata: allocation.metadata, + }, + }); + await this.ledgerRepo.save(ledgerEntry); + + await this.walletCacheService.invalidateWallet(wallet.userId.value); + + this.logger.debug( + `Allocated ${allocation.amount} USDT to headquarters community ${headquartersAccountSequence} for ${allocation.allocationType}`, + ); + } + + /** + * 省市团队/区域权益直接到账 + * - 省团队账户: 7+provinceCode (e.g., 7440000) + * - 市团队账户: 6+cityCode (e.g., 6440100) + * - 省区域账户: 9+provinceCode (e.g., 9440000) + * - 市区域账户: 8+cityCode (e.g., 8440100) + */ + private async allocateToRegionAccount( + allocation: FundAllocationItem, + orderId: string, + ): Promise { + const targetId = allocation.targetId; + + // 生成 userId (用于数据库约束) - userId = accountSequence 数值 + const systemUserId = BigInt(targetId); + + // 使用 getOrCreate 自动创建不存在的账户 + const wallet = await this.walletRepo.getOrCreate(targetId, systemUserId); + if (!wallet) { + this.logger.warn(`Failed to get or create wallet for region account ${targetId}`); + return; + } + + const amount = Money.USDT(allocation.amount); + wallet.addAvailableBalance(amount); + await this.walletRepo.save(wallet); + + // 记录流水 + const ledgerEntry = LedgerEntry.create({ + accountSequence: wallet.accountSequence, + userId: wallet.userId, + entryType: LedgerEntryType.SYSTEM_ALLOCATION, + amount, + refOrderId: orderId, + memo: `${allocation.allocationType} - region account allocation`, + payloadJson: { + allocationType: allocation.allocationType, + metadata: allocation.metadata, + }, + }); + await this.ledgerRepo.save(ledgerEntry); + + await this.walletCacheService.invalidateWallet(wallet.userId.value); + + this.logger.debug( + `Allocated ${allocation.amount} USDT to region account ${targetId} for ${allocation.allocationType} (direct)`, ); }