HarmonyOS ArkTS 实战:校园食堂评价与美食推荐完整实现

摘要

项目难度:⭐⭐⭐ 中级实战
适用人群:有 ArkTS 基础、希望学习生活类应用开发的 HarmonyOS 开发者
开发环境:DevEco Studio Next / API 24+
代码规模:单页面约 700 行,可直接运行

通过本项目,你将掌握:

  • 星级评分组件的实现与交互设计
  • 评价系统的数据结构与排序算法
  • 菜品收藏与推荐机制的设计
  • 瀑布流布局与卡片视觉设计
  • 多维度筛选与排行榜功能实现

目录

  • [一、项目概述与功能架构]
    • [1.1 应用场景与项目价值]
    • [1.2 完整功能清单]
    • [1.3 技术选型说明]
  • [二、数据结构设计]
    • [2.1 菜品模型 Dish]
    • [2.2 评价模型 Comment]
    • [2.3 设计思路说明]
  • [三、核心功能实现详解]
    • [3.1 菜品浏览与筛选]
    • [3.2 星级评分与发表评价]
    • [3.3 收藏与推荐算法]
    • [3.4 食堂排行榜]
  • [四、UI 设计与交互体验]
    • [4.1 整体布局结构]
    • [4.2 主题色与视觉规范]
    • [4.3 状态视觉区分表]
  • [五、关键技术点解析]
    • [5.1 星级评分的交互设计考量]
    • [5.2 美食推荐算法的基础设计]
  • [六、常见问题与优化建议]
  • [七、项目总结与扩展方向]
  • [附录:运行方式]

一、项目概述与功能架构

1.1 应用场景与项目价值

"今天吃什么"是大学生每天都要面对的灵魂拷问。校园食堂窗口众多、菜品丰富,但质量参差不齐,新生不了解哪些好吃,老生想尝新又怕踩雷。食堂评价与美食推荐应用正是为了解决这个痛点。

本项目基于 HarmonyOS ArkTS 实现了一个校园食堂评价与美食推荐应用,整合了菜品打分评价、美食推荐、收藏菜品、食堂排行、热门窗口、吐槽反馈等功能,通过UGC评价体系帮助学生发现美食、避开雷区。

项目核心价值:

  1. 决策效率价值:看评分选菜,减少选择困难,降低踩雷概率
  2. 信息透明价值:建立公开评价体系,促进食堂提升菜品质量
  3. 社区互动价值:美食分享形成校园饮食文化,增加生活乐趣

1.2 完整功能清单

功能模块 具体功能 实现难度⭐
菜品浏览 菜品列表、食堂筛选、搜索查找、分类浏览 ⭐⭐
评价系统 星级评分、文字评价、点赞互动、评价列表 ⭐⭐⭐
收藏管理 收藏菜品、我的收藏、收藏分类、快速查找 ⭐⭐
排行榜 菜品排行、食堂排行、窗口排行、新晋热门 ⭐⭐⭐
推荐系统 每日推荐、猜你喜欢、新品推荐、高分推荐 ⭐⭐⭐
反馈互动 吐槽反馈、问题上报、点赞评论、分享美食 ⭐⭐

1.3 技术选型说明

技术维度 选型方案 选型理由
开发语言 ArkTS 强类型支持,适合评分、排序等数据处理
状态管理 @State 装饰器 轻量响应式,满足评价和收藏状态更新
布局方式 瀑布流/网格布局 适合菜品卡片展示,视觉效果好
数据存储 内存状态 演示简化,生产环境需对接后端服务
最低版本 API 24 兼容主流 HarmonyOS 设备

⚠️ 注意:本项目为前端演示版本,评价数据均为本地模拟。真实食堂评价平台需要运营审核机制,防止恶意差评和广告灌水。


二、数据结构设计

2.1 菜品模型 Dish

菜品是系统的核心实体,包含基本信息和评分数据。

/**
 * 食堂菜品数据模型
 */
