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


整体架构

本项目采用React Native函数式组件架构,以RegulatoryInspectionApp为核心组件,实现了危化品运输车辆的监管功能。架构设计遵循模块化原则,将数据结构、状态管理和业务逻辑清晰分离,便于维护和扩展。

核心技术栈

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

危险品运输车辆类型(HazardousVehicle)

type HazardousVehicle = {
  id: string;
  licensePlate: string;
  vehicleType: string;
  driverName: string;
  driverLicense: string;
  route: string;
  status: '正常' | '异常' | '待检查';
  certificates: {
    transportLicense: string;
    safetyCertificate: string;
    insurance: string;
  };
  lastCheckTime: string;
  nextCheckTime: string;
};

该类型设计全面,包含了危险品运输车辆的核心信息:

  • id:唯一标识符,确保数据唯一性
  • licensePlate:车牌号,便于车辆识别
  • vehicleType:车型信息,确保运输工具符合要求
  • driverName:驾驶员姓名,便于责任追溯
  • driverLicense:驾驶证号,确保驾驶员资质
  • route:运输路线,便于监控
  • status:车辆状态,使用联合类型确保类型安全
  • certificates:证件信息,包含运输许可证、安全证书和保险单
  • lastCheckTimenextCheckTime:检查时间,确保定期安全检查

核心状态设计

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

  • vehicles:危险品运输车辆列表,使用常量状态
  • selectedVehicle:选中的车辆ID,用于显示车辆详情

状态更新机制

  1. 车辆选择:通过handleViewVehicle函数,更新selectedVehicle状态
  2. 详情关闭:通过handleCloseDetail函数,清空selectedVehicle状态
  3. 证件核查:通过handleVerifyCertificates函数,验证车辆证件并提供反馈
  4. 路线跟踪:通过handleTrackRoute函数,显示车辆实时路线信息

状态管理优化

  • 不可变数据模式:使用find方法查找车辆,避免直接修改原状态
  • 状态清理:在不需要时及时清空selectedVehicle状态,保持界面整洁
  • 用户交互反馈:使用Alert组件提供操作确认和信息提示,提升用户体验

核心业务流程

  1. 车辆监控:展示危险品运输车辆列表,包含车牌号、状态、驾驶员等信息
  2. 证件核查:验证车辆的运输许可证、安全证书和保险单
  3. 路线跟踪:监控车辆的实时路线和行驶状态
  4. 状态管理:标记车辆状态,确保安全监管
  5. 检查时间管理:跟踪车辆的检查时间,确保定期安全检查

核心业务

const handleVerifyCertificates = (vehicleId: string) => {
  const vehicle = vehicles.find(v => v.id === vehicleId);
  if (vehicle) {
    Alert.alert(
      '证件核查',
      `车牌号: ${vehicle.licensePlate}\n` +
      `运输许可证: ${vehicle.certificates.transportLicense}\n` +
      `安全证书: ${vehicle.certificates.safetyCertificate}\n` +
      `保险单号: ${vehicle.certificates.insurance}\n\n` +
      `上次检查: ${vehicle.lastCheckTime}\n` +
      `下次检查: ${vehicle.nextCheckTime}`,
      [
        {
          text: '标记异常',
          onPress: () => Alert.alert('提示', '已标记为异常状态'),
          style: 'destructive'
        },
        {
          text: '核查通过',
          onPress: () => Alert.alert('成功', '证件核查通过')
        }
      ]
    );
  }
};

数据流设计

  • 单向数据流:状态 → 视图 → 用户操作 → 状态更新
  • 数据验证:在处理车辆相关操作前,确保车辆存在
  • 业务逻辑封装:将复杂业务逻辑封装在专用函数中,提高代码可读性
  • 用户交互反馈:使用Alert组件提供操作确认和信息提示,提升用户体验

组件

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

资源

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

    • 避免不必要的重渲染,合理使用React.memo
    • 对于长车辆列表,建议使用FlatList替代ScrollView
    • 优化组件结构,减少嵌套层级
  2. 数据处理

    • 缓存计算结果,避免重复计算
    • 优化数据过滤和查找算法,特别是车辆查找逻辑
    • 考虑使用useMemo缓存计算结果,提高性能
  3. 内存管理

    • 及时释放不再使用的资源
    • 避免内存泄漏,特别是在处理多个车辆时
    • 合理使用缓存策略,平衡性能和内存占用
  • 条件渲染:使用Platform API检测平台,针对不同平台使用不同实现
  • 样式适配:考虑鸿蒙系统的设计规范,调整UI样式以符合平台特性
  • 权限处理:鸿蒙系统的权限管理与Android有所不同,需单独处理
  • 鸿蒙特性:充分利用鸿蒙系统的分布式能力,实现多设备协同
  • 安全适配:针对鸿蒙系统的安全机制,调整数据存储和传输方式

1. 类型定义

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

2. 状态管理

  • 状态分离:对于复杂状态,考虑使用useReducer或状态管理库(如Redux、Zustand)
  • 状态持久化:实现状态持久化,使用AsyncStorage存储车辆数据
  • 计算属性:使用useMemo缓存计算结果,避免重复计算
  • 批量操作:支持批量核查和管理车辆,提高监管效率

3. 组件化

  • 组件拆分:将大型组件拆分为更小的可复用组件,如VehicleCard、CertificateVerifier、RouteTracker等
  • 自定义Hook:提取重复的状态逻辑到自定义Hook,如useVehicleManager、useCertificateVerifier等
  • 高阶组件:使用高阶组件处理横切关注点,如错误边界、加载状态等
  • 表单组件:封装证件核查表单组件,提高代码复用性

4. 业务逻辑

  • 服务层分离:将业务逻辑分离到服务层,提高代码可测试性
  • 错误处理:增强错误处理机制,提供更友好的错误提示
  • 验证逻辑:添加更严格的证件验证逻辑,确保符合法规要求
  • 实时监控:实现更实时的车辆监控,考虑集成GPS定位API

5. 性能

  • 列表优化:使用FlatList的性能优化特性,如getItemLayout、initialNumToRender等
  • 网络优化:实现请求防抖和节流,减少网络请求频率
  • Bundle优化:使用代码分割和Tree Shaking,减少应用体积
  • 启动优化:优化应用启动速度,减少初始加载时间

