【推薦+1】HarmonyOS官方模板優(yōu)秀案例(第4期:餐飲行業(yè) ·?美食菜譜)

0 評論 1618 瀏覽 0 收藏 52 分鐘

?? 鴻蒙生態(tài)為開發(fā)者提供海量的HarmonyOS模板/組件,助力開發(fā)效率原地起飛 ??

★ 一鍵直達生態(tài)市場組件&模板市場?, 快速應用DevEco Studio插件市場集成組件&模板?★

好用的菜譜APP能夠幫助飲食管理事半功倍!小編本期為大家介紹餐飲行業(yè)案例

?? 覆蓋20+行業(yè),本帖以匯總形式持續(xù)更新中,點擊收藏!一鍵三連!??闯P拢?/p>

 

【第4期】餐飲行業(yè) ·?美食菜譜

一、概述

1、行業(yè)洞察

行業(yè)痛點:

傳統(tǒng)餐飲私域流量缺失,依賴第三方平臺導流,傭金成本高且較難沉淀用戶。

網(wǎng)絡菜譜步驟描述模糊,用料配比不精確,成功率低。

個性化不足:缺乏根據(jù)用戶口味偏好、飲食限制(素食/低糖/無麩質(zhì))的智能推薦。

購物不便:菜譜食材無法一鍵購買,特殊調(diào)料難以配齊。

數(shù)據(jù)價值未挖掘:用戶烹飪行為數(shù)據(jù)未形成精準畫像。

互動體驗差:用戶作品分享渠道單一,缺乏專業(yè)廚師點評指導。

行業(yè)常用三方SDK

SDK鏈接:支付寶SDK、微信支付SDK、銀聯(lián)SDK、騰訊QQ SDK、新浪微博SDK極光PUSH SDK、友盟移動統(tǒng)計SDK騰訊微信SDK、高德地圖SDK個推、BuglyShareSDK、聽云SDK

說明:“以上三方庫及鏈接僅為示例,三方庫由三方開發(fā)者獨立提供,以其官方內(nèi)容為準”

 

