3.1 KiB
3.1 KiB
Bug #526 分析报告
Bug 描述
[手术管理-门诊手术安排-计费] 勾选待签发状态的项目后上方签发按钮仍置灰不可用
根因定位
文件: openhis-ui-vue3/src/views/clinicmanagement/bargain/component/prescriptionlist.vue
签发按钮控制逻辑
<el-button type="primary" @click="handleSave()" :disabled="handleSaveDisabled"> 签发 </el-button>
handleSaveDisabled 是一个 ref(false)(第408行)。
两个更新机制都存在缺陷
机制1:watcher(第458-475行)
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 不会触发。
机制2:changeCheck 函数(第986-1019行)
groupList.value.map(k => {
if(k.check) {
if(k.statusEnum == 1) {
// 待签发:设置 handleSaveDisabled = false
}
if(k.statusEnum == 2) {
// 已签发:设置 handleSaveDisabled = true
}
}
})
问题:
- 用
.map()遍历逐个设置按钮状态,后面的项会覆盖前面项的设置 - 如果列表中先有"待签发"项(设置
handleSaveDisabled = false),后面遍历时碰到一个不满足bizRequestFlag条件的项,会被覆盖为true - 当取消勾选最后一个项目时,
groupList为空,.map()不执行任何操作,按钮状态保持原样
数据流
getListInfo()从后端加载数据 →prescriptionList.value被赋值- 用户勾选checkbox →
scope.row.check变为 true(v-model 自动) @change触发changeCheck()→ 更新groupIndexList和groupList- 但
changeCheck中逐个遍历设置按钮状态的逻辑不可靠 → 签发按钮可能仍为 disabled
修复方案
将 handleSaveDisabled 和 handleSingOutDisabled 从 ref + 手动管理改为 computed 属性,直接从 prescriptionList.value 实时计算按钮状态:
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() 部分)。