1. 代码

  • 模块化设计:采用模块化设计,分离平台特定代码
  • 配置管理:使用配置文件管理不同平台的差异
  • 目录结构:合理组织目录结构,便于维护和扩展
  • 安全分区:对于车辆证件等敏感数据,采用安全分区存储

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

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

  1. 使用React Native 0.70+版本:利用新的架构特性,如Fabric渲染器和Turbo Modules,提升应用性能
  2. 探索鸿蒙原生能力:充分利用鸿蒙系统的分布式能力,实现多设备协同和更丰富的功能
  3. 引入现代化状态管理:使用Redux Toolkit或Zustand等现代状态管理库,简化状态管理
  4. 实现PWA支持:扩展应用的使用场景,支持Web平台
  5. 集成AI能力:引入AI技术,如智能车辆识别、路线优化等,提升应用智能化水平
  6. 区块链集成:考虑使用区块链技术,确保证件信息的真实性和不可篡改性
  7. 实时监控系统:集成实时监控系统,实现对危化品运输车辆的24小时监控

通过持续的技术迭代和优化,可以构建更加稳定、高效、安全的危化品监管应用,为行业安全发展做出贡献。


危化品运输监管作为安全生产的核心环节,其数字化系统需兼顾监管合规性、数据准确性、操作便捷性三大核心诉求。本文将深度拆解基于 React Native 开发的危化品运输监管核查应用,剖析其车辆信息建模、证件核查、路线监控的核心技术实现,并提供完整的鸿蒙(HarmonyOS)ArkTS 跨端适配方案,为危化品监管类应用的跨端开发提供可落地的技术参考。

1. 危化品监管场景

危化品运输监管系统区别于普通物流监管的核心在于车辆资质的合规性校验、运输状态的实时监控、检查周期的严格管理。代码通过 TypeScript 类型系统构建了精准贴合危化品监管场景的领域模型,充分体现了危化品运输监管的行业特性:

// 危险品运输车辆类型
type HazardousVehicle = {
  id: string;
  licensePlate: string;
  vehicleType: string;
  driverName: string;
  driverLicense: string;
  route: string;
  status: '正常' | '异常' | '待检查';
  certificates: {
    transportLicense: string;
    safetyCertificate: string;
    insurance: string;
  };
  lastCheckTime: string;
  nextCheckTime: string;
};

模型设计的监管场景适配性分析

  • 车辆标识唯一性:通过idlicensePlate双字段保证车辆识别的唯一性,符合危化品运输车辆的监管要求;
  • 车型专业化分类vehicleType字段区分罐式货车、厢式危险品车等专业车型,匹配不同危化品运输工具的监管标准;
  • 人员资质合规化:包含驾驶员姓名和驾驶证编号,符合危化品运输的人员资质监管要求;
  • 运输路线透明化route字段记录完整运输路线,支持监管部门的路线合规性核查;
  • 状态管控精细化:采用"正常/异常/待检查"三态管理,贴合危化品运输的动态监管流程;
  • 证件信息结构化:嵌套式certificates对象整合运输许可证、安全证书、保险单等核心合规证件,符合危化品运输的证件监管规范;
  • 检查周期规范化lastCheckTimenextCheckTime字段记录检查时间节点,满足危化品运输定期检查的监管要求;
  • 类型安全保障:状态字段采用字面量类型约束,避免非法状态值输入,保证监管数据的严谨性;
  • 数据维度完整性:覆盖车辆、人员、证件、路线、状态、检查周期六大核心维度,满足危化品运输监管的全维度数据需求。

2. 危化品监管

危化品运输监管的核心痛点是证件合规性校验、车辆状态监控、检查周期管理,代码通过轻量化但专业的逻辑实现了危化品运输监管的核心业务流程:

(1)证件核查

危化品运输监管的核心环节是证件合规性核查,必须确保运输车辆具备完整有效的资质证件:

const handleVerifyCertificates = (vehicleId: string) => {
  const vehicle = vehicles.find(v => v.id === vehicleId);
  if (vehicle) {
    Alert.alert(
      '证件核查',
      `车牌号: ${vehicle.licensePlate}\n` +
      `运输许可证: ${vehicle.certificates.transportLicense}\n` +
      `安全证书: ${vehicle.certificates.safetyCertificate}\n` +
      `保险单号: ${vehicle.certificates.insurance}\n\n` +
      `上次检查: ${vehicle.lastCheckTime}\n` +
      `下次检查: ${vehicle.nextCheckTime}`,
      [
        {
          text: '标记异常',
          onPress: () => Alert.alert('提示', '已标记为异常状态'),
          style: 'destructive'
        },
        {
          text: '核查通过',
          onPress: () => Alert.alert('成功', '证件核查通过')
        }
      ]
    );
  }
};

证件核查逻辑的监管适配性

  • 数据关联完整性:通过车辆ID精准匹配对应的证件信息,保证核查的准确性;
  • 证件信息全面展示:完整展示运输许可证、安全证书、保险单等核心证件编号,符合监管核查的信息要求;
  • 检查周期同步展示:同步展示上次/下次检查时间,便于监管人员评估检查周期合规性;
  • 操作结果明确化:提供"标记异常"和"核查通过"两种操作选项,符合监管核查的业务流程;
  • 异常操作警示化:将"标记异常"设置为破坏性操作样式,强化监管操作的谨慎性;
  • 操作反馈及时化:提供明确的操作结果提示,保证监管操作的可追溯性;
  • 异常防护机制:先校验车辆信息是否存在,避免空指针异常,保证系统稳定性;
  • 信息展示结构化:按"基础信息-证件信息-检查信息"的逻辑展示,符合监管核查的思维习惯。
(2)路线监控

危化品运输的关键监管环节是路线监控,必须确保运输车辆按规定路线行驶:

const handleTrackRoute = (vehicleId: string) => {
  const vehicle = vehicles.find(v => v.id === vehicleId);
  if (vehicle) {
    Alert.alert(
      '实时路线',
      `车牌号: ${vehicle.licensePlate}\n` +
      `当前路线: ${vehicle.route}\n` +
      `驾驶员: ${vehicle.driverName}\n\n` +
      `GPS定位: 北纬39.9° 东经116.4°\n` +
      `行驶状态: 正常行驶\n` +
      `预计到达: 2023-12-15 16:30`,
      [{ text: '确定', style: 'cancel' }]
    );
  }
};

路线监控逻辑的监管适配性

  • 基础信息精准展示:展示车牌号、路线、驾驶员等核心信息,保证监管追踪的准确性;
  • 位置信息标准化:采用经纬度格式展示GPS定位,符合危化品运输的定位监管规范;
  • 状态信息实时化:展示行驶状态和预计到达时间,满足动态监管的需求;
  • 信息维度完整性:覆盖身份、路线、位置、状态、时间五大维度,符合路线监管的全维度要求;
  • 操作交互简洁化:仅提供确认按钮,符合监管查看类操作的交互习惯;
  • 数据容错处理:先校验车辆信息是否存在,避免无效操作;
  • 格式规范化:信息展示格式统一,提升监管人员的信息读取效率。
(3)车辆详情展示

危化品监管需要支持车辆详情的快速查看和状态切换,满足精细化监管需求:

const handleViewVehicle = (vehicleId: string) => {
  const vehicle = vehicles.find(v => v.id === vehicleId);
  if (vehicle) {
    setSelectedVehicle(vehicleId);
  }
};

const handleCloseDetail = () => {
  setSelectedVehicle('');
};

详情展示逻辑的监管适配性

  • 状态驱动展示:通过selectedVehicle状态控制详情面板的显示/隐藏,符合React的状态管理理念;
  • 数据精准匹配:通过车辆ID精准获取并展示对应车辆的完整信息;
  • 操作闭环化:提供关闭详情的操作入口,保证界面操作的完整性;
  • 性能优化考量:仅存储选中车辆ID而非完整对象,减少状态存储开销;
  • 异常防护机制:先校验车辆信息是否存在,避免展示空数据。

3. 监管场景

