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


本项目采用了典型的React Native函数式组件架构,以LargeItemDeliveryApp为核心组件,通过模块化的数据结构和状态管理,实现了大件商品的配送安装全流程管理。

核心技术栈

  • React Native:跨平台移动应用开发框架
  • TypeScript:提供类型安全和代码可维护性
  • Hooks API:使用useState进行状态管理
  • Flexbox:响应式布局系统
  • Base64图标:内置图标资源,减少网络请求

大件商品类型(LargeItem)

type LargeItem = {
  id: string;
  name: string;
  category: '家具' | '家电' | '其他';
  image: string;
  price: number;
  dimensions: string;
};

该类型设计合理,包含了商品的核心属性:

  • id:唯一标识符,便于数据追踪
  • name:商品名称,用户可直接识别
  • category:分类信息,使用联合类型确保类型安全
  • image:商品图片,提升用户体验
  • price:价格信息,便于成本核算
  • dimensions:尺寸信息,对大件商品尤为重要

配送订单类型(DeliveryOrder)

type DeliveryOrder = {
  id: string;
  itemId: string;
  customerName: string;
  deliveryAddress: string;
  appointmentTime: string;
  installationRequired: boolean;
  status: '待预约' | '已预约' | '配送中' | '已完成';
  deliveryTeam: string;
  contact: string;
};

订单类型设计全面,覆盖了配送流程的各个环节:

  • status字段使用联合类型,清晰定义了订单的生命周期状态
  • installationRequired字段标识是否需要安装服务,体现了大件商品的特殊性
  • appointmentTime字段支持预约时间管理,提升服务质量

配送团队信息类型(DeliveryTeam)

type DeliveryTeam = {
  id: string;
  name: string;
  phone: string;
  rating: number;
  services: string[];
};

团队信息设计包含了服务质量评估和服务范围:

  • rating字段提供服务质量参考
  • services数组明确了团队提供的具体服务类型

核心状态

项目使用useState钩子管理应用状态,主要包含以下状态:

  • items:大件商品列表,使用常量状态
  • orders:配送订单列表,支持动态更新
  • deliveryTeams:配送团队信息,使用常量状态
  • newOrder:新订单表单数据,支持用户输入

状态更新

  1. 订单创建:通过handleCreateOrder函数,验证表单数据后添加新订单
  2. 配送预约:通过handleScheduleDelivery函数,更新订单状态和预约信息
  3. 团队联系:通过handleContactTeam函数,实现与配送团队的联系功能

状态管理

  • 使用不可变数据模式,通过扩展运算符创建新状态
  • 状态更新逻辑集中在专用函数中,提高代码可维护性
  • 表单重置逻辑清晰,提升用户体验

组件层次结构

SafeAreaView
├── View (header)
│   ├── Text (title)
│   └── Text (subtitle)
└── ScrollView (content)
    ├── 商品列表
    ├── 订单列表
    ├── 新订单表单
    └── 配送团队信息

布局技术

  • SafeAreaView:确保内容在安全区域内显示,适配不同机型
  • ScrollView:支持内容滚动,处理长列表场景
  • Dimensions API:获取屏幕尺寸,实现响应式布局
  • Flexbox:实现灵活的组件排列和对齐

交互组件

  • TouchableOpacity:提供点击反馈,提升用户体验
  • TextInput:支持用户输入,实现表单功能
  • Alert:提供操作确认和信息提示
  • Image:显示商品图片和图标

核心业务流程

  1. 商品管理:展示大件商品信息,支持分类查看
  2. 订单创建:收集客户信息和配送需求
  3. 配送预约:安排配送时间和团队
  4. 状态跟踪:实时更新订单状态
  5. 团队联系:提供与配送团队的沟通渠道

数据流设计

  • 单向数据流:状态 -> 视图 -> 用户操作 -> 状态更新
  • 模块化设计:业务逻辑与UI渲染分离
  • 错误处理:表单验证和操作确认机制

组件兼容性

  • 核心组件:SafeAreaView、View、Text、ScrollView等在鸿蒙系统上有对应实现
  • 布局系统:Flexbox在鸿蒙系统中得到良好支持
  • API差异:需要注意平台特定API的兼容性处理

本项目展示了如何使用React Native和TypeScript构建一个功能完整的大件商品配送安装应用。通过合理的架构设计、类型定义和状态管理,实现了跨平台的一致性体验。

随着React Native和鸿蒙系统的不断发展,跨端开发将会变得更加成熟和高效。未来可以考虑:

  1. 使用React Native 0.70+版本:利用新的架构特性,提升应用性能
  2. 探索鸿蒙原生能力:充分利用鸿蒙系统的分布式特性,实现更丰富的功能
  3. 引入现代化状态管理:使用Redux Toolkit或Zustand等现代状态管理库
  4. 实现PWA支持:扩展应用的使用场景,支持Web平台

通过持续的技术迭代和优化,可以构建更加稳定、高效、用户友好的跨端应用,满足企业级应用的需求。


大件商品(家具、家电等)的配送安装是新零售场景下的核心服务环节,其数字化管理系统需要兼顾订单创建、状态追踪、团队协作三大核心特性。本文将深度拆解基于 React Native 开发的大件商品配送安装应用,剖析其商品管理、订单流程、配送协作的技术实现思路,并提供完整的鸿蒙(HarmonyOS)ArkTS 跨端适配方案,为大件物流配送类应用的跨端开发提供可落地的技术参考。

1. 贴合大件配送场景

大件商品配送安装场景的核心诉求是商品管理、订单流转、团队协作,代码通过 TypeScript 类型系统构建了精准贴合大件配送业务的领域模型:

// 大件商品类型
type LargeItem = {
  id: string;
  name: string;
  category: '家具' | '家电' | '其他';
  image: string;
  price: number;
  dimensions: string;
};

// 配送订单类型
type DeliveryOrder = {
  id: string;
  itemId: string;
  customerName: string;
  deliveryAddress: string;
  appointmentTime: string;
  installationRequired: boolean;
  status: '待预约' | '已预约' | '配送中' | '已完成';
  deliveryTeam: string;
  contact: string;
};

// 配送团队信息类型
type DeliveryTeam = {
  id: string;
  name: string;
  phone: string;
  rating: number;
  services: string[];
};

模型设计的大件配送场景适配性分析

  • 商品属性专业化:包含尺寸(dimensions)字段,适配大件商品的物理特性,满足物流配送的尺寸评估需求;
  • 订单状态精细化:采用"待预约-已预约-配送中-已完成"的状态流转体系,完整覆盖大件配送的全生命周期;
  • 安装服务标识installationRequired 布尔字段明确标识是否需要安装,贴合大件商品的服务特性;
  • 团队能力建模:配送团队模型包含评分(rating)和服务类型(services),支持按能力匹配配送需求;
  • 类型安全保障:商品分类、订单状态采用联合类型约束,避免非法状态值,保证企业级应用的数据严谨性;
  • 关联关系清晰:订单通过 itemId 关联商品、deliveryTeam 关联配送团队,构建完整的业务数据链路;
  • 联系方式独立:订单和团队均包含联系方式字段,满足大件配送的沟通协作需求;
  • 价格格式化适配:商品价格字段为数字类型,便于前端格式化展示,符合电商类应用的价格展示规范。

