HarmonyOS鸿蒙Next中《仿盒马》app开发技术分享02-- 新人专享券(端云一体)

HarmonyOS鸿蒙Next中《仿盒马》app开发技术分享02-- 新人专享券(端云一体)

开发准备

上一篇文章中我们实现了项目端云一体化的升级,我们的数据后期就要从云侧的数据库去获取了,现在我们从头开始对项目进行端云一体化的改造。我们在首页已经把新人专享券抽离为公共组件。

现在我们继续进行功能开发,把这个组建的本地数据展示修改为端侧获取。

功能分析

我们把之前实现的首页功能拿出改造一下。我们在首页实现了新用户领券中心,数据结构就是 模块的标题、说明、优惠券列表,列表包含优惠券的金额、类型,同时我们还要给券添加一些其他参数,比如领取时间,领取用户等,这时候就又延伸出一个功能,当我们用户没有登录的时候,我们点击立即领取,是需要跳转到用户登录页面的。

因为云数据库不支持外键,所以我们通过多插入id字段来进行数据查询。

代码实现

首先我们进行表的创建。

home_new_people_coupon 这是首页活动模块的表

{
  "objectTypeName": "home_new_people_coupon",
  "fields": [
    {"fieldName": "activity_id", "fieldType": "Integer", "notNull": true, "belongPrimaryKey": true},
    {"fieldName": "title", "fieldType": "String", "notNull": true, "defaultValue": 0},
    {"fieldName": "msg", "fieldType": "String"},
    {"fieldName": "home_coupon_activity_id", "fieldType": "Integer"},
    {"fieldName": "router", "fieldType": "String"},
    {"fieldName": "activity_time", "fieldType": "String"}
  ],
  "indexes": [
    {"indexName": "home_coupon_activity_id_index", "indexList": [{"fieldName":"home_coupon_activity_id","sortType":"ASC"}]}
  ],
  "permissions": [
    {"role": "World", "rights": ["Read"]},
    {"role": "Authenticated", "rights": ["Read", "Upsert"]},
    {"role": "Creator", "rights": ["Read", "Upsert", "Delete"]},
    {"role": "Administrator", "rights": ["Read", "Upsert", "Delete"]}
  ]
}

然后我们创建对应的活动id下的优惠券列表表

coupon_info

{
  "objectTypeName": "coupon_info",
  "fields": [
    {"fieldName": "coupon_id", "fieldType": "Integer", "notNull": true, "belongPrimaryKey": true},
    {"fieldName": "home_coupon_activity_id", "fieldType": "Integer", "notNull": true, "defaultValue": 0},
    {"fieldName": "price", "fieldType": "String"},
    {"fieldName": "type", "fieldType": "String"},
    {"fieldName": "get_time", "fieldType": "String"},
    {"fieldName": "limit_amount", "fieldType": "Integer"},
    {"fieldName": "txt", "fieldType": "String"},
    {"fieldName": "activity_id", "fieldType": "Integer"}
  ],
  "indexes": [
    {"indexName": "couponIdIndex", "indexList": [{"fieldName":"coupon_id","sortType":"ASC"}]}
  ],
  "permissions": [
    {"role": "World", "rights": ["Read"]},
    {"role": "Authenticated", "rights": ["Read", "Upsert"]},
    {"role": "Creator", "rights": ["Read", "Upsert", "Delete"]},
    {"role": "Administrator", "rights": ["Read", "Upsert", "Delete"]}
  ]
}

完成之后我们插入数据

{
  "cloudDBZoneName": "default",
  "objectTypeName": "home_new_people_coupon",
  "objects": [
    {
      "activity_id": 10,
      "title": "新人活动",
      "msg": "前三单免运费",
      "home_coupon_activity_id": 10,
      "router": "路由",
      "activity_time": "2025-4-3"
    }
  ]
}
{
  "cloudDBZoneName": "default",
  "objectTypeName": "coupon_info",
  "objects": [
    {
      "coupon_id": 10,
      "home_coupon_activity_id": 10,
      "price": "10",
      "type": "新人专享",
      "get_time": "2025-3-18",
      "limit_amount": 30,
      "txt": "string1",
      "activity_id": 1
    },
    {
      "coupon_id": 20,
      "home_coupon_activity_id": 10,
      "price": "string2",
      "type": "string2",
      "get_time": "string2",
      "limit_amount": 20,
      "txt": "string2",
      "activity_id": 1
    },
    {
      "coupon_id": 30,
      "home_coupon_activity_id": 10,
      "price": "string1",
      "type": "string1",
      "get_time": "string1",
      "limit_amount": 10,
      "txt": "string1",
      "activity_id": 1
    },
    {
      "coupon_id": 40,
      "home_coupon_activity_id": 10,
      "price": "string2",
      "type": "string2",
      "get_time": "string2",
      "limit_amount": 20,
      "txt": "string2",
      "activity_id": 1
    }
  ]
}

数据都插入完之后,我们把内容同步到云端数据库,然后client model 、server model 创建对应的类

都执行完之后我们就可以直接在index 页面进行数据的查询了

首先创建接收数据的对象

@State home_new_people_coupon:homeNewPeopleCoupon|null=null
@State couponList:couponInfo[]=[]

然后进行查询