危化品运输监管系统的视觉设计围绕安全性、合规性、易用性三个核心维度展开,贴合监管人员的操作习惯和业务特性:

  • 安全化色调体系:采用红色系(#dc2626/#991b1b)为主色调,契合危化品监管的安全警示属性,区别于普通物流系统的视觉风格;
  • 状态视觉差异化:不同车辆状态对应不同色系(正常-绿色、异常-红色、待检查-黄色),符合危化品监管的视觉识别习惯,便于快速识别风险车辆;
  • 车辆信息卡片化:采用卡片式布局展示车辆的核心监管信息,符合监管系统的信息展示规范;
  • 证件信息层级化:在详情页中通过边框分隔证件信息区域,突出核心监管证件;
  • 操作按钮场景化:针对不同监管操作设计独立按钮,符合监管业务的操作流程;
  • 统计信息可视化:采用数字+标签的形式展示车辆统计信息,便于快速掌握整体监管态势;
  • 操作指南显性化:专门设置操作指南模块,降低监管人员的学习成本;
  • 底部导航场景化:按车辆、核查、监控、我的分类,贴合监管工作的核心业务流程;
  • 安全区域适配:使用 SafeAreaView 适配异形屏,保证监管界面的完整性;
  • 卡片层级化设计:所有功能模块采用卡片式设计+轻微阴影,提升界面层次感,符合监管系统的设计趋势。
(2)交互优化
  • 状态标签化展示:车辆状态以彩色徽章形式展示,视觉突出,便于快速识别风险车辆;
  • 详情展开轻量化:点击车辆条目即可展开详情,操作直观,符合监管快速核查的需求;
  • 操作按钮分组化:将核查证件、查看路线等操作按钮分组展示,提升操作效率;
  • 统计信息聚合化:将总车辆、正常、异常数量聚合展示,便于监管人员快速掌握整体情况;
  • 底部导航固定展示:核心监管功能入口固定展示,便于监管过程中的功能快速切换;
  • 滚动体验流畅化:车辆列表支持滚动,适配多车辆监管的展示需求;
  • 操作反馈明确化:所有操作均提供明确的结果提示,保证监管操作的可追溯性;
  • 详情关闭便捷化:在详情页右上角提供关闭按钮,操作路径短,提升使用效率。

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

1. 架构

鸿蒙端适配遵循类型复用、逻辑对等、体验统一的原则,危化品监管的核心业务逻辑和视觉规范100%复用,仅需适配平台特有API和组件语法,确保监管应用的跨端体验一致性:

@Entry
@Component
struct RegulatoryInspectionApp {
  // 类型定义:对等实现 TypeScript 类型 → 接口定义
  interface HazardousVehicle {
    id: string;
    licensePlate: string;
    vehicleType: string;
    driverName: string;
    driverLicense: string;
    route: string;
    status: '正常' | '异常' | '待检查';
    certificates: {
      transportLicense: string;
      safetyCertificate: string;
      insurance: string;
    };
    lastCheckTime: string;
    nextCheckTime: string;
  }

  // 状态管理:对等实现 useState → @State
  @State vehicles: HazardousVehicle[] = [/* 初始车辆数据 */];
  @State selectedVehicle: string = '';

  // 业务逻辑:完全复用 RN 端的监管核心逻辑
  getStatusColor(status: string): string {/* 状态颜色映射 */}
  handleViewVehicle(vehicleId: string): void {/* 查看车辆详情 */}
  handleCloseDetail(): void {/* 关闭详情 */}
  handleVerifyCertificates(vehicleId: string): void {/* 核查证件 */}
  handleTrackRoute(vehicleId: string): void {/* 追踪路线 */}

  // 页面构建:镜像 RN 端布局结构,适配鸿蒙组件特性
  build() {
    Column() {
      // 头部区域
      // 车辆列表
      // 车辆详情
      // 统计信息
      // 操作指南
      // 底部导航
    }
  }
}

React Native 特性 鸿蒙 ArkUI 对应实现 监管场景适配关键说明
TypeScript 类型定义 TypeScript 接口定义 车辆、证件、状态等类型完全复用,保证监管数据结构一致性
useState @State 装饰器 车辆列表、选中车辆等状态的管理逻辑完全复用,保持监管流程一致性
证件核查算法 函数逻辑完全复用 证件展示、状态标记、操作反馈规则一致,保证监管操作的合规性
TouchableOpacity Column + onClick 所有可点击区域通过 onClick 事件实现,保持监管交互一致性
Alert.alert AlertDialog.show 证件核查、路线监控等弹窗逻辑对等,符合监管操作习惯
StyleSheet 链式样式 红色系主色调、车辆卡片样式等视觉规范100%复用
Array.map ForEach 组件 车辆列表渲染逻辑一致,适配多车辆监管展示需求
ScrollView Scroll 组件 滚动容器语法差异,功能一致,适配多车辆展示
状态颜色映射 函数逻辑完全复用 状态-颜色映射规则一致,保证监管视觉认知一致性
底部导航 Position.Fixed 导航栏定位语法差异,效果一致,保证监管操作的便捷性

3. 鸿蒙代码

// 鸿蒙 ArkTS 完整实现 - 危化品运输监管系统
@Entry
@Component
struct RegulatoryInspectionApp {
  // 类型定义
  interface HazardousVehicle {
    id: string;
    licensePlate: string;
    vehicleType: string;
    driverName: string;
    driverLicense: string;
    route: string;
    status: '正常' | '异常' | '待检查';
    certificates: {
      transportLicense: string;
      safetyCertificate: string;
      insurance: string;
    };
    lastCheckTime: string;
    nextCheckTime: string;
  }

  // 状态管理
  @State vehicles: HazardousVehicle[] = [
    {
      id: '1',
      licensePlate: '京A12345',
      vehicleType: '罐式货车',
      driverName: '张师傅',
      driverLicense: '_drv123456',
      route: '北京→天津→青岛',
      status: '正常',
      certificates: {
        transportLicense: 'TL202312001',
        safetyCertificate: 'SC202312001',
        insurance: 'INS202312001'
      },
      lastCheckTime: '2023-12-01 09:30',
      nextCheckTime: '2023-12-15 09:30'
    },
    {
      id: '2',
      licensePlate: '沪B67890',
      vehicleType: '厢式危险品车',
      driverName: '李师傅',
      driverLicense: '_drv789012',
      route: '上海→南京→合肥',
      status: '异常',
      certificates: {
        transportLicense: 'TL202312002',
        safetyCertificate: 'SC202312002',
        insurance: 'INS202312002'
      },
      lastCheckTime: '2023-11-28 14:20',
      nextCheckTime: '2023-12-12 14:20'
    }
  ];

  @State selectedVehicle: string = '';

  // 获取状态对应的颜色
  getStatusColor(status: string): string {
    switch (status) {
      case '正常': return '#10b981';
      case '异常': return '#ef4444';
      case '待检查': return '#f59e0b';
      default: return '#6b7280';
    }
  }

  // 查看车辆详情
  handleViewVehicle(vehicleId: string): void {
    const vehicle = this.vehicles.find(v => v.id === vehicleId);
    if (vehicle) {
      this.selectedVehicle = vehicleId;
    }
  }

  // 关闭详情
  handleCloseDetail(): void {
    this.selectedVehicle = '';
  }

  // 核查证件
  handleVerifyCertificates(vehicleId: string): void {
    const vehicle = this.vehicles.find(v => v.id === vehicleId);
    if (vehicle) {
      AlertDialog.show({
        title: '证件核查',
        message: `车牌号: ${vehicle.licensePlate}\n` +
                `运输许可证: ${vehicle.certificates.transportLicense}\n` +
                `安全证书: ${vehicle.certificates.safetyCertificate}\n` +
                `保险单号: ${vehicle.certificates.insurance}\n\n` +
                `上次检查: ${vehicle.lastCheckTime}\n` +
                `下次检查: ${vehicle.nextCheckTime}`,
        cancel: {
          value: '标记异常',
          action: () => AlertDialog.show({
            title: '提示',
            message: '已标记为异常状态',
            confirm: { value: '确定' }
          })
        },
        confirm: {
          value: '核查通过',
          action: () => AlertDialog.show({
            title: '成功',
            message: '证件核查通过',
            confirm: { value: '确定' }
          })
        }
      });
    }
  }

  // 追踪路线
  handleTrackRoute(vehicleId: string): void {
    const vehicle = this.vehicles.find(v => v.id === vehicleId);
    if (vehicle) {
      AlertDialog.show({
        title: '实时路线',
        message: `车牌号: ${vehicle.licensePlate}\n` +
                `当前路线: ${vehicle.route}\n` +
                `驾驶员: ${vehicle.driverName}\n\n` +
                `GPS定位: 北纬39.9° 东经116.4°\n` +
                `行驶状态: 正常行驶\n` +
                `预计到达: 2023-12-15 16:30`,
        confirm: { value: '确定' }
      });
    }
  }

  build() {
    Column()
      .flex(1)
      .backgroundColor('#fef2f2')
      .safeArea(true) {
      
      // 头部区域
      Column()
        .padding(16)
        .backgroundColor('#ffffff')
        .borderBottom({ width: 1, color: '#fecaca' }) {
        Text('危化品监管')
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .fontColor('#991b1b')
          .marginBottom(4);
        
        Text('车辆合规核查与路线监控')
          .fontSize(14)
          .fontColor('#dc2626');
      }

      // 滚动内容区
      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('#991b1b')
              .marginBottom(12);
            
            // 车辆列表
            ForEach(this.vehicles, (vehicle: HazardousVehicle) => {
              Column()
                .padding(12)
                .borderBottom({ width: 1, color: '#fecaca' })
                .onClick(() => this.handleViewVehicle(vehicle.id)) {
              
              // 车辆头部
              Column()
                .flexDirection(FlexDirection.Row)
                .justifyContent(FlexAlign.SpaceBetween)
                .alignItems(ItemAlign.Center)
                .marginBottom(8) {
                Text(vehicle.licensePlate)
                  .fontSize(16)
                  .fontWeight(FontWeight.SemiBold)
                  .fontColor('#991b1b');
                
                Column()
                  .paddingLeft(8)
                  .paddingRight(8)
                  .paddingTop(4)
                  .paddingBottom(4)
                  .borderRadius(12)
                  .backgroundColor(this.getStatusColor(vehicle.status)) {
                  Text(vehicle.status)
                    .fontSize(12)
                    .fontColor(Color.White)
                    .fontWeight(FontWeight.Medium);
                }
              }
              
              // 车辆详情
              Column()
                .marginBottom(12) {
                Text(`驾驶员: ${vehicle.driverName}`)
                  .fontSize(14)
                  .fontColor('#64748b')
                  .marginBottom(2);
                
                Text(`路线: ${vehicle.route}`)
                  .fontSize(14)
                  .fontColor('#64748b')
                  .marginBottom(2);
                
                Text(`下次检查: ${vehicle.nextCheckTime}`)
                  .fontSize(12)
                  .fontColor('#dc2626');
              }
              
              // 车辆操作按钮
              Column()
                .flexDirection(FlexDirection.Row)
                .justifyContent(FlexAlign.SpaceBetween) {
                Button('核查证件')
                  .backgroundColor('#fecaca')
                  .paddingLeft(12)
                  .paddingRight(12)
                  .paddingTop(6)
                  .paddingBottom(6)
                  .borderRadius(16)
                  .fontSize(12)
                  .fontColor('#dc2626')
                  .onClick(() => this.handleVerifyCertificates(vehicle.id));
                
                Button('查看路线')
                  .backgroundColor('#fecaca')
                  .paddingLeft(12)
                  .paddingRight(12)
                  .paddingTop(6)
                  .paddingBottom(6)
                  .borderRadius(16)
                  .fontSize(12)
                  .fontColor('#dc2626')
                  .onClick(() => this.handleTrackRoute(vehicle.id));
              }
            }
            })
          }

          // 车辆详情卡片
          if (this.selectedVehicle) {
            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 }) {
              
              // 详情头部
              Column()
                .flexDirection(FlexDirection.Row)
                .justifyContent(FlexAlign.SpaceBetween)
                .alignItems(ItemAlign.Center)
                .marginBottom(12) {
                Text('车辆详情')
                  .fontSize(16)
                  .fontWeight(FontWeight.SemiBold)
                  .fontColor('#991b1b');
                
                Text('✕')
                  .fontSize(18)
                  .fontColor('#64748b')
                  .onClick(() => this.handleCloseDetail());
              }
              
              // 详情内容
              const vehicle = this.vehicles.find(v => v.id === this.selectedVehicle);
              if (vehicle) {
                Column() {
                  // 基础信息
                  ForEach([
                    { label: '车牌号:', value: vehicle.licensePlate },
                    { label: '车型:', value: vehicle.vehicleType },
                    { label: '驾驶员:', value: vehicle.driverName },
                    { label: '驾驶证:', value: vehicle.driverLicense },
                    { label: '运输路线:', value: vehicle.route }
                  ], (item) => {
                    Column()
                      .flexDirection(FlexDirection.Row)
                      .marginBottom(8) {
                      Text(item.label)
                        .fontSize(14)
                        .fontColor('#64748b')
                        .width(80);
                      
                      Text(item.value)
                        .fontSize(14)
                        .fontColor('#991b1b')
                        .flexGrow(1);
                    }
                  });
                  
                  // 证件信息
                  Column()
                    .marginTop(12)
                    .paddingTop(12)
                    .borderTop({ width: 1, color: '#fecaca' }) {
                    Text('相关证件')
                      .fontSize(14)
                      .fontWeight(FontWeight.Medium)
                      .fontColor('#991b1b')
                      .marginBottom(8);
                    
                    ForEach([
                      { label: '运输许可证:', value: vehicle.certificates.transportLicense },
                      { label: '安全证书:', value: vehicle.certificates.safetyCertificate },
                      { label: '保险单号:', value: vehicle.certificates.insurance }
                    ], (item) => {
                      Column()
                        .flexDirection(FlexDirection.Row)
                        .marginBottom(4) {
                        Text(item.label)
                          .fontSize(12)
                          .fontColor('#64748b')
                          .width(80);
                        
                        Text(item.value)
                          .fontSize(12)
                          .fontColor('#991b1b')
                          .flexGrow(1);
                      }
                    });
                  }
                  
                  // 检查时间
                  Column()
                    .marginTop(12)
                    .paddingTop(12)
                    .borderTop({ width: 1, color: '#fecaca' }) {
                    ForEach([
                      { label: '上次检查:', value: vehicle.lastCheckTime },
                      { label: '下次检查:', value: vehicle.nextCheckTime }
                    ], (item) => {
                      Column()
                        .flexDirection(FlexDirection.Row)
                        .marginBottom(4) {
                        Text(item.label)
                          .fontSize(12)
                          .fontColor('#64748b')
                          .width(80);
                        
                        Text(item.value)
                          .fontSize(12)
                          .fontColor('#991b1b')
                          .flexGrow(1);
                      }
                    });
                  }
                }
              }
            }
          }

          // 统计信息卡片
          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 })
            .flexDirection(FlexDirection.Row)
            .justifyContent(FlexAlign.SpaceAround) {
            
            // 总车辆
            Column()
              .alignItems(ItemAlign.Center) {
              Text(`${this.vehicles.length}`)
                .fontSize(18)
                .fontWeight(FontWeight.Bold)
                .fontColor('#dc2626');
              
              Text('总车辆')
                .fontSize(12)
                .fontColor('#64748b')
                .marginTop(4);
            }
            
            // 正常车辆
            Column()
              .alignItems(ItemAlign.Center) {
              Text(`${this.vehicles.filter(v => v.status === '正常').length}`)
                .fontSize(18)
                .fontWeight(FontWeight.Bold)
                .fontColor('#dc2626');
              
              Text('正常')
                .fontSize(12)
                .fontColor('#64748b')
                .marginTop(4);
            }
            
            // 异常车辆
            Column()
              .alignItems(ItemAlign.Center) {
              Text(`${this.vehicles.filter(v => v.status === '异常').length}`)
                .fontSize(18)
                .fontWeight(FontWeight.Bold)
                .fontColor('#dc2626');
              
              Text('异常')
                .fontSize(12)
                .fontColor('#64748b')
                .marginTop(4);
            }
          }

          // 操作指南卡片
          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('#991b1b')
              .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);
          }
        }
      }

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

