import { Injectable, Logger } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; export interface ConfirmPlantingDeductionRequest { userId: string; accountSequence?: string; orderId: string; } export interface ConfirmPlantingDeductionResult { success: boolean; error?: string; } @Injectable() export class WalletServiceClient { private readonly logger = new Logger(WalletServiceClient.name); private readonly baseUrl: string; constructor(private readonly configService: ConfigService) { this.baseUrl = this.configService.get('WALLET_SERVICE_URL') || 'http://localhost:3002'; } /** * 确认认种扣款 * 将冻结的资金正式扣除,资金进入"待分配"状态 * * 由 referral-service 在发送 planting.order.paid 事件前调用 */ async confirmPlantingDeduction( request: ConfirmPlantingDeductionRequest, ): Promise { const maxRetries = 3; let lastError: Error | null = null; for (let attempt = 1; attempt <= maxRetries; attempt++) { try { this.logger.log( `Confirming planting deduction for order ${request.orderId} (attempt ${attempt}/${maxRetries})`, ); const response = await fetch( `${this.baseUrl}/api/v1/wallets/confirm-planting-deduction`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(request), }, ); if (!response.ok) { const errorData = await response.json().catch(() => ({})); this.logger.error( `Failed to confirm deduction for order ${request.orderId}:`, errorData, ); return { success: false, error: errorData.message || `Confirm deduction failed with status ${response.status}`, }; } this.logger.log( `Successfully confirmed deduction for order ${request.orderId}`, ); return { success: true }; } catch (error) { lastError = error instanceof Error ? error : new Error(String(error)); this.logger.warn( `Failed to confirm planting deduction (attempt ${attempt}/${maxRetries}): ${lastError.message}`, ); if (attempt < maxRetries) { await this.sleep(1000 * attempt); } } } // 在开发环境模拟成功 if (this.configService.get('NODE_ENV') === 'development') { this.logger.warn( 'Development mode: simulating successful deduction confirmation', ); return { success: true }; } return { success: false, error: `Failed to confirm deduction after ${maxRetries} attempts: ${lastError?.message}`, }; } private sleep(ms: number): Promise { return new Promise((resolve) => setTimeout(resolve, ms)); } }