img

一、场景介绍

在电商应用中,订单进度跟踪是一个重要的功能。本文将介绍如何使用StepperItem组件来构建一个订单进度跟踪界面,展示订单从下单到收货的完整流程。

二、功能实现

1. 页面结构设计

@Entry
@Component
struct OrderTrackingExample {
  @State orderStatus: number = 2  // 当前订单状态:0-已下单,1-已付款,2-已发货,3-已送达,4-已完成
  @State orderInfo: {
    orderNo: string,
    createTime: string,
    payTime: string,
    shipTime: string,
    deliveryTime: string,
    completeTime: string
  } = {
    orderNo: 'ORDER20240101001',
    createTime: '2024-01-01 10:00:00',
    payTime: '2024-01-01 10:05:00',
    shipTime: '2024-01-01 14:00:00',
    deliveryTime: '',
    completeTime: ''
  }

  build() {
    Column() {
      // 订单信息
      this.renderOrderInfo()

      // 进度跟踪
      Stepper() {
        // 已下单
        StepperItem() {
          Column() {
            Text('已下单')
              .fontSize(16)
              .fontWeight(FontWeight.Bold)
            Text(this.orderInfo.createTime)
              .fontSize(12)
              .opacity(0.6)
              .margin({ top: 4 })
          }
        }
        .status(ItemState.COMPLETED)

        // 已付款
        StepperItem() {
          Column() {
            Text('已付款')
              .fontSize(16)
              .fontWeight(FontWeight.Bold)
            Text(this.orderInfo.payTime)
              .fontSize(12)
              .opacity(0.6)
              .margin({ top: 4 })
          }
        }
        .status(ItemState.COMPLETED)

        // 已发货
        StepperItem() {
          Column() {
            Text('已发货')
              .fontSize(16)
              .fontWeight(FontWeight.Bold)
            Text(this.orderInfo.shipTime)
              .fontSize(12)
              .opacity(0.6)
              .margin({ top: 4 })
          }
        }
        .status(this.orderStatus >= 2 ? ItemState.COMPLETED :
                this.orderStatus === 1 ? ItemState.CURRENT : ItemState.WAITING)

        // 已送达
        StepperItem() {
          Column() {
            Text('已送达')
              .fontSize(16)
              .fontWeight(FontWeight.Bold)
            Text(this.orderInfo.deliveryTime || '待配送')
              .fontSize(12)
              .opacity(0.6)
              .margin({ top: 4 })
          }
        }
        .status(this.orderStatus >= 3 ? ItemState.COMPLETED :
                this.orderStatus === 2 ? ItemState.CURRENT : ItemState.WAITING)

        // 已完成
        StepperItem() {
          Column() {
            Text('已完成')
              .fontSize(16)
              .fontWeight(FontWeight.Bold)
            Text(this.orderInfo.completeTime || '待完成')
              .fontSize(12)
              .opacity(0.6)
              .margin({ top: 4 })
          }
        }
        .status(this.orderStatus >= 4 ? ItemState.COMPLETED :
                this.orderStatus === 3 ? ItemState.CURRENT : ItemState.WAITING)
      }
      .margin({ top: 20 })

      // 物流信息
      this.renderLogistics()

      // 操作按钮
      if (this.orderStatus === 2) {
        Button('确认收货')
          .onClick(() => this.confirmDelivery())
          .margin({ top: 40 })
      } else if (this.orderStatus === 3) {
        Button('完成订单')
          .onClick(() => this.completeOrder())
          .margin({ top: 40 })
      }
    }
    .padding(20)
  }

  @Builder
  renderOrderInfo() {
    Column() {
      Text('订单详情')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 16 })

      Row() {
        Text('订单编号:')
          .fontSize(14)
          .opacity(0.6)
        Text(this.orderInfo.orderNo)
          .fontSize(14)
      }
      .width('100%')
      .margin({ top: 8 })
    }
    .width('100%')
    .backgroundColor('#F5F5F5')
    .padding(16)
    .borderRadius(8)
  }

  @Builder
  renderLogistics() {
    if (this.orderStatus >= 2) {
      Column() {
        Text('物流信息')
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
          .margin({ top: 40, bottom: 16 })

        Column() {
          Text('【深圳市】已从深圳发货仓发出')
            .fontSize(14)
          Text('2024-01-01 14:00:00')
            .fontSize(12)
            .opacity(0.6)
            .margin({ top: 4 })
        }
        .backgroundColor('#F5F5F5')
        .padding(16)
        .borderRadius(8)
        .width('100%')
      }
    }
  }

  confirmDelivery() {
    AlertDialog.show({
      title: '确认收货',
      message: '请确认是否已收到商品?',
      confirm: {
        value: '确认收货',
        action: () => {
          // 更新订单状态和时间
          this.orderStatus = 3
          this.orderInfo.deliveryTime = this.getCurrentTime()
        }
      },
      cancel: {
        value: '取消'
      }
    })
  }

  completeOrder() {
    // 更新订单状态和时间
    this.orderStatus = 4
    this.orderInfo.completeTime = this.getCurrentTime()
  }

  getCurrentTime(): string {
    const now = new Date()
    return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`
  }
}

三、实现要点

1. 状态管理

  • 使用@State装饰器管理订单状态和信息
  • 根据订单状态动态更新StepperItem的显示状态
  • 实现了订单状态和时间的自动更新

2. 界面布局

  • 采用垂直布局展示订单信息和进度
  • 使用Column组件组织每个步骤的内容
  • 添加了物流信息的展示区域

3. 交互设计

  • 实现了确认收货和完成订单的功能
  • 添加了操作确认对话框
  • 根据订单状态显示不同的操作按钮

四、总结

本文通过HarmonyOS的StepperItem组件实现了一个订单进度跟踪界面,清晰地展示了从下单到收货的完整流程。通过状态管理、界面布局和交互设计,实现了动态更新订单状态、展示物流信息以及用户操作的功能,提升了用户体验和信息展示的清晰度。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