Files
his/BUG_526_ANALYSIS.md

3.1 KiB
Raw Blame History

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行

两个更新机制都存在缺陷

机制1watcher第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 不会触发。

机制2changeCheck 函数第986-1019行

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() → 更新 groupIndexListgroupList
  4. changeCheck 中逐个遍历设置按钮状态的逻辑不可靠 → 签发按钮可能仍为 disabled

修复方案

handleSaveDisabledhandleSingOutDisabledref + 手动管理改为 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)
  )
})

优势

  • 响应式自动计算,任何 checkstatusEnum 变化都会触发重新计算
  • 不需要 watcher删除 deep: false 的那个)
  • 不需要在 changeCheck 中手动管理按钮状态
  • 逻辑与 handleSavehandleSingOut 中的筛选条件一致

同时从 changeCheck 函数中移除按钮状态管理代码第986-1019行的 .map() 部分)。