import { Controller, Get, Post, Query, Res, UseGuards } from '@nestjs/common'; import { ApiTags, ApiBearerAuth, ApiOperation, ApiQuery } from '@nestjs/swagger'; import type { Response } from 'express'; import { ReportingService } from './reporting.service'; import { AdminAuthGuard } from '../../common/guards/admin-auth.guard'; import { AdminRolesGuard } from '../../common/guards/admin-roles.guard'; @ApiTags('admin-reporting') @ApiBearerAuth() @Controller('admin-api/reporting') @UseGuards(AdminAuthGuard, AdminRolesGuard) export class ReportingController { constructor(private readonly reportingService: ReportingService) {} @Get('export/users') @ApiOperation({ summary: '导出用户数据 CSV' }) @ApiQuery({ name: 'days', required: false }) async exportUsers(@Query('days') days = '30', @Res() res: Response) { const csv = await this.reportingService.userReport(Number(days)); res.setHeader('Content-Type', 'text/csv; charset=utf-8'); res.setHeader('Content-Disposition', `attachment; filename="user-report-${days}d.csv"`); res.send(csv); } @Get('export/learning') @ApiOperation({ summary: '导出学习数据 CSV' }) @ApiQuery({ name: 'days', required: false }) async exportLearning(@Query('days') days = '30', @Res() res: Response) { const csv = await this.reportingService.learningReport(Number(days)); res.setHeader('Content-Type', 'text/csv; charset=utf-8'); res.setHeader('Content-Disposition', `attachment; filename="learning-report-${days}d.csv"`); res.send(csv); } @Get('export/reviews') @ApiOperation({ summary: '导出复习数据 CSV' }) @ApiQuery({ name: 'days', required: false }) async exportReviews(@Query('days') days = '30', @Res() res: Response) { const csv = await this.reportingService.reviewReport(Number(days)); res.setHeader('Content-Type', 'text/csv; charset=utf-8'); res.setHeader('Content-Disposition', `attachment; filename="review-report-${days}d.csv"`); res.send(csv); } @Get('jobs') @ApiOperation({ summary: '导出任务历史' }) async listJobs(@Query('page') page?: string, @Query('limit') limit?: string) { return this.reportingService.getExportJobs(Number(page) || 1, Number(limit) || 20); } }