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


在医疗信息化时代,健康档案的安全共享成为了一个重要的需求。今天我们来深入分析一个基于 React Native 开发的健康档案共享应用,该应用允许用户授权家人或医生查看健康档案,支持紧急情况一键共享,为医疗信息的安全流通提供了便捷的解决方案。

使用 ViewTextTextInput 等构建用户界面

该应用采用了 React Native 现代开发技术栈,主要包括:

  • React Hooks:使用 useState 管理应用状态,包括用户数据、健康档案、授权用户和用户输入等
  • TypeScript:通过类型定义确保数据结构的一致性和代码的可维护性
  • 跨平台组件:使用 SafeAreaViewTouchableOpacityScrollViewModal 等实现跨平台兼容的用户界面
  • 响应式布局:利用 Dimensions API 获取屏幕尺寸,确保在不同设备上的良好显示效果
  • 基础组件:使用 ViewTextTextInput 等构建用户界面

表示授权用户,包含 ID、用户 ID、授权用户 ID、访问级别和过期日期

应用通过 TypeScript 定义了三个核心数据类型,构建了完整的健康档案共享数据模型:

  • User:表示用户信息,包含 ID、姓名、邮箱和电话
  • HealthRecord:表示健康档案,包含 ID、用户 ID、日期和内容
  • AuthorizedUser:表示授权用户,包含 ID、用户 ID、授权用户 ID、访问级别和过期日期

这种强类型定义不仅提高了代码的可读性和可维护性,也为鸿蒙跨端适配提供了清晰的数据结构映射基础。


应用采用了基于 useState 的轻量级状态管理方案,为不同功能模块分别管理状态:

  • 静态数据(用户列表)通过初始化的 useState 直接存储
  • 动态数据(健康档案、授权用户)通过 useState 管理,并支持添加新数据
  • 表单数据(新授权信息)通过独立的 useState 管理
  • 交互状态(选中的用户、模态框可见性)通过独立的 useState 管理

这种模式在中小型应用中非常高效,既避免了过度设计,又保证了状态管理的清晰性。


用户管理

用户管理是应用的基础功能,通过列表展示用户的基本信息,包括姓名、邮箱和电话。用户可以点击选择用户进行后续操作,为健康档案管理和授权管理提供明确的目标对象。

健康档案管理是应用的核心功能之一,主要包括:

  • 展示健康档案列表,包括日期和内容摘要
  • 查看健康档案详细信息
  • 管理健康档案的共享权限

授权管理是应用的关键功能,主要包括:

  • 添加授权用户,设置访问级别和过期日期
  • 查看授权用户列表和详情
  • 管理授权用户的访问权限

通过授权管理,用户可以安全地分享自己的健康档案给家人或医生,同时控制访问级别和权限有效期。

紧急共享功能

紧急共享功能为用户提供了在紧急情况下快速分享健康档案的能力:

  • 一键将健康档案共享给所有授权用户
  • 确保在紧急情况下医疗人员能够及时获取患者的健康信息

这一功能在医疗急救场景中尤为重要,可以为患者争取宝贵的治疗时间。

应用通过卡片式布局展示用户信息、健康档案和授权用户,使用 TouchableOpacity 组件实现交互功能,点击卡片后可以查看详细信息或执行相关操作。此外,应用使用 Modal 组件展示详细信息,提升了用户体验。


组件映射

在鸿蒙 OS 适配过程中,需要注意以下组件映射:

  • SafeAreaView:在鸿蒙上需要使用 SafeArea 组件或自定义适配
  • TouchableOpacity:对应鸿蒙的 ButtonText 组件配合点击事件
  • ScrollView:对应鸿蒙的 ListContainerScroll 组件
  • Modal:对应鸿蒙的 Dialog 组件
  • Alert:对应鸿蒙的 ToastDialogAlertDialog 组件
  • TextInput:对应鸿蒙的 TextField 组件

鸿蒙 OS 对 Flexbox 布局的支持与 React Native 基本一致,但在细节上仍需注意:

  • 确保样式命名符合鸿蒙规范
  • 调整间距和尺寸以适应鸿蒙设备的显示特性
  • 注意字体大小和行高的适配
  • 对于表单输入控件,需要适配鸿蒙的输入框样式和交互方式

在鸿蒙跨端开发中,性能优化是一个重要考虑因素:

  • 使用 memo 优化组件渲染,特别是对于用户列表、健康档案列表等重复渲染的场景
  • 合理使用 useCallbackuseMemo 减少不必要的计算
  • 优化图片资源,考虑使用鸿蒙的资源加载机制
  • 对于授权管理,考虑使用更高效的权限检查算法
  • 对于列表数据的渲染,考虑使用虚拟化技术减少内存占用

安全的授权机制

应用实现了安全的授权机制:

  • 基于用户 ID 的授权管理
  • 可设置不同的访问级别
  • 可设置授权过期日期
  • 支持紧急情况下的一键共享

