Fix Bug #403: 住院医生工作站:应用医嘱组套后,药品明细字段内容丢失未正确引入表格

根因分析:
1. orderGroupDrawer.vue 中 handleUseOrderGroup 的 mergedDetail 对象缺少
   categoryCode、minUnitCode、doseUnitCode、partPercent、partAttributeEnum、
   unitConversionRatio、defaultLotNumber 等关键字段,导致 setValue 和价格计算逻辑失效
2. 使用 || 替代 ?? 作为数字字段(如 doseQuantity=0)的回退操作符,导致值为 0 时被错误覆盖
3. handleSaveGroup 中价格计算使用 item.unitCode 查找 unitInfo,但 item.unitCode 可能为
   undefined,而 setValue 已正确填充了 prescriptionList 中的 unitCode

修复内容:
- mergedDetail 先展开 orderDetail(包含所有药品基础字段),再用组套用户覆盖值覆盖
- 所有数字字段回退从 || 改为 ??,确保 0 值不被覆盖
- 新增 doseQuantity 的 ?? 回退逻辑到 orderDetail.doseQuantity
- 新增 groupId、groupOrder、orgId、orgName、therapyEnum 到 mergedDetail
- handleSaveGroup 使用 baseRow 变量避免对象自引用问题
- 价格计算使用 newRow.unitCode(已由 setValue 填充)而非 item.unitCode

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
赵云
2026-05-14 00:18:24 +08:00
parent 55eba1a0b1
commit 53e3e9c4c0
2 changed files with 48 additions and 30 deletions

View File

@@ -589,36 +589,46 @@ function handleUseOrderGroup(row) {
minUnitPrice: orderDetail.minUnitPrice, minUnitPrice: orderDetail.minUnitPrice,
inventoryList: orderDetail.inventoryList || [], inventoryList: orderDetail.inventoryList || [],
priceList: orderDetail.priceList || [], priceList: orderDetail.priceList || [],
partPercent: orderDetail.partPercent || 1, partPercent: orderDetail.partPercent ?? 1,
partAttributeEnum: orderDetail.partAttributeEnum,
unitConversionRatio: orderDetail.unitConversionRatio,
// 🔧 Bug #218 修复positionId 可能存储在 item 本身,优先使用 item.positionId // 🔧 Bug #218 修复positionId 可能存储在 item 本身,优先使用 item.positionId
positionId: item.positionId || orderDetail.positionId, positionId: item.positionId ?? orderDetail.positionId,
defaultLotNumber: orderDetail.defaultLotNumber, defaultLotNumber: orderDetail.defaultLotNumber,
// 单位信息 // 单位信息
unitCode: item.unitCode || orderDetail.unitCode, unitCode: item.unitCode ?? orderDetail.unitCode,
categoryCode: item.categoryCode ?? orderDetail.categoryCode,
unitCodeName: item.unitCodeName || orderDetail.unitCode_dictText, unitCodeName: item.unitCodeName || orderDetail.unitCode_dictText,
minUnitCode: orderDetail.minUnitCode, minUnitCode: orderDetail.minUnitCode,
doseUnitCode: orderDetail.doseUnitCode, doseUnitCode: orderDetail.doseUnitCode,
// 合并后的完整对象(用于 setValue // 合并后的完整对象(用于 setValue
// 先展开 orderDetail 获取所有药品基础字段categoryCode、minUnitCode、doseUnitCode、
// partPercent、partAttributeEnum、unitConversionRatio、defaultLotNumber 等),
// 再用组套用户覆盖值覆盖,确保单次剂量/频次/用法/用药天数/总量等不被丢失
mergedDetail: { mergedDetail: {
...orderDetail, ...orderDetail,
adviceName: orderDetail.adviceName || item.orderDefinitionName || '未知项目', adviceName: orderDetail.adviceName || item.orderDefinitionName || '未知项目',
adviceType: orderDetail.adviceType, adviceType: orderDetail.adviceType,
quantity: item.quantity, quantity: item.quantity,
unitCode: item.unitCode || orderDetail.unitCode, unitCode: item.unitCode ?? orderDetail.unitCode,
categoryCode: item.categoryCode ?? orderDetail.categoryCode,
unitCodeName: item.unitCodeName, unitCodeName: item.unitCodeName,
dose: item.dose || orderDetail.dose, dose: item.dose ?? orderDetail.dose,
rateCode: item.rateCode || orderDetail.rateCode, rateCode: item.rateCode ?? orderDetail.rateCode,
methodCode: item.methodCode || orderDetail.methodCode, methodCode: item.methodCode ?? orderDetail.methodCode,
dispensePerDuration: item.dispensePerDuration || orderDetail.dispensePerDuration, dispensePerDuration: item.dispensePerDuration ?? orderDetail.dispensePerDuration,
doseQuantity: item.doseQuantity, doseQuantity: item.doseQuantity ?? orderDetail.doseQuantity,
inventoryList: orderDetail.inventoryList || [], // 🔧 Bug #218 / #403 修复positionId 可能存储在 item 本身,优先使用 item.positionId
priceList: orderDetail.priceList || [], positionId: item.positionId ?? orderDetail.positionId,
partPercent: orderDetail.partPercent || 1, // 执行科室:优先使用组套明细中保存的 orgId
// 🔧 Bug #218 修复positionId 可能存储在 item 本身,优先使用 item.positionId orgId: item.orgId ?? orderDetail.orgId,
positionId: item.positionId || orderDetail.positionId, orgName: item.orgName ?? orderDetail.orgName,
defaultLotNumber: orderDetail.defaultLotNumber, // 组号(保留组套中的分组信息)
groupId: item.groupId,
groupOrder: item.groupOrder,
therapyEnum: item.therapyEnum ?? orderDetail.therapyEnum ?? '1',
} }
}; };
}); });

