根因:getSurgeryPage接口缺少Redis缓存层,每次弹窗打开都直接查数据库。
修复:1. 后端getSurgeryPage添加Redis缓存(24h过期),与getAdviceBaseInfo保持一致
2. 前端getList()命中内存缓存时显式清除loading状态,防止加载动画卡住
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2.8 KiB
2.8 KiB
Bug #470 分析报告
根因分析
症状
住院医生工作站-手术申请单加载手术项目耗时过长,影响医生开单效率。
根本原因
后端 getSurgeryPage 接口缺少 Redis 缓存层。
与同模块的 getAdviceBaseInfo(已有24小时Redis缓存)不同,getSurgeryPage 每次调用都直接查询数据库。
代码对比:
-
getAdviceBaseInfo(DoctorStationAdviceAppServiceImpl.java:157-512):- 使用
ADVICE_BASE_INFO_CACHE_PREFIX前缀做 Redis 缓存 - 24小时过期
- 先查缓存,未命中才查 DB
- 使用
-
getSurgeryPage(DoctorStationAdviceAppServiceImpl.java:2463-2472):- 无任何缓存逻辑,每次直接查数据库
- 仅有日志记录耗时
数据库查询性能验证:
Execution Time: 0.400 ms (10102条手术项目,已有 idx_wor_activity_def_surgery 索引)
Planning Time: 4.349 ms
数据库查询本身很快(<1ms),但每次弹窗打开都重复执行查询 + 序列化 + 网络传输,累积延迟明显。
辅助因素:
applicationFormBottomBtn.vue的对话框设置了destroy-on-close,每次关闭都会销毁 Surgery 组件- 前端虽有模块级内存缓存(
surgeryRecordsCache/surgeryMappedCache),但首次加载仍需后端响应 - 前端
getList()命中缓存时未清除loading.value,导致 loading 动画可能卡住
影响范围
涉及文件:
openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java— 后端手术分页查询实现(需加缓存)openhis-ui-vue3/src/views/inpatientDoctor/home/components/order/applicationForm/surgery.vue— 前端手术申请单组件(需修复 loading 状态)
涉及数据表:
wor_activity_definition— 活动定义表(手术项目源表),10,102条手术记录adm_charge_item_definition— 收费项定义表(定价关联)
修复方案
后端:给 getSurgeryPage 添加 Redis 缓存
改动文件: DoctorStationAdviceAppServiceImpl.java
- 新增缓存键常量:
SURGERY_PAGE_CACHE_PREFIX = "surgery:page:" - 在无搜索关键字时,尝试从 Redis 读取缓存
- 缓存未命中时,查询数据库后写入 Redis(24小时过期)
- 有搜索关键字时不缓存(避免缓存爆炸)
改动量: 约 20 行
前端:修复 getList() 缓存命中时的 loading 状态
改动文件: surgery.vue
- 在
getList()方法中,当命中内存缓存时,显式设置loading.value = false
改动量: 1 行
验证计划
- 编译验证 Java 代码
- 语法验证 Vue 文件:
node --check surgery.vue - 手动验证:登录医生工作站,打开手术申请单,观察加载速度(首次应有loading,二次打开应秒开)