应用从多个维度管理健康档案:

  • 按用户分类管理健康档案
  • 按日期记录健康状况
  • 支持详细的健康信息描述
  • 提供便捷的共享和授权功能

这种多维度的管理模式为用户提供了全面的健康档案管理解决方案。

应用特别设计了紧急共享功能,在紧急情况下可以一键将健康档案共享给所有授权用户。这一功能在医疗急救场景中尤为重要,可以为患者争取宝贵的治疗时间。


模块化设计

应用采用了清晰的模块化设计:

  • 功能按模块划分(用户管理、健康档案管理、授权管理、紧急共享)
  • 组件职责单一,便于维护和扩展
  • 状态管理逻辑与 UI 渲染分离

Base64 图标

应用使用 Base64 编码的图标,这种方式有几个优点:

  • 减少网络请求,提高加载速度
  • 避免图标资源的跨平台适配问题
  • 减小应用包体积

虽然示例中使用的是占位 Base64 编码,但实际应用中可以使用真实的图标编码。


文件结构

示例代码集中在 App.tsx 文件中,适合小型应用。对于大型应用,建议按功能模块拆分文件:

  • /components:存放可复用组件,如用户卡片、健康档案卡片、授权用户卡片等

  • /types:存放类型定义,如 User、HealthRecord、AuthorizedUser 等

  • /hooks:存放自定义 hooks,如健康档案管理逻辑、授权管理逻辑等

  • /services:存放 API 调用和业务逻辑,如数据存储、授权服务等

  • /utils:存放工具函数,如日期处理、数据格式化等

  • 命名规范:变量和函数命名清晰,符合语义化要求

  • 类型安全:使用 TypeScript 确保类型安全

  • 错误处理:通过条件判断处理可能的异常情况,如表单验证

  • 注释:代码结构清晰,关键部分有适当注释

  • 性能考虑:合理使用 React Hooks,避免不必要的渲染和计算

应用架构具有良好的扩展性:

  • 可以轻松添加新的用户类型和健康档案类型
  • 可以集成真实的后端 API,实现数据的持久化存储
  • 可以扩展支持更多的授权级别和权限控制
  • 可以集成推送通知服务,实现授权过期提醒和紧急共享通知
  • 可以添加数据可视化功能,如健康状况趋势图表等

技术价值

这个健康档案共享应用展示了如何使用 React Native 构建功能完备的健康档案管理工具,特别是在安全授权机制和紧急共享功能方面的实践具有重要参考价值。通过跨端开发技术,可以在不同平台为用户提供一致的服务体验。

随着人们对健康管理重视程度的提高,这类应用的需求将不断增长。未来可以考虑:

  • 与更多医疗系统对接,实现健康档案的自动同步
  • 利用区块链技术提高健康档案的安全性和隐私保护
  • 支持更多的健康数据类型,如运动数据、饮食记录等
  • 开发配套的医疗专业版应用,为医生提供更专业的健康档案查看工具
  • 集成 AI 技术,为用户提供基于健康档案的个性化健康建议

React Native 鸿蒙跨端开发代表了移动应用开发的未来趋势,通过一套代码库覆盖多个平台,不仅可以降低开发成本,还可以确保用户体验的一致性。在医疗应用领域,这种开发模式尤为重要,因为它可以让开发者更专注于核心功能的实现,而不是平台差异的处理。

通过对这个健康档案共享应用的技术分析,我们可以看到 React Native 在构建跨平台医疗应用方面的强大能力。从技术架构到功能实现,从用户体验到跨端适配,这个应用都展示了现代移动应用开发的最佳实践。


健康档案共享是智慧医疗在数据授权与协同服务场景的核心落地形态,聚焦“用户管理-健康档案展示-授权配置-紧急共享”全流程的医疗数据服务逻辑,既要保证健康档案数据的安全性与授权规则的准确性,又需兼顾紧急共享的时效性与多端服务体验的一致性。本文基于这套 React Native 健康档案共享应用代码,从架构设计、核心业务逻辑、鸿蒙跨端适配三个维度,系统解读医疗数据授权场景的跨端开发逻辑与技术要点,重点剖析 React Native 与鸿蒙系统的适配底层逻辑和落地实践方案,尤其针对授权用户新增、健康档案查看、紧急共享触发等核心交互的跨端实现进行深度拆解。

一、SafeAreaView、ScrollView、TouchableOpacity、TextInput、Modal 等

该健康档案共享应用基于 React Native 函数式组件 + TypeScript 强类型架构构建,核心依赖 React Native 原生基础组件(SafeAreaView、ScrollView、TouchableOpacity、TextInput、Modal 等)与 useState 核心 Hook,未引入第三方 UI 框架或复杂状态管理库。这种极简架构是健康档案共享这类“强数据授权、轻实时交互”场景实现鸿蒙跨端的核心优势——轻量意味着适配成本更低,且能最大程度保证多端医疗数据服务流程逻辑的一致性,尤其适合用户选择、授权配置、紧急共享等核心逻辑的跨端复用。