interface Dish {
  id: number;            // 菜品ID
  name: string;          // 菜品名称
  canteen: string;       // 所属食堂
  window: string;        // 所属窗口
  price: number;         // 价格(元)
  score: number;         // 综合评分 0-5
  tags: string[];        // 标签:好吃/性价比高/分量足 等
  image: string;         // 菜品图片
  isCollected: boolean;  // 是否已收藏
  commentCount: number;  // 评价数量
}

2.2 评价模型 Comment

评价是用户对菜品的反馈,包含评分和文字内容。

/**
 * 菜品评价数据模型
 */
interface Comment {
  id: number;         // 评价ID
  dishId: number;     // 所属菜品ID
  userName: string;   // 评价用户
  score: number;      // 评分 1-5星
  content: string;    // 评价内容
  time: string;       // 评价时间
  likes: number;      // 点赞数
}

2.3 设计思路说明

为什么评分采用5星制?

5星评分是最经典也最符合用户习惯的评分体系:

  1. 认知成本低:几乎所有人都理解5星代表好,1星代表差
  2. 粒度适中:5个等级足够区分好坏,又不会因为选项太多让用户纠结
  3. 计算方便:平均分、加权分等统计都很直观
  4. 视觉友好:星星图标美观,交互反馈好

10分制太精细,3分制太粗糙,5星制是体验和精度的最佳平衡点。

关于标签系统的设计

标签是对评分的补充,提供更多维度的信息:

  • 口味维度:好吃、一般、难吃
  • 性价比维度:性价比高、有点贵、便宜
  • 分量维度:分量足、刚好、吃不饱
  • 其他:排队久、环境好、新品等

标签让评价信息更结构化,用户可以快速了解菜品的特点,而不只是一个干巴巴的分数。


三、核心功能实现详解

3.1 页面状态初始化

/**
 * 页面状态变量定义
 */
@State private commentContentText: string = '';  // 评价内容输入
@State private rating: number = 5;               // 当前评分(默认5星)
@State private selectedCanteen: string = '全部';  // 食堂筛选
@State private nextCommentId: number = 10;        // 下一条评价ID
@State private dishes: Dish[] = [];               // 菜品列表
@State private comments: Comment[] = [];          // 评价列表

3.2 菜品筛选与搜索

/**
 * 获取筛选后的菜品列表
 * 支持按食堂筛选和排序
 */
private getFilteredDishes(): Dish[] {
  let result = this.dishes;
  
  // 按食堂筛选
  if (this.selectedCanteen !== '全部') {
    result = result.filter(d => d.canteen === this.selectedCanteen);
  }
  
  // 按评分降序排序,高分在前
  return result.sort((a, b) => b.score - a.score);
}

/**
 * 切换收藏状态
 */
private toggleCollect(dishId: number): void {
  this.dishes = this.dishes.map(d => 
    d.id === dishId ? { ...d, isCollected: !d.isCollected } : d
  );
}

3.3 发表评价与星级评分

用户选择星级并填写评价内容后提交。

/**
 * 提交菜品评价
 * @param dishId 菜品ID
 */
private submitComment(dishId: number): void {
  const content = this.commentContentText.trim();
  if (content.length === 0) return;
  
  // 1. 创建新评价
  const comment: Comment = {
    id: this.nextCommentId,
    dishId: dishId,
    userName: '我',
    score: this.rating,
    content: content,
    time: new Date().toLocaleString(),
    likes: 0
  };
  
  this.comments = [comment, ...this.comments];
  this.nextCommentId++;
  
  // 2. 更新菜品的平均评分和评价数
  this.updateDishScore(dishId);
  
  // 3. 清空输入
  this.commentContentText = '';
  this.rating = 5;
}

/**
 * 重新计算菜品平均评分
 * 简化版:取所有评价的平均分
 */
