import { Controller, Get, Query, UseGuards } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiQuery, } from '@nestjs/swagger'; import { PlantingApplicationService, TrendPeriodType } from '../../application/services/planting-application.service'; import { JwtAuthGuard } from '../guards/jwt-auth.guard'; import { GlobalStatsResponseDto, TrendDataResponseDto } from '../dto/response/planting-stats.response'; /** * 认种统计控制器 * 提供全局统计数据 API,数据直接从订单表聚合查询 */ @ApiTags('认种统计') @Controller('planting/stats') export class PlantingStatsController { constructor( private readonly plantingService: PlantingApplicationService, ) {} /** * 获取全局认种统计(公开接口,无需认证) * 此接口可用于验证 reporting-service 的统计数据准确性 */ @Get('global') @ApiOperation({ summary: '获取全局认种统计', description: '从订单表实时聚合统计数据,可用于验证其他服务的统计准确性', }) @ApiResponse({ status: 200, description: '全局统计数据', type: GlobalStatsResponseDto, }) async getGlobalStats(): Promise<{ code: number; message: string; data: GlobalStatsResponseDto }> { const stats = await this.plantingService.getGlobalStats(); return { code: 0, message: 'success', data: stats, }; } /** * 获取全局认种统计(需要认证) * 管理后台调用此接口 */ @Get('admin/global') @UseGuards(JwtAuthGuard) @ApiBearerAuth() @ApiOperation({ summary: '获取全局认种统计(管理员)', description: '从订单表实时聚合统计数据,需要管理员权限', }) @ApiResponse({ status: 200, description: '全局统计数据', type: GlobalStatsResponseDto, }) async getAdminGlobalStats(): Promise<{ code: number; message: string; data: GlobalStatsResponseDto }> { const stats = await this.plantingService.getGlobalStats(); return { code: 0, message: 'success', data: stats, }; } /** * 获取认种趋势数据(公开接口) * [2026-01-06] 新增 */ @Get('trend') @ApiOperation({ summary: '获取认种趋势数据', description: '按时间维度聚合认种统计数据,用于绘制趋势图表', }) @ApiQuery({ name: 'period', required: false, enum: ['day', 'week', 'month', 'quarter', 'year'], description: '时间维度:day(最近30天)、week(最近12周)、month(最近12月)、quarter(最近8季度)、year(最近5年)', }) @ApiResponse({ status: 200, description: '趋势数据列表', type: [TrendDataResponseDto], }) async getTrendData( @Query('period') period: TrendPeriodType = 'day', ): Promise<{ code: number; message: string; data: TrendDataResponseDto[] }> { const validPeriods: TrendPeriodType[] = ['day', 'week', 'month', 'quarter', 'year']; if (!validPeriods.includes(period)) { period = 'day'; } const data = await this.plantingService.getTrendData(period); return { code: 0, message: 'success', data, }; } }