马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
💡 鸿蒙生态为开发者提供海量的HarmonyOS模板/组件,助力开发效率原地起飞 💡
★ 一键直达生态市场组件&模板市场 , 快速应用DevEco Studio插件市场集成组件&模板 ★
好用的菜谱APP能够帮助饮食管理事半功倍!
小编本期为大家介绍餐饮行业案例
👉 覆盖20+行业,本帖以汇总形式持续更新中,点击收藏!一键三连!常看常新!
【第4期】餐饮行业 · 美食菜谱
一、概述
1. 行业洞察
1)行业痛点:
- 传统餐饮私域流量缺失,依赖第三方平台导流,佣金本钱高且较难沉淀用户。
- 网络菜谱步骤描述模糊,用料配比不准确,乐成率低。
- 个性化不敷:缺乏根据用户口味偏好、饮食限制(素食/低糖/无麸质)的智能保举。
- 购物未便:菜谱食材无法一键购买,特别调料难以配齐。
- 数据代价未挖掘:用户烹饪行为数据未形成精准画像。
- 互动体验差:用户作品分享渠道单一,缺乏专业厨师点评指导。
2)行业常用三方SDK
分类
| 三方库名称
| 功能
| 支持情况
| SDK链接
| 媒体
| 阿里云视频播放器SDK
| 音视频
| 已支持
| 支付宝SDK
微信支付SDK
银联SDK
腾讯QQ SDK
新浪微博SDK
极光PUSH SDK
友盟移动统计SDK
腾讯微信SDK
高德地图SDK
个推
Bugly
ShareSDK
听云SDK
| 登录认证
| 中国移动一键登录SDK/易盾一键登录SDK/创蓝闪验/极光安全认证/阿里云号码认证SDK/中国电信一键登录SDK
| 登录
| 已支持
| 分享
| 友盟/ShareSDK/微信分享/QQ分享/新浪微博SDK/MobTech ShareSDK
| 统计/推送/分享
| 已支持
| 支付
| 支付宝支付/微信支付/银联支付
| 支付
| 已支持
| 数据分析
| 友盟移动统计SD/神策数据SDK
| 数据收集、处理、分析、运用
| 已支持
| 性能监控
| 腾讯Bugly SDK/听云SDK/岳鹰全景监控SDK
| 异常上报和运营统计
| 已支持
| 地图
| 高德地图SDK
| 地图
| 已支持
| 推送
| 个推/华为推送/极光PUSH/阿里推送SDK
| 消息推送
| 已支持
| 媒体
| 阿里云视频播放器SDK
| 音视频
| 已支持
| 说明:“以上三方库及链接仅为示例,三方库由三方开发者独立提供,以其官方内容为准”
2. 案例概览(下载模板)
基于以上行业分析,本期将介绍鸿蒙生态市场餐饮行业模板——美食菜谱应用模板,为行业提供常用功能的开发案例,涵盖分类搜刮、作品分享、菜谱用料、热量计算、饮食计划等多个实用功能。
- Stage开发模型 + 声明式UI开发范式。
- 分层架构设计 + 组件化拆分,支持开发者在开发时既可以选择完整使用模板,也可以根据需求单独选用此中的业务组件。
- 集成华为账号、支付等服务,只需做少量设置和定制即可快速实现华为账号的登录、菜谱上传等功能。
本模板紧张页面及核心功能如下所示:
二、应用架构设计
1. 分层模块化设计
- 产物定制层:专注于满足差别设备或使用场景的个性化需求,作为应用的入口,是用户直接互动的界面。
- 本实践暂时只支持直板机,为单HAP包形式,包罗路由根节点、底部导航栏等。
- 基础特性层:用于存放相对独立的功能UI和业务逻辑实现。
- 本实践的基础特性层将应用底部导航栏的每个选项拆分成一个独立的业务功能模块,包罗首页、分类、热量计算和我的。
- 每个功能模块都具备高内聚、低耦合、可定制的特点,支持产物的灵活摆设。
- 公共能力层:存放公共能力,包罗公共UI组件、数据管理、外部交互和工具库等共享功能。
- 本实践的公共能力层分为公共基础能力和可分可合组件,均打包为HAR包被上层业务组件引用。
- 公共基础能力包罗日志、文件处理等工具类,公共范例界说,网络库,以及弹窗、加载等公共组件。
- 可分可合组件将包罗行业特点、可完全自闭环的能力抽出独立的组件模块,支持开发者在开发中单独集成使用,详见业务组件设计章节。
2. 业务组件设计
为支持开发者单独获取特定场景的页面和功能,例如开发者已搭建了一个本身的美食菜谱元服务工程,只想单独取用本模板中的菜篮子或热量计算功能,本模板将功能完全自闭环的部门能力抽离出独立的行业组件模块,不依赖公共基础能力包,开发者可以单独集成,开箱即用,降低使用难度。
三、行业场景技能方案
1. 账号管理
1)场景说明
支持华为账号一键登录及其他方式(账号密码登录、微信登录)。
用户登录后展示昵称和头像,点击用户信息栏可进入用户主页,检察并编辑个人信息。
2)技能方案
- 华为账号一键登录
- 通过Account Kit实现华为账号一键登录,并获取用户手机号,关联应用已有用户。
- 微信登录
- 根据鸿蒙接入指南接入微信SDK,可通过跳转微信并获取微信用户授权进行登录。
- 头像修改
- 通过Scenario Fusion Kit提供的选择头像Button快速拉起头像选择页面,供用户完成华为账号头像或其他头像的选择与展示。
3)代码参考
2. 分类搜刮
1)场景说明
- 支持按菜谱分类展示和搜刮菜谱,点击菜谱可以检察菜谱详细信息。
2)技能方案
使用List和Grid组件实现分类列表的展示、一连滚动以及搜刮结果展示。
3)代码参考
3. 饮食计划
1)场景说明
支持制定饮食计划的食材,也可以自界说食材并填写热量。
2)技能方案
4. 热量计算
1)场景说明
支持检察当日饮食热量摄入情况,大概检察一周热量摄入统计。
2)技能方案
3)代码参考
四、模板代码
1. 工程结构(下载模板)
详细代码结构如下所示:2. 关键代码解读
本篇代码非应用的全量代码,只包罗应用的部门能力的关键代码。
若需获取全量代码,请检察模板集成章节。
1)个人信息
- javascript
- // components/aggregated_login/src/main/ets/components/LoginService.ets
- // 登录组件
- LoginWithHuaweiIDButton({
- params: {
- style: loginComponentManager.Style.BUTTON_CUSTOM,
- loginType: loginComponentManager.LoginType.QUICK_LOGIN,
- supportDarkMode: true,
- customButtonParams: {
- fontColor: loginComponentManager.FontColor.WHITE,
- backgroundColor: this.loginBtnBgColor,
- },
- },
- controller: this.controller,
- });
- ...
- // 登录方法控制器
- controller: loginComponentManager.LoginWithHuaweiIDButtonController =
- new loginComponentManager.LoginWithHuaweiIDButtonController()
- // 需要用户同意协议才能完成华为账号登录,请先设置协议状态为NOT_ACCEPTED,当用户同意协议后设置协议状态为ACCEPTED,才可以完成华为账号登录
- .setAgreementStatus(loginComponentManager.AgreementStatus.NOT_ACCEPTED)
- .onClickLoginWithHuaweiIDButton((error: BusinessError, response: loginComponentManager.HuaweiIDCredential) => {
- // 处理用户点击一键登录按钮逻辑,灰度传入undefined模拟流程,应用申请权限后,传入error
- this.handleLoginWithHuaweiIDButton(undefined, response);
- });
- ...
- // 处理点击一键登录后的方法
- handleLoginWithHuaweiIDButton(error: BusinessError | undefined,
- response: loginComponentManager.HuaweiIDCredential) {
- this.enableStatus = false;
- // if部分内容配置好可用的调试证书和client_id后再放开
- if (error) {
- Logger.error(this.domainId, this.logTag,
- `Failed to click LoginWithHuaweiIDButton. Code is ${error.code}, message is ${error.message}`);
- this.error = error;
- if (error.code === LoginErrorCode.ERROR_CODE_NETWORK_ERROR) {
- AlertDialog.show(
- {
- message: 'No Internet connection. Check your network settings. ',
- offset: { dx: 0, dy: -12 },
- alignment: DialogAlignment.Bottom,
- autoCancel: false,
- confirm: {
- value: 'OK',
- action: () => {
- },
- },
- },
- );
- } else if (error.code === LoginErrorCode.ERROR_CODE_AGREEMENT_STATUS_NOT_ACCEPTED) {
- // 未同意协议,弹出协议弹框,推荐使用该回调方式
- this.agreementDialog.open();
- this.customerDiaLogOpen = true;
- } else if (error.code === LoginErrorCode.ERROR_CODE_LOGIN_OUT) {
- // 华为账号未登录提示
- this.showToast($r('app.string.not_login_in'));
- } else if (error.code === LoginErrorCode.ERROR_CODE_NOT_SUPPORTED) {
- // 账号不支持该scopes或permissions提示
- this.showToast($r('app.string.scope_not_supported'));
- } else if (error.code === LoginErrorCode.ERROR_CODE_NOT_REQUIRED_SCOPE_OR_PERMISSION) {
- // 应用没有申请scope权限
- this.showToast($r('app.string.app_not_required_scopes_or_permissions'));
- } else {
- // 其他提示系统或服务异常
- this.showToast($r('app.string.service_error'));
- }
- this.enableStatus = true;
- return;
- }
- try {
- if (this.isSelected) {
- // 配置好可用的调试证书和client_id后需要处理response
- Logger.info(this.domainId, this.logTag, 'Succeed in clicking LoginWithHuaweiIDButton.');
- if (this.response.idToken !== undefined) {
- this.response = response;
- // 模拟登录成功后回调
- this.loginFinishedCb(true, this.unionID)
- }
- // 模拟登录成功后回调
- this.loginFinishedCb(false)
- } else {
- this.agreementDialog.open();
- this.customerDiaLogOpen = true;
- }
- } catch (e) {
- Logger.info(this.domainId, this.logTag,
- `Failed to LoginWithHuaweiIDButton, errCode: ${e.code}, errMessage: ${e.message}`);
- AlertDialog.show(
- {
- message: $r('app.string.service_error'),
- offset: { dx: 0, dy: -12 },
- alignment: DialogAlignment.Bottom,
- autoCancel: false,
- confirm: {
- value: 'OK',
- action: () => {
- },
- },
- },
- );
- } finally {
- this.enableStatus = true;
- }
- }
复制代码 2)分类搜刮
- javascript
- // components/link_category/src/main/ets/components/LinkCategory.ets
- // 列表页
- Row() {
- List({ space: 8, scroller: this.titleItemScroller }) {
- ForEach(this.recipeCategoryList, (item: RecipeCategory, index: number) => {
- ListItem() {
- this.leftListBuilder(item.name, index)
- }
- }, (item: RecipeCategory, index: number) => item.name + index)
- }
- .width(92)
- .height('100%')
- .backgroundColor('#F1F3F5')
- .listDirection(Axis.Vertical) // 排列方向
- .scrollBar(BarState.Off)
- .contentStartOffset(12)
- .contentEndOffset(12)
- List({ space: 12, scroller: this.scroller }) {
- ForEach(this.recipeCategoryList, (item: RecipeCategory) => {
- ListItemGroup({
- header: this.listTitleBuilder(item.name),
- space: 12,
- }) {
- ListItem() {
- Grid() {
- ForEach(item.recipeList, (listItem: RecipeBriefInfo) => {
- GridItem() {
- Column() {
- Image($r(`app.media.${listItem.thumbnail}`)).width(76).height(76).borderRadius(8)
- Text(listItem.title)
- .fontSize(14)
- .fontWeight(FontWeight.Medium)
- .fontColor($r('sys.color.font_primary'))
- .textAlign(TextAlign.Center)
- .constraintSize({ maxWidth: 76 })
- .maxLines(2)
- .margin({ top: 4 })
- .textOverflow({ overflow: TextOverflow.Ellipsis })
- }
- }.onClick(() => {
- this.onRecipeClick(listItem)
- })
- }, (listItem: RecipeBriefInfo) => `${item.id}${listItem.id}`)
- }
- .rowsGap(8)
- .columnsGap(8)
- .columnsTemplate('1fr 1fr 1fr')
- }
- }
- }, (item: RecipeCategory) => item.id.toString())
- }
- .layoutWeight(1)
- .height('100%')
- .margin({ left: 8, right: 16 })
- .scrollBar(BarState.Off)
- .sticky(StickyStyle.None)
- .contentStartOffset(12)
- .contentEndOffset(12)
- .onScrollIndex((start: number) => this.currentIndexChangeAction(start, false))
- }.layoutWeight(1)
- ...
- // 下标索引处理
- currentIndexChangeAction(index: number, isClassify: boolean): void {
- if (this.currentIndex !== index) {
- this.changeCurrentIndex(index);
- if (isClassify) {
- this.scroller.scrollToIndex(index);
- } else {
- this.titleItemScroller.scrollToIndex(index);
- }
- }
- }
复制代码 3)热量计算
- javascript
- // commons/lib_common/src/main/ets/utils/LoginUtils.ets
- // 环形组件
- Progress({ value: this.todayCalories, total: 2000, type: ProgressType.Ring })
- .width(176).style({ strokeWidth: 20 })
- .color(this.vm.gradientColor)
- ...
- // components/calorie_calculation/src/main/ets/viewModels/CaloriesSummaryVM.ets
- // 渐变色设置
- gradientColor: LinearGradient =
- new LinearGradient([{ color: '#C6F093', offset: 0.25 }, { color: '#83CE26', offset: 0.5 },
- { color: '#88DB23', offset: 0.85 }, { color: '#88DB24', offset: 1.0 }])
复制代码- javascript
- // components/calorie_calculation/src/main/ets/components/BarChart.ets
- // 柱状图参数设置
- this.name = this.xData[this.xData.length - 1]
- this.rate = this.seriesData[this.seriesData.length - 1]
- // Step1:必须:初始化图表配置构建类
- this.model = new BarChartModel();
- // Step2:配置图表指定样式,各部件间没有先后之分
- // 为图表添加数据选择的监听器
- this.model.setOnChartValueSelectedListener(this.valueSelectedListener);
- // 获取图表描述部件,设置图表描述部件不可用,即图表不进行绘制描述部件
- let description: Description | null = this.model.getDescription()
- if (description) {
- description.setEnabled(false);
- }
- // 获取图表图例部件,设置图表图例部件不可用
- let legend: Legend | null = this.model.getLegend();
- if (legend) {
- legend.setEnabled(false);
- }
- // 设置图表数据最大的绘制数,如果超过该数值,则不进行绘制图表的数值标签
- this.model.setMaxVisibleValueCount(7);
- // 为左Y轴设置LimitLine,可设置限制线的宽度,线段样式,限制标签的位置,标签字体大小等
- this.limitLine1 = new LimitLine(120, 'Upper Limit');
- this.limitLine1.setLineWidth(4);
- //设置虚线样式
- this.limitLine1.enableDashedLine(10, 10, 0);
- //设置标签位置
- this.limitLine1.setLabelPosition(LimitLabelPosition.RIGHT_TOP);
- this.limitLine1.setTextSize(10);
- this.limitLine2 = new LimitLine(50, 'Lower Limit');
- this.limitLine2.setLineWidth(4);
- this.limitLine2.enableDashedLine(10, 10, 0);
- this.limitLine2.setLineColor(Color.Yellow);
- this.limitLine2.setLabelPosition(LimitLabelPosition.RIGHT_BOTTOM);
- this.limitLine2.setTextSize(10);
- // 设置图表左Y轴信息
- this.leftAxis = this.model.getAxisLeft();
- if (this.leftAxis) {
- //设置绘制标签个数
- this.leftAxis.setLabelCount(7, false);
- //设置标签位置
- this.leftAxis.setPosition(YAxisLabelPosition.OUTSIDE_CHART)
- //设置距离顶部距离
- this.leftAxis.setSpaceTop(15);
- //设置最小值
- this.leftAxis.setAxisMinimum(0);
- //设置最大值
- this.leftAxis.setAxisMaximum(2000);
- this.leftAxis.setGridDashedLine({ dash: [2, 2, 0], offset: 0 })
- this.leftAxis.setTextColor('#E6000000')
- this.leftAxis.setTextSize(12)
- }
- // 设置图表右Y轴信息
- this.rightAxis = this.model.getAxisRight();
- if (this.rightAxis) {
- this.rightAxis.setEnabled(false);
- }
- class YAxisValueFormatter implements IAxisValueFormatter {
- getFormattedValue(value: number, axis: AxisBase): string {
- //将原本存在的对应的value转换成需要的字符串
- return value.toString();
- }
- }
- this.leftAxis?.setValueFormatter(new YAxisValueFormatter())
- // 设置X轴信息
- this.xAxis = this.model.getXAxis();
- if (this.xAxis) {
- this.xAxis.setPosition(XAxisPosition.BOTTOM);
- this.xAxis.setDrawGridLines(false);
- this.xAxis.setGranularity(1);
- this.xAxis.setLabelCount(this.xData.length);
- this.xAxis.setTextColor('#E6000000')
- this.xAxis.setTextSize(12)
- }
- class XAxisValueFormatter implements IAxisValueFormatter {
- data: string[] = []
- constructor(data: string[]) {
- this.data = data
- }
- getFormattedValue(value: number, axis: AxisBase): string {
- //将原本存在的对应的value转换成需要的字符串
- let day = new Date().getDay() - 1
- if (day === value) {
- return '今日'
- }
- return xMap[value];
- }
- }
- this.xAxis?.setValueFormatter(new XAxisValueFormatter(this.xData))
- // 生成图表数据
- let barData: BarData = this.getBarData();
- // 将数据与图表配置类绑定
- this.model.setData(barData);
- // 设置图表最大的X轴显示范围,如不设置,则默认显示全部数据
- this.model.setVisibleXRangeMaximum(20);
- ...
- // 柱状图组件
- BarChart({ model: this.model }).width('100%').height(190)
复制代码 3. 模板集成
本模板提供了两种代码集成方式,供开发者自由选用。
1)整体集成(下载模板)
开发者可以选择直接基于模板工程开发本身的应用工程。
- 模板代码获取:
- 打开模板工程,根据README说明中的快速入门章节,将本身的应用信息设置在模板工程内,即可运行并检察模板结果。
- 对接开发者本身的服务器接口,转换数据结构,展示真实的云侧数据。
将commons/lib_common/src/main/ets/httprequest/HttpRequestApi.ets文件中的mock接口更换为真实的服务器接口。
在commons/lib_common/src/main/ets/httprequest/HttpRequest.ets文件中将云侧开发者自界说的数据结构转换为端侧数据结构。
根据本身的业务内容修改模板,进行定制化开发。
2)按需集成
若开发者已搭建好本身的应用工程,但暂未实现此中的部门场景能力,可以选择取用此中的业务组件,集成在本身的工程中。
- 组件代码获取:
- 下载组件源码,根据README中的说明,将组件包设置在本身的工程中。
- 根据API参考和示例代码,将组件集成在本身的对应场景中。
以上是第四期“餐饮行业-美食菜谱”行业良好案例的内容,更多行业敬请等待~
欢迎下载使用行业模板“点击下载”,若您有体验和开发问题,大概迫不及待想相识XX行业的良好案例,欢迎在评论区留言,小编会快马加鞭为您解答~
👉 本系列持续更新,欢迎点击帖子末尾左下角“”收藏本帖!
期数
| 帖子
| 链接
| 第1期
| HarmonyOS官方模板良好案例 | 便捷生活行业 · 购物中心
| 点击检察
| 第2期
| HarmonyOS官方模板良好案例 | 消息行业 · 综合消息
| 点击检察
| 第3期
| HarmonyOS官方模板良好案例 | 教诲行业 · 教诲备考
| 点击检察
| 第4期
| HarmonyOS官方模板良好案例 | 餐饮行业 · 美食菜谱
| 点击检察
| 第5期
| HarmonyOS官方模板良好案例 | 工具行业 · 日历应用
| 点击检察
| 第6期
| 小编加急整理中,敬请等待
| | 👉 HarmonyOS组件模板干系保举
- 【活动ing】HarmonyOS组件/模板集成创新活动,报名时间截止2025年8月30日,点击检察
- 鸿蒙应用开发者激励计划2025,点击检察
|