Fix Bug #529: 根因+修复方案摘要

This commit is contained in:
2026-05-18 09:15:23 +08:00
parent 99b3154fc5
commit 057af2a717

78
BUG_526_ANALYSIS.md Normal file
View File

@@ -0,0 +1,78 @@
# Bug #526 分析报告
## Bug 描述
[手术管理-门诊手术安排-计费] 勾选待签发状态的项目后上方签发按钮仍置灰不可用
## 根因定位
**文件**: `openhis-ui-vue3/src/views/clinicmanagement/bargain/component/prescriptionlist.vue`
### 签发按钮控制逻辑
```vue
<el-button type="primary" @click="handleSave()" :disabled="handleSaveDisabled"> 签发 </el-button>
```
`handleSaveDisabled` 是一个 `ref(false)`第408行
### 两个更新机制都存在缺陷
**机制1watcher第458-475行**
```js
watch(() => prescriptionList.value, (newValue) => {
let saveList = prescriptionList.value.filter(item =>
item.check && item.statusEnum == 1 && (Number(item.bizRequestFlag)==1 || !item.bizRequestFlag)
)
handleSaveDisabled.value = saveList.length == 0
}, { immediate: true, deep: false }); // ← deep: false
```
`deep: false` 意味着 watcher 只能检测到数组引用变化push/splice**无法检测到数组元素的 `check` 属性变化**。用户勾选/取消勾选checkbox时watcher 不会触发。
**机制2changeCheck 函数第986-1019行**
```js
groupList.value.map(k => {
if(k.check) {
if(k.statusEnum == 1) {
// 待签发:设置 handleSaveDisabled = false
}
if(k.statusEnum == 2) {
// 已签发:设置 handleSaveDisabled = true
}
}
})
```
问题:
1. **用 `.map()` 遍历逐个设置按钮状态**,后面的项会覆盖前面项的设置
2. 如果列表中先有"待签发"项(设置 `handleSaveDisabled = false`),后面遍历时碰到一个不满足 `bizRequestFlag` 条件的项,会被覆盖为 `true`
3. 当取消勾选最后一个项目时,`groupList` 为空,`.map()` 不执行任何操作,按钮状态保持原样
### 数据流
1. `getListInfo()` 从后端加载数据 → `prescriptionList.value` 被赋值
2. 用户勾选checkbox → `scope.row.check` 变为 truev-model 自动)
3. `@change` 触发 `changeCheck()` → 更新 `groupIndexList``groupList`
4. **但 `changeCheck` 中逐个遍历设置按钮状态的逻辑不可靠** → 签发按钮可能仍为 disabled
## 修复方案
`handleSaveDisabled``handleSingOutDisabled``ref` + 手动管理改为 **`computed` 属性**,直接从 `prescriptionList.value` 实时计算按钮状态:
```js
const handleSaveDisabled = computed(() => {
return !prescriptionList.value.some(item =>
item.check && item.statusEnum == 1 && (Number(item.bizRequestFlag) === 1 || !item.bizRequestFlag)
)
})
const handleSingOutDisabled = computed(() => {
return !prescriptionList.value.some(item =>
item.check && item.statusEnum == 2 && item.chargeStatus != 5 &&
(Number(item.bizRequestFlag) === 1 || !item.bizRequestFlag)
)
})
```
**优势**
- 响应式自动计算,任何 `check``statusEnum` 变化都会触发重新计算
- 不需要 watcher删除 deep: false 的那个)
- 不需要在 changeCheck 中手动管理按钮状态
- 逻辑与 `handleSave``handleSingOut` 中的筛选条件一致
同时从 `changeCheck` 函数中移除按钮状态管理代码第986-1019行的 `.map()` 部分)。