写点什么

【宝藏贴】HarmonyOS 官方模板优秀案例 (第 1 期:便捷生活 · 购物中心)

  • 2025-07-28
    北京
  • 本文字数:3401 字

    阅读完需:约 11 分钟

【宝藏贴】HarmonyOS官方模板优秀案例
(第1期:便捷生活 · 购物中心)

🚀🚀🚀🚀

鸿蒙生态为开发者提供海量的 HarmonyOS 模板/组件,助力开发效率原地起飞

★一键直达生态市场组件&模板市场 , 快速应用DevEco Studio插件市场集成组件&模板 ★

如何通过行业模板,快速高效完成项目开发?

HarmonyOS 官方模板优秀案例,带您找到答案!

👉覆盖 20+行业,本帖下方以汇总形式持续更新中,点击收藏!一键三连!常看常新!

 

【第 1 期】便捷生活行业· 购物中心

一、 概述

1. 行业洞察

1) 行业痛点:

  • 传统零售流量缺失,依赖第三方平台导流,佣金成本高且较难沉淀用户;

  • 离场排队缴费耗时、找车难、支付流程复杂是用户最大的“离场焦虑”;

  • 传统积分体系感知弱、兑换门槛高、缺乏即时激励,导致会员活跃度低;

  • 传统服务链接割裂(App、小程序、收银系统独立),用户需在不同平台跳转,体验碎片化;

  • 低频使用的独立 App 极易被用户遗忘删除;公众号/小程序需主动打开,入口深且触达率低。


2) 行业常用三方 SDK

SDK 链接:

支付宝 SDK 微信支付 SDK 银联 SDK 极光 SDK 同盾SDK

神策数据 SDK 腾讯微信 SDK 高德地图 百度地图 腾讯地图定位 高德地图定位 穿山甲广告 SDK 广点通广告SDK 友盟SDK 听云 SDK 声网 agoraSDK

腾讯浏览器服务 SDK 字节跳动火山引擎增长营销套件 SDK


2. 优秀案例概览(下载模板

购物中心元服务模板是基于以上行业分析实现的参考,为行业元服务提供了常用功能的开发样例,涵盖停车缴费、自助积分、店铺导购、个人钱包、券包等多个实用场景。

  • Stage 开发模型 + 声明式 UI 开发范式

  • 分层架构设计+ 组件化拆分,支持开发者在开发时既可以选择完整使用模板,也可以根据需求单独选用其中的业务组件。

  • 集成华为账号、支付等服务,只需做少量配置和定制即可快速实现华为账号的登录、停车缴费等功能。

基于本模板构建的【XX 购物中心】元服务已正式发布上线,开发者反馈模板高度适配业务需求,显著提升了团队开发效率。


 

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

 

二、 应用架构设计

1. 分层模块化设计

  • 产品定制层:专注于满足不同设备或使用场景的个性化需求,作为应用的入口,是用户直接互动的界面。

① 本实践暂时只支持直板机,为单 HAP 包形式,包含路由根节点、底部导航栏等。

  • 基础特性层:用于存放相对独立的功能 UI 和业务逻辑实现。

① 本实践的基础特性层将应用底部导航栏的每个选项拆分成一个独立的业务功能模块,包含首页和我的。

② 每个功能模块都具备高内聚、低耦合、可定制的特点,支持产品的灵活部署。

  • 公共能力层:存放公共能力,包括公共 UI 组件、数据管理、外部交互和工具库等共享功能。

① 本实践的公共能力层分为公共基础能力和可分可合组件,均打包为 HAR 包被上层业务组件引用。

② 公共基础能力包含日志、文件处理等工具类,公共类型定义,网络库,以及弹窗、加载等公共组件。

③ 可分可合组件将包含行业特点、可完全自闭环的能力抽出独立的组件模块,支持开发者在开发中单独集成使用,详见业务组件设计章节

本模板整体工程共分为 7 个包:

  • 产品定制层

① phone HAP 包,手机设备的主入口模块

  • 基础特性层

① business_home HSP 包,首页场景

② business_mine HSP 包,我的场景

  • 公共能力层

① lib_common HAR 包,封装全局工具方法及公共组件

② module_coupon HAR 包,优惠券组件

③ module_keyboard HAR 包,车牌键盘组件

④ module_points HAR 包,自助积分组件

详细工程结构可见工程结构章节


2. 业务组件设计

为支持开发者单独获取特定场景的页面和功能,例如开发者已搭建了一个自己的购物中心元服务工程,只想单独取用本模板中的优惠券或积分功能,本模板将功能完全自闭环的部分能力抽离出独立的行业组件模块,不依赖公共基础能力包,开发者可以单独集成,开箱即用,降低使用难度。

 

三、 行业场景技术方案

1. 账号管理

1) 场景说明