从跨端技术底层逻辑来看,React Native 以“JS 桥接层(JS Bridge)”为核心实现跨端能力:前端编写的 JSX 组件与健康档案共享业务逻辑,通过桥接层映射为不同平台的原生组件,iOS 端映射为 UIKit 体系、Android 端映射为 View 体系,而鸿蒙(HarmonyOS)端则通过 React Native for HarmonyOS 适配层,完成 React Native 组件/API 与鸿蒙 ArkUI 组件/API 的双向映射。该应用的代码结构完全遵循跨端开发规范:无平台专属硬编码、状态管理基于 React 原生 Hooks、样式采用跨端通用的 Flex 布局,从根源上消除了鸿蒙适配的技术壁垒,同时保证授权用户新增、健康档案查看、紧急共享触发等核心医疗数据授权流程逻辑在多端的一致性。

值得注意的是,应用核心的授权新增(handleAddAuthorization)、健康档案详情查看(handleViewRecord)、紧急共享(handleShareEmergency)逻辑均为纯 JS 状态操作与数组关联查询实现,无任何平台相关依赖,这是跨端复用的关键——鸿蒙端可通过 JS 引擎直接执行该逻辑,无需适配任何原生能力,保证医疗数据授权规则在多端的完全一致,避免因平台差异导致的授权配置失败、紧急共享触发异常等核心问题。


1. User(用户)、HealthRecord(健康档案)、AuthorizedUser(授权用户)三类核心数据类型

应用通过 TypeScript 接口定义了 User(用户)、HealthRecord(健康档案)、AuthorizedUser(授权用户)三类核心数据类型,字段设计精准匹配医疗数据授权全流程数据需求,且所有字段均为 JS 基础数据类型(string/number/boolean),为跨端适配奠定基础:

  • User 作为基础用户数据模型,涵盖用户ID、姓名、邮箱、电话字段,所有字段均为标准化字符串,在鸿蒙端适配层可直接映射为 ArkTS 的 string 类型,避免多端数据类型解析差异导致的用户信息展示错误,尤其在“李先生 li@example.com 13800138000”这类核心用户信息的传递上,保证了跨端的数据准确性;
  • HealthRecord 模型涵盖档案ID、用户ID、日期、内容字段,日期(date: string)采用标准化日期格式字符串,内容(content: string)为医疗数据标准化描述字符串,鸿蒙端适配层可直接解析,保证健康档案信息展示的跨端一致性;
  • AuthorizedUser 模型作为核心授权数据模型,涵盖授权ID、用户ID、被授权用户ID、访问级别、过期日期字段,访问级别(accessLevel: string)采用标准化枚举式字符串(完全访问/只读/部分访问),过期日期(expirationDate: string)为标准化日期格式字符串,鸿蒙端适配层可直接解析,保证授权规则的跨端一致性。

这种强类型+场景化的数据模型设计,在跨端场景下保证了数据结构的一致性——鸿蒙端适配层可直接解析 TypeScript 类型定义,与 ArkTS 中的数据模型形成精准映射,避免多端数据格式不一致导致的用户信息展示异常、授权规则错误等核心问题,是健康档案共享场景跨端落地的基础保障。

2. Hooks 状态管理

应用采用 useState 实现多维度状态管理,核心状态均具备跨端复用的特性,且针对健康档案共享场景做了适配性设计:

  • 核心业务数据状态(users/healthRecords/authorizedUsers)中,users 为只读设计,适配层自动映射为鸿蒙的 @State 响应式状态,用户列表的展示逻辑跨端统一;healthRecords/authorizedUsers 支持状态更新操作(setHealthRecords/setAuthorizedUsers),数组扩展运算符([...authorizedUsers, newAuthEntry])为 ES6+ 标准语法,鸿蒙端直接执行,授权用户新增的规则跨端一致,保证多端授权数据的同步性;
  • 表单录入状态(newAuthorization)采用对象式状态管理,其属性更新逻辑(setNewAuthorization({ ...newAuthorization, authorizedUserId: text }))为纯 JS 对象解构赋值,鸿蒙端直接执行,授权配置表单录入的交互逻辑跨端统一;
  • 交互状态(selectedUser)维护选中用户,为字符串/空值赋值,鸿蒙端直接执行,用户选择的状态管理逻辑跨端统一;
  • 弹窗状态(isModalVisible/modalContent)维护弹窗显隐与内容,其更新逻辑为基础状态操作,鸿蒙端适配层会将 Modal 的显示状态映射为 ArkUI 弹窗的显隐状态,健康档案/授权信息详情展示的逻辑跨端统一。

1. 健康档案共享专属样式的跨端适配

