feat(diet-records): 新增营养成分表图片分析功能
- 添加营养成分表图片识别API接口,支持通过AI模型分析食物营养成分 - 新增NutritionAnalysisService服务,集成GLM-4.5V和Qwen VL视觉模型 - 实现营养成分提取和健康建议生成功能 - 添加完整的API文档和TypeScript类型定义 - 支持多种营养素类型识别,包括热量、蛋白质、脂肪等20+种营养素
This commit is contained in:
@@ -15,7 +15,10 @@ import {
|
||||
} from '@nestjs/common';
|
||||
import { ApiOperation, ApiBody, ApiResponse, ApiTags, ApiQuery } from '@nestjs/swagger';
|
||||
import { DietRecordsService } from './diet-records.service';
|
||||
import { NutritionAnalysisService } from './services/nutrition-analysis.service';
|
||||
import { CreateDietRecordDto, UpdateDietRecordDto, GetDietHistoryQueryDto, DietRecordResponseDto, DietHistoryResponseDto, NutritionSummaryDto, FoodRecognitionRequestDto, FoodRecognitionResponseDto, FoodRecognitionToDietRecordsResponseDto } from '../users/dto/diet-record.dto';
|
||||
import { NutritionAnalysisResponseDto } from './dto/nutrition-analysis.dto';
|
||||
import { NutritionAnalysisRequestDto } from './dto/nutrition-analysis-request.dto';
|
||||
import { JwtAuthGuard } from '../common/guards/jwt-auth.guard';
|
||||
import { CurrentUser } from '../common/decorators/current-user.decorator';
|
||||
import { AccessTokenPayload } from '../users/services/apple-auth.service';
|
||||
@@ -27,6 +30,7 @@ export class DietRecordsController {
|
||||
|
||||
constructor(
|
||||
private readonly dietRecordsService: DietRecordsService,
|
||||
private readonly nutritionAnalysisService: NutritionAnalysisService,
|
||||
) { }
|
||||
|
||||
/**
|
||||
@@ -161,4 +165,57 @@ export class DietRecordsController {
|
||||
requestDto.mealType
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分析食物营养成分表图片
|
||||
*/
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Post('analyze-nutrition-image')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@ApiOperation({ summary: '分析食物营养成分表图片' })
|
||||
@ApiBody({ type: NutritionAnalysisRequestDto })
|
||||
@ApiResponse({ status: 200, description: '成功分析营养成分表', type: NutritionAnalysisResponseDto })
|
||||
@ApiResponse({ status: 400, description: '请求参数错误' })
|
||||
@ApiResponse({ status: 401, description: '未授权访问' })
|
||||
@ApiResponse({ status: 500, description: '服务器内部错误' })
|
||||
async analyzeNutritionImage(
|
||||
@Body() requestDto: NutritionAnalysisRequestDto,
|
||||
@CurrentUser() user: AccessTokenPayload,
|
||||
): Promise<NutritionAnalysisResponseDto> {
|
||||
this.logger.log(`分析营养成分表 - 用户ID: ${user.sub}, 图片URL: ${requestDto.imageUrl}`);
|
||||
|
||||
if (!requestDto.imageUrl) {
|
||||
return {
|
||||
success: false,
|
||||
data: [],
|
||||
message: '请提供图片URL'
|
||||
};
|
||||
}
|
||||
|
||||
// 验证URL格式
|
||||
try {
|
||||
new URL(requestDto.imageUrl);
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
data: [],
|
||||
message: '图片URL格式不正确'
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await this.nutritionAnalysisService.analyzeNutritionImage(requestDto.imageUrl);
|
||||
|
||||
this.logger.log(`营养成分表分析完成 - 用户ID: ${user.sub}, 成功: ${result.success}, 营养素数量: ${result.data.length}`);
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
this.logger.error(`营养成分表分析失败 - 用户ID: ${user.sub}, 错误: ${error instanceof Error ? error.message : String(error)}`);
|
||||
return {
|
||||
success: false,
|
||||
data: [],
|
||||
message: '营养成分表分析失败,请稍后重试'
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user