2、案例概覽(下載模板

基于以上行業(yè)分析,本期將介紹鴻蒙生態(tài)市場餐飲行業(yè)模板——美食菜譜應用模板,為行業(yè)提供常用功能的開發(fā)案例,涵蓋分類搜索、作品分享、菜譜用料、熱量計算、飲食計劃等多個實用功能。

  • Stage開發(fā)模型 + 聲明式UI開發(fā)范式。
  • 分層架構(gòu)設計 + 組件化拆分,支持開發(fā)者在開發(fā)時既可以選擇完整使用模板,也可以根據(jù)需求單獨選用其中的業(yè)務組件。
  • 集成華為賬號、支付等服務,只需做少量配置和定制即可快速實現(xiàn)華為賬號的登錄、菜譜上傳等功能。

本模板主要頁面及核心功能如下所示

二、應用架構(gòu)設計

1、分層模塊化設計

產(chǎn)品定制層:專注于滿足不同設備或使用場景的個性化需求,作為應用的入口,是用戶直接互動的界面。

本實踐暫時只支持直板機,為單HAP包形式,包含路由根節(jié)點、底部導航欄等。

基礎(chǔ)特性層:用于存放相對獨立的功能UI和業(yè)務邏輯實現(xiàn)。

本實踐的基礎(chǔ)特性層將應用底部導航欄的每個選項拆分成一個獨立的業(yè)務功能模塊,包含首頁、分類、熱量計算和我的。

每個功能模塊都具備高內(nèi)聚、低耦合、可定制的特點,支持產(chǎn)品的靈活部署。

公共能力層:存放公共能力,包括公共UI組件、數(shù)據(jù)管理、外部交互和工具庫等共享功能。

本實踐的公共能力層分為公共基礎(chǔ)能力和可分可合組件,均打包為HAR包被上層業(yè)務組件引用。

公共基礎(chǔ)能力包含日志、文件處理等工具類,公共類型定義,網(wǎng)絡庫,以及彈窗、加載等公共組件。

可分可合組件將包含行業(yè)特點、可完全自閉環(huán)的能力抽出獨立的組件模塊,支持開發(fā)者在開發(fā)中單獨集成使用,詳見業(yè)務組件設計章節(jié)。

2、業(yè)務組件設計

為支持開發(fā)者單獨獲取特定場景的頁面和功能,例如開發(fā)者已搭建了一個自己的美食菜譜元服務工程,只想單獨取用本模板中的菜籃子或熱量計算功能,本模板將功能完全自閉環(huán)的部分能力抽離出獨立的行業(yè)組件模塊,不依賴公共基礎(chǔ)能力包,開發(fā)者可以單獨集成,開箱即用,降低使用難度。

三、行業(yè)場景技術(shù)方案

1、賬號管理

場景說明

支持華為賬號一鍵登錄及其他方式(賬號密碼登錄、微信登錄)。

用戶登錄后展示昵稱和頭像,點擊用戶信息欄可進入用戶主頁,查看并編輯個人信息。

技術(shù)方案

華為賬號一鍵登錄

通過Account Kit實現(xiàn)華為賬號一鍵登錄,并獲取用戶手機號,關(guān)聯(lián)應用已有用戶。

微信登錄

根據(jù)鴻蒙接入指南接入微信SDK,可通過跳轉(zhuǎn)微信并獲取微信用戶授權(quán)進行登錄。

頭像修改

通過Scenario Fusion Kit提供的選擇頭像Button快速拉起頭像選擇頁面,供用戶完成華為賬號頭像或其他頭像的選擇與展示。

代碼參考

部分核心代碼參見個人信息實現(xiàn)章節(jié)。

2、分類搜索

  • 場景說明
    • 支持按菜譜分類展示和搜索菜譜,點擊菜譜可以查看菜譜詳細信息。

技術(shù)方案

使用ListGrid組件實現(xiàn)分類列表的展示、連續(xù)滾動以及搜索結(jié)果展示。

代碼參考

部分核心代碼參見分類搜索實現(xiàn)章節(jié)。

3、飲食計劃

場景說明

支持制定飲食計劃的食材,也可以自定義食材并填寫熱量。

技術(shù)方案

列表展示

使用ListListItemGroup實現(xiàn)列表的連續(xù)滾動,并快速滾動到指定分類。

自定義添加食物

使用bindSheet方法對當前頁面綁定半模態(tài)彈框,實現(xiàn)自定義食物的添加。

4、熱量計算

場景說明

支持查看當日飲食熱量攝入情況,或者查看一周熱量攝入統(tǒng)計。

技術(shù)方案

使用Progress繪制環(huán)形數(shù)據(jù)統(tǒng)計,使用LinearGradient實現(xiàn)環(huán)形顏色的漸變效果。

使用三方庫@ohos/mpchart繪制柱狀圖,展示一周熱量攝入信息。

代碼參考

部分核心代碼參見熱量計算實現(xiàn)章節(jié)。

四、模板代碼

1、工程結(jié)構(gòu)下載模板

詳細代碼結(jié)構(gòu)如下所示:

Recipes

├─commons/commonlib/src/main

│ ?├─ets

│ ?│ ?├─components

│ ?│ ?│ ?????BaseHeader.ets ????????????????// 一級頁面標題組件

│ ?│ ?│ ?????BuildTitleBar.ets ?????????????// 二級頁面標題組件

│ ?│ ?│ ?????HeaderMenuBuilder.ets ?????????// 標題菜單內(nèi)容組件

│ ?│ ?│ ?????MenuItemBuilder.ets ???????????// 下拉菜單選項

│ ?│ ?├─constants

│ ?│ ?│ ?????CommonContants.ets ????????????// 公共常量

│ ?│ ?│ ?????CommonEnums.ets ???????????????// 公共枚舉值

│ ?│ ?├─types

│ ?│ ?│ ?????Types.ets ?????????????????????// 公共抽象類

│ ?│ ?└─utils

│ ?│ ????????AccountUtil.ets ???????????????// 賬號工具類

│ ?│ ????????DialogUtil.ets ????????????????// 彈窗工具類

│ ?│ ????????FormatUtil.ets ????????????????// 格式化工具類

│ ?│ ????????Logger.ets ????????????????????// 日志工具類

│ ?│ ????????PermissionUtil.ets ????????????// 權(quán)限獲取工具類

│ ?│ ????????PreferenceUtil.ets ????????????// 數(shù)據(jù)持久化工具類

│ ?│ ????????RouterModule.ets ??????????????// 路由工具類

│ ?│ ????????WindowUtil.ets ????????????????// 窗口管理工具類

│ ?└─resources

├─commons/network/src/main

│ ?├─ets

│ ?│ ?├─apis

│ ?│ ?│ ?????APIList.ets ???????????????????// 網(wǎng)絡請求API

│ ?│ ?│ ?????HttpRequest.ets ???????????????// 網(wǎng)絡請求

│ ?│ ?├─mocks

│ ?│ ?│ ?└─MockData

│ ?│ ?│ ????????Calories.ets ???????????????// 熱量mock數(shù)據(jù)

│ ?│ ?│ ????????Mine.ets ???????????????????// 我的mock數(shù)據(jù)

│ ?│ ?│ ????????Notice.ets ?????????????????// 通知mock數(shù)據(jù)

│ ?│ ?│ ????????RecipeList.ets ?????????????// 菜譜mock數(shù)據(jù)

│ ?│ ?│ ?????AxiosMock.ets ?????????????????// mock請求

│ ?│ ?│ ?????RequestMock.ets ???????????????// mock API

│ ?│ ?└─types

│ ?│ ????????Calories.ets ??????????????????// 熱量抽象類

│ ?│ ????????Member.ets ????????????????????// 會員抽象類

│ ?│ ????????Notice.ets ????????????????????// 通知抽象類

│ ?│ ????????Recipe.ets ????????????????????// 菜譜抽象類

│ ?└─resources

│─components/aggregated_ads/src/main

│ ?├─ets

│ ?│ ?├─common

│ ?│ ?│ ?????Constant.ets ??????????????????// 常量類

│ ?│ ?├─components

│ ?│ ?│ ?????AdServicePage.ets ?????????????// 廣告服務組件

│ ?│ ?│ ?????HwAdService.ets ???????????????// 華為廣告

│ ?│ ?├─util

│ ?│ ?│ ?????UIUtil.ets ????????????????????// UI工具類

│ ?│ ?└─viewmodel

│ ?│ ????????AggreagetedAdVM.ets ???????????// 廣告頁面數(shù)據(jù)模型

│ ?└─resources

│─components/aggregated_login/src/main

│ ?├─ets

│ ?│ ?├─common

│ ?│ ?│ ?????Constant.ets ??????????????????// 常量類

│ ?│ ?│ ?????Logger.ets ????????????????????// 日志類

│ ?│ ?├─components

│ ?│ ?│ ?????AgreementDialog.ets ???????????// 協(xié)議彈窗組件

│ ?│ ?│ ?????LoginService.ets ??????????????// 登錄組件

│ ?│ ?├─model

│ ?│ ?│ ?????Index.ets ?????????????????????// 數(shù)據(jù)類型

│ ?│ ?│ ?????WXApiWrap.ets ?????????????????// 微信登錄數(shù)據(jù)類型

│ ?│ ?└─viewmodel

│ ?│ ????????AggregatedLoginVM.ets ?????????// 登錄組件數(shù)據(jù)模型

│ ?└─resources

│─components/aggregated_payment/src/main

│ ?├─ets

│ ?│ ?├─common

│ ?│ ?│ ?????Constant.ets ??????????????????// 常量類

│ ?│ ?├─components

│ ?│ ?│ ?????AggregatedPaymentPicker.ets ???// 支付組件

│ ?│ ?├─model

│ ?│ ?│ ?????Index.ets ?????????????????????// 數(shù)據(jù)類型

│ ?│ ?│ ?????WXApiWrap.ets ?????????????????// 微信支付數(shù)據(jù)類型

│ ?│ ?└─viewmodel

│ ?│ ????????AggregatedPaymentVM.ets ???????// 支付組件數(shù)據(jù)模型

│ ?└─resources

│─components/base_ui/src/main

│ ?├─ets

│ ?│ ?├─components

│ ?│ ?│ ?????BaseTabs.ets ??????????????????// Tabs組件

│ ?│ ?└──types

│ ?│ ????????Index.ets ?????????????????????// 數(shù)據(jù)類型

│ ?└─resources

│─components/calorie_calculation/src/main

│ ?├─ets

│ ?│ ?├─components

│ ?│ ?│ ?????BarChart.ets ??????????????????// 協(xié)議彈窗組件

│ ?│ ?│ ?????CalorieCalculation.ets ????????// 熱量計算組件

│ ?│ ?│ ?????CaloriesSummary.ets ???????????// 熱量匯總組件

│ ?│ ?│ ?????FoodDiary.ets ?????????????????// 飲食計劃組件

│ ?│ ?├─types

│ ?│ ?│ ?????Index.ets ?????????????????????// 數(shù)據(jù)類型

│ ?│ ?└─viewModels

│ ?│ ????????CaloriesSummaryVM.ets ?????????// 熱量計算數(shù)據(jù)模型

│ ?└─resources

│─components/featured_recipes/src/main

│ ?├─ets

│ ?│ ?├─components

│ ?│ ?│ ?????FeaturedRecipes.ets ???????????// 菜譜瀑布流組件

│ ?│ ?│ ?????RecommendedCard.ets ???????????// 菜譜卡片

│ ?│ ?│─types

│ ?│ ?│ ?????Index.ets ?????????????????????// 數(shù)據(jù)類型

│ ?│ ?└─utils

│ ?│ ????????LazyDataSource.ets ????????????// 懶加載對象

│ ?│ ????????Logger.ets ????????????????????// 日志工具

│ ?│ ????????ObservedArray.ets ?????????????// 數(shù)組監(jiān)聽工具

│ ?└─resources

│─components/home_search/src/main

│ ?├─ets

│ ?│ ?├─components

│ ?│ ?│ ?????HomeSearch.ets ????????????????// 搜索組件

│ ?│ ?│ ?????SearchKeys.ets ????????????????// 熱搜詞組件

│ ?│ ?│ ?????SearchResult.ets ??????????????// 搜索結(jié)果組件

│ ?│ ?└─types

│ ?│ ????????Index.ets ?????????????????????// 數(shù)據(jù)類型

│ ?└─resources

│─components/link_category/src/main

│ ?├─ets

│ ?│ ?├─components

│ ?│ ?│ ?????LinkCategory.ets ??????????????// 分類列表組件

│ ?│ ?└─types

│ ?│ ????????Index.ets ?????????????????????// 數(shù)據(jù)類型

│ ?└─resources

│─components/personal_homepage/src/main

│ ?├─ets

│ ?│ ?├─components

│ ?│ ?│ ?????BloggerInfomation.ets ?????????// 個人介紹組件

│ ?│ ?│ ?????PersonalHomepage.ets ??????????// 個人中心組件

│ ?│ ?└─types

│ ?│ ????????Index.ets ?????????????????????// 數(shù)據(jù)類型

│ ?└─resources

│─components/shopping_basket/src/main

│ ?├─ets

│ ?│ ?├─components

│ ?│ ?│ ?????IngredientList.ets ????????????// 用料列表

│ ?│ ?│ ?????PurchaseIngredients.ets ???????// 用料組件

│ ?│ ?│ ?????ShoppingBasket.ets ????????????// 菜籃子組件

│ ?│ ?└─types

│ ?│ ????????Index.ets ?????????????????????// 數(shù)據(jù)類型

│ ?└─resources

│─components/upload_recipe/src/main

│ ?├─ets

│ ?│ ?├─components

│ ?│ ?│ ?????UploadRecipe.ets ??????????????// 上傳菜譜組件

│ ?│ ?├─types

│ ?│ ?│ ?????Index.ets ?????????????????????// 數(shù)據(jù)類型

│ ?│ ?└─viewmodel

│ ?│ ????????UploadRecipeVM.ets ????????????// 上傳菜譜數(shù)據(jù)模型

│ ?└─resources

│─features/calories/src/main

│ ?├─ets

│ ?│ ?├─pages

│ ?│ ?│ ?????CaloriesPage.ets ??????????????// 熱量頁面

│ ?│ ?│ ?????DietPlanPage.ets ??????????????// 飲食計劃食物列表頁面

│ ?│ ?│ ?????SearchFoodPage.ets ????????????// 食物搜索頁面

│ ?│ ?├─types

│ ?│ ?│ ?????Index.ets ?????????????????????// 數(shù)據(jù)對象

│ ?│ ?└─viewModels

│ ?│ ????????CaloriesPageVM.ets ????????????// 熱量頁面數(shù)據(jù)模型

│ ?│ ????????DietPlanPageVM.ets ????????????// 食物列表頁面數(shù)據(jù)模型

│ ?│ ????????SearchFoodPageVM.ets ??????????// 食物搜索頁面數(shù)據(jù)模型

│ ?└─resources

│─features/classification/src/main

│ ?├─ets

│ ?│ ?├─constants

│ ?│ ?│ ?????Enums.ets ?????????????????????// 枚舉數(shù)據(jù)

│ ?│ ?├─pages

│ ?│ ?│ ?????ClassificationPage.ets ????????// 分類頁面

│ ?│ ?│ ?????DishesPage.ets ????????????????// 菜譜詳情頁面

│ ?│ ?│ ?????ShoppingBasketPage.ets ????????// 菜籃子頁面

│ ?│ ?├─types

│ ?│ ?│ ?????Index.ets ?????????????????????// 菜譜數(shù)據(jù)對象

│ ?│ ?└─viewModels

│ ?│ ????????ClassificationVM.ets ??????????// 分類頁面數(shù)據(jù)模型

│ ?│ ????????DishesVM.ets ??????????????????// 菜譜詳情頁面數(shù)據(jù)模型

│ ?└─resources

│─features/home/src/main

│ ?├─ets

│ ?│ ?├─pages

│ ?│ ?│ ?????BloggerProfilePage.ets ????????// 博主信息頁面

│ ?│ ?│ ?????FollowersPage.ets ?????????????// 博主關(guān)注頁面

│ ?│ ?│ ?????HomePage.ets ??????????????????// 首頁頁面

│ ?│ ?│ ?????SearchPage.ets ????????????????// 搜索頁面

│ ?│ ?├─types

│ ?│ ?│ ?????Index.ets ?????????????????????// 首頁數(shù)據(jù)對象

│ ?│ ?└─viewModels

│ ?│ ????????BloggerProfilePageVM.ets ??????// 博主信息頁面數(shù)據(jù)模型

│ ?│ ????????FollowersPageVM.ets ???????????// 博主關(guān)注頁面數(shù)據(jù)模型

│ ?│ ????????HomePageVM.ets ????????????????// 首頁頁面數(shù)據(jù)模型

│ ?│ ????????SearchPageVM.ets ??????????????// 搜索頁面數(shù)據(jù)模型

│─features/mine/src/main

│ ?├─ets

│ ?│ ?├─components

│ ?│ ?│ ?????ConfirmDialogComponent.ets ????// 確認彈窗組件

│ ?│ ?│ ?????Recipes.ets ???????????????????// 菜譜卡片組件

│ ?│ ?├─mapper

│ ?│ ?│ ?????Index.ets ?????????????????????// 數(shù)據(jù)映射

│ ?│ ?├─model

│ ?│ ?│ ?????Index.ets ?????????????????????// 數(shù)據(jù)類型

│ ?│ ?├─pages

│ ?│ ?│ ?????BrowsingHistory.ets ???????????// 瀏覽歷史頁面

│ ?│ ?│ ?????MemberCenterPage.ets ??????????// 會員中心頁面

│ ?│ ?│ ?????MinePage.ets ??????????????????// 我的頁面

│ ?│ ?│ ?????MyCollection.ets ??????????????// 我的收藏頁面

│ ?│ ?│ ?????NoticeCenterPage.ets ??????????// 通知中心頁面

│ ?│ ?│ ?????NoticeDetailPage.ets ??????????// 通知詳情頁面

│ ?│ ?│ ?????PersonalInfo.ets ??????????????// 個人信息頁面

│ ?│ ?│ ?????PrivacyPolicyDetailPage.ets ???// 用戶協(xié)議頁面

│ ?│ ?│ ?????QuickLoginPage.ets ????????????// 一鍵登錄頁面

│ ?│ ?│ ?????SettingsPage.ets ??????????????// 設置頁面

│ ?│ ?│ ?????SideBarPage.ets ???????????????// 服務菜單頁面

│ ?│ ?│ ?????TermsOfServicePage.ets ????????// 隱私政策頁面

│ ?│ ?│ ?????UploadRecipe.ets ??????????????// 上傳菜譜頁面

│ ?│ ?├─types

│ ?│ ?│ ?????Index.ets ?????????????????????// 抽象類

│ ?│ ?├─util

│ ?│ ?│ ?????MockApi.ets ???????????????????// 支付mock數(shù)據(jù)

│ ?│ ?│ ?????OrderInfoUtil.ets ?????????????// 支付mock參數(shù)工具

│ ?│ ?│ ?????SignUtils.ets ?????????????????// 支付mock簽名工具

│ ?│ ?└─viewModels

│ ?│ ????????BrowsingHistoryVM.ets ?????????// 瀏覽歷史頁面數(shù)據(jù)模型

│ ?│ ????????MemberCenterPageVM.ets ????????// 會員中心頁面數(shù)據(jù)模型

│ ?│ ????????MinePageVM.ets ????????????????// 我的頁面數(shù)據(jù)模型

│ ?│ ????????MyCollectionVM.ets ????????????// 我的收藏頁面數(shù)據(jù)模型

│ ?│ ????????MyRecipeVM.ets ????????????????// 我的菜譜頁面數(shù)據(jù)模型

│ ?│ ????????NoticeCenterPageVM.ets ????????// 通知中心頁面數(shù)據(jù)模型

│ ?│ ????????SettingsPageVM.ets ????????????// 設置頁面數(shù)據(jù)模型

│ ?│ ????????UploadRecipeVM.ets ????????????// 上傳菜譜頁面數(shù)據(jù)模型

│ ?└─resources

└─products/entry/src/main

├─ets

│ ?├─entryability

│ ?│ ?????EntryAbility.ets ??????????????// 應用程序入口

│ ?├─entryformability

│ ?│ ?????EntryFormAbility.ets ??????????// 卡片程序入口

│ ?├─pages

│ ?│ ?????Index.ets ?????????????????????// 入口頁面

│ ?│ ?????LaunchAdPage.ets ??????????????// 廣告頁面

│ ?│ ?????LaunchPage.ets ????????????????// 開屏頁面

│ ?│ ?????MainEntry.ets ?????????????????// 主頁面

│ ?│ ?????PrivacyPolicyPage.ets ?????????// 隱私協(xié)議頁面

│ ?├─types

│ ?│ ?????Types.ets ?????????????????????// 抽象類

│ ?├─viewModels

│ ?│ ?????MainEntryVM.ets ???????????????// 入口頁面數(shù)據(jù)

│ ?└─widget/pages

│ ????????WidgetCard.ets ????????????????// 卡片頁面

└─resources

?

2、關(guān)鍵代碼解讀

本篇代碼非應用的全量代碼,只包括應用的部分能力的關(guān)鍵代碼。

若需獲取全量代碼,請查看模板集成章節(jié)。

個人信息

華為賬號一鍵登錄

?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()

// 需要用戶同意協(xié)議才能完成華為賬號登錄,請先設置協(xié)議狀態(tài)為NOT_ACCEPTED,當用戶同意協(xié)議后設置協(xié)議狀態(tài)為ACCEPTED,才可以完成華為賬號登錄

????.setAgreementStatus(loginComponentManager.AgreementStatus.NOT_ACCEPTED)

????.onClickLoginWithHuaweiIDButton((error: BusinessError, response: loginComponentManager.HuaweiIDCredential) => {

????// 處理用戶點擊一鍵登錄按鈕邏輯,灰度傳入undefined模擬流程,應用申請權(quán)限后,傳入error

????this.handleLoginWithHuaweiIDButton(undefined, response);

});

?

...

?

// 處理點擊一鍵登錄后的方法

handleLoginWithHuaweiIDButton(error: BusinessError | undefined,

??????????????????????????????response: loginComponentManager.HuaweiIDCredential) {

????this.enableStatus = false;

????// if部分內(nèi)容配置好可用的調(diào)試證書和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) {

????????????// 未同意協(xié)議,彈出協(xié)議彈框,推薦使用該回調(diào)方式

????????????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權(quán)限

????????????this.showToast($r('app.string.app_not_required_scopes_or_permissions'));

????????} else {

????????????// 其他提示系統(tǒng)或服務異常

????????????this.showToast($r('app.string.service_error'));

????????}

????????this.enableStatus = true;

????????return;

????}