应用在基础样式之上新增用户卡片、健康档案卡片、授权配置表单、紧急共享按钮专属样式,核心样式设计既遵循跨端兼容原则,又针对医疗数据授权场景的操作习惯做了特殊优化,适配鸿蒙系统无明显改造成本:

  • Flex 布局的跨端统一:从用户卡片的“图标+信息”、健康档案卡片的“图标+信息”,到授权配置表单的“多行输入框+添加按钮”、紧急共享按钮的独立布局,全量采用 Flex 布局体系——授权配置表单使用 flexDirection: 'row' + justifyContent: 'space-between' 横向布局,输入框均分宽度,保证表单录入的整洁性;用户/健康档案/授权卡片使用 flexDirection: 'row' + alignItems: 'center' 横向布局,图标与信息区域分层展示,方便快速识别信息。Flex 作为 W3C 标准布局方案,在鸿蒙端可被适配层直接解析为 ArkUI 的 Flex 布局,无需重构任何布局逻辑,仅需保证样式属性命名与 React Native 规范一致,尤其在用户选择、授权配置、紧急共享等核心医疗数据授权交互区域的布局上,Flex 布局的跨端一致性表现突出;
  • 健康档案共享专属样式的跨端适配
    • 选中用户卡片样式(selectedCardborderWidth: 2 + borderColor: '#0284c7')为通用样式属性,鸿蒙端适配层会将边框属性转换为 ArkUI 的 border 相关属性,选中项的高亮边框视觉效果跨端统一,帮助用户快速识别选择状态;
    • 表单输入框样式(input)设置 flex: 1 + marginRight: 8,为通用样式属性,鸿蒙端适配层直接解析,多输入框的均分布局逻辑跨端统一,符合用户授权配置表单录入的操作习惯;
    • 添加授权按钮/紧急共享按钮样式(addButton/emergencyButton)分别采用蓝/红背景色区分功能,红色系的紧急共享按钮符合医疗场景的视觉警示规范,为通用样式属性,鸿蒙端适配层直接解析,按钮的视觉辨识度与点击区域跨端统一,方便用户完成授权新增/紧急共享操作;
    • 各类卡片样式(card/recordCard/authCard)采用统一的圆角(borderRadius: 12)、内边距(padding: 16)设计,为通用样式属性,鸿蒙端适配层直接解析,卡片的视觉风格跨端统一,符合医疗场景专业、清晰的视觉需求;
  • 屏幕适配与层级兼容Dimensions.get('window') 获取设备宽高的 API 在鸿蒙端已完成原生映射,为不同尺寸鸿蒙设备(手机、平板)的自适应布局预留基础,尤其适配平板设备的多用户/多档案大屏查看场景;shadow + elevation 的双层阴影设计,鸿蒙系统对 elevation 属性的支持与 Android 端完全兼容,保证各类卡片、信息卡片的视觉层级跨端统一,同时阴影透明度(0.1)的低饱和度设计,避免视觉干扰,符合医疗数据场景严谨、专业的视觉调性;
  • 安全区域适配SafeAreaView 组件在鸿蒙端已适配为 ArkUI 的 SafeArea 组件,保证头部健康档案共享标题区域在不同鸿蒙设备上的展示完整性,避免标题被刘海屏、全面屏遮挡,尤其适配医护人员/患者的视觉聚焦习惯。

(1)用户与健康档案管理组件

用户与健康档案管理是健康档案共享的基础功能,核心适配逻辑如下:

  • 用户/健康档案列表渲染采用 map 方法遍历 users/healthRecords 数组,该逻辑为纯 JS 数组操作,鸿蒙端通过 JS 引擎直接执行,列表渲染的顺序与信息展示的完整性跨端一致,保证用户/健康档案信息的准确展示;
  • 用户选择逻辑(handleSelectUser)包含状态更新(setSelectedUser)与弹窗反馈(Alert.alert),状态更新为基础字符串赋值,弹窗反馈转换为鸿蒙 AlertDialog 组件,选择操作的反馈逻辑跨端一致;
  • 健康档案详情查看逻辑(handleViewRecord)包含数据查找(healthRecords.find)、弹窗内容拼接、弹窗显隐控制,数据查找为 JS 原生数组方法,弹窗内容拼接为纯 JS 模板字符串操作,弹窗显隐控制为基础状态赋值,鸿蒙端直接执行,详情展示的逻辑跨端统一。
(2)授权管理组件

授权管理是健康档案共享的核心数据授权功能,核心适配逻辑如下:

  • 授权配置表单采用 TextInput 组件实现多字段录入,onChangeText/placeholder 属性在鸿蒙端已适配,表单录入的交互逻辑跨端统一;
  • 授权新增逻辑(handleAddAuthorization)包含表单校验(newAuthorization.authorizedUserId && newAuthorization.accessLevel && newAuthorization.expirationDate)、数据构造、状态更新、表单重置、弹窗反馈,表单校验为纯 JS 布尔运算,数据构造为对象字面量赋值,状态更新使用数组扩展运算符,表单重置为对象属性清空,弹窗反馈转换为鸿蒙 AlertDialog 组件,新增操作的逻辑跨端一致;
  • 授权信息详情查看逻辑(handleViewAuthorization)包含双层数据查找(authorizedUsers.find + users.find)、弹窗内容拼接、弹窗显隐控制,数据查找为 JS 原生数组方法,弹窗内容拼接为纯 JS 模板字符串操作,弹窗显隐控制为基础状态赋值,鸿蒙端直接执行,授权详情展示的逻辑跨端统一。
