From c8fa9b4bf00de57ef5abbc8cbd4fbc151e09d3b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E4=BA=91?= <赵云@gentronhealth.com> Date: Tue, 12 May 2026 11:34:50 +0800 Subject: [PATCH 1/2] =?UTF-8?q?Fix=20Bug=20#492:=20=E3=80=90=E9=97=A8?= =?UTF-8?q?=E8=AF=8A=E6=89=8B=E6=9C=AF=E5=AE=89=E6=8E=92=E3=80=91=E5=85=B3?= =?UTF-8?q?=E9=97=AD"=E6=89=8B=E6=9C=AF=E8=AE=A1=E8=B4=B9"=E4=B8=BB?= =?UTF-8?q?=E5=BC=B9=E7=AA=97=E5=90=8E=EF=BC=8C=E9=A1=B9=E7=9B=AE=E5=AD=97?= =?UTF-8?q?=E5=85=B8=E9=80=89=E6=8B=A9=E5=88=97=E8=A1=A8=E4=BE=9D=E7=84=B6?= =?UTF-8?q?=E6=AE=8B=E7=95=99=E6=82=AC=E6=B5=AE=E5=9C=A8=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E4=B8=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因:关闭计费弹窗时未调用 prescriptionlist 子组件的 closeAllPopovers 方法, 导致 el-popover(项目字典悬浮列表)在父弹窗销毁后仍残留显示。 修复:在 closeChargeDialog 中先调用 prescriptionRef.value.closeAllPopovers() 关闭所有子 popover。 Co-Authored-By: Claude Opus 4.7 --- openhis-ui-vue3/src/views/surgicalschedule/index.vue | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openhis-ui-vue3/src/views/surgicalschedule/index.vue b/openhis-ui-vue3/src/views/surgicalschedule/index.vue index 2e1045b1..5825b188 100755 --- a/openhis-ui-vue3/src/views/surgicalschedule/index.vue +++ b/openhis-ui-vue3/src/views/surgicalschedule/index.vue @@ -1412,6 +1412,10 @@ async function handleChargeCharge(row) { // 关闭计费弹窗 function closeChargeDialog() { + // 先关闭 prescriptionlist 内所有已打开的项目字典 popover + if (prescriptionRef.value && prescriptionRef.value.closeAllPopovers) { + prescriptionRef.value.closeAllPopovers() + } showChargeDialog.value = false chargePatientInfo.value = {} chargeSurgeryInfo.value = {} From 01d48c75a50c934e98deb179123ac101cc8b0a64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=B3=E7=BE=BD?= <关羽@gentronhealth.com> Date: Tue, 12 May 2026 12:18:49 +0800 Subject: [PATCH 2/2] =?UTF-8?q?Fix=20Bug=20#480:=20[=E4=BD=8F=E9=99=A2?= =?UTF-8?q?=E6=8A=A4=E5=A3=AB=E7=AB=99-=E5=8C=BB=E5=98=B1=E6=89=A7?= =?UTF-8?q?=E8=A1=8C]=20=E9=9D=9E=E8=80=97=E6=9D=90=E7=B1=BB=E5=8C=BB?= =?UTF-8?q?=E5=98=B1=E6=89=A7=E8=A1=8C=E6=8A=A5"=E8=80=97=E6=9D=90?= =?UTF-8?q?=E5=BA=93=E5=AD=98"=E9=94=99=E8=AF=AF=E4=B8=94=E5=85=A8?= =?UTF-8?q?=E9=80=89=E9=80=BB=E8=BE=91=E8=81=94=E5=8A=A8=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause analysis: 1. 非耗材类医嘱(如口服药"荆防颗粒")执行后,前端调用lotNumberMatch时传入所有患者 encounterId。该后端函数会查询所有DeviceDispense记录并校验耗材库存,若任一患者存 在耗材记录但无库存则报错"发耗材单生成失败,请检查耗材库存"。原代码的hasMedOrDevice检 查包含了med_medication_request(药品医嘱),导致纯药品执行也触发耗材校验。 2. 执行成功后调用handleGetPrescription()刷新列表,触发defaultSelectAllRows()自动全选 所有行,导致用户看到复选框全部选中的联动异常。 Fix: 1. hasMedOrDevice改为hasDevice,仅当选中医嘱包含device类型时才调用lotNumberMatch 2. handleGetPrescription新增skipAutoSelectAll参数,执行/不执行/取消执行后刷新时不自动全选 Co-Authored-By: Claude Opus 4.7 --- .../components/prescriptionList.vue | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/openhis-ui-vue3/src/views/inpatientNurse/medicalOrderExecution/components/prescriptionList.vue b/openhis-ui-vue3/src/views/inpatientNurse/medicalOrderExecution/components/prescriptionList.vue index 36df2f50..488c1358 100755 --- a/openhis-ui-vue3/src/views/inpatientNurse/medicalOrderExecution/components/prescriptionList.vue +++ b/openhis-ui-vue3/src/views/inpatientNurse/medicalOrderExecution/components/prescriptionList.vue @@ -270,7 +270,7 @@ function normalizeDayTimeHm(part) { return `${h}:${m}`; } -function handleGetPrescription() { +function handleGetPrescription(skipAutoSelectAll = false) { if (patientInfoList.value.length > 0) { loading.value = true; let encounterIds = patientInfoList.value.map((i) => i.encounterId).join(','); @@ -430,10 +430,12 @@ function handleGetPrescription() { // 将分组结果转换为数组形式 prescriptionList.value = Object.values(groupedPrescriptions); - // 默认选中全部行 - nextTick(() => { - defaultSelectAllRows(); - }); + // 默认选中全部行(执行后刷新时不自动全选,保持用户操作状态) + if (!skipAutoSelectAll) { + nextTick(() => { + defaultSelectAllRows(); + }); + } } catch (error) { console.error('医嘱执行-获取处方列表数据处理失败:', error); prescriptionList.value = []; @@ -469,18 +471,17 @@ function handleExecute() { console.log(list, 'list'); adviceExecute({ exeDate: exeDate.value, adviceExecuteDetailList: list }).then((res) => { if (res.code == 200) { - handleGetPrescription(); - // 仅当选中医嘱中包含药品/耗材类医嘱时,才调用耗材批号匹配 - const hasMedOrDevice = list.some( - (item) => - item.adviceTable === 'med_medication_request' || - String(item.adviceTable || '').includes('device'), + // 仅当选中医嘱中包含耗材类医嘱时,才调用耗材批号匹配(排除纯药品医嘱场景) + const hasDevice = list.some((item) => + String(item.adviceTable || '').includes('device'), ); - if (hasMedOrDevice) { + if (hasDevice) { lotNumberMatch({ encounterIdList: encounterIds }, { skipErrorMsg: true }).catch((error) => { console.warn('lotNumberMatch failed after adviceExecute:', error); }); } + // 刷新列表(不自动全选,保持用户操作前的选择状态) + handleGetPrescription(true); proxy.$modal.msgSuccess(res.msg || '医嘱执行成功'); } else { proxy.$modal.msgError(res.msg || '医嘱执行失败'); @@ -504,7 +505,7 @@ function handleNoExecute() { adviceNoExecute({ adviceExecuteDetailList: list }).then((res) => { if (res.code == 200) { proxy.$modal.msgSuccess(res.msg || '操作成功'); - handleGetPrescription(); + handleGetPrescription(true); } else { proxy.$modal.msgError(res.msg || '操作失败'); } @@ -543,7 +544,7 @@ function handleCancel() { adviceCancel({ adviceExecuteDetailList: producerIds }).then((res) => { if (res.code == 200) { proxy.$modal.msgSuccess(res.msg || '取消执行成功'); - handleGetPrescription(); + handleGetPrescription(true); } else { proxy.$modal.msgError(res.msg || '取消执行失败'); }