HarmonyOS鸿蒙Next官方模板优秀案例 (第1期:便捷生活 · 购物中心)

HarmonyOS鸿蒙Next官方模板优秀案例 (第1期:便捷生活 · 购物中心)

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

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

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

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

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

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

一、概述
1.行业洞察

1)行业痛点:

  • 传统零售流量缺失,依赖第三方平台导流,佣金成本高且较难沉淀用户;
  • 离场排队缴费耗时、找车难、支付流程复杂是用户最大的“离场焦虑”;
  • 传统积分体系感知弱、兑换门槛高、缺乏即时激励,导致会员活跃度低;
  • 传统服务链接割裂(App、小程序、收银系统独立),用户需在不同平台跳转,体验碎片化;
  • 低频使用的独立App极易被用户遗忘删除;公众号/小程序需主动打开,入口深且触达率低。

2)行业常用三方SDK:

功能类别 SDK名称示例 共性收集数据类型 特殊收集项/行为 SDK链接
支付类 支付宝、微信支付、银联云闪付、全民付、星图金融、京东支付、数字人民币支付 设备标识符(IMEI/Android ID/OAID)、网络信息(IP/运营商)、设备型号/系统版本、应用包名 银联SDK额外收集SIM卡国家码;星图金融收集生物识别信息(指纹/面部) 支付宝SDK
推送通知类 极光推送、华为推送、小米推送、OPPO推送、vivo推送、魅族推送、荣耀推送、TPNS 设备标识符(OAID/Android ID)、应用信息(包名/版本)、网络类型、通知栏状态 厂商SDK(如OPPO)收集锁屏状态;极光推送收集应用列表活跃状态 极光推送SDK
地图定位类 高德地图、百度地图、腾讯地图、高德定位SDK、百度定位SDK 精确位置(经纬度/GNSS)、WiFi信息(BSSID/SSID/信号强度)、基站信息、设备传感器数据、IP地址 百度地图收集陀螺仪角度;高德收集地磁传感器数据 高德地图SDK
登录认证类 极光认证、友盟智能认证、运营商一键登录(移动/电信/联通) 手机号码、SIM卡信息(ICCID/IMSI)、网络类型、设备标识符 电信SDK收集国际移动用户标识码;联通SDK需读取本机号码 极光认证SDK
数据统计/风控类 友盟+SDK、Bugly、神策SDK、灯塔SDK、同盾设备指纹、腾讯天御 设备标识符、应用崩溃日志、网络状态、设备型号/系统版本、磁盘/内存使用情况 同盾SDK收集运行中进程信息;灯塔SDK用于防会员卡共享 友盟+SDK
广告营销类 优量汇(腾讯广告)、穿山甲(字节)、倍孜广告、火山引擎增长营销SDK 设备标识符、粗略位置、应用安装列表、广告交互数据、IP地址 穿山甲SDK后台获取OAID/Android ID;倍孜广告收集USB调试模式/CPU信息 优量汇SDK
社交分享类 微信Open SDK、QQ互联SDK、微博SDK 用户主动分享的内容、微信/QQ头像昵称、剪切板信息(iOS)、应用安装状态(微信/QQ) QQ SDK请求相册/存储权限;微博SDK收集设备厂商 微信Open SDK
浏览器内核类 腾讯浏览服务(TBS/X5)、Chromium、UC 设备型号、网络类型、WiFi列表、页面性能数据 X5浏览器收集页面加载耗时/DNS解析耗时;Chromium收集剪切板内容 腾讯浏览服务SDK
音视频类 声网agora、腾讯云视频播放(LiteAVSDK)、ijkplayer 设备型号/分辨率、IP地址、网络类型、电池电量、CPU信息 声网SDK用于直播连麦;LiteAV监控WiFi信号强度 声网agoraSDK
2.优秀案例概览

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

  • Stage开发模型 + 声明式UI开发范式
  • 分层架构设计 + 组件化拆分,支持开发者在开发时既可以选择完整使用模板,也可以根据需求单独选用其中的业务组件。
  • 集成华为账号、支付等服务,只需做少量配置和定制即可快速实现华为账号的登录、停车缴费等功能。

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

二、应用架构设计
1.分层模块化设计
  • 产品定制层:专注于满足不同设备或使用场景的个性化需求,作为应用的入口,是用户直接互动的界面。
    • 本实践暂时只支持直板机,为单HAP包形式,包含路由根节点、底部导航栏等。
  • 基础特性层:用于存放相对独立的功能UI和业务逻辑实现。
    • 本实践的基础特性层将应用底部导航栏的每个选项拆分成一个独立的业务功能模块,包含首页和我的。
    • 每个功能模块都具备高内聚、低耦合、可定制的特点,支持产品的灵活部署。
  • 公共能力层:存放公共能力,包括公共UI组件、数据管理、外部交互和工具库等共享功能。
    • 本实践的公共能力层分为公共基础能力和可分可合组件,均打包为HAR包被上层业务组件引用。
    • 公共基础能力包含日志、文件处理等工具类,公共类型定义,网络库,以及弹窗、加载等公共组件。
    • 可分可合组件将包含行业特点、可完全自闭环的能力抽出独立的组件模块,支持开发者在开发中单独集成使用,详见业务组件设计章节。
三、行业场景技术方案
1.账号管理
场景说明

元服务打开后无需用户手动登录,通过静默登录后展示默认头像和默认昵称。 用户可自行选择点击关联账号按钮获取华为账号关联手机号,可将静默登录账号与用户历史注册账号关联,同步用户历史数据资产,例如头像、昵称、生日等。

