☰
HospitalRun 前端项目演进全解:从 CHANGELOG 读懂 2.0 架构、破坏性变更与工程实践
2026/10/15 17:15:09 网站建设 项目流程
  • 前端
  • 企业应用

【免费下载链接】hospitalrun-frontend

Frontend for HospitalRun

项目地址:https://gitcode.com/gh_mirrors/ho/hospitalrun-frontend
点击查看免费下载

本文以 HospitalRun 前端仓库(@hospitalrun/frontend,当前版本 2.0.0-alpha.7)的 CHANGELOG.md 为骨架,逐条还原 1.0.0 到 2.0.0-alpha.7 期间的架构演进、破坏性变更与工程化实践,并结合src/、couchdb/、scripts/等目录的真实源码,帮助读者理解这套「React + Redux Toolkit + PouchDB/CouchDB」医院信息系统前端的核心模块、数据层原理与开发工作流。

一、CHANGELOG 是什么:一份可追溯的工程史

CHANGELOG.md 采用 standard-version 中的@commitlint/config-conventional强制校验)。日志把每次发版拆分为:

  • Features:新功能,如患者模块、预约、检验(Lab)、用药(Medication)、影像(Imaging)、事件(Incident)等;
  • Bug Fixes:缺陷修复,多数附带 GitHub issue 编号(如closes #2292);
  • ⚠ BREAKING CHANGES:破坏性变更,是升级时最需要关注的段落;
  • CI / Performance Improvements / chore:工程与基础设施类变更。

从 package.json 可以看到,当前版本号为2.0.0-alpha.7,与日志最新条目一致;standard-version作为 devDependency 存在,配合 commitizen(npm run commit)与 husky 的 pre-commit / commit-msg 钩子,构成了「规范提交 → 自动生成 changelog → 自动打 tag」的完整链路。日志中typo in changelog.md的修复记录也说明它是一份被持续维护、逐字校对过的文档。

二、2.0.0 系列的破坏性变更:升级前必读

日志中共有三处明确标注的 BREAKING CHANGES,理解它们能避免升级后功能异常:

1. 移除基于 CouchDB 实例的登录(alpha.6)

* **login:** removed login connected with CouchDB instance

这是 2.0.0-alpha.6 最重要的变更:前端不再直接依赖 CouchDB 实例账号体系完成登录。从源码看,登录逻辑集中在 src/user/user-slice.ts:

  • loginaction 通过remoteDb.logIn(username, password)(PouchDB Authentication 插件)完成鉴权,并在失败时区分「必填字段缺失」与error.status === 401(账号或密码错误)两类错误;
  • 登录成功后通过remoteDb.getUser()读取用户元数据(givenName、familyName),并写入 Redux 状态;
  • getCurrentSession用于恢复会话,logout调用remoteDb.logOut()后清空状态。

2. 患者 friendlyId 不再回填(alpha.3)

* **patients:** Any patient saved with friendly id will no longer map friendly id to the patient object, thus not displaying it in the UI or have it available for search

从 alpha.3 起,前端不再把 friendlyId(友好编号)映射回患者对象,界面与搜索都不再依赖它。取而代之的是随机生成的 code:

  • src/patients/util/patient-util.ts 中getPatientCode从患者对象读取code字段;
  • src/shared/util/generateCode.ts 用shortid生成形如P-xxxxxxx的代码;
  • src/shared/db/PatientRepository.ts 的save()在落库前先调用generateCode('P')生成患者编号,搜索时同时匹配data.fullName(正则、忽略大小写)与data.code(精确匹配)。

3. 组件库接口变更与 Node 版本底线(alpha.1)

* **frontend:** update components package changing some interfaces * This module no longer supports Node.js 0.10

日志同时记录了 Node.js 0.10 支持被移除(chore),以及@hospitalrun/components组件库接口更新。此外 alpha.7 将 CI 从 Node v12 LTS 迁移到Node v14 LTS,因此本地开发与 CI 构建应使用 Node 14 及以上的 LTS 环境。

三、数据层演进:从简单 PouchDB 客户端到关系型仓储

alpha.1 的 init 阶段日志逐步揭示了数据层的搭建轨迹:creates a very simple pouchdb client→creates a generic repository class and refactors patient db→add saveOrUpdate function in repositories→adds remote couchdb。这些在源码中都有完整对应:

1. 关系型 PouchDB 与 schema 定义

src/shared/config/pouchdb.ts 通过PouchDB.plugin(...)挂载了 5 个插件:

插件用途
pouchdb-quick-search快速全文搜索
pouchdb-adapter-memory测试环境内存适配器
relational-pouch关系型数据建模(belongsTo / hasMany)
pouchdb-findMongoDB 风格 find 查询
pouchdb-authentication登录/会话管理

同时定义了schema:patient与appointment、lab、medication、imaging之间存在hasMany/belongsTo关系,这解释了日志中「imaging 与 visit 关联」「diagnosis 与 visit 关联」等数据建模类特性为何能直接通过rel.findHasMany('appointment', 'patient', patientId)(见 PatientRepository.ts)实现。

2. 环境区分:测试内存库 vs 远程 CouchDB

同一文件中,NODE_ENV === 'test'时创建skip_setup: true的内存库;否则连接${process.env.REACT_APP_HOSPITALRUN_API}/hospitalrun,并通过localDb.sync(serverDb, { live: true, retry: true })开启本地与远端 CouchDB 的实时双向同步——这正是日志 alpha.4「network-status 离线工作提示」得以成立的基础:本地库离线可用,联网后自动同步。

3. 通用仓储类 Repository

src/shared/db/Repository.ts 是日志「creates a generic repository class」的直接成果,提供:

  • find(id):按关系型 id 查询;
  • findAll(sort):按_id正则限定文档类型,并为排序字段动态创建 PouchDB 索引(避免 find 缺索引报错);
  • search(criteria):$and组合类型正则与业务条件;
  • save(entity):剥离id/rev后,用uuidv4()生成新 id,并写入createdAt/updatedAt(对应日志 alpha.3「add created date and last updated date」);
  • saveOrUpdate(entity):先查再改,不存在则走save;
  • delete(entity)。

四、核心业务模块的时间线:一张功能演进地图

把日志按模块归类,可以得到项目 2.0 的功能全景:

1. 患者模块(贯穿全程,迭代最密集)

  • alpha.1:创建/查看患者、按 fullName 与 friendlyId 搜索、模糊搜索(fuzzy search)、近似年龄、添加与显示关联人(related persons)、患者标签页(tabs)、fullName扁平化存储;
  • alpha.2:患者视图新增「预约」标签页;条件渲染 familyName 与 suffix;
  • alpha.3:新增就诊(visit)概念雏形、诊断标签页、患者笔记(notes)、多联系方式(phone/email/address)、表单校验与错误反馈、随机 code 取代序列号(对应generateCode)、预约/编辑预约/删除预约完整闭环;
  • alpha.4:分页与排序(见下文)、新增预约按钮、按状态过滤检验单、网络状态提示;
  • alpha.5:过敏点击查看(#2224)、重复患者预警(#2187,逻辑见 src/patients/util/is-possible-duplicate-patient.ts,比较 givenName/familyName/sex/dateOfBirth 四元组)、血型信息(#2190)、患者护理计划 care plan 与护理目标 care goal(#2360)、就诊功能(#2251)、无患者空状态(#2235);
  • alpha.6:患者信息面板(ImportantPatientInfo,src/patients/view/ImportantPatientInfo.tsx)。

2. 检验(Lab)与用药(Medication)模块

  • alpha.1 就位;alpha.3 加入「请求/查看检验单」、按requestedOn排序(ViewLabs.tsx);
  • alpha.4 增加检验状态过滤(#2033)、Lab code(#2040)、requestBy字段(#2082);
  • alpha.5 支持检验单多条备注(#2325)、完成检验的成功提示与「successfully completed」文案修复(#2295)。

3. 事件(Incident)模块与可视化

  • alpha.3 起新增报告事件、查看事件、事件路由与过滤(#2087);
  • alpha.4 支持按状态过滤、加载中状态(#2085);
  • alpha.5 加入「解决事件」能力(#2222,实现见 src/incidents/hooks/useResolveIncident.tsx,将status置为'resolved'并写入resolvedOn);
  • 同一版本引入CSV 导出(#2292):基于json2csv对事件表格做数据过滤后下载;
  • 引入事件可视化(visualize):新增viewIncidentWidgets权限(见 Permissions.ts)、路由/incidents/visualize(见 pageMap.tsx)以及 VisualizeIncidents.tsx——该组件用useIncidents({ status: IncidentFilter.reported })拉取已上报事件,按reportedOn的月份累加进monthlyIncidents状态数组,最终渲染 12 个月的LineGraph折线图。

4. 影像(Imaging)模块

alpha.5 新增(#2250、#2249 与 medications 同期),并在 alpha.6 将影像与就诊关联(#2309)。模块包含请求页 NewImagingRequest.tsx、搜索表格 ImagingRequestTable.tsx 与校验工具 validate-imaging-request.ts。

5. 预约(Scheduling)与编辑预约

alpha.1 建立日历展示与创建;alpha.2 在患者视图加入预约标签页;alpha.3 实现编辑预约(#1770 相关)、删除预约、'Walk Up'改为'Walk In';alpha.6 重构编辑预约流程(EditAppointment.tsx)并新增 hook 测试。

五、工程化实践:测试、i18n 与代码质量门禁

1. 测试体系:从 matchMediaMock 到 react-hooks 测试

日志中的大量added tests、fix ... test条目反映出测试先行文化。测试基础设施包括:

  • src/mocks/matchMediaMock.js 解决 jsdom 缺少matchMedia的问题;
  • src/setupTests.js 统一注入 mocks;
  • src/tests/test-utils/use-query.util.tsx 与 use-mutation.util.ts 封装 react-query 测试工具;
  • 各业务模块均配套 hooks 测试(如usePatient、useResolveIncident、useLab)与组件测试(*.test.tsx);
  • standardize mock store setup in tests(#2075)、standardized react router imports(#2067)等条目表明测试代码也经历了规范化重构。

运行方式见 package.json:npm run test:ci使用cross-env CI=true、jest-environment-jsdom-sixteen与--maxWorkers=2;npm run lint覆盖src/**与scripts/check-translations/**。

2. 国际化:多语言资源与翻译完整性检查

i18n 是日志中出现频率最高的主题之一,演进脉络为:alpha.1 引入国际化 → alpha.3 重组翻译资源、修复大量缺失 key → alpha.4 新增意大利语(#2035)、翻译缺失检查脚本(#1919)→ alpha.5 新增俄语(patient/actions/incidents/scheduling)→ 后续补全中文(zhCN)等语言。

当前 src/shared/locales/index.ts 注册了12 种语言:Italian、Arabic、German、English (American)、Spanish、French、Indonesian、Japanese、Portuguese、Russian、Turkish、Chinese。国际化配置见 src/shared/config/i18n.ts:fallbackLng: 'en'、通过i18next-browser-languagedetector自动检测语言。

翻译完整性由 scripts/check-translations/index.ts 保证:

  • 以en(English)为基准语言,递归遍历其他 11 种语言的 key 树;
  • 缺少 key 时输出橙色警告(The key ... is not present ...);
  • 发现「基准语言是对象、对照语言是字符串」的结构错位时输出橙色警告;
  • 若找不到英文资源则直接process.exit(1)报错退出。

该脚本通过 npm scripts 深度集成:start、test前都会先执行translation:check(由tsc -p scripts/tsconfig.json编译后运行),并在运行前后自动清理编译产物(remove-compiled-translations),确保任何一次启动或测试都先通过翻译完整性检查。

3. ESLint no-console 与依赖治理

  • alpha.5 的eslint rule no-console added(#2307)说明项目对console使用有严格约束(scripts/check-translations/index.ts头部显式/* eslint-disable no-console */即为佐证);
  • moment通过 package.json 的resolutions字段锁定到 2.24.0(临时规避上游 issue);
  • alpha.6 的react-hooks/exhaustive-deps相关修复保证 hooks 依赖数组的规范性。

六、开发环境:CouchDB 一键初始化与本地部署

日志 alpha.5 加入「init 与 cleanup CouchDB 脚本」,alpha.4 修复了 CouchDB 认证弹窗问题(#2256,涉及local.ini与nginx.conf),alpha.6 为脚本补充 Windows 版本。这一整套开发环境脚本位于 couchdb/ 目录:

1. 启动 / 清理脚本

  • couchdb/couchdb-init.sh(Linux/macOS)与 couchdb-init.bat(Windows)执行docker-compose up --build -d启动开发库;
  • couchdb/couchdb-cleanup.sh(及 .bat)执行docker-compose down -v --rmi all --remove-orphans彻底清理容器、卷与镜像。

2. docker-compose 与数据库初始化

docker-compose.yml 定义了couchdb(暴露 5984 端口,默认账号admin/password)与dbinit两个服务。dbinit在 CouchDB 启动 5 秒后依次执行:

  • 创建_global_changes库;
  • 设置_users/_security;
  • 创建hospitalrun数据库(partitioned=false);
  • 配置库安全角色;
  • 创建演示用户org.couchdb.user:username(含metadata.givenName/familyName)。

3. CORS 与认证弹窗规避

  • couchdb/local.ini:开启single_node、CORS(origins = *、credentials = true),并将默认的WWW-Authenticate: Basic realm="administrator"替换为Other realm="app";
  • nginx.conf:生产 Nginx 在 401 响应时同样用more_set_headers覆盖WWW-Authenticate头。

这一对配置正是日志中「couchdb auth popup」系列修复(#2256)的落地成果:通过替换 WWW-Authenticate 头,避免浏览器在访问 PouchDB/CouchDB 时弹出原生认证对话框,转而由前端表单接管登录。

七、用户体验与交互细节的持续打磨

日志中的大量小条目体现了对 UX 的细致打磨,部分可在源码中直接验证:

  • 网络状态提示(alpha.4,#2109):useNetworkStatus.ts 监听window的online/offline事件;NetworkStatusMessage.tsx 离线时显示红色横幅,恢复在线后绿色横幅在 4000ms 内淡出;
  • 面包屑导航(alpha.3,#1770):breadcrumbs-slice.ts 中addBreadcrumbs会对面包屑按location.length升序排序;Breadcrumbs.tsx 渲染时最后一项高亮为 active 且不可点击;
  • 侧边栏权限控制(alpha.4,#2110):Sidebar.tsx 中「新增/列表」子菜单项按permissions.includes(...)条件渲染,如WritePatients控制「New Patient」、ViewIncidentWidgets控制「Visualize」入口;alpha.3 的「sidebar collapsible」特性由sidebarCollapsed(Redux 状态)驱动,折叠时宽度变为 56px;
  • 导航栏:alpha.4 增加汉堡菜单(移动端)、下拉分隔线、sticky 样式(#2057);alpha.5 移除导航栏搜索框(#2237)、在「quick add」中加入图标(#2220)、显示当前登录用户名(currentlySignedInAs,见 Navbar.tsx);
  • 分页与排序(alpha.4,#1969/#1967):PageComponent.tsx 提供 25/50/100/200/All 五种页大小与上一页/下一页按钮;PageRequest.ts 定义number/size/nextPageInfo/previousPageInfo结构;排序则在 Repository.findAll 中通过动态建索引 +data.<field>的 Mongo-style find 实现;
  • 日期选择器:alpha.4 增加年份下拉(#2060,DatePickerWithLabelFormGroup.tsx 的showYearDropdown属性)、放大尺寸(#2056),alpha.5 为出生日期设置最大日期(#2002)。

八、从日志到源码:一个可复用的研究方法

HospitalRun 前端的 CHANGELOG 之所以值得细读,是因为每条记录都能在仓库中找到可验证的实现锚点:

CHANGELOG 条目(版本)源码证据
关系型仓储重构(alpha.1)Repository.ts + pouchdb.ts schema
随机 code 取代序列(alpha.3)generateCode.ts + PatientRepository.save
created/updated 时间戳(alpha.3)Repository.save/saveOrUpdate
事件 CSV 导出(alpha.5,#2292)json2csv依赖(package.json)+ 事件表格组件
事件可视化(alpha.5)VisualizeIncidents.tsx +viewIncidentWidgets权限
重复患者预警(alpha.5,#2187)is-possible-duplicate-patient.ts
翻译检查脚本(alpha.4,#1919)scripts/check-translations/index.ts
CouchDB 初始化脚本(alpha.5)couchdb-init.sh + docker-compose.yml
认证弹窗修复(alpha.4,#2256)couchdb/local.ini + nginx.conf

对读者而言,这套「版本日志 → 提交/issue → 源码实现」的追踪方法,可以快速定位某个能力是什么时候引入的、为什么引入、底层又是如何实现的,也便于在升级到 2.0.0-alpha.x 系列时提前评估破坏性变更的影响面。

九、小结与升级建议

纵观 CHANGELOG,HospitalRun 前端 2.0 系列的演进主线清晰:

  1. 数据层从简单 PouchDB 客户端走向关系型建模 + 通用仓储 + 远端 CouchDB 实时同步;
  2. 业务域从患者单一模块扩展为患者/预约/检验/用药/影像/事件六大模块,并逐步补齐编辑、删除、过滤、排序、分页与可视化;
  3. 工程质量通过 translation check 门禁、commitlint/standard-version 规范提交、覆盖各模块的 jest 测试持续加固;
  4. 体验细节(网络状态、面包屑、权限化侧边栏、快捷操作)在多语言与离线场景下不断完善。

升级到最新 2.0.0-alpha.7 前,请重点关注三处破坏性变更:CouchDB 登录已被移除、患者 friendlyId 不再回填(改用code字段)、组件库接口与 Node 版本要求(CI 已迁移至 Node 14 LTS)。本地开发推荐按 couchdb/ 目录脚本一键起停 CouchDB 环境,再以npm start启动前端,配合npm run test:ci与npm run lint验证改动质量。

  • 前端
  • 企业应用

【免费下载链接】hospitalrun-frontend

Frontend for HospitalRun

项目地址:https://gitcode.com/gh_mirrors/ho/hospitalrun-frontend
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询