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


企业采购追踪是制造业供应链管理的核心场景,高效的采购追踪系统需要兼顾订单可视化、物流实时性、生产联动性三大核心特性。本文将深度拆解基于 React Native 开发的企业采购追踪应用,剖析其订单管理、状态可视化、生产计划联动的技术实现思路,并提供完整的鸿蒙(HarmonyOS)ArkTS 跨端适配方案,为企业级供应链管理应用的跨端开发提供可落地的技术参考。

1. 贴合企业采购场景

企业采购追踪场景的核心诉求是采购订单管理、物流节点追踪、生产计划联动,代码通过 TypeScript 类型系统构建了精准贴合企业采购业务的领域模型:

// 采购订单类型
type PurchaseOrder = {
  id: string;
  orderNumber: string;
  itemName: string;
  supplier: string;
  quantity: number;
  unit: string;
  expectedDelivery: string;
  status: '已下单' | '运输中' | '已到货' | '延迟';
  currentLocation: string;
  trackingNumber: string;
};

// 物流节点类型
type LogisticsNode = {
  id: string;
  status: string;
  time: string;
  location: string;
  description: string;
};

模型设计的采购场景适配性分析

  • 采购订单全维度覆盖:包含订单号、物料名称、供应商、数量、单位、预计到货时间、状态、当前位置、追踪号等企业采购核心要素,完整还原从下单到到货的全生命周期信息;
  • 状态严格枚举:采购状态采用联合类型('已下单' | '运输中' | '已到货' | '延迟'),强类型约束保证状态管理的规范性,符合企业级应用的数据严谨性要求;
  • 物流节点解耦设计:将物流节点与采购订单分离设计,既保证订单核心信息的简洁性,又支持精细化的物流轨迹追踪;
  • 数量单位结构化:单独的 quantityunit 字段,适配工业物料的计量特性(如台、套、个等);
  • 时空属性完整:包含 expectedDelivery(时间)和 currentLocation(空间)属性,满足采购追踪的时空管理需求;
  • 唯一标识体系:订单 id + 物流节点 id 的双层唯一标识,为状态管理和渲染提供精准索引;
  • 追踪号关联trackingNumber 字段打通采购订单与物流系统,实现订单-物流的双向追溯。

2. 采购追踪

采购追踪系统的状态架构围绕采购订单列表、物流节点列表、搜索关键词三层核心状态构建,通过 React 的 useState 实现从订单筛选到物流追踪的全流程状态管控:

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

// 物流节点列表状态
const [logisticsNodes] = useState<LogisticsNode[]>([/* 初始物流节点 */]);

// 搜索关键词状态
const [searchTerm, setSearchTerm] = useState('');

状态管理的采购特性适配

  • 订单数据中心化:所有采购订单集中管理,支持批量筛选、统计和状态更新,符合企业级采购管理的业务形态;
  • 物流数据静态化设计:物流节点数据采用只读状态(仅声明不更新),模拟真实场景中物流数据由外部系统推送的特性;
  • 搜索驱动筛选:基于 searchTerm 实现多维度订单筛选(订单号、物料名称、供应商),满足企业采购的快速检索需求;
  • 不可变更新策略:状态更新均采用全新数组替换,保证 React 渲染机制的正常触发,确保采购信息的实时更新;
  • 统计计算实时化:基于订单状态的统计数据(总订单、运输中、延迟)实时计算,反映最新的采购状态;
  • 状态联动设计:订单状态直接驱动 UI 展示(状态徽章、操作按钮、预警提醒),实现数据-视图的双向绑定。

3. 采购追踪

企业采购追踪系统的核心价值在于订单筛选-物流追踪-生产联动的闭环能力,代码通过轻量化但专业的业务逻辑实现了采购追踪的核心交互:

(1)多维度订单筛选逻辑

企业采购场景下,快速定位目标订单是核心需求,代码实现了灵活的多维度筛选逻辑:

const filteredOrders = orders.filter(order => 
  order.orderNumber.includes(searchTerm) || 
  order.itemName.includes(searchTerm) ||
  order.supplier.includes(searchTerm)
);

筛选逻辑的企业采购适配性

  • 多维度检索:支持订单号、物料名称、供应商三个核心维度的模糊匹配,覆盖企业采购的主要检索场景;
  • 实时筛选:输入关键词即时筛选,无需额外触发,提升采购管理人员的操作效率;
  • 大小写兼容:代码中未做大小写转换(实际业务中可扩展),保持企业级数据的精确性;
  • 空值兼容:搜索关键词为空时返回全部订单,符合常规的筛选交互逻辑;
  • 性能优化:基于数组过滤实现轻量级筛选,避免复杂查询带来的性能损耗,适配移动端采购管理的轻量需求。
(2)状态

采购状态的可视化是提升管理效率的关键,代码通过状态-色彩映射实现了直观的视觉区分:

const getStatusColor = (status: string) => {
  switch (status) {
    case '已下单': return '#3b82f6';
    case '运输中': return '#f59e0b';
    case '已到货': return '#10b981';
    case '延迟': return '#ef4444';
    default: return '#6b7280';
  }
};

色彩映射的企业采购语义化设计

  • 已下单(蓝色):代表采购流程的启动,蓝色传递专业、可靠的企业级视觉感受;
  • 运输中(黄色):代表物料在途状态,黄色传递提醒、关注的视觉感受,符合生产物料管控的需求;
  • 已到货(绿色):代表采购流程的完成,绿色传递成功、就绪的视觉感受,可直接投入生产;
  • 延迟(红色):代表异常状态,红色传递警告、紧急的视觉感受,触发生产计划调整;
  • 默认色(灰色):兼容未知状态,保证企业级应用的鲁棒性;
  • 色彩体系统一:状态色彩在订单列表、统计卡片、预警提醒中保持一致,强化采购管理人员的视觉认知。
(3)物流追踪

采购追踪的最终价值在于指导生产,代码实现了物流追踪与生产计划调整的核心联动:

// 物流追踪逻辑
const handleTrackShipment = (orderId: string) => {
  const order = orders.find(o => o.id === orderId);
  if (order) {
    Alert.alert(
      '货物追踪',
      `订单号: ${order.orderNumber}\n` +
      `物品: ${order.itemName}\n` +
      `供应商: ${order.supplier}\n` +
      `预计到货: ${order.expectedDelivery}\n\n` +
      `物流轨迹:\n` +
      logisticsNodes.map(node => 
        `${node.time}\n${node.status}\n${node.location}\n${node.description}\n`
      ).join('\n'),
      [{ text: '确定', style: 'cancel' }]
    );
  }
};

// 生产计划调整逻辑
const handleUpdateProductionPlan = (orderId: string) => {
  const order = orders.find(o => o.id === orderId);
  if (order) {
    Alert.alert(
      '更新生产计划',
      `根据订单 ${order.orderNumber} 的到货情况调整生产排程`,
      [
        { text: '取消', style: 'cancel' },
        { 
          text: '确认调整', 
          onPress: () => Alert.alert('成功', '生产计划已更新') 
        }
      ]
    );
  }
};

