feat(ai): 添加AI报告生成历史记录功能,支持每日生成限制和双API提供商

This commit is contained in:
richarjiang
2025-12-02 12:07:08 +08:00
parent 5b89a07751
commit 562c66a930
21 changed files with 942 additions and 2074 deletions

View File

@@ -47,6 +47,7 @@ import { JwtAuthGuard } from 'src/common/guards/jwt-auth.guard';
import { ResponseCode } from 'src/base.dto';
import { CosService } from './cos.service';
import { AiReportService } from '../ai-coach/services/ai-report.service';
import { GetAiReportHistoryQueryDto, GetAiReportHistoryResponseDto } from '../ai-coach/dto/ai-report-history.dto';
@ApiTags('users')
@@ -497,6 +498,7 @@ export class UsersController {
data: {
type: 'object',
properties: {
id: { type: 'string', example: '550e8400-e29b-41d4-a716-446655440000' },
imageUrl: { type: 'string', example: 'https://example.com/generated-image.png' }
}
}
@@ -506,7 +508,7 @@ export class UsersController {
async generateAiHealthReport(
@CurrentUser() user: AccessTokenPayload,
@Body() body: { date?: string },
): Promise<{ code: ResponseCode; message: string; data: { imageUrl: string } }> {
): Promise<{ code: ResponseCode; message: string; data: { id: string; imageUrl: string } }> {
try {
this.logger.log(`生成AI健康报告请求 - 用户ID: ${user.sub}, 日期: ${body.date || '今天'}`);
@@ -516,6 +518,7 @@ export class UsersController {
code: ResponseCode.SUCCESS,
message: 'AI健康报告生成成功',
data: {
id: result.id,
imageUrl: result.imageUrl,
},
};
@@ -531,10 +534,78 @@ export class UsersController {
code: ResponseCode.ERROR,
message: `生成失败: ${(error as Error).message}`,
data: {
id: '',
imageUrl: '',
},
};
}
}
/**
* 获取用户的 AI 健康报告历史列表
*/
@UseGuards(JwtAuthGuard)
@Get('ai-report/history')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: '获取用户的 AI 健康报告历史列表(分页)' })
@ApiQuery({ name: 'page', required: false, description: '页码从1开始默认1' })
@ApiQuery({ name: 'pageSize', required: false, description: '每页条数默认10最大50' })
@ApiQuery({ name: 'startDate', required: false, description: '开始日期,格式 YYYY-MM-DD' })
@ApiQuery({ name: 'endDate', required: false, description: '结束日期,格式 YYYY-MM-DD' })
@ApiQuery({ name: 'status', required: false, description: '状态筛选: pending | processing | success | failed不传则返回所有状态' })
@ApiResponse({ status: 200, description: '成功获取报告历史列表', type: GetAiReportHistoryResponseDto })
async getAiReportHistory(
@CurrentUser() user: AccessTokenPayload,
@Query() query: GetAiReportHistoryQueryDto,
): Promise<GetAiReportHistoryResponseDto> {
try {
this.logger.log(`获取AI健康报告历史 - 用户ID: ${user.sub}, 页码: ${query.page}, 每页: ${query.pageSize}`);
const result = await this.aiReportService.getReportHistory(user.sub, {
page: query.page,
pageSize: query.pageSize,
startDate: query.startDate,
endDate: query.endDate,
status: query.status,
});
return {
code: ResponseCode.SUCCESS,
message: 'success',
data: {
records: result.records.map(r => ({
id: r.id,
reportDate: r.reportDate,
imageUrl: r.imageUrl || '', // 成功记录一定有 imageUrl
status: r.status,
createdAt: r.createdAt,
})),
total: result.total,
page: result.page,
pageSize: result.pageSize,
totalPages: result.totalPages,
},
};
} catch (error) {
this.winstonLogger.error('获取AI健康报告历史失败', {
context: 'UsersController',
userId: user?.sub,
error: (error as Error).message,
stack: (error as Error).stack,
});
return {
code: ResponseCode.ERROR,
message: `获取失败: ${(error as Error).message}`,
data: {
records: [],
total: 0,
page: 1,
pageSize: 10,
totalPages: 0,
},
};
}
}
}