元服务打开后无需用户手动登录,通过静默登录后展示默认头像和默认昵称。

用户可自行选择点击关联账号按钮获取华为账号关联手机号,可将静默登录账号与用户历史注册账号关联,同步用户历史数据资产,例如头像、昵称、生日等。


2) 技术方案

  • 静默登录

① 通过 Account Kit 实现元服务静默登录

  • 手机号获取

① 通过 Scenario Fusion Kit 的快速验证手机号Button,向用户发起手机号授权申请;

② 经用户同意后,根据获取到的 Authorization Code,以及元服务服务器使用 Client ID、Client Secret 实现服务端开发


2. 停车缴费

1) 场景说明

点击车牌号输入框拉起自定义键盘,根据车牌的位数展示省份、市区编号、车牌等自定义内容。

点击新增车牌支持存储常用车牌。

 

2) 技术方案

  • 特殊键盘绑定

通过 TextInput 组件的customKeyboard属性,传入自定义 UI,实现特殊键盘和输入框的关联。

  • 常用车牌存储:

将车牌输入能力封装成独立组件,通过bindSheet方法对当前页面绑定半模态弹框,并复用车牌输入组件。


3. 会员积分

1) 场景说明

用户在商场内消费后,可通过扫描小票二维码或拍摄小票照片等方式提交自助积分申请。

 

2) 技术方案

  • 本模板使用 Scan Kit 提供的默认界面扫码能力,实现系统级体验一致的扫码界面以及相册扫码入口。开发者也可以通过自定义界面扫码实现更定制化的界面样式和功能。

  • 使用 Media Library Kit 提供的特定接口安全Picker拉起系统图库,用户可以自行选择相册内资源或拍摄照片,开发者通过获取到的图片 uri 进行后续的分享、上传等操作。


四、 模板代码