联动逻辑的企业采购适配性

  • 订单精准定位:通过 orderId 精准检索目标订单,保证物流追踪和计划调整的准确性;
  • 信息完整展示:物流追踪弹窗展示订单核心信息 + 完整物流轨迹,满足采购管理人员的信息需求;
  • 操作权限控制:仅"运输中"状态的订单显示"调整计划"按钮,符合企业生产计划调整的业务规则;
  • 操作确认机制:生产计划调整增加二次确认,避免误操作,符合企业级应用的严谨性要求;
  • 反馈明确:操作成功后给出明确提示,让采购管理人员确认操作结果;
  • 数据联动设计:物流信息与采购订单数据联动展示,打通采购-物流-生产的数据链路;
  • 异常处理:订单不存在时静默处理,避免企业级应用的崩溃风险。

4. 采购追踪

采购追踪系统的视觉设计围绕数据可视化、状态语义化、操作轻量化三个核心维度展开,贴合企业采购管理的用户习惯:

(1)采购数据

数据可视化是企业级应用的核心需求,代码通过精准的布局和样式设计实现了专业的采购数据展示:

<View style={styles.statsCard}>
  <View style={styles.statItem}>
    <Text style={styles.statNumber}>{orders.length}</Text>
    <Text style={styles.statLabel}>总订单</Text>
  </View>
  <View style={styles.statItem}>
    <Text style={styles.statNumber}>
      {orders.filter(o => o.status === '运输中').length}
    </Text>
    <Text style={styles.statLabel}>运输中</Text>
  </View>
  <View style={styles.statItem}>
    <Text style={styles.statNumber}>
      {orders.filter(o => o.status === '延迟').length}
    </Text>
    <Text style={styles.statLabel}>延迟</Text>
  </View>
</View>

数据可视化的企业采购适配性

  • 核心指标突出:展示总订单、运输中、延迟三个核心采购指标,符合企业采购管理的关注重点;
  • 数字可视化:大号加粗数字 + 小号标签的组合,突出关键数据,提升信息获取效率;
  • 布局均衡:三列均分布局,保证统计卡片的视觉平衡,符合企业级应用的专业视觉风格;
  • 实时计算:统计数据基于当前订单状态实时计算,反映最新的采购状态;
  • 异常突出:延迟订单数量单独展示,便于采购管理人员快速识别异常;
  • 色彩语义化:统计数字采用主色调(蓝色),强化企业品牌视觉识别。
