HarmonyOS开发 - 餐饮APP中多门店多窗口打开实例

        一个餐饮APP开发,主要包括以下几个核心步骤和功能:

  1. 需求和功能规划:首先需要确定APP的基本功能,如商品展示、在线点餐、订单管理、支付结算、扫码核销等。同时需要实现多门店特色功能,如门店切换与定位、库存管理和销售数据统计等。此外,还有营销功能、如优惠券发放、会员制度、积分兑换等,以吸引顾客和提高用户的粘性。
  2. 选择开发方式:如企业有自己的技术团队,可以选择自主研发,以实现高度定制化。如没有,则可以选择第三方开发平台或外包给专业的软件公司,以降低成本和提高效率。
  3. 申请账号和认证:注册相关的账号并进行企业主体认证,以确保可以使用APP的更多功能,如支付接口等。
  4. 设计与开发:设计简洁、美观、易用的界面,确保各个功能模块的正常运行和数据的准确传输。特别是多门店管理系统的开发,需要建立一个集中的管理后台,用于管理各个门店的信息、菜品、库存、订单等,以使总部可以统一管理和监控。
  5. 测试与优化:在开发完成后,进行功能测试和优化,确保APP的稳定性和用户体验。测试内容包括订单处理、支付功能、用户界面等方面。
  6. 多门店管理:实现多门店的统一管理和调试,实时监控各门店的运营情况,确保高效顺畅。
  7. 营销工具:支持优惠券、满减活动、会员积会等多种促销方式,提升客户黏性和销售额。
  8. 支付功能:支持多种支付方式,确保支付案例,提升顾客满意度。

        通过以上方案和功能特点,餐饮APP可以实现多门店的多窗口打开,提升管理效率和顾问体验。

        这里,我们将通过HarmonyOS来实现餐饮APP的开发,以及多门店窗口的打开。另外,这篇是上一篇“餐饮App首页”后续,需要app首页代码的,可以前去查看,地址:HarmonyOS开发 - 餐饮APP首页开发实例-CSDN博客

一、HarmonyOS启动模式

        在HarmonyOS中提供了三种启动模式:singleton(单实例模式)、multiton(多实例模式)和specified(指定实例模式)。

  • 在单例模式下,每次启动应用时,如该类型的UIAbility实例已经存在,则会利用已有的实例,不会创建新的实例;
  • 在多实例模式下,每次启动都会创建一个新的实例,允许同时存在多个实例。
  • 指定实例模式,则根据一个指定的键来决定是否复用实例。

        具体实现时,可以在应用的module.json5配置文件中设置启动模式,将UIAbility的启动模式设置为多实例模式,可以配置文件中 "launchType": "multiton"。这样设置后,每次调用startAbility()方法都会创建一个新的实例,允许同时存在多个应用界面。

二、Ability和Module

        在HarmonyOS开发中,Ability是应用或服务所具备的能力的抽象,它可以响应用户的操作,与用户进行交互。一个Module可以包含一个或多个Ability。HarmonyOS提供了两种应用模式:FA(Feature Ability)模型和Stage模型。

        FA模型从API7开始支持,但已不再是主推的模型。而Stage模型从API 9开始新增,是目前主推且会长期演进的模型。在Stage模型中,Ability分为两种组件类型:

  • UIAbility组件:包含UI界面,提供展示UI的能力,主要用于和用户交互。
  • ExtensionAbility组件:提供特定场景的扩展能力,满足更多的使用场景。当前仅OpenHarmony工程支持使用ExtensionAbility组件。

        在HarmonyOS中,应用可以设计为包含多个Ability或者多个module,这取决于应用的复杂性和模块化需求。

        在此篇中,我们将子门店用多个Module创建,因为每个门店都有首页、产品列表页、购物车、我的页面、订单列表页、订单详情页等等;用单独Module模块,在创建页面和文件命名上会方便许多。

三、创建Module

        在项目名称上(MultiStoreApplication)右击,选择创建Module,如下图:

        进行模板选择界面,选择空模块点击下一步,如下图:

        进入下一个操作界面,给Module重新名称或使用默认名称,如下图:

        进步下一个操作界面,点击“完成”即可。

        此时,项目中除了之前默认的入口Module,又创建了一个新的store门店模块,关于子门店的页面就可以在该模块下创建、修改和删除了。