1. 工程结构(下载模板

详细代码结构如下所示:

ShoppingMall

├─commons                           

 └─lib_common/src/main/ets

      ├─components  

        ├── AlertDialog.ets                          //警告对话框

        ├── AsWebRichText.ets                        //富文本编辑器

        ├── CallTelSheet.ets                         //电话呼叫

        ├── EmptyComp.ets                            //空白组件

        ├── LoadingDialog.ets                        //加载组件

        ├── LoginComp.ets                            //登录组件

        ├── NavHeaderBar.ets                         //页面导航栏头部组件               

        ├── PageHeaderComp.ets                       //页面标题组件

        └── SheetHeaderComp.ets                      //半模态标题组件

              

      ├─constants         

        ├── Common.ets                               //通用常量

        └── RouterMap.ets                            //路由表常量             

                         

      ├─httprequest    

        ├── AxiosHttp.ets                            // axios二次封装                   

        ├── AxiomRequest.ets                         //创建请求实例          

        ├── HttpRequest.ets                          //业务接口封装                   

        └── HttpRequestApi.ets                       //业务接口定义

      

      ├─mock/MockData.ets                              // mock数据

        

      ├─models

        ├── ParamsModel.ets                          //接口参数模型          

        ├── RequestModel.ets                         //接口请求模型

        ├── ResponseModel.ets                        //接口响应模型          

        ├── RouterModel.ets                          //路由跳转模型                   

        ├── StorageModel.ets                         //状态变量模型          

        └── TabBarModel.ets                          // Tab模型                    

              

      ├─utils

        ├── EmitUtils.ets                            //全局事件方法类

        ├── FileUtils.ets                            //文件处理方法类          

        ├── FormatUtils.ets                          //格式化方法类

        ├── GlobalUtils.ets                          //全局变量类          

        ├── Logger.ets                               //日志类

        ├── LoginUtils.ets                           //登录方法          

        ├── RouterUtil.ets                           //路由管理类      

        └── Utils.ets                                //通用方法     

      

      └─viewmodels/BaseViewModel.ets                   //基础viewmodel抽象类

├─components

 ├── module_coupon                                     //优惠券组件                     

 ├── module_keyboard                                   //车牌键盘组件

 └── module_points                                     //自助积分组件            

     

├─features

 ├─business_home/src/main/ets                          //首页模块             

    ├─components

      ├── AddPlateComp.ets                         //添加车牌组件

      └── GuideListComp.ets                        //指南列表组件                  

    ├─constants

      └── Constants.ets                            //常量定义             

    ├─pages

      ├── ConsiderateServicePage.ets               //尊享服务页面

      ├── FindCarPage.ets                          //寻车页面

      ├── FindCarResultPage.ets                    //寻车结果页面

      ├── ParkingPaymentPage.ets                   //停车缴费入口页面

      ├── PayDetailPage.ets                        //支付详情页

      ├── PayRecordPage.ets                        //缴费记录页面

      ├── PaySuccessPage.ets                       //支付成功页面

      ├── PlateNumberMgtPage.ets                   //车牌管理页面

      ├── PlateNumberPage.ets                      //停车缴费页面

      ├── ServiceDetailPage.ets                    //贴心服务二级页面

      ├── StoreGuideDetailPage.ets                 //店铺详情页面

      ├── StoreGuidePage.ets                       //店铺导航页面

      └── WebPage.ets                              //网页页面                  

    └─viewmodel

        ├── PayDetailViewModel.ets                   //支付详情视图模型

        ├── PayRecordViewModel.ets                   //缴费记录视图模型

        ├── PaySuccessViewModel.ets                  //支付成功视图模型

        ├── ServiceDetailViewModel.ets               //服务详细视图模型

        ├── StoreGuideDetailViewModel.ets            //店铺指南详细视图模型

        └── StoreGuideViewModel.ets                  //店铺指南视图模型      

 

 └─business_mine/src/main/ets                         //我的模块             

      ├──components

        ├── MenuComp.ets                            //菜单组件

        └── UserInfoComp.ets                        //用户信息组件

      ├──constants

        └── WalletConstants.ets                     //钱包常量

      ├──pages

        ├── MembershipManualPage.ets                //成员手册页面

        ├── MembershipPage.ets                      //成员页面

        ├── MinePage.ets                            //我的页面

        ├── MyCouponsPage.ets                       //我的优惠券页面

        ├── MyWalletPage.ets                        //我的钱包页面

        ├── PrivacyPage.ets                         //隐私政策页面

        ├── RechargeWalletPage.ets                  //充值钱包页面

        ├── SettingPage.ets                         //设置页面

        └── UserInfoPage.ets                        //用户信息页面

      └──viewmodel               

          ├── MinePageViewModel.ets                   //我的页面视图模型

          ├── MyWalletViewModel.ets                   //我的钱包页面视图模型

          ├── RechargeWalletViewModel.ets             //充值钱包页面视图模型

          ├── SettingPageViewModel.ets                //设置页面视图模型

          └── UserInfoViewModel.ets                   //用户信息页面视图模型

└─products

   └─entry/src/main/ets                

        ├── common/Constants.ets                        //常量定义

        ├── components/CustomTabBar.ets                 //自定义标签栏组件      

        ├── entryability/EntryAbility.ets               //主入口能力

        ├── entryformability/EntryFormAbility.ets       //表单主入口能力

        ├── pages

          ├── HomePage.ets                            //首页

          ├── Index.ets                               //入口页面

          ├── IndexPage.ets                           // Tab页面        

          └── IntroducePage.ets                       //商场介绍页面

        ├── utils/WidgetUtil.ets                        //卡片工具类

        ├── viewModels/IndexViewModel.ets               // Tab页面ViewModel      

        └── widget/pages/WidgetCard.ets                 //服务卡片        

 

2. 关键代码解读

1) 静默登录及手机号关联

  • 代码使用效果

