React Native鸿蒙跨平台new Date().toISOString().split(‘T‘)[0]在鸿蒙系统中会被解析为标准`YYYY-MM-DD`格式,保证日期在不同鸿蒙设备上跨端一致性
本文探讨了基于React Native开发的社区医生签约管理应用如何适配鸿蒙系统。应用采用React Native通用组件与Hooks体系构建,通过TypeScript强类型数据模型确保医疗数据精准性,并利用StyleSheet实现跨平台UI适配。核心功能如医生签约状态校验、健康评估自动推送等采用不可变更新策略,保障了在鸿蒙多设备间的数据同步稳定性。该架构充分发挥了React Native&quo
欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。
在基层医疗数字化转型的背景下,社区医生签约管理类应用需要兼顾医疗服务的精准性、慢病管理的连续性以及多终端的适配能力。鸿蒙系统的分布式全场景架构为基层医疗应用的跨端部署提供了核心支撑,而React Native则凭借“一次开发、多端运行”的技术特性,成为这类应用跨端开发的最优解。本文将从数据模型设计、核心业务逻辑实现、UI适配到鸿蒙跨端兼容的底层逻辑,全方位拆解这款社区医生签约管理应用的技术架构,剖析React Native与鸿蒙生态融合的关键技术要点。
React Native与鸿蒙
这款社区医生签约管理应用的核心架构遵循React Native的“通用抽象层+平台适配层”设计理念,所有核心功能均基于React Native的通用API(View、TextInput、Modal、TouchableOpacity)和Hooks体系构建,未引入任何平台专属代码,这是实现鸿蒙跨端兼容的核心前提。
从底层适配逻辑来看,React Native for HarmonyOS框架会将React Native的通用组件无缝映射为鸿蒙ArkUI的原生组件:TouchableOpacity对应鸿蒙的Button原生组件,保留点击反馈的同时适配鸿蒙的交互规范,尤其适合社区医生签约这类需要明确操作反馈的医疗场景;TextInput映射为鸿蒙的TextInput原生控件,保证健康评估结果、慢病管理方案等文本输入在鸿蒙设备上的响应速度和输入体验;Modal组件转换为鸿蒙的Dialog原生模态框,适配鸿蒙系统的弹窗交互逻辑,用于展示健康评估详情、紧急接诊记录等核心医疗信息;Alert则调用鸿蒙的系统级弹窗能力,确保签约成功/失败、信息填写不全等提示的原生展示效果。
此外,应用通过Dimensions.get('window')获取设备屏幕尺寸,该API在鸿蒙系统中会被React Native框架适配为鸿蒙的getWindowSize原生能力,能够精准获取不同形态鸿蒙设备(手机、平板、智慧屏)的屏幕参数——例如在鸿蒙平板上展示完整的慢病管理方案详情,在手机上则呈现精简的签约医生列表,在智慧屏上适配社区医疗中心的大屏展示需求,完美契合基层医疗多终端服务的业务场景。
强类型数据模型:
社区医生签约管理的核心是医疗数据的精准性和业务逻辑的严谨性,代码中通过TypeScript构建了多层级的强类型数据模型,从用户档案、医生信息到健康评估、慢病管理、紧急接诊,形成了闭环的基层医疗数据体系,既规避了前端开发中的类型错误,又在跨端编译阶段拦截了数据格式偏差,适配鸿蒙ArkTS的静态类型特性。
// 用户档案模型:整合基础信息与签约状态,适配签约管理核心需求
type User = {
id: string;
name: string;
age: number; // 数值型年龄,为健康评估提供基础参考
gender: string;
signedDoctor: string | null; // 可空字符串,适配"未签约/已签约"两种状态
};
// 社区医生模型:标准化医生核心信息,适配签约筛选需求
type CommunityDoctor = {
id: string;
name: string;
specialty: string; // 字符串型专长,适配全科/心血管等多科室场景
experience: string; // 字符串型经验,兼容"10年经验"等自然语言描述
rating: number; // 数值型评分,支持跨端数值排序
available: boolean; // 布尔型可用状态,适配签约状态校验
};
// 健康评估模型:对接医生诊疗结果记录
type HealthAssessment = {
id: string;
userId: string;
doctorId: string;
date: string; // 字符串型日期,兼容跨端日期格式
results: string; // 字符串型评估结果,适配医疗文本描述
};
// 慢病管理模型:聚焦病情与管理方案,适配基层慢病管控需求
type ChronicDiseaseManagement = {
id: string;
userId: string;
doctorId: string;
condition: string; // 字符串型病情,兼容糖尿病/高血压等描述
plan: string; // 字符串型管理方案,适配个性化诊疗需求
};
// 紧急接诊模型:优先级设计适配急救场景
type EmergencyAdmission = {
id: string;
userId: string;
doctorId: string;
reason: string; // 字符串型紧急原因,适配胸痛/头晕等症状描述
priority: string; // 字符串型优先级,兼容"高/中/低"分级
};
这些类型定义严格约束了基层医疗数据的格式和类型,在鸿蒙系统中,React Native的TypeScript编译器会对JS层与鸿蒙ArkTS层之间的数据交互进行严格校验。例如,available(医生可用状态)作为布尔类型,在跨端传递时会被强制校验,避免因鸿蒙ArkTS的静态类型特性与JavaScript动态类型特性不兼容导致的签约逻辑错误;signedDoctor采用可空字符串类型,既满足“未签约”的空值场景,又保证了已签约状态下医生ID的精准传递,符合基层医疗签约管理的业务规范。
应用的核心业务逻辑(医生签约、健康评估自动推送、慢病管理方案添加、紧急接诊记录)均基于React Hooks(useState、useEffect)实现,这种轻量级的状态管理方式完美适配React Native的跨端生命周期模型,同时与鸿蒙组件的生命周期深度融合,保障了核心医疗逻辑的跨端稳定运行。
状态设计与不可变更新:
应用通过useState管理核心数据状态,采用“不可变更新”的方式修改状态,避免了引用类型数据在跨端环境下的共享冲突。例如,添加新的健康评估记录时,通过解构赋值创建新数组副本:
setHealthAssessments([...healthAssessments, newAssess]);
这种不可变更新策略在鸿蒙系统中尤为关键——鸿蒙的分布式数据管理要求数据副本的一致性,不可变更新保证了每次状态变更都会生成新的数据源,避免了多端数据同步时的冲突问题,确保社区医生签约记录、健康评估结果在鸿蒙多设备间的同步准确性。
健康评估自动推送:
应用通过useEffect实现每分钟一次的健康评估自动推送,这一核心逻辑在鸿蒙系统中稳定运行的核心在于:setInterval/clearInterval是React Native封装的通用定时器API,已适配鸿蒙的任务调度机制;useEffect的返回清理函数对应鸿蒙组件的onDestroy生命周期,确保定时器在组件卸载时被销毁,避免鸿蒙设备的内存泄漏。
useEffect(() => {
const interval = setInterval(() => {
const randomUser = users[Math.floor(Math.random() * users.length)];
const randomDoctor = communityDoctors[Math.floor(Math.random() * communityDoctors.length)];
const newAssessment: HealthAssessment = {
id: (healthAssessments.length + 1).toString(),
userId: randomUser.id,
doctorId: randomDoctor.id,
date: new Date().toISOString().split('T')[0], // 跨端兼容的日期格式化
results: '健康状况良好,继续保持'
};
setHealthAssessments([...healthAssessments, newAssessment]);
}, 60000);
return () => clearInterval(interval); // 适配鸿蒙组件销毁生命周期
}, [users, communityDoctors, healthAssessments]);
推送逻辑中使用的new Date().toISOString().split('T')[0]是跨端兼容的日期格式化方式,在鸿蒙系统中会被解析为标准的YYYY-MM-DD格式,保证了健康评估日期在不同鸿蒙设备上的展示一致性;数组find/map等方法是ES6通用API,在鸿蒙系统中会被React Native框架转换为ArkTS的数组操作逻辑,避免了因平台API差异导致的评估记录推送错误,符合基层医疗服务的连续性要求。
医生签约状态校验:
handleSignDoctor函数中对医生可用状态(available)的校验是核心业务逻辑,该逻辑在鸿蒙系统中能够稳定运行的关键在于布尔类型的跨端一致性——React Native的布尔值在鸿蒙系统中会被精准映射为ArkTS的布尔类型,确保“可签约/忙碌”状态的校验逻辑无偏差,避免因平台类型转换导致的签约错误,保障基层医疗服务的安全性。
应用的UI层基于React Native的StyleSheet统一管理样式,既保证了鸿蒙系统中的原生渲染效果,又兼顾了社区医生签约管理应用对数据展示清晰性、操作安全性的特殊要求。
样式系统
StyleSheet将CSS样式抽象为跨平台的样式对象,核心样式属性(flex、borderRadius、padding、elevation)在鸿蒙系统中会被精准转换为ArkUI的布局属性。例如:
const styles = StyleSheet.create({
section: {
backgroundColor: '#ffffff',
marginHorizontal: 16,
borderRadius: 12,
padding: 16,
// 阴影跨端适配:elevation适配鸿蒙/Android,shadow系列适配iOS
elevation: 2,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
},
signButton: {
backgroundColor: '#10b981', // 医疗场景专属绿色,适配签约确认按钮
padding: 16,
borderRadius: 12,
alignItems: 'center',
},
input: {
flex: 1,
backgroundColor: '#f0f9ff', // 浅蓝主题,适配医疗应用视觉规范
borderRadius: 8,
paddingHorizontal: 12,
paddingVertical: 8,
fontSize: 14,
color: '#0c4a6e',
}
});
其中,elevation属性在鸿蒙系统中会被解析为原生的阴影层级,borderRadius适配鸿蒙的圆角渲染规则,保证了UI视觉效果的跨端一致性;签约按钮采用医疗场景专属的绿色(#10b981),既符合基层医疗应用的视觉规范,又适配鸿蒙系统的色彩体系,提升了签约操作的辨识度。
基层医疗场景适配
核心交互组件TouchableOpacity在鸿蒙系统中会被渲染为具备原生点击反馈的按钮,选中态的selectedCard样式(边框高亮)能够清晰标识当前选择的用户/医生,符合医疗应用“操作可追溯、状态可识别”的核心要求。用于录入健康评估结果、慢病管理方案的TextInput组件采用双列布局,适配多维度医疗信息的录入,在鸿蒙设备上保证了输入框的响应速度和输入体验,避免因平台输入组件差异导致的医疗信息录入错误。
Modal组件通过animationType="slide"实现滑动弹窗效果,在鸿蒙系统中适配为原生的滑动模态框,用于展示健康评估详情、紧急接诊记录等核心医疗信息,既保证了数据展示的完整性,又符合鸿蒙系统的交互规范,提升了基层医疗服务的操作安全性。
当前代码已实现基础的鸿蒙跨端兼容,在生产环境中,可针对鸿蒙系统的特性和社区医生签约管理的业务需求进行深度优化,进一步提升应用的基层医疗服务能力:
1. 高性能列表渲染
应用中健康评估、慢病管理、紧急接诊等列表采用ScrollView + map的方式渲染,在鸿蒙系统中面对大量基层医疗数据时可能出现卡顿。可替换为React Native的FlatList组件,该组件在鸿蒙系统中会适配ArkUI的List原生组件,实现按需渲染和组件复用,通过getItemLayout优化列表滚动性能,尤其适合展示用户长期的健康评估记录和慢病管理方案。
2. 鸿蒙原生
紧急接诊是基层医疗的核心需求,可通过React Native的Native Module机制封装鸿蒙的NotificationKit和AlarmManager原生API,将紧急接诊记录中的优先级同步到鸿蒙的系统级提醒能力。例如,将EmergencyAdmission中的priority为“高”的记录推送至鸿蒙社区医生端的系统通知,实现跨鸿蒙设备(医生端平板、用户端手机)的紧急接诊提醒同步,充分利用鸿蒙的分布式能力提升基层医疗的急救响应效率。
3. 分布式
基于鸿蒙的分布式数据管理能力,可通过React Native的跨端通信机制,实现社区医生签约数据在多鸿蒙设备间的同步。例如,用户在手机上签约的社区医生信息,可实时同步到鸿蒙平板的医生端和社区医疗中心的智慧屏,医生可通过平板查看签约用户的健康评估记录,社区医护人员可通过智慧屏查看辖区内的紧急接诊需求,形成“用户-医生-社区医疗中心”的闭环管理。
这款基于React Native开发的社区医生签约管理应用,通过强类型数据模型、React Hooks状态管理和通用UI组件设计,构建了具备完整鸿蒙跨端兼容能力的基层医疗应用架构,核心技术要点可总结为:
- 通用API选型是实现鸿蒙兼容的基础,基于React Native通用组件构建核心逻辑,规避平台专属代码,保证了社区医生签约管理UI和交互的跨端一致性;
- TypeScript强类型约束不仅提升基层医疗数据的精准性,更适配鸿蒙ArkTS的静态类型特性,避免跨端数据交互中的类型错误,保障签约状态、健康评估等核心逻辑的准确性;
- React Hooks状态管理与鸿蒙组件生命周期深度融合,保障了健康评估自动推送等周期性任务的跨端稳定运行;
- 统一的StyleSheet样式系统实现了UI在鸿蒙设备上的原生渲染,兼顾社区医生签约管理应用的数据展示清晰性和操作安全性。
在基层医疗领域,社区医生签约服务是实现分级诊疗的重要抓手。本文将深入剖析一个基于 React Native 构建的社区医生签约应用,探讨其技术实现细节及鸿蒙跨端能力的应用。
技术选型
该应用采用了现代 React Native 函数式组件架构,通过 TypeScript 类型系统和 React Hooks 实现了一个功能完整的社区医生签约管理系统。核心技术栈包括:
- React Native:作为跨端开发框架,提供了统一的组件 API,确保应用在 iOS、Android 及鸿蒙平台上的一致性体验
- TypeScript:通过严格的类型定义增强代码可维护性,明确了数据结构和组件接口
- React Hooks:使用 useState 管理应用状态,useEffect 处理副作用逻辑,实现了声明式的状态管理
- Base64 图标:采用 Base64 编码的图标资源,避免了不同平台资源格式的差异,提高了跨端兼容性
- 响应式布局:使用 Dimensions API 获取屏幕尺寸,实现适配不同设备的响应式界面
数据模型
应用通过 TypeScript 接口定义了五个核心数据类型,构建了完整的社区医疗数据模型体系:
// 用户类型
type User = {
id: string;
name: string;
age: number;
gender: string;
signedDoctor: string | null;
};
// 社区医生类型
type CommunityDoctor = {
id: string;
name: string;
specialty: string;
experience: string;
rating: number;
available: boolean;
};
// 健康评估类型
type HealthAssessment = {
id: string;
userId: string;
doctorId: string;
date: string;
results: string;
};
// 慢病管理类型
type ChronicDiseaseManagement = {
id: string;
userId: string;
doctorId: string;
condition: string;
plan: string;
};
// 紧急接诊类型
type EmergencyAdmission = {
id: string;
userId: string;
doctorId: string;
reason: string;
priority: string;
};
这种强类型设计不仅提高了代码可读性,也为鸿蒙跨端适配提供了清晰的数据契约,确保不同平台间数据传递的一致性。数据模型的设计充分考虑了社区医疗的核心要素,包含了用户信息、医生信息、健康评估、慢病管理和紧急接诊等关键数据。
状态管理
应用使用 useState Hook 管理多个复杂状态,包括用户列表、社区医生列表、健康评估、慢病管理和紧急接诊等:
const [users] = useState<User[]>([
{
id: '1',
name: '李先生',
age: 45,
gender: '男',
signedDoctor: null
},
{
id: '2',
name: '王女士',
age: 32,
gender: '女',
signedDoctor: null
}
]);
// 其他状态定义...
特别值得注意的是,应用通过 useEffect 实现了健康评估的自动推送机制:
// 自动推送健康评估
useEffect(() => {
const interval = setInterval(() => {
const randomUser = users[Math.floor(Math.random() * users.length)];
const randomDoctor = communityDoctors[Math.floor(Math.random() * communityDoctors.length)];
const newAssessment: HealthAssessment = {
id: (healthAssessments.length + 1).toString(),
userId: randomUser.id,
doctorId: randomDoctor.id,
date: new Date().toISOString().split('T')[0],
results: '健康状况良好,继续保持'
};
setHealthAssessments([...healthAssessments, newAssessment]);
}, 60000);
return () => clearInterval(interval);
}, [users, communityDoctors, healthAssessments]);
这种基于时间间隔的自动推送机制,模拟了真实场景中社区医生定期为签约居民提供健康评估的过程,为用户提供了持续的健康管理支持。同时,通过 useEffect 的清理函数,确保了定时器在组件卸载时被正确清除,避免了内存泄漏。
在 React Native 鸿蒙跨端开发中,该应用体现了以下关键技术点:
- 组件兼容性:使用 React Native 核心组件(如 SafeAreaView、View、Text、TouchableOpacity、ScrollView、Modal 等),确保在鸿蒙系统上的兼容性
- 资源管理:通过 Base64 编码的图标资源,避免了不同平台资源格式的差异,提高了跨端部署的一致性
- 尺寸适配:使用 Dimensions API 获取屏幕尺寸,实现响应式布局,适应不同设备屏幕
- 状态管理:采用 React Hooks 进行状态管理,保持跨平台代码一致性
- 类型安全:TypeScript 类型定义确保了数据结构在不同平台间的一致性
- API 调用:使用 React Native 统一的 API 调用方式,如 Alert 组件,确保在鸿蒙平台上的正确显示
社区医生签约功能
应用实现了用户与社区医生的签约功能,通过选择用户和医生,完成签约过程:
const handleSignDoctor = () => {
if (selectedUser && selectedDoctor) {
const user = users.find(u => u.id === selectedUser);
const doctor = communityDoctors.find(d => d.id === selectedDoctor);
if (user && doctor && doctor.available) {
const updatedUsers = users.map(u =>
u.id === selectedUser ? { ...u, signedDoctor: selectedDoctor } : u
);
Alert.alert('签约成功', `${user.name}已成功签约${doctor.name}医生`);
} else {
Alert.alert('提示', '该医生不可用或未选择用户和医生');
}
} else {
Alert.alert('提示', '请选择用户和医生');
}
};
健康评估管理
应用提供了健康评估的添加功能,医生可以为签约用户添加健康评估记录:
const handleAddAssessment = () => {
if (newAssessment.date && newAssessment.results && selectedUser && selectedDoctor) {
const newAssess: HealthAssessment = {
id: (healthAssessments.length + 1).toString(),
userId: selectedUser,
doctorId: selectedDoctor,
date: newAssessment.date,
results: newAssessment.results
};
setHealthAssessments([...healthAssessments, newAssess]);
setNewAssessment({ date: '', results: '' });
Alert.alert('添加成功', '新的健康评估已添加');
} else {
Alert.alert('提示', '请选择用户和医生并填写完整的评估信息');
}
};
慢病管理功能
应用实现了慢病管理功能,医生可以为患有慢性疾病的用户添加慢病管理计划。
应用提供了紧急接诊功能,处理用户的紧急医疗需求,根据优先级进行处理。
应用通过定时任务自动推送健康评估,模拟了社区医生定期为签约居民提供健康服务的场景。
应用的 UI 设计遵循了现代移动应用的设计原则,使用了以下组件和交互模式:
- 安全区域:通过 SafeAreaView 确保内容显示在安全区域内,适应不同设备的屏幕刘海和底部指示条
- 滚动视图:通过 ScrollView 实现内容的垂直滚动,适应不同长度的用户列表和医生信息
- 卡片布局:使用 TouchableOpacity 和 View 组合实现卡片式列表项,提供清晰的视觉层次和交互反馈
- 模态框:通过 Modal 组件展示详细信息,如健康评估结果、慢病管理计划等
- 交互反馈:使用 Alert 组件提供操作反馈和提示信息
- 响应式设计:根据屏幕尺寸动态调整布局,确保在不同设备上的良好显示效果
- 跨端架构:基于 React Native 构建,实现了一次编码多平台运行的目标,特别关注了鸿蒙平台的适配
- 类型安全:全面使用 TypeScript 类型定义,提高代码质量和可维护性,确保医疗数据的准确性
- 社区医生签约:实现了用户与社区医生的签约功能,支持分级诊疗的落地
- 多维度健康管理:同时支持健康评估、慢病管理和紧急接诊,提供全面的社区医疗服务
- 自动化服务:通过定时任务自动推送健康评估,模拟了真实的社区医疗服务场景
- 医生可用性管理:通过 available 字段管理医生的可用性,提高服务资源的合理分配
- 模块化设计:通过清晰的类型定义和函数划分,实现了代码的模块化,提高了可维护性
- 实时数据反馈:通过即时的 Alert 反馈,增强用户操作体验
- 数据结构设计:通过关联的数据结构,如健康评估关联用户和医生,实现了复杂医疗数据的有效组织
在实际应用中,还可以考虑以下性能优化策略:
- 状态管理优化:对于大型应用,可以考虑使用 Redux 或 Context API 进行全局状态管理,提高状态更新的效率
- 组件拆分:将大型组件拆分为更小的可复用组件,提高渲染性能和代码可维护性
- 数据缓存:对用户数据和医生信息进行本地缓存,减少重复计算和网络请求
- 动画性能:使用 React Native 的 Animated API 实现流畅的过渡动画,提升用户体验
- 内存管理:确保及时清理不再使用的状态和事件监听器,避免内存泄漏
- 网络优化:对于实际应用中的远程数据同步,实现合理的网络请求策略,如批量上传、增量同步等
- 计算优化:对于健康评估等逻辑,可以考虑使用 memoization 技术缓存计算结果
- 列表优化:对于长列表,使用 FlatList 组件替代 ScrollView,提高渲染性能
在开发过程中,可能面临的技术挑战及解决方案:
- 鸿蒙平台适配:通过使用 React Native 核心组件和统一的 API 调用方式,确保应用在鸿蒙平台上的兼容性
- 数据同步:实现本地数据与云端数据的实时同步,确保多设备数据一致性
- 用户隐私保护:实现医疗数据的加密存储和传输,保护用户隐私
- 离线功能:实现基本的离线操作能力,确保在网络不稳定情况下的正常使用
- 性能优化:针对不同设备性能差异,实现自适应的性能优化策略,确保在中低端设备上的流畅运行
- 用户体验一致性:确保在不同平台上的用户体验一致,特别是交互方式和视觉效果
- 多语言支持:实现多语言支持,满足不同地区用户的需求
- 无障碍访问:确保应用符合无障碍访问标准,方便行动不便的用户使用
通过对这个社区医生签约应用的技术解读,我们可以看到 React Native 在跨端开发中的强大能力。该应用不仅实现了完整的社区医生签约管理功能,还展示了如何通过 TypeScript、React Hooks 等现代前端技术构建高质量的跨端应用。
真实演示案例代码:
// App.tsx
import React, { useState, useEffect } from 'react';
import { SafeAreaView, View, Text, StyleSheet, TouchableOpacity, ScrollView, Dimensions, Alert, TextInput, Modal } from 'react-native';
// Base64 图标库
const ICONS_BASE64 = {
doctor: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
assessment: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
management: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
emergency: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
};
const { width, height } = Dimensions.get('window');
// 用户类型
type User = {
id: string;
name: string;
age: number;
gender: string;
signedDoctor: string | null;
};
// 社区医生类型
type CommunityDoctor = {
id: string;
name: string;
specialty: string;
experience: string;
rating: number;
available: boolean;
};
// 健康评估类型
type HealthAssessment = {
id: string;
userId: string;
doctorId: string;
date: string;
results: string;
};
// 慢病管理类型
type ChronicDiseaseManagement = {
id: string;
userId: string;
doctorId: string;
condition: string;
plan: string;
};
// 紧急接诊类型
type EmergencyAdmission = {
id: string;
userId: string;
doctorId: string;
reason: string;
priority: string;
};
// 社区医生签约应用组件
const CommunityDoctorSigningApp: React.FC = () => {
const [users] = useState<User[]>([
{
id: '1',
name: '李先生',
age: 45,
gender: '男',
signedDoctor: null
},
{
id: '2',
name: '王女士',
age: 32,
gender: '女',
signedDoctor: null
}
]);
const [communityDoctors] = useState<CommunityDoctor[]>([
{
id: '1',
name: '张医生',
specialty: '全科医学',
experience: '10年经验',
rating: 4.8,
available: true
},
{
id: '2',
name: '李医生',
specialty: '心血管内科',
experience: '15年经验',
rating: 4.9,
available: false
}
]);
const [healthAssessments, setHealthAssessments] = useState<HealthAssessment[]>([
{
id: '1',
userId: '1',
doctorId: '1',
date: '2023-12-01',
results: '血压正常,血糖偏高,建议控制饮食'
}
]);
const [chronicDiseaseManagements, setChronicDiseaseManagements] = useState<ChronicDiseaseManagement[]>([
{
id: '1',
userId: '1',
doctorId: '1',
condition: '糖尿病',
plan: '控制饮食,定期监测血糖,按时服药'
}
]);
const [emergencyAdmissions, setEmergencyAdmissions] = useState<EmergencyAdmission[]>([
{
id: '1',
userId: '1',
doctorId: '1',
reason: '突发胸痛',
priority: '高'
}
]);
const [selectedUser, setSelectedUser] = useState<string | null>(null);
const [selectedDoctor, setSelectedDoctor] = useState<string | null>(null);
const [newAssessment, setNewAssessment] = useState({
date: '',
results: ''
});
const [newManagement, setNewManagement] = useState({
condition: '',
plan: ''
});
const [newEmergency, setNewEmergency] = useState({
reason: '',
priority: ''
});
const [isModalVisible, setIsModalVisible] = useState(false);
const [modalContent, setModalContent] = useState('');
// 自动推送健康评估
useEffect(() => {
const interval = setInterval(() => {
const randomUser = users[Math.floor(Math.random() * users.length)];
const randomDoctor = communityDoctors[Math.floor(Math.random() * communityDoctors.length)];
const newAssessment: HealthAssessment = {
id: (healthAssessments.length + 1).toString(),
userId: randomUser.id,
doctorId: randomDoctor.id,
date: new Date().toISOString().split('T')[0],
results: '健康状况良好,继续保持'
};
setHealthAssessments([...healthAssessments, newAssessment]);
}, 60000);
return () => clearInterval(interval);
}, [users, communityDoctors, healthAssessments]);
const handleSelectUser = (userId: string) => {
setSelectedUser(userId);
Alert.alert('选择用户', '您已选择该用户进行社区医生签约');
};
const handleSelectDoctor = (doctorId: string) => {
setSelectedDoctor(doctorId);
Alert.alert('选择医生', '您已选择该社区医生进行签约');
};
const handleSignDoctor = () => {
if (selectedUser && selectedDoctor) {
const user = users.find(u => u.id === selectedUser);
const doctor = communityDoctors.find(d => d.id === selectedDoctor);
if (user && doctor && doctor.available) {
const updatedUsers = users.map(u =>
u.id === selectedUser ? { ...u, signedDoctor: selectedDoctor } : u
);
Alert.alert('签约成功', `${user.name}已成功签约${doctor.name}医生`);
} else {
Alert.alert('提示', '该医生不可用或未选择用户和医生');
}
} else {
Alert.alert('提示', '请选择用户和医生');
}
};
const handleAddAssessment = () => {
if (newAssessment.date && newAssessment.results && selectedUser && selectedDoctor) {
const newAssess: HealthAssessment = {
id: (healthAssessments.length + 1).toString(),
userId: selectedUser,
doctorId: selectedDoctor,
date: newAssessment.date,
results: newAssessment.results
};
setHealthAssessments([...healthAssessments, newAssess]);
setNewAssessment({ date: '', results: '' });
Alert.alert('添加成功', '新的健康评估已添加');
} else {
Alert.alert('提示', '请选择用户和医生并填写完整的评估信息');
}
};
const handleAddManagement = () => {
if (newManagement.condition && newManagement.plan && selectedUser && selectedDoctor) {
const newManage: ChronicDiseaseManagement = {
id: (chronicDiseaseManagements.length + 1).toString(),
userId: selectedUser,
doctorId: selectedDoctor,
condition: newManagement.condition,
plan: newManagement.plan
};
setChronicDiseaseManagements([...chronicDiseaseManagements, newManage]);
setNewManagement({ condition: '', plan: '' });
Alert.alert('添加成功', '新的慢病管理方案已添加');
} else {
Alert.alert('提示', '请选择用户和医生并填写完整的管理信息');
}
};
const handleAddEmergency = () => {
if (newEmergency.reason && newEmergency.priority && selectedUser && selectedDoctor) {
const newEmerg: EmergencyAdmission = {
id: (emergencyAdmissions.length + 1).toString(),
userId: selectedUser,
doctorId: selectedDoctor,
reason: newEmergency.reason,
priority: newEmergency.priority
};
setEmergencyAdmissions([...emergencyAdmissions, newEmerg]);
setNewEmergency({ reason: '', priority: '' });
Alert.alert('添加成功', '新的紧急接诊记录已添加');
} else {
Alert.alert('提示', '请选择用户和医生并填写完整的紧急信息');
}
};
const handleViewAssessment = (assessmentId: string) => {
const assessment = healthAssessments.find(a => a.id === assessmentId);
if (assessment) {
const user = users.find(u => u.id === assessment.userId);
const doctor = communityDoctors.find(d => d.id === assessment.doctorId);
setModalContent(`用户: ${user?.name}\n医生: ${doctor?.name}\n日期: ${assessment.date}\n结果: ${assessment.results}`);
setIsModalVisible(true);
}
};
const handleViewManagement = (managementId: string) => {
const management = chronicDiseaseManagements.find(m => m.id === managementId);
if (management) {
const user = users.find(u => u.id === management.userId);
const doctor = communityDoctors.find(d => d.id === management.doctorId);
setModalContent(`用户: ${user?.name}\n医生: ${doctor?.name}\n病情: ${management.condition}\n管理方案: ${management.plan}`);
setIsModalVisible(true);
}
};
const handleViewEmergency = (emergencyId: string) => {
const emergency = emergencyAdmissions.find(e => e.id === emergencyId);
if (emergency) {
const user = users.find(u => u.id === emergency.userId);
const doctor = communityDoctors.find(d => d.id === emergency.doctorId);
setModalContent(`用户: ${user?.name}\n医生: ${doctor?.name}\n原因: ${emergency.reason}\n优先级: ${emergency.priority}`);
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.age}</Text>
<Text style={styles.cardDescription}>性别: {user.gender}</Text>
<Text style={styles.cardDescription}>签约医生: {user.signedDoctor ? communityDoctors.find(d => d.id === user.signedDoctor)?.name : '未签约'}</Text>
</View>
</TouchableOpacity>
))}
</View>
{/* 社区医生列表 */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>社区医生列表</Text>
{communityDoctors.map(doctor => (
<TouchableOpacity
key={doctor.id}
style={[
styles.card,
selectedDoctor === doctor.id && styles.selectedCard
]}
onPress={() => handleSelectDoctor(doctor.id)}
>
<Text style={styles.icon}>👨⚕️</Text>
<View style={styles.cardInfo}>
<Text style={styles.cardTitle}>{doctor.name}</Text>
<Text style={styles.cardDescription}>专长: {doctor.specialty}</Text>
<Text style={styles.cardDescription}>经验: {doctor.experience}</Text>
<Text style={styles.cardDescription}>评分: {doctor.rating}</Text>
<Text style={styles.cardDescription}>状态: {doctor.available ? '可签约' : '忙碌'}</Text>
</View>
</TouchableOpacity>
))}
<TouchableOpacity
style={styles.signButton}
onPress={handleSignDoctor}
>
<Text style={styles.signText}>签约医生</Text>
</TouchableOpacity>
</View>
{/* 健康评估 */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>健康评估</Text>
<View style={styles.inputRow}>
<TextInput
style={styles.input}
placeholder="评估日期 (YYYY-MM-DD)"
value={newAssessment.date}
onChangeText={(text) => setNewAssessment({ ...newAssessment, date: text })}
/>
<TextInput
style={styles.input}
placeholder="评估结果"
value={newAssessment.results}
onChangeText={(text) => setNewAssessment({ ...newAssessment, results: text })}
/>
</View>
<TouchableOpacity
style={styles.addButton}
onPress={handleAddAssessment}
>
<Text style={styles.addText}>添加评估</Text>
</TouchableOpacity>
{healthAssessments.map(assessment => (
<TouchableOpacity
key={assessment.id}
style={styles.assessmentCard}
onPress={() => handleViewAssessment(assessment.id)}
>
<Text style={styles.icon}>📊</Text>
<View style={styles.cardInfo}>
<Text style={styles.cardTitle}>评估ID: {assessment.id}</Text>
<Text style={styles.cardDescription}>日期: {assessment.date}</Text>
<Text style={styles.cardDescription}>结果: {assessment.results}</Text>
</View>
</TouchableOpacity>
))}
</View>
{/* 慢病管理 */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>慢病管理</Text>
<View style={styles.inputRow}>
<TextInput
style={styles.input}
placeholder="病情"
value={newManagement.condition}
onChangeText={(text) => setNewManagement({ ...newManagement, condition: text })}
/>
<TextInput
style={styles.input}
placeholder="管理方案"
value={newManagement.plan}
onChangeText={(text) => setNewManagement({ ...newManagement, plan: text })}
/>
</View>
<TouchableOpacity
style={styles.addButton}
onPress={handleAddManagement}
>
<Text style={styles.addText}>添加管理方案</Text>
</TouchableOpacity>
{chronicDiseaseManagements.map(management => (
<TouchableOpacity
key={management.id}
style={styles.managementCard}
onPress={() => handleViewManagement(management.id)}
>
<Text style={styles.icon}>📝</Text>
<View style={styles.cardInfo}>
<Text style={styles.cardTitle}>管理ID: {management.id}</Text>
<Text style={styles.cardDescription}>病情: {management.condition}</Text>
<Text style={styles.cardDescription}>方案: {management.plan}</Text>
</View>
</TouchableOpacity>
))}
</View>
{/* 紧急接诊 */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>紧急接诊</Text>
<View style={styles.inputRow}>
<TextInput
style={styles.input}
placeholder="紧急原因"
value={newEmergency.reason}
onChangeText={(text) => setNewEmergency({ ...newEmergency, reason: text })}
/>
<TextInput
style={styles.input}
placeholder="优先级"
value={newEmergency.priority}
onChangeText={(text) => setNewEmergency({ ...newEmergency, priority: text })}
/>
</View>
<TouchableOpacity
style={styles.addButton}
onPress={handleAddEmergency}
>
<Text style={styles.addText}>添加紧急记录</Text>
</TouchableOpacity>
{emergencyAdmissions.map(emergency => (
<TouchableOpacity
key={emergency.id}
style={styles.emergencyCard}
onPress={() => handleViewEmergency(emergency.id)}
>
<Text style={styles.icon}>🚨</Text>
<View style={styles.cardInfo}>
<Text style={styles.cardTitle}>紧急ID: {emergency.id}</Text>
<Text style={styles.cardDescription}>原因: {emergency.reason}</Text>
<Text style={styles.cardDescription}>优先级: {emergency.priority}</Text>
</View>
</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',
},
assessmentCard: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#f0f9ff',
borderRadius: 12,
padding: 16,
marginBottom: 12,
},
managementCard: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: '#f0f9ff',
borderRadius: 12,
padding: 16,
marginBottom: 12,
},
emergencyCard: {
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',
},
signButton: {
backgroundColor: '#10b981',
padding: 16,
borderRadius: 12,
alignItems: 'center',
},
signText: {
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 CommunityDoctorSigningApp;

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

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

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

本文探讨了基于React Native开发的社区医生签约管理应用如何适配鸿蒙系统。应用采用React Native通用组件与Hooks体系构建,通过TypeScript强类型数据模型确保医疗数据精准性,并利用StyleSheet实现跨平台UI适配。核心功能如医生签约状态校验、健康评估自动推送等采用不可变更新策略,保障了在鸿蒙多设备间的数据同步稳定性。该架构充分发挥了React Native"一次开发、多端运行"的优势,同时完美兼容鸿蒙系统的分布式特性,为基层医疗数字化转型提供了高效可靠的跨端解决方案。
欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。
更多推荐


所有评论(0)