在电商应用中,订单管理是用户查看和管理购买记录的重要功能。本文将深入分析一个基于 React Native 实现的订单列表系统,探讨其架构设计、技术实现以及鸿蒙跨端适配策略。

核心数据

该系统构建了清晰的订单数据模型,为订单管理提供了完整的数据支持:

// 订单状态类型
type OrderStatus = 'pending-payment' | 'pending-delivery' | 'shipped' | 'delivered' | 'cancelled' | 'refunded';

// 订单项目类型
type OrderItem = {
  id: string;
  name: string;
  price: number;
  quantity: number;
  image: string;
};

// 订单类型
type Order = {
  id: string;
  orderNumber: string;
  date: string;
  status: OrderStatus;
  totalAmount: number;
  items: OrderItem[];
  shippingAddress: string;
  estimatedDelivery?: string;
};

这种数据模型设计的优势:

  • 类型安全:使用 TypeScript 联合类型定义订单状态,确保状态值的合法性
  • 完整性:涵盖了订单的所有核心属性,包括订单号、状态、商品、地址等
  • 关联性:订单包含多个订单项,构建了完整的订单结构
  • 扩展性:支持添加更多属性,如物流信息、支付方式等

状态管理

系统采用了 React Hooks 中的 useState 进行轻量级状态管理:

const [orders] = useState<Order[]>([
  // 订单数据...
]);

const [activeTab, setActiveTab] = useState<OrderStatus | 'all'>('all');

这种状态管理方式具有以下优势:

  • 模块化:将订单数据和标签页状态分离管理,提高代码可读性
  • 响应式:状态变更自动触发组件重渲染,确保 UI 与数据同步
  • 跨端兼容:React Hooks 在鸿蒙系统的 React Native 实现中通常都有良好支持
  • 简洁性:代码结构清晰,易于理解和维护

订单状态

系统实现了完整的订单状态处理逻辑:

const getStatusText = (status: OrderStatus): string => {
  switch (status) {
    case 'pending-payment': return '待付款';
    case 'pending-delivery': return '待发货';
    case 'shipped': return '已发货';
    case 'delivered': return '已签收';
    case 'cancelled': return '已取消';
    case 'refunded': return '已退款';
    default: return '未知状态';
  }
};

const getStatusColor = (status: OrderStatus): string => {
  switch (status) {
    case 'pending-payment': return '#f59e0b';
    case 'pending-delivery': return '#3b82f6';
    case 'shipped': return '#10b981';
    case 'delivered': return '#10b981';
    case 'cancelled': return '#9ca3af';
    case 'refunded': return '#8b5cf6';
    default: return '#9ca3af';
  }
};

订单状态处理支持:

  • 状态文本转换:将订单状态枚举值转换为用户友好的文本
  • 状态颜色映射:根据订单状态设置不同的颜色,增强视觉反馈
  • 状态过滤:根据选中的标签页过滤显示的订单
  • 状态操作:根据订单状态提供不同的操作按钮

订单操作

系统实现了基于订单状态的操作处理逻辑:

const handleOrderAction = (orderId: string, status: OrderStatus) => {
  switch (status) {
    case 'pending-payment':
      Alert.alert('去付款', `为订单 ${orderId} 进行付款`);
      break;
    case 'shipped':
      Alert.alert('查看物流', `查看订单 ${orderId} 的物流信息`);
      break;
    case 'delivered':
      Alert.alert('确认收货', `确认收货订单 ${orderId}`);
      break;
    case 'cancelled':
      Alert.alert('订单详情', `查看已取消订单 ${orderId} 的详情`);
      break;
    default:
      Alert.alert('订单详情', `查看订单 ${orderId} 的详情`);
  }
};

订单操作支持:

  • 待付款:跳转到付款页面
  • 已发货:查看物流信息
  • 已签收:确认收货
  • 已取消:查看订单详情
  • 其他状态:查看订单详情

基础架构

该实现采用了 React Native 核心组件库,确保了在鸿蒙系统上的基本兼容性:

  • SafeAreaView:适配刘海屏等异形屏
  • ScrollView:处理内容滚动,确保长页面可浏览
  • TouchableOpacity:提供触摸反馈,增强用户体验
  • FlatList:高效渲染订单列表和订单项,支持虚拟滚动
  • Image:显示商品图片和其他视觉元素
  • Alert:系统级弹窗提示,提供操作反馈

Base64 图标

系统使用 Base64 编码的图标库,这种处理方式在跨端开发中尤为重要:

  • 避免了不同平台对资源文件格式的兼容性问题
  • 减少了网络请求,提高了加载速度
  • 简化了构建流程,无需处理多平台资源文件
  • 确保图标在不同设备上的显示一致性

屏幕尺寸适配

系统通过 Dimensions API 获取屏幕尺寸,确保了在不同屏幕尺寸的设备上都能获得一致的布局体验,无论是 React Native 环境还是鸿蒙系统:

const { width, height } = Dimensions.get('window');

系统采用了模块化的样式定义,确保了样式的一致性和可维护性:

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f5f5f5',
  },
  // 其他样式...
});

这种方式为后续的主题定制和深色模式适配预留了扩展空间。


在鸿蒙系统上使用 React Native 时,应注意以下 API 兼容性问题:

  1. FlatList API:鸿蒙系统的 FlatList 实现可能与 React Native 有所差异,建议测试确认滚动和渲染行为
  2. Alert API:鸿蒙系统的 Alert 实现可能与 React Native 有所差异,建议测试确认弹窗行为
  3. TouchableOpacity API:鸿蒙系统的 TouchableOpacity 实现可能与 React Native 有所差异,建议测试确认触摸反馈

本订单管理系统实现了一个功能完整、用户友好的订单列表界面,通过合理的架构设计和代码组织,为用户提供了良好的订单管理体验。在跨端开发场景下,该实现充分考虑了 React Native 和鸿蒙系统的兼容性需求,为后续的功能扩展和性能优化预留了空间。

通过订单状态处理、订单操作、商品展示等核心功能,结合 Base64 图标处理、FlatList 优化等技术手段,该系统不仅功能完善,而且具有良好的可维护性和可扩展性。这些实践经验对于构建其他跨端应用组件也具有参考价值。


订单列表是电商类应用的核心功能模块,其设计需要兼顾状态可视化、数据结构化、操作便捷性、跨端体验一致性四大核心诉求。本文将从类型系统设计、状态管理逻辑、UI 组件实现三个维度拆解这份 React Native 订单列表应用代码,并提供完整的鸿蒙(HarmonyOS)ArkTS 跨端适配方案,为跨端电商订单模块开发提供可落地的技术参考。

1. 数据模型

订单场景的核心是多状态管理、多商品聚合、多维度信息展示,代码通过 TypeScript 构建了精准匹配电商订单场景的类型体系,为后续的状态渲染和交互逻辑奠定了坚实基础:

// 订单状态类型:覆盖电商订单全生命周期
type OrderStatus = 'pending-payment' | 'pending-delivery' | 'shipped' | 'delivered' | 'cancelled' | 'refunded';

// 订单商品项类型:描述订单中的单个商品信息
type OrderItem = {
  id: string;
  name: string;
  price: number;
  quantity: number;
  image: string;
};

