ITPub博客

首页 > 移动开发 > HTML5 > 《仿盒马》app开发技术分享--确认订单选择优惠券(59)

《仿盒马》app开发技术分享--确认订单选择优惠券(59)

原创 HTML5 作者:鸿蒙小林 时间:2025-06-27 21:12:47 0 删除 编辑


## 技术栈


Appgallery connect


## 开发准备

在上一节我们实现了在确认订单页查询优惠券,但是我们并没有其他优惠券相关的逻辑,我们的目的还是在订单结算的时候去使用我们对应的优惠券,现在我们要在确认订单页去进行优惠券的选择,为了方便用户操作,我们以弹窗的形式展现



## 功能分析

要实现在弹窗中展示优惠券首先,我们要创建一个自定义弹窗,在弹窗中我们要查询的数据应该是全部的数据,这样我们就能实现可用优惠券跟不可用优惠券的展示,告知用户可用优惠券的金额,以及不可用优惠券差多少额度可用,点击可用优惠券修改结算金额,展示选中的优惠券金额


## 代码实现

首先我们创建弹窗,把优惠券金额设置为双向绑定


```css

@Preview

@CustomDialog

export struct CouponCheckDialog {

  @State user: User | null = null

  @State couponList: CouponMall[] = []

  controller: CustomDialogController;

  @State lessThanLimit:CouponMall[]=[]

  @State greaterOrEqualLimit:CouponMall[]=[]

  @Prop price:number

  @Link couponPrice:number


```

在自定义弹窗组件生命周期中把我们优惠券所有的数据查询出来

```css

async aboutToAppear(): Promise<void> {

    const value = await StorageUtils.getAll('user');

    if (value != "") {

      this.user = JSON.parse(value)

    }

    let databaseZone = cloudDatabase.zone('default');

    let condition = new cloudDatabase.DatabaseQuery(coupon_mall);

    condition.equalTo("user_id", this.user?.user_id)

    let listData = await databaseZone.query(condition);

    let json = JSON.stringify(listData)

    let data: CouponMall[] = JSON.parse(json)

    this.couponList = data


    this.splitCouponsByLimit(data,this.price)

  }

```

因为我们要在一个list中展示不同类型的数据所以我们要用到ListItemGroup来实现,因为要展示不同的头部说明,我们还需要创建一个头部布局


```css

@Builder

  Header(type:number){

    Text(type==0?"可用优惠券":"不可用优惠券")

      .width('100%')

      .padding(10)

      .textAlign(TextAlign.Start)

      .fontColor(Color.Black)

      .fontSize(16)

  }

     List({ space: 10 }) {

        ListItemGroup({header:this.Header(0)}){

          ForEach(this.lessThanLimit, (item: CouponMall, index: number) => {

            ListItem() {

              this.Item(item)

            }

          })


        }

        ListItemGroup({header:this.Header(1)}){

          ForEach(this.greaterOrEqualLimit, (item: CouponMall, index: number) => {

            ListItem() {

              this.NotItem(item)

            }

          })

        }



      }

      .padding(10)

```

对应的item布局我们可以根据参数来修改状态也可以分开写,这里我们分开来写