View File

@@ -1639,20 +1639,14 @@ function handleSaveGroup(orderGroupList) {
// 创建新的处方项目 // 创建新的处方项目
// 🔧 Bug #403 修复:关键字段使用 null-safe 回退到 mergedDetail已由 setValue 填充完整数据) // 🔧 Bug #403 修复:关键字段使用 null-safe 回退到 mergedDetail已由 setValue 填充完整数据)
// 先取 setValue 填充的行数据作为基础
const baseRow = prescriptionList.value[rowIndex.value];
const newRow = { const newRow = {
...prescriptionList.value[rowIndex.value], ...baseRow,
patientId: patientInfo.value.patientId, patientId: patientInfo.value.patientId,
encounterId: patientInfo.value.encounterId, encounterId: patientInfo.value.encounterId,
accountId: accountId.value, accountId: accountId.value,
quantity: item.quantity ?? mergedDetail.quantity,
methodCode: item.methodCode ?? mergedDetail.methodCode,
rateCode: item.rateCode ?? mergedDetail.rateCode,
dispensePerDuration: item.dispensePerDuration ?? mergedDetail.dispensePerDuration,
dose: item.dose ?? mergedDetail.dose,
doseQuantity: item.doseQuantity ?? mergedDetail.doseQuantity,
executeNum: 1, executeNum: 1,
unitCode: item.unitCode ?? mergedDetail.unitCode,
unitCode_dictText: item.unitCodeName || mergedDetail.unitCodeName || '',
statusEnum: 1, statusEnum: 1,
orgId: resolveOrgId(item.orderDetailInfos?.orgId || mergedDetail.orgId || patientInfo.value?.inHospitalOrgId) || '', orgId: resolveOrgId(item.orderDetailInfos?.orgId || mergedDetail.orgId || patientInfo.value?.inHospitalOrgId) || '',
// 🔧 修复:同时保存 orgName确保树匹配不到时仍有中文名称可显示 // 🔧 修复:同时保存 orgName确保树匹配不到时仍有中文名称可显示
@@ -1661,19 +1655,33 @@ function handleSaveGroup(orderGroupList) {
conditionId: conditionId.value, conditionId: conditionId.value,
conditionDefinitionId: conditionDefinitionId.value, conditionDefinitionId: conditionDefinitionId.value,
encounterDiagnosisId: encounterDiagnosisId.value, encounterDiagnosisId: encounterDiagnosisId.value,
therapyEnum: prescriptionList.value[rowIndex.value]?.therapyEnum || '1', therapyEnum: baseRow?.therapyEnum || '1',
}; };
// 覆盖关键字段:优先使用 item 的值,其次 mergedDetail已由 setValue 填充),最后 baseRow
newRow.quantity = item.quantity ?? mergedDetail.quantity ?? baseRow.quantity;
newRow.methodCode = item.methodCode ?? mergedDetail.methodCode ?? baseRow.methodCode;
newRow.rateCode = item.rateCode ?? mergedDetail.rateCode ?? baseRow.rateCode;
newRow.dispensePerDuration = item.dispensePerDuration ?? mergedDetail.dispensePerDuration ?? baseRow.dispensePerDuration;
newRow.dose = item.dose ?? mergedDetail.dose ?? baseRow.dose;
newRow.doseQuantity = item.doseQuantity ?? mergedDetail.doseQuantity ?? baseRow.doseQuantity;
newRow.unitCode = item.unitCode ?? mergedDetail.unitCode ?? baseRow.unitCode;
newRow.unitCode_dictText = item.unitCodeName || mergedDetail.unitCodeName || baseRow.unitCode_dictText || '';
// 计算价格和总量 // 计算价格和总量
const unitInfo = unitCodeList.value.find((k) => k.value == item.unitCode); // 🔧 Bug #403 修复:使用 newRow.unitCode已由 setValue 填充)而非 item.unitCode
// 使用 ?? 替代 || 计算 partPercent确保值为 0 时不会被错误替换
const finalUnitCode = newRow.unitCode;
const unitInfo = unitCodeList.value.find((k) => k.value == finalUnitCode);
const finalQuantity = newRow.quantity;
const partPercent = item.orderDetailInfos?.partPercent ?? mergedDetail.partPercent ?? baseRow.partPercent ?? 1;
if (unitInfo && unitInfo.type == 'minUnit') { if (unitInfo && unitInfo.type == 'minUnit') {
newRow.price = newRow.minUnitPrice; newRow.price = newRow.minUnitPrice;
newRow.totalPrice = (item.quantity * newRow.minUnitPrice).toFixed(6); newRow.totalPrice = ((finalQuantity || 0) * newRow.minUnitPrice).toFixed(6);
newRow.minUnitQuantity = item.quantity; newRow.minUnitQuantity = finalQuantity || 0;
} else { } else {
newRow.price = newRow.unitPrice; newRow.price = newRow.unitPrice;
newRow.totalPrice = (item.quantity * newRow.unitPrice).toFixed(6); newRow.totalPrice = ((finalQuantity || 0) * newRow.unitPrice).toFixed(6);
newRow.minUnitQuantity = item.quantity * (item.orderDetailInfos?.partPercent || mergedDetail.partPercent || 1); newRow.minUnitQuantity = (finalQuantity || 0) * partPercent;
} }
newRow.contentJson = JSON.stringify(newRow); newRow.contentJson = JSON.stringify(newRow);