private updateDishScore(dishId: number): void {
  const dishComments = this.comments.filter(c => c.dishId === dishId);
  if (dishComments.length === 0) return;
  
  const totalScore = dishComments.reduce((sum, c) => sum + c.score, 0);
  const avgScore = Math.round((totalScore / dishComments.length) * 10) / 10;
  
  this.dishes = this.dishes.map(d => 
    d.id === dishId ? { 
      ...d, 
      score: avgScore, 
      commentCount: dishComments.length 
    } : d
  );
}

设计要点解析:

  • 实时更新平均分:提交评价后立即重新计算菜品平均分,保证数据一致性
  • 保留一位小数:评分精度到0.1分,既精确又不会太琐碎
  • 评价数同步更新:评价数量也是重要参考指标,避免只有1个5分就排第一

3.4 评价点赞功能

/**
 * 给评价点赞
 */
private likeComment(commentId: number): void {
  this.comments = this.comments.map(c => 
    c.id === commentId ? { ...c, likes: c.likes + 1 } : c
  );
}

/**
 * 获取某菜品的热门评价
 * 按点赞数排序,取前3条
 */
private getTopComments(dishId: number): Comment[] {
  return this.comments
    .filter(c => c.dishId === dishId)
    .sort((a, b) => b.likes - a.likes)
    .slice(0, 3);
}

3.5 食堂排行榜

/**
 * 计算各食堂的平均评分
 * 生成食堂排行榜
 */
private getCanteenRanking() {
  const canteenMap = new Map<string, { total: number; count: number }>();
  
  this.dishes.forEach(d => {
    if (!canteenMap.has(d.canteen)) {
      canteenMap.set(d.canteen, { total: 0, count: 0 });
    }
    const data = canteenMap.get(d.canteen)!;
    data.total += d.score;
    data.count++;
  });
  
  const ranking: { name: string; avgScore: number }[] = [];
  canteenMap.forEach((value, key) => {
    ranking.push({
      name: key,
      avgScore: Math.round((value.total / value.count) * 10) / 10
    });
  });
  
  // 按平均分降序
  return ranking.sort((a, b) => b.avgScore - a.avgScore);
}

四、UI 设计与交互体验

4.1 整体布局结构

┌─────────────────────────┐
│     数据统计栏           │  ← 收录菜品/我的收藏/已评价/今日推荐
├─────────────────────────┤
│     搜索栏 + 食堂筛选     │  ← 搜索 + 一食堂/二食堂 切换
├─────────────────────────┤
│     Tab 切换栏           │  ← 推荐 / 排行榜 / 我的收藏
├─────────────────────────┤
│                         │
│     菜品瀑布流           │  ← 菜品卡片 + 评分 + 价格
│                         │
└─────────────────────────┘

4.2 主题色与视觉规范

主色调:玫瑰红 #F43F5E

选择玫瑰红作为主题色的设计考量:

  1. 美食属性联想:玫瑰红/玫红色与美食、食欲有着天然的视觉关联,令人联想到美味的食物,激发用户探索美食的兴趣
  2. 热情活力调性:玫红色传递热情、活力、愉悦的情绪,与"发现美食、分享快乐"的产品定位高度契合
  3. 视觉吸引力强:高饱和度的红色系在视觉上非常醒目,能够快速抓住用户注意力,适合推荐和热门标记
  4. 层次感丰富:从浅粉到深红的色阶变化丰富,可以用于评分高低、热门程度等不同层级的视觉区分

辅助色规范:

  • 主色调:#F43F5E(玫瑰红)
  • 高分菜品:#F43F5E(红色高亮推荐)
  • 中等评分:#F59E0B(琥珀色)
  • 低分菜品:#6B7280(灰色)
  • 价格标签:#1F2937(深灰加粗)
  • 收藏高亮:#F59E0B(金色星星)

4.3 状态视觉区分表