????try {

????????if (this.isSelected) {

????????????// 配置好可用的調(diào)試證書和client_id后需要處理response

????????????Logger.info(this.domainId, this.logTag, 'Succeed in clicking LoginWithHuaweiIDButton.');

????????????if (this.response.idToken !== undefined) {

????????????????this.response = response;

????????????????// 模擬登錄成功后回調(diào)

????????????????this.loginFinishedCb(true, this.unionID)

????????????}

????????????// 模擬登錄成功后回調(diào)

????????????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;

????}

}

分類搜索

分類列表

?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);

????????}

????}

}

熱量計算

環(huán)形圖

javascript

// commons/lib_common/src/main/ets/utils/LoginUtils.ets

// 環(huán)形組件

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

// 柱狀圖參數(shù)設置

this.name = this.xData[this.xData.length - 1]

this.rate = this.seriesData[this.seriesData.length - 1]

// Step1:必須:初始化圖表配置構(gòu)建類

this.model = new BarChartModel();

?

// Step2:配置圖表指定樣式,各部件間沒有先后之分

?

// 為圖表添加數(shù)據(jù)選擇的監(jiān)聽器

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);

}

?

// 設置圖表數(shù)據(jù)最大的繪制數(shù),如果超過該數(shù)值,則不進行繪制圖表的數(shù)值標簽

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) {

????//設置繪制標簽個數(shù)

????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轉(zhuǎn)換成需要的字符串

????????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轉(zhuǎn)換成需要的字符串

????????let day = new Date().getDay() - 1

????????if (day === value) {

????????????return '今日'

????????}

????????return xMap[value];

????}

}

