import { Controller, Get, Post, Query, Body, Param, NotFoundException } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiResponse, ApiParam } from '@nestjs/swagger'; import { SnapshotService } from '../../application/services/snapshot.service'; import { DailySnapshotResponse, UserContributionRatioResponse, BatchUserRatiosResponse, } from '../dto/response/snapshot.response'; import { CreateSnapshotRequest, GetBatchRatiosRequest } from '../dto/request/snapshot.request'; import { Public } from '../../shared/guards/jwt-auth.guard'; @ApiTags('Snapshot') @Controller('snapshots') export class SnapshotController { constructor(private readonly snapshotService: SnapshotService) {} @Post() @ApiOperation({ summary: '创建每日快照' }) @ApiResponse({ status: 201, type: DailySnapshotResponse }) async createSnapshot(@Body() request: CreateSnapshotRequest): Promise { const snapshot = await this.snapshotService.createDailySnapshot(new Date(request.snapshotDate)); return this.toResponse(snapshot); } @Get('latest') @ApiOperation({ summary: '获取最新快照' }) @ApiResponse({ status: 200, type: DailySnapshotResponse }) @ApiResponse({ status: 404, description: '快照不存在' }) async getLatestSnapshot(): Promise { const latestDate = await this.snapshotService.getLatestSnapshotDate(); if (!latestDate) { throw new NotFoundException('No snapshot found'); } const snapshot = await this.snapshotService.getSnapshotSummary(latestDate); if (!snapshot) { throw new NotFoundException('No snapshot found'); } return this.toResponse(snapshot); } @Get(':date') @ApiOperation({ summary: '获取指定日期的快照' }) @ApiParam({ name: 'date', description: '快照日期 (YYYY-MM-DD)' }) @ApiResponse({ status: 200, type: DailySnapshotResponse }) @ApiResponse({ status: 404, description: '快照不存在' }) async getSnapshot(@Param('date') date: string): Promise { const snapshot = await this.snapshotService.getSnapshotSummary(new Date(date)); if (!snapshot) { throw new NotFoundException(`Snapshot for ${date} not found`); } return this.toResponse(snapshot); } @Get(':date/ratios/:accountSequence') @ApiOperation({ summary: '获取用户在指定日期的算力占比' }) @ApiParam({ name: 'date', description: '快照日期 (YYYY-MM-DD)' }) @ApiParam({ name: 'accountSequence', description: '账户序号' }) @ApiResponse({ status: 200, type: UserContributionRatioResponse }) @ApiResponse({ status: 404, description: '快照或账户不存在' }) async getUserRatio( @Param('date') date: string, @Param('accountSequence') accountSequence: string, ): Promise { const result = await this.snapshotService.getUserContributionRatio(accountSequence, new Date(date)); if (!result) { throw new NotFoundException(`Snapshot or account not found`); } return { contribution: result.contribution.value.toString(), ratio: result.ratio, }; } @Get(':date/ratios') @Public() @ApiOperation({ summary: '批量获取用户算力占比' }) @ApiParam({ name: 'date', description: '快照日期 (YYYY-MM-DD)' }) @ApiResponse({ status: 200, type: BatchUserRatiosResponse }) async getBatchRatios( @Param('date') date: string, @Query() query: GetBatchRatiosRequest, ): Promise { return this.snapshotService.batchGetUserContributionRatios(new Date(date), query.page, query.pageSize); } private toResponse(snapshot: any): DailySnapshotResponse { return { id: snapshot.id?.toString() ?? snapshot.snapshotDate.toISOString().split('T')[0], snapshotDate: snapshot.snapshotDate, totalPersonalContribution: '0', // Not available in summary totalTeamLevelContribution: '0', // Not available in summary totalTeamBonusContribution: '0', // Not available in summary totalContribution: snapshot.networkTotalContribution?.value?.toString() ?? '0', totalAccounts: snapshot.totalAccounts, activeAccounts: snapshot.activeAccounts, createdAt: snapshot.createdAt, }; } }