(2)企业级
  • 主色调适配:采用蓝色系(#0284c7)为主色调,契合企业级应用的专业、可靠的品牌属性;
  • 卡片式布局:所有功能模块采用卡片式设计,区分搜索区、统计区、订单区、预警区,提升界面的层次感;
  • 状态徽章设计:采购订单状态采用彩色徽章展示,强化视觉识别,便于快速扫描订单状态;
  • 预警提醒设计:延迟订单单独展示为预警卡片,黄色背景 + 警告图标,突出异常状态;
  • 操作按钮轻量化:追踪和调整计划按钮采用圆角胶囊设计,既突出可操作性,又不占用过多空间;
  • 信息层级清晰:订单号(重要)→ 物料名称(次要)→ 供应商/数量/位置(辅助)的信息层级,符合企业采购的信息阅读习惯;
  • 底部导航适配:按采购、追踪、计划、我的分类,贴合企业采购管理的核心功能场景;
  • 安全区域适配:使用 SafeAreaView 适配异形屏,保证企业级应用的界面完整性;
  • 阴影效果:卡片添加轻微阴影,提升界面的立体感和层次感,符合现代企业应用的视觉趋势;
  • 圆角设计:统一的12px圆角,兼顾企业级应用的专业性和移动端的友好性;
  • 字体层级:标题(16px)→ 正文(14px)→ 辅助文字(12px)的字体层级,保证信息的可读性。
(3)交互
  • 搜索即时响应:搜索框实时绑定关键词状态,输入过程中即时筛选订单,提升采购管理人员的检索效率;
  • 操作权限控制:仅运输中订单显示调整计划按钮,符合企业生产计划调整的业务规则;
  • 预警自动识别:延迟订单自动展示在预警提醒区域,无需手动筛选,提升异常处理效率;
  • 订单滚动优化:订单列表区域支持滚动,适配大批量采购订单的展示需求;
  • 信息折叠合理:订单详情自动换行,保证信息完整性的同时不破坏布局;
  • 底部导航固定:导航栏固定在底部,保证核心功能的快速访问;
  • 弹窗信息完整:物流追踪弹窗展示完整的订单和物流信息,满足采购管理人员的决策需求;
  • 二次确认机制:生产计划调整增加确认步骤,避免企业级操作的误执行。

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

1. 架构

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

@Entry
@Component
struct ProcurementTrackingApp {
  // 类型定义:对等实现 TypeScript 类型 → 接口定义
  interface PurchaseOrder {
    id: string;
    orderNumber: string;
    itemName: string;
    supplier: string;
    quantity: number;
    unit: string;
    expectedDelivery: string;
    status: '已下单' | '运输中' | '已到货' | '延迟';
    currentLocation: string;
    trackingNumber: string;
  }

  interface LogisticsNode {
    id: string;
    status: string;
    time: string;
    location: string;
    description: string;
  }

  // 状态管理:对等实现 useState → @State
  @State orders: PurchaseOrder[] = [/* 初始订单数据 */];
  @State logisticsNodes: LogisticsNode[] = [/* 初始物流节点 */];
  @State searchTerm: string = '';

  // 业务逻辑:完全复用 RN 端实现
  getStatusColor(status: string): string {/* 状态色彩映射 */}
  handleTrackShipment(orderId: string): void {/* 物流追踪 */}
  handleUpdateProductionPlan(orderId: string): void {/* 生产计划调整 */}

  // 计算属性:对等实现筛选逻辑
  get filteredOrders(): PurchaseOrder[] {
    return this.orders.filter(order => 
      order.orderNumber.includes(this.searchTerm) || 
      order.itemName.includes(this.searchTerm) ||
      order.supplier.includes(this.searchTerm)
    );
  }

  // 页面构建:镜像 RN 端布局结构
  build() {
    Column() {
      // 头部区域
      // 搜索栏
      // 统计概览
      // 订单列表
      // 预警提醒
      // 操作说明
      // 底部导航
    }
  }
}

React Native 特性 鸿蒙 ArkUI 对应实现 采购追踪适配关键说明
TypeScript 类型定义 TypeScript 接口定义 采购订单和物流节点类型完全复用,保证企业级数据结构一致性
useState @State 装饰器 订单、物流节点、搜索关键词的状态管理逻辑完全复用
数组过滤筛选 计算属性 get filteredOrders() 多维度订单筛选逻辑一致,保证企业采购检索体验
TouchableOpacity Button/Column + onClick 追踪、调整计划、导航项等可点击区域通过 onClick 事件实现
Alert.alert AlertDialog.show 物流追踪、计划调整等交互逻辑对等,符合企业级操作习惯
StyleSheet 链式样式 蓝色系主色调、状态色彩映射等企业级视觉规范 100% 复用
Array.map ForEach 组件 订单列表渲染逻辑一致,保证采购订单展示效果
ScrollView Scroll 组件 滚动容器语法差异,功能一致,适配大批量订单展示
TextInput TextInput 组件 搜索输入框属性基本一致,仅键盘类型适配
绝对定位 position: Position.Fixed 底部导航定位语法差异,效果一致
统计计算 内联表达式 订单状态统计逻辑一致,保证企业采购数据可视化
状态徽章 Column + 背景色 状态色彩映射逻辑一致,保证企业级视觉识别性
预警提醒 条件渲染 延迟订单筛选逻辑一致,保证异常状态突出展示

3. 鸿蒙代码

// 鸿蒙 ArkTS 完整实现
@Entry
@Component
struct ProcurementTrackingApp {
  // 采购订单类型定义
  interface PurchaseOrder {
    id: string;
    orderNumber: string;
    itemName: string;
    supplier: string;
    quantity: number;
    unit: string;
    expectedDelivery: string;
    status: '已下单' | '运输中' | '已到货' | '延迟';
    currentLocation: string;
    trackingNumber: string;
  }

  // 物流节点类型定义
  interface LogisticsNode {
    id: string;
    status: string;
    time: string;
    location: string;
    description: string;
  }

  // 状态管理
  @State orders: PurchaseOrder[] = [
    {
      id: '1',
      orderNumber: 'PO20231201001',
      itemName: '工业电机',
      supplier: 'ABB电气',
      quantity: 10,
      unit: '台',
      expectedDelivery: '2023-12-15',
      status: '运输中',
      currentLocation: '上海港',
      trackingNumber: 'TRK20231201001'
    },
    {
      id: '2',
      orderNumber: 'PO20231201002',
      itemName: 'PLC控制器',
      supplier: '西门子自动化',
      quantity: 25,
      unit: '套',
      expectedDelivery: '2023-12-10',
      status: '已到货',
      currentLocation: '工厂仓库',
      trackingNumber: 'TRK20231201002'
    },
    {
      id: '3',
      orderNumber: 'PO20231201003',
      itemName: '传感器',
      supplier: '欧姆龙',
      quantity: 100,
      unit: '个',
      expectedDelivery: '2023-12-20',
      status: '延迟',
      currentLocation: '日本大阪港',
      trackingNumber: 'TRK20231201003'
    }
  ];

  @State logisticsNodes: LogisticsNode[] = [
    {
      id: '1',
      status: '已发货',
      time: '2023-12-01 09:00',
      location: 'ABB上海工厂',
      description: '货物已从供应商工厂发出'
    },
    {
      id: '2',
      status: '海关清关',
      time: '2023-12-05 14:30',
      location: '上海海关',
      description: '货物正在办理海关清关手续'
    },
    {
      id: '3',
      status: '运输中',
      time: '2023-12-08 10:15',
      location: '上海港',
      description: '货物已装船,正在海上运输'
    }
  ];

  @State searchTerm: string = '';

  // 获取状态颜色
  getStatusColor(status: string): string {
    switch (status) {
      case '已下单': return '#3b82f6';
      case '运输中': return '#f59e0b';
      case '已到货': return '#10b981';
      case '延迟': return '#ef4444';
      default: return '#6b7280';
    }
  }

  // 处理物流追踪
  handleTrackShipment(orderId: string): void {
    const order = this.orders.find(o => o.id === orderId);
    if (order) {
      let logisticsText = '';
      this.logisticsNodes.forEach(node => {
        logisticsText += `${node.time}\n${node.status}\n${node.location}\n${node.description}\n\n`;
      });

      AlertDialog.show({
        title: '货物追踪',
        message: `订单号: ${order.orderNumber}\n` +
                 `物品: ${order.itemName}\n` +
                 `供应商: ${order.supplier}\n` +
                 `预计到货: ${order.expectedDelivery}\n\n` +
                 `物流轨迹:\n${logisticsText}`,
        confirm: { value: '确定' }
      });
    }
  }

  // 处理生产计划更新
  handleUpdateProductionPlan(orderId: string): void {
    const order = this.orders.find(o => o.id === orderId);
    if (order) {
      AlertDialog.show({
        title: '更新生产计划',
        message: `根据订单 ${order.orderNumber} 的到货情况调整生产排程`,
        cancel: { value: '取消' },
        confirm: { 
          value: '确认调整',
          action: () => {
            AlertDialog.show({
              title: '成功',
              message: '生产计划已更新',
              confirm: { value: '确定' }
            });
          }
        }
      });
    }
  }

  // 筛选订单
  get filteredOrders(): PurchaseOrder[] {
    return this.orders.filter(order => 
      order.orderNumber.includes(this.searchTerm) || 
      order.itemName.includes(this.searchTerm) ||
      order.supplier.includes(this.searchTerm)
    );
  }

  build() {
    Column()
      .flex(1)
      .backgroundColor('#f0f9ff')
      .safeArea(true) {
      
      // 头部区域
      Column()
        .padding(16)
        .backgroundColor('#ffffff')
        .borderBottom({ width: 1, color: '#bae6fd' }) {
        Text('采购追踪')
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .fontColor('#0c4a6e')
          .marginBottom(4);
        
        Text('实时监控重要物料到货情况')
          .fontSize(14)
          .fontColor('#0284c7');
      }

      // 滚动内容区
      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 }) {
            
            // 搜索容器
            Row()
              .alignItems(ItemAlign.Center)
              .backgroundColor('#f0f9ff')
              .borderRadius(8)
              .paddingHorizontal(12) {
              Text('🔍')
                .fontSize(16)
                .fontColor('#64748b')
                .marginRight(8);
              
              TextInput({
                placeholder: '搜索订单号、物品名称或供应商',
                text: this.searchTerm
              })
                .onChange((value) => {
                  this.searchTerm = value;
                })
                .flex(1)
                .paddingVertical(12)
                .fontSize(14)
                .fontColor('#0c4a6e');
            }
          }

          // 统计概览卡片
          Row()
            .backgroundColor('#ffffff')
            .marginLeft(16)
            .marginRight(16)
            .marginBottom(12)
            .borderRadius(12)
            .padding(16)
            .shadow({ color: '#000', offsetX: 0, offsetY: 2, opacity: 0.1, radius: 4 })
            .justifyContent(FlexAlign.SpaceAround) {
            
            // 总订单
            Column()
              .alignItems(ItemAlign.Center) {
              Text(`${this.orders.length}`)
                .fontSize(18)
                .fontWeight(FontWeight.Bold)
                .fontColor('#0284c7');
              
              Text('总订单')
                .fontSize(12)
                .fontColor('#64748b')
                .marginTop(4);
            }
            
            // 运输中
            Column()
              .alignItems(ItemAlign.Center) {
              Text(`${this.orders.filter(o => o.status === '运输中').length}`)
                .fontSize(18)
                .fontWeight(FontWeight.Bold)
                .fontColor('#0284c7');
              
              Text('运输中')
                .fontSize(12)
                .fontColor('#64748b')
                .marginTop(4);
            }
            
            // 延迟
            Column()
              .alignItems(ItemAlign.Center) {
              Text(`${this.orders.filter(o => o.status === '延迟').length}`)
                .fontSize(18)
                .fontWeight(FontWeight.Bold)
                .fontColor('#0284c7');
              
              Text('延迟')
                .fontSize(12)
                .fontColor('#64748b')
                .marginTop(4);
            }
          }

          // 订单列表卡片
          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('#0c4a6e')
              .marginBottom(12);
            
            // 订单列表
            ForEach(this.filteredOrders, (order: PurchaseOrder) => {
              Column()
                .paddingVertical(12)
                .borderBottom({ width: 1, color: '#bae6fd' }) {
                
                // 订单头部
                Row()
                  .justifyContent(FlexAlign.SpaceBetween)
                  .alignItems(ItemAlign.Center)
                  .marginBottom(8) {
                  Column() {
                    Text(order.orderNumber)
                      .fontSize(14)
                      .fontWeight(FontWeight.SemiBold)
                      .fontColor('#0c4a6e');
                    
                    Text(order.itemName)
                      .fontSize(12)
                      .fontColor('#64748b')
                      .marginTop(2);
                  }
                  
                  // 状态徽章
                  Column()
                    .paddingHorizontal(8)
                    .paddingVertical(4)
                    .borderRadius(12)
                    .backgroundColor(this.getStatusColor(order.status)) {
                    Text(order.status)
                      .fontSize(12)
                      .fontColor('#ffffff')
                      .fontWeight(FontWeight.Medium);
                  }
                }
                
                // 订单详情
                Column()
                  .marginBottom(12) {
                  // 供应商
                  Row()
                    .marginBottom(4) {
                    Text('供应商:')
                      .fontSize(12)
                      .fontColor('#64748b')
                      .width(70);
                    
                    Text(order.supplier)
                      .fontSize(12)
                      .fontColor('#0c4a6e')
                      .flex(1);
                  }
                  
                  // 数量
                  Row()
                    .marginBottom(4) {
                    Text('数量:')
                      .fontSize(12)
                      .fontColor('#64748b')
                      .width(70);
                    
                    Text(`${order.quantity} ${order.unit}`)
                      .fontSize(12)
                      .fontColor('#0c4a6e')
                      .flex(1);
                  }
                  
                  // 预计到货
                  Row()
                    .marginBottom(4) {
                    Text('预计到货:')
                      .fontSize(12)
                      .fontColor('#64748b')
                      .width(70);
                    
                    Text(order.expectedDelivery)
                      .fontSize(12)
                      .fontColor('#0c4a6e')
                      .flex(1);
                  }
                  
                  // 当前位置
                  Row() {
                    Text('当前位置:')
                      .fontSize(12)
                      .fontColor('#64748b')
                      .width(70);
                    
                    Text(order.currentLocation)
                      .fontSize(12)
                      .fontColor('#0c4a6e')
                      .flex(1);
                  }
                }
                
                // 订单操作
                Row()
                  .justifyContent(FlexAlign.End) {
                  // 追踪按钮
                  Button()
                    .backgroundColor('#0284c7')
                    .paddingHorizontal(12)
                    .paddingVertical(6)
                    .borderRadius(16)
                    .marginRight(8)
                    .onClick(() => this.handleTrackShipment(order.id)) {
                    Text('追踪')
                      .fontColor('#ffffff')
                      .fontSize(12);
                  }
                  
                  // 调整计划按钮(仅运输中显示)
                  if (order.status === '运输中') {
                    Button()
                      .backgroundColor('#f59e0b')
                      .paddingHorizontal(12)
                      .paddingVertical(6)
                      .borderRadius(16)
                      .onClick(() => this.handleUpdateProductionPlan(order.id)) {
                      Text('调整计划')
                        .fontColor('#ffffff')
                        .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('#0c4a6e')
              .marginBottom(12);
            
            // 延迟订单预警
            ForEach(this.orders.filter(o => o.status === '延迟'), (order: PurchaseOrder) => {
              Row()
                .alignItems(ItemAlign.Center)
                .padding(12)
                .backgroundColor('#fffbeb')
                .borderRadius(8)
                .marginBottom(8) {
                Text('⚠️')
                  .fontSize(16)
                  .marginRight(8);
                
                Column()
                  .flex(1) {
                  Text('订单延迟')
                    .fontSize(14)
                    .fontWeight(FontWeight.Medium)
                    .fontColor('#92400e')
                    .marginBottom(2);
                  
                  Text(`${order.itemName} 预计 ${order.expectedDelivery} 到货,当前状态延迟`)
                    .fontSize(12)
                    .fontColor('#92400e');
                }
              }
            })
          }

          // 操作说明卡片
          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('#0c4a6e')
              .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: '#bae6fd' })
        .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: '#0284c7' }) {
        Text('👤')
          .fontSize(20)
          .fontColor('#0284c7')
          .marginBottom(4);
        
        Text('我的')
          .fontSize(12)
          .fontColor('#0284c7')
          .fontWeight(FontWeight.Medium);
      }
    }
  }
}