(3)紧急共享组件

紧急共享是健康档案共享的核心应急功能,核心适配逻辑如下:

  • 紧急共享触发逻辑(handleShareEmergency)包含条件校验(selectedUser)、弹窗反馈,条件校验为纯 JS 布尔运算,弹窗反馈转换为鸿蒙 AlertDialog 组件,触发操作的逻辑跨端一致;
  • 紧急共享按钮采用 TouchableOpacity 组件,onPress 回调绑定触发逻辑,该组件在鸿蒙端已适配为 ArkUI 的 Button 组件,点击交互逻辑跨端统一,红色背景色的视觉警示效果跨端一致。

1. 健康档案共享的核心数据授权机制

handleAddAuthorization 是健康档案共享的核心数据授权机制,实现了“表单校验-数据构造-状态更新-表单重置-反馈提示”的全流程授权配置处理,核心适配逻辑如下:

  • 表单校验逻辑(newAuthorization.authorizedUserId && newAuthorization.accessLevel && newAuthorization.expirationDate)为纯 JS 布尔运算,鸿蒙端直接执行,校验规则跨端一致,保证授权信息录入的完整性;
  • 数据构造逻辑(newAuthEntry)采用对象字面量赋值,ID 生成((authorizedUsers.length + 1).toString())为纯 JS 数值运算与类型转换,关联用户ID(userId: selectedUser || '')为基础字符串赋值,鸿蒙端直接执行,数据构造的规则跨端一致;
  • 状态更新逻辑(setAuthorizedUsers([...authorizedUsers, newAuthEntry]))使用数组扩展运算符,鸿蒙端直接执行,授权用户新增的规则跨端一致,保证多端授权数据的同步性;
  • 表单重置逻辑(setNewAuthorization({ authorizedUserId: '', accessLevel: '', expirationDate: '' }))为对象属性清空,鸿蒙端直接执行,输入框重置的规则跨端一致;
  • 反馈提示逻辑(Alert.alert)转换为鸿蒙 AlertDialog 组件,提示文案为纯 JS 字符串,鸿蒙端直接执行,提示展示的逻辑跨端一致。

应用使用的核心 API 均为 React Native 跨端兼容 API,在鸿蒙端可无缝适配,且针对健康档案共享场景做了适配性验证:

  • 数组 API:map/find/扩展运算符等数组方法为 JS 原生 API,鸿蒙端通过 JS 引擎直接执行,无需适配,保证用户/健康档案/授权列表的渲染、查找、新增等核心逻辑的跨端一致性;
  • 字符串 API:字符串拼接、模板字符串等操作为 JS 原生 API,鸿蒙端直接执行,保证弹窗内容拼接、表单校验等核心逻辑的跨端一致性;
  • 交互 API:TouchableOpacityonPress 回调、TextInputonChangeText/placeholder 属性、Alert.alert 弹窗、Modal 组件的核心属性,在鸿蒙端均已完成适配,点击交互、输入交互、弹窗反馈、模态框展示的逻辑跨端一致,符合医疗数据授权场景的操作习惯;
  • 样式 API:StyleSheet.create 封装的样式规则,适配层转换为 ArkUI 的样式对象,尤其选中用户卡片的条件样式绑定逻辑,鸿蒙端可直接解析,保证选择状态的视觉适配跨端统一;
  • 对象 API:对象解构赋值(setNewAuthorization({ ...newAuthorization, authorizedUserId: text }))为 ES6+ 标准语法,鸿蒙端直接执行,授权配置表单录入的状态更新逻辑跨端统一。

该健康档案共享应用作为智慧医疗数据授权场景核心模块,适配鸿蒙系统的成本极低,核心适配思路与技术要点如下:

应用核心的授权新增、用户选择、健康档案查看、紧急共享等逻辑均为纯 JS 实现,无任何平台相关依赖,这是跨端复用的最大优势——鸿蒙端可通过 JS 引擎直接执行该逻辑,无需适配任何原生能力。在生产环境中扩展授权撤销、访问日志、健康档案编辑等逻辑时,新增规则仍为纯 JS 逻辑(授权撤销可通过数组过滤实现,健康档案编辑可通过数组映射实现),鸿蒙端可直接复用,仅需保证规则逻辑的通用性,无需考虑平台差异,这也是健康档案共享场景跨端开发的核心优势。

该应用当前的列表渲染采用基础 map 方法,在生产环境中若用户/健康档案/授权数据量较大(如超过50位用户、30份健康档案、20条授权记录),可替换为 React Native 的 FlatList 高性能列表组件——FlatList 在鸿蒙端已完成深度适配,支持虚拟化列表渲染,其核心属性(data/renderItem/keyExtractor)与 React Native 端完全一致,且 FlatListrenderItem 中可直接复用现有卡片样式与选中条件样式绑定逻辑,仅需少量调整即可适配鸿蒙端的性能优化策略,保证列表的滚动性能,尤其适合多用户、多档案的医疗数据授权场景。