```css

 @Builder

  Item(item: CouponMall) {

    Column({ space: 10 }) {

      Row({ space: 10 }) {

        Column() {

          Text("¥" + item.price)

            .fontSize(30)

            .fontColor(Color.Red)

            .fontWeight(FontWeight.Bold)

          Text("满" + item.limit_amount + "元可用")

            .fontColor(Color.Red)

            .fontWeight(FontWeight.Bold)

            .fontSize(12)

        }


        Column({ space: 10 }) {

          Text(item.type_str)

            .fontColor(Color.Black)

            .fontWeight(FontWeight.Bold)

            .fontSize(16)


          Text(item.txt)

            .fontColor(Color.Grey)

            .fontSize(12)


        }


        Blank()

        Text("待使用")

          .width(80)

          .height(80)

          .borderRadius(40)

          .fontSize(14)

          .textAlign(TextAlign.Center)

          .fontColor(Color.White)

          .backgroundColor(Color.Red)

      }

      .width('100%')

      .justifyContent(FlexAlign.SpaceBetween)


      Divider().width('100%').height(0.8)

        .color("#e6e6e6")

      Text("有效期至" + item.start_time + "至" + item.end_time)

        .fontSize(12)

        .fontColor(Color.Grey)

    }

    .margin({top:10})

    .padding(10)

    .backgroundColor(Color.White)

    .borderRadius(10)

    .onClick(()=>{

      this.couponPrice=item.price

      this.controller.close()

    })

  }



  @Builder

  NotItem(item: CouponMall) {

    Column({ space: 10 }) {

      Row({ space: 10 }) {

        Column() {

          Text("¥" + item.price)

            .fontSize(30)

            .fontColor(Color.Grey)

            .fontWeight(FontWeight.Bold)

          Text("满" + item.limit_amount + "元可用")

            .fontColor(Color.Grey)

            .fontWeight(FontWeight.Bold)

            .fontSize(12)

        }


        Column({ space: 10 }) {

          Text(item.type_str)

            .fontColor(Color.Grey)

            .fontWeight(FontWeight.Bold)

            .fontSize(16)


          Text(item.txt)

            .fontColor(Color.Grey)

            .fontSize(12)


        }


        Blank()

        Text("不可用")

          .width(80)

          .height(80)

          .borderRadius(40)

          .fontSize(14)

          .textAlign(TextAlign.Center)

          .fontColor(Color.White)

          .backgroundColor(Color.Grey)

      }

      .width('100%')

      .justifyContent(FlexAlign.SpaceBetween)


      Divider().width('100%').height(0.8)

        .color("#e6e6e6")


      Text("有效期至" + item.start_time + "至" + item.end_time)

        .fontSize(12)

        .fontColor(Color.Grey)

      Text(){

        Span("不可用原因:")

          .fontColor(Color.Red)

          .fontSize(12)

        Span("商品结算价距使用门槛还差")

          .fontColor(Color.Gray)

          .fontSize(12)

        Span(""+(item.price-(this.couponPrice!=undefined?this.couponPrice:0)))

          .fontColor(Color.Red)

          .fontSize(12)

        Span("元")

          .fontColor(Color.Gray)

          .fontSize(12)

      }

      .backgroundColor("#fffacfcf")

      .padding(5)

      .borderRadius(5)

    }

    .margin({top:10})

    .padding(10)

    .backgroundColor(Color.White)

    .borderRadius(10)

    .onClick(()=>{

      showToast("优惠券不可用")

    })

  }

```

之后我们在查询出的数据中根据结算商品的金额分别筛选出两个不同的数据源


```css

   splitCouponsByLimit(coupons: CouponMall[], price: number) {

  const lessThanLimit = coupons.filter(coupon =>

  coupon.limit_amount < price

  );

     this.lessThanLimit=lessThanLimit


  const greaterOrEqualLimit = coupons.filter(coupon =>

  coupon.limit_amount >= price

  );

     this.greaterOrEqualLimit=greaterOrEqualLimit


}


```

在确认订单页引用弹窗


```css

  couponController: CustomDialogController| null = new CustomDialogController({

    builder: CouponCheckDialog({

      couponPrice:this.couponPrice,

      price:this.price()

    }),

    alignment: DialogAlignment.Bottom,

    customStyle:true

  });

```

修改优惠券展示组件的逻辑


```css

  Row(){

            Text("优惠券")

              .fontSize(14)

              .fontColor(Color.Black)


            if (this.getCoupon()>0){

              if (this.couponPrice>0){

                Text("已选:-¥"+this.couponPrice+" >")

                  .fontSize(14)

                  .fontColor(Color.Red)

                  .onClick(()=>{

                    this.couponController?.open()

                  })

              }else {

                Text("可用"+this.getCoupon()+"张 >")

                  .fontSize(14)

                  .fontColor(Color.Red)

                  .onClick(()=>{

                    this.couponController?.open()

                  })


              }


            }else {

              Text("无可用优惠券")

                .fontSize(14)

                .fontColor(Color.Black)

            }


          }

          .padding(10)

          .width('100%')

          .justifyContent(FlexAlign.SpaceBetween)

```


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70046889/viewspace-3089306/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2025-06-26

  • 博文量
    90
  • 访问量
    67437