Harmonyos5应用开发实战——订单卡片组件开发(part2)

205 阅读1分钟
3. 订单操作按钮

根据订单状态显示不同的操作按钮,如待支付状态下显示支付、添加商品和取消订单按钮,已完成状态下显示删除订单和再次下单按钮,其他状态下显示联系商家按钮。

Row() {
  if (this.storeType === StoreType.PICK_NUM_TYPE && this.orderItem.order?.dnState === DnState.COMPLETED) {
    Text() {
      Span($r('app.string.pick_good_id'))
      Span(`${this.orderItem.order?.oid}`)
    }.fontSize($r('sys.float.Body_M')).fontColor($r('sys.color.font_primary'))
  }
  // 订单操作按钮
  Row({ space: 8 }) {
    if (this.orderItem.order?.dnState === DnState.TO_BE_PAID) {
      Text($r('app.string.pay'))
        .border({
          width: 1,
          color: $r('sys.color.multi_color_09'),
        })
        .height(28)
        .width(72)
        .fontSize($r('sys.float.Body_M'))
        .textAlign(TextAlign.Center)
        .fontColor($r('sys.color.multi_color_09'))
        .borderRadius(14)
        .onClick(() => {
          this.paySheetFlag = true
        })
        .bindSheet($$this.paySheetFlag, paySheetBuilder(Number(this.payMoney ?? 0), (flag: boolean) => {
          if (flag) {
            this.confirmOrder()
          }
          this.paySheetFlag = false
        }), {
          height: 397,
          blurStyle: BlurStyle.Thick,
          showClose: false,
        })
      Text($r('app.string.add_good'))
        .border({
          width: 1,
          color: $r('sys.color.multi_color_09'),
        })
        .height(28)
        .width(72)
        .fontSize($r('sys.float.Body_M'))
        .textAlign(TextAlign.Center)
        .fontColor($r('sys.color.multi_color_09'))
        .borderRadius(14)
        .onClick(() => {
          if (this.orderItem.order?.id) {
            HttpRequestApi.addGoods(this.orderItem.order.id).then((resp: number) => {
              if (resp === HttpCode.SUCCESS) {
                getMyCarUtil()
                this.pageStack.replacePathByName('HomePage', null)
              } else if (resp === HttpCode.STATUE_ERROR) {
                promptAction.showToast({ message: $r('app.string.order_statue_error') })
                this.getMyOrder()
              }
            })
          } else {
            promptAction.showToast({ message: $r('app.string.order_not_exist') })
          }
        })
      Text($r('app.string.cancel'))
        .border({
          width: 1,
          color: $r('sys.color.font_secondary'),
        })
        .height(28)
        .width(72)
        .fontSize($r('sys.float.Body_M'))
        .textAlign(TextAlign.Center)
        .fontColor($r('sys.color.font_secondary'))
        .borderRadius(14)
        .onClick(() => {
          cancelOrderUtil(this.orderItem.order?.id || '').then((resp: number) => {
            let msg: Resource = $r('app.string.cancel_success')
            if (resp === HttpCode.SUCCESS) {
              this.getMyOrder()
            } else if (resp === HttpCode.STATUE_ERROR) {
              promptAction.showToast({ message: $r('app.string.order_statue_error') })
              this.getMyOrder()
              return
            } else {
              msg = $r('app.string.cancel_failed')
            }
            promptAction.showToast({ message: msg })
          })
        })
    } else if (this.orderItem.order?.dnState === DnState.COMPLETED) {
      Text($r('app.string.delete_order'))
        .border({
          width: 1,
          color: $r('sys.color.font_secondary'),
        })
        .height(28)
        .width(72)
        .fontSize($r('sys.float.Body_M'))
        .textAlign(TextAlign.Center)
        .fontColor($r('sys.color.font_secondary'))
        .borderRadius(14)
        .onClick(() => {
          promptAction.showDialog({
            title: $r('app.string.delete_order'),
            message: $r('app.string.delete_confirm'),
            buttons: [
              {
                text: $r('app.string.cancel'),
                color: $r('sys.color.font_primary'),
              },
              {
                text: $r('app.string.confirm'),
                color: $r('sys.color.multi_color_09'),
              },
            ],
          }, (err, data) => {
            if (err) {
              console.error('showDialog err: ' + err);
              return;
            }
            if (data.index === 1) {
              if (this.orderItem.order?.id) {
                HttpRequestApi.deleteOrder(this.orderItem.order.id).then(() => {
                  this.getMyOrder()
                })
              } else {
                promptAction.showToast({ message: $r('app.string.order_not_exist') })
              }
            }
            console.info('showDialog success callback, click button: ' + data.index);
          });
        })
      Text($r('app.string.one_more_order'))
        .border({
          width: 1,
          color: $r('sys.color.multi_color_09'),
        })
        .height(28)
        .width(72)
        .fontSize($r('sys.float.Body_M'))
        .textAlign(TextAlign.Center)
        .fontColor($r('sys.color.multi_color_09'))
        .borderRadius(14)
        .onClick(() => {
          this.currentIndex = 0
        })
    } else {
      Text($r('app.string.contact_store'))
        .border({
          width: 1,
          color: $r('sys.color.multi_color_09'),
        })
        .height(28)
        .width(72)
        .fontSize($r('sys.float.Body_M'))
        .textAlign(TextAlign.Center)
        .fontColor($r('sys.color.multi_color_09'))
        .borderRadius(14)
        .onClick(() => {
          this.callTelSheet = true
        })
        .bindSheet($$this.callTelSheet, CallTelDialogBuilder(this.storeInfo.tel!, () => {
          this.callTelSheet = false
        }), {
          height: 309,
          blurStyle: BlurStyle.Thick,
          showClose: false,
        });
    }
  }.layoutWeight(1).justifyContent(FlexAlign.End)
}
.width(Constants.FULL_SIZE)
.margin({ top: 12 })
.justifyContent(FlexAlign.SpaceBetween)
4. 支付功能