2. 大件配送

大件配送系统的状态架构围绕商品列表、订单列表、配送团队、新建订单四层核心状态构建,通过 React 的 useState 实现从订单创建到配送完成的全流程状态管控:

// 大件商品列表状态
const [items] = useState<LargeItem[]>([/* 初始商品数据 */]);

// 配送订单列表状态
const [orders, setOrders] = useState<DeliveryOrder[]>([/* 初始订单数据 */]);

// 配送团队列表状态
const [deliveryTeams] = useState<DeliveryTeam[]>([/* 初始团队数据 */]);

// 新建订单表单状态
const [newOrder, setNewOrder] = useState({/* 表单初始值 */});

状态管理的大件配送特性适配

  • 商品数据只读化:商品列表采用只读状态设计,模拟商品库的静态特性,符合电商商品管理的业务逻辑;
  • 订单数据可写化:订单列表支持增删改操作,满足配送订单的动态流转需求;
  • 表单状态精细化:新建订单表单状态包含所有必要字段,支持实时更新,保证表单填写的流畅性;
  • 状态不可变更新:所有状态更新均采用新对象/新数组替换,遵循 React 状态更新最佳实践;
  • 关联数据联动:订单渲染时通过 itemId 关联商品信息,保证数据展示的完整性;
  • 团队数据静态化:配送团队数据只读,模拟合作商库的稳定特性,便于快速检索和联系;
  • 表单校验前置:订单创建前做必填字段校验,避免无效订单生成,符合企业级应用的数据规范。

3. 大件配送

大件商品配送安装系统的核心价值在于订单创建-预约配送-团队协作的闭环能力,代码通过轻量化但专业的业务逻辑实现了配送管理的核心交互:

(1)订单创建与表单校验

大件配送订单的创建需要严格的表单校验,确保配送信息的完整性:

const handleCreateOrder = () => {
  if (!newOrder.itemId || !newOrder.customerName || !newOrder.deliveryAddress) {
    Alert.alert('提示', '请填写完整的配送信息');
    return;
  }

  const order: DeliveryOrder = {
    id: (orders.length + 1).toString(),
    itemId: newOrder.itemId,
    customerName: newOrder.customerName,
    deliveryAddress: newOrder.deliveryAddress,
    appointmentTime: newOrder.appointmentTime || '待预约',
    installationRequired: newOrder.installationRequired,
    status: '待预约',
    deliveryTeam: '',
    contact: newOrder.contact || '未填写'
  };

  setOrders([...orders, order]);
  setNewOrder({/* 重置表单 */});
  Alert.alert('成功', '配送订单创建成功!');
};

订单创建逻辑的大件配送适配性

  • 必填字段校验:商品选择、收货人、配送地址为必填项,符合大件配送的核心信息要求;
  • 默认值合理设置:预约时间默认"待预约"、联系方式默认"未填写",保证订单数据的完整性;
  • 状态初始值规范:新订单默认状态为"待预约",符合大件配送的业务流程;
  • 订单ID自动生成:基于现有订单数量生成ID,简化前端实现,实际项目中可对接后端生成;
  • 表单重置机制:订单创建成功后清空表单,便于连续创建多个订单;
  • 操作反馈明确:创建成功/失败均给出明确提示,提升用户操作体验;
  • 数据不可变更新:采用数组扩展运算符添加新订单,避免直接修改原数组。
(2)订单状态流转

大件配送的核心是预约流程管理,代码实现了从"待预约"到"已预约"的状态流转:

const handleScheduleDelivery = (orderId: string) => {
  Alert.alert(
    '预约配送',
    '请选择配送时间和团队',
    [
      { text: '取消', style: 'cancel' },
      {
        text: '确定预约',
        onPress: () => {
          setOrders(orders.map(order => 
            order.id === orderId 
              ? { 
                  ...order, 
                  status: '已预约',
                  appointmentTime: '2023-12-20 09:00-12:00',
                  deliveryTeam: '顺丰大件物流'
                } 
              : order
          ));
          Alert.alert('成功', '配送已预约成功!');
        }
      }
    ]
  );
};

预约逻辑的大件配送适配性

  • 状态精准更新:仅更新目标订单的状态、预约时间、配送团队,其他订单保持不变;
  • 时间格式标准化:采用"YYYY-MM-DD HH:MM-HH:MM"格式,符合大件配送的时间预约习惯;
  • 团队分配明确:预约时指定配送团队,建立订单与团队的关联关系;
  • 确认机制完善:增加二次确认弹窗,避免误操作,符合企业级应用的严谨性要求;
  • 反馈及时:预约成功后给出明确提示,让用户确认操作结果;
  • 批量更新优化:使用数组map方法批量处理订单,保证状态更新的效率。
(3)联系方式

大件配送依赖高效的团队协作,代码实现了配送团队的联系功能:

const handleContactTeam = (teamId: string) => {
  const team = deliveryTeams.find(t => t.id === teamId);
  if (team) {
    Alert.alert('联系配送团队', `拨打 ${team.phone}`, [
      { text: '取消', style: 'cancel' },
      { text: '拨打', onPress: () => Alert.alert('提示', '正在拨打电话...') }
    ]);
  }
};

团队协作逻辑的适配性

  • 团队精准检索:通过teamId快速定位目标团队,保证联系的准确性;
  • 联系方式展示:弹窗展示团队电话,符合用户的操作预期;
  • 操作引导明确:提供"拨打"按钮,引导用户完成联系操作;
  • 异常处理完善:团队不存在时静默处理,避免应用崩溃;
  • 交互体验友好:模拟拨打电话的提示,提升用户体验;
  • 扩展性预留:实际项目中可集成react-native-communications库实现真实拨号功能。

4. 大件配送的场景化

大件配送系统的视觉设计围绕场景化、易用性、专业性三个核心维度展开,贴合大件物流配送的业务特性:

(1)场景
  • 暖色调体系:采用橙色系(#f97316)为主色调,契合物流配送行业的温暖、可靠的品牌属性;
  • 商品选择可视化:商品选项卡展示图片+名称+价格,直观呈现大件商品信息;
  • 状态色彩语义化:待预约(黄色)、已预约(蓝色)、配送中(紫色)、已完成(绿色)的色彩映射,强化状态识别;
  • 表单分区清晰:创建订单表单按商品选择、收货人信息、地址、联系方式分区,符合用户填写习惯;
  • 团队信息卡片化:配送团队信息包含名称、评分、服务类型,便于快速评估团队能力;
  • 操作按钮差异化:创建订单(主按钮)、预约配送(成功色)、联系团队(次要色)的按钮样式区分,引导用户操作;
  • 底部导航场景化:按配送、订单、团队、我的分类,贴合大件配送的核心业务场景;
  • 安全区域适配:使用SafeAreaView适配异形屏,保证界面完整性;
  • 卡片阴影效果:所有功能模块采用卡片式设计+轻微阴影,提升界面层次感;
  • 圆角统一规范:12px大圆角+8px小组件圆角,兼顾移动端的友好性和专业性。
(2)大件配送
  • 商品选择直观化:选中状态的商品选项卡变色,直观反馈选择结果;
  • 表单校验即时化:创建订单前校验必填字段,避免无效提交;
  • 状态展示突出化:订单状态采用彩色徽章展示,便于快速识别;
  • 操作权限动态化:仅"待预约"订单显示"预约配送"按钮,符合业务规则;
  • 团队联系便捷化:订单和团队列表均提供联系入口,提升协作效率;
  • 地址输入多行化:配送地址采用多行输入框,适配详细地址的填写需求;
  • 安装服务勾选化:使用自定义复选框,直观选择是否需要安装服务;
  • 价格格式化展示:商品价格采用toLocaleString格式化,符合电商展示规范;
  • 滚动体验流畅化:订单列表支持滚动,适配大批量订单的展示需求;
  • 底部导航固定化:导航栏固定在底部,保证核心功能的快速访问。

将 React Native 大件配送系统迁移至鸿蒙平台,核心是基于 ArkTS + ArkUI 实现类型系统、状态管理、业务逻辑、视觉交互的对等还原,同时适配鸿蒙的组件特性和布局范式,保证大件配送体验的一致性。

1. 架构

鸿蒙端适配遵循类型复用、逻辑对等、体验统一的原则,大件配送的核心业务逻辑和视觉规范100%复用,仅需适配平台特有API和组件语法:

@Entry
@Component
struct LargeItemDeliveryApp {
  // 类型定义:对等实现 TypeScript 类型 → 接口定义
  interface LargeItem {
    id: string;
    name: string;
    category: '家具' | '家电' | '其他';
    image: string;
    price: number;
    dimensions: string;
  }

  interface DeliveryOrder {
    id: string;
    itemId: string;
    customerName: string;
    deliveryAddress: string;
    appointmentTime: string;
    installationRequired: boolean;
    status: '待预约' | '已预约' | '配送中' | '已完成';
    deliveryTeam: string;
    contact: string;
  }

  interface DeliveryTeam {
    id: string;
    name: string;
    phone: string;
    rating: number;
    services: string[];
  }

  // 状态管理:对等实现 useState → @State
  @State items: LargeItem[] = [/* 初始商品数据 */];
  @State orders: DeliveryOrder[] = [/* 初始订单数据 */];
  @State deliveryTeams: DeliveryTeam[] = [/* 初始团队数据 */];
  @State newOrder: {
    itemId: string;
    customerName: string;
    deliveryAddress: string;
    appointmentTime: string;
    installationRequired: boolean;
    contact: string;
  } = {/* 表单初始值 */};

  // 业务逻辑:完全复用 RN 端实现
  getStatusColor(status: string): string {/* 状态色彩映射 */}
  handleCreateOrder(): void {/* 订单创建 */}
  handleScheduleDelivery(orderId: string): void {/* 预约配送 */}
  handleContactTeam(teamId: string): void {/* 联系团队 */}

  // 页面构建:镜像 RN 端布局结构
  build() {
    Column() {
      // 头部区域
      // 创建订单表单
      // 订单列表
      // 配送团队
      // 服务说明
      // 底部导航
    }
  }
}

2. 核心适配要点对比

React Native 特性 鸿蒙 ArkUI 对应实现 大件配送适配关键说明
TypeScript 类型定义 TypeScript 接口定义 大件商品、配送订单、团队类型完全复用,保证业务数据结构一致性
useState @State 装饰器 商品、订单、团队、表单的状态管理逻辑完全复用
商品选择交互 ForEach + 点击事件 商品选择的视觉反馈逻辑一致,保证大件商品选择体验
TouchableOpacity Button/Column + onClick 所有可点击区域通过onClick事件实现,保持交互一致性
Alert.alert AlertDialog.show 订单创建、预约配送、联系团队等弹窗逻辑对等
StyleSheet 链式样式 橙色系主色调、状态色彩映射等视觉规范100%复用
Array.map ForEach 组件 订单/商品/团队列表渲染逻辑一致
ScrollView Scroll 组件 滚动容器语法差异,功能一致,适配大批量订单展示
TextInput TextInput 组件 表单输入框属性基本一致,多行输入适配鸿蒙特性
Image Image 组件 商品图片展示语法差异,效果一致
绝对定位 position: Position.Fixed 底部导航定位语法差异,效果一致
自定义复选框 Checkbox 组件 安装服务选择逻辑一致,UI样式适配鸿蒙组件
状态徽章 Column + 背景色 订单状态色彩映射逻辑一致
价格格式化 字符串格式化 商品价格展示逻辑一致,保证电商类展示规范

3. 完整鸿蒙适配代码

// 鸿蒙 ArkTS 完整实现
@Entry
@Component
struct LargeItemDeliveryApp {
  // 类型定义
  interface LargeItem {
    id: string;
    name: string;
    category: '家具' | '家电' | '其他';
    image: string;
    price: number;
    dimensions: string;
  }

  interface DeliveryOrder {
    id: string;
    itemId: string;
    customerName: string;
    deliveryAddress: string;
    appointmentTime: string;
    installationRequired: boolean;
    status: '待预约' | '已预约' | '配送中' | '已完成';
    deliveryTeam: string;
    contact: string;
  }

  interface DeliveryTeam {
    id: string;
    name: string;
    phone: string;
    rating: number;
    services: string[];
  }

  // 状态管理
  @State items: LargeItem[] = [
    {
      id: '1',
      name: '真皮沙发三人位',
      category: '家具',
      image: 'https://via.placeholder.com/100x100',
      price: 8999,
      dimensions: '220×90×85cm'
    },
    {
      id: '2',
      name: '双开门冰箱',
      category: '家电',
      image: 'https://via.placeholder.com/100x100',
      price: 5999,
      dimensions: '170×70×70cm'
    }
  ];

  @State orders: DeliveryOrder[] = [
    {
      id: '1',
      itemId: '1',
      customerName: '张三',
      deliveryAddress: '北京市朝阳区某某小区12号楼',
      appointmentTime: '2023-12-15 09:00-12:00',
      installationRequired: true,
      status: '已预约',
      deliveryTeam: '顺丰大件物流',
      contact: '138****1234'
    },
    {
      id: '2',
      itemId: '2',
      customerName: '李四',
      deliveryAddress: '上海市浦东新区某别墅区',
      appointmentTime: '待预约',
      installationRequired: true,
      status: '待预约',
      deliveryTeam: '',
      contact: '139****5678'
    }
  ];

  @State deliveryTeams: DeliveryTeam[] = [
    {
      id: 't1',
      name: '顺丰大件物流',
      phone: '400-111-1111',
      rating: 4.8,
      services: ['配送', '安装', '拆旧']
    },
    {
      id: 't2',
      name: '德邦物流',
      phone: '400-222-2222',
      rating: 4.7,
      services: ['配送', '安装']
    }
  ];

  @State newOrder: {
    itemId: string;
    customerName: string;
    deliveryAddress: string;
    appointmentTime: string;
    installationRequired: boolean;
    contact: string;
  } = {
    itemId: '',
    customerName: '',
    deliveryAddress: '',
    appointmentTime: '',
    installationRequired: true,
    contact: ''
  };

  // 获取状态颜色
  getStatusColor(status: string): string {
    switch (status) {
      case '待预约': return '#f59e0b';
      case '已预约': return '#3b82f6';
      case '配送中': return '#8b5cf6';
      case '已完成': return '#10b981';
      default: return '#6b7280';
    }
  }

  // 创建配送订单
  handleCreateOrder(): void {
    if (!this.newOrder.itemId || !this.newOrder.customerName || !this.newOrder.deliveryAddress) {
      AlertDialog.show({
        title: '提示',
        message: '请填写完整的配送信息',
        confirm: { value: '确定' }
      });
      return;
    }

    const order: DeliveryOrder = {
      id: (this.orders.length + 1).toString(),
      itemId: this.newOrder.itemId,
      customerName: this.newOrder.customerName,
      deliveryAddress: this.newOrder.deliveryAddress,
      appointmentTime: this.newOrder.appointmentTime || '待预约',
      installationRequired: this.newOrder.installationRequired,
      status: '待预约',
      deliveryTeam: '',
      contact: this.newOrder.contact || '未填写'
    };

    this.orders = [...this.orders, order];
    this.newOrder = {
      itemId: '',
      customerName: '',
      deliveryAddress: '',
      appointmentTime: '',
      installationRequired: true,
      contact: ''
    };

    AlertDialog.show({
      title: '成功',
      message: '配送订单创建成功!',
      confirm: { value: '确定' }
    });
  }

  // 预约配送
  handleScheduleDelivery(orderId: string): void {
    AlertDialog.show({
      title: '预约配送',
      message: '请选择配送时间和团队',
      cancel: { value: '取消' },
      confirm: {
        value: '确定预约',
        action: () => {
          this.orders = this.orders.map(order => 
            order.id === orderId 
              ? { 
                  ...order, 
                  status: '已预约',
                  appointmentTime: '2023-12-20 09:00-12:00',
                  deliveryTeam: '顺丰大件物流'
                } 
              : order
          );
          AlertDialog.show({
            title: '成功',
            message: '配送已预约成功!',
            confirm: { value: '确定' }
          });
        }
      }
    });
  }

  // 联系配送团队
  handleContactTeam(teamId: string): void {
    const team = this.deliveryTeams.find(t => t.id === teamId);
    if (team) {
      AlertDialog.show({
        title: '联系配送团队',
        message: `拨打 ${team.phone}`,
        cancel: { value: '取消' },
        confirm: {
          value: '拨打',
          action: () => {
            AlertDialog.show({
              title: '提示',
              message: '正在拨打电话...',
              confirm: { value: '确定' }
            });
          }
        }
      });
    }
  }

  build() {
    Column()
      .flex(1)
      .backgroundColor('#fff7ed')
      .safeArea(true) {
      
      // 头部区域
      Column()
        .padding(16)
        .backgroundColor('#ffffff')
        .borderBottom({ width: 1, color: '#fed7aa' }) {
        Text('大件配送安装')
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .fontColor('#9a3412')
          .marginBottom(4);
        
        Text('专业团队,安心交付')
          .fontSize(14)
          .fontColor('#ea580c');
      }

      // 滚动内容区
      Scroll()
        .flex(1)
        .marginTop(12) {
        Column() {
          // 创建配送订单卡片
          Column()
            .backgroundColor('#ffffff')
            .marginLeft(16)
            .marginRight(16)
            .marginBottom(12)
            .borderRadius(12)
            .padding(16)
            .shadow({ color: '#000', offsetX: 0, offsetY: 2, opacity: 0.1, radius: 4 }) {
            
            Text('创建配送订单')
              .fontSize(16)
              .fontWeight(FontWeight.SemiBold)
              .fontColor('#9a3412')
              .marginBottom(12);
            
            // 商品选择器
            Row()
              .justifyContent(FlexAlign.SpaceBetween)
              .marginBottom(12) {
              ForEach(this.items, (item: LargeItem) => {
                Column()
                  .flexGrow(0.48)
                  .padding(12)
                  .borderRadius(8)
                  .backgroundColor(this.newOrder.itemId === item.id ? '#f97316' : '#ffedd5')
                  .alignItems(ItemAlign.Center)
                  .onClick(() => {
                    this.newOrder = {...this.newOrder, itemId: item.id};
                  }) {
                  Image(item.image)
                    .width(60)
                    .height(60)
                    .borderRadius(8)
                    .marginBottom(8);
                  
                  Column()
                    .alignItems(ItemAlign.Center) {
                    Text(item.name)
                      .fontSize(12)
                      .fontColor('#9a3412')
                      .textAlign(TextAlign.Center);
                    
                    Text(`¥${item.price.toLocaleString()}`)
                      .fontSize(14)
                      .fontWeight(FontWeight.Bold)
                      .fontColor('#ea580c')
                      .marginTop(4);
                  }
                }
              })
            }
            
            // 收货人姓名输入
            TextInput({
              placeholder: '收货人姓名',
              text: this.newOrder.customerName
            })
              .onChange((value) => {
                this.newOrder = {...this.newOrder, customerName: value};
              })
              .border({ width: 1, color: '#fed7aa' })
              .borderRadius(8)
              .padding(12)
              .fontSize(14)
              .backgroundColor('#fff7ed')
              .marginBottom(12);
            
            // 配送地址输入
            TextInput({
              placeholder: '详细配送地址',
              text: this.newOrder.deliveryAddress
            })
              .onChange((value) => {
                this.newOrder = {...this.newOrder, deliveryAddress: value};
              })
              .border({ width: 1, color: '#fed7aa' })
              .borderRadius(8)
              .padding(12)
              .fontSize(14)
              .backgroundColor('#fff7ed')
              .marginBottom(12)
              .minHeight(80)
              .textAlign(TextAlign.Top);
            
            // 联系电话输入
            TextInput({
              placeholder: '联系电话',
              text: this.newOrder.contact
            })
              .onChange((value) => {
                this.newOrder = {...this.newOrder, contact: value};
              })
              .border({ width: 1, color: '#fed7aa' })
              .borderRadius(8)
              .padding(12)
              .fontSize(14)
              .backgroundColor('#fff7ed')
              .marginBottom(12)
              .type(InputType.Number);
            
            // 安装服务选项
            Row()
              .alignItems(ItemAlign.Center)
              .marginBottom(12)
              .onClick(() => {
                this.newOrder = {...this.newOrder, installationRequired: !this.newOrder.installationRequired};
              }) {
              Column()
                .width(20)
                .height(20)
                .borderRadius(10)
                .border({ width: 1, color: '#fed7aa' })
                .backgroundColor(this.newOrder.installationRequired ? '#f97316' : Color.White)
                .alignItems(ItemAlign.Center)
                .justifyContent(FlexAlign.Center)
                .marginRight(8) {
                if (this.newOrder.installationRequired) {
                  Text('✓')
                    .fontColor(Color.White)
                    .fontSize(12)
                    .fontWeight(FontWeight.Bold);
                }
              }
              
              Text('需要安装服务')
                .fontSize(14)
                .fontColor('#9a3412');
            }
            
            // 创建订单按钮
            Button()
              .backgroundColor('#f97316')
              .paddingVertical(14)
              .borderRadius(8)
              .width('100%')
              .onClick(() => this.handleCreateOrder()) {
              Text('创建订单')
                .fontColor(Color.White)
                .fontSize(16)
                .fontWeight(FontWeight.SemiBold);
            }
          }

          // 配送订单列表卡片
          Column()
            .backgroundColor('#ffffff')
            .marginLeft(16)
            .marginRight(16)
            .marginBottom(12)
            .borderRadius(12)
            .padding(16)
            .shadow({ color: '#000', offsetX: 0, offsetY: 2, opacity: 0.1, radius: 4 }) {
            
            Text('我的配送订单')
              .fontSize(16)
              .fontWeight(FontWeight.SemiBold)
              .fontColor('#9a3412')
              .marginBottom(12);
            
            // 订单列表
            ForEach(this.orders, (order: DeliveryOrder) => {
              const item = this.items.find(i => i.id === order.itemId);
              Column()
                .padding(12)
                .borderBottom({ width: 1, color: '#fed7aa' }) {
                
                // 订单头部
                Row()
                  .justifyContent(FlexAlign.SpaceBetween)
                  .alignItems(ItemAlign.Center)
                  .marginBottom(8) {
                  Text(item?.name || '未知商品')
                    .fontSize(16)
                    .fontWeight(FontWeight.SemiBold)
                    .fontColor('#9a3412')
                    .flexGrow(1);
                  
                  // 状态徽章
                  Column()
                    .paddingHorizontal(8)
                    .paddingVertical(4)
                    .borderRadius(12)
                    .backgroundColor(this.getStatusColor(order.status)) {
                    Text(order.status)
                      .fontSize(12)
                      .fontColor(Color.White)
                      .fontWeight(FontWeight.Medium);
                  }
                }
                
                // 订单详情
                Column()
                  .marginBottom(12) {
                  // 收货人
                  Row()
                    .marginBottom(4) {
                    Text('收货人:')
                      .fontSize(12)
                      .fontColor('#64748b')
                      .width(70);
                    
                    Text(order.customerName)
                      .fontSize(12)
                      .fontColor('#9a3412')
                      .flexGrow(1);
                  }
                  
                  // 地址
                  Row()
                    .marginBottom(4) {
                    Text('地址:')
                      .fontSize(12)
                      .fontColor('#64748b')
                      .width(70);
                    
                    Text(order.deliveryAddress)
                      .fontSize(12)
                      .fontColor('#9a3412')
                      .flexGrow(1);
                  }
                  
                  // 预约时间
                  Row()
                    .marginBottom(4) {
                    Text('预约时间:')
                      .fontSize(12)
                      .fontColor('#64748b')
                      .width(70);
                    
                    Text(order.appointmentTime)
                      .fontSize(12)
                      .fontColor('#9a3412')
                      .flexGrow(1);
                  }
                  
                  // 配送团队(有值时显示)
                  if (order.deliveryTeam) {
                    Row() {
                      Text('配送团队:')
                        .fontSize(12)
                        .fontColor('#64748b')
                        .width(70);
                      
                      Text(order.deliveryTeam)
                        .fontSize(12)
                        .fontColor('#9a3412')
                        .flexGrow(1);
                    }
                  }
                }
                
                // 订单操作
                Row()
                  .justifyContent(FlexAlign.End) {
                  // 预约配送按钮(仅待预约显示)
                  if (order.status === '待预约') {
                    Button()
                      .backgroundColor('#10b981')
                      .paddingHorizontal(12)
                      .paddingVertical(6)
                      .borderRadius(16)
                      .marginRight(8)
                      .onClick(() => this.handleScheduleDelivery(order.id)) {
                      Text('预约配送')
                        .fontColor(Color.White)
                        .fontSize(12);
                    }
                  }
                  
                  // 联系团队按钮(有团队时显示)
                  if (order.deliveryTeam) {
                    // 查找团队ID
                    const team = this.deliveryTeams.find(t => t.name === order.deliveryTeam);
                    if (team) {
                      Button()
                        .backgroundColor('#fed7aa')
                        .paddingHorizontal(12)
                        .paddingVertical(6)
                        .borderRadius(16)
                        .onClick(() => this.handleContactTeam(team.id)) {
                        Text('联系团队')
                          .fontColor('#f97316')
                          .fontSize(12);
                      }
                    }
                  }
                }
              }
            })
          }

          // 合作配送团队卡片
          Column()
            .backgroundColor('#ffffff')
            .marginLeft(16)
            .marginRight(16)
            .marginBottom(12)
            .borderRadius(12)
            .padding(16)
            .shadow({ color: '#000', offsetX: 0, offsetY: 2, opacity: 0.1, radius: 4 }) {
            
            Text('合作配送团队')
              .fontSize(16)
              .fontWeight(FontWeight.SemiBold)
              .fontColor('#9a3412')
              .marginBottom(12);
            
            // 团队列表
            ForEach(this.deliveryTeams, (team: DeliveryTeam) => {
              Row()
                .justifyContent(FlexAlign.SpaceBetween)
                .alignItems(ItemAlign.Center)
                .paddingVertical(12)
                .borderBottom({ width: 1, color: '#fed7aa' }) {
                
                Column()
                  .flexGrow(1) {
                  Text(team.name)
                    .fontSize(16)
                    .fontWeight(FontWeight.SemiBold)
                    .fontColor('#9a3412')
                    .marginBottom(4);
                  
                  Text(`${team.rating}`)
                    .marginBottom(4);
                  
                  Text(`服务: ${team.services.join('、')}`)
                    .fontSize(12)
                    .fontColor('#64748b');
                }
                
                // 致电按钮
                Button()
                  .backgroundColor('#f97316')
                  .paddingHorizontal(16)
                  .paddingVertical(8)
                  .borderRadius(20)
                  .onClick(() => this.handleContactTeam(team.id)) {
                  Text('致电')
                    .fontColor(Color.White)
                    .fontSize(14)
                    .fontWeight(FontWeight.Medium);
                }
              }
            })
          }

          // 服务说明卡片
          Column()
            .backgroundColor('#ffffff')
            .marginLeft(16)
            .marginRight(16)
            .marginBottom(80)
            .borderRadius(12)
            .padding(16)
            .shadow({ color: '#000', offsetX: 0, offsetY: 2, opacity: 0.1, radius: 4 }) {
            
            Text('服务说明')
              .fontSize(16)
              .fontWeight(FontWeight.SemiBold)
              .fontColor('#9a3412')
              .marginBottom(12);
            
            Text('• 专业大件物流团队配送')
              .fontSize(14)
              .fontColor('#64748b')
              .lineHeight(20)
              .marginBottom(4);
            
            Text('• 提供上门安装服务')
              .fontSize(14)
              .fontColor('#64748b')
              .lineHeight(20)
              .marginBottom(4);
            
            Text('• 支持旧家具拆除回收')
              .fontSize(14)
              .fontColor('#64748b')
              .lineHeight(20)
              .marginBottom(4);
            
            Text('• 全程跟踪配送状态')
              .fontSize(14)
              .fontColor('#64748b')
              .lineHeight(20);
          }
        }
      }

      // 底部导航
      Row()
        .justifyContent(FlexAlign.SpaceAround)
        .backgroundColor('#ffffff')
        .borderTop({ width: 1, color: '#fed7aa' })
        .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: '#f97316' }) {
        Text('👤')
          .fontSize(20)
          .fontColor('#f97316')
          .marginBottom(4);
        
        Text('我的')
          .fontSize(12)
          .fontColor('#f97316')
          .fontWeight(FontWeight.Medium);
      }
    }
  }
}