① 当系统华为账号未登录时,打开本元服务模板,静默登录不成功,自动拉起系统半模态弹窗提示登录/注册华为账号;

② 当系统华为账号已登录时,打开本元服务模板,静默登录成功,显示“华为用户”;

③ 用户可以选择点击关联账号,将静默登录账号与已注册账号关联,为用户同步历史数据资产。注意若要完整体验该功能,对应包名的元服务需要完成对应开发前提工作

  • 核心代码实现

① 通过 AccountKit 实现静默登录。

// products/phone/src/main/ets/viewmodel/IndexViewModel.ets

private loginWithHuaweiID(): Promise<HuaweiIDResp> {

    return new Promise((resolve, reject) => {

      //创建静默登录请求

      let loginRequest = new authentication.HuaweiIDProvider().createLoginWithHuaweiIDRequest();

      loginRequest.forceLogin = false;

      let controller = new authentication.AuthenticationController();

      controller.executeRequest(loginRequest).then((data) => {

        let loginWithHuaweiIDResponse = data as authentication.LoginWithHuaweiIDResponse;

        let authCode = loginWithHuaweiIDResponse.data?.authorizationCode;

        let openId = loginWithHuaweiIDResponse.data?.openID;

        let unionId = loginWithHuaweiIDResponse.data?.unionID;

        //静默登录成功,返回账号相关的ID数据

        resolve({ openId, unionId, authCode } as HuaweiIDResp);

      }).catch((error: BusinessError) => {

        Logger.error(TAG, 'loginWithHuaweiID error: ' + JSON.stringify(error));

      }).finally(() => {

        //静默登录失败,返回空值

        resolve({

          openId: '',

          unionId: '',

          authCode: '',

        } as HuaweiIDResp);

      });

    });

  }

 

② 使用 Scenario Fusion Kit 的快速验证手机号Button请求云侧获取手机号需要的 authCode。

// commons/lib_common/src/main/ets/components/LoginComp.ets

FunctionalButton({

  params: {

    openType: functionalButtonComponentManager.OpenType.GET_PHONE_NUMBER,

    label: '',

    styleOption: {

      styleConfig: new functionalButtonComponentManager

        .ButtonConfig()

        .size({ width: 48, height: 48 })

        .borderRadius(24)

        .backgroundImage($r('app.media.ic_tab_code_pass'))

        .backgroundImageSize(ImageSize.Cover)

    },

  },

  controller: new functionalButtonComponentManager.FunctionalButtonController()

    .onGetPhoneNumber((err, data) => {

      if (err) {

        //使用该方法的元服务未获取scope权限时,使用mock账户返回结果。获取权限参考上一节【代码使用效果】的第三步【开发前提工作】

        LoginUtils.onBindFail(this.callback);

        return;

      }

      LoginUtils.onBindSuccess(data.code || '', this.callback);

    }),

})

 

③ 端侧使用获取到的 auth_code 调用接口,云侧参考服务端开发获取用户的手机号信息后,端侧将号码与登录用户进行关联,并持久化存储到本地。

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

export class LoginUtils {

  /**

   *关联成功

   * @param code

   * @param callback

   */

  static onBindSuccess(code: string, callback?: () => void) {

    HttpRequestApi.getOpenLoginHm(encodeURIComponent(code)).then((res) => {

      if (res.code === HttpCode.SUCCESS) {

        let tel = res.data.userTel ?? ''

        let userInfo: UserInfoModel = AppStorageV2.connect(UserInfoModel, () => new UserInfoModel())!;

        userInfo.userInfo.userTel = `${tel.substring(0, tel.length - 8)}****${tel.substring(tel.length - 4)}`

        userInfo.isRelative = true

        if (callback) {

          callback();

        }

      } else {

        promptAction.showToast({ message: '账号关联失败,请重试~' })

      }

    }).catch(() => {

      promptAction.showToast({ message: '账号关联失败' })

    }).finally(() => {

      LoadingDialogUtil.close()

    })

  };

}

 