点击支付按钮后,弹出支付面板,确认支付后调用华为支付接口进行支付。

confirmOrder() {
  // 拉华为支付
  HttpRequestApi.getHuaweiPayInfo(this.orderItem.order?.id ?? '').then((resp: number) => {
    if (resp === HttpCode.SUCCESS) {
      promptAction.showToast({ message: $r('app.string.pay_success') })
      this.getMyOrder()
    } else if (resp === HttpCode.STATUE_ERROR) {
      promptAction.showToast({ message: $r('app.string.order_statue_error') })
      this.getMyOrder()
    } else {
      promptAction.showToast({ message: $r('app.string.pay_failed') })
    }
  }).catch((e: BusinessError) => {
    console.error(`getHuaweiPayInfo error: ${JSON.stringify(e)}.`);
    promptAction.showToast({ message: $r('app.string.pay_failed_msg', JSON.stringify(e)) })
  })
}

通过以上核心功能的实现,在HarmonyOS 5应用中成功开发了订单卡片组件,为用户提供了便捷的订单管理体验。##### 3. 订单操作按钮 根据订单状态显示不同的操作按钮,如待支付状态下显示支付、添加商品和取消订单按钮,已完成状态下显示删除订单和再次下单按钮,其他状态下显示联系商家按钮。

