体检报告解读 —— AI 赋能健康管理,鸿蒙原生应用深度解析

一、引言

在快节奏的现代生活中,健康管理成为每个人不可忽视的课题。每年体检后,面对密密麻麻的化验单——总胆固醇、低密度脂蛋白、谷丙转氨酶、空腹血糖……这些专业术语往往让人一头雾水。体检报告解读 这款鸿蒙原生 AI 应用,正是为解决这一痛点而生:用户只需粘贴化验单文本,选择关注项(血脂/血糖/肝功/肾功/血常规/全部),AI 即可自动识别异常指标,给出含义解读、生活建议和就医提示。

本文将从应用架构设计、鸿蒙技术深度解析、AI 应用亮点、技术挑战与解决方案、用户体验设计五个维度,全面复盘这款应用的开发实践。

在这里插入图片描述

二、应用架构设计

2.1 整体架构

体检报告解读采用经典的 MVS(Model-View-Service)架构,这是鸿蒙 ArkTS 开发中推荐的轻量级分层模式:

  • Model 层(HealthReportModel.ets):定义数据模型,包括 AbnormalEntry(异常指标条目)、HealthData(解读结果)、HRMessage(消息记录)以及常量配置(关注项数组、欢迎语)。
  • View 层(HealthReportPage.ets):基于 @Component 装饰器的声明式 UI,负责用户交互和结果展示,通过 @State 管理响应式数据。
  • Service 层(HealthReportService.ets):封装 AI 解读逻辑,接收原始化验单文本和关注项,返回结构化的解读数据。
┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   View Layer     │────▶│   Service Layer  │────▶│   Model Layer    │
│ (HealthReport    │     │ (HealthReport    │     │ (HealthReport    │
│   Page.ets)      │◀────│   Service.ets)   │◀────│   Model.ets)     │
└─────────────────┘     └─────────────────┘     └─────────────────┘
       │                       │
       │ @State 驱动UI          │ 返回 HealthData
       │ 用户交互                │ 处理业务逻辑
       └───────────────────────┘

2.2 数据流设计

应用的数据流遵循单向流动原则:

  1. 用户在 TextArea 中输入化验单文本,@State bigText 随之更新
  2. 用户在 Flex 多选区域点击关注项,@State selectedFocus 更新
  3. 点击"开始解读"按钮后,调用 service.getHealthReport() 方法
  4. Service 层处理文本并返回 HealthData 对象
  5. @State currentData 更新,触发 UI 重新渲染
  6. 结果通过 Scroll 容器中的 @Builder 卡片展示

三、鸿蒙技术深度解析

3.1 @State 声明式响应式状态管理

在鸿蒙 ArkTS 中,@State 是最核心的装饰器之一,用于标记组件的内部状态。当状态变化时,系统自动重新渲染相关 UI 部分,无需手动操作 DOM。

@State messages: HRMessage[] = []
@State bigText: string = ''
@State selectedFocus: string = ''
@State currentData: HealthData | null = null
@State isLoading: boolean = false

设计亮点

  • 细粒度响应:每个 @State 变量独立管理,bigText 的变化仅触发 TextArea 区域的重新渲染,不会影响其他 UI 部分,保证了性能。
  • 空值安全currentData 声明为 HealthData | null,在结果未生成时为 null,UI 通过 if (this.currentData !== null) 进行条件渲染,避免了空指针异常。
  • 加载状态isLoading 用于控制加载动画的显示,用户在等待 AI 处理时获得明确的视觉反馈。

3.2 @Builder 声明式 UI 组件复用

@Builder 是鸿蒙 ArkTS 提供的自定义构建函数装饰器,允许开发者将重复的 UI 片段封装为可复用的构建块。

@Builder
buildSection(title: string, items: string[], selected: string, onClick: (item: string) => void) {
  Column() {
    Row() {
      Text(title).fontSize(14).fontColor(COLOR_TEXT_SEC)
      Blank()
    }
    .width('100%')
    .padding({ left: 16, top: 8 })

    Flex({ wrap: FlexWrap.Wrap, justifyContent: FlexAlign.Start }) {
      ForEach(items, (item: string) => {
        Text(item)
          .fontSize(14)
          .fontWeight(selected === item ? FontWeight.Bold : FontWeight.Normal)
          .fontColor(selected === item ? COLOR_PRIMARY : COLOR_TEXT)
          .padding({ left: 14, right: 14, top: 8, bottom: 8 })
          .backgroundColor(selected === item ? '#FEE2E2' : COLOR_CARD)
          .borderRadius(16)
          .border({ width: 1, color: selected === item ? COLOR_PRIMARY : COLOR_BORDER })
          .margin({ right: 8, bottom: 8 })
          .onClick(() => { onClick(item) })
      })
    }
    .width('100%')
    .padding({ left: 16, right: 16, top: 8, bottom: 4 })
  }
}