// 订单主类型:聚合订单核心信息
type Order = {
  id: string;
  orderNumber: string;
  date: string;
  status: OrderStatus;
  totalAmount: number;
  items: OrderItem[];
  shippingAddress: string;
  estimatedDelivery?: string; // 可选字段:仅已发货状态有预计送达时间
};

设计亮点解析

  • 状态枚举化OrderStatus 类型通过联合类型限定订单状态的取值范围,避免非法状态值的出现,符合电商订单的标准化管理规范;
  • 数据分层合理:将订单拆分为「主订单」和「订单项」两层结构,既满足订单级别的操作(付款、查看物流),也支持商品级别的展示(图片、价格、数量);
  • 可选字段精准estimatedDelivery 作为可选字段,仅在已发货状态下展示,避免空值渲染异常;
  • 业务属性完备:包含订单号、下单时间、总金额、收货地址等核心字段,覆盖订单展示的全维度需求;
  • 类型安全保障:所有字段类型明确,编译阶段即可发现数据异常,降低生产环境 bug 率;
  • 扩展性预留OrderItem 支持多商品聚合,适配一个订单包含多个商品的真实业务场景。

2. 状态管理

订单列表的交互核心是状态筛选、状态可视化、订单操作,代码通过 React 的 useState 构建了轻量且高效的状态管理体系,兼顾性能与业务灵活性:

(1)核心状态初始化
// 订单列表:模拟后端返回的订单数据
const [orders] = useState<Order[]>([/* 订单数据 */]);

// 激活标签页:控制订单状态筛选
const [activeTab, setActiveTab] = useState<OrderStatus | 'all'>('all');

初始化策略分析

  • 数据与状态分离:静态的订单数据与动态的筛选状态分离,符合“数据驱动 UI”的最佳实践;
  • 筛选状态合理:默认展示全部订单,贴合用户查看订单的核心诉求;
  • 状态类型精准activeTab 类型限定为订单状态或 all,避免非法筛选值的出现;
  • 不可变数据处理:订单数据使用 const [orders] = useState() 声明,避免不必要的重渲染。

① 订单状态
// 状态文本映射:将枚举值转换为用户可读的中文
const getStatusText = (status: OrderStatus): string => {
  switch (status) {
    case 'pending-payment': return '待付款';
    case 'pending-delivery': return '待发货';
    case 'shipped': return '已发货';
    case 'delivered': return '已签收';
    case 'cancelled': return '已取消';
    case 'refunded': return '已退款';
    default: return '未知状态';
  }
};

// 状态颜色映射:不同状态使用差异化色彩,增强视觉辨识度
const getStatusColor = (status: OrderStatus): string => {
  switch (status) {
    case 'pending-payment': return '#f59e0b'; // 黄色:提醒付款
    case 'pending-delivery': return '#3b82f6'; // 蓝色:待处理
    case 'shipped': return '#10b981';         // 绿色:处理中
    case 'delivered': return '#10b981';       // 绿色:完成
    case 'cancelled': return '#9ca3af';       // 灰色:已取消
    case 'refunded': return '#8b5cf6';        // 紫色:退款
    default: return '#9ca3af';
  }
};

可视化设计亮点

  • 用户体验优化:将技术枚举值转换为用户易懂的中文文本,降低认知成本;
  • 视觉分层清晰:通过色彩心理学设计状态色值(黄色提醒、绿色完成、灰色取消),用户可快速识别订单状态;
  • 扩展性强:新增状态时仅需在 switch 中添加对应分支,无需修改渲染逻辑;
  • 容错机制:默认返回“未知状态”和灰色,避免状态值异常导致的 UI 崩溃。
② 订单筛选逻辑
// 基于激活标签页筛选订单,all 时展示全部
const filteredOrders = activeTab === 'all' 
  ? orders 
  : orders.filter(order => order.status === activeTab);

筛选逻辑解析

  • 逻辑简洁高效:三元表达式实现核心筛选逻辑,可读性强且性能优异;
  • 精准匹配:通过状态字符串精准匹配,保证筛选结果的准确性;
  • 无感知渲染:筛选结果直接作为 FlatList 的数据源,状态变化时自动刷新列表。
③ 订单操作逻辑
const handleOrderAction = (orderId: string, status: OrderStatus) => {
  switch (status) {
    case 'pending-payment':
      Alert.alert('去付款', `为订单 ${orderId} 进行付款`);
      break;
    case 'shipped':
      Alert.alert('查看物流', `查看订单 ${orderId} 的物流信息`);
      break;
    case 'delivered':
      Alert.alert('确认收货', `确认收货订单 ${orderId}`);
      break;
    case 'cancelled':
      Alert.alert('订单详情', `查看已取消订单 ${orderId} 的详情`);
      break;
    default:
      Alert.alert('订单详情', `查看订单 ${orderId} 的详情`);
  }
};

操作逻辑亮点

  • 状态驱动操作:不同状态的订单展示不同的操作按钮,符合电商业务逻辑;
  • 用户反馈明确:通过 Alert 提示操作意图,为后续对接真实 API 预留接口;
  • 容错机制:默认展示订单详情,避免未定义状态的操作异常;
  • 参数传递清晰:传递订单 ID 和状态,满足后端接口调用的参数需求。

订单列表的视觉核心是多状态订单卡片、嵌套商品列表、操作按钮组,代码通过 FlatList 实现高性能渲染,并结合样式系统构建符合电商视觉规范的界面:

(1)嵌套列表
<FlatList
  data={item.items}
  renderItem={({ item: orderItem }) => (
    <View style={styles.itemRow}>
      <Image source={{ uri: orderItem.image }} style={styles.itemImage} />
      <View style={styles.itemInfo}>
        <Text style={styles.itemName} numberOfLines={1}>{orderItem.name}</Text>
        <Text style={styles.itemPrice}>¥{orderItem.price} x {orderItem.quantity}</Text>
      </View>
    </View>
  )}
  keyExtractor={item => item.id}
  showsVerticalScrollIndicator={false}
/>

嵌套列表设计解析

  • 性能优化:使用 FlatList 而非 map 渲染订单项,支持商品列表的复用,提升长订单的滚动性能;
  • 视觉优化numberOfLines={1} 限制商品名称单行显示,避免名称过长导致的布局错乱;
  • 布局合理:图片+文字的横向布局,符合移动端商品展示的视觉习惯;
  • 交互友好:隐藏垂直滚动条,提升视觉体验。
(2)订单卡片
<View style={styles.orderCard}>
  {/* 订单头部:订单号+状态 */}
  <View style={styles.orderHeader}>
    <Text style={styles.orderNumber}>订单号: {item.orderNumber}</Text>
    <Text style={[styles.statusText, { color: getStatusColor(item.status) }]}>
      {getStatusText(item.status)}
    </Text>
  </View>
  
  {/* 下单时间 */}
  <View style={styles.orderDate}>
    <Text style={styles.dateText}>下单时间: {item.date}</Text>
  </View>
  
  {/* 订单项列表 */}
  <View style={styles.orderItems}>
    {/* 嵌套FlatList */}
  </View>
  
  {/* 订单汇总:商品数量+总金额 */}
  <View style={styles.orderSummary}>
    <Text style={styles.totalText}>{item.items.reduce((sum, item) => sum + item.quantity, 0)}件商品</Text>
    <Text style={styles.totalAmount}>¥{item.totalAmount}</Text>
  </View>
  
  {/* 收货地址 */}
  <View style={styles.shippingInfo}>
    {/* 地址展示 */}
  </View>
  
  {/* 预计送达时间(可选) */}
  {item.estimatedDelivery && (
    <View style={styles.deliveryInfo}>
      {/* 预计送达时间展示 */}
    </View>
  )}
  
  {/* 操作按钮组 */}
  <View style={styles.orderActions}>
    {/* 状态对应的操作按钮 */}
  </View>