?

this.xAxis?.setValueFormatter(new XAxisValueFormatter(this.xData))

// 生成圖表數(shù)據(jù)

let barData: BarData = this.getBarData();

// 將數(shù)據(jù)與圖表配置類綁定

this.model.setData(barData);

// 設置圖表最大的X軸顯示范圍,如不設置,則默認顯示全部數(shù)據(jù)

this.model.setVisibleXRangeMaximum(20);

?

...

?

// 柱狀圖組件

BarChart({ model: this.model }).width('100%').height(190)

3、模板集成

本模板提供了兩種代碼集成方式,供開發(fā)者自由選用。

整體集成下載模板

開發(fā)者可以選擇直接基于模板工程開發(fā)自己的應用工程。

模板代碼獲取:

通過IDE插件創(chuàng)建模板工程,開發(fā)指導。

通過生態(tài)市場下載源碼,下載模板

通過開源倉訪問源碼,倉庫地址。

打開模板工程,根據(jù)README說明中的快速入門章節(jié),將自己的應用信息配置在模板工程內(nèi),即可運行并查看模板效果。

對接開發(fā)者自己的服務器接口,轉(zhuǎn)換數(shù)據(jù)結(jié)構(gòu),展示真實的云側(cè)數(shù)據(jù)。

將commons/lib_common/src/main/ets/httprequest/HttpRequestApi.ets文件中的mock接口替換為真實的服務器接口。

