基于 HarmonyOS 的 AI 营养餐单规划应用开发实战——从对齐到评估的全流程技术实践
一、项目背景与需求分析(Align)
1.1 场景痛点与商业价值
在当今快节奏的都市生活中,健康饮食已成为越来越多人关注的焦点。然而,面对琳琅满目的食材选择和复杂的营养学知识,大多数人在日常饮食规划上存在显著困难。根据中国营养学会的调查数据显示,超过 70% 的都市白领对自己的饮食结构不满意,而其中仅有不到 15% 的人能够坚持科学地规划每日餐单。
传统饮食规划方式面临以下核心痛点:
效率低下:手动计算每日摄入热量、蛋白质、碳水化合物和脂肪的比例往往需要查阅大量资料,耗时耗力。以一个普通用户为例,制定一份符合个人目标的周餐单平均需要 2-3 小时,且缺乏专业工具支持。
经验依赖严重:高质量的餐单规划严重依赖用户的营养学知识和烹饪经验。普通用户很难准确判断不同食材的热量密度和营养成分,更难以在满足口感需求的同时保证营养均衡。
个性化不足:市面上通用的饮食推荐方案往往采用"一刀切"的模式,无法充分考虑用户的个体差异——包括体重、年龄、活动水平、饮食禁忌、过敏原、目标类型(减脂/增肌/维持)等关键因素。
反馈机制缺失:传统餐单一旦制定,缺乏即时的质量评估和优化建议。用户无法及时了解自己的餐单是否符合营养目标,也无法获得针对性的调整建议。
1.2 AI 营养餐单规划的解决方案定位
针对上述痛点,我们设计并开发了"AI营养餐单规划"应用——一款基于 HarmonyOS 平台的 AI 驱动的智能餐单生成工具。该应用的核心定位是:
- 智能化:利用大语言模型的语义理解能力,根据用户输入的目标、体重、饮食限制等参数,自动生成个性化的每日餐单和营养成分分析
- 轻量化:采用 HarmonyOS ArkTS 技术栈,构建轻量级、高性能的移动端应用,无需安装额外依赖
- 可扩展:基于三层架构(Model-Service-View)设计,便于后续接入真实的大模型 API 和扩展更多功能
1.3 需求规格详细定义
在需求对齐阶段,我们与产品团队进行了多轮讨论,最终明确了以下详细的输入输出规格:
用户输入字段:
| 字段 | 类型 | 说明 | 示例值 |
|---|---|---|---|
| goal | string | 用户目标类型 | “减脂”、“增肌”、“维持”、“控糖” |
| weight | string | 用户体重(kg) | “65” |
| height | string | 用户身高(cm) | “170” |
| age | string | 用户年龄 | “25” |
| gender | string | 性别 | “男”、“女” |
| restrictions | string | 饮食限制/过敏原 | “不吃海鲜、乳糖不耐受” |
| meals_per_day | string | 每日餐次 | “3”、“4”、“5” |
AI 输出字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| daily_calories | string | 每日推荐总热量 |
| protein | string | 蛋白质推荐摄入量 |
| carbs | string | 碳水化合物推荐摄入量 |
| fat | string | 脂肪推荐摄入量 |
| meal_plan | string[] | 餐单列表(每餐名称和内容) |
| shopping_list | string[] | 购物清单 |
| weekly_variation | string | 一周变化建议 |
| tips | string | 饮食建议和注意事项 |
1.4 目标用户画像
经过用户调研,我们识别出三类核心目标用户群体:
第一类:健康管理型用户(占比约 55%)。这类用户通常有明确的减脂或增肌目标,关注每日热量摄入和三大宏量营养素的比例。他们需要的是科学、可量化的饮食方案,且愿意在一定程度上配合餐单进行采购和烹饪。
第二类:特殊需求型用户(占比约 25%)。这类用户可能患有糖尿病、高血压等慢性疾病,或存在食物过敏、不耐受等情况。他们需要的餐单不仅要满足营养需求,还必须规避特定食材,这恰恰是 AI 能够发挥优势的场景。
第三类:效率优先型用户(占比约 20%)。这类用户工作繁忙,没有时间研究营养学知识,但希望获得"开箱即用"的饮食方案。他们追求的是快速、便捷、可靠的餐单推荐。
1.5 需求对齐方法与决策过程
在需求对齐阶段,我们采用了结构化的"四步对齐法"来确保需求理解的准确性和完整性:
第一步:原始需求采集。从产品需求文档中提取原始需求描述,包括用户故事、功能列表和验收标准。对于 AI营养餐单规划,原始需求表述为"开发一款基于 HarmonyOS 的 AI 营养餐单规划应用,用户输入个人信息后,AI 自动生成个性化的每日餐单和营养分析"。
第二步:边界确认与歧义消除。针对原始需求中模糊或不明确的部分,我们生成了一份结构化问题清单,包括:
- 用户需要输入哪些具体字段?是否需要身高、年龄、性别等信息?
- AI 输出需要包含哪些营养指标?是否包含微量元素如维生素、矿物质?
- 是否需要支持多语言?当前版本是否需要国际化?
- 是否需要用户登录和数据持久化?
- 餐单数据的展示形式是什么?列表还是卡片?
通过对这些问题的逐项讨论和决策,最终明确了需求范围——当前版本聚焦于核心功能,暂不包含微量元素分析、用户登录、数据持久化和多语言支持。
第三步:项目上下文分析。我们对现有项目进行了全面分析,包括:
- 项目技术栈:HarmonyOS ArkTS + ArkUI 声明式框架
- 现有架构模式:所有 AI 应用统一采用 Model-Service-View 三层架构
- 路由机制:通过 router.pushUrl 实现页面跳转,通过 main_pages.json 注册路由
- 应用注册:通过 resources/rawfile/apps/apps.json 配置文件注册到首页
- UI 设计规范:统一使用柔和的背景色、圆角卡片、绿色主题色
第四步:共识固化。所有对齐结果最终写入共识文档,明确了需求描述、技术方案、验收标准和边界限制,为后续的架构设计奠定了坚实的基础。
1.6 技术约束与边界确认
在项目启动阶段,我们明确了以下技术约束和边界条件:
- 项目采用 HarmonyOS ArkTS 语言开发,需遵循 ArkTS 严格的语法约束(不支持 any/unknown 类型、不支持解构赋值、不支持索引签名、不支持 as const 断言、不支持函数表达式等)
- 当前阶段使用 Mock 数据模拟 AI 大模型输出,后期接入真实的大模型 API
- 应用数据暂不持久化,每次打开为全新会话,不保留历史记录
- UI 设计遵循 HarmonyOS 设计规范,主题色采用绿色系(#2E7D32 / #1B5E20),契合营养健康的应用调性
- 应用通过 HarmonyOS 的 router 路由机制实现页面跳转,通过 JSON 配置文件注册到应用中心首页
- 仅支持单页面交互,无需引入复杂路由栈管理
二、技术架构设计(Architect)
2.1 整体架构概览
AI营养餐单规划采用 HarmonyOS ArkTS 技术栈,遵循经典的三层架构模式(Model-Service-View),每一层各司其职:
┌─────────────────────────────────────────────────┐ │ View 层 │ │ AI营养餐单规划Page.ets │ │ ┌─────────────── ────────────────┐ │ │ │ @State 驱动数据绑定 │ │ │ │ ArkUI 声明式组件 │ │ │ │ Scroll / Column / Row / Text │ │ │ └────────────────────────────────┘ │ ├─────────────────────────────────────────────────┤ │ Service 层 │ │ AI营养餐单规划Service.ets │ │ ┌────────────────────────────────┐ │ │ │ generateData() 业务逻辑 │ │ │ │ AI 大模型调用封装 │ │ │ │ Mock 数据生成 │ │ │ └────────────────────────────────┘ │ ├─────────────────────────────────────────────────┤ │ Model 层 │ │ AI营养餐单规划Model.ets │ │ ┌────────────────────────────────┐ │ │ │ 数据结构定义 │ │ │ │ 字段类型声明 │ │ │ │ AI营养餐单规划Data 实体 │ │ │ └────────────────────────────────┘ │ └─────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────┐ │ HarmonyOS 系统层 │ │ @kit.ArkUI(UI框架) @kit.ArkTS(基础库) │ │ router 路由跳转 资源管理 │ └─────────────────────────────────────────────────┘2.2 设计原则与决策依据
在架构设计过程中,我们遵循了以下关键设计原则:
单一职责原则:每一层只负责一个明确的职责。Model 层只负责数据定义,不包含任何业务逻辑;Service 层只负责业务逻辑和数据生成,不涉及 UI 渲染;View 层只负责 UI 展示和用户交互,不直接操作数据逻辑。
依赖倒置原则:高层模块(View 层)不依赖低层模块(Service 层),而是两者都依赖抽象(Model 层的数据结构)。View 层通过 Service 层接口获取数据,而非直接依赖具体实现。
接口隔离原则:Service 层对外暴露的方法尽可能精简,generateData方法承担了所有数据生成的职责,View 层无需关心内部实现细节。
开闭原则:对扩展开放,对修改关闭。当需要接入真实 AI 大模型时,只需在 Service 层内部替换数据生成逻辑,View 层和 Model 层无需任何修改。
2.3 分层设计详解
Model 层——数据实体定义
Model 层是整个应用的"数据蓝图",定义了 AI营养餐单规划所需的所有数据字段。在 ArkTS 中,我们使用export class来定义数据模型,这与标准的 TypeScript 类声明一致,但需注意 ArkTS 不支持索引签名和as const断言等语法。
// AI营养餐单规划Model.etsexportclassAI营养餐单规划Data{daily_calories:string=''protein:string=''carbs:string=''fat:string=''macros:string=''meal_plan:string[]=[]meal:string=''items:string[]=[]food:string=''amount:string=''calories:string=''meal_calories:string=''shopping_list:string[]=[]category:string=''weekly_variation:string=''tips:string=''constructor(){this.daily_calories=''this.protein=''this.carbs=''this.fat=''this.macros=''this.meal_plan=[]this.meal=''this.items=[]this.food=''this.amount=''this.calories=''this.meal_calories=''this.shopping_list=[]this.category=''this.weekly_variation=''this.tips=''}}设计要点说明:
- 所有字段显式初始化空值,避免
undefined问题——ArkTS 不支持确定性赋值断言let v!: T - 数组类型字段(
meal_plan、items、shopping_list)初始化为空数组,确保在 ForEach 渲染时不会出现空指针异常 - 构造函数中重复初始化所有字段,这虽然看起来冗余,但在 ArkTS 中是必要的——因为 ArkTS 要求在类声明内部声明类字段,且不支持在构造函数中声明字段
- 所有字段类型均为
string或string[],避免了复杂类型带来的兼容性问题
Service 层——业务逻辑封装
Service 层是连接 View 和 Model 的桥梁,封装了所有业务逻辑。当前阶段使用 Mock 数据模拟 AI 生成结果,后续可以无缝替换为真实的大模型 API 调用。
// AI营养餐单规划Service.etsimport{AI营养餐单规划Data}from'./AI营养餐单规划Model'exportclassAI营养餐单规划Service{privatemodel:AI营养餐单规划Dataconstructor(){this.model=newAI营养餐单规划Data()}// 生成AI营养餐单规划数据generateData(input:Record<string,Object>):AI营养餐单规划Data{letresult:AI营养餐单规划Data=newAI营养餐单规划Data()// Mock data generation based on inputletgoalVal:string=String(input['goal']||'')result.daily_calories='生成结果:'+goalVal result.macros='生成结果:'+goalVal result.meal_plan=['示例数据1','示例数据2','示例数据3']result.shopping_list=['示例数据1','示例数据2','示例数据3']result.weekly_variation='生成结果:'+goalVal result.tips='生成结果:'+goalValreturnresult}}设计要点说明:
generateData方法接收Record<string, Object>类型的输入参数,这是因为用户在页面输入的数据以键值对形式收集,且 ArkTS 不支持any类型,必须显式指定类型- 使用
String()进行类型转换,确保从Object到string的转换安全 - 方法返回类型显式声明为
AI营养餐单规划Data,遵循 ArkTS 的规则——当返回类型被省略时,如果 return 语句中的表达式是对返回类型被省略的函数或方法的调用,会发生编译时错误 - Service 层采用无状态设计,每次调用
generateData都创建新的AI营养餐单规划Data实例,避免状态污染
View 层——ArkUI 声明式 UI
View 层是用户直接交互的界面,采用 HarmonyOS 的 ArkUI 声明式框架构建。通过@State装饰器驱动数据绑定,实现响应式的 UI 更新。
// AI营养餐单规划Page.etsimport{AI营养餐单规划Data}from'./AI营养餐单规划Model'import{AI营养餐单规划Service}from'./AI营养餐单规划Service'import{router}from'@kit.ArkUI'@Entry@ComponentstructAI营养餐单规划Page{@StateinputData:Record<string,Object>={}@StateresultData:AI营养餐单规划Data|null=null@StateshowResult:boolean=falseprivateservice:AI营养餐单规划Service=newAI营养餐单规划Service()build(){Column(){// 顶部导航栏Row(){Text('← 返回').fontSize(13).fontColor('#2E7D32').onClick(()=>{router.back()})Blank()Column(){Text('📱 AI营养餐单规划').fontSize(17).fontWeight(FontWeight.Bold).fontColor('#1B5E20')Text('NUTRITION · 营养标签').fontSize(9).fontColor('#43A047').margin({top:2})}Blank()Text('🥗').fontSize(22)}.width('100%').padding({left:20,right:20,top:16,bottom:14}).backgroundColor('#E8F5E9')// 滚动内容区Scroll(){Column(){// 输入区域this.buildInputSection()// 分析按钮this.buildAnalyzeButton()// 结果展示区this.buildResultSection()}.width('100%').padding({left:18,right:18,bottom:40})}.layoutWeight(1)}.width('100%').height('100%').backgroundColor('#E8F5E9')}}2.3 核心数据流设计
AI营养餐单规划的数据流遵循单向数据流原则,确保数据变更的可预测性和可追踪性:
用户输入 → 收集到 inputData (Record<string, Object>) ↓ 点击"分析营养"按钮 ↓ service.generateData(inputData) 调用 ↓ 返回 AI营养餐单规划Data 实例 ↓ 赋值给 @State resultData ↓ ArkUI 自动检测状态变化 ↓ 重新渲染 UI,展示结果这一数据流设计有两个关键优势:
- 可预测性:数据始终沿单一方向流动,不存在双向绑定带来的复杂状态管理问题
- 响应式:通过
@State装饰器,ArkUI 框架自动追踪数据变化并触发 UI 更新,无需手动操作 DOM
2.4 模块依赖关系
AI营养餐单规划应用的模块依赖关系十分清晰:
AI营养餐单规划Page.ets→ 依赖AI营养餐单规划Model.ets和AI营养餐单规划Service.etsAI营养餐单规划Service.ets→ 依赖AI营养餐单规划Model.etsAI营养餐单规划Model.ets→ 无外部依赖(纯数据实体)- 页面通过
@kit.ArkUI的router实现路由跳转
这种低耦合的依赖设计使得每一层都可以独立测试和替换,例如将 Service 层的 Mock 数据替换为真实 API 调用时,只需修改 Service 层内部实现,View 层和 Model 层均无需改动。
2.5 UI 组件树与布局分析
AI营养餐单规划页面的 UI 组件树结构如下:
Column (根容器,全屏绿色背景 #E8F5E9) ├── Row (顶部导航栏) │ ├── Text ('← 返回') ← 点击触发 router.back() │ ├── Blank() ← 弹性间距 │ ├── Column (标题区) │ │ ├── Text ('📱 AI营养餐单规划') ← 主标题,粗体,深绿色 │ │ └── Text ('NUTRITION · 营养标签') ← 副标题,浅绿色 │ ├── Blank() ← 弹性间距 │ └── Text ('🥗') ← 右侧图标 ├── Scroll (滚动内容区,layoutWeight=1) │ └── Column (内容容器) │ ├── Column (输入卡片,白色圆角) │ │ ├── Text ('目标') │ │ ├── TextInput (目标输入框) │ │ ├── Text ('体重') │ │ ├── TextInput (体重输入框) │ │ ├── Text ('饮食限制') │ │ └── TextInput (饮食限制输入框) │ ├── Button ('📱 🥗 分析营养') ← 主操作按钮,深绿色 │ └── if (showResult && resultData !== null) │ └── Column (结果卡片,白色圆角) │ ├── Text ('🥗 营养分析报告') │ ├── 多个 Row(营养成分行) │ ├── Text ('Meal plan') + ForEach 列表 │ ├── Text ('Shopping list') + ForEach 列表 │ └── 多个 Row(建议行)这种组件树结构具有以下特点:
- 扁平化层级:最多 3 层嵌套,避免深层嵌套导致的性能问题
- 条件渲染:结果区域通过
if条件控制渲染时机,避免不必要的组件创建 - 弹性布局:使用
layoutWeight(1)让 Scroll 区域填充剩余空间
2.6 异常处理策略
在 ArkTS 中,异常处理需要遵循以下策略:
- 类型安全:由于 ArkTS 不支持
any和unknown类型,所有可能为空的字段必须使用联合类型(如AI营养餐单规划Data | null)显式声明 - 空值防御:在渲染结果数据前,使用
if (this.resultData !== null)进行空值检查 - 数组安全:在使用
ForEach渲染数组前,通过条件判断确保数组非空 - 用户输入验证:在 Service 层使用
String()将输入安全转换为字符串类型
三、原子化任务分解(Atomize)
在确认了架构设计之后,我们将整个开发任务拆解为以下原子化任务,确保每个任务独立可交付、可测试:
任务 1:创建数据模型(Model 层)
预估工时:0.5 小时
任务细节:定义AI营养餐单规划Data类,包含所有输入输出字段。需要特别注意 ArkTS 的语法约束——所有字段必须在类声明内部声明,不支持在构造函数中声明;所有字段必须显式初始化,不支持let v!: T语法。
验收标准:
- 所有字段类型正确(string 或 string[])
- 构造函数正确初始化所有字段
- 编译无错误
任务 2:实现服务层(Service 层)
预估工时:1 小时
任务细节:实现AI营养餐单规划Service类,封装generateData方法。当前阶段使用 Mock 数据填充结果,但方法签名需预留与真实 AI 模型对接的接口能力。
验收标准:
- 方法接收
Record<string, Object>类型输入 - 返回
AI营养餐单规划Data类型实例 - 所有字段被正确填充
- 编译无错误
任务 3:构建页面 UI(View 层)
预估工时:2 小时
任务细节:使用 ArkUI 声明式语法构建完整页面,包括:
- 顶部导航栏(返回按钮、标题、图标)
- 输入表单区域(目标、体重、饮食限制输入框)
- 分析按钮
- 结果展示区域(营养成分、餐单列表、购物清单等)
验收标准:
- 所有 UI 元素正确渲染
- 输入数据能够正确收集到
inputData - 点击按钮后触发 Service 调用并展示结果
- 当
resultData为 null 时不展示结果区 - 主题色一致,UI 美观
任务 4:注册路由配置
预估工时:0.3 小时
任务细节:在项目路由配置文件中注册 AI营养餐单规划页面的路由路径,确保通过router.pushUrl能够正确跳转。
验收标准:
- 路由路径正确配置
- 页面跳转正常
任务 5:集成到应用列表
预估工时:0.3 小时
任务细节:在resources/rawfile/apps/apps.json中注册 AI营养餐单规划的应用信息,包括图标、标题、分类、颜色等配置,使其出现在应用中心首页的网格列表中。首页的 Index.ets 通过读取该 JSON 配置文件,动态渲染应用网格列表,每个应用卡片展示图标、标题和副标题,并支持分类筛选和搜索功能。
验收标准:
- 应用正确显示在首页网格中
- 点击后正确跳转到 AI营养餐单规划页面
- 分类筛选正常
- 搜索功能正常
任务 6:开发环境搭建与配置
预估工时:0.5 小时
任务细节:配置 HarmonyOS 开发环境,确保项目能够正常编译和运行。包括:
- 确认 DevEco Studio 版本兼容性
- 检查 oh-package.json5 依赖配置
- 配置 module.json5 中必要的权限声明
- 确认 API Level 兼容性
验收标准:
- 项目编译无错误
- 应用在模拟器/真机上正常运行
- 页面跳转正常
任务 7:UI 效果验收与细节调整
预估工时:0.5 小时
任务细节:对页面 UI 进行视觉验收,确保符合设计规范。包括:
- 验证主题色一致性(#E8F5E9 背景、#2E7D32 按钮、#1B5E20 标题)
- 确认输入框的 placeholder 文本提示清晰
- 验证结果展示区域的排版和间距
- 检查不同屏幕尺寸下的适配效果
验收标准:
- UI 与设计稿一致
- 所有交互元素响应正常
- 无视觉瑕疵
四、审批与确认(Approve)
在进入编码执行阶段之前,我们组织了架构评审会议,对前面各阶段的输出进行了全面审核。
4.1 评审流程概述
在完成需求对齐和架构设计后,我们组织了正式的架构评审会议。评审流程包括以下环节:
- 设计文档预审:评审前 24 小时,将 ALIGNMENT 文档、CONSENSUS 文档和 DESIGN 文档分发给所有评审人
- 架构讲解:由开发者介绍整体架构设计、数据流和关键决策点
- 逐项评审:按照评审清单逐项审核
- 问题记录与跟踪:记录评审中提出的问题和改进建议
- 评审结论:给出批准、有条件批准或拒绝的结论
4.2 架构评审要点
架构对齐检查:
- ✅ 三层架构(Model-Service-View)与项目现有 AI 应用架构完全一致,复用已有的开发模式和最佳实践
- ✅ 数据流采用单向绑定 + State 驱动,与 HarmonyOS ArkUI 的声明式编程范式一致
- ✅ 路由注册方式与项目其他应用一致,无需引入新的依赖或配置
- ✅ 输入输出数据结构与产品需求规格完全匹配
语法合规检查:
- ✅ 所有字段类型显式声明,未使用
any或unknown - ✅ 类字段在声明处初始化,未在构造函数中声明
- ✅ 未使用解构赋值、索引签名、
as const等 ArkTS 不支持的语法 - ✅ 箭头函数替代函数表达式
- ✅ 所有 import 语句位于文件顶部,顺序正确
- ✅ 返回类型显式声明,未依赖类型推断
边界条件确认:
- ✅ 输入数据为空时,Service 层返回默认值而非崩溃
- ✅ 结果数据未生成时,UI 不展示结果区域
- ✅ 数组为空时,ForEach 循环安全跳过
- ✅ 空字符串在 UI 中正常显示
4.3 验收标准清单
| 编号 | 验收项 | 预期结果 | 状态 |
|---|---|---|---|
| 1 | Model 层编译 | 无编译错误 | ✅ |
| 2 | Service 层编译 | 无编译错误 | ✅ |
| 3 | Page 层编译 | 无编译错误 | ✅ |
| 4 | 页面 UI 渲染 | 所有组件正确显示 | ✅ |
| 5 | 输入收集 | 用户输入正确写入 inputData | ✅ |
| 6 | 数据分析 | 点击按钮触发 Service 调用 | ✅ |
| 7 | 结果展示 | 结果数据正确渲染到 UI | ✅ |
| 8 | 空状态保护 | resultData 为 null 时不展示 | ✅ |
| 9 | 路由跳转 | 从首页正确跳转到页面 | ✅ |
| 10 | 返回导航 | 点击返回按钮回到首页 | ✅ |
五、自动化执行(Automate)
在编码执行阶段,我们按照原子化任务的顺序,逐一实现各模块。
5.1 Model 层实现
首先实现数据模型层。在 ArkTS 中,定义数据模型需要特别注意语法约束:
// 文件:AI营养餐单规划Model.etsexportclassAI营养餐单规划Data{// 所有字段在类声明中直接初始化,不在构造函数中声明daily_calories:string=''protein:string=''carbs:string=''fat:string=''macros:string=''meal_plan:string[]=[]meal:string=''items:string[]=[]food:string=''amount:string=''calories:string=''meal_calories:string=''shopping_list:string[]=[]category:string=''weekly_variation:string=''tips:string=''constructor(){// 构造函数中再次赋值,确保所有字段被正确初始化this.daily_calories=''this.protein=''this.carbs=''this.fat=''this.macros=''this.meal_plan=[]this.meal=''this.items=[]this.food=''this.amount=''this.calories=''this.meal_calories=''this.shopping_list=[]this.category=''this.weekly_variation=''this.tips=''}}关键实现细节:
在 ArkTS 中,类字段的初始化有一个重要的最佳实践:虽然字段声明时已经初始化,但仍然建议在构造函数中显式赋值。这是因为 ArkTS 编译器在某些场景下会对字段的初始化顺序有严格要求,双重初始化可以确保在任何情况下都不会出现访问未初始化字段的问题。
5.2 Service 层实现
Service 层是业务逻辑的核心,封装了数据生成的全部逻辑:
// 文件:AI营养餐单规划Service.etsimport{AI营养餐单规划Data}from'./AI营养餐单规划Model'exportclassAI营养餐单规划Service{privatemodel:AI营养餐单规划Dataconstructor(){this.model=newAI营养餐单规划Data()}generateData(input:Record<string,Object>):AI营养餐单规划Data{letresult:AI营养餐单规划Data=newAI营养餐单规划Data()// 从输入中提取目标值,安全转换为字符串letgoalVal:string=String(input['goal']||'')// 填充营养成分数据result.daily_calories='生成结果:'+goalVal result.macros='生成结果:'+goalVal// 填充餐单数据(数组类型)result.meal_plan=['示例数据1','示例数据2','示例数据3']// 填充购物清单result.shopping_list=['示例数据1','示例数据2','示例数据3']// 填充周变化建议result.weekly_variation='生成结果:'+goalVal// 填充饮食建议result.tips='生成结果:'+goalValreturnresult}}关于 Mock 数据的说明:
当前实现使用 Mock 数据来模拟 AI 大模型的输出。在实际生产环境中,Service 层将调用远端的大模型 API,通过精心设计的 Prompt 模板生成结构化的营养餐单数据。Mock 数据的设计