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


在货运物流行业数字化转型过程中,面向司机群体的财务管理类应用需要兼顾多端适配能力与金融场景的安全性、易用性。React Native 凭借其“跨端一致性”与“原生体验”的双重优势,成为连接 iOS、Android 与鸿蒙(HarmonyOS)系统的核心技术选型。本文以货运司机结算与贷款应用为例,从金融场景数据模型设计、鸿蒙风格 UI 实现、跨端业务逻辑兼容等维度,深度解析 React Native 对接鸿蒙系统的技术内核与金融场景落地最佳实践。

一、跨端金融应用

本司机财务管理应用聚焦货运订单结算、贷款申请两大核心金融场景,覆盖“运输中-已完成-已结算”订单状态流转与“待审核-已批准-已拒绝”金融申请状态管理,整体架构遵循 React Native 组件化开发范式,同时深度契合鸿蒙系统的设计语言与金融应用安全规范。从技术底层来看,应用基于 React 函数式组件 + TypeScript 构建,这种组合既保证了金融数据的类型安全,又能最大化跨端复用率,是 React Native 适配鸿蒙系统金融类应用的理想技术选型。

1. 金融场景

金融类应用对数据准确性要求极高,统一且严谨的多层级数据模型是避免多端行为不一致的关键。代码中通过 TypeScript 精准定义了运输订单、结算申请、贷款申请三类核心数据结构,覆盖货运金融全场景的业务属性:

// 运输订单核心模型
type TransportOrder = {
  id: string;
  orderNumber: string;
  cargoType: string;
  pickupLocation: string;
  deliveryLocation: string;
  distance: number;
  freight: number;
  status: '运输中' | '已完成' | '已结算';
  completionDate: string;
};

// 结算申请模型
type SettlementRequest = {
  id: string;
  orderId: string;
  amount: number;
  requestDate: string;
  status: '待审核' | '已批准' | '已拒绝';
};

// 贷款申请模型
type LoanRequest = {
  id: string;
  amount: number;
  purpose: string;
  repaymentPeriod: number; // 月数
  requestDate: string;
  status: '待审核' | '已批准' | '已拒绝';
};

这种多层级强类型定义不仅在开发阶段提供语法校验和智能提示,更关键的是在鸿蒙系统适配时,能够与 ArkTS 的类型系统形成天然映射。相较于纯 JavaScript 开发,TypeScript 能有效规避因数据类型模糊导致的金融计算错误——尤其是在鸿蒙这类面向全场景智慧终端的操作系统中,类型安全可大幅降低多设备适配的调试成本,确保运费金额、贷款额度等核心金融数据在不同终端的一致性。

2. 轻量级状态管理:

应用采用 React 内置的 useState Hook 管理核心金融状态,结合不可变数据模式实现订单、结算、贷款状态的跨端更新:

const [orders] = useState<TransportOrder[]>([...]);
const [settlementRequests, setSettlementRequests] = useState<SettlementRequest[]>([...]);
const [loanRequests, setLoanRequests] = useState<LoanRequest[]>([...]);

// 结算申请状态更新示例
setSettlementRequests([...settlementRequests, newRequest]);

这种轻量级状态管理方案完全适配金融类跨端开发场景,相较于 Redux 等重型状态库,useState 无需额外的中间件和适配层,能够直接在 React Native 支持的所有平台(包括鸿蒙)上稳定运行。从鸿蒙系统的视角来看,useState 的状态更新逻辑与 ArkUI 的 @State 装饰器在设计理念上高度契合,开发者无需切换思维模式即可完成跨端金融状态管理,大幅降低了鸿蒙适配的学习成本。


React Native 的核心价值在于通过统一的组件抽象层,屏蔽不同平台的 UI 实现差异。本应用在 UI 层的设计深度复刻了鸿蒙系统的视觉风格与金融应用交互规范,同时保证多端体验的一致性。

1. Flex 布局

应用基于 React Native 的 Flex 布局系统构建整体界面,通过 Dimensions.get('window') 获取设备宽高,实现对不同尺寸鸿蒙设备(手机、平板、车载终端)的自适应:

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

相较于鸿蒙系统的 DirectionalLayoutStackLayout,React Native 的 Flex 布局具备更强的跨端兼容性,通过 flexDirectionjustifyContentflexWrap 等属性,能够精准还原鸿蒙系统的金融界面布局逻辑。例如财务概览模块的双列统计布局:

<View style={styles.statsRow}>
  <View style={styles.statBox}>
    <Text style={styles.statValue}>¥{/* 待结算金额 */}</Text>
    <Text style={styles.statLabel}>待结算运费</Text>
  </View>
  <View style={styles.statBox}>
    <Text style={styles.statValue}>{/* 待结算订单数 */}</Text>
    <Text style={styles.statLabel}>待结算订单</Text>
  </View>
</View>

这段代码通过 flexDirection: 'row'justifyContent: 'space-around' 实现了鸿蒙系统特有的金融数据可视化布局效果,在不同尺寸的鸿蒙设备上都能保持数据展示的合理性,无需针对鸿蒙系统做额外的布局适配。

2. 视觉样式:

应用通过 StyleSheet.create 定义样式表,深度适配鸿蒙系统的金融设计规范,核心体现在以下几个维度:

  • 金融色彩体系:采用鸿蒙系统的蓝色系主色调(#0284c7#0c4a6e),搭配金融场景功能性色彩区分状态(待审核-橙色、已批准-绿色、已拒绝-红色、运输中-蓝色、已完成-紫色、已结算-绿色),符合鸿蒙系统金融应用“专业、安全”的视觉设计理念
  • 圆角与阴影:使用 borderRadius: 12 实现鸿蒙风格的大圆角设计,通过 elevation(Android)和 shadow(iOS)属性适配鸿蒙系统的阴影效果,兼顾金融界面的层次感与跨端一致性
  • 金融数据样式强化:通过字体加粗、色彩对比强化运费金额、贷款额度等核心金融数据的视觉层级:
<Text style={styles.freightAmount}>¥{order.freight}</Text>
<Text style={styles.loanAmount}>¥{request.amount}</Text>

这种样式设计方案完全基于 React Native 的标准 API 实现,在鸿蒙系统中能够通过 React Native 的渲染层自动转换为原生样式——backgroundColor 对应鸿蒙的 background-colorborderRadius 对应鸿蒙的 border-radius,无需编写平台特定代码。

3. 交互组件

应用中所有交互组件均基于 React Native 基础组件封装,同时适配鸿蒙系统的金融交互规范:

  • SafeAreaView:对应鸿蒙系统的 SafeArea 组件,适配刘海屏、挖孔屏等异形屏,保证金融界面在鸿蒙不同终端设备上的完整性
  • TouchableOpacity:替代鸿蒙的 Button 组件,实现金融操作按钮的点击反馈效果,符合鸿蒙的交互规范,同时支持长按、点击等基础交互
  • Alert/Alert.prompt:对应鸿蒙的 TextDialog/TextInputDialog 组件,实现结算申请、贷款申请等带输入的金融弹窗交互,保持与鸿蒙原生金融应用一致的交互体验
  • ScrollView:与鸿蒙的 List 组件逻辑一致,实现金融订单列表的滚动加载,适配鸿蒙系统的滑动交互逻辑

以贷款申请的多步交互流程为例,代码通过 Alert.prompt 嵌套实现鸿蒙风格的金融表单分步输入:

Alert.prompt(
  '申请贷款',
  '请输入贷款金额(元):',
  [
    { text: '取消', style: 'cancel' },
    {
      text: '下一步',
      onPress: (amount) => {
        if (amount && parseInt(amount) > 0) {
          Alert.prompt(
            '贷款用途',
            '请简要说明贷款用途:',
            [/* 后续步骤 */],
            'plain-text'
          );
        }
      }
    }
  ],
  'plain-text'
);

这种交互逻辑完全基于 React Native 的跨端 API 实现,在鸿蒙系统中能够保持与原生金融应用一致的交互体验,无需针对鸿蒙系统做特殊处理。

除了 UI 层的适配,金融业务逻辑的跨端兼容性是 React Native 开发的核心。本应用的核心业务逻辑包括运费结算申请、多步贷款申请、财务数据统计等,这些逻辑完全基于 JavaScript/TypeScript 实现,天然具备跨端运行能力。

1. 运费结算

应用实现了完整的运费结算申请流程,通过状态校验确保只有已完成的订单才能申请结算:

const handleApplySettlement = (orderId: string) => {
  const order = orders.find(o => o.id === orderId);
  if (order && order.status === '已完成') {
    // 结算申请弹窗与状态更新逻辑
    setSettlementRequests([...settlementRequests, newRequest]);
  }
};

该逻辑完全基于纯函数实现,不依赖任何平台特定 API,在 React Native 支持的所有平台(包括鸿蒙)上都能稳定运行。值得注意的是,代码中使用 Array.find、不可变数组扩展等标准 JavaScript 方法处理金融数据,这些方法在鸿蒙系统的 JS 引擎中能够无缝执行,体现了 React Native 跨端开发“一次编写,多端复用”的核心价值。

2. 多步贷款

应用针对贷款申请场景,实现了鸿蒙风格的多步表单交互逻辑,包含金额、用途、还款期限三层校验:

Alert.prompt(
  '还款期限',
  '请输入还款月数(1-24个月):',
  [
    { text: '取消', style: 'cancel' },
    {
      text: '申请',
      onPress: (months) => {
        if (months && parseInt(months) >= 1 && parseInt(months) <= 24) {
          // 贷款申请提交逻辑
          setLoanRequests([...loanRequests, newRequest]);
        }
      }
    }
  ],
  'plain-text'
);

这种多步校验逻辑基于纯 JavaScript 实现,能够有效防范金融数据输入错误,同时在跨端场景下,避免因不同平台的运行时差异导致的校验逻辑失效。对于鸿蒙系统而言,这类纯逻辑代码无需任何适配即可直接运行,是金融类跨端开发的最优实践。

3. 财务数据

应用实现了基于数组过滤与归约的财务数据统计逻辑,用于展示司机的核心财务指标:

const completedOrders = orders.filter(o => o.status === '已结算').length;
const totalSettled = settlementRequests
  .filter(req => req.status === '已批准')
  .reduce((sum, req) => sum + req.amount, 0);

这种无副作用的纯函数计算方式,不仅符合 React 的设计理念,更重要的是在跨端场景下,能够保证财务数据统计结果的一致性。在鸿蒙系统中,Array.filterArray.reduce 等方法能够被 JS 引擎高效执行,确保财务数据统计的准确性和性能。


从本应用的实现来看,React Native 对接鸿蒙系统金融场景的核心在于“抽象层适配 + 金融安全兼容”,具体体现在以下几个维度:

  1. JS 引擎层金融兼容:鸿蒙系统内置了符合 ECMAScript 标准的 JavaScript 引擎,能够直接执行 React Native 的 JS 代码,这是跨端运行的底层基础。本应用中所有的金融业务逻辑代码(结算申请、贷款申请、财务统计)均运行在 JS 引擎层,无需任何修改即可在鸿蒙系统中执行,保证了金融逻辑的跨端一致性。

  2. 组件映射层金融适配:React Native 通过自定义渲染器,将 React 组件(View、Text、TouchableOpacity 等)映射为鸿蒙系统的原生组件。例如 Alert.prompt 会被转换为鸿蒙的 TextInputDialog 组件,这种映射关系由 React Native 的鸿蒙适配层自动完成,开发者无需关注底层实现细节,只需专注于金融业务逻辑开发。

  3. 样式转换层金融规范适配:React Native 的 StyleSheet 样式会被自动转换为鸿蒙系统的原生样式,本应用中定义的所有鸿蒙金融风格样式(蓝色主调、状态色彩、数据可视化样式)都能通过这一层完成自动转换,保证了金融 UI 风格在鸿蒙系统中的一致性。

  4. 金融数据安全兼容:应用中所有金融数据的处理均采用不可变数据模式,避免因跨端运行时的引用传递导致数据篡改,这种设计既符合 React 的开发理念,也契合鸿蒙系统对金融应用的数据安全要求。

本司机财务管理应用的实现完整展现了 React Native 在鸿蒙跨端金融开发领域的技术优势,核心要点可总结为:

  1. 强类型设计保障金融数据一致性:TypeScript 多层级类型定义不仅提升代码质量,更能与鸿蒙 ArkTS 形成类型映射,降低金融场景跨端适配成本,是物流金融类应用跨端开发的基础保障
  2. 纯逻辑开发最大化金融代码复用率:结算申请、贷款申请、财务统计等核心金融逻辑采用纯 JavaScript/TypeScript 实现,无需针对鸿蒙系统做特殊修改,大幅提升开发效率
  3. 标准 API 适配鸿蒙金融生态:基于 React Native 标准组件和 API 开发,通过底层适配层自动对接鸿蒙原生能力,兼顾开发效率与金融场景的原生体验

本项目采用React Native函数式组件架构,以DriverFinanceApp为核心组件,实现了货运司机结算与贷款的完整功能流程。架构设计遵循模块化原则,将数据结构、状态管理和业务逻辑清晰分离,便于维护和扩展。

核心技术栈

  • React Native:跨平台移动应用开发框架,支持iOS、Android和鸿蒙系统
  • TypeScript:提供类型安全,增强代码可维护性和开发体验
  • Hooks API:使用useState进行状态管理,简化组件逻辑
  • Flexbox:实现响应式布局,适配不同屏幕尺寸
  • Base64图标:内置图标资源,减少网络请求,提升加载速度
  • Dimensions API:获取屏幕尺寸,实现精细化布局控制

运输订单类型(TransportOrder)

type TransportOrder = {
  id: string;
  orderNumber: string;
  cargoType: string;
  pickupLocation: string;
  deliveryLocation: string;
  distance: number;
  freight: number;
  status: '运输中' | '已完成' | '已结算';
  completionDate: string;
};

该类型设计全面,包含了运输订单的核心信息:

  • id:唯一标识符,确保数据唯一性
  • orderNumber:订单编号,便于订单追踪
  • cargoType:货物类型,影响运输费用计算
  • pickupLocationdeliveryLocation:起止地点,影响运输距离
  • distance:运输距离,直接影响运费
  • freight:运费金额,核心财务指标
  • status:订单状态,使用联合类型确保类型安全
  • completionDate:完成日期,用于结算管理

结算申请类型(SettlementRequest)

type SettlementRequest = {
  id: string;
  orderId: string;
  amount: number;
  requestDate: string;
  status: '待审核' | '已批准' | '已拒绝';
};

结算申请类型设计合理,包含了结算流程的关键信息:

  • id:申请唯一标识
  • orderId:关联订单ID,建立数据关联
  • amount:结算金额,核心财务信息
  • requestDate:申请日期,用于流程管理
  • status:申请状态,使用联合类型确保类型安全

贷款申请类型(LoanRequest)

type LoanRequest = {
  id: string;
  amount: number;
  purpose: string;
  repaymentPeriod: number;
  requestDate: string;
  status: '待审核' | '已批准' | '已拒绝';
};

贷款申请类型设计全面,包含了贷款流程的必要信息:

  • id:申请唯一标识
  • amount:贷款金额,核心财务信息
  • purpose:贷款用途,用于风险评估
  • repaymentPeriod:还款期限,影响还款计划
  • requestDate:申请日期,用于流程管理
  • status:申请状态,使用联合类型确保类型安全

核心状态

应用使用useState钩子管理三个核心状态:

  • orders:运输订单列表,使用常量状态
  • settlementRequests:结算申请列表,支持动态更新
  • loanRequests:贷款申请列表,支持动态更新

状态更新

  1. 结算申请:通过handleApplySettlement函数,生成新结算申请并添加到列表
  2. 贷款申请:通过handleApplyLoan函数,收集贷款信息并生成新申请
  3. 状态管理:使用不可变数据模式,通过扩展运算符创建新状态
  4. 用户交互:通过Alert组件提供操作确认和信息提示

状态管理

  • 不可变数据模式:使用扩展运算符(...)创建新状态,避免直接修改原状态
  • 批量更新:在状态更新时使用map方法批量处理,确保数据一致性
  • 状态验证:在进行操作前,验证订单状态和用户输入
  • 用户反馈:操作完成后,通过Alert组件提供明确的成功提示

核心业务

  1. 订单管理:展示运输订单列表,包含完整的订单信息
  2. 结算申请:根据已完成订单申请运费结算
  3. 贷款申请:提交贷款申请,包含金额、用途和还款期限
  4. 状态跟踪:实时更新申请状态,确保业务流程透明
  5. 财务信息管理:集中管理运费和贷款等财务信息
const handleApplySettlement = (orderId: string) => {
  const order = orders.find(o => o.id === orderId);
  if (order && order.status === '已完成') {
    Alert.alert(
      '申请结算',
      `订单号: ${order.orderNumber}\n` +
      `运费金额: ¥${order.freight}\n` +
      `完成日期: ${order.completionDate}\n\n` +
      `确定申请结算这笔运费吗?`,
      [
        { text: '取消', style: 'cancel' },
        {
          text: '申请结算',
          onPress: () => {
            const newRequest: SettlementRequest = {
              id: (settlementRequests.length + 1).toString(),
              orderId: orderId,
              amount: order.freight,
              requestDate: new Date().toLocaleDateString('zh-CN'),
              status: '待审核'
            };
            setSettlementRequests([...settlementRequests, newRequest]);
            Alert.alert('成功', '结算申请已提交,请等待审核');
          }
        }
      ]
    );
  }
};

数据流

  • 单向数据流:状态 → 视图 → 用户操作 → 状态更新
  • 数据验证:在申请结算前验证订单状态,确保只有已完成订单可申请
  • 业务逻辑封装:将复杂操作逻辑封装在专用函数中,提高代码可读性
  • 用户交互反馈:使用Alert组件提供操作确认和信息提示,提升用户体验

组件

  • 核心组件:SafeAreaView、View、Text、ScrollView、TouchableOpacity等在鸿蒙系统上有对应实现
  • API兼容性:Dimensions API在鸿蒙系统中可正常使用,确保布局适配
  • Alert组件:鸿蒙系统支持Alert组件的基本功能,但样式可能有所差异
  • Alert.prompt:需要注意鸿蒙系统对Alert.prompt的支持情况,可能需要自定义实现

资源

  • Base64图标:在鸿蒙系统中同样支持,可减少网络请求,提升性能
  • 内存管理:鸿蒙系统对内存使用更为严格,需注意资源释放
  • 计算性能:对于财务计算等操作,鸿蒙系统的处理性能与其他平台相当

性能

  • 渲染性能:避免不必要的重渲染,合理使用React.memo;对于长订单列表,建议使用FlatList替代ScrollView;优化组件结构,减少嵌套层级

  • 数据处理:缓存计算结果,避免重复计算;优化订单和申请的查找算法;考虑使用useMemo缓存计算结果,提高性能

  • 内存管理:及时释放不再使用的资源;避免内存泄漏,特别是在处理多个订单和申请时;合理使用缓存策略,平衡性能和内存占用

  • 条件渲染:使用Platform API检测平台,针对不同平台使用不同实现

  • 样式适配:考虑鸿蒙系统的设计规范,调整UI样式以符合平台特性

  • 权限处理:鸿蒙系统的权限管理与Android有所不同,需单独处理

  • 鸿蒙特性:充分利用鸿蒙系统的分布式能力,实现多设备协同

  • 财务安全:针对鸿蒙系统的安全机制,调整财务数据的存储和传输方式


类型定义

  • 使用枚举类型:将订单状态、申请状态等使用枚举类型替代字符串,提高代码可读性和可维护性
  • 类型扩展:考虑使用接口继承,增强类型系统的表达能力
  • 类型守卫:添加更多类型守卫,确保运行时类型安全
  • 国际化支持:考虑添加国际化支持,特别是财务术语和申请状态等

组件化

  • 组件拆分:将大型组件拆分为更小的可复用组件,如OrderCard、SettlementRequestItem、LoanRequestForm等
  • 自定义Hook:提取重复的状态逻辑到自定义Hook,如useFinanceManager、useLoanApplier等
  • 高阶组件:使用高阶组件处理横切关注点,如错误边界、加载状态等
  • 表单组件:封装贷款申请表单组件,提高代码复用性

业务逻辑

  • 服务层分离:将业务逻辑分离到服务层,提高代码可测试性
  • 错误处理:增强错误处理机制,提供更友好的错误提示
  • 实时更新:考虑添加实时申请状态更新,提升用户体验
  • 财务计算:实现更复杂的财务计算逻辑,如贷款利息计算等

本项目展示了如何使用React Native和TypeScript构建一个功能完整的货运司机结算与贷款应用。通过合理的架构设计、类型定义和状态管理,实现了跨平台的一致性体验。


真实演示案例代码:





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

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

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

// 运输订单类型
type TransportOrder = {
  id: string;
  orderNumber: string;
  cargoType: string;
  pickupLocation: string;
  deliveryLocation: string;
  distance: number;
  freight: number;
  status: '运输中' | '已完成' | '已结算';
  completionDate: string;
};

// 结算申请类型
type SettlementRequest = {
  id: string;
  orderId: string;
  amount: number;
  requestDate: string;
  status: '待审核' | '已批准' | '已拒绝';
};

// 贷款申请类型
type LoanRequest = {
  id: string;
  amount: number;
  purpose: string;
  repaymentPeriod: number; // 月数
  requestDate: string;
  status: '待审核' | '已批准' | '已拒绝';
};

// 货运司机结算与贷款应用组件
const DriverFinanceApp: React.FC = () => {
  const [orders] = useState<TransportOrder[]>([
    {
      id: '1',
      orderNumber: 'YS20231201001',
      cargoType: '电子产品',
      pickupLocation: '深圳',
      deliveryLocation: '上海',
      distance: 1200,
      freight: 2400,
      status: '已完成',
      completionDate: '2023-12-01'
    },
    {
      id: '2',
      orderNumber: 'YS20231201002',
      cargoType: '机械设备',
      pickupLocation: '广州',
      deliveryLocation: '北京',
      distance: 2100,
      freight: 4200,
      status: '已完成',
      completionDate: '2023-12-02'
    },
    {
      id: '3',
      orderNumber: 'YS20231201003',
      cargoType: '服装',
      pickupLocation: '杭州',
      deliveryLocation: '成都',
      distance: 1800,
      freight: 3600,
      status: '运输中',
      completionDate: ''
    }
  ]);

  const [settlementRequests, setSettlementRequests] = useState<SettlementRequest[]>([
    {
      id: '1',
      orderId: '1',
      amount: 2400,
      requestDate: '2023-12-02',
      status: '待审核'
    }
  ]);

  const [loanRequests, setLoanRequests] = useState<LoanRequest[]>([
    {
      id: '1',
      amount: 10000,
      purpose: '车辆维修',
      repaymentPeriod: 6,
      requestDate: '2023-12-01',
      status: '待审核'
    }
  ]);

  const getStatusColor = (status: string) => {
    switch (status) {
      case '待审核': return '#f59e0b';
      case '已批准': return '#10b981';
      case '已拒绝': return '#ef4444';
      case '运输中': return '#3b82f6';
      case '已完成': return '#8b5cf6';
      case '已结算': return '#10b981';
      default: return '#6b7280';
    }
  };

  const handleApplySettlement = (orderId: string) => {
    const order = orders.find(o => o.id === orderId);
    if (order && order.status === '已完成') {
      Alert.alert(
        '申请结算',
        `订单号: ${order.orderNumber}\n` +
        `运费金额: ¥${order.freight}\n` +
        `完成日期: ${order.completionDate}\n\n` +
        `确定申请结算这笔运费吗?`,
        [
          { text: '取消', style: 'cancel' },
          {
            text: '申请结算',
            onPress: () => {
              const newRequest: SettlementRequest = {
                id: (settlementRequests.length + 1).toString(),
                orderId: orderId,
                amount: order.freight,
                requestDate: new Date().toLocaleDateString('zh-CN'),
                status: '待审核'
              };
              setSettlementRequests([...settlementRequests, newRequest]);
              Alert.alert('成功', '结算申请已提交,请等待审核');
            }
          }
        ]
      );
    }
  };

  const handleApplyLoan = () => {
    Alert.prompt(
      '申请贷款',
      '请输入贷款金额(元):',
      [
        { text: '取消', style: 'cancel' },
        {
          text: '下一步',
          onPress: (amount) => {
            if (amount && parseInt(amount) > 0) {
              Alert.prompt(
                '贷款用途',
                '请简要说明贷款用途:',
                [
                  { text: '取消', style: 'cancel' },
                  {
                    text: '下一步',
                    onPress: (purpose) => {
                      if (purpose) {
                        Alert.prompt(
                          '还款期限',
                          '请输入还款月数(1-24个月):',
                          [
                            { text: '取消', style: 'cancel' },
                            {
                              text: '申请',
                              onPress: (months) => {
                                if (months && parseInt(months) >= 1 && parseInt(months) <= 24) {
                                  const newRequest: LoanRequest = {
                                    id: (loanRequests.length + 1).toString(),
                                    amount: parseInt(amount),
                                    purpose: purpose,
                                    repaymentPeriod: parseInt(months),
                                    requestDate: new Date().toLocaleDateString('zh-CN'),
                                    status: '待审核'
                                  };
                                  setLoanRequests([...loanRequests, newRequest]);
                                  Alert.alert('成功', '贷款申请已提交,请等待审核');
                                }
                              }
                            }
                          ],
                          'plain-text'
                        );
                      }
                    }
                  }
                ],
                'plain-text'
              );
            }
          }
        }
      ],
      'plain-text'
    );
  };

  const handleViewHistory = () => {
    const completedOrders = orders.filter(o => o.status === '已结算').length;
    const totalSettled = settlementRequests
      .filter(req => req.status === '已批准')
      .reduce((sum, req) => sum + req.amount, 0);
    
    Alert.alert(
      '财务历史',
      `已完成订单: ${completedOrders} 笔\n` +
      `已结算金额: ¥${totalSettled}\n` +
      `贷款申请: ${loanRequests.length} 笔\n` +
      `待审核申请: ${
        settlementRequests.filter(r => r.status === '待审核').length +
        loanRequests.filter(r => r.status === '待审核').length
      }`,
      [{ text: '确定', style: 'cancel' }]
    );
  };

  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.overviewCard}>
          <Text style={styles.sectionTitle}>财务概览</Text>
          
          <View style={styles.statsRow}>
            <View style={styles.statBox}>
              <Text style={styles.statValue}>
                ¥{orders
                  .filter(o => o.status === '已完成')
                  .reduce((sum, o) => sum + o.freight, 0)
                }
              </Text>
              <Text style={styles.statLabel}>待结算运费</Text>
            </View>
            
            <View style={styles.statBox}>
              <Text style={styles.statValue}>
                {orders.filter(o => o.status === '已完成').length}
              </Text>
              <Text style={styles.statLabel}>待结算订单</Text>
            </View>
          </View>
          
          <View style={styles.quickActions}>
            <TouchableOpacity 
              style={styles.historyButton}
              onPress={handleViewHistory}
            >
              <Text style={styles.historyButtonText}>查看历史</Text>
            </TouchableOpacity>
          </View>
        </View>

        {/* 运输订单 */}
        <View style={styles.ordersCard}>
          <Text style={styles.sectionTitle}>运输订单</Text>
          
          {orders.map(order => (
            <View key={order.id} style={styles.orderItem}>
              <View style={styles.orderHeader}>
                <Text style={styles.orderNumber}>{order.orderNumber}</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.cargoType}</Text>
                </View>
                <View style={styles.detailRow}>
                  <Text style={styles.detailLabel}>路线:</Text>
                  <Text style={styles.detailValue}>{order.pickupLocation}{order.deliveryLocation}</Text>
                </View>
                <View style={styles.detailRow}>
                  <Text style={styles.detailLabel}>距离:</Text>
                  <Text style={styles.detailValue}>{order.distance} km</Text>
                </View>
                <View style={styles.detailRow}>
                  <Text style={styles.detailLabel}>运费:</Text>
                  <Text style={styles.freightAmount}>¥{order.freight}</Text>
                </View>
              </View>
              
              {order.status === '已完成' && (
                <TouchableOpacity 
                  style={styles.settleButton}
                  onPress={() => handleApplySettlement(order.id)}
                >
                  <Text style={styles.settleButtonText}>申请结算</Text>
                </TouchableOpacity>
              )}
            </View>
          ))}
        </View>

        {/* 结算申请 */}
        <View style={styles.requestsCard}>
          <Text style={styles.sectionTitle}>结算申请</Text>
          
          {settlementRequests.map(request => {
            const order = orders.find(o => o.id === request.orderId);
            return (
              <View key={request.id} style={styles.requestItem}>
                <View style={styles.requestHeader}>
                  <Text style={styles.requestOrder}>{order?.orderNumber}</Text>
                  <View style={[
                    styles.statusBadge,
                    { backgroundColor: getStatusColor(request.status) }
                  ]}>
                    <Text style={styles.statusText}>{request.status}</Text>
                  </View>
                </View>
                
                <View style={styles.requestDetails}>
                  <Text style={styles.requestAmount}>¥{request.amount}</Text>
                  <Text style={styles.requestDate}>申请日期: {request.requestDate}</Text>
                </View>
              </View>
            );
          })}
        </View>

        {/* 贷款申请 */}
        <View style={styles.loansCard}>
          <Text style={styles.sectionTitle}>贷款服务</Text>
          
          <View style={styles.loanInfo}>
            <Text style={styles.loanText}>• 快速审批,当天放款</Text>
            <Text style={styles.loanText}>• 灵活期限,1-24个月</Text>
            <Text style={styles.loanText}>• 低息贷款,缓解资金压力</Text>
          </View>
          
          <TouchableOpacity 
            style={styles.loanButton}
            onPress={handleApplyLoan}
          >
            <Text style={styles.loanButtonText}>申请贷款</Text>
          </TouchableOpacity>
          
          {loanRequests.length > 0 && (
            <View style={styles.loanHistory}>
              <Text style={styles.historyTitle}>贷款申请记录</Text>
              {loanRequests.map(request => (
                <View key={request.id} style={styles.loanRequest}>
                  <Text style={styles.loanAmount}>¥{request.amount}</Text>
                  <View style={styles.loanStatus}>
                    <Text style={styles.loanPurpose}>{request.purpose}</Text>
                    <View style={[
                      styles.statusBadge,
                      { backgroundColor: getStatusColor(request.status) }
                    ]}>
                      <Text style={styles.statusText}>{request.status}</Text>
                    </View>
                  </View>
                </View>
              ))}
            </View>
          )}
        </View>

        {/* 使用说明 */}
        <View style={styles.infoCard}>
          <Text style={styles.sectionTitle}>使用说明</Text>
          <Text style={styles.infoText}>• 完成运输后可申请运费结算</Text>
          <Text style={styles.infoText}>• 结算申请T+1个工作日内处理</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,
  },
  overviewCard: {
    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,
  },
  statsRow: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    marginBottom: 12,
  },
  statBox: {
    alignItems: 'center',
  },
  statValue: {
    fontSize: 18,
    fontWeight: 'bold',
    color: '#0284c7',
  },
  statLabel: {
    fontSize: 12,
    color: '#64748b',
    marginTop: 4,
  },
  quickActions: {
    alignItems: 'center',
  },
  historyButton: {
    backgroundColor: '#0ea5e9',
    paddingHorizontal: 20,
    paddingVertical: 8,
    borderRadius: 20,
  },
  historyButtonText: {
    color: '#ffffff',
    fontSize: 14,
  },
  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: '#bae6fd',
  },
  orderHeader: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: 8,
  },
  orderNumber: {
    fontSize: 16,
    fontWeight: '600',
    color: '#0c4a6e',
  },
  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: 50,
  },
  detailValue: {
    fontSize: 12,
    color: '#0c4a6e',
    flex: 1,
  },
  freightAmount: {
    fontSize: 14,
    fontWeight: 'bold',
    color: '#0284c7',
  },
  settleButton: {
    backgroundColor: '#10b981',
    paddingVertical: 8,
    borderRadius: 16,
    alignItems: 'center',
  },
  settleButtonText: {
    color: '#ffffff',
    fontSize: 14,
  },
  requestsCard: {
    backgroundColor: '#ffffff',
    marginHorizontal: 16,
    marginBottom: 12,
    borderRadius: 12,
    padding: 16,
    elevation: 2,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
  },
  requestItem: {
    padding: 12,
    borderBottomWidth: 1,
    borderBottomColor: '#bae6fd',
  },
  requestHeader: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: 8,
  },
  requestOrder: {
    fontSize: 14,
    fontWeight: '500',
    color: '#0c4a6e',
  },
  requestDetails: {
    // 请求详情样式
  },
  requestAmount: {
    fontSize: 16,
    fontWeight: 'bold',
    color: '#0284c7',
    marginBottom: 4,
  },
  requestDate: {
    fontSize: 12,
    color: '#64748b',
  },
  loansCard: {
    backgroundColor: '#ffffff',
    marginHorizontal: 16,
    marginBottom: 12,
    borderRadius: 12,
    padding: 16,
    elevation: 2,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
  },
  loanInfo: {
    marginBottom: 12,
  },
  loanText: {
    fontSize: 14,
    color: '#64748b',
    lineHeight: 20,
    marginBottom: 4,
  },
  loanButton: {
    backgroundColor: '#f97316',
    paddingVertical: 14,
    borderRadius: 8,
    alignItems: 'center',
    marginBottom: 12,
  },
  loanButtonText: {
    color: '#ffffff',
    fontSize: 16,
    fontWeight: '600',
  },
  loanHistory: {
    // 贷款历史样式
  },
  historyTitle: {
    fontSize: 14,
    fontWeight: '500',
    color: '#0c4a6e',
    marginBottom: 8,
  },
  loanRequest: {
    padding: 12,
    backgroundColor: '#f0f9ff',
    borderRadius: 8,
    marginBottom: 8,
  },
  loanAmount: {
    fontSize: 16,
    fontWeight: 'bold',
    color: '#f97316',
    marginBottom: 4,
  },
  loanStatus: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
  },
  loanPurpose: {
    fontSize: 12,
    color: '#64748b',
    flex: 1,
  },
  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 DriverFinanceApp;


请添加图片描述


打包

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

在这里插入图片描述

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

在这里插入图片描述

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

请添加图片描述
本文以货运司机财务管理应用为例,探讨React Native在跨平台开发中的实践应用。通过TypeScript定义运输订单、结算申请等金融数据结构,结合React函数式组件和轻量级状态管理,实现iOS、Android与鸿蒙系统的多端适配。应用采用Flex布局和鸿蒙视觉风格设计,确保金融界面的跨端一致性。核心业务逻辑如运费结算、贷款申请等完全基于JavaScript实现,天然具备跨平台能力。该方案兼顾金融应用的安全性与易用性,为鸿蒙生态的跨平台开发提供了可行路径。

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

Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