2) 动态服务卡片

  • 代码使用效果

① 将停车服务卡片加桌后,可显示剩余车位和用户积分(当前为纯端模拟数据);

② 点击卡片刷新按钮将刷新剩余车位数,并实时同步给元服务内停车缴费页面;

③ 在元服务内缴费消耗积分后,最新剩余积分实时同步给桌面卡片。

  • 核心代码实现

① 通过 commonEventManager 公共事件管理实现卡片事件的注册和实时通信。

import { preferences } from '@kit.ArkData';

import { BusinessError, commonEventManager } from '@kit.BasicServicesKit';

import { formBindingData, formProvider } from '@kit.FormKit';

import { Logger } from 'lib_common';

import { CardManager } from 'module_points';

 

const TAG = '[WidgetUtil]';

 

export class WidgetUtil {

  // ...

  private static readonly _formClickEventName: string = 'form_click_event_name';

 

  //发布卡片按钮点击事件

  public static publishFormClick(formId: string) {

    commonEventManager.publish(

      WidgetUtil._formClickEventName,

      { data: formId },

      (err: BusinessError) => {

        if (err) {

          Logger.error(

            TAG,

            `Failed to publish form_click_event_name. Code is ${err.code}, message is ${err.message}`,

          );

        } else {

          Logger.info(TAG, 'Succeeded in publishing form_click_event_name.');

        }

      },

    );

  }

 

  //订阅卡片按钮点击事件

  public static async subscribeFormClick(ctx: Context) {

    let subscriber: commonEventManager.CommonEventSubscriber | undefined =

      undefined;

    let subscribeInfo: commonEventManager.CommonEventSubscribeInfo = {

      events: [WidgetUtil._formClickEventName],

      publisherPermission: '',

    };

    commonEventManager.createSubscriber(subscribeInfo, (err1, data1) => {

      if (data1) {

        subscriber = data1;

        //订阅公共事件回调

        commonEventManager.subscribe(subscriber, async (err2, data2) => {

          if (data2) {

            Logger.info(TAG, 'Succeeded in creating subscribeFormClick.');

            const formData = CardManager.get().getCardData(true);

            //在回调中获取当前的卡片数据,并通过formProvider.updateForm方法刷新卡片数据

            formProvider.updateForm(

              data2.data,

              formBindingData.createFormBindingData(formData),

            );

          }

        });

      }

    });

  }

 

  // ...

}

 

3. 模板集成

本模板提供了两种代码集成方式,供开发者自由选用。

1) 整体集成

开发者可以选择直接基于模板工程开发自己的应用工程。

  • 模板代码获取:

① 通过 IDE 插件创建模板工程,开发指导

② 通过生态市场下载源码, 下载地址

③ 通过开源仓访问源码,仓库地址

  • 打开模板工程,根据 README 说明中的快速入门章节,将自己的应用信息配置在模板工程内,即可运行并查看模板效果。


 

  • 对接开发者自己的服务器接口,转换数据结构,展示真实的云侧数据。

① 将 commons/lib_common/src/main/ets/httprequest/HttpRequestApi.ets 文件中的 mock 接口替换为真实的服务器接口。


 

② 在 commons/lib_common/src/main/ets/httprequest/HttpRequest.ets 文件中将云侧开发者自定义的数据结构转换为端侧数据结构。


 

  • 根据自己的业务内容修改模板,进行定制化开发。


2) 按需集成

若开发者已搭建好自己的应用工程,但暂未实现其中的部分场景能力,可以选择取用其中的业务组件,集成在自己的工程中。

  • 组件代码获取:

① 通过 IDE 插件下载组件源码。开发指导

② 通过生态市场下载组件源码。 下载地址

  • 下载组件源码,根据 README 中的说明,将组件包配置在自己的工程中。


 

  • 根据 API 参考和示例代码,将组件集成在自己的对应场景中。

 

以上是本期“便捷生活行业”行业优秀案例的内容,更多行业敬请期待~

欢迎下载使用行业模板“点击下载”,若您有体验和开发问题,或者迫不及待想了解 XX 行业的优秀案例,欢迎在评论区留言,小编会快马加鞭为您解答~

