fix(wallet): 统一使用 accountSequence 查询钱包,修复转账余额不足问题
背景:幽灵钱包 D26010800000 (user_id=133, 余额=0) 导致真实用户 D26010900000 (user_id=0, 余额=200465) 转账失败 原因: - D26010800000 是 2026-01-08 16:23 通过未知方式创建的脏数据 - 真实用户 D26010900000 在 18:40 注册时,user_id=133 已被占用 - getMyWallet 用 accountSequence 查询显示余额正确 - requestWithdrawal 用 userId 查询找到错误的空钱包 修复: - Controller: 传 user.accountSequence 而非 user.userId - Service: 移除 findByUserId fallback,仅用 findByAccountSequence - 从钱包记录获取 userId 用于订单、流水、事件关联 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
974d660544
commit
88368d1705
|
|
@ -117,8 +117,14 @@ export class WalletController {
|
|||
actualAddress = resolvedAddress;
|
||||
}
|
||||
|
||||
// [2026-01-16] 使用 accountSequence 而非 userId 查找钱包
|
||||
// 背景:发现幽灵钱包 D26010800000 (user_id=133, 余额=0) 导致真实用户 D26010900000 (user_id=0, 余额=200465) 转账失败
|
||||
// 原因:D26010800000 是 2026-01-08 16:23 通过未知方式创建的脏数据,占用了 user_id=133
|
||||
// 而真实用户 D26010900000 在 2026-01-08 18:40 注册时,因 user_id=133 已被占用,其钱包 user_id 被设为 0
|
||||
// 问题:getMyWallet 用 accountSequence 查询显示余额正确,但 requestWithdrawal 用 userId 查询找到错误的空钱包
|
||||
// 修复:统一使用 accountSequence 作为钱包查询的唯一标识
|
||||
const command = new RequestWithdrawalCommand(
|
||||
user.userId,
|
||||
user.accountSequence,
|
||||
dto.amount,
|
||||
actualAddress,
|
||||
dto.chainType,
|
||||
|
|
|
|||
|
|
@ -1512,7 +1512,6 @@ export class WalletApplicationService {
|
|||
netAmount: number;
|
||||
status: string;
|
||||
}> {
|
||||
const userId = BigInt(command.userId);
|
||||
const amount = Money.USDT(command.amount);
|
||||
|
||||
// 从配置获取动态手续费
|
||||
|
|
@ -1524,8 +1523,6 @@ export class WalletApplicationService {
|
|||
? `固定 ${feeValue} 绿积分`
|
||||
: `${(feeValue * 100).toFixed(2)}%`;
|
||||
|
||||
this.logger.log(`Processing withdrawal request for user ${userId}: ${command.amount} USDT to ${command.toAddress}, fee: ${feeAmount} (${feeDescription})`);
|
||||
|
||||
// 验证最小提现金额
|
||||
if (command.amount < this.MIN_WITHDRAWAL_AMOUNT) {
|
||||
throw new Error(`最小提现金额为 ${this.MIN_WITHDRAWAL_AMOUNT} USDT`);
|
||||
|
|
@ -1541,15 +1538,20 @@ export class WalletApplicationService {
|
|||
throw new BadRequestException(hotWalletCheck.error || '财务系统审计中,请稍后再试');
|
||||
}
|
||||
|
||||
// 优先按 accountSequence 查找,如果未找到则按 userId 查找
|
||||
let wallet = await this.walletRepo.findByAccountSequence(command.userId);
|
||||
// [2026-01-16] 仅按 accountSequence 查找钱包,不再 fallback 到 userId
|
||||
// 背景:幽灵钱包 D26010800000 (user_id=133) 与真实用户 D26010900000 (user_id=0) 的 userId 冲突
|
||||
// 导致按 userId 查询时找到错误的空钱包,用户转账报"余额不足"
|
||||
// 修复:command.userId 实际传入的是 accountSequence,直接按 accountSequence 查询
|
||||
const wallet = await this.walletRepo.findByAccountSequence(command.userId);
|
||||
if (!wallet) {
|
||||
wallet = await this.walletRepo.findByUserId(userId);
|
||||
}
|
||||
if (!wallet) {
|
||||
throw new WalletNotFoundError(`userId/accountSequence: ${command.userId}`);
|
||||
throw new WalletNotFoundError(`accountSequence: ${command.userId}`);
|
||||
}
|
||||
|
||||
// 从钱包记录获取 userId(用于订单、流水、事件等关联)
|
||||
const userId = wallet.userId.value;
|
||||
|
||||
this.logger.log(`Processing withdrawal request for user ${userId} (${command.userId}): ${command.amount} USDT to ${command.toAddress}, fee: ${feeAmount} (${feeDescription})`);
|
||||
|
||||
// 验证余额是否足够
|
||||
if (wallet.balances.usdt.available.lessThan(totalRequired)) {
|
||||
throw new BadRequestException(
|
||||
|
|
|
|||
Loading…
Reference in New Issue