rwadurian/backend/services/contribution-service/src/api/controllers/snapshot.controller.ts

100 lines
4.1 KiB
TypeScript

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<DailySnapshotResponse> {
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<DailySnapshotResponse> {
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<DailySnapshotResponse> {
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<UserContributionRatioResponse> {
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<BatchUserRatiosResponse> {
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,
};
}
}