一个餐饮APP开发,主要包括以下几个核心步骤和功能:
- 需求和功能规划:首先需要确定APP的基本功能,如商品展示、在线点餐、订单管理、支付结算、扫码核销等。同时需要实现多门店特色功能,如门店切换与定位、库存管理和销售数据统计等。此外,还有营销功能、如优惠券发放、会员制度、积分兑换等,以吸引顾客和提高用户的粘性。
- 选择开发方式:如企业有自己的技术团队,可以选择自主研发,以实现高度定制化。如没有,则可以选择第三方开发平台或外包给专业的软件公司,以降低成本和提高效率。
- 申请账号和认证:注册相关的账号并进行企业主体认证,以确保可以使用APP的更多功能,如支付接口等。
- 设计与开发:设计简洁、美观、易用的界面,确保各个功能模块的正常运行和数据的准确传输。特别是多门店管理系统的开发,需要建立一个集中的管理后台,用于管理各个门店的信息、菜品、库存、订单等,以使总部可以统一管理和监控。
- 测试与优化:在开发完成后,进行功能测试和优化,确保APP的稳定性和用户体验。测试内容包括订单处理、支付功能、用户界面等方面。
- 多门店管理:实现多门店的统一管理和调试,实时监控各门店的运营情况,确保高效顺畅。
- 营销工具:支持优惠券、满减活动、会员积会等多种促销方式,提升客户黏性和销售额。
- 支付功能:支持多种支付方式,确保支付案例,提升顾客满意度。
通过以上方案和功能特点,餐饮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/*"等。 |
只读 | string | 否 | 表示要执行的通用操作(如:查看、分享、应用详情)。在隐式Want中,您可定义该字段,配合uri或parameters来表示对数据要执行的操作。如打开,查看该uri数据。例如,当uri为一段网址,action为ohos.want.action.viewData则表示匹配可查看该网址的Ability。 | |
只读 | Array<string> | 否 | 表示目标Ability额外的类别信息(如:浏览器,视频播放器),在隐式Want中是对action的补充。在隐式Want中,您可定义该字段,来过滤匹配UIAbility类别,如必须是浏览器。例如,在action字段的举例中,可存在多个应用声明了支持查看网址的操作,其中有应用为普通社交应用,有的为浏览器应用,您可通过entity.system.browsable过滤掉非浏览器的其他应用。 | |
只读 | 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同时选中,点击完成,重启虚拟机即可。
以上步骤完成后,进入门店列表页,点击子门店则会弹出新窗口并展示子门店界面。如下图:
此篇就到这,希望对大家有所帮助 ~