技术方案
  • 静默登录
    • 通过Account Kit实现元服务静默登录。
  • 手机号获取
    • 通过Scenario Fusion Kit的快速验证手机号Button,向用户发起手机号授权申请;
    • 经用户同意后,根据获取到的Authorization Code,以及元服务服务器使用Client ID、Client Secret实现服务端开发。
2.停车缴费
场景说明

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

技术方案
  • 特殊键盘绑定
    • 通过TextInput组件的customKeyboard属性,传入自定义UI,实现特殊键盘和输入框的关联。
  • 常用车牌存储
    • 将车牌输入能力封装成独立组件,通过bindSheet方法对当前页面绑定半模态弹框,并复用车牌输入组件。
3.会员积分
场景说明

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

技术方案
  • 本模板使用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)静默登录及手机号关联
  • 代码使用效果

    • 当系统华为账号未登录时,打开本元服务模板,静默登录不成功,自动拉起系统半模态弹窗提示登录/注册华为账号;
    • 当系统华为账号已登录时,打开本元服务模板,静默登录成功,显示“华为用户”;
    • 用户可以选择点击关联账号,将静默登录账号与已注册账号关联,为用户同步历史数据资产。注意若要完整体验该功能,对应包名的元服务需要完成对应开发前提工作。
  • 核心代码实现

    // products/phone/src/main/ets/viewmodel/IndexViewModel.ets
    private async 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;
          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) {
            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 {
      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)动态服务卡片
  • 代码使用效果

    • 将停车服务卡片加桌后,可显示剩余车位和用户积分(当前为纯端模拟数据);
    • 点击卡片刷新按钮将刷新剩余车位数,并实时同步给元服务内停车缴费页面;
    • 在元服务内缴费消耗积分后,最新剩余积分实时同步给桌面卡片。
  • 核心代码实现

    // commons/lib_common/src/main/ets/utils/WidgetUtil.ets
    import { preferences } from '[@kit](/user/kit).ArkData';
    import { BusinessError, commonEventManager } from '[@kit](/user/kit).BasicServicesKit';
    import { formBindingData, formProvider } from '[@kit](/user/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(
                  data2.data,
                  formBindingData.createFormBindingData(formData),
                );
              }
            });
          }
        });
      }
    }
    
3.模板集成
  • 整体集成

    • 开发者可以选择直接基于模板工程开发自己的应用工程。
  • 组件代码获取

    • 通过IDE插件下载组件源码。
    • 通过生态市场下载组件源码。
    • 通过开源仓访问源码。
  • 下载组件源码,根据README中的说明,将组件包配置在自己的工程中。

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

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

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

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

加入社群二维码

HarmonyOS线上服务助手,添加微信时请备注“组件模板”

👉 本系列持续更新,欢迎点击帖子末尾左下角“♥”收藏本帖!

期数 帖子 链接
第1期 HarmonyOS官方模板优秀案例 点击查看
第2期 小编加急整理中,敬请期待

👉 HarmonyOS组件模板相关推荐

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

更多关于HarmonyOS鸿蒙Next官方模板优秀案例 (第1期:便捷生活 · 购物中心)的实战教程也可以访问 https://www.itying.com/category-93-b0.html

15 回复

真不错,官方就应该多出出这种高质量模板供大家去copy改改,能节省不少时间

更多关于HarmonyOS鸿蒙Next官方模板优秀案例 (第1期:便捷生活 · 购物中心)的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


更多的模板在这里:

  • 模板1
  • 模板2
  • 模板3

写的很详细了,感觉立刻就可以实践起来

开发有参照,容易多了

优秀

有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html

确实优秀, 这种例子越多越好, 比自己空想要好多了

有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html

非常不错,加快开发进度

能够帮我学习并快速上手开发,非常好用

通俗易懂,上手很快,节省开发时间,希望持续更新模板功能

内容详细,对鸿蒙初学者非常友好,能方便我们更快更好地开发鸿蒙,期望更多行业的模板尽快出来

很好的模板,学习了

HarmonyOS Next购物中心模板展示了鸿蒙分布式能力在零售场景的应用。该模板采用ArkUI开发框架实现跨设备协同,支持手机、平板、大屏等多终端无缝流转。关键特性包括:

  1. 基于原子化服务实现商品详情跨设备接续;
  2. 使用Stage模型管理多窗口交互;
  3. 集成分布式数据管理实现购物车多端同步;
  4. 采用声明式UI开发自适应布局。

模板已开源至Gitee的HarmonyOS应用样例仓库。

这是一个非常全面的HarmonyOS购物中心模板案例分享,展示了如何利用HarmonyOS Next的特性开发商业应用。主要亮点包括:

  1. 分层架构设计:采用产品定制层、基础特性层和公共能力层的分层架构,模块化程度高,便于复用和维护。

  2. 关键场景实现:

  • 账号管理:通过Account Kit实现静默登录,使用Scenario Fusion Kit获取手机号
  • 停车缴费:自定义车牌键盘组件,集成支付功能
  • 会员积分:集成Scan Kit扫码和Media Library图片选择能力
  1. 动态服务卡片:通过公共事件管理实现卡片与应用的实时数据同步

  2. 两种集成方式:

  • 整体集成:适合全新项目开发
  • 按需集成:可单独使用优惠券、积分等业务组件

这个模板充分利用了HarmonyOS的原子化服务特性,解决了传统购物中心App的多个痛点,如用户留存低、支付流程复杂等问题。代码结构清晰,文档完善,是学习HarmonyOS商业应用开发的优秀参考案例。

回到顶部