diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/IDoctorStationAdviceAppService.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/IDoctorStationAdviceAppService.java index 76da432c7..641ad4db7 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/IDoctorStationAdviceAppService.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/IDoctorStationAdviceAppService.java @@ -147,4 +147,6 @@ public interface IDoctorStationAdviceAppService { */ IPage getSurgeryPage(Long organizationId, Integer pageNo, Integer pageSize, String searchKey); + IPage getExaminationPage(Long organizationId, Integer pageNo, Integer pageSize, String searchKey); + } diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java index 5283f5630..81ac08532 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java @@ -2456,4 +2456,14 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp return result; } + @Override + public IPage getExaminationPage(Long organizationId, Integer pageNo, Integer pageSize, String searchKey) { + IPage result = doctorStationAdviceAppMapper.getExaminationPage( + new Page<>(pageNo, pageSize), + PublicationStatus.ACTIVE.getValue(), + organizationId, + searchKey); + return result; + } + } diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/controller/DoctorStationAdviceController.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/controller/DoctorStationAdviceController.java index adaa524f7..84b833343 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/controller/DoctorStationAdviceController.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/controller/DoctorStationAdviceController.java @@ -221,4 +221,13 @@ public class DoctorStationAdviceController { return R.ok(iDoctorStationAdviceAppService.getSurgeryPage(organizationId, pageNo, pageSize, searchKey)); } + @GetMapping(value = "/examination-page") + public R getExaminationPage( + @RequestParam(value = "organizationId", required = false) Long organizationId, + @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(value = "pageSize", defaultValue = "500") Integer pageSize, + @RequestParam(value = "searchKey", defaultValue = "") String searchKey) { + return R.ok(iDoctorStationAdviceAppService.getExaminationPage(organizationId, pageNo, pageSize, searchKey)); + } + } diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/mapper/DoctorStationAdviceAppMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/mapper/DoctorStationAdviceAppMapper.java index 64e7f2adc..b14fdb214 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/mapper/DoctorStationAdviceAppMapper.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/mapper/DoctorStationAdviceAppMapper.java @@ -199,4 +199,9 @@ public interface DoctorStationAdviceAppMapper { @Param("organizationId") Long organizationId, @Param("searchKey") String searchKey); + IPage getExaminationPage(@Param("page") Page page, + @Param("statusEnum") Integer statusEnum, + @Param("organizationId") Long organizationId, + @Param("searchKey") String searchKey); + } diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/doctorstation/DoctorStationAdviceAppMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/doctorstation/DoctorStationAdviceAppMapper.xml index 5c57e9ad3..c8bbfdbdd 100755 --- a/openhis-server-new/openhis-application/src/main/resources/mapper/doctorstation/DoctorStationAdviceAppMapper.xml +++ b/openhis-server-new/openhis-application/src/main/resources/mapper/doctorstation/DoctorStationAdviceAppMapper.xml @@ -836,4 +836,29 @@ ORDER BY t1.name ASC + + + \ No newline at end of file diff --git a/openhis-server-new/openhis-application/src/main/resources/mapper/personalization/OrdersGroupPackageAppMapper.xml b/openhis-server-new/openhis-application/src/main/resources/mapper/personalization/OrdersGroupPackageAppMapper.xml index e32d41578..7b428ba37 100755 --- a/openhis-server-new/openhis-application/src/main/resources/mapper/personalization/OrdersGroupPackageAppMapper.xml +++ b/openhis-server-new/openhis-application/src/main/resources/mapper/personalization/OrdersGroupPackageAppMapper.xml @@ -44,7 +44,9 @@ sdd.dict_label AS unit_code_name, togpd.dose AS dose, togpd.rate_code AS rate_code, + rate_d.dict_label AS rate_code_dictText, togpd.method_code AS method_code, + method_d.dict_label AS method_code_dictText, togpd.dose_quantity AS dose_quantity, togpd.group_id, togpd.group_order AS group_order, @@ -67,8 +69,9 @@ AND togpd.order_definition_id = adm.ID LEFT JOIN wor_activity_definition AS wor ON togpd.order_definition_table = 'wor_activity_definition' AND togpd.order_definition_id = wor.ID - LEFT JOIN sys_dict_data AS sdd ON sdd.dict_value = togpd.unit_code AND sdd.dict_type = 'unit_code' AND - sdd.status = '0' + LEFT JOIN sys_dict_data AS sdd ON sdd.dict_value = togpd.unit_code AND sdd.dict_type = 'unit_code' AND sdd.status = '0' + LEFT JOIN sys_dict_data AS rate_d ON rate_d.dict_value = togpd.rate_code AND rate_d.dict_type = 'rate_code' AND rate_d.status = '0' + LEFT JOIN sys_dict_data AS method_d ON method_d.dict_value = togpd.method_code AND method_d.dict_type = 'method_code' AND method_d.status = '0' WHERE togpd.delete_flag = '0' AND togpd.group_package_id IN diff --git a/openhis-ui-vue3/src/views/doctorstation/components/prescription/orderGroupDrawer.vue b/openhis-ui-vue3/src/views/doctorstation/components/prescription/orderGroupDrawer.vue index 21d059bb4..3db8e33e5 100755 --- a/openhis-ui-vue3/src/views/doctorstation/components/prescription/orderGroupDrawer.vue +++ b/openhis-ui-vue3/src/views/doctorstation/components/prescription/orderGroupDrawer.vue @@ -564,22 +564,74 @@ function handleRemoveItem(index) { editingGroup.value.detailList.splice(index, 1); } -// 单击应用按钮 -function handleUseOrderGroup(row) { +// 单击应用按钮(应用组套) +async function handleUseOrderGroup(row) { if (!row.detailList || row.detailList.length === 0) { ElMessage.warning('该组套没有明细项'); return; } + + // 🔧 Bug 修复:组套保存时未持久化 orderDetailInfos,导致应用时缺失医嘱库信息。 + // 通过 API 批量查询补全,确保 setValue 能获取到 adviceType、inventoryList、priceList 等关键字段。 + const itemsMissingDetail = row.detailList.filter( + item => !item.orderDetailInfos || Object.keys(item.orderDetailInfos).length === 0 + ); + const detailMap = {}; + if (itemsMissingDetail.length > 0) { + const ids = itemsMissingDetail + .map(item => item.orderDefinitionId) + .filter(Boolean) + .join(','); + if (ids) { + try { + const res = await getAdviceBaseInfo({ + adviceDefinitionIdParamList: ids, + organizationId: props.organizationId, + }); + const records = res.data?.records || res.rows || []; + records.forEach(rec => { + if (rec.adviceDefinitionId) { + detailMap[rec.adviceDefinitionId] = rec; + } + }); + } catch (e) { + // 批量查询失败,使用原始 orderDetailInfos + } + } + } + + // 🔧 辅助函数:根据字典 code 查找对应的 dictText + const findDictText = (dictList, code) => { + if (!code || !dictList?.value?.length) return ''; + const found = dictList.value.find(d => d.value === code); + return found?.label || ''; + }; // 🔧 数据预处理:确保每个明细项都有完整的医嘱信息 const processedDetailList = row.detailList.map(item => { - const orderDetail = item.orderDetailInfos || {}; + // 优先使用组套中已带的 orderDetailInfos,否则使用 API 查询结果 + const orderDetail = (item.orderDetailInfos && Object.keys(item.orderDetailInfos).length > 0) + ? item.orderDetailInfos + : (detailMap[item.orderDefinitionId] || {}); + // 🔧 修复:组套明细只存了 methodCode/rateCode,没有 dictText。 + // 用字典查找补充 dictText,确保界面显示正确的用法/频次名称。 + const resolvedMethodCode = item.methodCode ?? orderDetail.methodCode; + const resolvedRateCode = item.rateCode ?? orderDetail.rateCode; + const methodCodeDictText = item.methodCode_dictText + || findDictText(method_code, resolvedMethodCode) + || orderDetail.methodCode_dictText + || ''; + const rateCodeDictText = item.rateCode_dictText + || findDictText(rate_code, resolvedRateCode) + || orderDetail.rateCode_dictText + || ''; + return { // 组套明细字段 ...item, - // 医嘱库字段(可能为空,需要兜底) + // 医嘱库字段 adviceName: orderDetail.adviceName || item.orderDefinitionName || '未知项目', adviceType: orderDetail.adviceType, adviceDefinitionId: item.orderDefinitionId || orderDetail.adviceDefinitionId, @@ -592,7 +644,6 @@ function handleUseOrderGroup(row) { partPercent: orderDetail.partPercent ?? 1, partAttributeEnum: orderDetail.partAttributeEnum, unitConversionRatio: orderDetail.unitConversionRatio, - // 🔧 Bug #218 修复:positionId 可能存储在 item 本身,优先使用 item.positionId positionId: item.positionId ?? orderDetail.positionId, defaultLotNumber: orderDetail.defaultLotNumber, @@ -602,6 +653,10 @@ function handleUseOrderGroup(row) { unitCodeName: item.unitCodeName || orderDetail.unitCode_dictText, minUnitCode: orderDetail.minUnitCode, doseUnitCode: orderDetail.doseUnitCode, + + // 字典文本(传递到 item 层级,避免后续代码依赖 mergedDetail 再查一次) + methodCode_dictText: methodCodeDictText, + rateCode_dictText: rateCodeDictText, // 合并后的完整对象(用于 setValue) // 先展开 orderDetail 获取所有药品基础字段(categoryCode、minUnitCode、doseUnitCode、 @@ -616,19 +671,19 @@ function handleUseOrderGroup(row) { categoryCode: item.categoryCode ?? orderDetail.categoryCode, unitCodeName: item.unitCodeName, dose: item.dose ?? orderDetail.dose, - rateCode: item.rateCode ?? orderDetail.rateCode, - methodCode: item.methodCode ?? orderDetail.methodCode, + rateCode: resolvedRateCode, + rateCode_dictText: rateCodeDictText, + methodCode: resolvedMethodCode, + methodCode_dictText: methodCodeDictText, dispensePerDuration: item.dispensePerDuration ?? orderDetail.dispensePerDuration, doseQuantity: item.doseQuantity ?? orderDetail.doseQuantity, - // 🔧 Bug #218 / #403 修复:positionId 可能存储在 item 本身,优先使用 item.positionId positionId: item.positionId ?? orderDetail.positionId, - // 执行科室:优先使用组套明细中保存的 orgId orgId: item.orgId ?? orderDetail.orgId, orgName: item.orgName ?? orderDetail.orgName, - // 组号(保留组套中的分组信息) groupId: item.groupId, groupOrder: item.groupOrder, - therapyEnum: item.therapyEnum ?? orderDetail.therapyEnum ?? '1', + // 🔧 类型默认为临时医嘱(2=临时,1=长期) + therapyEnum: item.therapyEnum ?? orderDetail.therapyEnum ?? '2', } }; }); @@ -645,9 +700,9 @@ function handlePreviewGroup(row) { } // 确认应用组套(从预览对话框) -function confirmUseGroup() { +async function confirmUseGroup() { if (currentGroup.value) { - handleUseOrderGroup(currentGroup.value); + await handleUseOrderGroup(currentGroup.value); previewVisible.value = false; } } diff --git a/openhis-ui-vue3/src/views/doctorstation/components/prescription/prescriptionlist.vue b/openhis-ui-vue3/src/views/doctorstation/components/prescription/prescriptionlist.vue index cd137662c..0bfa62f3d 100755 --- a/openhis-ui-vue3/src/views/doctorstation/components/prescription/prescriptionlist.vue +++ b/openhis-ui-vue3/src/views/doctorstation/components/prescription/prescriptionlist.vue @@ -3662,6 +3662,13 @@ function handleSaveGroup(orderGroupList) { defaultLotNumber: item.orderDetailInfos?.defaultLotNumber, }; + // 🔧 Bug 修复:字典查找兜底,防止 mergedDetail 中 dictText 为空 + const findDictText = (dictList, code) => { + if (!code || !dictList?.length) return ''; + const found = dictList.find(d => d.value === code); + return found?.label || ''; + }; + // 在 setValue 之前预初始化空行 prescriptionList.value[rowIndex.value] = { uniqueKey: nextId.value++, @@ -3672,43 +3679,105 @@ function handleSaveGroup(orderGroupList) { // 使用医嘱项目详情设置值 setValue(mergedDetail); + // 🔧 Bug 修复:使用 mergedDetail 优先,避免 item 中 undefined 覆盖 setValue 中已设置的字段 + const resolvedQuantity = mergedDetail.quantity ?? item.quantity ?? 1; + const resolvedDose = mergedDetail.dose ?? item.dose; + const resolvedMethodCode = mergedDetail.methodCode ?? item.methodCode; + const resolvedRateCode = mergedDetail.rateCode ?? item.rateCode; + const resolvedUnitCode = mergedDetail.unitCode ?? item.unitCode; + + // 🔧 Bug 修复:setValue 可能因库存不足提前 return,导致 unitPrice/minUnitPrice 等字段未设置。 + // 从 mergedDetail 或 item 中获取兜底值,避免价格计算产生 NaN。 + const safePrice = (val) => { + const n = Number(val); + return (n !== undefined && n !== null && !isNaN(n) && isFinite(n)) ? n : 0; + }; + const resolvedUnitPrice = safePrice( + prescriptionList.value[rowIndex.value]?.unitPrice + ?? mergedDetail.unitPrice + ?? item.unitPrice + ?? 0 + ); + const resolvedMinUnitPrice = safePrice( + prescriptionList.value[rowIndex.value]?.minUnitPrice + ?? mergedDetail.minUnitPrice + ?? item.minUnitPrice + ?? 0 + ); + const resolvedPartPercent = safePrice( + item.orderDetailInfos?.partPercent + ?? mergedDetail.partPercent + ?? 1 + ); + // 创建新的处方项目 const newRow = { ...prescriptionList.value[rowIndex.value], patientId: props.patientInfo.patientId, encounterId: props.patientInfo.encounterId, accountId: accountId.value, - quantity: item.quantity, - methodCode: item.methodCode, - rateCode: item.rateCode, - dispensePerDuration: item.dispensePerDuration, - dose: item.dose, - doseQuantity: item.doseQuantity, + quantity: resolvedQuantity, + methodCode: resolvedMethodCode, + methodCode_dictText: mergedDetail.methodCode_dictText + || findDictText(method_code.value, resolvedMethodCode) + || '', + rateCode: resolvedRateCode, + rateCode_dictText: mergedDetail.rateCode_dictText + || findDictText(rate_code.value, resolvedRateCode) + || '', + dispensePerDuration: mergedDetail.dispensePerDuration ?? item.dispensePerDuration, + dose: resolvedDose, + doseQuantity: mergedDetail.doseQuantity ?? item.doseQuantity, executeNum: 1, - unitCode: item.unitCode, - unitCode_dictText: item.unitCodeName || '', + unitCode: resolvedUnitCode, + unitCode_dictText: item.unitCodeName + || mergedDetail.unitCodeName + || findDictText(unit_code.value, resolvedUnitCode) + || '', + doseUnitCode: mergedDetail.doseUnitCode, + doseUnitCode_dictText: mergedDetail.doseUnitCode_dictText || '', + // 🔧 确保 price/adviceType 字段有安全默认值(避免 NaN 导致模板条件判断失效) + unitPrice: resolvedUnitPrice, + minUnitPrice: resolvedMinUnitPrice, + unitTempPrice: resolvedUnitPrice, + adviceType: prescriptionList.value[rowIndex.value]?.adviceType + || Number(mergedDetail.adviceType) + || Number(item.adviceType) + || 0, + adviceType_dictText: prescriptionList.value[rowIndex.value]?.adviceType_dictText + || mergedDetail.adviceType_dictText + || item.adviceType_dictText + || '', statusEnum: 1, + // 🔧 类型:组套应用默认为临时医嘱(2=临时,1=长期) + therapyEnum: mergedDetail.therapyEnum ?? item.therapyEnum ?? '2', // 🔧 修复执行科室逻辑:优先使用 orgId(所属科室),其次 positionId // 🔧 Bug #455: 诊疗类(adviceType=3)使用患者就诊科室,不使用目录配置的ID orgId: item.adviceType === 3 ? props.patientInfo?.orgId : (item.orderDetailInfos?.orgId || mergedDetail.orgId || item.positionId || item.orderDetailInfos?.positionId || mergedDetail.positionId), + positionName: prescriptionList.value[rowIndex.value]?.positionName + || mergedDetail.orgName + || mergedDetail.positionName + || findOrgNameById(mergedDetail.orgId || props.patientInfo?.orgId) + || '', dbOpType: prescriptionList.value[rowIndex.value].requestId ? '2' : '1', conditionId: conditionId.value, conditionDefinitionId: conditionDefinitionId.value, encounterDiagnosisId: encounterDiagnosisId.value, + diagnosisName: diagnosisName.value, }; - // 计算价格和总量 - const unitInfo = unitCodeList.value.find((k) => k.value == item.unitCode); + // 计算价格和总量(使用安全值) + const unitInfo = unitCodeList.value.find((k) => k.value == resolvedUnitCode); if (unitInfo && unitInfo.type == 'minUnit') { - newRow.price = newRow.minUnitPrice; - newRow.totalPrice = (item.quantity * newRow.minUnitPrice).toFixed(6); - newRow.minUnitQuantity = item.quantity; + newRow.price = resolvedMinUnitPrice; + newRow.totalPrice = (resolvedQuantity * resolvedMinUnitPrice).toFixed(6); + newRow.minUnitQuantity = resolvedQuantity; } else { - newRow.price = newRow.unitPrice; - newRow.totalPrice = (item.quantity * newRow.unitPrice).toFixed(6); - newRow.minUnitQuantity = item.quantity * (item.orderDetailInfos?.partPercent || mergedDetail.partPercent || 1); + newRow.price = resolvedUnitPrice; + newRow.totalPrice = (resolvedQuantity * resolvedUnitPrice).toFixed(6); + newRow.minUnitQuantity = resolvedQuantity * resolvedPartPercent; } newRow.contentJson = JSON.stringify(newRow); diff --git a/openhis-ui-vue3/src/views/inpatientDoctor/home/components/applicationShow/examineApplication.vue b/openhis-ui-vue3/src/views/inpatientDoctor/home/components/applicationShow/examineApplication.vue index f8979e466..9ee386e8a 100755 --- a/openhis-ui-vue3/src/views/inpatientDoctor/home/components/applicationShow/examineApplication.vue +++ b/openhis-ui-vue3/src/views/inpatientDoctor/home/components/applicationShow/examineApplication.vue @@ -220,6 +220,7 @@ :is-edit-mode="true" :edit-data="editingRow" :external-patient-info="patientInfo" + @submit-ok="handleEditSuccess" />