破局 EMR 痛点:如何化解“护理记录跨页”与“A4物理打印”的架构冲突

1. 背景与痛点:跨越"查询区间"的黑洞效应

在医疗信息化(EMR)的前端开发中,"护理记录单"受制于极度严格的病案归档和物理打印规范(A4标准分页)

为了保证打在 A4 纸上的内容不超高,后端会实行"物理切割":当一条长记录在第 5 页底部装不下时,后端会将其"腰斩",把溢出的部分打上"虚拟行"标记,塞进第 6 页的顶部。

如果在同一个查询区间内(比如一次性查询了 1-10 页),这种切断并不可怕 ,前端完全可以把它们拼起来。但真正的灾难发生在我们 跨"查询区间边界" 的时候。

为了前端性能,通常采用步长为 5 或 10 的区间分页查询(如先查 1-5 页,再翻查 6-10 页)。此时,边界断层带来了两大灾难:

  • 无头悬案(首边界断层):当护士翻到第 6-10 页区间时,第 6 页的第一条可能恰好是个被腰斩的"下半截"。因为它的"头"在第 5 页(未被请求),导致这条记录在 UI 上失去了日期、时间和签名,就像一条幽灵数据。
  • 吃数据的黑洞(尾边界断层):当护士在第 5 页(1-5区间的尾部)录入了一大段病情,点击保存后,因为超长被后端切到了第 6 页。由于护士当前还在 1-5 页的视图里,超出的一半直接"凭空消失"(掉出了查询范围),引发极大的数据安全恐慌。

如何在 "保障物理 A4 分页绝对严谨" 的前提下,解决这种跨查询区间的视觉断层?我们经历了两轮核心架构的演进。


2. 演进一:突破区间思维,引入"相邻页双向边界缝合"

既然断层发生在查询区间的两端,我们就不能局限于当前获取到的数据。在表格的核心控制器中,我们实现了 "双向边界缝合算法"

算法核心
  1. 向上找头(突破首边界) :拦截当前查询范围(如 6-10 页)的第一条记录,一旦探测到它是个"虚拟行"且当前数据集里找不到它的主行,系统会静默发起向上一区间边界(第 5 页)的请求,把被隔断的"头"抓取过来,在前端内存中进行完整拼接。

  2. 向下找尾(追踪尾边界):如果当前区间(如 1-5 页)的最后一条记录未能闭合(数据溢出到了第 6 页),系统会自动向下一区间的起步页(第 6 页甚至第 7 页)发起递归追踪请求。

    在此过程中,MAX_EXTRA_PAGES = 3 这道保险丝一直稳稳地插在那里。不过,它的机制非常精妙,并不是简单粗暴地"超过3页就不找了",而是采用了一种 "平滑降级(Graceful Degradation)" 策略来兼顾"消除视觉盲区"与"系统性能保护":

    • 第 1 ~ 3 页(正常消除盲区) :如果跨界追踪发生在 3 页以内,系统不仅会把被截断的尾巴拿过来,还会顺手把这几页里其他的正常记录也一并追加进来显示给护士看。这也就是消除由于跨查询范围导致的视觉盲区。
    • 超过 3 页(触发降级熔断) :如果某个护士写了一篇"几千字的小作文",导致这条记录的残躯断臂连续蔓延了 4 页、5 页甚至 10 页。此时如果系统还一整页一整页地往内存里塞所有数据,浏览器就会因为 DOM 节点过多而卡死。一旦触发 MAX_EXTRA_PAGES = 3 熔断,循环依然会继续(以保证小作文的完整性),但策略突变 :系统不再追加后面的整页数据,而是变成了一把"手术刀",精准地只从后续页面中剔出属于这条巨长记录的那个残肢(虚拟行)拼接回来,抛弃其他无关记录。

    通过这套机制,既保证了在 99% 的日常跨页场景中护士享有极佳的无盲区体验,又在 1% 的极端病历数据面前守住了前端崩溃的底线,可谓 "进可攻、退可守"

  3. UX 降维打击(Auto-Jump):针对"填完消失"的黑洞效应,我们在保存拦截器中加入特征比对。一旦发现刚填写的记录溢出到了当前查询范围之外,系统直接触发跳转,提示护士"记录跨越了当前页码,已自动为您跳转至下一区间",护士的视线可以无缝跟随数据流动。