1. 原则

  • 领域模型完全复用:大件商品、配送订单、配送团队的类型定义在两端保持一致,包含尺寸、安装需求、团队评分等大件配送核心属性,保证业务逻辑的准确性;
  • 视觉规范100%对齐:橙色系主色调、状态色彩映射、卡片布局等视觉属性完全复用,符合物流配送行业的视觉认知;
  • 配送业务流程统一:订单创建、预约配送、团队联系等核心业务流程保持一致的规则,符合大件物流配送的行业惯例;
  • 表单交互逻辑对等:商品选择、表单填写、复选框交互等表单逻辑保持一致,保证订单创建体验的统一性;
  • 状态流转规则一致:订单状态从待预约→已预约→配送中→已完成的流转规则在两端完全一致;
  • 语义化设计统一:状态色彩、操作按钮样式等语义化设计保持一致,提升配送信息的可读性;
  • 平台特性兼容:弹窗展示、图片加载、输入框交互等平台特有API做适配处理,保证配送功能的可用性;
  • 性能优化适配:鸿蒙端利用ForEach组件的复用机制优化列表渲染性能,RN端利用数组映射实现高效渲染。

2. 大件配送

  • 地址定位集成:接入地图SDK,支持地址定位和距离计算,评估配送费用;
  • 配送费用计算:基于商品尺寸、重量、配送距离自动计算配送费用;
  • 电子签名确认:配送完成后支持客户电子签名确认,完成交付闭环;
  • 安装验收单:支持安装服务验收单的在线填写和提交;
  • 团队派单系统:集成派单功能,支持管理员向配送团队分配订单;
  • 路线规划优化:基于多个配送地址优化配送路线,提升配送效率;
  • 实时位置追踪:集成GPS定位,实时追踪配送车辆位置;
  • 评价体系完善:支持客户对配送和安装服务进行评价,完善服务质量管控;
  • 异常处理流程:增加配送异常(如商品损坏、无法入户)的处理流程;
  • 批量操作功能:支持批量创建订单、批量派单等批量操作;
  • 数据统计分析:增加配送完成率、安装满意度、团队绩效等统计报表;
  • 多语言支持:适配中英文等多语言,支持跨境大件配送业务;
  • 权限管理系统:集成企业权限管理,按角色控制配送操作权限。