1. 原则

  • 监管模型专业化复用:车辆、证件、检查周期等类型定义在两端保持一致,包含运输许可证、安全证书等核心合规字段,保证监管的专业性;
  • 视觉规范100%对齐:红色系主色调、车辆卡片样式、状态颜色映射等视觉属性完全复用,符合危化品监管的安全警示要求;
  • 业务逻辑统一:证件核查、路线监控、状态管理等核心逻辑保持一致,保证监管流程的合规性;
  • 合规校验对等:证件完整性校验、检查周期核对等合规性逻辑保持一致,符合危化品监管的要求;
  • 安全体验一致:状态警示色、操作反馈等安全相关设计保持一致,强化监管的安全意识;
  • 语义化设计统一:车牌号、证件编号等语义化设计保持一致,提升监管的识别效率;
  • 平台特性兼容:弹窗展示、点击事件等平台特有API做适配处理,保证监管应用的可用性;
  • 性能优化适配:鸿蒙端利用 ForEach 组件的复用机制优化列表渲染性能,RN 端利用数组映射实现高效渲染,均满足多车辆监管展示的性能要求。

2. 危化品监管系统

  • 证件验真集成:对接交通运输部证件查询接口,实现在线验真运输许可证、安全证书等证件的有效性;
  • GPS实时监控:集成高德/百度地图SDK,实现运输车辆的实时位置监控和电子围栏告警;
  • 检查周期提醒:增加检查周期到期提醒功能,自动推送待检查车辆列表,提升监管效率;
  • 异常处理流程:完善异常车辆的处理流程,支持记录异常原因、整改要求、复查结果等全流程信息;
  • 数据统计分析:增加监管数据统计分析功能,支持按时间、区域、车型等维度分析监管情况;
  • 离线操作支持:支持离线状态下的基础监管操作,联网后自动同步数据;
  • 电子签名审批:增加电子签名功能,实现证件核查结果的在线审批和存档;
  • 多端数据同步:实现React Native和鸿蒙端的数据实时同步,保证监管数据的一致性;
  • 权限精细化管理:区分管理员、核查员、监控员等角色,提供精细化的权限控制;
  • 批量操作支持:增加批量核查、批量导出等功能,提升大规模监管的效率;
  • 历史记录查询:支持查询车辆的历史核查记录、异常处理记录等,满足监管追溯需求;
  • 报表导出功能:支持导出监管报表,符合监管部门的上报要求;
  • 应急响应集成:对接应急管理系统,支持异常情况的快速上报和应急处置。