同时诚邀您添加下方二维码加入“组件模板活动社群”,精彩上新 &活动不错过!



👉本系列持续更新,欢迎收藏本帖!

第一期:【宝藏贴】HarmonyOS官方模板优秀案例 (第1期:便捷生活 · 购物中心)


👉HarmonyOS 组件模板相关推荐

  • 【活动 ing】HarmonyOS 组件/模板集成创新活动,报名时间截止 2025 年 8 月 30 日,点击查看

 

2025-07-28 14:186665

评论

发布
暂无评论

通过折纸视角理解神经网络:ReLU网络的几何直观与实验探索

qife122

神经网络 机器学习

AI 口语练习 App 的主要功能

北京木奇移动技术有限公司

软件外包公司 AI口语练习 AI英语学习

首发!百度百科全系能力上线百度智能云千帆,权威知识增强Agent一键打造

科技热闻

前沿论文分享 | 京东零售技术团队5篇论文入选SIGIR 2025

京东零售技术

AI 英语数字人App的主要功能

北京木奇移动技术有限公司

软件外包公司 AI技术应用 AI数字人

烟草行业企业综合管理平台(信创版)上线运行

中烟创新

CST的UAV无人机RCS --- A求解器 - 一维距离像(HRRP)和正弦图(Sinogram)

思茂信息

cst电磁仿真 CST软件 CST Studio Suite

佛山律协与iCourt围绕法律AI应用达成战略合作

科技汇

产品研发的永恒难题:质量、速度与成本的三角博弈

IPD产品研发管理

产品 产品经理 产品设计 研发管理 产品研发

数据治理之构建数据资产目录

天翼云开发者社区

大数据、

8 月 9 日,TiDB 社区活动在厦门!瑞幸咖啡、美柚、美图、飞连、福建四大机场、厦门三甲医院的 TiDB 实践分享 & 数据库选型趋势!到场的小伙伴可领瑞幸咖啡!评论区互动参与社区新款周边抽奖~

TiDB 社区干货传送门

社区活动

音频控制工具SoundSource for Mac

晨光熹微

Web3 项目的外包开发验收

北京木奇移动技术有限公司

区块链开发 软件外包公司 web3开发

AI 英语学习数字人 App 的主要功能

北京木奇移动技术有限公司

软件外包公司 AI技术外包 AI数字人

2025全球数字经济大会拉萨高层论坛开幕

科技热闻

Playwright | 元素定位四大法宝:CSS/文本/XPath/语义化定位实战

测试人

添加DNS解析记录时,提醒记录冲突是怎么回事?

国科云

数据治理的长效机制

天翼云开发者社区

大数据 数据仓库

MCP 极简开发 读书笔记2

wasa

数据治理之数据分类分级

天翼云开发者社区

大数据 数据仓库

大模型如何算出最优价格?电商定价策略的变革实践

京东零售技术

系统上线最大的难点其实不是技术问题,而是人和管理!

积木链小链

数字化转型 管理系统 智能制造

应对2025年律师团队持续增长难题,Alpha系统助力律所人效升级

科技汇

国产化即时通讯软件,支持内网私有化部署

BeeWorks

即时通讯IM 私有化部署

当 Aily 遇上盈米且慢 MCP,你的 AI 智能助手也能秒变投资顾问

盈米AI开放平台

小度首发智能硬件MCP Server,开启物理世界智能交互新时代

科技大数据

OpenAI Agents: 配置,运行

wasa

企业IT运维方案怎么选?盘点排行几款企业远控软件

科技热闻

安全可控的AI底座:灯塔大模型应用开发平台全面实现国产信创兼容适配认证

中烟创新

代码简洁之道:'两个就是太多'的编程哲学

qife122

设计模式 代码重构

如何构建跨语言、跨文化的海外舆情监测防火墙

沃观Wovision

出海企业 舆情监测 海外舆情监控 沃观Wovision

【宝藏贴】HarmonyOS官方模板优秀案例
(第1期:便捷生活 · 购物中心)_HarmonyOS_HarmonyOS_InfoQ精选文章