根因:getSurgeryPage接口缺少Redis缓存层,每次弹窗打开都直接查数据库。
修复:1. 后端getSurgeryPage添加Redis缓存(24h过期),与getAdviceBaseInfo保持一致
2. 前端getList()命中内存缓存时显式清除loading状态,防止加载动画卡住
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
73 lines
2.8 KiB
Markdown
73 lines
2.8 KiB
Markdown
# 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),但每次弹窗打开都重复执行查询 + 序列化 + 网络传输,累积延迟明显。
|
||
|
||
**辅助因素:**
|
||
1. `applicationFormBottomBtn.vue` 的对话框设置了 `destroy-on-close`,每次关闭都会销毁 Surgery 组件
|
||
2. 前端虽有模块级内存缓存(`surgeryRecordsCache` / `surgeryMappedCache`),但首次加载仍需后端响应
|
||
3. 前端 `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`
|
||
|
||
1. 新增缓存键常量:`SURGERY_PAGE_CACHE_PREFIX = "surgery:page:"`
|
||
2. 在无搜索关键字时,尝试从 Redis 读取缓存
|
||
3. 缓存未命中时,查询数据库后写入 Redis(24小时过期)
|
||
4. 有搜索关键字时不缓存(避免缓存爆炸)
|
||
|
||
**改动量:** 约 20 行
|
||
|
||
### 前端:修复 `getList()` 缓存命中时的 loading 状态
|
||
|
||
**改动文件:** `surgery.vue`
|
||
|
||
1. 在 `getList()` 方法中,当命中内存缓存时,显式设置 `loading.value = false`
|
||
|
||
**改动量:** 1 行
|
||
|
||
## 验证计划
|
||
|
||
1. 编译验证 Java 代码
|
||
2. 语法验证 Vue 文件:`node --check surgery.vue`
|
||
3. 手动验证:登录医生工作站,打开手术申请单,观察加载速度(首次应有loading,二次打开应秒开)
|