四、多窗口启动配置

       当store子门店模块创建后,从主入口模块的某个页面跳转到子门店,如果不配置launchType则会以默认标准模式打开;正常情况下属门店不会只有一家,当每个子门店都需要以新窗口打开时,则需要将launchType设置为multiton。

        打开store子门店模块下的moudle.json5配置文件,ablities中name=StoreAbility应用设置为multiton,示例如下:

{
  "module": {
    "name": "store",
    "type": "feature",
    "description": "$string:module_desc",
    "mainElement": "StoreAbility",
    "deviceTypes": [
      "phone",
      "tablet"
    ],
    "deliveryWithInstall": true,
    "installationFree": false,
    "pages": "$profile:main_pages",
    "abilities": [
      {
        "name": "StoreAbility",
        "srcEntry": "./ets/storeability/StoreAbility.ts",
        "description": "$string:StoreAbility_desc",
        "icon": "$media:icon",
        "label": "$string:StoreAbility_label",
        "startWindowIcon": "$media:icon",
        "startWindowBackground": "$color:start_window_background",
        "exported": true,
        "launchType": "multiton"
      }
    ]
  }
}

    

五、门店列表

        在餐饮app首页点击“门店”进入门店列表,然后通过此列表页点击进入相应的子门店窗口中。上篇地址:HarmonyOS开发 - 餐饮APP首页开发实例-CSDN博客

        打开entry主模块下的pages目录,创建一个门店列表页,用于展示所有子门店列表信息。右击选择创建Page,如下图:

        点击“完成”后,门店列表页则创建成功了,接下来我们将在页面中简单添加两个门店信息。

        这里拿首页的产品列表数据修改下即可,pages/Stores.ets代码如下:


import router from '@ohos.router'
type StoresType = {
  id: number
  name: string
  thumb: Resource
}

@Entry
@Component
struct Stores {
  @State productList: Array<StoresType> = [
    { id: 1, name: '门店一', thumb: $rawfile('u62.png'), },
    { id: 2, name: '门店二', thumb: $rawfile('u76.png') }
  ]
  // 定义内联构建函数
  @Builder ImageItems(item: StoresType){
    Row(){
      Column(){
        Image(item.thumb)
          .width("100%")
          .height("100vp")
          .borderRadius(8)
        Text(item.name)
          .width("100%")
          .height("36vp")
          .textOverflow({ overflow: TextOverflow.Ellipsis })
          .fontSize("18fp")
      }
    }.width('100%').padding(10)
  }

  build() {
    Row() {
      Column() {
        Row(){
          Image($rawfile('back.png'))
            .width("35vp")
            .height("35vp")
            .margin({ top: "0vp", bottom: "0vp", left: "0vp", right: "0vp" })
            .onClick(() => {
              // 返回上一页
              router.back()
            })
        }.width('100%').justifyContent(FlexAlign.Start)

        Text("门店列表")
          .width("100%")
          .height("50vp")
          .fontSize("16fp")
          .fontWeight(FontWeight.Bold)
          .padding(10)
        // 每行分两列展示
        GridRow({columns: 2}){
          ForEach(this.productList, (item: StoresType, index) => {
            GridCol(){
              this.ImageItems(item)
            }
          })
        }
      }.padding(5)
    }
    .width("100%")
  }
}

        页面效果如下图:

六、创建子门店

        子门店的Module已创建过了,下面将entry模块中的首页pages/index.ets及相关组件(components目录中组件)全部拷过去,简单修改下即可;另外,图片资源也需要全部拷到store模块的resources/rawfile目录。如下图,

        子门店首页只需要将“门店”分类删除即可。

        删除门店分类后,页面效果如下图:

七、实现多门店窗口打开

        在该示例中,需要在当前UIAbility调用 startAbility方法拉起目标UIAbility;即在entry模块主页点击门店时,拉起store模块的UIAbility界面,打开新的交互窗口。

7.1 Want的定义与用途

        Want是对象间信息传递的载体,可以用于应用组件间的信息传递。其使用场景之一是作为startAbility()的参数,包含了指定的启动目标以及启动时需携带的相关数据,如bundleName和abilityName字段分别指明目标Ability所在应用的包名以及对应包内的Ability名称。当UIAbilityA启动UIAbilityB并需要传入一些数据给UIAbilityB时,Want可以作为一个载体将数据传给UIAbilityB。

        Want参数说明:

