feat(ai): 添加AI报告生成历史记录功能,支持每日生成限制和双API提供商
This commit is contained in:
@@ -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,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user