大件商品配送安装系统作为新零售物流服务的核心工具,其跨端适配的关键在于领域模型的行业专业性、表单交互的易用性、状态管理的流程化。这份 React Native 实现的大件配送组件,通过强类型领域建模、精细化状态管理、场景化视觉设计,构建了高效的移动端配送管理体验;而鸿蒙 ArkTS 端的适配实现,则验证了跨端开发中"逻辑复用、体验统一"的核心原则。

  1. 大件配送系统的类型设计需贴合物流配送场景,覆盖商品尺寸、安装需求、团队评分等核心属性,状态建议采用联合类型保证数据严谨性;
  2. 订单创建表单需包含商品选择、收货人、详细地址等必填项,符合大件配送的核心信息要求;
  3. 跨端适配的核心是配送业务逻辑复用 + 平台特性适配,订单创建、预约配送、团队联系等核心逻辑无需重写;
  4. 状态色彩的语义化设计能显著提升配送状态的识别效率,待预约(黄色)、已完成(绿色)等色彩映射符合用户认知;
  5. 商品选择的可视化设计(图片+名称+价格)是提升大件商品选择体验的关键技术手段;
  6. 配送团队信息需包含评分和服务类型,便于按能力匹配配送需求;
  7. 表单校验前置处理能有效避免无效订单生成,符合企业级应用的数据规范要求。

