From 24a46521f39033fa73819ceade1b7803f03c4ef7 Mon Sep 17 00:00:00 2001 From: hailin Date: Fri, 26 Dec 2025 01:48:22 -0800 Subject: [PATCH] =?UTF-8?q?fix(planting-service):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=B7=A8=E6=9C=8D=E5=8A=A1=E8=B0=83=E7=94=A8=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E6=A0=87=E8=AF=86=E7=AC=A6=E5=AF=BC=E8=87=B4?= =?UTF-8?q?=E7=9A=84500=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题根源: - getBalance 调用使用 userId.toString() (纯数字如 "14") - wallet-service 按 accountSequence 查找钱包失败后尝试创建新钱包 - 但 userId 已存在,触发唯一约束冲突导致500错误 修复内容: 1. planting-application.service.ts: - createOrder: getBalance(userId.toString()) → getBalance(accountSequence) - payOrder: getBalance(userId.toString()) → getBalance(walletIdentifier) 2. payment-compensation.service.ts: - 注入 IPlantingOrderRepository 获取订单的 accountSequence - handleUnfreeze/handleRetryConfirm 添加 accountSequence 参数 3. wallet-service.client.ts: - ensureRegionAccounts 接口添加 provinceTeamAccount/cityTeamAccount 字段 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../services/payment-compensation.service.ts | 20 ++++++++++++++++++- .../services/planting-application.service.ts | 9 +++++---- .../external/wallet-service.client.ts | 6 ++++++ 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/backend/services/planting-service/src/application/services/payment-compensation.service.ts b/backend/services/planting-service/src/application/services/payment-compensation.service.ts index 7c90d8b7..1448686a 100644 --- a/backend/services/planting-service/src/application/services/payment-compensation.service.ts +++ b/backend/services/planting-service/src/application/services/payment-compensation.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Logger, OnModuleInit } from '@nestjs/common'; +import { Injectable, Logger, OnModuleInit, Inject } from '@nestjs/common'; import { PaymentCompensationRepository, PaymentCompensationRecord, @@ -7,6 +7,7 @@ import { FailureStage, } from '../../infrastructure/persistence/repositories/payment-compensation.repository'; import { WalletServiceClient } from '../../infrastructure/external/wallet-service.client'; +import { IPlantingOrderRepository, PLANTING_ORDER_REPOSITORY } from '../../domain/repositories/planting-order.repository'; /** * 支付补偿服务 @@ -30,6 +31,8 @@ export class PaymentCompensationService implements OnModuleInit { constructor( private readonly compensationRepo: PaymentCompensationRepository, private readonly walletService: WalletServiceClient, + @Inject(PLANTING_ORDER_REPOSITORY) + private readonly orderRepository: IPlantingOrderRepository, ) {} onModuleInit() { @@ -137,12 +140,25 @@ export class PaymentCompensationService implements OnModuleInit { } } + /** + * 从订单获取 accountSequence + */ + private async getAccountSequence(orderNo: string): Promise { + const order = await this.orderRepository.findByOrderNo(orderNo); + if (!order) { + throw new Error(`Order ${orderNo} not found`); + } + return order.accountSequence; + } + /** * 处理解冻补偿 */ private async handleUnfreeze(record: PaymentCompensationRecord): Promise { + const accountSequence = await this.getAccountSequence(record.orderNo); await this.walletService.unfreezeForPlanting({ userId: record.userId.toString(), + accountSequence, orderId: record.orderNo, }); this.logger.log(`Unfroze funds for order ${record.orderNo}`); @@ -152,8 +168,10 @@ export class PaymentCompensationService implements OnModuleInit { * 处理重试确认扣款 */ private async handleRetryConfirm(record: PaymentCompensationRecord): Promise { + const accountSequence = await this.getAccountSequence(record.orderNo); await this.walletService.confirmPlantingDeduction({ userId: record.userId.toString(), + accountSequence, orderId: record.orderNo, }); this.logger.log(`Confirmed deduction for order ${record.orderNo}`); diff --git a/backend/services/planting-service/src/application/services/planting-application.service.ts b/backend/services/planting-service/src/application/services/planting-application.service.ts index 67318357..c8ad2762 100644 --- a/backend/services/planting-service/src/application/services/planting-application.service.ts +++ b/backend/services/planting-service/src/application/services/planting-application.service.ts @@ -82,8 +82,8 @@ export class PlantingApplicationService { ): Promise { this.logger.log(`Creating order for user ${accountSequence}, treeCount: ${treeCount}`); - // 检查余额 - const balance = await this.walletService.getBalance(userId.toString()); + // 检查余额 - 使用 accountSequence 进行跨服务调用 + const balance = await this.walletService.getBalance(accountSequence); const requiredAmount = treeCount * PRICE_PER_TREE; if (balance.available < requiredAmount) { throw new Error( @@ -219,8 +219,9 @@ export class PlantingApplicationService { throw new Error('请先选择并确认省市'); } - // 2. 验证钱包余额 (先检查,不扣款) - const balance = await this.walletService.getBalance(userId.toString()); + // 2. 验证钱包余额 (先检查,不扣款) - 使用 accountSequence 进行跨服务调用 + const walletIdentifier = accountSequence || order.accountSequence; + const balance = await this.walletService.getBalance(walletIdentifier); if (balance.available < order.totalAmount) { throw new Error( `余额不足: 需要 ${order.totalAmount} USDT, 当前可用 ${balance.available} USDT`, diff --git a/backend/services/planting-service/src/infrastructure/external/wallet-service.client.ts b/backend/services/planting-service/src/infrastructure/external/wallet-service.client.ts index ed24f882..b62832a2 100644 --- a/backend/services/planting-service/src/infrastructure/external/wallet-service.client.ts +++ b/backend/services/planting-service/src/infrastructure/external/wallet-service.client.ts @@ -399,6 +399,8 @@ export class WalletServiceClient { }): Promise<{ provinceAccount: { accountSequence: string; created: boolean }; cityAccount: { accountSequence: string; created: boolean }; + provinceTeamAccount: { accountSequence: string; created: boolean }; + cityTeamAccount: { accountSequence: string; created: boolean }; }> { try { return await this.withRetry( @@ -408,6 +410,8 @@ export class WalletServiceClient { this.httpService.post<{ provinceAccount: { accountSequence: string; created: boolean }; cityAccount: { accountSequence: string; created: boolean }; + provinceTeamAccount: { accountSequence: string; created: boolean }; + cityTeamAccount: { accountSequence: string; created: boolean }; }>( `${this.baseUrl}/api/v1/wallets/ensure-region-accounts`, params, @@ -427,6 +431,8 @@ export class WalletServiceClient { return { provinceAccount: { accountSequence: `9${params.provinceCode}`, created: true }, cityAccount: { accountSequence: `8${params.cityCode}`, created: true }, + provinceTeamAccount: { accountSequence: `7${params.provinceCode}`, created: true }, + cityTeamAccount: { accountSequence: `6${params.cityCode}`, created: true }, }; } throw error;