在commons/lib_common/src/main/ets/httprequest/HttpRequest.ets文件中將云側(cè)開發(fā)者自定義的數(shù)據(jù)結(jié)構(gòu)轉(zhuǎn)換為端側(cè)數(shù)據(jù)結(jié)構(gòu)。

根據(jù)自己的業(yè)務內(nèi)容修改模板,進行定制化開發(fā)。

按需集成

若開發(fā)者已搭建好自己的應用工程,但暫未實現(xiàn)其中的部分場景能力,可以選擇取用其中的業(yè)務組件,集成在自己的工程中。

組件代碼獲?。?/strong>

通過IDE插件下載組件源碼。開發(fā)指導

通過生態(tài)市場下載組件源碼。下載地址

下載組件源碼,根據(jù)README中的說明,將組件包配置在自己的工程中。

根據(jù)API參考和示例代碼,將組件集成在自己的對應場景中。

 

以上是第四期“餐飲行業(yè)-美食菜譜”行業(yè)優(yōu)秀案例的內(nèi)容,更多行業(yè)敬請期待~

歡迎下載使用行業(yè)模板“點擊下載”,若您有體驗和開發(fā)問題,或者迫不及待想了解XX行業(yè)的優(yōu)秀案例,歡迎在評論區(qū)留言,小編會快馬加鞭為您解答~

同時誠邀您添加下方二維碼加入“組件模板活動社群”,精彩上新&活動不錯過!

?? 系列持續(xù)更新,歡迎收藏本帖!

HarmonyOS官方模板優(yōu)秀案例 | 便捷生活行業(yè) · 購物中心-點擊查看

HarmonyOS官方模板優(yōu)秀案例 | 新聞行業(yè) · 綜合新聞-點擊查看

HarmonyOS官方模板優(yōu)秀案例 | 教育行業(yè) · 教育備考-點擊查看

HarmonyOS官方模板優(yōu)秀案例 | 餐飲行業(yè) · 美食菜譜-點擊查看

HarmonyOS官方模板優(yōu)秀案例 | 工具行業(yè) · 日歷應用-點擊查看

?? HarmonyOS組件模板相關(guān)推薦

  • 【活動ing】HarmonyOS組件/模板集成創(chuàng)新活動,報名時間截止2025年8月30日,點擊查看
  • 鴻蒙應用開發(fā)者激勵計劃2025,點擊查看
更多精彩內(nèi)容,請關(guān)注人人都是產(chǎn)品經(jīng)理微信公眾號或下載App
評論
評論請登錄
  1. 目前還沒評論,等你發(fā)揮!