rwadurian/backend/services/reporting-service/src/api/controllers/report.controller.ts

155 lines
4.4 KiB
TypeScript

import {
Controller,
Get,
Post,
Body,
Param,
Query,
HttpCode,
HttpStatus,
NotFoundException,
} from '@nestjs/common';
import {
ApiTags,
ApiOperation,
ApiResponse,
ApiBearerAuth,
} from '@nestjs/swagger';
import { GenerateReportDto } from '../dto/request/generate-report.dto';
import { QueryReportDto } from '../dto/request/query-report.dto';
import { ReportSnapshotResponseDto } from '../dto/response/report-snapshot.dto';
import { ReportDefinitionResponseDto } from '../dto/response/report-definition.dto';
import { GenerateReportHandler } from '../../application/commands/generate-report/generate-report.handler';
import { GenerateReportCommand } from '../../application/commands/generate-report/generate-report.command';
import { ReportingApplicationService } from '../../application/services/reporting-application.service';
@ApiTags('Reports')
@Controller('reports')
@ApiBearerAuth()
export class ReportController {
constructor(
private readonly generateReportHandler: GenerateReportHandler,
private readonly reportingService: ReportingApplicationService,
) {}
@Get('definitions')
@ApiOperation({ summary: '获取所有报表定义' })
@ApiResponse({
status: 200,
description: '报表定义列表',
type: [ReportDefinitionResponseDto],
})
async getDefinitions(): Promise<ReportDefinitionResponseDto[]> {
return this.reportingService.getReportDefinitions();
}
@Get('definitions/:code')
@ApiOperation({ summary: '获取报表定义详情' })
@ApiResponse({
status: 200,
description: '报表定义详情',
type: ReportDefinitionResponseDto,
})
@ApiResponse({ status: 404, description: '报表定义不存在' })
async getDefinition(
@Param('code') code: string,
): Promise<ReportDefinitionResponseDto> {
const definition = await this.reportingService.getReportDefinitionByCode(code);
if (!definition) {
throw new NotFoundException(`Report definition not found: ${code}`);
}
return definition;
}
@Post('generate')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: '生成报表' })
@ApiResponse({
status: 200,
description: '报表生成成功',
type: ReportSnapshotResponseDto,
})
async generateReport(
@Body() dto: GenerateReportDto,
): Promise<ReportSnapshotResponseDto> {
const command = new GenerateReportCommand(
dto.reportCode,
dto.reportPeriod,
new Date(dto.startDate),
new Date(dto.endDate),
dto.dimensions,
dto.filters,
);
const snapshot = await this.generateReportHandler.execute(command);
return {
id: snapshot.id?.toString() || '',
reportType: snapshot.reportType,
reportCode: snapshot.reportCode,
reportPeriod: snapshot.reportPeriod,
periodKey: snapshot.periodKey,
rowCount: snapshot.rowCount,
summary: snapshot.snapshotData.summary,
rows: snapshot.snapshotData.rows,
periodStartAt: snapshot.periodStartAt,
periodEndAt: snapshot.periodEndAt,
generatedAt: snapshot.generatedAt,
};
}
@Get('snapshots')
@ApiOperation({ summary: '查询报表快照' })
@ApiResponse({
status: 200,
description: '报表快照列表',
type: [ReportSnapshotResponseDto],
})
async getSnapshots(
@Query() query: QueryReportDto,
): Promise<ReportSnapshotResponseDto[]> {
if (query.reportCode) {
const snapshots = await this.reportingService.getReportSnapshots(
query.reportCode,
);
return snapshots.map((s) => ({
...s,
rows: undefined,
}));
}
if (query.reportPeriod) {
const snapshots = await this.reportingService.getSnapshotsByPeriod(
query.reportPeriod,
);
return snapshots.map((s) => ({
...s,
rows: undefined,
}));
}
return [];
}
@Get('snapshots/:code/latest')
@ApiOperation({ summary: '获取最新报表快照' })
@ApiResponse({
status: 200,
description: '最新报表快照',
type: ReportSnapshotResponseDto,
})
@ApiResponse({ status: 404, description: '快照不存在' })
async getLatestSnapshot(
@Param('code') code: string,
): Promise<ReportSnapshotResponseDto> {
const snapshot = await this.reportingService.getLatestSnapshot(code);
if (!snapshot) {
throw new NotFoundException(`No snapshot found for report: ${code}`);
}
return {
...snapshot,
rows: undefined,
};
}
}