rwadurian/backend/services/wallet-service/src/api/controllers/internal-transfer-wallet.co...

118 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 转让钱包内部 API纯新增
* 供 transfer-service Saga 编排器通过 HTTP 调用
*
* 路由前缀:/api/v1/internal/wallet/*
* 与 InternalWalletController(/api/v1/wallets/*) 分开,避免路由冲突
*
* 回滚方式:删除此文件并从 api.module.ts 中移除引用
*/
import { Controller, Post, Get, Body, Param, Logger } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { WalletApplicationService } from '@/application/services';
import {
FreezeForTransferCommand,
UnfreezeForTransferCommand,
SettleTransferPaymentCommand,
} from '@/application/commands';
import { Public } from '@/shared/decorators';
import {
FreezeForTransferDto,
UnfreezeForTransferDto,
SettleTransferDto,
} from '../dto/request/transfer-wallet.dto';
@ApiTags('Internal Transfer Wallet API')
@Controller('internal/wallet')
export class InternalTransferWalletController {
private readonly logger = new Logger(InternalTransferWalletController.name);
constructor(
private readonly walletService: WalletApplicationService,
) {}
/**
* 冻结买方资金
* POST /api/v1/internal/wallet/freeze
*/
@Post('freeze')
@Public()
async freezeForTransfer(@Body() dto: FreezeForTransferDto): Promise<{ freezeId: string }> {
this.logger.log(`[freeze] Request: accountSequence=${dto.accountSequence}, amount=${dto.amount}, transferOrderNo=${dto.transferOrderNo}`);
const command = new FreezeForTransferCommand(
dto.accountSequence,
dto.amount,
dto.transferOrderNo,
dto.reason,
);
const result = await this.walletService.freezeForTransfer(command);
this.logger.log(`[freeze] Success: freezeId=${result.freezeId}`);
return result;
}
/**
* 解冻买方资金(补偿/回滚)
* POST /api/v1/internal/wallet/unfreeze
*/
@Post('unfreeze')
@Public()
async unfreezeForTransfer(@Body() dto: UnfreezeForTransferDto): Promise<{ success: boolean }> {
this.logger.log(`[unfreeze] Request: accountSequence=${dto.accountSequence}, freezeId=${dto.freezeId}, transferOrderNo=${dto.transferOrderNo}`);
const command = new UnfreezeForTransferCommand(
dto.accountSequence,
dto.freezeId,
dto.transferOrderNo,
dto.reason,
);
await this.walletService.unfreezeForTransfer(command);
this.logger.log(`[unfreeze] Success: transferOrderNo=${dto.transferOrderNo}`);
return { success: true };
}
/**
* 结算转让资金:买方冻结扣减 → 卖方入账 → 手续费归集
* POST /api/v1/internal/wallet/settle-transfer
*/
@Post('settle-transfer')
@Public()
async settleTransfer(@Body() dto: SettleTransferDto): Promise<{ success: boolean }> {
this.logger.log(`[settle-transfer] Request: buyer=${dto.buyerAccountSequence}, seller=${dto.sellerAccountSequence}, transferOrderNo=${dto.transferOrderNo}`);
const command = new SettleTransferPaymentCommand(
dto.buyerAccountSequence,
dto.sellerAccountSequence,
dto.freezeId,
dto.sellerReceiveAmount,
dto.platformFeeAmount,
dto.transferOrderNo,
);
await this.walletService.settleTransferPayment(command);
this.logger.log(`[settle-transfer] Success: transferOrderNo=${dto.transferOrderNo}`);
return { success: true };
}
/**
* 查询钱包余额
* GET /api/v1/internal/wallet/balance/:accountSequence
*/
@Get('balance/:accountSequence')
@Public()
async getBalance(@Param('accountSequence') accountSequence: string): Promise<{
available: string;
frozen: string;
}> {
const query = { userId: accountSequence } as any;
const wallet = await this.walletService.getMyWallet(query);
return {
available: wallet.balances.usdt.available.toString(),
frozen: wallet.balances.usdt.frozen.toString(),
};
}
}