1. 核心原则

  • 采购领域模型完全复用:采购订单和物流节点的类型定义在两端保持一致,包含订单号、物料名称、供应商、状态等企业采购核心属性,保证业务逻辑的准确性;
  • 视觉规范100%对齐:蓝色系主色调、状态色彩映射、卡片布局等视觉属性完全复用,符合企业级应用的专业视觉认知;
  • 采购业务流程统一:订单筛选、物流追踪、计划调整等核心业务流程保持一致的规则,符合企业采购管理的行业惯例;
  • 数据可视化逻辑对等:订单状态统计、预警提醒展示等数据可视化算法在两端使用相同的规则,保证采购数据展示的一致性;
  • 交互体验一致:搜索筛选、物流追踪、计划调整等交互逻辑保持相同的用户体验,符合企业采购管理的操作习惯;
  • 语义化设计统一:状态色彩、预警提醒样式等语义化设计保持一致,提升采购信息的可读性;
  • 平台特性兼容:弹窗展示、输入框交互等平台特有 API 做适配处理,保证采购追踪功能的可用性;
  • 性能优化适配:鸿蒙端利用 ForEach 组件的复用机制优化订单渲染性能,RN 端利用数组映射实现高效渲染。

2. 采购追踪系统

  • 供应商管理集成:接入供应商管理系统,展示供应商评级、交货准时率等信息;
  • 采购审批流程:集成采购审批流,支持移动端审批采购订单;
  • 库存联动管理:对接库存系统,展示物料库存水平,自动触发补货提醒;
  • 智能预警算法:基于历史数据和到货周期,预测延迟风险,提前预警;
  • 多维度统计分析:增加采购金额、交付准时率、供应商绩效等多维度统计报表;
  • 批量操作功能:支持批量追踪、批量调整生产计划等批量操作;
  • 电子签章集成:支持移动端电子签章,完成采购合同签署;
  • 条码/二维码扫描:集成扫码功能,快速录入物料信息和订单号;
  • 采购报表导出:支持采购数据报表导出,便于企业数据分析;
  • 消息推送集成:支持订单状态变更、延迟预警等消息推送;
  • 多语言支持:适配中英文等多语言,支持跨国采购管理;
  • 权限管理系统:集成企业权限管理,按角色控制采购操作权限。

企业采购追踪系统作为供应链管理的核心工具,其跨端适配的关键在于领域模型的企业级专业性、数据可视化的管理效率、交互体验的业务适配性。这份 React Native 实现的采购追踪组件,通过强类型领域建模、精细化状态管理、企业级视觉设计,构建了高效的移动端采购追踪体验;而鸿蒙 ArkTS 端的适配实现,则验证了跨端开发中"逻辑复用、体验统一"的核心原则。

  1. 企业采购追踪系统的类型设计需贴合采购场景,覆盖订单号、物料、供应商、状态等核心属性,状态建议采用联合类型保证数据严谨性;
  2. 多维度订单筛选是企业采购管理的核心需求,需支持订单号、物料名称、供应商等维度的模糊匹配;
  3. 跨端适配的核心是采购业务逻辑复用 + 平台特性适配,订单筛选、物流追踪、计划调整等核心逻辑无需重写;
  4. 状态色彩的语义化设计能显著提升采购状态的识别效率,延迟状态建议使用红色突出异常;
  5. 数据可视化是企业级应用的核心,需突出总订单、运输中、延迟等核心采购指标;
  6. 预警提醒自动识别延迟订单,是提升企业采购管理效率的关键技术手段;
  7. 生产计划联动逻辑需增加二次确认机制,符合企业级应用的操作严谨性要求。