设计亮点

  • 参数化组件buildSection 接收 title(标题)、items(选项数组)、selected(当前选中项)和 onClick(点击回调)四个参数,形成高度通用的多选组件,可在多个应用中复用。
  • 选中态视觉反馈:通过比较 selected === item 动态切换字体权重、颜色、背景色和边框颜色,提供清晰的选中/未选中状态区分。
  • 函数式回调:使用回调函数而非事件冒泡,保持了组件的纯粹性和可测试性。

3.3 Flex + ForEach 实现响应式多选布局

Flex({ wrap: FlexWrap.Wrap, justifyContent: FlexAlign.Start }) {
  ForEach(items, (item: string) => {
    // 每个选项的 Text 组件
  })
}

技术要点

  • FlexWrap.Wrap:当选项过多时自动换行,适配不同屏幕宽度,无需手动计算布局。
  • FlexAlign.Start:选项左对齐排列,符合阅读习惯。
  • ForEach 列表渲染:基于数据数组动态生成 UI 组件,当数据变化时只更新变更的部分。

3.4 TextArea 大文本输入与 Scroll 滚动容器

TextArea({ text: this.bigText, placeholder: '粘贴体检报告/化验单文本...' })
  .height(120)
  .fontSize(14)
  .onChange((val: string) => { this.bigText = val })

// 结果区域使用 Scroll 包裹
Scroll() {
  Column() {
    this.buildResultCard(this.currentData)
  }
  .padding({ bottom: 20 })
}
.layoutWeight(1)
.scrollBar(BarState.Off)

技术要点

  • TextArea:鸿蒙原生多行文本输入组件,支持 placeholder、自定义样式和 onChange 回调,适合大文本粘贴场景。
  • Scroll:当解读结果超出屏幕高度时自动滚动,.scrollBar(BarState.Off) 隐藏滚动条,保持界面简洁美观。
  • layoutWeight(1):让 Scroll 占据剩余所有可用空间,适配不同屏幕高度。

3.5 @Builder 异常指标卡片(颜色编码)

解读结果是应用的核心输出,采用了颜色编码的卡片式设计:

@Builder
buildResultCard(data: HealthData) {
  Column() {
    // 异常指标卡片 - 红色标题
    if (data.abnormal.length > 0) {
      Column() {
        Text('⚠️ 异常指标')
          .fontSize(14)
          .fontWeight(FontWeight.Bold)
          .fontColor(COLOR_PRIMARY)  // #EF4444 红色
        // 每个异常条目使用 ForEach 渲染
        ForEach(data.abnormal, (entry: AbnormalEntry) => {
          Column() {
            Text(entry.item).fontSize(15).fontWeight(FontWeight.Bold)
            Text(entry.value).fontColor(COLOR_PRIMARY)
            Text(entry.meaning).fontColor(COLOR_TEXT_SEC)
            Text('💡 ' + entry.advice).fontColor('#16A34A')  // 绿色建议
          }
          .backgroundColor('#FEF2F2')  // 浅红背景
          .borderRadius(12)
          .margin({ bottom: 8 })
        })
      }
    }

    // 就医提示卡片 - 深红色
    if (data.warning !== '') {
      Column() {
        Text('🚨 就医提示')
          .fontSize(14)
          .fontWeight(FontWeight.Bold)
          .fontColor('#DC2626')
        Text(data.warning)
      }
      .backgroundColor('#FFF5F5')
      .border({ width: 1, color: '#FECACA' })
    }
  }
}

颜色编码体系

卡片类型 标题颜色 背景色 语义
异常指标 #EF4444 红 #FEF2F2 浅红 需要关注的异常值
生活建议 #16A34A 绿 无特殊背景 可执行的改善建议
就医提示 #DC2626 深红 #FFF5F5 浅粉 需要立即就医的警告

这种颜色编码使得用户即使不阅读全文,也能通过颜色快速感知健康风险的严重程度。

四、AI 应用亮点分析

4.1 6 种关注项深度解析