真实演示案例代码:

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

// Base64 图标库
const ICONS_BASE64 = {
  sofa: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  fridge: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  calendar: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  location: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  phone: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  truck: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  check: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  info: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
};

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

// 大件商品类型
type LargeItem = {
  id: string;
  name: string;
  category: '家具' | '家电' | '其他';
  image: string;
  price: number;
  dimensions: string;
};

// 配送订单类型
type DeliveryOrder = {
  id: string;
  itemId: string;
  customerName: string;
  deliveryAddress: string;
  appointmentTime: string;
  installationRequired: boolean;
  status: '待预约' | '已预约' | '配送中' | '已完成';
  deliveryTeam: string;
  contact: string;
};

// 配送团队信息类型
type DeliveryTeam = {
  id: string;
  name: string;
  phone: string;
  rating: number;
  services: string[];
};

// 大件商品配送安装应用组件
const LargeItemDeliveryApp: React.FC = () => {
  const [items] = useState<LargeItem[]>([
    {
      id: '1',
      name: '真皮沙发三人位',
      category: '家具',
      image: 'https://via.placeholder.com/100x100',
      price: 8999,
      dimensions: '220×90×85cm'
    },
    {
      id: '2',
      name: '双开门冰箱',
      category: '家电',
      image: 'https://via.placeholder.com/100x100',
      price: 5999,
      dimensions: '170×70×70cm'
    }
  ]);

  const [orders, setOrders] = useState<DeliveryOrder[]>([
    {
      id: '1',
      itemId: '1',
      customerName: '张三',
      deliveryAddress: '北京市朝阳区某某小区12号楼',
      appointmentTime: '2023-12-15 09:00-12:00',
      installationRequired: true,
      status: '已预约',
      deliveryTeam: '顺丰大件物流',
      contact: '138****1234'
    },
    {
      id: '2',
      itemId: '2',
      customerName: '李四',
      deliveryAddress: '上海市浦东新区某别墅区',
      appointmentTime: '待预约',
      installationRequired: true,
      status: '待预约',
      deliveryTeam: '',
      contact: '139****5678'
    }
  ]);

  const [deliveryTeams] = useState<DeliveryTeam[]>([
    {
      id: 't1',
      name: '顺丰大件物流',
      phone: '400-111-1111',
      rating: 4.8,
      services: ['配送', '安装', '拆旧']
    },
    {
      id: 't2',
      name: '德邦物流',
      phone: '400-222-2222',
      rating: 4.7,
      services: ['配送', '安装']
    }
  ]);

  const [newOrder, setNewOrder] = useState({
    itemId: '',
    customerName: '',
    deliveryAddress: '',
    appointmentTime: '',
    installationRequired: true,
    contact: ''
  });

  const getStatusColor = (status: string) => {
    switch (status) {
      case '待预约': return '#f59e0b';
      case '已预约': return '#3b82f6';
      case '配送中': return '#8b5cf6';
      case '已完成': return '#10b981';
      default: return '#6b7280';
    }
  };

  const handleCreateOrder = () => {
    if (!newOrder.itemId || !newOrder.customerName || !newOrder.deliveryAddress) {
      Alert.alert('提示', '请填写完整的配送信息');
      return;
    }

    const order: DeliveryOrder = {
      id: (orders.length + 1).toString(),
      itemId: newOrder.itemId,
      customerName: newOrder.customerName,
      deliveryAddress: newOrder.deliveryAddress,
      appointmentTime: newOrder.appointmentTime || '待预约',
      installationRequired: newOrder.installationRequired,
      status: '待预约',
      deliveryTeam: '',
      contact: newOrder.contact || '未填写'
    };

    setOrders([...orders, order]);
    setNewOrder({
      itemId: '',
      customerName: '',
      deliveryAddress: '',
      appointmentTime: '',
      installationRequired: true,
      contact: ''
    });

    Alert.alert('成功', '配送订单创建成功!');
  };

  const handleScheduleDelivery = (orderId: string) => {
    Alert.alert(
      '预约配送',
      '请选择配送时间和团队',
      [
        {
          text: '取消',
          style: 'cancel'
        },
        {
          text: '确定预约',
          onPress: () => {
            setOrders(orders.map(order => 
              order.id === orderId 
                ? { 
                    ...order, 
                    status: '已预约',
                    appointmentTime: '2023-12-20 09:00-12:00',
                    deliveryTeam: '顺丰大件物流'
                  } 
                : order
            ));
            Alert.alert('成功', '配送已预约成功!');
          }
        }
      ]
    );
  };

  const handleContactTeam = (teamId: string) => {
    const team = deliveryTeams.find(t => t.id === teamId);
    if (team) {
      Alert.alert('联系配送团队', `拨打 ${team.phone}`, [
        { text: '取消', style: 'cancel' },
        { text: '拨打', onPress: () => Alert.alert('提示', '正在拨打电话...') }
      ]);
    }
  };

  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.orderCard}>
          <Text style={styles.sectionTitle}>创建配送订单</Text>
          
          <View style={styles.itemSelector}>
            {items.map(item => (
              <TouchableOpacity
                key={item.id}
                style={[
                  styles.itemOption,
                  newOrder.itemId === item.id && styles.selectedItem
                ]}
                onPress={() => setNewOrder({...newOrder, itemId: item.id})}
              >
                <Image source={{ uri: item.image }} style={styles.itemImage} />
                <View style={styles.itemInfo}>
                  <Text style={styles.itemName}>{item.name}</Text>
                  <Text style={styles.itemPrice}>¥{item.price.toLocaleString()}</Text>
                </View>
              </TouchableOpacity>
            ))}
          </View>
          
          <TextInput
            style={styles.input}
            placeholder="收货人姓名"
            value={newOrder.customerName}
            onChangeText={(text) => setNewOrder({...newOrder, customerName: text})}
          />
          
          <TextInput
            style={[styles.input, styles.textArea]}
            placeholder="详细配送地址"
            value={newOrder.deliveryAddress}
            onChangeText={(text) => setNewOrder({...newOrder, deliveryAddress: text})}
            multiline
            numberOfLines={3}
          />
          
          <TextInput
            style={styles.input}
            placeholder="联系电话"
            value={newOrder.contact}
            onChangeText={(text) => setNewOrder({...newOrder, contact: text})}
            keyboardType="phone-pad"
          />
          
          <View style={styles.installationOption}>
            <TouchableOpacity 
              style={styles.checkbox}
              onPress={() => setNewOrder({...newOrder, installationRequired: !newOrder.installationRequired})}
            >
              <View style={[
                styles.checkboxInner,
                newOrder.installationRequired && styles.checked
              ]}>
                {newOrder.installationRequired && <Text style={styles.checkmark}></Text>}
              </View>
              <Text style={styles.checkboxText}>需要安装服务</Text>
            </TouchableOpacity>
          </View>
          
          <TouchableOpacity 
            style={styles.createButton}
            onPress={handleCreateOrder}
          >
            <Text style={styles.createButtonText}>创建订单</Text>
          </TouchableOpacity>
        </View>

        {/* 配送订单列表 */}
        <View style={styles.ordersCard}>
          <Text style={styles.sectionTitle}>我的配送订单</Text>
          
          {orders.map(order => {
            const item = items.find(i => i.id === order.itemId);
            return (
              <View key={order.id} style={styles.orderItem}>
                <View style={styles.orderHeader}>
                  <Text style={styles.orderItemName}>{item?.name}</Text>
                  <View style={[
                    styles.statusBadge,
                    { backgroundColor: getStatusColor(order.status) }
                  ]}>
                    <Text style={styles.statusText}>{order.status}</Text>
                  </View>
                </View>
                
                <View style={styles.orderDetails}>
                  <View style={styles.detailRow}>
                    <Text style={styles.detailLabel}>收货人:</Text>
                    <Text style={styles.detailValue}>{order.customerName}</Text>
                  </View>
                  <View style={styles.detailRow}>
                    <Text style={styles.detailLabel}>地址:</Text>
                    <Text style={styles.detailValue}>{order.deliveryAddress}</Text>
                  </View>
                  <View style={styles.detailRow}>
                    <Text style={styles.detailLabel}>预约时间:</Text>
                    <Text style={styles.detailValue}>{order.appointmentTime}</Text>
                  </View>
                  {order.deliveryTeam && (
                    <View style={styles.detailRow}>
                      <Text style={styles.detailLabel}>配送团队:</Text>
                      <Text style={styles.detailValue}>{order.deliveryTeam}</Text>
                    </View>
                  )}
                </View>
                
                <View style={styles.orderActions}>
                  {order.status === '待预约' && (
                    <TouchableOpacity 
                      style={styles.scheduleButton}
                      onPress={() => handleScheduleDelivery(order.id)}
                    >
                      <Text style={styles.scheduleButtonText}>预约配送</Text>
                    </TouchableOpacity>
                  )}
                  {order.deliveryTeam && (
                    <TouchableOpacity 
                      style={styles.contactButton}
                      onPress={() => handleContactTeam(order.deliveryTeam)}
                    >
                      <Text style={styles.contactButtonText}>联系团队</Text>
                    </TouchableOpacity>
                  )}
                </View>
              </View>
            );
          })}
        </View>

        {/* 合作配送团队 */}
        <View style={styles.teamsCard}>
          <Text style={styles.sectionTitle}>合作配送团队</Text>
          
          {deliveryTeams.map(team => (
            <View key={team.id} style={styles.teamItem}>
              <View style={styles.teamInfo}>
                <Text style={styles.teamName}>{team.name}</Text>
                <View style={styles.teamRating}>
                  <Text>{team.rating}</Text>
                </View>
                <Text style={styles.teamServices}>
                  服务: {team.services.join('、')}
                </Text>
              </View>
              
              <TouchableOpacity 
                style={styles.callButton}
                onPress={() => handleContactTeam(team.id)}
              >
                <Text style={styles.callButtonText}>致电</Text>
              </TouchableOpacity>
            </View>
          ))}
        </View>

        {/* 服务说明 */}
        <View style={styles.infoCard}>
          <Text style={styles.sectionTitle}>服务说明</Text>
          <Text style={styles.infoText}>• 专业大件物流团队配送</Text>
          <Text style={styles.infoText}>• 提供上门安装服务</Text>
          <Text style={styles.infoText}>• 支持旧家具拆除回收</Text>
          <Text style={styles.infoText}>• 全程跟踪配送状态</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: '#fff7ed',
  },
  header: {
    flexDirection: 'column',
    padding: 16,
    backgroundColor: '#ffffff',
    borderBottomWidth: 1,
    borderBottomColor: '#fed7aa',
  },
  title: {
    fontSize: 20,
    fontWeight: 'bold',
    color: '#9a3412',
    marginBottom: 4,
  },
  subtitle: {
    fontSize: 14,
    color: '#ea580c',
  },
  content: {
    flex: 1,
    marginTop: 12,
  },
  orderCard: {
    backgroundColor: '#ffffff',
    marginHorizontal: 16,
    marginBottom: 12,
    borderRadius: 12,
    padding: 16,
    elevation: 2,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
  },
  sectionTitle: {
    fontSize: 16,
    fontWeight: '600',
    color: '#9a3412',
    marginBottom: 12,
  },
  itemSelector: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    marginBottom: 12,
  },
  itemOption: {
    flex: 0.48,
    padding: 12,
    borderRadius: 8,
    backgroundColor: '#ffedd5',
    alignItems: 'center',
  },
  selectedItem: {
    backgroundColor: '#f97316',
  },
  itemImage: {
    width: 60,
    height: 60,
    borderRadius: 8,
    marginBottom: 8,
  },
  itemInfo: {
    alignItems: 'center',
  },
  itemName: {
    fontSize: 12,
    color: '#9a3412',
    textAlign: 'center',
  },
  itemPrice: {
    fontSize: 14,
    fontWeight: 'bold',
    color: '#ea580c',
    marginTop: 4,
  },
  input: {
    borderWidth: 1,
    borderColor: '#fed7aa',
    borderRadius: 8,
    padding: 12,
    fontSize: 14,
    backgroundColor: '#fff7ed',
    marginBottom: 12,
  },
  textArea: {
    minHeight: 80,
    textAlignVertical: 'top',
  },
  installationOption: {
    marginBottom: 12,
  },
  checkbox: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  checkboxInner: {
    width: 20,
    height: 20,
    borderRadius: 10,
    borderWidth: 1,
    borderColor: '#fed7aa',
    alignItems: 'center',
    justifyContent: 'center',
    marginRight: 8,
  },
  checked: {
    backgroundColor: '#f97316',
    borderColor: '#f97316',
  },
  checkmark: {
    color: '#ffffff',
    fontSize: 12,
    fontWeight: 'bold',
  },
  checkboxText: {
    fontSize: 14,
    color: '#9a3412',
  },
  createButton: {
    backgroundColor: '#f97316',
    paddingVertical: 14,
    borderRadius: 8,
    alignItems: 'center',
  },
  createButtonText: {
    color: '#ffffff',
    fontSize: 16,
    fontWeight: '600',
  },
  ordersCard: {
    backgroundColor: '#ffffff',
    marginHorizontal: 16,
    marginBottom: 12,
    borderRadius: 12,
    padding: 16,
    elevation: 2,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
  },
  orderItem: {
    padding: 12,
    borderBottomWidth: 1,
    borderBottomColor: '#fed7aa',
  },
  orderHeader: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: 8,
  },
  orderItemName: {
    fontSize: 16,
    fontWeight: '600',
    color: '#9a3412',
    flex: 1,
  },
  statusBadge: {
    paddingHorizontal: 8,
    paddingVertical: 4,
    borderRadius: 12,
  },
  statusText: {
    fontSize: 12,
    color: '#ffffff',
    fontWeight: '500',
  },
  orderDetails: {
    marginBottom: 12,
  },
  detailRow: {
    flexDirection: 'row',
    marginBottom: 4,
  },
  detailLabel: {
    fontSize: 12,
    color: '#64748b',
    width: 70,
  },
  detailValue: {
    fontSize: 12,
    color: '#9a3412',
    flex: 1,
  },
  orderActions: {
    flexDirection: 'row',
    justifyContent: 'flex-end',
  },
  scheduleButton: {
    backgroundColor: '#10b981',
    paddingHorizontal: 12,
    paddingVertical: 6,
    borderRadius: 16,
    marginRight: 8,
  },
  scheduleButtonText: {
    color: '#ffffff',
    fontSize: 12,
  },
  contactButton: {
    backgroundColor: '#fed7aa',
    paddingHorizontal: 12,
    paddingVertical: 6,
    borderRadius: 16,
  },
  contactButtonText: {
    color: '#f97316',
    fontSize: 12,
  },
  teamsCard: {
    backgroundColor: '#ffffff',
    marginHorizontal: 16,
    marginBottom: 12,
    borderRadius: 12,
    padding: 16,
    elevation: 2,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
  },
  teamItem: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    paddingVertical: 12,
    borderBottomWidth: 1,
    borderBottomColor: '#fed7aa',
  },
  teamInfo: {
    flex: 1,
  },
  teamName: {
    fontSize: 16,
    fontWeight: '600',
    color: '#9a3412',
    marginBottom: 4,
  },
  teamRating: {
    marginBottom: 4,
  },
  teamServices: {
    fontSize: 12,
    color: '#64748b',
  },
  callButton: {
    backgroundColor: '#f97316',
    paddingHorizontal: 16,
    paddingVertical: 8,
    borderRadius: 20,
  },
  callButtonText: {
    color: '#ffffff',
    fontSize: 14,
    fontWeight: '500',
  },
  infoCard: {
    backgroundColor: '#ffffff',
    marginHorizontal: 16,
    marginBottom: 80,
    borderRadius: 12,
    padding: 16,
    elevation: 2,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
  },
  infoText: {
    fontSize: 14,
    color: '#64748b',
    lineHeight: 20,
    marginBottom: 4,
  },
  bottomNav: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    backgroundColor: '#ffffff',
    borderTopWidth: 1,
    borderTopColor: '#fed7aa',
    paddingVertical: 12,
    position: 'absolute',
    bottom: 0,
    left: 0,
    right: 0,
  },
  navItem: {
    alignItems: 'center',
    flex: 1,
  },
  activeNavItem: {
    paddingTop: 4,
    borderTopWidth: 2,
    borderTopColor: '#f97316',
  },
  navIcon: {
    fontSize: 20,
    color: '#94a3b8',
    marginBottom: 4,
  },
  activeNavIcon: {
    color: '#f97316',
  },
  navText: {
    fontSize: 12,
    color: '#94a3b8',
  },
  activeNavText: {
    color: '#f97316',
    fontWeight: '500',
  },
});

export default LargeItemDeliveryApp;

请添加图片描述


打包

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

在这里插入图片描述

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

在这里插入图片描述

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

请添加图片描述
本文介绍了一个基于React Native和TypeScript的大件商品配送管理系统,采用模块化架构实现商品管理、订单流转和团队协作功能。系统通过精心设计的类型定义(LargeItem、DeliveryOrder、DeliveryTeam)确保数据安全性和业务匹配度,使用React Hooks进行状态管理,支持订单全生命周期跟踪。技术栈包含Flexbox布局、表单验证和跨平台组件,未来可升级至React Native新架构并适配鸿蒙系统。该系统为新零售场景下的大件物流配送提供了完整的数字化解决方案。

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

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