危化品运输监管系统作为安全生产的关键工具,其跨端适配的关键在于合规性、安全性、专业性的三位一体。这份 React Native 实现的危化品监管核查组件,通过强类型领域建模、精准的合规校验逻辑、安全化视觉设计,构建了高效的移动端监管体验;而鸿蒙 ArkTS 端的适配实现,则验证了跨端开发中"逻辑复用、体验统一"的核心原则。

  1. 危化品监管系统的类型设计需包含运输许可证、安全证书、保险单等合规字段,保证监管数据的完整性和合规性;
  2. 证件核查逻辑需完整展示核心证件信息和检查周期,支持异常标记和核查通过两种操作,符合监管业务流程;
  3. 车辆状态采用"正常/异常/待检查"三态管理,通过不同色系视觉区分,便于监管人员快速识别风险车辆;
  4. 视觉设计采用红色系主色调,强化危化品监管的安全警示属性,符合行业视觉认知;
  5. 跨端适配的核心是监管合规逻辑复用 + 平台特性适配,无需重写核心业务逻辑;
  6. 路线监控功能需展示车牌号、路线、驾驶员、GPS定位、行驶状态等全维度信息,满足动态监管需求;
  7. 统计信息模块聚合展示总车辆、正常、异常数量,便于监管人员快速掌握整体监管态势;
  8. 操作指南模块独立展示,降低监管人员的学习成本,提升系统的易用性。

真实演示案例代码:






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

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

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

// 危险品运输车辆类型
type HazardousVehicle = {
  id: string;
  licensePlate: string;
  vehicleType: string;
  driverName: string;
  driverLicense: string;
  route: string;
  status: '正常' | '异常' | '待检查';
  certificates: {
    transportLicense: string;
    safetyCertificate: string;
    insurance: string;
  };
  lastCheckTime: string;
  nextCheckTime: string;
};