核心功能模块

ProcurementTrackingApp组件是一个典型的React Native功能型组件,专注于实现企业采购追踪功能。该应用采用了现代化的React函数式组件架构,通过useState钩子管理本地状态,构建了一个完整的企业采购追踪系统。

从代码结构来看,应用主要包含以下核心功能模块:

  • 采购订单管理:显示采购订单列表,包括订单号、物品名称、供应商、数量、单位、预计到货时间、状态、当前位置和追踪号等信息,帮助企业快速了解采购订单情况。

  • 物流追踪:支持追踪采购订单的物流信息,显示物流节点的状态、时间、地点和描述等,帮助企业了解采购物品的运输轨迹。

  • 生产计划更新:支持根据采购订单的到货情况调整生产排程,确保生产计划与采购到货情况的协调。

  • 搜索功能:支持根据订单号、物品名称或供应商搜索订单,提高订单查找效率。

  • 统计概览:显示采购订单的统计信息,如总订单数、运输中订单数等,帮助企业快速了解采购订单的整体情况。

代码结构特点

该组件采用了清晰的模块化结构,通过不同的View容器组织各个功能区域,使用ScrollView确保在小屏幕设备上的完整显示。组件状态管理简洁明了,使用useState钩子管理订单列表、物流节点和搜索词等状态。

二、React Native核心技术点详解

状态管理与Hooks应用

ProcurementTrackingApp组件充分利用了React Hooks的优势,使用useState钩子管理多个状态变量:

const [orders, setOrders] = useState<PurchaseOrder[]>([
  // 采购订单数据
]);

const [logisticsNodes] = useState<LogisticsNode[]>([
  // 物流节点数据
]);

const [searchTerm, setSearchTerm] = useState('');

这种状态管理方式相比传统的类组件更为简洁,代码可读性更高,同时也更符合React的函数式编程理念。通过TypeScript类型定义,确保了数据结构的一致性和类型安全。

TypeScript类型

ProcurementTrackingApp组件使用了TypeScript的类型定义功能,为采购订单和物流节点定义了明确的类型:

// 采购订单类型
type PurchaseOrder = {
  id: string;
  orderNumber: string;
  itemName: string;
  supplier: string;
  quantity: number;
  unit: string;
  expectedDelivery: string;
  status: '已下单' | '运输中' | '已到货' | '延迟';
  currentLocation: string;
  trackingNumber: string;
};

// 物流节点类型
type LogisticsNode = {
  id: string;
  status: string;
  time: string;
  location: string;
  description: string;
};

这种类型定义方式提高了代码的可读性和可维护性,减少了运行时错误的可能性。

布局系统

应用使用了React Native的核心UI组件构建界面:

  • SafeAreaView:确保内容在刘海屏等异形屏设备上正常显示。

  • ScrollView:实现内容的垂直滚动,适应不同屏幕尺寸。

  • TouchableOpacity:实现可点击的交互元素,如追踪货物按钮和更新生产计划按钮。

  • TextInput:实现文本输入功能,用于搜索订单。

  • View:作为布局容器,组织界面结构。

  • Text:显示文本内容,如标题、标签和提示信息。

布局方面,应用采用了Flexbox布局系统,通过样式定义实现响应式设计。例如,搜索栏使用了水平布局,统计概览使用了水平布局,订单列表使用了垂直布局。

事件处理

应用实现了多种用户交互功能:

  • 追踪货物:通过TouchableOpacity的onPress属性处理用户点击,调用handleTrackShipment函数执行货物追踪操作。

  • 更新生产计划:通过TouchableOpacity的onPress属性处理用户点击,调用handleUpdateProductionPlan函数执行生产计划更新操作。

  • 搜索功能:通过TextInput的onChangeText属性实时更新搜索词,实现订单的实时过滤。

  • 警告提示:使用Alert组件显示操作结果和订单信息,提供清晰的用户反馈。

数据过滤

应用实现了数据过滤和处理逻辑:

const filteredOrders = orders.filter(order =>
  order.orderNumber.includes(searchTerm) ||
  order.itemName.includes(searchTerm) ||
  order.supplier.includes(searchTerm)
);

这种实现方式使用了简单的字符串包含判断进行数据过滤,确保搜索功能的流畅运行。


组件兼容性

在跨端开发中,React Native组件与鸿蒙平台的兼容性是关键考虑因素。ProcurementTrackingApp组件使用的核心UI组件在鸿蒙平台上都有对应的实现:

  • SafeAreaView:在鸿蒙平台上可以使用类似的安全区域组件。

  • ScrollView:鸿蒙平台提供了滚动视图组件。

  • TouchableOpacity:鸿蒙平台有对应的可点击组件。

  • TextInput:鸿蒙平台支持文本输入功能。

  • ViewText:鸿蒙平台提供了基础的布局和文本组件。

API差异

React Native与鸿蒙平台在API层面存在一些差异,需要注意以下几点:

  1. Dimensions API:应用使用Dimensions.get(‘window’)获取屏幕尺寸,在鸿蒙平台上需要使用相应的API获取屏幕信息。

  2. Alert API:React Native的Alert组件在鸿蒙平台上可能有不同的实现方式,需要进行适配。

  3. Base64图标:应用使用Base64编码的图标,这种方式在跨平台开发中是可行的,但需要注意性能影响。

样式适配

React Native的样式系统与鸿蒙平台的样式系统存在差异,需要注意以下几点:

  1. 样式写法:React Native使用驼峰命名法定义样式,而鸿蒙平台可能使用不同的样式定义方式。

  2. 布局系统:虽然两者都支持Flexbox布局,但在具体实现细节上可能存在差异。

  3. 响应式设计:需要确保应用在不同屏幕尺寸和方向下都能正常显示。


组件渲染

ProcurementTrackingApp组件在性能优化方面采取了以下措施:

  1. 避免不必要的重渲染:使用useState钩子管理状态,确保只有状态变化时才会触发组件重渲染。

  2. 合理使用ScrollView:使用ScrollView包装内容,确保在小屏幕设备上的完整显示,同时避免一次性加载过多内容。

  3. 样式复用:通过StyleSheet.create()创建可复用的样式,减少运行时的样式计算。

  4. 数据过滤优化:使用简单的字符串包含判断进行数据过滤,确保搜索功能的流畅运行。

用户体验

  1. 视觉层次感:通过卡片式设计、阴影效果和边框,创建清晰的视觉层次,提高界面的可读性。

  2. 色彩方案:为不同订单状态定义了不同的颜色,增强视觉识别度,提高用户体验。

  3. 交互反馈:所有可点击元素都应该有明确的视觉反馈,如TouchableOpacity的默认触摸效果。

  4. 信息展示:通过Alert组件显示详细的订单信息和物流信息,帮助用户快速了解采购订单情况。

  5. 状态反馈:通过颜色和文本,清晰展示订单的当前状态,帮助用户了解订单情况。

响应式设计

