乐于分享
好东西不私藏

开源EMR文档编辑器求Star

开源EMR文档编辑器求Star

写了一年,我想把这款电子病历文档编辑器开源出来,希望你愿意点个 ⭐

一款从零手写的 Canvas 编辑器,前端 React + 后端 Spring Boot,把"医疗文书怎么写才对"这件事,认真做了一遍。


一、先说为什么

去年我开始做 EMR 文档编辑器引擎(EMR Document Engine),起因其实挺朴素:

做医疗系统的同行都知道,病历编辑器是整个 HIS / 电子病历系统的"咽喉"。上面顶着医生一天的工作效率,下面压着病历质量、合规审计、科研数据化。但行业里能用的开源方案寥寥无几——要么是 Quill、Slate、Tiptap 这类通用富文本魔改,要么是商业产品闭源收费,要找到一款从医疗场景出发、自带质控规则、纸张级排版、可长期维护的开源编辑器,几乎不可能。

于是我决定自己写。

从 ModelD 文档模型、到 LayoutEngine 排版、到三层 Canvas 渲染、到 20 多条医疗质控规则、再到 25 条医学缩写自动更正——逐行敲代码,敲了一年

今天,它已经是一个能在线预览、能写进真实生产流程的系统。我想把它正式开源出来,邀请更多的同行一起来打磨。

如果你对编辑器内核、富文本、Canvas 渲染、可视化排版、医疗信息化中的某一个方向感兴趣,欢迎 Star、Fork、提 Issue、提 PR。这是给愿意在开源里长期投入的开发者的一份邀请。


二、这是一款怎样的编辑器

简单来说,它不是一个"在 contenteditable 上贴 toolbar"的玩具,而是一套面向电子病历场景、纸张级排版、可扩展的文档编辑器内核

它能做什么:

  • 📝 像 Word 一样顺手——字体、字号、加粗、斜体、下划线、删除线、上标/下标、文字颜色、文字高亮、清除格式、格式刷,一个不少
  • 📐 段落级精细控制——左/中/右/两端对齐、有序/无序列表(支持 CJK / 罗马数字编号)、多级标题、缩进、行距
  • 🧩 复杂结构元素——表格(合并/拆分/表头重复/跨页断表)、图片、脚注、书签、交叉引用、域代码(页码/总页数/作者等 8 种)、分节符、分隔线
  • 🏥 医疗专用控件——7 种结构化录入控件(文本/文本域/数字/下拉/日期/复选/单选),关键字段不再"随手敲"
  • 🧠 医疗智能——25 条医学缩写自动更正(i.v.g.t.t. → 静脉滴注)、智能中文标点配对
  • 🔍 查找替换——支持正则、大小写敏感、全词匹配
  • 📊 可视化能力——Canvas 图表(柱/线/饼/雷达/散点)、条码(Code128B + QR)
  • 🎨 纸张级排版——A4 页面、页眉页脚、页码、水印、孤行寡行控制、所见即所得
  • 💬 批注协作——添加/回复/解决批注,黄色高亮标记
  • 🧾 多格式导出——JSON / TXT / HTML 已可用,PDF / DOCX 正在路上
  • 🌐 多语言——i18n 框架已接入

更值得一提的是,它不是一个孤零零的前端 demo——前后端一体,后端用 Spring Boot 3 + MyBatis-Plus + Spring Security + WebSocket 提供文档服务、用户权限、审计日志、自动保存、版本回溯。

👉 在线体验:http://139.196.151.15/


三、作为开源项目,它"硬核"在哪里

如果只是"功能多",并不稀奇。这一年里,我觉得它真正有意思的地方,是底层架构的反复打磨

1. 自研 Canvas 编辑器内核(不基于任何富文本框架)