let databaseZone = cloudDatabase.zone('default');
let condition = new cloudDatabase.DatabaseQuery(home_new_people_coupon);
let condition1 = new cloudDatabase.DatabaseQuery(coupon_info);
let listData = await databaseZone.query(condition);
let json = JSON.stringify(listData)
let data:homeNewPeopleCoupon= JSON.parse(json)
this.home_new_people_coupon=data;
let listData1 = await databaseZone.query(condition1);
condition1.equalTo("home_coupon_activity_id",data.home_coupon_activity_id)
let json1 = JSON.stringify(listData1)
let data1:couponInfo[]= JSON.parse(json1)
this.couponList=data1

可以看到我们的云端数据已经查出来了

我们把数据修改一下提交到云端

{
  "cloudDBZoneName": "default",
  "objectTypeName": "coupon_info",
  "objects": [
    {
      "coupon_id": 10,
      "home_coupon_activity_id": 10,
      "price": "10",
      "type": "新人专享",
      "get_time": "2025-3-18",
      "limit_amount": 30,
      "txt": "string1",
      "activity_id": 1
    },
    {
      "coupon_id": 20,
      "home_coupon_activity_id": 10,
      "price": "15",
      "type": "新人专享",
      "get_time": "string2",
      "limit_amount": 20,
      "txt": "string2",
      "activity_id": 1
    },
    {
      "coupon_id": 30,
      "home_coupon_activity_id": 10,
      "price": "20",
      "type": "新人专享",
      "get_time": "string1",
      "limit_amount": 10,
      "txt": "string1",
      "activity_id": 1
    },
    {
      "coupon_id": 40,
      "home_coupon_activity_id": 10,
      "price": "30",
      "type": "新人专享",
      "get_time": "string2",
      "limit_amount": 20,
      "txt": "string2",
      "activity_id": 1
    }
  ]
}

然后修改我们之间创建的新人活动的组件

import { couponInfo } from "../entity/couponInfo"
import { homeNewPeopleCoupon } from "../entity/homeNewPeopleCoupon"

@Component
@Preview
export struct CouponComponent {
  @Link home_activity:homeNewPeopleCoupon|null
  @Link couponList:couponInfo[]

  build() {
    Column() {
      Row() {
        Text(this.home_activity?.title)
          .fontSize(20)
          .fontColor('#FF0000')
        Text(this.home_activity?.msg)
          .fontSize(14)
          .fontColor('#888888')
          .margin({left:10})
      }
      .width('100%')
      .padding(16)
      List({ space: 10 }) {
        ForEach(this.couponList, (item:couponInfo) => {
          ListItem() {
            Column() {
              Text(item.price)
                .fontSize(22)
                .fontColor('#FF4444')
                .margin({ bottom: 8 })
              Text(item.type)
                .fontSize(12)
                .fontColor('#FF4444')
            }
            .padding(10)
            .backgroundColor("#ffffff")
            .borderRadius(8)
          }
        })
      }
      .margin({left:50})
      .listDirection(Axis.Horizontal)
      .width('100%')
      .height(80)
      Button('立即领取', { type: ButtonType.Normal })
        .width(240)
        .height(40)
        .backgroundColor('#FF0000')
        .fontColor(Color.White)
        .borderRadius(20)
        .margin({ bottom: 16 })
        .onClick(() => {
          console.log(`"router"`)
        })
    }
    .backgroundColor("#fffce2be")
    .width('95%')
    .margin({top:20})
    .borderRadius(20)
  }
}

首页调用组件进行参数的传入

CouponComponent({home_activity:this.home_new_people_coupon,couponList:this.couponList})

到这里我们的新人活动就完成了

更多关于HarmonyOS鸿蒙Next中《仿盒马》app开发技术分享02-- 新人专享券(端云一体)的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

在HarmonyOS鸿蒙Next中开发《仿盒马》的新人专享券功能(端云一体)主要涉及以下技术点:

  1. 使用ArkUI框架搭建优惠券UI组件
  2. 集成华为AGC的云函数和云数据库实现券发放逻辑
  3. 通过端云协同SDK实现设备与云端数据同步
  4. 利用分布式数据管理实现多设备券状态一致

关键代码采用TypeScript编写,使用@ohos相关API处理业务逻辑。云侧使用CloudDB存储用户领券记录,端侧通过Preferences存储本地券状态。

更多关于HarmonyOS鸿蒙Next中《仿盒马》app开发技术分享02-- 新人专享券(端云一体)的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


从技术实现来看,这篇分享展示了HarmonyOS Next中端云一体化开发的完整流程,有几个关键点值得注意:

  1. 数据库设计方面采用了多表关联方案,通过home_coupon_activity_id字段建立关联关系,解决了云数据库不支持外键的限制。表结构设计合理,包含主键、索引和权限控制。

  2. 数据查询部分展示了Cloud DB的典型用法:

  • 使用DatabaseQuery构建查询条件
  • 通过equalTo实现条件过滤
  • 采用JSON序列化/反序列化处理查询结果
  • 实现了主表和子表的关联查询
  1. 组件开发方面:
  • 使用@Link实现父子组件数据双向绑定
  • 采用ForEach渲染动态列表
  • 通过链式调用设置样式属性
  • 实现了点击事件处理
  1. 端云协同:
  • 本地组件与云端数据完美结合
  • 展示了数据从云端到组件的完整流动
  • 实现了数据的增删改查全套操作

这个案例很好地演示了如何将传统本地功能迁移到云端,同时保持界面交互的流畅性。对于电商类应用中的优惠券、活动等典型场景具有参考价值。

回到顶部