HarmonyOS ArkTS 实战:实现一个校园食堂菜品评价与打卡应用
项目效果
本文使用 HarmonyOS 和 ArkTS 实现一个校园食堂菜品评价与打卡应用。
应用可以记录校园食堂菜品、窗口、价格、菜品类别和评分,并提供推荐菜品、修改评分、状态筛选、平均评分统计和删除记录等功能。
项目使用 DevEco Studio 开发,适配 API 23 及以上版本。
功能介绍
本项目实现了以下功能:
- 添加校园食堂菜品记录
- 填写菜品名称和食堂窗口
- 填写菜品价格和评分
- 选择主食套餐、风味小吃、早餐面点和健康轻食
- 推荐高分菜品
- 取消推荐菜品
- 修改菜品评分
- 筛选高分推荐、强烈推荐和待评价菜品
- 统计打卡菜品数量、推荐数量和平均评分
- 删除菜品记录
定义数据结构
首先定义菜品记录的数据结构:
interfaceFoodRecord{id:number;dishName:string;windowName:string;price:number;score:number;category:string;status:string;}字段说明如下:
id:菜品记录的唯一编号dishName:菜品名称windowName:食堂窗口名称price:菜品价格score:菜品评分category:菜品分类status:打卡和推荐状态
初始化页面状态
使用@State保存输入内容、菜品分类和筛选条件:
@StateprivatedishText:string='';@StateprivatewindowText:string='';@StateprivatepriceText:string='';@StateprivatescoreText:string='';@Stateprivatecategory:string='主食套餐';@StateprivatefilterType:string='全部';@StateprivatenextId:number=6;准备一些初始数据,让应用运行后可以直接展示完整效果:
@Stateprivaterecords:FoodRecord[]=[{id:1,dishName:'番茄牛腩饭',windowName:'一食堂 3 号窗口',price:12,score:5,category:'主食套餐',status:'强烈推荐'},{id:2,dishName:'麻辣香锅',windowName:'二食堂风味窗口',price:16,score:4,category:'风味小吃',status:'已打卡'},{id:3,dishName:'鸡蛋灌饼',windowName:'南区食堂早餐档',price:6,score:4,category:'早餐面点',status:'已打卡'},{id:4,dishName:'轻食鸡胸肉沙拉',windowName:'图书馆轻食站',price:18,score:5,category:'健康轻食',status:'强烈推荐'}];添加美食记录
用户填写菜品名称、窗口、价格和评分后,可以新增一条美食打卡记录:
privateaddRecord():void{constdishName:string=this.dishText.trim();constwindowName:string=this.windowText.trim();constprice:number=Number(this.priceText);constscore:number=Number(this.scoreText);if(dishName.length===0||windowName.length===0||Number.isNaN(price)||price<0||Number.isNaN(score)||score<1||score>5){return;}constrecord:FoodRecord={id:this.nextId,dishName,windowName,price,score,category:this.category,status:'已打卡'};this.records=[record,...this.records];this.nextId+=1;this.dishText='';this.windowText='';this.priceText='';this.scoreText='';}评分范围限定在 1 到 5 分,避免录入无效数据。
推荐和取消推荐菜品
用户可以将喜欢的菜品标记为“强烈推荐”:
privatetoggleRecommend(id:number):void{this.records=this.records.map((item:FoodRecord)=>{if(item.id===id){conststatus:string=item.status==='强烈推荐'?'已打卡':'强烈推荐';return{id:item.id,dishName:item.dishName,windowName:item.windowName,price:item.price,score:item.score,category:item.category,status};}returnitem;});}再次点击按钮后,状态会从“强烈推荐”恢复为“已打卡”。
修改菜品评分
点击“修改评分”后,评分会循环增加:
privateaddScore(id:number):void{this.records=this.records.map((item:FoodRecord)=>{if(item.id===id){constscore:number=item.score>=5?1:item.score+1;return{id:item.id,dishName:item.dishName,windowName:item.windowName,price:item.price,score,category:item.category,status:item.status==='待评价'?'已打卡':item.status};}returnitem;});}评分达到 5 分后,再次点击会回到 1 分,方便在预览页面中演示评分变化。
筛选美食记录
页面支持按高分推荐、强烈推荐和待评价筛选:
privategetFilteredRecords():FoodRecord[]{if(this.filterType==='高分推荐'){returnthis.records.filter((item:FoodRecord)=>item.score>=4);}if(this.filterType==='强烈推荐'){returnthis.records.filter((item:FoodRecord)=>item.status==='强烈推荐');}if(this.filterType==='待评价'){returnthis.records.filter((item:FoodRecord)=>item.status==='待评价');}returnthis.records;}筛选按钮可以封装为一个自定义组件:
@BuilderFilterButton(text:string){Button(text).height(34).layoutWeight(1).fontSize(12).fontColor(this.filterType===text?Color.White:'#344054').backgroundColor(this.filterType===text?'#EA580C':'#E8EEF7').borderRadius(8).onClick(()=>{this.filterType=text;});}计算平均评分
统计全部菜品的平均评分:
privategetAverageScore():string{if(this.records.length===0){return'0.0';}lettotal:number=0;this.records.forEach((item:FoodRecord)=>{total+=item.score;});return(total/this.records.length).toFixed(1);}toFixed(1)可以让平均分保留一位小数。
统计推荐菜品
统计指定状态的菜品数量:
privategetCount(status:string):number{returnthis.records.filter((item:FoodRecord)=>item.status===status).length;}顶部统计区域展示打卡菜品数量、强烈推荐数量和待评价数量:
this.StatCard('打卡菜品',`${this.records.length}`,'#EA580C','#FFF7ED');this.StatCard('强烈推荐',`${this.getCount('强烈推荐')}`,'#059669','#ECFDF3');this.StatCard('待评价',`${this.getCount('待评价')}`,'#667085','#F2F4F7');设置菜品分类颜色
不同菜品分类使用不同颜色:
privategetCategoryColor(category:string):ResourceColor{if(category==='主食套餐'){return'#D97706';}if(category==='风味小吃'){return'#D92D20';}if(category==='早餐面点'){return'#2563EB';}return'#059669';}颜色含义如下:
- 橙色:主食套餐
- 红色:风味小吃
- 蓝色:早餐面点
- 绿色:健康轻食
- 深橙色:页面主题色
删除菜品记录
不再需要的菜品记录可以从列表中删除:
privatedeleteRecord(id:number):void{this.records=this.records.filter((item:FoodRecord)=>item.id!==id);}删除后,菜品列表和平均评分会自动更新。
使用列表展示菜品
使用List和ForEach渲染筛选后的菜品:
List({space:10}){ForEach(this.getFilteredRecords(),(item:FoodRecord)=>{ListItem(){this.FoodCard(item)}},(item:FoodRecord)=>item.id.toString());}.width('100%').layoutWeight(1).scrollBar(BarState.Off);每条菜品记录使用独立卡片展示,卡片中包含菜品名称、窗口、价格、评分、分类、推荐状态和操作按钮。
页面设计说明
应用使用暖橙色作为主题色,符合食堂和美食打卡场景。
页面主要分为以下区域:
- 顶部标题和平均评分区域
- 菜品打卡统计区域
- 新美食记录添加区域
- 菜品筛选区域
- 今日食堂推荐列表
页面采用浅灰色背景和白色卡片,价格使用红色强调,评分和推荐状态使用不同颜色展示。
SDK 配置
本项目使用 HarmonyOS API 24,满足 API 23 及以上要求:
{ "name": "default", "compatibleSdkVersion": "6.1.1(24)", "runtimeOS": "HarmonyOS", "targetSdkVersion": "6.1.1(24)", "compileSdkVersion": "6.1.1(24)" }entry 模块中的运行系统也要保持一致:
{ "apiType": "stageMode", "targets": [ { "name": "default", "runtimeOS": "HarmonyOS" } ] }运行项目
使用 DevEco Studio 打开项目,然后找到:
entry/src/main/ets/pages/Index.ets等待项目同步完成,点击右侧的Preview按钮即可查看应用效果。
项目总结
本文使用 HarmonyOS 和 ArkTS 实现了一个校园食堂菜品评价与打卡应用。
项目实现了菜品登记、类别选择、评分录入、推荐切换、评分修改、状态筛选、平均分统计和删除等功能。
通过这个项目可以掌握:
- ArkTS 接口定义
@State状态管理TextInput输入组件- 数值输入校验
List和ForEach列表渲染map和filter数组操作- 数组统计计算
- 自定义
@Builder组件 - HarmonyOS 页面布局
后续还可以加入菜品图片、食堂地图、评论内容、收藏功能、每周菜品榜单和本地数据持久化等功能。