应用实现了响应式设计,确保在不同屏幕尺寸下都能正常显示:

  1. 使用Dimensions API:获取屏幕尺寸,为不同屏幕尺寸提供适当的布局。

  2. Flexbox布局:使用Flexbox布局系统,实现自适应的界面布局。

  3. 滚动视图:使用ScrollView确保在小屏幕设备上的完整显示。

  4. 字体大小:使用相对字体大小,确保在不同屏幕尺寸下的可读性。


数据结构

ProcurementTrackingApp组件使用了TypeScript的类型定义功能,为采购订单和物流节点定义了明确的类型:

// 采购订单类型
type PurchaseOrder = {
  id: string;
  orderNumber: string;
  itemName: string;
  supplier: string;
  quantity: number;
  unit: string;
  expectedDelivery: string;
  status: '已下单' | '运输中' | '已到货' | '延迟';
  currentLocation: string;
  trackingNumber: string;
};

// 物流节点类型
type LogisticsNode = {
  id: string;
  status: string;
  time: string;
  location: string;
  description: string;
};

这种类型定义方式提高了代码的可读性和可维护性,减少了运行时错误的可能性。

状态管理

ProcurementTrackingApp组件使用useState钩子管理应用状态:

const [orders, setOrders] = useState<PurchaseOrder[]>([
  // 采购订单数据
]);

const [logisticsNodes] = useState<LogisticsNode[]>([
  // 物流节点数据
]);

const [searchTerm, setSearchTerm] = useState('');

这种状态管理方式简洁明了,使用单个状态变量管理相关联的数据,提高了代码的组织性。

物流追踪

应用实现了物流追踪的核心功能:

const handleTrackShipment = (orderId: string) => {
  const order = orders.find(o => o.id === orderId);
  if (order) {
    Alert.alert(
      '货物追踪',
      `订单号: ${order.orderNumber}\n` +
      `物品: ${order.itemName}\n` +
      `供应商: ${order.supplier}\n` +
      `预计到货: ${order.expectedDelivery}\n\n` +
      `物流轨迹:\n` +
      logisticsNodes.map(node =>
        `${node.time}\n${node.status}\n${node.location}\n${node.description}\n`
      ).join('\n'),
      [{ text: '确定', style: 'cancel' }]
    );
  }
};

这种实现方式使用了Alert组件显示详细的订单信息和物流信息,确保了物流追踪过程的完整性和可靠性。

生产计划

应用实现了生产计划更新的核心功能:

const handleUpdateProductionPlan = (orderId: string) => {
  const order = orders.find(o => o.id === orderId);
  if (order) {
    Alert.alert(
      '更新生产计划',
      `根据订单 ${order.orderNumber} 的到货情况调整生产排程`,
      [
        { text: '取消', style: 'cancel' },
        {
          text: '确认调整',
          onPress: () => Alert.alert('成功', '生产计划已更新')
        }
      ]
    );
  }
};

这种实现方式使用了Alert组件显示生产计划更新的确认信息,确保了生产计划更新过程的完整性和可靠性。

搜索功能

应用实现了搜索功能的核心逻辑,通过过滤订单数组,根据搜索词匹配订单号、物品名称或供应商,实现订单的实时搜索。

ProcurementTrackingApp组件展示了如何使用React Native构建一个功能完整、用户体验良好的企业采购追踪应用。通过现代化的React函数式组件架构和Hooks状态管理,实现了清晰的代码结构和高效的开发体验。

ProcurementTrackingApp组件展示了React Native在构建功能型应用方面的优势:

  • 开发效率高:使用React的声明式编程模型和组件化架构,提高开发效率。

  • 跨平台兼容:一套代码可以运行在iOS、Android和鸿蒙等多个平台。

  • 用户体验好:通过原生组件和优化,提供接近原生应用的用户体验。

  • 维护成本低:统一的代码库和现代化的架构,降低维护成本。

  • 扩展性强:模块化的设计和清晰的代码结构,便于后续功能的扩展和维护。

通过对ProcurementTrackingApp组件的技术解读,我们可以看到React Native在跨端开发中的强大潜力,以及如何通过合理的架构设计和优化策略,构建高质量的移动应用。


1. 状态管理

当前应用使用了多个useState钩子管理状态,可以考虑将相关状态组合到一个状态对象中,提高代码的组织性:

const [appState, setAppState] = useState({
  orders: [
    // 采购订单数据
  ],
  logisticsNodes: [
    // 物流节点数据
  ],
  searchTerm: ''
});

2. 组件拆分

将大组件拆分为更小的、可复用的子组件,提高代码的可读性和可维护性:

// 子组件示例
const OrderItem: React.FC<{ order: PurchaseOrder; onTrackShipment: (id: string) => void; onUpdateProductionPlan: (id: string) => void }> = ({ order, onTrackShipment, onUpdateProductionPlan }) => (
  <View style={styles.orderItem}>
    <View style={styles.orderInfo}>
      <Text style={styles.orderNumber}>订单号: {order.orderNumber}</Text>
      <Text style={styles.itemInfo}>物品: {order.itemName} × {order.quantity} {order.unit}</Text>
      <Text style={styles.supplierInfo}>供应商: {order.supplier}</Text>
      <Text style={styles.deliveryInfo}>预计到货: {order.expectedDelivery}</Text>
      <Text style={styles.locationInfo}>当前位置: {order.currentLocation}</Text>
      <View style={[styles.statusBadge, { backgroundColor: getStatusColor(order.status) }]}>
        <Text style={styles.statusText}>{order.status}</Text>
      </View>
    </View>
    <View style={styles.orderActions}>
      <TouchableOpacity 
        style={styles.actionButton} 
        onPress={() => onTrackShipment(order.id)}
      >
        <Text style={styles.actionButtonText}>追踪货物</Text>
      </TouchableOpacity>
      <TouchableOpacity 
        style={styles.actionButton} 
        onPress={() => onUpdateProductionPlan(order.id)}
      >
        <Text style={styles.actionButtonText}>更新生产计划</Text>
      </TouchableOpacity>
    </View>
  </View>
);

// 父组件中使用
<View style={styles.orderList}>
  {filteredOrders.map(order => (
    <OrderItem
      key={order.id}
      order={order}
      onTrackShipment={handleTrackShipment}
      onUpdateProductionPlan={handleUpdateProductionPlan}
    />
  ))}
</View>

3. 类型定义

使用TypeScript的接口和类型别名,为状态和props定义更清晰的类型结构:

interface PurchaseOrder {
  id: string;
  orderNumber: string;
  itemName: string;
  supplier: string;
  quantity: number;
  unit: string;
  expectedDelivery: string;
  status: '已下单' | '运输中' | '已到货' | '延迟';
  currentLocation: string;
  trackingNumber: string;
}

interface LogisticsNode {
  id: string;
  status: string;
  time: string;
  location: string;
  description: string;
}

interface AppState {
  orders: PurchaseOrder[];
  logisticsNodes: LogisticsNode[];
  searchTerm: string;
}

4. 错误处理

添加更全面的错误处理机制,提高应用的稳定性和可靠性:

const handleTrackShipment = (orderId: string) => {
  try {
    const order = orders.find(o => o.id === orderId);
    if (order) {
      Alert.alert(
        '货物追踪',
        `订单号: ${order.orderNumber}\n` +
        `物品: ${order.itemName}\n` +
        `供应商: ${order.supplier}\n` +
        `预计到货: ${order.expectedDelivery}\n\n` +
        `物流轨迹:\n` +
        logisticsNodes.map(node =>
          `${node.time}\n${node.status}\n${node.location}\n${node.description}\n`
        ).join('\n'),
        [{ text: '确定', style: 'cancel' }]
      );
    } else {
      Alert.alert('错误', '未找到订单信息', [
        { text: '确定' }
      ]);
    }
  } catch (error) {
    Alert.alert('错误', '操作失败,请稍后重试', [
      { text: '确定' }
    ]);
  }
};

5. 网络请求

实现真正的网络请求,获取真实的采购订单和物流节点数据:

import axios from 'axios';

// 获取采购订单数据
const fetchOrders = async () => {
  try {
    const response = await axios.get('https://api.example.com/orders');
    return response.data;
  } catch (error) {
    console.error('获取采购订单数据失败:', error);
    throw error;
  }
};

// 获取物流节点数据
const fetchLogisticsNodes = async (trackingNumber: string) => {
  try {
    const response = await axios.get(`https://api.example.com/logistics/${trackingNumber}`);
    return response.data;
  } catch (error) {
    console.error('获取物流节点数据失败:', error);
    throw error;
  }
};

// 组件挂载时获取数据
useEffect(() => {
  const loadData = async () => {
    try {
      const ordersData = await fetchOrders();
      setOrders(ordersData);
    } catch (error) {
      Alert.alert('错误', '获取采购订单数据失败,请稍后重试', [
        { text: '确定' }
      ]);
    }
  };
  loadData();
}, []);

6. 搜索功能

优化搜索功能,提高搜索效率:

const filteredOrders = orders.filter(order => {
  const searchLower = searchTerm.toLowerCase();
  return (
    order.orderNumber.toLowerCase().includes(searchLower) ||
    order.itemName.toLowerCase().includes(searchLower) ||
    order.supplier.toLowerCase().includes(searchLower)
  );
});

通过以上优化建议,可以进一步提高ProcurementTrackingApp组件的性能、可维护性和用户体验,使其成为一个更加完善的企业采购追踪应用。

React Native企业采购追踪应用展示了如何使用现代化的React技术构建一个功能完整、用户体验良好的移动应用。通过合理的架构设计、状态管理和性能优化,可以构建出高质量的跨端应用,同时为后续的鸿蒙平台适配奠定基础。


真实演示案例代码:







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

// Base64 图标库
const ICONS_BASE64 = {
  factory: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  tracking: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  calendar: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  location: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  alert: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  document: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  check: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  info: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
};

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

// 采购订单类型
type PurchaseOrder = {
  id: string;
  orderNumber: string;
  itemName: string;
  supplier: string;
  quantity: number;
  unit: string;
  expectedDelivery: string;
  status: '已下单' | '运输中' | '已到货' | '延迟';
  currentLocation: string;
  trackingNumber: string;
};

// 物流节点类型
type LogisticsNode = {
  id: string;
  status: string;
  time: string;
  location: string;
  description: string;
};