鸿蒙系统有自身的医疗数据授权场景友好型设计规范,在适配时可通过条件编译实现差异化样式,既保证遵循鸿蒙设计规范,又能保留现有代码的完整性与场景友好特性:

// 鸿蒙端健康档案共享样式差异化适配示例
import { Platform } from 'react-native';
const isHarmonyOS = Platform.OS === 'harmony';

const adaptiveStyles = {
  card: {
    ...styles.card,
    backgroundColor: isHarmonyOS ? '#e0f7fa' : '#f0f9ff',
    borderRadius: isHarmonyOS ? 14 : 12,
    padding: isHarmonyOS ? 20 : 16, // 鸿蒙端增大内边距,更适合查看医疗数据
  },
  selectedCard: {
    ...styles.selectedCard,
    borderWidth: isHarmonyOS ? 3 : 2, // 鸿蒙端增大选中边框宽度
    borderColor: isHarmonyOS ? '#0369a1' : '#0284c7',
  },
  input: {
    ...styles.input,
    fontSize: isHarmonyOS ? 16 : 14, // 鸿蒙端增大输入框字体
    paddingHorizontal: isHarmonyOS ? 16 : 12,
    paddingVertical: isHarmonyOS ? 10 : 8,
  },
  emergencyButton: {
    ...styles.emergencyButton,
    padding: isHarmonyOS ? 18 : 16, // 鸿蒙端增大紧急按钮点击区域
    borderRadius: isHarmonyOS ? 14 : 12,
    backgroundColor: isHarmonyOS ? '#dc2626' : '#ef4444', // 鸿蒙端调整紧急按钮红色系
  }
};

这种轻量级的差异化适配,既能保证符合鸿蒙的医疗数据授权场景友好设计规范,又能保留现有代码的完整性,尤其在用户卡片、授权配置输入框、紧急共享按钮等核心医疗数据授权交互组件的样式适配中,效果显著,同时维持了健康档案共享场景专业、严谨的视觉调性。

该 React Native 健康档案共享应用实现了用户管理、健康档案展示、授权配置、紧急共享等核心智慧医疗服务功能,代码结构符合跨端开发规范,可低成本适配鸿蒙系统。针对生产环境落地,可做以下优化:

  1. 授权撤销与权限调整:新增授权撤销逻辑(数组过滤)与权限调整逻辑(数组映射),该逻辑为纯 JS 数组操作,鸿蒙端直接执行,无需适配原生能力,提升授权管理的灵活性;
  2. 访问日志与操作记录:新增访问日志数据模型与状态管理,实现授权用户访问健康档案的日志记录,该逻辑为纯 JS 数组新增操作,鸿蒙端直接执行,提升医疗数据授权的可追溯性;
  3. 健康档案编辑与同步:新增健康档案编辑逻辑(数组映射),对接医院 HIS 系统接口实现档案同步,数据同步逻辑为纯 JS 数组/对象序列化,鸿蒙端直接执行,保证健康档案数据的实时性;
  4. 生物识别授权验证:通过 React Native 原生模块封装鸿蒙的指纹/人脸验证 API,实现高权限授权的生物识别验证,核心授权配置逻辑可复用,仅需扩展生物识别能力,提升医疗数据授权的安全性;
  5. 离线授权规则缓存:通过 React Native 原生模块封装鸿蒙的本地存储 API,实现授权规则的离线缓存,核心授权管理逻辑可复用,仅需扩展离线存储能力,提升无网络场景下的授权服务体验。

真实演示案例代码:





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

// Base64 图标库
const ICONS_BASE64 = {
  profile: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  share: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  emergency: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
  access: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
};

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

// 用户类型
type User = {
  id: string;
  name: string;
  email: string;
  phone: string;
};

// 健康档案类型
type HealthRecord = {
  id: string;
  userId: string;
  date: string;
  content: string;
};

// 授权用户类型
type AuthorizedUser = {
  id: string;
  userId: string;
  authorizedUserId: string;
  accessLevel: string;
  expirationDate: string;
};