至此,无论区间怎么切,护士在屏幕上看到的始终是一幅没有盲区、严丝合缝的连续长卷。


3. 演进二:深水区危机,UI 状态与物理打印的彻底解耦

然而,当我们用跨区间缝合技术提供了完美的 UI 体验时,迎来了最致命的考验------打印

为了消除视觉盲区,我们在前端内存里把第 5 页和第 6 页跨界切断的半截记录"缝"成了一条完美的数据(recordData)。当我们直接把这份数据喂给打印引擎时:

  • 打印机会在第 5 页末尾打印了一遍这行长记录;
  • 翻到第 6 页,又把这行被拼接出的记录打了一遍(造成重复)。
  • 更糟的是,缝合后的数据改变了原有的物理行高,导致基于浏览器的打印引擎算错高度,挤出了毫无意义的空白尾页。

痛点结论:为了取悦人眼而消除边界的 UI 状态,变成了严格物理分页打印机的毒药。

终极解法:数据分流与绝对服从

我们对数据流控进行了彻底的重构,确立了两大架构铁律:

铁律一:UI 状态与打印状态必须解耦

fetchRecordContent 函数执行任何"跨区间边界缝合"动作之前,直接通过 JSON.parse(JSON.stringify(records)) 将后端原汁原味的、带着原始断层标记的物理数据拦截并克隆一份,专门赋值给 rawRecordData

从此,屏幕展示走 recordData(被缝合的连续流),物理打印走 rawRecordData(保持原始物理切割的断层流),两者平行,互不干涉。

铁律二:前端打印引擎对后端的绝对服从

重写基于浏览器的 PrintEngine 分页算法。废弃前端"计算物理行数除以 16 强行分页"的做法。强制打印引擎扫描 rawRecordData 中由后端下发的 _pageNum 物理边界字段。

后端说这是第 5 页的数据,前端就只往第 5 页的 A4 纸容器里渲染;严禁前端自作主张做跨页溢流计算。就连页脚打印的"第 X 页",也严格取自后端的真实边界值。


4. 总结与启示

经过这两次重构,这套架构实现了真正意义上的"鱼和熊掌兼得":

  • 在屏幕前,护士享受着突破查询区间的现代 Web 连续录入体验;
  • 在病案室,打印机忠实、严谨地输出着符合国家病历质控标准、一字不差的 A4 物理存档。

核心启发

前端架构设计不仅仅是"调接口、画页面"。在面对具有复杂物理世界映射逻辑(如归档、打印)的系统时,绝不能让"UI体验"越俎代庖去污染"物理边界数据"。适时地在数据总线处做分层解耦(UI View vs Physical View),绝对尊重并贯彻后端的物理切割指令,才是保障企业级重型医疗应用稳如磐石的根本之道。

相关推荐
Swift社区8 小时前
传统游戏引擎 vs 鸿蒙 System 架构
架构·游戏引擎·harmonyos
m0_738120728 小时前
后渗透维权提权基础——CTF模拟红队进行权限维持(一)
服务器·前端·python·安全·web安全·php
朝阳399 小时前
react【实战】自定义下拉框、单选、多选、输入框
前端·javascript·react.js
涵涵(互关)9 小时前
GoView各项目文件中的相关语法3
前端·vue.js·typescript
李白的天不白9 小时前
vs code -- uniapp gets
前端
lifewange9 小时前
CNode API v1 完整接口文档(JSON 规范整理)
java·前端·json
QQ1__81151751517 小时前
Spring boot名城小区物业管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot
钛态17 小时前
前端微前端架构:大项目的救命稻草还是自找麻烦?
前端·vue·react·web
一粒黑子17 小时前
【实战解析】阿里开源 PageAgent:纯前端 GUI Agent,一行JS让网页支持自然语言操控
前端·javascript·开源