Row() {
  if (this.storeType === StoreType.PICK_NUM_TYPE && this.orderItem.order?.dnState === DnState.COMPLETED) {
    Text() {
      Span($r('app.string.pick_good_id'))
      Span(`${this.orderItem.order?.oid}`)
    }.fontSize($r('sys.float.Body_M')).fontColor($r('sys.color.font_primary'))
  }
  // 订单操作按钮
  Row({ space: 8 }) {
    if (this.orderItem.order?.dnState === DnState.TO_BE_PAID) {
      Text($r('app.string.pay'))
        .border({
          width: 1,
          color: $r('sys.color.multi_color_09'),
        })
        .height(28)
        .width(72)
        .fontSize($r('sys.float.Body_M'))
        .textAlign(TextAlign.Center)
        .fontColor($r('sys.color.multi_color_09'))
        .borderRadius(14)
        .onClick(() => {
          this.paySheetFlag = true
        })
        .bindSheet($$this.paySheetFlag, paySheetBuilder(Number(this.payMoney ?? 0), (flag: boolean) => {
          if (flag) {
            this.confirmOrder()
          }
          this.paySheetFlag = false
        }), {
          height: 397,
          blurStyle: BlurStyle.Thick,
          showClose: false,
        })
      Text($r('app.string.add_good'))
        .border({
          width: 1,
          color: $r('sys.color.multi_color_09'),
        })
        .height(28)
        .width(72)
        .fontSize($r('sys.float.Body_M'))
        .textAlign(TextAlign.Center)
        .fontColor($r('sys.color.multi_color_09'))
        .borderRadius(14)
        .onClick(() => {
          if (this.orderItem.order?.id) {
            HttpRequestApi.addGoods(this.orderItem.order.id).then((resp: number) => {
              if (resp === HttpCode.SUCCESS) {
                getMyCarUtil()
                this.pageStack.replacePathByName('HomePage', null)
              } else if (resp === HttpCode.STATUE_ERROR) {
                promptAction.showToast({ message: $r('app.string.order_statue_error') })
                this.getMyOrder()
              }
            })
          } else {
            promptAction.showToast({ message: $r('app.string.order_not_exist') })
          }
        })
      Text($r('app.string.cancel'))
        .border({
          width: 1,
          color: $r('sys.color.font_secondary'),
        })
        .height(28)
        .width(72)
        .fontSize($r('sys.float.Body_M'))
        .textAlign(TextAlign.Center)
        .fontColor($r('sys.color.font_secondary'))
        .borderRadius(14)
        .onClick(() => {
          cancelOrderUtil(this.orderItem.order?.id || '').then((resp: number) => {
            let msg: Resource = $r('app.string.cancel_success')
            if (resp === HttpCode.SUCCESS) {
              this.getMyOrder()
            } else if (resp === HttpCode.STATUE_ERROR) {
              promptAction.showToast({ message: $r('app.string.order_statue_error') })
              this.getMyOrder()
              return
            } else {
              msg = $r('app.string.cancel_failed')
            }
            promptAction.showToast({ message: msg })
          })
        })
    } else if (this.orderItem.order?.dnState === DnState.COMPLETED) {
      Text($r('app.string.delete_order'))
        .border({
          width: 1,
          color: $r('sys.color.font_secondary'),
        })
        .height(28)
        .width(72)
        .fontSize($r('sys.float.Body_M'))
        .textAlign(TextAlign.Center)
        .fontColor($r('sys.color.font_secondary'))
        .borderRadius(14)
        .onClick(() => {
          promptAction.showDialog({
            title: $r('app.string.delete_order'),
            message: $r('app.string.delete_confirm'),
            buttons: [
              {
                text: $r('app.string.cancel'),
                color: $r('sys.color.font_primary'),
              },
              {
                text: $r('app.string.confirm'),
                color: $r('sys.color.multi_color_09'),
              },
            ],
          }, (err, data) => {
            if (err) {
              console.error('showDialog err: ' + err);
              return;
            }
            if (data.index === 1) {
              if (this.orderItem.order?.id) {
                HttpRequestApi.deleteOrder(this.orderItem.order.id).then(() => {
                  this.getMyOrder()
                })
              } else {
                promptAction.showToast({ message: $r('app.string.order_not_exist') })
              }
            }
            console.info('showDialog success callback, click button: ' + data.index);
          });
        })
      Text($r('app.string.one_more_order'))
        .border({
          width: 1,
          color: $r('sys.color.multi_color_09'),
        })
        .height(28)
        .width(72)
        .fontSize($r('sys.float.Body_M'))
        .textAlign(TextAlign.Center)
        .fontColor($r('sys.color.multi_color_09'))
        .borderRadius(14)
        .onClick(() => {
          this.currentIndex = 0
        })
    } else {
      Text($r('app.string.contact_store'))
        .border({
          width: 1,
          color: $r('sys.color.multi_color_09'),
        })
        .height(28)
        .width(72)
        .fontSize($r('sys.float.Body_M'))
        .textAlign(TextAlign.Center)
        .fontColor($r('sys.color.multi_color_09'))
        .borderRadius(14)
        .onClick(() => {
          this.callTelSheet = true
        })
        .bindSheet($$this.callTelSheet, CallTelDialogBuilder(this.storeInfo.tel!, () => {
          this.callTelSheet = false
        }), {
          height: 309,
          blurStyle: BlurStyle.Thick,
          showClose: false,
        });
    }
  }.layoutWeight(1).justifyContent(FlexAlign.End)
}
.width(Constants.FULL_SIZE)
.margin({ top: 12 })
.justifyContent(FlexAlign.SpaceBetween)
4. 支付功能

点击支付按钮后,弹出支付面板,确认支付后调用华为支付接口进行支付。

confirmOrder() {
  // 拉华为支付
  HttpRequestApi.getHuaweiPayInfo(this.orderItem.order?.id ?? '').then((resp: number) => {
    if (resp === HttpCode.SUCCESS) {
      promptAction.showToast({ message: $r('app.string.pay_success') })
      this.getMyOrder()
    } else if (resp === HttpCode.STATUE_ERROR) {
      promptAction.showToast({ message: $r('app.string.order_statue_error') })
      this.getMyOrder()
    } else {
      promptAction.showToast({ message: $r('app.string.pay_failed') })
    }
  }).catch((e: BusinessError) => {
    console.error(`getHuaweiPayInfo error: ${JSON.stringify(e)}.`);
    promptAction.showToast({ message: $r('app.string.pay_failed_msg', JSON.stringify(e)) })
  })
}