名称

读写属性

类型

必填

描述

deviceId

只读

string

表示目标Ability所在设备ID。如果未设置该字段,则表明本设备。

bundleName

只读

string

表示目标Ability所在应用名称。

moduleName

只读

string

表示目标Ability所属的模块名称。

abilityName

只读

string

表示目标Ability名称。如果未设置该字段,则该Want为隐式。如果在Want中同时指定了bundleName,moduleName和abilityName,则Want可以直接匹配到指定的Ability。

uri

只读

string

表示携带的数据,一般配合type使用,指明待处理的数据类型。如果在Want中指定了uri,则Want将匹配指定的Uri信息,包括scheme, schemeSpecificPart, authority和path信息。

type

只读

string

表示携带数据类型,使用MIME类型规范。例如:"text/plain"、"image/*"等。

action

只读

string

表示要执行的通用操作(如:查看、分享、应用详情)。在隐式Want中,您可定义该字段,配合uri或parameters来表示对数据要执行的操作。如打开,查看该uri数据。例如,当uri为一段网址,action为ohos.want.action.viewData则表示匹配可查看该网址的Ability。

entities

只读

Array<string>

表示目标Ability额外的类别信息(如:浏览器,视频播放器),在隐式Want中是对action的补充。在隐式Want中,您可定义该字段,来过滤匹配UIAbility类别,如必须是浏览器。例如,在action字段的举例中,可存在多个应用声明了支持查看网址的操作,其中有应用为普通社交应用,有的为浏览器应用,您可通过entity.system.browsable过滤掉非浏览器的其他应用。

flags

只读

number

表示处理Want的方式。例如通过wantConstant.Flags.FLAG_ABILITY_CONTINUATION表示是否以设备间迁移方式启动Ability。

parameters

只读

{[key: string]: any}

此参数用于传递自定义数据,通过用户自定义的键值对进行数据填充,具体支持的数据类型如Want API所示。

        需要进步了解更为详细的说明,可前去查看官网API,地址:文档中心

7.2 拉起目标UIAbility

        首先需要在entry模块下的门店列表(Stores)页中引入Want模块,代码如下:

import Want from '@ohos.app.ability.Want';

        当点击某个门店时,拉起store模块的目录UIAbility,代码如下:

  // 定义内联构建函数
  @Builder ImageItems(item: StoresType){
    Row(){
      Column(){
        Image(item.thumb)
          .width("100%")
          .height("100vp")
          .borderRadius(8)
        Text(item.name)
          .width("100%")
          .height("36vp")
          .textOverflow({ overflow: TextOverflow.Ellipsis })
          .fontSize("18fp")
      }.onClick(() => {
        // 获取本应用的上下文
        const context = getContext(this) as common.UIAbilityContext
        let want: Want = {
          'deviceId': '', // deviceId为空表示本设备
          'bundleName': 'com.example.multistoreapplication',
          'abilityName': 'StoreAbility',
          'moduleName': 'store' // moduleName非必选
        };
        context.startAbility(want)
        console.log('testTag', item.id)
      })
    }.width('100%').padding(10)
  }

        boundleName信息在AppScope目录下的app.json5文件中,如下图:

        abilityName和moduleName信息在目标Module目录(即store模块)下的module.json5文件中,如下图:

7.3 Deploy multi Hap

        此时点击门店列表中的子门店,点击事件已被触发,但是子门店窗口并未被拉起,这是因为如果工程中同时存在多个模块,且您的应用/服务存在跨模块间的调用时,在调试阶段需要同时安装多个模块的HAP到设备中。此时,需要在Deploy Multi Hap中选择多个模块,启动调试时,DevEco Studio会将所有的模块都安装到设备上。

        解决这个问题很简单,选择“Edit Configurations...”,打开Run/Debug配置界面。

        在配置界面中,勾选上“Deploy Multi Hap Packages”,并且Module:中将entry和store同时选中,点击完成,重启虚拟机即可。

        以上步骤完成后,进入门店列表页,点击子门店则会弹出新窗口并展示子门店界面。如下图:

        此篇就到这,希望对大家有所帮助 ~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

觉醒法师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值