4. 医生端工作台前端工程选型与架构

医生端工作台是临床业务的“主入口”,它同时承担患者列表、病历摘要、医嘱开立、检验检查结果、会诊与消息提醒等高频任务。前端技术选型一旦确定,后续三到五年的迭代成本、交付速度与稳定性都会受其约束。因此,本章不讨论“哪个框架更流行”,而是围绕医生端工作台的真实约束,对比 Web、桌面跨端、原生与混合四类方案,并给出可落地的技术栈与模块化架构。

一、先明确选型的约束条件

医生端工作台与普通互联网产品最大的差异在于:运行环境受控、外设依赖强、数据敏感度高、交互密度大。典型约束包括:

  • 外设与系统能力:读卡器、扫码枪、打印机、CA 签名 UKey、DICOM 影像控件、语音输入等,往往需要访问本地串口、USB 或系统 API。
  • 网络与部署:院内网多为隔离环境,无法依赖公网 CDN;版本发布需走内网灰度,回滚窗口短。
  • 性能与稳定性:门诊高峰期单医生可能同时打开 10 个以上患者标签页,长列表、影像缩略图、实时消息推送并存,内存与渲染压力大。
  • 合规与审计:操作留痕、会话超时、屏幕水印、数据不落地等要求,直接影响前端存储与缓存策略。
  • 多端一致性:医生可能在诊室工作站、护士站大屏、平板查房、手机端之间切换,业务逻辑需要复用。

这些约束决定了选型不能只看开发效率,还要看本地能力接入成本、部署可控性、长期维护成本三个维度。

二、四类方案对比

纯 Web 方案(浏览器访问)部署最轻,跨平台天然支持,迭代最快。但浏览器沙箱限制了本地外设访问,读卡器、签名 UKey 通常需要额外安装本地服务或浏览器插件,影像控件体验也受限。适合以“查看、录入、轻交互”为主的工作台,或作为多端统一入口。

桌面跨端方案(Electron、Tauri、Flutter Desktop 等)用 Web 技术栈开发,但打包为桌面应用,可直接调用 Node/Rust 侧能力访问串口、文件系统与系统 API,同时保留前端生态。代价是安装包体积、内存占用与自动更新机制需要额外设计。对于需要读卡、打印、签名的诊室工作站,这是当前较均衡的选择。

原生方案(Windows WPF/WinUI、macOS SwiftUI)对系统能力与性能控制最好,适合影像工作站、手术室等重交互场景。但开发成本高、跨平台复用差、前端人才储备少,通常只在特定科室或特定模块使用。

混合方案是实践中常见的折中:外壳用桌面跨端承载外设与系统能力,核心业务页面用 Web 技术实现,通过统一路由与状态管理复用;移动端则用同一套 Web 组件适配。它避免了“全原生重写”,也避免了“纯 Web 无法接外设”的困境。

医生端工作台前端方案对比与分层架构 纯 Web 部署:浏览器直访,最轻 外设:需本地服务/插件 性能:长列表需虚拟滚动 适用:查看、录入、轻交互 短板:UKey/读卡器接入弱 桌面跨端 部署:安装包+自动更新 外设:Node/Rust 直连 性能:可控,内存偏高 适用:诊室工作站主力 短板:包体与更新需设计 原生 部署:按平台分发 外设:系统 API 最完整 性能:最优 适用:影像/手术重交互 短板:成本高、复用差 混合(推荐) 外壳:桌面跨端接外设 页面:Web 组件复用 移动:同组件适配 适用:多端统一工作台 优势:兼顾外设与迭代 工作台前端分层架构 应用层 诊室工作台 · 查房平板 · 护士站大屏 · 移动端(同一路由与权限模型) 业务模块层 患者列表 · 病历摘要 · 医嘱开立 · 检验检查 · 会诊 · 消息中心(按需加载) 共享能力层 状态管理 · 请求封装 · 权限指令 · 埋点审计 · 主题与水印 · 虚拟列表 桥接层 外设 SDK(读卡器/UKey/打印)· 本地缓存 · 离线队列 · 版本与灰度通道 选型结论:以桌面跨端为外壳、Web 组件为业务主体、桥接层统一外设接入

三、推荐技术栈与模块化架构

结合上述对比,医生端工作台推荐采用“桌面跨端外壳 + Web 业务内核 + 桥接层”的混合架构。具体技术栈示例(可按团队情况替换):

  • 外壳:Tauri 或 Electron,负责窗口管理、自动更新、外设进程通信与系统托盘。
  • 前端框架:React 18 + TypeScript,配合 Vite 构建,保证类型安全与热更新效率。
  • 状态与数据:Zustand 管理全局会话与患者上下文,TanStack Query 管理服务端状态与缓存失效。
  • UI 与交互:组件库统一表单、表格、弹窗;长列表使用虚拟滚动;影像缩略图懒加载。
  • 桥接层:定义统一的 NativeBridge 接口,Web 侧只调用抽象方法,由外壳注入具体实现。

模块化架构的关键是按业务域拆分,而不是按技术类型拆分。每个业务模块(如“医嘱开立”)内部包含自己的页面、组件、状态、API 与类型定义,对外只暴露一个入口。这样模块可以独立开发、独立测试,也便于后续按科室裁剪功能。

src/
├─ app/                 # 应用入口、路由、权限守卫
├─ modules/
│  ├─ patient-list/     # 患者列表:页面、store、api、types
│  ├─ record-summary/   # 病历摘要
│  ├─ order-entry/      # 医嘱开立
│  └─ message-center/   # 消息中心
├─ shared/
│  ├─ bridge/           # NativeBridge 抽象与 Web 实现
│  ├─ request/          # 请求封装、重试、审计埋点
│  ├─ auth/             # 会话、超时、水印
│  └─ ui/               # 通用组件
└─ platform/            # 外壳适配:Tauri/Electron 注入

四、落地时的关键判断

选型不是一次性决策,而是随场景演进的。实际落地时可用三个问题快速判断:是否需要直接访问本地外设?若是,纯 Web 需加本地服务,桌面跨端更直接。是否需要多端一致?若是,业务逻辑必须与渲染层解耦,优先 Web 组件。是否有重交互模块?如影像阅片,可单独用原生或专用控件嵌入,而不是让整个工作台背负重成本。

建议在项目初期就定义好 NativeBridge 接口,即使第一版只用 Web 实现。这样后续从纯 Web 迁移到桌面跨端时,业务代码几乎不需要改动,只需替换桥接实现。
不要把“跨端”理解为“一套代码跑所有端”。医生端工作台更现实的目标是业务逻辑与状态复用、渲染层按端适配。强行追求 100% 代码复用,往往会在外设接入和交互体验上付出更大代价。

综上,医生端工作台的前端选型应围绕“外设接入、部署可控、多端复用、长期维护”四个维度权衡。对多数医院场景,混合方案在成本与能力之间取得了较好的平衡;而模块化架构则决定了这套技术栈能否在后续版本中持续演进,而不是在第三个迭代周期就变成难以维护的单体页面。