</View>

视觉设计解析

  • 信息层级清晰:订单号/状态 → 下单时间 → 商品列表 → 订单汇总 → 收货地址 → 操作按钮,符合用户查看订单的视觉流;
  • 状态可视化:状态文本使用对应颜色,视觉辨识度高;
  • 条件渲染精准:仅在有预计送达时间时展示该模块,避免空信息展示;
  • 汇总信息直观:通过 reduce 计算商品总数,展示订单总金额,核心信息突出;
  • 操作按钮适配:不同状态展示不同的操作按钮,符合业务逻辑;
  • 卡片式布局:圆角+阴影+内边距的组合,营造立体感和层次感。

代码通过 StyleSheet.create 构建了符合电商订单场景的样式体系,核心设计原则包括:

  • 色彩体系统一:状态色值与电商平台一致,主操作按钮使用蓝色(#3b82f6),金额使用红色(#ef4444),中性色使用灰度系;
  • 圆角规范:卡片(12px)、按钮(6px)、商品图片(4px),不同元素使用差异化圆角,增强视觉层次感;
  • 间距体系:采用 16/12/8/4px 的间距梯度,保证页面布局的呼吸感;
  • 文字层级:通过字体大小(20/16/14/12px)和字重区分信息优先级;
  • 状态样式分离:操作按钮与详情按钮使用不同背景色,视觉区分明显;
  • 固定底部导航:绝对定位+顶部边框高亮当前页,符合移动端导航设计习惯;
  • 边框分隔:订单汇总区域使用顶部边框,区分商品列表和汇总信息,视觉分割清晰。

将 React Native 订单列表应用迁移至鸿蒙平台,核心是基于 ArkTS + ArkUI 实现数据模型、状态管理、列表渲染、交互逻辑的对等还原,同时适配鸿蒙的组件特性和交互范式。

1. 核心适配

@Entry
@Component
struct OrderListApp {
  // 数据模型:完全复用 RN 端字段定义
  @State orders: Order[] = [/* 订单数据 */];
  @State activeTab: OrderStatus | 'all' = 'all';

  // 状态文本映射:对等实现
  getStatusText(status: OrderStatus): string {
    switch (status) {
      case 'pending-payment': return '待付款';
      case 'pending-delivery': return '待发货';
      case 'shipped': return '已发货';
      case 'delivered': return '已签收';
      case 'cancelled': return '已取消';
      case 'refunded': return '已退款';
      default: return '未知状态';
    }
  }

  // 状态颜色映射:对等实现
  getStatusColor(status: OrderStatus): string {
    switch (status) {
      case 'pending-payment': return '#f59e0b';
      case 'pending-delivery': return '#3b82f6';
      case 'shipped': return '#10b981';
      case 'delivered': return '#10b981';
      case 'cancelled': return '#9ca3af';
      case 'refunded': return '#8b5cf6';
      default: return '#9ca3af';
    }
  }

  // 订单操作逻辑:对等实现
  handleOrderAction(orderId: string, status: OrderStatus) {
    switch (status) {
      case 'pending-payment':
        AlertDialog.show({
          title: '去付款',
          message: `为订单 ${orderId} 进行付款`,
          confirm: { value: '确定' }
        });
        break;
      // 其他状态逻辑...
    }
  }

  // 列表项渲染:使用 @Builder 封装
  @Builder
  renderOrderItem(item: Order) {
    // 订单卡片渲染逻辑(对等还原 RN 端 UI)
  }

  // 页面构建:镜像 RN 端布局结构
  build() {
    Column()
      .flex(1)
      .backgroundColor('#f5f7fa')
      .safeArea(true) {
      
      // 头部区域
      // 标签页区域
      // 订单列表区域
      // 快捷入口区域
      // 订单帮助区域
      // 底部导航区域
    }
  }
}

React Native 特性 鸿蒙 ArkUI 对应实现 适配关键说明
useState @State 装饰器 状态初始化与更新逻辑完全复用,仅调整语法形式
FlatList ForEach 组件 列表渲染逻辑对等,嵌套列表通过双层 ForEach 实现
TouchableOpacity Button + onClick 可点击组件的交互逻辑完全复用
ScrollView Scroll 组件 滚动容器语法差异,功能一致
Alert.alert AlertDialog.show 弹窗 API 语法差异,交互逻辑对等
StyleSheet 链式样式 样式属性(颜色、间距、圆角等)100% 复用
numberOfLines={1} maxLines: 1 文本行数限制属性名差异,效果一致
reduce 计算 原生 JS/TS 语法 商品总数计算逻辑完全复用
条件渲染 && if 语句 预计送达时间等条件渲染逻辑对等实现
嵌套列表 双层 ForEach 订单列表嵌套商品列表的结构一致
动态样式对象 条件样式绑定 状态文本颜色动态绑定逻辑一致
Dimensions viewport API 屏幕尺寸获取方式不同,本案例未使用

3. 鸿蒙代码

// 鸿蒙 ArkTS 完整实现
type OrderStatus = 'pending-payment' | 'pending-delivery' | 'shipped' | 'delivered' | 'cancelled' | 'refunded';

interface OrderItem {
  id: string;
  name: string;
  price: number;
  quantity: number;
  image: string;
}

interface Order {
  id: string;
  orderNumber: string;
  date: string;
  status: OrderStatus;
  totalAmount: number;
  items: OrderItem[];
  shippingAddress: string;
  estimatedDelivery?: string;
}

@Entry
@Component
struct OrderListApp {
  @State orders: Order[] = [
    {
      id: 'o1',
      orderNumber: 'ORD202310150001',
      date: '2023-10-15',
      status: 'pending-payment',
      totalAmount: 10997,
      items: [
        { id: 'i1', name: 'iPhone 15 Pro Max', price: 9999, quantity: 1, image: 'https://via.placeholder.com/60x60' },
        { id: 'i2', name: '手机壳', price: 299, quantity: 1, image: 'https://via.placeholder.com/60x60' },
        { id: 'i3', name: '钢化膜', price: 699, quantity: 1, image: 'https://via.placeholder.com/60x60' }
      ],
      shippingAddress: '北京市朝阳区某某街道123号',
    },
    {
      id: 'o2',
      orderNumber: 'ORD202310140002',
      date: '2023-10-14',
      status: 'shipped',
      totalAmount: 5999,
      items: [
        { id: 'i4', name: '小米13 Ultra', price: 5999, quantity: 1, image: 'https://via.placeholder.com/60x60' }
      ],
      shippingAddress: '上海市浦东新区某某路456号',
      estimatedDelivery: '2023-10-20'
    },
    {
      id: 'o3',
      orderNumber: 'ORD202310130003',
      date: '2023-10-13',
      status: 'delivered',
      totalAmount: 8999,
      items: [
        { id: 'i5', name: '戴尔XPS 13', price: 8999, quantity: 1, image: 'https://via.placeholder.com/60x60' }
      ],
      shippingAddress: '广州市天河区某某大道789号'
    },
    {
      id: 'o4',
      orderNumber: 'ORD202310120004',
      date: '2023-10-12',
      status: 'cancelled',
      totalAmount: 2499,
      items: [
        { id: 'i6', name: '索尼WH-1000XM5', price: 2499, quantity: 1, image: 'https://via.placeholder.com/60x60' }
      ],
      shippingAddress: '深圳市南山区某某科技园101号'
    },
    {
      id: 'o5',
      orderNumber: 'ORD202310110005',
      date: '2023-10-11',
      status: 'delivered',
      totalAmount: 3299,
      items: [
        { id: 'i7', name: '美的变频空调', price: 3299, quantity: 1, image: 'https://via.placeholder.com/60x60' }
      ],
      shippingAddress: '杭州市西湖区某某街道202号'
    }
  ];

  @State activeTab: OrderStatus | 'all' = 'all';

  getStatusText(status: OrderStatus): string {
    switch (status) {
      case 'pending-payment': return '待付款';
      case 'pending-delivery': return '待发货';
      case 'shipped': return '已发货';
      case 'delivered': return '已签收';
      case 'cancelled': return '已取消';
      case 'refunded': return '已退款';
      default: return '未知状态';
    }
  }

  getStatusColor(status: OrderStatus): string {
    switch (status) {
      case 'pending-payment': return '#f59e0b';
      case 'pending-delivery': return '#3b82f6';
      case 'shipped': return '#10b981';
      case 'delivered': return '#10b981';
      case 'cancelled': return '#9ca3af';
      case 'refunded': return '#8b5cf6';
      default: return '#9ca3af';
    }
  }

  handleOrderAction(orderId: string, status: OrderStatus) {
    switch (status) {
      case 'pending-payment':
        AlertDialog.show({
          title: '去付款',
          message: `为订单 ${orderId} 进行付款`,
          confirm: { value: '确定' }
        });
        break;
      case 'shipped':
        AlertDialog.show({
          title: '查看物流',
          message: `查看订单 ${orderId} 的物流信息`,
          confirm: { value: '确定' }
        });
        break;
      case 'delivered':
        AlertDialog.show({
          title: '确认收货',
          message: `确认收货订单 ${orderId}`,
          confirm: { value: '确定' }
        });
        break;
      case 'cancelled':
        AlertDialog.show({
          title: '订单详情',
          message: `查看已取消订单 ${orderId} 的详情`,
          confirm: { value: '确定' }
        });
        break;
      default:
        AlertDialog.show({
          title: '订单详情',
          message: `查看订单 ${orderId} 的详细信息`,
          confirm: { value: '确定' }
        });
    }
  }

  get filteredOrders(): Order[] {
    return this.activeTab === 'all' 
      ? this.orders 
      : this.orders.filter(order => order.status === this.activeTab);
  }

  @Builder
  renderOrderItem(item: Order) {
    Column()
      .backgroundColor('#ffffff')
      .borderRadius(12)
      .padding(16)
      .marginBottom(16)
      .shadow({ color: '#000', offsetX: 0, offsetY: 1, opacity: 0.1, radius: 2 }) {
      
      // 订单头部
      Row()
        .justifyContent(FlexAlign.SpaceBetween)
        .alignItems(ItemAlign.Center)
        .marginBottom(8) {
        Text(`订单号: ${item.orderNumber}`)
          .fontSize(14)
          .fontColor('#64748b');
        
        Text(this.getStatusText(item.status))
          .fontSize(14)
          .fontWeight(FontWeight.Medium)
          .fontColor(this.getStatusColor(item.status));
      }

      // 下单时间
      Text(`下单时间: ${item.date}`)
        .fontSize(12)
        .fontColor('#94a3b8')
        .marginBottom(12);

      // 订单项列表
      Column()
        .marginBottom(12) {
        ForEach(item.items, (orderItem: OrderItem) => {
          Row()
            .alignItems(ItemAlign.Center)
            .marginBottom(8) {
            Image(orderItem.image)
              .width(50)
              .height(50)
              .borderRadius(4)
              .marginRight(12);
            
            Column()
              .flexGrow(1) {
              Text(orderItem.name)
                .fontSize(14)
                .fontColor('#1e293b')
                .marginBottom(4)
                .maxLines(1);
              
              Text(`¥${orderItem.price} x ${orderItem.quantity}`)
                .fontSize(12)
                .fontColor('#64748b');
            }
          }
        }, (orderItem: OrderItem) => orderItem.id)
      }

      // 订单汇总
      Row()
        .justifyContent(FlexAlign.SpaceBetween)
        .alignItems(ItemAlign.Center)
        .marginBottom(12)
        .paddingVertical(8)
        .borderTop({ width: 1, color: '#e2e8f0' }) {
        Text(`${item.items.reduce((sum, item) => sum + item.quantity, 0)}件商品`)
          .fontSize(14)
          .fontColor('#64748b');
        
        Text(`¥${item.totalAmount}`)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
          .fontColor('#ef4444');
      }

      // 收货地址
      Row()
        .marginBottom(8) {
        Text('收货地址:')
          .fontSize(12)
          .fontColor('#64748b')
          .width(60);
        
        Text(item.shippingAddress)
          .fontSize(12)
          .fontColor('#1e293b')
          .flexGrow(1)
          .maxLines(1);
      }

      // 预计送达时间(可选)
      if (item.estimatedDelivery) {
        Row()
          .marginBottom(12) {
          Text('预计送达:')
            .fontSize(12)
            .fontColor('#64748b')
            .width(60);
          
          Text(item.estimatedDelivery)
            .fontSize(12)
            .fontColor('#1e293b')
            .flexGrow(1);
        }
      }

      // 操作按钮组
      Row()
        .justifyContent(FlexAlign.FlexEnd) {
        if (item.status === 'pending-payment') {
          Button('立即付款')
            .backgroundColor('#3b82f6')
            .paddingHorizontal(16)
            .paddingVertical(8)
            .borderRadius(6)
            .marginRight(8)
            .onClick(() => this.handleOrderAction(item.id, item.status)) {
            Text('立即付款')
              .fontSize(14)
              .fontWeight(FontWeight.Medium)
              .fontColor('#ffffff');
          }
        }
        
        if (item.status === 'shipped') {
          Button('查看物流')
            .backgroundColor('#3b82f6')
            .paddingHorizontal(16)
            .paddingVertical(8)
            .borderRadius(6)
            .marginRight(8)
            .onClick(() => this.handleOrderAction(item.id, item.status)) {
            Text('查看物流')
              .fontSize(14)
              .fontWeight(FontWeight.Medium)
              .fontColor('#ffffff');
          }
        }
        
        if (item.status === 'delivered') {
          Button('确认收货')
            .backgroundColor('#3b82f6')
            .paddingHorizontal(16)
            .paddingVertical(8)
            .borderRadius(6)
            .marginRight(8)
            .onClick(() => this.handleOrderAction(item.id, item.status)) {
            Text('确认收货')
              .fontSize(14)
              .fontWeight(FontWeight.Medium)
              .fontColor('#ffffff');
          }
        }
        
        Button('查看详情')
          .backgroundColor('#f1f5f9')
          .paddingHorizontal(16)
          .paddingVertical(8)
          .borderRadius(6)
          .onClick(() => AlertDialog.show({
            title: '订单详情',
            message: `查看订单 ${item.orderNumber} 的详细信息`,
            confirm: { value: '确定' }
          })) {
          Text('查看详情')
            .fontSize(14)
            .fontWeight(FontWeight.Medium)
            .fontColor('#475569');
        }
      }
    }
  }

  build() {
    Column()
      .flex(1)
      .backgroundColor('#f5f7fa')
      .safeArea(true) {
      
      // 头部
      Column()
        .alignItems(ItemAlign.Center)
        .padding(16)
        .backgroundColor('#ffffff')
        .borderBottom({ width: 1, color: '#e2e8f0' }) {
        Text('我的订单')
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .fontColor('#1e293b')
          .marginBottom(4);
        
        Text('查看和管理您的订单')
          .fontSize(14)
          .fontColor('#64748b');
      }

      // 滚动内容区
      Scroll()
        .flex(1) {
        Column() {
          // 标签页
          Row()
            .backgroundColor('#ffffff')
            .marginLeft(16)
            .marginRight(16)
            .borderRadius(8)
            .marginBottom(16)
            .shadow({ color: '#000', offsetX: 0, offsetY: 1, opacity: 0.1, radius: 2 }) {
            
            // 全部
            Button()
              .flexGrow(1)
              .backgroundColor(this.activeTab === 'all' ? '#3b82f6' : Color.Transparent)
              .borderRadius(8)
              .paddingVertical(12)
              .onClick(() => this.activeTab = 'all') {
              Text('全部')
                .fontSize(14)
                .fontColor(this.activeTab === 'all' ? '#ffffff' : '#64748b')
                .fontWeight(FontWeight.Medium);
            }
            
            // 待付款
            Button()
              .flexGrow(1)
              .backgroundColor(this.activeTab === 'pending-payment' ? '#3b82f6' : Color.Transparent)
              .borderRadius(8)
              .paddingVertical(12)
              .onClick(() => this.activeTab = 'pending-payment') {
              Text('待付款')
                .fontSize(14)
                .fontColor(this.activeTab === 'pending-payment' ? '#ffffff' : '#64748b')
                .fontWeight(FontWeight.Medium);
            }
            
            // 待收货
            Button()
              .flexGrow(1)
              .backgroundColor(this.activeTab === 'shipped' ? '#3b82f6' : Color.Transparent)
              .borderRadius(8)
              .paddingVertical(12)
              .onClick(() => this.activeTab = 'shipped') {
              Text('待收货')
                .fontSize(14)
                .fontColor(this.activeTab === 'shipped' ? '#ffffff' : '#64748b')
                .fontWeight(FontWeight.Medium);
            }
            
            // 已完成
            Button()
              .flexGrow(1)
              .backgroundColor(this.activeTab === 'delivered' ? '#3b82f6' : Color.Transparent)
              .borderRadius(8)
              .paddingVertical(12)
              .onClick(() => this.activeTab = 'delivered') {
              Text('已完成')
                .fontSize(14)
                .fontColor(this.activeTab === 'delivered' ? '#ffffff' : '#64748b')
                .fontWeight(FontWeight.Medium);
            }
          }

          // 订单列表
          Column()
            .paddingLeft(16)
            .paddingRight(16) {
            ForEach(this.filteredOrders, (item: Order) => {
              this.renderOrderItem(item);
            }, (item: Order) => item.id)
          }

          // 快捷入口
          Column()
            .backgroundColor('#ffffff')
            .marginLeft(16)
            .marginRight(16)
            .marginBottom(16)
            .borderRadius(12)
            .padding(16)
            .shadow({ color: '#000', offsetX: 0, offsetY: 1, opacity: 0.1, radius: 2 }) {
            
            Text('快捷入口')
              .fontSize(16)
              .fontWeight(FontWeight.Medium)
              .fontColor('#1e293b')
              .marginBottom(12);
            
            Row()
              .justifyContent(FlexAlign.SpaceBetween) {
              Column()
                .alignItems(ItemAlign.Center)
                .flexGrow(1)
                .paddingVertical(8) {
                Text('📦')
                  .fontSize(24)
                  .marginBottom(4);
                Text('待付款')
                  .fontSize(12)
                  .fontColor('#64748b');
              }
              
              Column()
                .alignItems(ItemAlign.Center)
                .flexGrow(1)
                .paddingVertical(8) {
                Text('🚚')
                  .fontSize(24)
                  .marginBottom(4);
                Text('待发货')
                  .fontSize(12)
                  .fontColor('#64748b');
              }
              
              Column()
                .alignItems(ItemAlign.Center)
                .flexGrow(1)
                .paddingVertical(8) {
                Text('📦')
                  .fontSize(24)
                  .marginBottom(4);
                Text('待收货')
                  .fontSize(12)
                  .fontColor('#64748b');
              }
              
              Column()
                .alignItems(ItemAlign.Center)
                .flexGrow(1)
                .paddingVertical(8) {
                Text('⭐')
                  .fontSize(24)
                  .marginBottom(4);
                Text('评价晒单')
                  .fontSize(12)
                  .fontColor('#64748b');
              }
            }
          }

          // 订单帮助
          Column()
            .backgroundColor('#ffffff')
            .marginLeft(16)
            .marginRight(16)
            .marginBottom(80)
            .borderRadius(12)
            .padding(16)
            .shadow({ color: '#000', offsetX: 0, offsetY: 1, opacity: 0.1, radius: 2 }) {
            
            Text('订单帮助')
              .fontSize(16)
              .fontWeight(FontWeight.Medium)
              .fontColor('#1e293b')
              .marginBottom(12);
            
            Text('• 如何修改订单信息?')
              .fontSize(14)
              .fontColor('#64748b')
              .lineHeight(22)
              .marginBottom(8);
            
            Text('• 申请售后流程')
              .fontSize(14)
              .fontColor('#64748b')
              .lineHeight(22)
              .marginBottom(8);
            
            Text('• 查看退换货政策')
              .fontSize(14)
              .fontColor('#64748b')
              .lineHeight(22)
              .marginBottom(8);
            
            Text('• 联系客服')
              .fontSize(14)
              .fontColor('#64748b')
              .lineHeight(22);
          }
        }
      }

      // 底部导航
      Row()
        .justifyContent(FlexAlign.SpaceAround)
        .backgroundColor('#ffffff')
        .borderTop({ width: 1, color: '#e2e8f0' })
        .paddingVertical(12)
        .position(Position.Fixed)
        .bottom(0)
        .width('100%') {
      
      Column()
        .alignItems(ItemAlign.Center)
        .flexGrow(1) {
        Text('🏠')
          .fontSize(20)
          .fontColor('#94a3b8')
          .marginBottom(4);
        Text('首页')
          .fontSize(12)
          .fontColor('#94a3b8');
      }
      
      Column()
        .alignItems(ItemAlign.Center)
        .flexGrow(1) {
        Text('🔍')
          .fontSize(20)
          .fontColor('#94a3b8')
          .marginBottom(4);
        Text('分类')
          .fontSize(12)
          .fontColor('#94a3b8');
      }
      
      Column()
        .alignItems(ItemAlign.Center)
        .flexGrow(1) {
        Text('🛒')
          .fontSize(20)
          .fontColor('#94a3b8')
          .marginBottom(4);
        Text('购物车')
          .fontSize(12)
          .fontColor('#94a3b8');
      }
      
      Column()
        .alignItems(ItemAlign.Center)
        .flexGrow(1)
        .paddingTop(4)
        .borderTop({ width: 2, color: '#3b82f6' }) {
        Text('📦')
          .fontSize(20)
          .fontColor('#3b82f6')
          .marginBottom(4);
        Text('订单')
          .fontSize(12)
          .fontColor('#3b82f6')
          .fontWeight(FontWeight.Medium);
      }
    }
  }
}
  1. 订单列表场景的核心是状态管理与信息结构化展示:多状态的可视化区分、多维度订单信息的层级展示、状态驱动的操作按钮,是跨端适配的核心要点;
  2. 强类型数据模型是跨端复用的基础:精准的 TypeScript/ArkTS 类型定义,保证了数据层在不同平台的一致性和可维护性;
  3. 嵌套列表是性能优化的关键:RN 端的嵌套 FlatList 与鸿蒙端的双层 ForEach 均需做好列表复用,避免长列表性能问题;
  4. 跨端适配的核心是逻辑复用+语法适配:90%以上的业务逻辑和视觉规范可跨端复用,仅需适配平台特有 API 和组件语法;
  5. 电商场景的视觉体验需符合用户认知:订单状态颜色、操作按钮位置、信息展示层级需遵循电商平台的设计规范,保证用户体验一致性;
  6. 状态驱动的 UI 设计是订单模块的核心:订单状态不仅决定展示文本和颜色,还驱动操作按钮的展示和行为,需保证状态与 UI 的精准映射。

这份订单列表应用的跨端适配实践,验证了 React Native 与鸿蒙 ArkTS 在电商核心场景下的高度兼容性,为跨端电商应用开发提供了可落地的技术参考。


真实演示案例代码:






// App.tsx
import React, { useState } from 'react';
import { SafeAreaView, View, Text, StyleSheet, TouchableOpacity, ScrollView, Dimensions, Alert, Image, FlatList } from 'react-native';

// Base64 图标库
const ICONS_BASE64 = {
  pending: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  shipped: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  delivered: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  cancelled: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  refund: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  tracking: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  home: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  user: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
};

const { width, height } = Dimensions.get('window');

// 订单状态类型
type OrderStatus = 'pending-payment' | 'pending-delivery' | 'shipped' | 'delivered' | 'cancelled' | 'refunded';

// 订单项目类型
type OrderItem = {
  id: string;
  name: string;
  price: number;
  quantity: number;
  image: string;
};

// 订单类型
type Order = {
  id: string;
  orderNumber: string;
  date: string;
  status: OrderStatus;
  totalAmount: number;
  items: OrderItem[];
  shippingAddress: string;
  estimatedDelivery?: string;
};

// 订单列表应用组件
const OrderListApp: React.FC = () => {
  const [orders] = useState<Order[]>([
    {
      id: 'o1',
      orderNumber: 'ORD202310150001',
      date: '2023-10-15',
      status: 'pending-payment',
      totalAmount: 10997,
      items: [
        { id: 'i1', name: 'iPhone 15 Pro Max', price: 9999, quantity: 1, image: 'https://via.placeholder.com/60x60' },
        { id: 'i2', name: '手机壳', price: 299, quantity: 1, image: 'https://via.placeholder.com/60x60' },
        { id: 'i3', name: '钢化膜', price: 699, quantity: 1, image: 'https://via.placeholder.com/60x60' }
      ],
      shippingAddress: '北京市朝阳区某某街道123号',
    },
    {
      id: 'o2',
      orderNumber: 'ORD202310140002',
      date: '2023-10-14',
      status: 'shipped',
      totalAmount: 5999,
      items: [
        { id: 'i4', name: '小米13 Ultra', price: 5999, quantity: 1, image: 'https://via.placeholder.com/60x60' }
      ],
      shippingAddress: '上海市浦东新区某某路456号',
      estimatedDelivery: '2023-10-20'
    },
    {
      id: 'o3',
      orderNumber: 'ORD202310130003',
      date: '2023-10-13',
      status: 'delivered',
      totalAmount: 8999,
      items: [
        { id: 'i5', name: '戴尔XPS 13', price: 8999, quantity: 1, image: 'https://via.placeholder.com/60x60' }
      ],
      shippingAddress: '广州市天河区某某大道789号'
    },
    {
      id: 'o4',
      orderNumber: 'ORD202310120004',
      date: '2023-10-12',
      status: 'cancelled',
      totalAmount: 2499,
      items: [
        { id: 'i6', name: '索尼WH-1000XM5', price: 2499, quantity: 1, image: 'https://via.placeholder.com/60x60' }
      ],
      shippingAddress: '深圳市南山区某某科技园101号'
    },
    {
      id: 'o5',
      orderNumber: 'ORD202310110005',
      date: '2023-10-11',
      status: 'delivered',
      totalAmount: 3299,
      items: [
        { id: 'i7', name: '美的变频空调', price: 3299, quantity: 1, image: 'https://via.placeholder.com/60x60' }
      ],
      shippingAddress: '杭州市西湖区某某街道202号'
    }
  ]);

  const [activeTab, setActiveTab] = useState<OrderStatus | 'all'>('all');

  const getStatusText = (status: OrderStatus): string => {
    switch (status) {
      case 'pending-payment': return '待付款';
      case 'pending-delivery': return '待发货';
      case 'shipped': return '已发货';
      case 'delivered': return '已签收';
      case 'cancelled': return '已取消';
      case 'refunded': return '已退款';
      default: return '未知状态';
    }
  };

  const getStatusColor = (status: OrderStatus): string => {
    switch (status) {
      case 'pending-payment': return '#f59e0b';
      case 'pending-delivery': return '#3b82f6';
      case 'shipped': return '#10b981';
      case 'delivered': return '#10b981';
      case 'cancelled': return '#9ca3af';
      case 'refunded': return '#8b5cf6';
      default: return '#9ca3af';
    }
  };

  const handleOrderAction = (orderId: string, status: OrderStatus) => {
    switch (status) {
      case 'pending-payment':
        Alert.alert('去付款', `为订单 ${orderId} 进行付款`);
        break;
      case 'shipped':
        Alert.alert('查看物流', `查看订单 ${orderId} 的物流信息`);
        break;
      case 'delivered':
        Alert.alert('确认收货', `确认收货订单 ${orderId}`);
        break;
      case 'cancelled':
        Alert.alert('订单详情', `查看已取消订单 ${orderId} 的详情`);
        break;
      default:
        Alert.alert('订单详情', `查看订单 ${orderId} 的详情`);
    }
  };

  const filteredOrders = activeTab === 'all' 
    ? orders 
    : orders.filter(order => order.status === activeTab);

  const renderOrderItem = ({ item }: { item: Order }) => (
    <View style={styles.orderCard}>
      <View style={styles.orderHeader}>
        <Text style={styles.orderNumber}>订单号: {item.orderNumber}</Text>
        <Text style={[styles.statusText, { color: getStatusColor(item.status) }]}>
          {getStatusText(item.status)}
        </Text>
      </View>
      
      <View style={styles.orderDate}>
        <Text style={styles.dateText}>下单时间: {item.date}</Text>
      </View>
      
      <View style={styles.orderItems}>
        <FlatList
          data={item.items}
          renderItem={({ item: orderItem }) => (
            <View style={styles.itemRow}>
              <Image source={{ uri: orderItem.image }} style={styles.itemImage} />
              <View style={styles.itemInfo}>
                <Text style={styles.itemName} numberOfLines={1}>{orderItem.name}</Text>
                <Text style={styles.itemPrice}>¥{orderItem.price} x {orderItem.quantity}</Text>
              </View>
            </View>
          )}
          keyExtractor={item => item.id}
          showsVerticalScrollIndicator={false}
        />
      </View>
      
      <View style={styles.orderSummary}>
        <Text style={styles.totalText}>{item.items.reduce((sum, item) => sum + item.quantity, 0)}件商品</Text>
        <Text style={styles.totalAmount}>¥{item.totalAmount}</Text>
      </View>
      
      <View style={styles.shippingInfo}>
        <Text style={styles.shippingLabel}>收货地址:</Text>
        <Text style={styles.shippingAddress} numberOfLines={1}>{item.shippingAddress}</Text>
      </View>
      
      {item.estimatedDelivery && (
        <View style={styles.deliveryInfo}>
          <Text style={styles.deliveryLabel}>预计送达:</Text>
          <Text style={styles.deliveryDate}>{item.estimatedDelivery}</Text>
        </View>
      )}
      
      <View style={styles.orderActions}>
        {item.status === 'pending-payment' && (
          <TouchableOpacity 
            style={styles.actionButton}
            onPress={() => handleOrderAction(item.id, item.status)}
          >
            <Text style={styles.actionButtonText}>立即付款</Text>
          </TouchableOpacity>
        )}
        
        {item.status === 'shipped' && (
          <TouchableOpacity 
            style={styles.actionButton}
            onPress={() => handleOrderAction(item.id, item.status)}
          >
            <Text style={styles.actionButtonText}>查看物流</Text>
          </TouchableOpacity>
        )}
        
        {item.status === 'delivered' && (
          <TouchableOpacity 
            style={styles.actionButton}
            onPress={() => handleOrderAction(item.id, item.status)}
          >
            <Text style={styles.actionButtonText}>确认收货</Text>
          </TouchableOpacity>
        )}
        
        <TouchableOpacity 
          style={styles.detailButton}
          onPress={() => Alert.alert('订单详情', `查看订单 ${item.orderNumber} 的详细信息`)}
        >
          <Text style={styles.detailButtonText}>查看详情</Text>
        </TouchableOpacity>
      </View>
    </View>
  );

  return (
    <SafeAreaView style={styles.container}>
      {/* 头部 */}
      <View style={styles.header}>
        <Text style={styles.title}>我的订单</Text>
        <Text style={styles.subtitle}>查看和管理您的订单</Text>
      </View>

      <ScrollView style={styles.content}>
        {/* 选项卡 */}
        <View style={styles.tabContainer}>
          <TouchableOpacity 
            style={[
              styles.tab,
              activeTab === 'all' && styles.activeTab
            ]}
            onPress={() => setActiveTab('all')}
          >
            <Text style={[
              styles.tabText,
              activeTab === 'all' && styles.activeTabText
            ]}>全部</Text>
          </TouchableOpacity>
          <TouchableOpacity 
            style={[
              styles.tab,
              activeTab === 'pending-payment' && styles.activeTab
            ]}
            onPress={() => setActiveTab('pending-payment')}
          >
            <Text style={[
              styles.tabText,
              activeTab === 'pending-payment' && styles.activeTabText
            ]}>待付款</Text>
          </TouchableOpacity>
          <TouchableOpacity 
            style={[
              styles.tab,
              activeTab === 'shipped' && styles.activeTab
            ]}
            onPress={() => setActiveTab('shipped')}
          >
            <Text style={[
              styles.tabText,
              activeTab === 'shipped' && styles.activeTabText
            ]}>待收货</Text>
          </TouchableOpacity>
          <TouchableOpacity 
            style={[
              styles.tab,
              activeTab === 'delivered' && styles.activeTab
            ]}
            onPress={() => setActiveTab('delivered')}
          >
            <Text style={[
              styles.tabText,
              activeTab === 'delivered' && styles.activeTabText
            ]}>已完成</Text>
          </TouchableOpacity>
        </View>

        {/* 订单列表 */}
        <FlatList
          data={filteredOrders}
          renderItem={renderOrderItem}
          keyExtractor={item => item.id}
          showsVerticalScrollIndicator={false}
          contentContainerStyle={styles.orderList}
        />

        {/* 快捷入口 */}
        <View style={styles.shortcutsContainer}>
          <Text style={styles.shortcutsTitle}>快捷入口</Text>
          <View style={styles.shortcutsGrid}>
            <TouchableOpacity style={styles.shortcutItem}>
              <Text style={styles.shortcutIcon}>📦</Text>
              <Text style={styles.shortcutText}>待付款</Text>
            </TouchableOpacity>
            <TouchableOpacity style={styles.shortcutItem}>
              <Text style={styles.shortcutIcon}>🚚</Text>
              <Text style={styles.shortcutText}>待发货</Text>
            </TouchableOpacity>
            <TouchableOpacity style={styles.shortcutItem}>
              <Text style={styles.shortcutIcon}>📦</Text>
              <Text style={styles.shortcutText}>待收货</Text>
            </TouchableOpacity>
            <TouchableOpacity style={styles.shortcutItem}>
              <Text style={styles.shortcutIcon}></Text>
              <Text style={styles.shortcutText}>评价晒单</Text>
            </TouchableOpacity>
          </View>
        </View>

        {/* 订单帮助 */}
        <View style={styles.helpCard}>
          <Text style={styles.helpTitle}>订单帮助</Text>
          <Text style={styles.helpText}>• 如何修改订单信息?</Text>
          <Text style={styles.helpText}>• 申请售后流程</Text>
          <Text style={styles.helpText}>• 查看退换货政策</Text>
          <Text style={styles.helpText}>• 联系客服</Text>
        </View>
      </ScrollView>

      {/* 底部导航 */}
      <View style={styles.bottomNav}>
        <TouchableOpacity style={styles.navItem}>
          <Text style={styles.navIcon}>🏠</Text>
          <Text style={styles.navText}>首页</Text>
        </TouchableOpacity>
        <TouchableOpacity style={styles.navItem}>
          <Text style={styles.navIcon}>🔍</Text>
          <Text style={styles.navText}>分类</Text>
        </TouchableOpacity>
        <TouchableOpacity style={styles.navItem}>
          <Text style={styles.navIcon}>🛒</Text>
          <Text style={styles.navText}>购物车</Text>
        </TouchableOpacity>
        <TouchableOpacity style={[styles.navItem, styles.activeNavItem]}>
          <Text style={styles.navIcon}>📦</Text>
          <Text style={styles.navText}>订单</Text>
        </TouchableOpacity>
      </View>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f5f7fa',
  },
  header: {
    flexDirection: 'column',
    alignItems: 'center',
    padding: 16,
    backgroundColor: '#ffffff',
    borderBottomWidth: 1,
    borderBottomColor: '#e2e8f0',
  },
  title: {
    fontSize: 20,
    fontWeight: 'bold',
    color: '#1e293b',
    marginBottom: 4,
  },
  subtitle: {
    fontSize: 14,
    color: '#64748b',
  },
  content: {
    flex: 1,
  },
  tabContainer: {
    flexDirection: 'row',
    backgroundColor: '#ffffff',
    marginHorizontal: 16,
    borderRadius: 8,
    marginBottom: 16,
    elevation: 1,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 1 },
    shadowOpacity: 0.1,
    shadowRadius: 2,
  },
  tab: {
    flex: 1,
    paddingVertical: 12,
    alignItems: 'center',
  },
  activeTab: {
    backgroundColor: '#3b82f6',
    borderRadius: 8,
  },
  tabText: {
    fontSize: 14,
    color: '#64748b',
    fontWeight: '500',
  },
  activeTabText: {
    color: '#ffffff',
  },
  orderList: {
    paddingHorizontal: 16,
  },
  orderCard: {
    backgroundColor: '#ffffff',
    borderRadius: 12,
    padding: 16,
    marginBottom: 16,
    elevation: 1,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 1 },
    shadowOpacity: 0.1,
    shadowRadius: 2,
  },
  orderHeader: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: 8,
  },
  orderNumber: {
    fontSize: 14,
    color: '#64748b',
  },
  statusText: {
    fontSize: 14,
    fontWeight: '500',
  },
  orderDate: {
    marginBottom: 12,
  },
  dateText: {
    fontSize: 12,
    color: '#94a3b8',
  },
  orderItems: {
    marginBottom: 12,
  },
  itemRow: {
    flexDirection: 'row',
    alignItems: 'center',
    marginBottom: 8,
  },
  itemImage: {
    width: 50,
    height: 50,
    borderRadius: 4,
    marginRight: 12,
  },
  itemInfo: {
    flex: 1,
  },
  itemName: {
    fontSize: 14,
    color: '#1e293b',
    marginBottom: 4,
  },
  itemPrice: {
    fontSize: 12,
    color: '#64748b',
  },
  orderSummary: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: 12,
    paddingVertical: 8,
    borderTopWidth: 1,
    borderTopColor: '#e2e8f0',
  },
  totalText: {
    fontSize: 14,
    color: '#64748b',
  },
  totalAmount: {
    fontSize: 16,
    fontWeight: 'bold',
    color: '#ef4444',
  },
  shippingInfo: {
    flexDirection: 'row',
    marginBottom: 8,
  },
  shippingLabel: {
    fontSize: 12,
    color: '#64748b',
    width: 60,
  },
  shippingAddress: {
    fontSize: 12,
    color: '#1e293b',
    flex: 1,
  },
  deliveryInfo: {
    flexDirection: 'row',
    marginBottom: 12,
  },
  deliveryLabel: {
    fontSize: 12,
    color: '#64748b',
    width: 60,
  },
  deliveryDate: {
    fontSize: 12,
    color: '#1e293b',
    flex: 1,
  },
  orderActions: {
    flexDirection: 'row',
    justifyContent: 'flex-end',
  },
  actionButton: {
    backgroundColor: '#3b82f6',
    paddingHorizontal: 16,
    paddingVertical: 8,
    borderRadius: 6,
    marginRight: 8,
  },
  actionButtonText: {
    color: '#ffffff',
    fontSize: 14,
    fontWeight: '500',
  },
  detailButton: {
    backgroundColor: '#f1f5f9',
    paddingHorizontal: 16,
    paddingVertical: 8,
    borderRadius: 6,
  },
  detailButtonText: {
    color: '#475569',
    fontSize: 14,
    fontWeight: '500',
  },
  shortcutsContainer: {
    backgroundColor: '#ffffff',
    marginHorizontal: 16,
    marginBottom: 16,
    borderRadius: 12,
    padding: 16,
    elevation: 1,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 1 },
    shadowOpacity: 0.1,
    shadowRadius: 2,
  },
  shortcutsTitle: {
    fontSize: 16,
    fontWeight: '500',
    color: '#1e293b',
    marginBottom: 12,
  },
  shortcutsGrid: {
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  shortcutItem: {
    alignItems: 'center',
    flex: 1,
    paddingVertical: 8,
  },
  shortcutIcon: {
    fontSize: 24,
    marginBottom: 4,
  },
  shortcutText: {
    fontSize: 12,
    color: '#64748b',
  },
  helpCard: {
    backgroundColor: '#ffffff',
    marginHorizontal: 16,
    marginBottom: 80,
    borderRadius: 12,
    padding: 16,
    elevation: 1,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 1 },
    shadowOpacity: 0.1,
    shadowRadius: 2,
  },
  helpTitle: {
    fontSize: 16,
    fontWeight: '500',
    color: '#1e293b',
    marginBottom: 12,
  },
  helpText: {
    fontSize: 14,
    color: '#64748b',
    lineHeight: 22,
    marginBottom: 8,
  },
  bottomNav: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    backgroundColor: '#ffffff',
    borderTopWidth: 1,
    borderTopColor: '#e2e8f0',
    paddingVertical: 12,
    position: 'absolute',
    bottom: 0,
    left: 0,
    right: 0,
  },
  navItem: {
    alignItems: 'center',
    flex: 1,
  },
  activeNavItem: {
    paddingTop: 4,
    borderTopWidth: 2,
    borderTopColor: '#3b82f6',
  },
  navIcon: {
    fontSize: 20,
    color: '#94a3b8',
    marginBottom: 4,
  },
  activeNavIcon: {
    color: '#3b82f6',
  },
  navText: {
    fontSize: 12,
    color: '#94a3b8',
  },
  activeNavText: {
    color: '#3b82f6',
    fontWeight: '500',
  },
});

export default OrderListApp;

请添加图片描述


打包

接下来通过打包命令npn run harmony将reactNative的代码打包成为bundle,这样可以进行在开源鸿蒙OpenHarmony中进行使用。

在这里插入图片描述

打包之后再将打包后的鸿蒙OpenHarmony文件拷贝到鸿蒙的DevEco-Studio工程目录去:

在这里插入图片描述

最后运行效果图如下显示:

请添加图片描述
本文探讨了基于React Native的电商订单管理系统实现方案,重点分析了其核心架构设计与跨端适配策略。系统采用TypeScript构建了完整的订单数据模型,通过React Hooks进行轻量级状态管理,并实现了订单状态处理、操作逻辑等核心功能。技术实现上使用React Native核心组件确保跨端兼容性,采用Base64图标和Dimensions API优化跨平台体验。文章还提供了鸿蒙系统下的适配建议,包括FlatList、Alert等API的兼容性考量。该方案通过模块化设计和类型安全机制,构建了功能完善、可维护性强的订单管理系统,为电商类应用的跨端开发提供了实践参考。

欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