应用支持 血脂、血糖、肝功、肾功、血常规、全部 6 种关注项的选择,每种关注项对应不同的指标解读逻辑:

  • 血脂:总胆固醇、低密度脂蛋白、甘油三酯,聚焦心血管风险
  • 血糖:空腹血糖、糖化血红蛋白,聚焦糖尿病风险
  • 肝功:谷丙转氨酶、谷草转氨酶,聚焦肝细胞损伤
  • 肾功:肌酐、尿酸,聚焦肾功能和痛风风险
  • 血常规:血红蛋白、白细胞,聚焦贫血和感染
  • 全部:综合所有指标,提供全面分析

每种关注项的解读包含 3 个层次:

  1. 异常值提示:标注具体数值和参考范围
  2. 临床含义:解释该指标升高/降低的病理意义
  3. 生活建议:从饮食、运动、作息等方面给出可执行的改善方案

4.2 异常指标自动识别

AI 引擎自动解析化验单文本,提取关键指标和数值,与正常参考范围比对,自动标记异常项。异常项展示包括:

  • 指标名称(如"总胆固醇(TC)")
  • 当前值 + 趋势箭头(如"6.8 mmol/L ↑")
  • 参考范围(如"参考范围 3.1-5.7 mmol/L")
  • 异常含义解读

4.3 生活建议 + 就医提示分级

应用根据异常严重程度提供分级建议:

级别 适用场景 内容
💡 生活建议 轻度异常 饮食调整、运动建议、生活习惯改善
🚨 就医提示 显著异常 建议就诊科室、推荐检查项目、明确就医时限

例如,当总胆固醇 6.8 mmol/L(轻度升高)时,建议"减少饱和脂肪摄入,增加有氧运动";当空腹血糖 7.2 mmol/L(已达糖尿病诊断阈值)时,建议"尽快到内分泌科就诊"。

五、关键技术挑战与解决方案

5.1 挑战一:大文本解析与结构化输出

问题:化验单文本格式不统一,不同医院的报告格式差异大,直接解析困难。

解决方案:Service 层采用模拟 AI 引擎(真实场景可对接大模型 API),通过关注项 intelligent routing 实现结构化输出。每个关注项对应一套完整的解读方案,包括异常条目、含义和建议。

5.2 挑战二:多条件输入的时序控制

问题:用户可能先选择关注项再输入文本,或反之。需要在两个条件都满足时才能触发"开始解读"按钮。

解决方案:使用组合条件判断:

if (this.bigText !== '' && this.selectedFocus !== '') {
  Text('开始解读')
    // ...按钮样式
    .onClick(() => { this.onGenerate() })
}

只有当 bigText 非空且 selectedFocus 已选择时,按钮才可点击。这种显式条件渲染比传统的 disable 方式更加直观。

5.3 挑战三:消息对话历史的维护

问题:用户可能进行多次解读,需要维护对话上下文。

解决方案:使用 messages: HRMessage[] 数组记录完整的对话历史,每次生成结果时添加新的消息条目,支持重置功能清空历史。

六、用户体验设计

6.1 视觉设计

  • 温暖色系:以浅红 (#FEF2F2) 为主背景色,传达健康关怀的温暖感
  • 卡片化布局:所有信息模块采用圆角卡片设计,视觉层级分明
  • Emoji 辅助:使用 🩺、⚠️、🚨、💡 等 emoji 增强信息辨识度

6.2 交互反馈

  • 即时反馈:点击"开始解读"后立即显示"🔬 正在解读报告……"加载提示
  • 模拟延迟:使用 setTimeout 模拟 AI 处理延迟(1500ms),避免界面突变
  • 重置功能:头部导航栏提供"重置"按钮,一键清空所有已输入内容

6.3 无障碍设计

  • 字体大小适中(12-20px),可读性强
  • 颜色对比度高,红/绿/白配色清晰
  • 交互区域(按钮、选项)尺寸足够大,便于触控操作

七、总结

体检报告解读 应用通过鸿蒙原生技术栈的深度运用,实现了一款实用的 AI 健康助手。从技术角度看,@State 响应式状态管理确保了 UI 与数据的同步更新,@Builder 组件复用模式提升了代码的可维护性,Flex + ForEach + Scroll 的组合构建了流畅的交互体验。从 AI 角度看,6 种关注项精细划分、异常指标自动识别、分级建议机制,体现了 AI 在健康管理领域的实用价值。

这款应用的核心价值在于:将专业医疗知识转化为普通人可理解的健康建议。它不仅仅是一个工具,更是一个"AI 健康顾问"的雏形。未来,随着大模型的接入和更多医疗知识的积累,这类应用将为用户的日常健康管理提供更有力的支持。


技术栈:HarmonyOS ArkTS · 声明式 UI · @State · @Builder · TextArea · Flex · ForEach · Scroll · router

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