// 健康档案共享应用组件
const HealthRecordSharingApp: React.FC = () => {
  const [users] = useState<User[]>([
    {
      id: '1',
      name: '李先生',
      email: 'li@example.com',
      phone: '13800138000'
    },
    {
      id: '2',
      name: '王女士',
      email: 'wang@example.com',
      phone: '13800138001'
    }
  ]);

  const [healthRecords, setHealthRecords] = useState<HealthRecord[]>([
    {
      id: '1',
      userId: '1',
      date: '2023-12-01',
      content: '血压正常,心率稳定'
    },
    {
      id: '2',
      userId: '1',
      date: '2023-12-02',
      content: '血糖偏高,需调整饮食'
    }
  ]);

  const [authorizedUsers, setAuthorizedUsers] = useState<AuthorizedUser[]>([
    {
      id: '1',
      userId: '1',
      authorizedUserId: '2',
      accessLevel: '完全访问',
      expirationDate: '2024-12-31'
    }
  ]);

  const [selectedUser, setSelectedUser] = useState<string | null>(null);
  const [newAuthorization, setNewAuthorization] = useState({
    authorizedUserId: '',
    accessLevel: '',
    expirationDate: ''
  });
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [modalContent, setModalContent] = useState('');

  const handleSelectUser = (userId: string) => {
    setSelectedUser(userId);
    Alert.alert('选择用户', '您已选择该用户进行操作');
  };

  const handleAddAuthorization = () => {
    if (newAuthorization.authorizedUserId && newAuthorization.accessLevel && newAuthorization.expirationDate) {
      const newAuthEntry: AuthorizedUser = {
        id: (authorizedUsers.length + 1).toString(),
        userId: selectedUser || '',
        authorizedUserId: newAuthorization.authorizedUserId,
        accessLevel: newAuthorization.accessLevel,
        expirationDate: newAuthorization.expirationDate
      };
      setAuthorizedUsers([...authorizedUsers, newAuthEntry]);
      setNewAuthorization({ authorizedUserId: '', accessLevel: '', expirationDate: '' });
      Alert.alert('授权成功', '已成功添加授权用户');
    } else {
      Alert.alert('提示', '请填写完整的授权信息');
    }
  };

  const handleShareEmergency = () => {
    if (selectedUser) {
      Alert.alert('紧急共享', '健康档案已紧急共享给所有授权用户');
    } else {
      Alert.alert('提示', '请先选择用户');
    }
  };

  const handleViewRecord = (recordId: string) => {
    const record = healthRecords.find(r => r.id === recordId);
    if (record) {
      setModalContent(`日期: ${record.date}\n内容: ${record.content}`);
      setIsModalVisible(true);
    }
  };

  const handleViewAuthorization = (authId: string) => {
    const auth = authorizedUsers.find(a => a.id === authId);
    if (auth) {
      const user = users.find(u => u.id === auth.authorizedUserId);
      setModalContent(`授权用户: ${user?.name}\n访问级别: ${auth.accessLevel}\n过期日期: ${auth.expirationDate}`);
      setIsModalVisible(true);
    }
  };

  const openModal = (content: string) => {
    setModalContent(content);
    setIsModalVisible(true);
  };

  const closeModal = () => {
    setIsModalVisible(false);
  };

  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.section}>
          <Text style={styles.sectionTitle}>用户列表</Text>
          {users.map(user => (
            <TouchableOpacity 
              key={user.id}
              style={[
                styles.card,
                selectedUser === user.id && styles.selectedCard
              ]}
              onPress={() => handleSelectUser(user.id)}
            >
              <Text style={styles.icon}>👤</Text>
              <View style={styles.cardInfo}>
                <Text style={styles.cardTitle}>{user.name}</Text>
                <Text style={styles.cardDescription}>邮箱: {user.email}</Text>
                <Text style={styles.cardDescription}>电话: {user.phone}</Text>
              </View>
            </TouchableOpacity>
          ))}
        </View>

        {/* 健康档案 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>健康档案</Text>
          {healthRecords.map(record => (
            <TouchableOpacity 
              key={record.id}
              style={styles.recordCard}
              onPress={() => handleViewRecord(record.id)}
            >
              <Text style={styles.icon}>📋</Text>
              <View style={styles.cardInfo}>
                <Text style={styles.cardTitle}>{record.date}</Text>
                <Text style={styles.cardDescription}>{record.content}</Text>
              </View>
            </TouchableOpacity>
          ))}
        </View>

        {/* 授权管理 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>授权管理</Text>
          <View style={styles.inputRow}>
            <TextInput
              style={styles.input}
              placeholder="授权用户ID"
              value={newAuthorization.authorizedUserId}
              onChangeText={(text) => setNewAuthorization({ ...newAuthorization, authorizedUserId: text })}
            />
            <TextInput
              style={styles.input}
              placeholder="访问级别"
              value={newAuthorization.accessLevel}
              onChangeText={(text) => setNewAuthorization({ ...newAuthorization, accessLevel: text })}
            />
          </View>
          <View style={styles.inputRow}>
            <TextInput
              style={styles.input}
              placeholder="过期日期 (YYYY-MM-DD)"
              value={newAuthorization.expirationDate}
              onChangeText={(text) => setNewAuthorization({ ...newAuthorization, expirationDate: text })}
            />
          </View>
          <TouchableOpacity 
            style={styles.addButton}
            onPress={handleAddAuthorization}
          >
            <Text style={styles.addText}>添加授权</Text>
          </TouchableOpacity>
          {authorizedUsers.map(auth => (
            <TouchableOpacity 
              key={auth.id}
              style={styles.authCard}
              onPress={() => handleViewAuthorization(auth.id)}
            >
              <Text style={styles.icon}>🔒</Text>
              <View style={styles.cardInfo}>
                <Text style={styles.cardTitle}>授权ID: {auth.id}</Text>
                <Text style={styles.cardDescription}>访问级别: {auth.accessLevel}</Text>
                <Text style={styles.cardDescription}>过期日期: {auth.expirationDate}</Text>
              </View>
            </TouchableOpacity>
          ))}
        </View>

        {/* 紧急共享 */}
        <View style={styles.section}>
          <Text style={styles.sectionTitle}>紧急共享</Text>
          <TouchableOpacity 
            style={styles.emergencyButton}
            onPress={handleShareEmergency}
          >
            <Text style={styles.emergencyText}>一键共享</Text>
          </TouchableOpacity>
        </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>

        {/* 弹框内容 */}
        <Modal
          animationType="slide"
          transparent={true}
          visible={isModalVisible}
          onRequestClose={closeModal}
        >
          <View style={styles.modalContainer}>
            <View style={styles.modalContent}>
              <Text style={styles.modalTitle}>详细信息</Text>
              <Text style={styles.modalText}>{modalContent}</Text>
              <TouchableOpacity
                style={styles.closeButton}
                onPress={closeModal}
              >
                <Text style={styles.closeButtonText}>关闭</Text>
              </TouchableOpacity>
            </View>
          </View>
        </Modal>
      </ScrollView>
    </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,
  },
  section: {
    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,
  },
  card: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#f0f9ff',
    borderRadius: 12,
    padding: 16,
    marginBottom: 12,
  },
  selectedCard: {
    borderWidth: 2,
    borderColor: '#0284c7',
  },
  recordCard: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#f0f9ff',
    borderRadius: 12,
    padding: 16,
    marginBottom: 12,
  },
  authCard: {
    flexDirection: 'row',
    alignItems: 'center',
    backgroundColor: '#f0f9ff',
    borderRadius: 12,
    padding: 16,
    marginBottom: 12,
  },
  icon: {
    fontSize: 28,
    marginRight: 12,
  },
  cardInfo: {
    flex: 1,
  },
  cardTitle: {
    fontSize: 16,
    fontWeight: '500',
    color: '#0c4a6e',
    marginBottom: 4,
  },
  cardDescription: {
    fontSize: 14,
    color: '#0284c7',
    marginBottom: 2,
  },
  inputRow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    marginBottom: 12,
  },
  input: {
    flex: 1,
    backgroundColor: '#f0f9ff',
    borderRadius: 8,
    paddingHorizontal: 12,
    paddingVertical: 8,
    fontSize: 14,
    color: '#0c4a6e',
    marginRight: 8,
  },
  addButton: {
    backgroundColor: '#0284c7',
    padding: 12,
    borderRadius: 8,
    alignItems: 'center',
  },
  addText: {
    color: '#ffffff',
    fontSize: 14,
    fontWeight: '500',
  },
  emergencyButton: {
    backgroundColor: '#ef4444',
    padding: 16,
    borderRadius: 12,
    alignItems: 'center',
  },
  emergencyText: {
    color: '#ffffff',
    fontSize: 16,
    fontWeight: '500',
  },
  infoCard: {
    backgroundColor: '#ffffff',
    marginHorizontal: 16,
    marginBottom: 80,
    borderRadius: 12,
    padding: 16,
    elevation: 2,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
  },
  infoText: {
    fontSize: 14,
    color: '#64748b',
    lineHeight: 20,
    marginBottom: 4,
  },
  modalContainer: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'rgba(0, 0, 0, 0.5)',
  },
  modalContent: {
    width: '80%',
    backgroundColor: '#ffffff',
    borderRadius: 12,
    padding: 20,
    elevation: 5,
  },
  modalTitle: {
    fontSize: 18,
    fontWeight: 'bold',
    color: '#0c4a6e',
    marginBottom: 12,
    textAlign: 'center',
  },
  modalText: {
    fontSize: 14,
    color: '#0c4a6e',
    lineHeight: 20,
    marginBottom: 20,
  },
  closeButton: {
    backgroundColor: '#0284c7',
    padding: 10,
    borderRadius: 8,
    alignItems: 'center',
  },
  closeButtonText: {
    color: '#ffffff',
    fontSize: 14,
    fontWeight: '500',
  },
});

export default HealthRecordSharingApp;



请添加图片描述


打包

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

在这里插入图片描述

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

在这里插入图片描述

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

请添加图片描述
摘要:本文分析了一款基于React Native开发的健康档案共享应用,该应用通过安全授权机制实现医疗数据共享,支持紧急情况一键共享功能。文章重点探讨了其技术架构、核心功能模块及鸿蒙跨平台适配方案。应用采用React Hooks和TypeScript构建,实现了用户管理、健康档案展示、授权配置等核心功能,并通过组件映射和性能优化确保在鸿蒙系统的兼容性。该案例展示了React Native在医疗信息化领域的应用价值,为跨平台医疗应用开发提供了实践参考。

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

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