import { ApiProperty } from '@nestjs/swagger'; import { IsArray, IsBoolean, IsNotEmpty, IsOptional, IsString, IsInt, Min, Max } from 'class-validator'; /** * 食物营养数据DTO */ export class FoodNutritionDataDto { @ApiProperty({ description: '蛋白质含量(克)', required: false }) @IsOptional() @IsInt() @Min(0) proteinGrams?: number; @ApiProperty({ description: '碳水化合物含量(克)', required: false }) @IsOptional() @IsInt() @Min(0) carbohydrateGrams?: number; @ApiProperty({ description: '脂肪含量(克)', required: false }) @IsOptional() @IsInt() @Min(0) fatGrams?: number; @ApiProperty({ description: '膳食纤维含量(克)', required: false }) @IsOptional() @IsInt() @Min(0) fiberGrams?: number; } /** * 食物确认选项DTO */ export class FoodConfirmationOptionDto { @ApiProperty({ description: '食物选项唯一标识符' }) @IsString() @IsNotEmpty() id: string; @ApiProperty({ description: '显示给用户的完整选项文本' }) @IsString() @IsNotEmpty() label: string; @ApiProperty({ description: '食物名称' }) @IsString() @IsNotEmpty() foodName: string; @ApiProperty({ description: '份量描述' }) @IsString() @IsNotEmpty() portion: string; @ApiProperty({ description: '估算热量' }) @IsInt() @Min(0) @Max(5000) calories: number; @ApiProperty({ description: '餐次类型' }) @IsString() @IsNotEmpty() mealType: string; @ApiProperty({ description: '营养数据', type: FoodNutritionDataDto }) nutritionData: FoodNutritionDataDto; } /** * 食物识别请求DTO */ export class FoodRecognitionRequestDto { @ApiProperty({ description: '图片URL数组' }) @IsArray() @IsString({ each: true }) @IsNotEmpty({ each: true }) imageUrls: string[]; } /** * 食物识别响应DTO - 总是返回数组结构 */ export class FoodRecognitionResponseDto { @ApiProperty({ description: '识别到的食物列表,即使只有一种食物也返回数组格式', type: [FoodConfirmationOptionDto] }) @IsArray() items: FoodConfirmationOptionDto[]; @ApiProperty({ description: '识别说明文字' }) @IsString() analysisText: string; @ApiProperty({ description: '识别置信度', minimum: 0, maximum: 100 }) @IsInt() @Min(0) @Max(100) confidence: number; @ApiProperty({ description: '是否识别到食物', default: true }) @IsBoolean() isFoodDetected: boolean; @ApiProperty({ description: '非食物提示信息,当isFoodDetected为false时显示', required: false }) @IsOptional() @IsString() nonFoodMessage?: string; } /** * 食物确认请求DTO */ export class FoodConfirmationRequestDto { @ApiProperty({ description: '用户选择的食物选项' }) selectedOption: FoodConfirmationOptionDto; @ApiProperty({ description: '图片URL', required: false }) @IsOptional() @IsString() imageUrl?: string; } /** * 文本食物分析请求DTO */ export class TextFoodAnalysisRequestDto { @ApiProperty({ description: '用户描述的饮食文本内容', example: '今天早餐吃了一碗燕麦粥加香蕉' }) @IsString() @IsNotEmpty() text: string; }