// 监管人员核查应用组件
const RegulatoryInspectionApp: React.FC = () => {
  const [vehicles] = useState<HazardousVehicle[]>([
    {
      id: '1',
      licensePlate: '京A12345',
      vehicleType: '罐式货车',
      driverName: '张师傅',
      driverLicense: '_drv123456',
      route: '北京→天津→青岛',
      status: '正常',
      certificates: {
        transportLicense: 'TL202312001',
        safetyCertificate: 'SC202312001',
        insurance: 'INS202312001'
      },
      lastCheckTime: '2023-12-01 09:30',
      nextCheckTime: '2023-12-15 09:30'
    },
    {
      id: '2',
      licensePlate: '沪B67890',
      vehicleType: '厢式危险品车',
      driverName: '李师傅',
      driverLicense: '_drv789012',
      route: '上海→南京→合肥',
      status: '异常',
      certificates: {
        transportLicense: 'TL202312002',
        safetyCertificate: 'SC202312002',
        insurance: 'INS202312002'
      },
      lastCheckTime: '2023-11-28 14:20',
      nextCheckTime: '2023-12-12 14:20'
    }
  ]);

  const [selectedVehicle, setSelectedVehicle] = useState<string>('');

  const getStatusColor = (status: string) => {
    switch (status) {
      case '正常': return '#10b981';
      case '异常': return '#ef4444';
      case '待检查': return '#f59e0b';
      default: return '#6b7280';
    }
  };

  const handleViewVehicle = (vehicleId: string) => {
    const vehicle = vehicles.find(v => v.id === vehicleId);
    if (vehicle) {
      setSelectedVehicle(vehicleId);
    }
  };

  const handleCloseDetail = () => {
    setSelectedVehicle('');
  };

  const handleVerifyCertificates = (vehicleId: string) => {
    const vehicle = vehicles.find(v => v.id === vehicleId);
    if (vehicle) {
      Alert.alert(
        '证件核查',
        `车牌号: ${vehicle.licensePlate}\n` +
        `运输许可证: ${vehicle.certificates.transportLicense}\n` +
        `安全证书: ${vehicle.certificates.safetyCertificate}\n` +
        `保险单号: ${vehicle.certificates.insurance}\n\n` +
        `上次检查: ${vehicle.lastCheckTime}\n` +
        `下次检查: ${vehicle.nextCheckTime}`,
        [
          {
            text: '标记异常',
            onPress: () => Alert.alert('提示', '已标记为异常状态'),
            style: 'destructive'
          },
          {
            text: '核查通过',
            onPress: () => Alert.alert('成功', '证件核查通过')
          }
        ]
      );
    }
  };

  const handleTrackRoute = (vehicleId: string) => {
    const vehicle = vehicles.find(v => v.id === vehicleId);
    if (vehicle) {
      Alert.alert(
        '实时路线',
        `车牌号: ${vehicle.licensePlate}\n` +
        `当前路线: ${vehicle.route}\n` +
        `驾驶员: ${vehicle.driverName}\n\n` +
        `GPS定位: 北纬39.9° 东经116.4°\n` +
        `行驶状态: 正常行驶\n` +
        `预计到达: 2023-12-15 16:30`,
        [{ 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.vehiclesCard}>
          <Text style={styles.sectionTitle}>运输车辆</Text>
          
          {vehicles.map(vehicle => (
            <TouchableOpacity
              key={vehicle.id}
              style={styles.vehicleItem}
              onPress={() => handleViewVehicle(vehicle.id)}
            >
              <View style={styles.vehicleHeader}>
                <Text style={styles.licensePlate}>{vehicle.licensePlate}</Text>
                <View style={[
                  styles.statusBadge,
                  { backgroundColor: getStatusColor(vehicle.status) }
                ]}>
                  <Text style={styles.statusText}>{vehicle.status}</Text>
                </View>
              </View>
              
              <View style={styles.vehicleDetails}>
                <Text style={styles.driverInfo}>驾驶员: {vehicle.driverName}</Text>
                <Text style={styles.routeInfo}>路线: {vehicle.route}</Text>
                <Text style={styles.nextCheck}>下次检查: {vehicle.nextCheckTime}</Text>
              </View>
              
              <View style={styles.vehicleActions}>
                <TouchableOpacity 
                  style={styles.actionButton}
                  onPress={() => handleVerifyCertificates(vehicle.id)}
                >
                  <Text style={styles.actionText}>核查证件</Text>
                </TouchableOpacity>
                <TouchableOpacity 
                  style={styles.actionButton}
                  onPress={() => handleTrackRoute(vehicle.id)}
                >
                  <Text style={styles.actionText}>查看路线</Text>
                </TouchableOpacity>
              </View>
            </TouchableOpacity>
          ))}
        </View>

        {/* 车辆详情 */}
        {selectedVehicle && (
          <View style={styles.detailCard}>
            <View style={styles.detailHeader}>
              <Text style={styles.sectionTitle}>车辆详情</Text>
              <TouchableOpacity onPress={handleCloseDetail}>
                <Text style={styles.closeButton}></Text>
              </TouchableOpacity>
            </View>
            
            {(() => {
              const vehicle = vehicles.find(v => v.id === selectedVehicle);
              return vehicle ? (
                <View style={styles.detailContent}>
                  <View style={styles.detailRow}>
                    <Text style={styles.detailLabel}>车牌号:</Text>
                    <Text style={styles.detailValue}>{vehicle.licensePlate}</Text>
                  </View>
                  <View style={styles.detailRow}>
                    <Text style={styles.detailLabel}>车型:</Text>
                    <Text style={styles.detailValue}>{vehicle.vehicleType}</Text>
                  </View>
                  <View style={styles.detailRow}>
                    <Text style={styles.detailLabel}>驾驶员:</Text>
                    <Text style={styles.detailValue}>{vehicle.driverName}</Text>
                  </View>
                  <View style={styles.detailRow}>
                    <Text style={styles.detailLabel}>驾驶证:</Text>
                    <Text style={styles.detailValue}>{vehicle.driverLicense}</Text>
                  </View>
                  <View style={styles.detailRow}>
                    <Text style={styles.detailLabel}>运输路线:</Text>
                    <Text style={styles.detailValue}>{vehicle.route}</Text>
                  </View>
                  <View style={styles.certificatesSection}>
                    <Text style={styles.certTitle}>相关证件</Text>
                    <View style={styles.certItem}>
                      <Text style={styles.certLabel}>运输许可证:</Text>
                      <Text style={styles.certValue}>{vehicle.certificates.transportLicense}</Text>
                    </View>
                    <View style={styles.certItem}>
                      <Text style={styles.certLabel}>安全证书:</Text>
                      <Text style={styles.certValue}>{vehicle.certificates.safetyCertificate}</Text>
                    </View>
                    <View style={styles.certItem}>
                      <Text style={styles.certLabel}>保险单号:</Text>
                      <Text style={styles.certValue}>{vehicle.certificates.insurance}</Text>
                    </View>
                  </View>
                  <View style={styles.checkTimes}>
                    <View style={styles.timeItem}>
                      <Text style={styles.timeLabel}>上次检查:</Text>
                      <Text style={styles.timeValue}>{vehicle.lastCheckTime}</Text>
                    </View>
                    <View style={styles.timeItem}>
                      <Text style={styles.timeLabel}>下次检查:</Text>
                      <Text style={styles.timeValue}>{vehicle.nextCheckTime}</Text>
                    </View>
                  </View>
                </View>
              ) : null;
            })()}
          </View>
        )}

        {/* 统计信息 */}
        <View style={styles.statsCard}>
          <View style={styles.statItem}>
            <Text style={styles.statNumber}>{vehicles.length}</Text>
            <Text style={styles.statLabel}>总车辆</Text>
          </View>
          <View style={styles.statItem}>
            <Text style={styles.statNumber}>
              {vehicles.filter(v => v.status === '正常').length}
            </Text>
            <Text style={styles.statLabel}>正常</Text>
          </View>
          <View style={styles.statItem}>
            <Text style={styles.statNumber}>
              {vehicles.filter(v => v.status === '异常').length}
            </Text>
            <Text style={styles.statLabel}>异常</Text>
          </View>
        </View>

        {/* 操作指南 */}
        <View style={styles.guideCard}>
          <Text style={styles.sectionTitle}>操作指南</Text>
          <Text style={styles.guideText}>• 点击车辆查看详细信息</Text>
          <Text style={styles.guideText}>• 核查证件确保合规性</Text>
          <Text style={styles.guideText}>• 监控实时路线状态</Text>
          <Text style={styles.guideText}>• 异常情况及时处理</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: '#fef2f2',
  },
  header: {
    flexDirection: 'column',
    padding: 16,
    backgroundColor: '#ffffff',
    borderBottomWidth: 1,
    borderBottomColor: '#fecaca',
  },
  title: {
    fontSize: 20,
    fontWeight: 'bold',
    color: '#991b1b',
    marginBottom: 4,
  },
  subtitle: {
    fontSize: 14,
    color: '#dc2626',
  },
  content: {
    flex: 1,
    marginTop: 12,
  },
  vehiclesCard: {
    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: '#991b1b',
    marginBottom: 12,
  },
  vehicleItem: {
    padding: 12,
    borderBottomWidth: 1,
    borderBottomColor: '#fecaca',
  },
  vehicleHeader: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: 8,
  },
  licensePlate: {
    fontSize: 16,
    fontWeight: '600',
    color: '#991b1b',
  },
  statusBadge: {
    paddingHorizontal: 8,
    paddingVertical: 4,
    borderRadius: 12,
  },
  statusText: {
    fontSize: 12,
    color: '#ffffff',
    fontWeight: '500',
  },
  vehicleDetails: {
    marginBottom: 12,
  },
  driverInfo: {
    fontSize: 14,
    color: '#64748b',
    marginBottom: 2,
  },
  routeInfo: {
    fontSize: 14,
    color: '#64748b',
    marginBottom: 2,
  },
  nextCheck: {
    fontSize: 12,
    color: '#dc2626',
  },
  vehicleActions: {
    flexDirection: 'row',
    justifyContent: 'space-between',
  },
  actionButton: {
    backgroundColor: '#fecaca',
    paddingHorizontal: 12,
    paddingVertical: 6,
    borderRadius: 16,
  },
  actionText: {
    color: '#dc2626',
    fontSize: 12,
  },
  detailCard: {
    backgroundColor: '#ffffff',
    marginHorizontal: 16,
    marginBottom: 12,
    borderRadius: 12,
    padding: 16,
    elevation: 2,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
  },
  detailHeader: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: 12,
  },
  closeButton: {
    fontSize: 18,
    color: '#64748b',
  },
  detailContent: {
    // 详情内容样式
  },
  detailRow: {
    flexDirection: 'row',
    marginBottom: 8,
  },
  detailLabel: {
    fontSize: 14,
    color: '#64748b',
    width: 80,
  },
  detailValue: {
    fontSize: 14,
    color: '#991b1b',
    flex: 1,
  },
  certificatesSection: {
    marginTop: 12,
    paddingTop: 12,
    borderTopWidth: 1,
    borderTopColor: '#fecaca',
  },
  certTitle: {
    fontSize: 14,
    fontWeight: '500',
    color: '#991b1b',
    marginBottom: 8,
  },
  certItem: {
    flexDirection: 'row',
    marginBottom: 4,
  },
  certLabel: {
    fontSize: 12,
    color: '#64748b',
    width: 80,
  },
  certValue: {
    fontSize: 12,
    color: '#991b1b',
    flex: 1,
  },
  checkTimes: {
    marginTop: 12,
    paddingTop: 12,
    borderTopWidth: 1,
    borderTopColor: '#fecaca',
  },
  timeItem: {
    flexDirection: 'row',
    marginBottom: 4,
  },
  timeLabel: {
    fontSize: 12,
    color: '#64748b',
    width: 80,
  },
  timeValue: {
    fontSize: 12,
    color: '#991b1b',
    flex: 1,
  },
  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: '#dc2626',
  },
  statLabel: {
    fontSize: 12,
    color: '#64748b',
    marginTop: 4,
  },
  guideCard: {
    backgroundColor: '#ffffff',
    marginHorizontal: 16,
    marginBottom: 80,
    borderRadius: 12,
    padding: 16,
    elevation: 2,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
  },
  guideText: {
    fontSize: 14,
    color: '#64748b',
    lineHeight: 20,
    marginBottom: 4,
  },
  bottomNav: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    backgroundColor: '#ffffff',
    borderTopWidth: 1,
    borderTopColor: '#fecaca',
    paddingVertical: 12,
    position: 'absolute',
    bottom: 0,
    left: 0,
    right: 0,
  },
  navItem: {
    alignItems: 'center',
    flex: 1,
  },
  activeNavItem: {
    paddingTop: 4,
    borderTopWidth: 2,
    borderTopColor: '#dc2626',
  },
  navIcon: {
    fontSize: 20,
    color: '#94a3b8',
    marginBottom: 4,
  },
  activeNavIcon: {
    color: '#dc2626',
  },
  navText: {
    fontSize: 12,
    color: '#94a3b8',
  },
  activeNavText: {
    color: '#dc2626',
    fontWeight: '500',
  },
});

export default RegulatoryInspectionApp;


请添加图片描述


打包

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

在这里插入图片描述

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

在这里插入图片描述

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

请添加图片描述
本文介绍了一个基于React Native和TypeScript的危化品运输监管应用,采用模块化架构设计,实现跨平台兼容性。系统核心包括车辆信息管理、证件核查、路线跟踪等功能,通过Hooks进行状态管理,优化性能与内存使用。文章详细解析了技术架构、业务逻辑和跨平台适配方案,并提出了AI集成、区块链应用等未来优化方向,为危化品运输安全监管提供数字化解决方案。

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

Logo

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

更多推荐