// 企业采购追踪应用组件
const ProcurementTrackingApp: React.FC = () => {
  const [orders, setOrders] = useState<PurchaseOrder[]>([
    {
      id: '1',
      orderNumber: 'PO20231201001',
      itemName: '工业电机',
      supplier: 'ABB电气',
      quantity: 10,
      unit: '台',
      expectedDelivery: '2023-12-15',
      status: '运输中',
      currentLocation: '上海港',
      trackingNumber: 'TRK20231201001'
    },
    {
      id: '2',
      orderNumber: 'PO20231201002',
      itemName: 'PLC控制器',
      supplier: '西门子自动化',
      quantity: 25,
      unit: '套',
      expectedDelivery: '2023-12-10',
      status: '已到货',
      currentLocation: '工厂仓库',
      trackingNumber: 'TRK20231201002'
    },
    {
      id: '3',
      orderNumber: 'PO20231201003',
      itemName: '传感器',
      supplier: '欧姆龙',
      quantity: 100,
      unit: '个',
      expectedDelivery: '2023-12-20',
      status: '延迟',
      currentLocation: '日本大阪港',
      trackingNumber: 'TRK20231201003'
    }
  ]);

  const [logisticsNodes] = useState<LogisticsNode[]>([
    {
      id: '1',
      status: '已发货',
      time: '2023-12-01 09:00',
      location: 'ABB上海工厂',
      description: '货物已从供应商工厂发出'
    },
    {
      id: '2',
      status: '海关清关',
      time: '2023-12-05 14:30',
      location: '上海海关',
      description: '货物正在办理海关清关手续'
    },
    {
      id: '3',
      status: '运输中',
      time: '2023-12-08 10:15',
      location: '上海港',
      description: '货物已装船,正在海上运输'
    }
  ]);

  const [searchTerm, setSearchTerm] = useState('');

  const getStatusColor = (status: string) => {
    switch (status) {
      case '已下单': return '#3b82f6';
      case '运输中': return '#f59e0b';
      case '已到货': return '#10b981';
      case '延迟': return '#ef4444';
      default: return '#6b7280';
    }
  };

  const handleTrackShipment = (orderId: string) => {
    const order = orders.find(o => o.id === orderId);
    if (order) {
      Alert.alert(
        '货物追踪',
        `订单号: ${order.orderNumber}\n` +
        `物品: ${order.itemName}\n` +
        `供应商: ${order.supplier}\n` +
        `预计到货: ${order.expectedDelivery}\n\n` +
        `物流轨迹:\n` +
        logisticsNodes.map(node => 
          `${node.time}\n${node.status}\n${node.location}\n${node.description}\n`
        ).join('\n'),
        [{ text: '确定', style: 'cancel' }]
      );
    }
  };

  const handleUpdateProductionPlan = (orderId: string) => {
    const order = orders.find(o => o.id === orderId);
    if (order) {
      Alert.alert(
        '更新生产计划',
        `根据订单 ${order.orderNumber} 的到货情况调整生产排程`,
        [
          { text: '取消', style: 'cancel' },
          { 
            text: '确认调整', 
            onPress: () => Alert.alert('成功', '生产计划已更新') 
          }
        ]
      );
    }
  };

  const filteredOrders = orders.filter(order => 
    order.orderNumber.includes(searchTerm) || 
    order.itemName.includes(searchTerm) ||
    order.supplier.includes(searchTerm)
  );

  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.searchCard}>
          <View style={styles.searchContainer}>
            <Text style={styles.searchIcon}>🔍</Text>
            <TextInput
              style={styles.searchInput}
              placeholder="搜索订单号、物品名称或供应商"
              value={searchTerm}
              onChangeText={setSearchTerm}
            />
          </View>
        </View>

        {/* 统计概览 */}
        <View style={styles.statsCard}>
          <View style={styles.statItem}>
            <Text style={styles.statNumber}>{orders.length}</Text>
            <Text style={styles.statLabel}>总订单</Text>
          </View>
          <View style={styles.statItem}>
            <Text style={styles.statNumber}>
              {orders.filter(o => o.status === '运输中').length}
            </Text>
            <Text style={styles.statLabel}>运输中</Text>
          </View>
          <View style={styles.statItem}>
            <Text style={styles.statNumber}>
              {orders.filter(o => o.status === '延迟').length}
            </Text>
            <Text style={styles.statLabel}>延迟</Text>
          </View>
        </View>

        {/* 订单列表 */}
        <View style={styles.ordersCard}>
          <Text style={styles.sectionTitle}>采购订单</Text>
          
          {filteredOrders.map(order => (
            <View key={order.id} style={styles.orderItem}>
              <View style={styles.orderHeader}>
                <View>
                  <Text style={styles.orderNumber}>{order.orderNumber}</Text>
                  <Text style={styles.itemName}>{order.itemName}</Text>
                </View>
                <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.supplier}</Text>
                </View>
                <View style={styles.detailRow}>
                  <Text style={styles.detailLabel}>数量:</Text>
                  <Text style={styles.detailValue}>{order.quantity} {order.unit}</Text>
                </View>
                <View style={styles.detailRow}>
                  <Text style={styles.detailLabel}>预计到货:</Text>
                  <Text style={styles.detailValue}>{order.expectedDelivery}</Text>
                </View>
                <View style={styles.detailRow}>
                  <Text style={styles.detailLabel}>当前位置:</Text>
                  <Text style={styles.detailValue}>{order.currentLocation}</Text>
                </View>
              </View>
              
              <View style={styles.orderActions}>
                <TouchableOpacity 
                  style={styles.trackButton}
                  onPress={() => handleTrackShipment(order.id)}
                >
                  <Text style={styles.trackButtonText}>追踪</Text>
                </TouchableOpacity>
                {order.status === '运输中' && (
                  <TouchableOpacity 
                    style={styles.planButton}
                    onPress={() => handleUpdateProductionPlan(order.id)}
                  >
                    <Text style={styles.planButtonText}>调整计划</Text>
                  </TouchableOpacity>
                )}
              </View>
            </View>
          ))}
        </View>

        {/* 预警提醒 */}
        <View style={styles.alertsCard}>
          <Text style={styles.sectionTitle}>预警提醒</Text>
          {orders.filter(o => o.status === '延迟').map(order => (
            <View key={order.id} style={styles.alertItem}>
              <Text style={styles.alertIcon}>⚠️</Text>
              <View style={styles.alertContent}>
                <Text style={styles.alertTitle}>订单延迟</Text>
                <Text style={styles.alertText}>
                  {order.itemName} 预计 {order.expectedDelivery} 到货,当前状态延迟
                </Text>
              </View>
            </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: '#f0f9ff',
  },
  header: {
    flexDirection: 'column',
    padding: 16,
    backgroundColor: '#ffffff',
    borderBottomWidth: 1,
    borderBottomColor: '#bae6fd',
  },
  title: {
    fontSize: 20,
    fontWeight: 'bold',
    color: '#0c4a6e',
    marginBottom: 4,
  },
  subtitle: {
    fontSize: 14,
    color: '#0284c7',
  },
  content: {
    flex: 1,
    marginTop: 12,
  },
  searchCard: {
    backgroundColor: '#ffffff',
    marginHorizontal: 16,
    marginBottom: 12,
    borderRadius: 12,
    padding: 16,
    elevation: 2,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
  },
  searchContainer: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#f0f9ff',
    borderRadius: 8,
    paddingHorizontal: 12,
  },
  searchIcon: {
    fontSize: 16,
    color: '#64748b',
    marginRight: 8,
  },
  searchInput: {
    flex: 1,
    paddingVertical: 12,
    fontSize: 14,
    color: '#0c4a6e',
  },
  statsCard: {
    backgroundColor: '#ffffff',
    marginHorizontal: 16,
    marginBottom: 12,
    borderRadius: 12,
    padding: 16,
    elevation: 2,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
    flexDirection: 'row',
    justifyContent: 'space-around',
  },
  statItem: {
    alignItems: 'center',
  },
  statNumber: {
    fontSize: 18,
    fontWeight: 'bold',
    color: '#0284c7',
  },
  statLabel: {
    fontSize: 12,
    color: '#64748b',
    marginTop: 4,
  },
  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,
  },
  sectionTitle: {
    fontSize: 16,
    fontWeight: '600',
    color: '#0c4a6e',
    marginBottom: 12,
  },
  orderItem: {
    paddingVertical: 12,
    borderBottomWidth: 1,
    borderBottomColor: '#bae6fd',
  },
  orderHeader: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: 8,
  },
  orderNumber: {
    fontSize: 14,
    fontWeight: '600',
    color: '#0c4a6e',
  },
  itemName: {
    fontSize: 12,
    color: '#64748b',
    marginTop: 2,
  },
  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: '#0c4a6e',
    flex: 1,
  },
  orderActions: {
    flexDirection: 'row',
    justifyContent: 'flex-end',
  },
  trackButton: {
    backgroundColor: '#0284c7',
    paddingHorizontal: 12,
    paddingVertical: 6,
    borderRadius: 16,
    marginRight: 8,
  },
  trackButtonText: {
    color: '#ffffff',
    fontSize: 12,
  },
  planButton: {
    backgroundColor: '#f59e0b',
    paddingHorizontal: 12,
    paddingVertical: 6,
    borderRadius: 16,
  },
  planButtonText: {
    color: '#ffffff',
    fontSize: 12,
  },
  alertsCard: {
    backgroundColor: '#ffffff',
    marginHorizontal: 16,
    marginBottom: 12,
    borderRadius: 12,
    padding: 16,
    elevation: 2,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
  },
  alertItem: {
    flexDirection: 'row',
    alignItems: 'center',
    padding: 12,
    backgroundColor: '#fffbeb',
    borderRadius: 8,
    marginBottom: 8,
  },
  alertIcon: {
    fontSize: 16,
    marginRight: 8,
  },
  alertContent: {
    flex: 1,
  },
  alertTitle: {
    fontSize: 14,
    fontWeight: '500',
    color: '#92400e',
    marginBottom: 2,
  },
  alertText: {
    fontSize: 12,
    color: '#92400e',
  },
  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: '#bae6fd',
    paddingVertical: 12,
    position: 'absolute',
    bottom: 0,
    left: 0,
    right: 0,
  },
  navItem: {
    alignItems: 'center',
    flex: 1,
  },
  activeNavItem: {
    paddingTop: 4,
    borderTopWidth: 2,
    borderTopColor: '#0284c7',
  },
  navIcon: {
    fontSize: 20,
    color: '#94a3b8',
    marginBottom: 4,
  },
  activeNavIcon: {
    color: '#0284c7',
  },
  navText: {
    fontSize: 12,
    color: '#94a3b8',
  },
  activeNavText: {
    color: '#0284c7',
    fontWeight: '500',
  },
});

export default ProcurementTrackingApp;


请添加图片描述


打包

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

在这里插入图片描述

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

在这里插入图片描述

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

请添加图片描述
摘要
本文介绍了基于React Native开发的企业采购追踪系统技术方案,重点分析了该系统的三大核心特性:订单可视化、物流实时性和生产联动性。文章详细阐述了采购订单和物流节点的TypeScript领域模型设计,展示了如何通过状态管理实现采购全流程管控,并解析了多维度订单筛选、状态色彩映射以及物流追踪与生产计划联动的关键技术实现。最后提供了完整的鸿蒙ArkTS跨端适配方案,为企业供应链管理应用的开发提供实践参考。该方案充分考虑了企业采购场景的业务特性,包括严谨的数据模型、高效的状态管理和直观的可视化设计。

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

Logo

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

更多推荐