评分等级 星星颜色 文字颜色 推荐标签 心理暗示
4.5-5分 全金色星星 玫瑰红 强烈推荐 必吃美食
4.0-4.4分 金色星星 深橙 推荐 值得一试
3.5-3.9分 半金半灰 琥珀 还行 可以尝试
3.0-3.4分 灰色星星 灰色 一般 谨慎选择
3分以下 全灰星星 深灰 不推荐 建议避雷
收藏状态 图标样式 视觉表现 交互反馈
未收藏 空心星星 灰色 点击填充金色
已收藏 实心星星 金色 点击变空心

五、关键技术点解析

5.1 星级评分的交互设计考量

星级评分看似简单,实际上有很多交互细节影响用户体验。

交互设计要点:

  1. 实时预览:手指滑到第几颗星,星星就实时点亮到第几颗,给用户即时反馈
  2. 点击区域:每颗星的点击区域要比视觉图标大,方便手指点击
  3. 半星支持:可选支持0.5星精度,提供更精细的评分粒度
  4. 取消评分:再次点击当前星级可以取消,回到未评分状态
  5. 文字辅助:可以配合"很差/一般/好/很好/非常好"等文字提示

常见的评分偏差问题:

  • 分数膨胀:大多数人都打4-5分,导致区分度不高
  • 极端评价:特别好或特别差才会评价,中间的不评价
  • 恶意差评:竞争对手或情绪性的不合理低分

解决方案:增加评价审核、加权计算、异常检测等机制。

5.2 美食推荐算法的基础设计

推荐系统是美食应用的核心竞争力,从简单到复杂有多个层级。

推荐算法演进路径:

算法级别 实现方式 推荐效果 开发难度
L1 基础 按评分排序推荐 一般
L2 标签 基于标签的相似推荐 中等
L3 协同过滤 基于用户行为的协同过滤 较好
L4 深度学习 深度学习个性化推荐 很好 很高

本项目采用的简化推荐策略:

  1. 热门推荐:评分高 + 评价数多的菜品,质量有保障
  2. 新品推荐:最近新增的菜品,鼓励尝鲜
  3. 收藏相似:根据用户收藏的菜品,推荐同食堂同类型的菜品

对于校园场景,简单的规则推荐已经能满足基本需求,开发成本低效果也不错。


六、常见问题与优化建议

踩坑点 1:评分水军刷分

问题表现:有人恶意刷高分或恶意刷低分,影响评分公正性
解决方案:增加评价审核机制,限制单人评价次数,异常评分加权处理

踩坑点 2:菜品信息不准确

问题表现:窗口换了菜品、价格变了,信息更新不及时
解决方案:建立用户纠错机制,允许用户上报信息变更,运营审核后更新

踩坑点 3:评价内容质量低

问题表现:很多评价只有"好吃""一般"几个字,参考价值不大
解决方案:引导用户填写结构化评价(口味、分量、性价比等维度),奖励优质评价

踩坑点 4:搜索匹配度差

问题表现:搜索"红烧肉"搜不到"红烧五花肉"
解决方案:增加同义词和模糊匹配,支持拼音搜索,优化搜索算法

优化方向

  1. 增加菜品图片上传功能,用户评价时可以配图
  2. 实现实时排队人数显示,帮助学生错峰就餐
  3. 增加营养成分信息,提供健康饮食建议
  4. 接入每日菜单更新,提前知道今天有什么菜

七、项目总结与扩展方向

核心收获

通过完成食堂评价与美食推荐项目,你将掌握:

  • 星级评分组件的完整交互实现
  • 评价系统的数据结构与排序算法
  • 瀑布流布局的卡片视觉设计
  • 基础推荐系统的设计思路

后续扩展功能

  • 📸 图片评价:评价可以上传图片,有图有真相
  • 👥 排队人数:实时显示各食堂窗口排队情况,错峰就餐
  • 🥗 营养成分:展示菜品热量和营养,健康饮食
  • 📋 每日菜单:每日更新菜单,提前知道今天吃什么
  • 🛒 外卖点餐:在线点餐,送到宿舍楼下
  • 🏆 美食榜单:周榜月榜年榜,发现校园美食天花板

运行效果

36-校园食堂评价与美食推荐应用

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