通过以上核心功能的实现,在HarmonyOS 5应用中成功开发了订单卡片组件,为用户提供了便捷的订单管理体验。### Harmonyos5应用开发实战——订单商品卡片组件开发

文章内容概要

本文聚焦于HarmonyOS 5应用开发中订单商品卡片组件的实现。该组件主要用于展示订单中的商品信息,包括套餐商品、单品商品和必选商品,并根据商品类型进行分类展示,同时显示商品的基本信息、价格和数量等。

核心功能介绍

1. 商品分类展示

在组件初始化时,根据商品的类型(必选品、套餐、单品)对商品列表进行分类,分别存储在不同的状态变量中。

aboutToAppear(): void {
  this.goodList.forEach(item => {
    if (item.isMust === Constants.GOODS_MUST) {
      this.carMustGoodList.push(item);
    } else if (item.specType === GoodSpecEnum.PACKAGE_TYPE) {
      this.carPgkGoodList.push(item);
    } else {
      this.carGoodList.push(item);
    }
  });
}
2. 套餐商品展示

对于套餐商品,展示商品的基本信息、原价、折扣和实际价格,同时显示套餐内的具体商品组合。

@Component
export struct GoodPkgCard {
  @Prop goodInfo: CarGoodInfo | GoodsOfOrder;

  build() {
    Column() {
      Row() {
        Row() {
          Image(`${CommonUrl.CLOUD_STORAGE_URL}${this.goodInfo.logo}`).width(50).height(50).borderRadius(8)
          Column() {
            Text(this.goodInfo.name)
              .fontSize($r('sys.float.Body_M'))
              .fontColor($r('sys.color.font_primary'))
              .fontWeight(FontWeight.Medium)
              .maxLines(2)
              .textOverflow({ overflow: TextOverflow.Ellipsis });

            Row() {
              Text(`x`)
                .fontSize($r('sys.float.Caption_M'))
                .fontColor($r('sys.color.font_secondary'))
              Text(`${this.goodInfo.num}`)
                .fontSize($r('sys.float.Caption_L'))
                .fontColor($r('sys.color.font_secondary'))
            }.alignItems(VerticalAlign.Bottom)
          }
          .margin({ left: 8 })
          .alignItems(HorizontalAlign.Start)
          .justifyContent(FlexAlign.SpaceBetween);
        }.layoutWeight(1);

        Row() {
          Text($r('app.string.currency_symbol_post_params',
            new Decimal(this.goodInfo.money2).mul(this.goodInfo.num!).toString()))
            .fontSize($r('sys.float.Caption_S'))
            .fontColor($r('sys.color.font_primary'))
            .decoration({
              type: TextDecorationType.LineThrough,
              color: $r('sys.color.font_secondary'),
            });
          Text($r('app.string.discount', this.goodInfo.discount))
            .fontSize($r('sys.float.Caption_L'))
            .fontColor($r('sys.color.multi_color_09'))
            .padding({
              left: 4,
              right: 4,
              top: 2,
              bottom: 2,
            })
            .borderWidth(1)
            .borderColor($r('sys.color.multi_color_09'))
            .borderRadius(4)
            .margin({ left: 4, right: 4 });
          Text() {
            Span($r('app.string.currency_symbol'))
              .fontSize($r('sys.float.Caption_S'))
              .fontWeight(FontWeight.Medium)
              .fontColor($r('sys.color.font_primary'))
            Span(new Decimal(this.goodInfo.money).mul(new Decimal(this.goodInfo.num)).toString())
              .fontSize($r('sys.float.Body_M'))
              .fontWeight(FontWeight.Medium)
              .fontColor($r('sys.color.font_primary'))
          };
        }.height(50).alignItems(VerticalAlign.Bottom);
      }.width(Constants.FULL_SIZE).justifyContent(FlexAlign.SpaceBetween);

      Column() {
        List({ space: 8 }) {
          ForEach(this.goodInfo.combination, (item: PackageSpec) => {
            ListItem() {
              Row() {
                Text(item.specName).fontSize($r('sys.float.Caption_L')).fontColor($r('sys.color.font_primary'))
                Text(`x${item.specNum}`).fontSize($r('sys.float.Caption_L')).fontColor($r('sys.color.font_secondary'))
              }.width(Constants.FULL_SIZE).justifyContent(FlexAlign.SpaceBetween);
            };
          }, (item: PackageSpec) => JSON.stringify(item));
        };
      }.margin({ top: 12 })
    };
  }
}