From 057af2a71764911b820b4c696e524cbb9e4e4fc1 Mon Sep 17 00:00:00 2001 From: guanyu Date: Mon, 18 May 2026 09:15:23 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20Bug=20#529:=20=E6=A0=B9=E5=9B=A0+?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=96=B9=E6=A1=88=E6=91=98=E8=A6=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BUG_526_ANALYSIS.md | 78 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 BUG_526_ANALYSIS.md diff --git a/BUG_526_ANALYSIS.md b/BUG_526_ANALYSIS.md new file mode 100644 index 000000000..78211779d --- /dev/null +++ b/BUG_526_ANALYSIS.md @@ -0,0 +1,78 @@ +# Bug #526 分析报告 + +## Bug 描述 +[手术管理-门诊手术安排-计费] 勾选待签发状态的项目后上方签发按钮仍置灰不可用 + +## 根因定位 + +**文件**: `openhis-ui-vue3/src/views/clinicmanagement/bargain/component/prescriptionlist.vue` + +### 签发按钮控制逻辑 +```vue + 签发 +``` +`handleSaveDisabled` 是一个 `ref(false)`(第408行)。 + +### 两个更新机制都存在缺陷 + +**机制1:watcher(第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 不会触发。 + +**机制2:changeCheck 函数(第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` 变为 true(v-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()` 部分)。