Fix Bug #480: [住院护士站-医嘱执行] 非耗材类医嘱执行报"耗材库存"错误且全选逻辑联动异常

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 <noreply@anthropic.com>
This commit is contained in:
关羽
2026-05-12 12:18:49 +08:00
parent c8fa9b4bf0
commit 01d48c75a5

View File

@@ -270,7 +270,7 @@ function normalizeDayTimeHm(part) {
return `${h}:${m}`; return `${h}:${m}`;
} }
function handleGetPrescription() { function handleGetPrescription(skipAutoSelectAll = false) {
if (patientInfoList.value.length > 0) { if (patientInfoList.value.length > 0) {
loading.value = true; loading.value = true;
let encounterIds = patientInfoList.value.map((i) => i.encounterId).join(','); let encounterIds = patientInfoList.value.map((i) => i.encounterId).join(',');
@@ -430,10 +430,12 @@ function handleGetPrescription() {
// 将分组结果转换为数组形式 // 将分组结果转换为数组形式
prescriptionList.value = Object.values(groupedPrescriptions); prescriptionList.value = Object.values(groupedPrescriptions);
// 默认选中全部行 // 默认选中全部行(执行后刷新时不自动全选,保持用户操作状态)
nextTick(() => { if (!skipAutoSelectAll) {
defaultSelectAllRows(); nextTick(() => {
}); defaultSelectAllRows();
});
}
} catch (error) { } catch (error) {
console.error('医嘱执行-获取处方列表数据处理失败:', error); console.error('医嘱执行-获取处方列表数据处理失败:', error);
prescriptionList.value = []; prescriptionList.value = [];
@@ -469,18 +471,17 @@ function handleExecute() {
console.log(list, 'list'); console.log(list, 'list');
adviceExecute({ exeDate: exeDate.value, adviceExecuteDetailList: list }).then((res) => { adviceExecute({ exeDate: exeDate.value, adviceExecuteDetailList: list }).then((res) => {
if (res.code == 200) { if (res.code == 200) {
handleGetPrescription(); // 仅当选中医嘱中包含耗材类医嘱时,才调用耗材批号匹配(排除纯药品医嘱场景)
// 仅当选中医嘱中包含药品/耗材类医嘱时,才调用耗材批号匹配 const hasDevice = list.some((item) =>
const hasMedOrDevice = list.some( String(item.adviceTable || '').includes('device'),
(item) =>
item.adviceTable === 'med_medication_request' ||
String(item.adviceTable || '').includes('device'),
); );
if (hasMedOrDevice) { if (hasDevice) {
lotNumberMatch({ encounterIdList: encounterIds }, { skipErrorMsg: true }).catch((error) => { lotNumberMatch({ encounterIdList: encounterIds }, { skipErrorMsg: true }).catch((error) => {
console.warn('lotNumberMatch failed after adviceExecute:', error); console.warn('lotNumberMatch failed after adviceExecute:', error);
}); });
} }
// 刷新列表(不自动全选,保持用户操作前的选择状态)
handleGetPrescription(true);
proxy.$modal.msgSuccess(res.msg || '医嘱执行成功'); proxy.$modal.msgSuccess(res.msg || '医嘱执行成功');
} else { } else {
proxy.$modal.msgError(res.msg || '医嘱执行失败'); proxy.$modal.msgError(res.msg || '医嘱执行失败');
@@ -504,7 +505,7 @@ function handleNoExecute() {
adviceNoExecute({ adviceExecuteDetailList: list }).then((res) => { adviceNoExecute({ adviceExecuteDetailList: list }).then((res) => {
if (res.code == 200) { if (res.code == 200) {
proxy.$modal.msgSuccess(res.msg || '操作成功'); proxy.$modal.msgSuccess(res.msg || '操作成功');
handleGetPrescription(); handleGetPrescription(true);
} else { } else {
proxy.$modal.msgError(res.msg || '操作失败'); proxy.$modal.msgError(res.msg || '操作失败');
} }
@@ -543,7 +544,7 @@ function handleCancel() {
adviceCancel({ adviceExecuteDetailList: producerIds }).then((res) => { adviceCancel({ adviceExecuteDetailList: producerIds }).then((res) => {
if (res.code == 200) { if (res.code == 200) {
proxy.$modal.msgSuccess(res.msg || '取消执行成功'); proxy.$modal.msgSuccess(res.msg || '取消执行成功');
handleGetPrescription(); handleGetPrescription(true);
} else { } else {
proxy.$modal.msgError(res.msg || '取消执行失败'); proxy.$modal.msgError(res.msg || '取消执行失败');
} }