import { Controller, Get, Post, Param, Query, Body, NotFoundException, Req } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiQuery, ApiBearerAuth } from '@nestjs/swagger'; import { OrderService } from '../../application/services/order.service'; import { OrderRepository } from '../../infrastructure/persistence/repositories/order.repository'; import { TradingAccountRepository } from '../../infrastructure/persistence/repositories/trading-account.repository'; import { OrderType } from '../../domain/aggregates/order.aggregate'; class CreateOrderDto { type: 'BUY' | 'SELL'; price: string; quantity: string; } @ApiTags('Trading') @ApiBearerAuth() @Controller('trading') export class TradingController { constructor( private readonly orderService: OrderService, private readonly orderRepository: OrderRepository, private readonly accountRepository: TradingAccountRepository, ) {} @Get('accounts/:accountSequence') @ApiOperation({ summary: '获取交易账户信息' }) @ApiParam({ name: 'accountSequence', description: '账户序号' }) async getAccount(@Param('accountSequence') accountSequence: string) { const account = await this.accountRepository.findByAccountSequence(accountSequence); if (!account) { throw new NotFoundException('Account not found'); } return { accountSequence: account.accountSequence, shareBalance: account.shareBalance.toString(), cashBalance: account.cashBalance.toString(), availableShares: account.availableShares.toString(), availableCash: account.availableCash.toString(), frozenShares: account.frozenShares.toString(), frozenCash: account.frozenCash.toString(), totalBought: account.totalBought.toString(), totalSold: account.totalSold.toString(), }; } @Get('orderbook') @ApiOperation({ summary: '获取订单簿' }) @ApiQuery({ name: 'limit', required: false, type: Number }) async getOrderBook(@Query('limit') limit?: number) { return this.orderRepository.getOrderBook(limit ?? 20); } @Post('orders') @ApiOperation({ summary: '创建订单' }) async createOrder(@Body() dto: CreateOrderDto, @Req() req: any) { const accountSequence = req.user?.accountSequence; if (!accountSequence) { throw new Error('Unauthorized'); } return this.orderService.createOrder( accountSequence, dto.type === 'BUY' ? OrderType.BUY : OrderType.SELL, dto.price, dto.quantity, ); } @Post('orders/:orderNo/cancel') @ApiOperation({ summary: '取消订单' }) @ApiParam({ name: 'orderNo', description: '订单号' }) async cancelOrder(@Param('orderNo') orderNo: string, @Req() req: any) { const accountSequence = req.user?.accountSequence; if (!accountSequence) { throw new Error('Unauthorized'); } await this.orderService.cancelOrder(accountSequence, orderNo); return { success: true }; } @Get('orders') @ApiOperation({ summary: '获取用户订单列表' }) @ApiQuery({ name: 'page', required: false, type: Number }) @ApiQuery({ name: 'pageSize', required: false, type: Number }) async getOrders( @Req() req: any, @Query('page') page?: number, @Query('pageSize') pageSize?: number, ) { const accountSequence = req.user?.accountSequence; if (!accountSequence) { throw new Error('Unauthorized'); } const result = await this.orderRepository.findByAccountSequence(accountSequence, { page: page ?? 1, pageSize: pageSize ?? 50, }); return { data: result.data.map((o) => ({ id: o.id, orderNo: o.orderNo, type: o.type, status: o.status, price: o.price.toString(), quantity: o.quantity.toString(), filledQuantity: o.filledQuantity.toString(), remainingQuantity: o.remainingQuantity.toString(), averagePrice: o.averagePrice.toString(), totalAmount: o.totalAmount.toString(), createdAt: o.createdAt, completedAt: o.completedAt, cancelledAt: o.cancelledAt, })), total: result.total, }; } }