diff --git a/backend/services/planting-service/src/domain/aggregates/planting-order.aggregate.ts b/backend/services/planting-service/src/domain/aggregates/planting-order.aggregate.ts index ab7be781..b3868a44 100644 --- a/backend/services/planting-service/src/domain/aggregates/planting-order.aggregate.ts +++ b/backend/services/planting-service/src/domain/aggregates/planting-order.aggregate.ts @@ -262,9 +262,10 @@ export class PlantingOrder { /** * 安排底池注入 + * 注意:资金分配已移至 reward-service 异步处理,所以支付后即可安排底池注入 */ schedulePoolInjection(batchId: bigint, scheduledTime: Date): void { - this.ensureStatus(PlantingOrderStatus.FUND_ALLOCATED); + this.ensureStatus(PlantingOrderStatus.PAID); this._poolInjectionBatchId = batchId; this._poolInjectionScheduledTime = scheduledTime; diff --git a/backend/services/wallet-service/src/api/controllers/internal-wallet.controller.ts b/backend/services/wallet-service/src/api/controllers/internal-wallet.controller.ts index d6b53420..38803ebc 100644 --- a/backend/services/wallet-service/src/api/controllers/internal-wallet.controller.ts +++ b/backend/services/wallet-service/src/api/controllers/internal-wallet.controller.ts @@ -29,8 +29,14 @@ export class InternalWalletController { @ApiParam({ name: 'userId', description: '用户ID或accountSequence' }) @ApiResponse({ status: 200, description: '余额信息' }) async getBalance(@Param('userId') userId: string) { - // 优先使用 accountSequence,如果相同则使用 userId - const query = new GetMyWalletQuery(userId, userId); + // 判断是 accountSequence (以 D 开头) 还是 userId (纯数字) + const isAccountSequence = userId.startsWith('D'); + // 如果是 accountSequence,userId 参数设为 '0'(会被忽略,通过 accountSequence 查找) + // 如果是纯 userId,accountSequence 参数设为 userId(会通过 userId 查找) + const query = new GetMyWalletQuery( + isAccountSequence ? userId : userId, // accountSequence + isAccountSequence ? '0' : userId, // userId (如果是 accountSequence 则忽略) + ); const wallet = await this.walletService.getMyWallet(query); return { userId, 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 53d470f8..8e4dea76 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 @@ -196,7 +196,6 @@ export class WalletApplicationService { this.logger.log(`[freezeForPlanting] amount: ${command.amount}`); this.logger.log(`[freezeForPlanting] orderId: ${command.orderId}`); - const userId = BigInt(command.userId); const amount = Money.USDT(command.amount); this.logger.log(`[freezeForPlanting] 解析后 amount.value: ${amount.value}`); @@ -216,7 +215,11 @@ export class WalletApplicationService { // 优先按 accountSequence 查找,如果未找到则按 userId 查找 let wallet = await this.walletRepo.findByAccountSequence(command.userId); if (!wallet) { - wallet = await this.walletRepo.findByUserId(userId); + // 尝试将 userId 转换为 BigInt(如果不是 accountSequence 格式) + const isAccountSequence = command.userId.startsWith('D'); + if (!isAccountSequence) { + wallet = await this.walletRepo.findByUserId(BigInt(command.userId)); + } } if (!wallet) { this.logger.error(`[freezeForPlanting] 钱包不存在: userId/accountSequence=${command.userId}`); @@ -249,7 +252,7 @@ export class WalletApplicationService { // 记录冻结流水 const ledgerEntry = LedgerEntry.create({ accountSequence: wallet.accountSequence, - userId: UserId.create(userId), + userId: wallet.userId, entryType: LedgerEntryType.PLANT_FREEZE, amount: Money.signed(-command.amount, 'USDT'), // Negative: 可用余额减少 balanceAfter: wallet.balances.usdt.available, @@ -259,7 +262,7 @@ export class WalletApplicationService { await this.ledgerRepo.save(ledgerEntry); this.logger.log(`[freezeForPlanting] 流水已记录`); - await this.walletCacheService.invalidateWallet(userId); + await this.walletCacheService.invalidateWallet(wallet.userId.value); this.logger.log(`[freezeForPlanting] 成功冻结 ${command.amount} USDT for order ${command.orderId}`); return { success: true, frozenAmount: command.amount }; @@ -270,8 +273,6 @@ export class WalletApplicationService { * 幂等设计:如果订单已确认扣款,直接返回成功 */ async confirmPlantingDeduction(command: ConfirmPlantingDeductionCommand): Promise { - const userId = BigInt(command.userId); - // 查找冻结记录,获取冻结金额 const existingEntries = await this.ledgerRepo.findByRefOrderId(command.orderId); @@ -300,7 +301,11 @@ export class WalletApplicationService { // 优先按 accountSequence 查找,如果未找到则按 userId 查找 let wallet = await this.walletRepo.findByAccountSequence(command.userId); if (!wallet) { - wallet = await this.walletRepo.findByUserId(userId); + // 尝试将 userId 转换为 BigInt(如果不是 accountSequence 格式) + const isAccountSequence = command.userId.startsWith('D'); + if (!isAccountSequence) { + wallet = await this.walletRepo.findByUserId(BigInt(command.userId)); + } } if (!wallet) { throw new WalletNotFoundError(`userId/accountSequence: ${command.userId}`); @@ -313,7 +318,7 @@ export class WalletApplicationService { // 记录扣款流水 const ledgerEntry = LedgerEntry.create({ accountSequence: wallet.accountSequence, - userId: UserId.create(userId), + userId: wallet.userId, entryType: LedgerEntryType.PLANT_PAYMENT, amount: Money.signed(-frozenAmount.value, 'USDT'), balanceAfter: wallet.balances.usdt.available, @@ -322,7 +327,7 @@ export class WalletApplicationService { }); await this.ledgerRepo.save(ledgerEntry); - await this.walletCacheService.invalidateWallet(userId); + await this.walletCacheService.invalidateWallet(wallet.userId.value); this.logger.log(`Confirmed deduction ${frozenAmount.value} USDT for order ${command.orderId}`); return true; @@ -333,8 +338,6 @@ export class WalletApplicationService { * 幂等设计:如果订单已解冻或未冻结,直接返回成功 */ async unfreezeForPlanting(command: UnfreezeForPlantingCommand): Promise { - const userId = BigInt(command.userId); - // 查找相关流水 const existingEntries = await this.ledgerRepo.findByRefOrderId(command.orderId); @@ -378,7 +381,11 @@ export class WalletApplicationService { // 优先按 accountSequence 查找,如果未找到则按 userId 查找 let wallet = await this.walletRepo.findByAccountSequence(command.userId); if (!wallet) { - wallet = await this.walletRepo.findByUserId(userId); + // 尝试将 userId 转换为 BigInt(如果不是 accountSequence 格式) + const isAccountSequence = command.userId.startsWith('D'); + if (!isAccountSequence) { + wallet = await this.walletRepo.findByUserId(BigInt(command.userId)); + } } if (!wallet) { throw new WalletNotFoundError(`userId/accountSequence: ${command.userId}`); @@ -391,7 +398,7 @@ export class WalletApplicationService { // 记录解冻流水 const ledgerEntry = LedgerEntry.create({ accountSequence: wallet.accountSequence, - userId: UserId.create(userId), + userId: wallet.userId, entryType: LedgerEntryType.PLANT_UNFREEZE, amount: frozenAmount, // Positive: 可用余额增加 balanceAfter: wallet.balances.usdt.available, @@ -400,7 +407,7 @@ export class WalletApplicationService { }); await this.ledgerRepo.save(ledgerEntry); - await this.walletCacheService.invalidateWallet(userId); + await this.walletCacheService.invalidateWallet(wallet.userId.value); this.logger.log(`Unfrozen ${frozenAmount.value} USDT for order ${command.orderId}`); return true; @@ -915,23 +922,28 @@ export class WalletApplicationService { async getMyWallet(query: GetMyWalletQuery): Promise { const accountSequence = query.accountSequence; - const userId = BigInt(query.userId); + // userId 可能是 '0' (当仅通过 accountSequence 查询时),此时跳过缓存和 BigInt 转换 + const userIdStr = query.userId; + const hasValidUserId = userIdStr && userIdStr !== '0' && !userIdStr.startsWith('D'); + const userId = hasValidUserId ? BigInt(userIdStr) : BigInt(0); - // Try to get from cache first - const cached = await this.walletCacheService.getWallet(userId); - if (cached) { - this.logger.debug(`Returning cached wallet for user: ${userId}`); - return { - walletId: cached.walletId, - userId: cached.userId, - balances: cached.balances, - hashpower: cached.hashpower, - rewards: cached.rewards, - status: cached.status, - }; + // Try to get from cache first (only if we have a valid userId) + if (hasValidUserId) { + const cached = await this.walletCacheService.getWallet(userId); + if (cached) { + this.logger.debug(`Returning cached wallet for user: ${userId}`); + return { + walletId: cached.walletId, + userId: cached.userId, + balances: cached.balances, + hashpower: cached.hashpower, + rewards: cached.rewards, + status: cached.status, + }; + } } - // Cache miss - fetch from database (by accountSequence) + // Cache miss or no valid userId - fetch from database (by accountSequence) const wallet = await this.walletRepo.getOrCreate(accountSequence, userId); const walletDTO: WalletDTO = {