整个编辑器没有依赖 Quill / ProseMirror / Slate / Tiptap 任何一个第三方富文本框架——所有能力都是手写的:

  • 三层 Canvas 架构static(页面背景、水印、阴影) / content(文本、表格、图片) / interact(光标、选区、IME 预览),配合 rAF 重排与脏区裁剪,几十页病历也能丝滑滚动
  • 排版-渲染分离DocumentModel 排版无关,分页与版式由 LayoutEngine 全权负责;LineBreaker(UAX#14 参考)+ PageBreaker(含孤行寡行控制)+ IncrementalLayout(段落级缓存)
  • 粒子化渲染TextParticle / TableParticle / ListParticle / ImageParticle / LaTeXParticle / CommentParticle / ChartParticle / BarcodeParticle……每种元素独立渲染,通过 ParticleRegistry 调度,方便扩展
  • 多语言字体系统FontManager + FontFallback(缺字降级链) + ScriptResolver(Unicode 脚本检测),中英文混排不串字
  • 虚拟滚动VirtualViewport 根据 scrollY 计算可见页范围,仅渲染可见页,长文档零压力

这意味着:你可以把这个内核拆出来,单独用于任何"纸张级排版 + 文档编辑"的场景,不必局限于医疗。

2. 完整的 Command 模式与 Undo/Redo

编辑器内核有10 种 Command 类型(插入/删除/拆分合并段/格式化/清除/格式刷/段落样式/插入节点/状态变更),全部支持:

  • ✅ Undo / Redo(Ctrl+Z / Ctrl+Y)
  • ✅ 500ms 自动合并——连续输入/删除自动合并成一个不可分割的操作
  • ✅ 栈深度限制 + 跨命令级联撤销
  • ✅ 任何编辑操作都走 Command,不会出现"绕过撤销栈的偷偷修改"

这是很多"看起来能编辑"的项目没做到的——而它决定了病历在多人协作、长时间编辑下的可靠性。

3. 插件系统 + 扩展点

编辑器内置 PluginManager,提供 IPlugin / PluginContext / ExtensionPoint / ToolbarAction 一套完整接口,编辑器本身就是可扩展的

  • 想给工具栏加按钮?挂一个 ToolbarAction
  • 想拦截某些操作?注册一个 ExtensionPoint
  • 想加入自定义元素?注册到 ParticleRegistry

启动时已自带 emr.demo 示例插件。这个设计参考了 ProseMirror 的 plugin 思路,但更轻量、更适合病历这种"业务规则密集"的场景。

4. 医疗质控引擎(QCEngine)

病历质量不是"事后检查"出来的,而是"书写时"就该有保障的。系统内置20+ 条质控规则,对病历内容实时评分、分级,问题在书写阶段就被提示,而不是等到归档后才被退回。

5. 错误恢复 + 自动保存 + 乐观锁

医疗文书不是普通文档——丢一行可能就是医疗事故。编辑器有三道保险:

  • ErrorRecovery
     —— safeRenderParticle / safeRenderPage / safeLoadDocument,一次异常不会拖垮整份病历
  • AutoSaveManager
     —— IndexedDB 存储,3 秒防抖,保留最近 3 个版本,崩溃可恢复
  • 文档乐观锁插件 —— 多人同时编辑时,基于版本号检测冲突,避免相互覆盖

6. Yjs + y-websocket 已就位(协同编辑预留)

虽然协同编辑本身还在路上,但 yjs 和 y-websocket 已经作为依赖装好,CommandContext 也预留了 collab 模式入口。这等于告诉你:项目的下一步往哪走,架构上已经留好了位置


四、技术栈一览

前端:React 18 · TypeScript (strict) · Vite · Tailwind CSS · Zustand · Radix UI · Lucide · Axios · HTML5 Canvas(自研渲染器) · KaTeX · Yjs

后端:Java 17 · Spring Boot 3.x · MyBatis-Plus · Spring Security · JWT · WebSocket · Redis · Springdoc OpenAPI · MySQL 8.0(测试 H2)

工程化:Vitest(213 个单元测试) · Docker + docker-compose · Nginx · Conventional Commits · Gitee 托管

文档完备:output/ 下放了 5 份正式文档(调研、PRD、架构、UI/UX、技术规格),knowledge/ 下放了一份完整的编辑器功能清单(基于代码逐项盘点,含 170 项功能与已知边界)


五、为什么希望你来 ⭐

我把它开源出来,初心很简单:让医疗信息化少一些重复造轮子

但我知道,一款开源编辑器能不能走得远,不取决于我一个人敲多少行代码,而取决于有多少人愿意停下来看它一眼、提一个 Issue、补一行测试

所以——

  • 如果你做医疗信息化,被病历编辑器折磨过,这个项目值得你花 5 分钟看个 demo
  • 如果你对编辑器内核、富文本、Canvas 渲染、可视化排版感兴趣,源代码值得你点个 ⭐
  • 如果你愿意参与建设,PR / Issue / 文档修订,每一份都弥足珍贵——你可以在 README 末尾看到完整的贡献流程

一颗 ⭐ 不多,但它是开源世界给作者最重要的回馈——它告诉我:这个方向有人在乎,值得继续走下去


六、Roadmap(不画大饼,只说已经在做的)

为了不让你失望,下面这些是真实在推进的事:

优先级
项目
说明
🔴 P0
持续打磨已实现功能
光标渲染、表格编辑、剪切粘贴、文字高亮、列表编号等近 30 项已修复,回归测试在跟进
🟡 P1
PDF 导出 / DOCX 导出
用户呼声最高的功能,正在加紧实现
🟡 P2
多人实时协同
Yjs 已就位,正在接入编辑流
🟢 P3
E2E 测试套件
基于 Playwright 的端到端回归
🟢 P4
HarfBuzz WASM L2 文本塑形
对追求极致排版精度的场景

PDF 导出、协同编辑一旦完成,会单独发文同步。


七、写在最后

做开源最难的,不是写代码,是一个人能走多远

我一个人写了一年,把"自研 Canvas 编辑器内核 + 完整医疗业务闭环 + 200+ 测试 + 完整文档"这套东西交了出来。但一款真正能在医院里跑起来的电子病历编辑器,还需要:

  • 更多同行来 review 内核设计
  • 更多有医疗背景的朋友来补充质控规则
  • 更多前端工程师来打磨交互细节
  • 更多贡献者把它翻译成更多语言

如果上面的某一件事正好是你擅长的,或者你正在找一款"可以长期投入"的开源项目——

👉仓库地址:https://gitee.com/wangwang_1_1665527118/emrdocument-engine👉在线预览:http://139.196.151.15/

期待你的 ⭐。更期待你的 PR ❤️。

让病历不再只是负担,让好的工具成就更好的医疗。