100 手术安排界面:增加【医嘱】按钮弹出门诊术中临时医嘱生成界面

This commit is contained in:
Ranyunqiao
2026-04-10 15:01:26 +08:00
parent 74e28be0b0
commit d052d268f5
9 changed files with 1314 additions and 265 deletions

View File

@@ -143,7 +143,7 @@
<!-- 弹窗头部操作按钮 -->
<div class="dialog-header-buttons" v-if="!isViewMode && !isEditMode">
<el-button @click="handleFindApply">查找</el-button>
<el-button @click="handleRefresh">刷新</el-button>
<el-button class="refresh-btn" @click="handleRefresh">刷新</el-button>
<el-button @click="cancel">返回</el-button>
<el-button type="primary" :disabled="isViewMode" @click="submitForm">保存</el-button>
</div>
@@ -837,21 +837,28 @@
</el-dialog>
<!-- 临时医嘱弹窗 -->
<el-dialog :title="temporaryMedicalTitle" v-model="showTemporaryMedical" width="80%" append-to-body :close-on-click-modal="false">
<el-dialog title="" v-model="showTemporaryMedical" width="80%" append-to-body :close-on-click-modal="false">
<!-- 🔧 新增加载状态提示 -->
<div v-if="temporaryMedicalLoading" class="loading-container">
<el-icon class="is-loading"><loading /></el-icon>
<span>正在加载医嘱数据请稍候...</span>
</div>
<temporary-medical
v-else
:patient-info="temporaryPatientInfo"
:billing-medicines="temporaryBillingMedicines"
v-model:temporary-advices="temporaryAdvices"
@submit="handleTemporaryMedicalSubmit"
@cancel="handleTemporaryMedicalCancel"
@delete-advice="handleDeleteTemporaryAdvice"
@refresh="handleTemporaryMedicalRefresh"
@quote-billing="handleQuoteBilling"
/>
</el-dialog>
</div>
</template>
<script setup name="SurgicalSchedule">
import { ref, reactive, onMounted, nextTick, computed } from 'vue'
import { ref, reactive, onMounted, nextTick, computed, watch } from 'vue'
import { getCurrentInstance } from 'vue'
import { parseTime } from '@/utils/openhis'
import { useDict } from '@/utils/dict'
@@ -859,6 +866,7 @@ import download from '@/plugins/download'
import Prescriptionlist from '@/views/clinicmanagement/bargain/component/prescriptionlist.vue'
import useUserStore from '@/store/modules/user'
import { ElMessage } from 'element-plus'
import { Loading } from '@element-plus/icons-vue' // 🔧 新增:导入 Loading 图标
// 导入计费相关接口
import { getPrescriptionList } from '@/views/clinicmanagement/bargain/component/api'
@@ -1013,6 +1021,17 @@ const temporaryPatientInfo = ref({})
const temporaryBillingMedicines = ref([])
const temporaryAdvices = ref([])
// 🔧 新增:监听 temporaryAdvices 的变化,用于调试
watch(temporaryAdvices, (newVal, oldVal) => {
console.log('=== temporaryAdvices 变化 ===')
console.log('=== 新值 ===', newVal)
console.log('=== 新值[1]?.dosage ===', newVal[1]?.dosage)
console.log('=== 旧值 ===', oldVal)
console.log('=== 旧值[1]?.dosage ===', oldVal[1]?.dosage)
}, { deep: true })
const temporaryMedicalLoading = ref(false) // 🔧 新增:临时医嘱加载状态
// 下拉列表数据
const orgList = ref([])
const deptList = ref([])
@@ -1067,8 +1086,9 @@ const {
isolation_type: isolationTypeList,
surgery_type,
surgery_level,
surgery_nature: surgeryNatureList
} = useDict('surgical_site', 'anesthesia_type', 'incision_level', 'isolation_type', 'surgery_type', 'surgery_level', 'surgery_nature')
surgery_nature: surgeryNatureList,
method_code
} = useDict('surgical_site', 'anesthesia_type', 'incision_level', 'isolation_type', 'surgery_type', 'surgery_level', 'surgery_nature', 'method_code')
// 加载数据
onMounted(() => {
@@ -1370,19 +1390,22 @@ function closeChargeDialog() {
chargeSurgeryInfo.value = {}
}
// 🔧 新增:标志位,用于区分是"打开"还是"刷新"
const isRefreshAction = ref(false)
// 处理医嘱按钮点击事件
function handleMedicalAdvice(row) {
// 如果没有传入行数据,使用选中的行
if (!row && selectedRow.value) {
row = selectedRow.value
}
// 如果还是没有行数据,显示提示
if (!row) {
proxy.$modal.msgWarning('请先选择要开具医嘱的手术安排')
return
}
// 设置临时医嘱弹窗数据
temporaryPatientInfo.value = {
patientName: row.patientName,
@@ -1391,55 +1414,119 @@ function handleMedicalAdvice(row) {
roomCode: row.roomCode,
doctorName: userStore.nickName,
role: userStore.roles[0],
effectiveOrgId : row.effectiveOrgId,
orgId: userStore.orgId,
positionId: userStore.orgId
}
// 🔧 关键修复:如果已有提交的医嘱数据,并且是同一个患者的就诊,则使用保存的数据
// 这样可以保留 requestId避免重复创建医嘱记录
console.log('=== 检查是否使用已保存的医嘱数据 ===')
console.log('=== temporaryAdvices.value.length ===', temporaryAdvices.value.length)
console.log('=== temporaryAdvices.value[0]?.originalMedicine?.encounterId ===', temporaryAdvices.value[0]?.originalMedicine?.encounterId)
console.log('=== row.visitId ===', row.visitId)
console.log('=== isRefreshAction.value ===', isRefreshAction.value)
// 初始化临时医嘱列表
const isSameEncounter = temporaryAdvices.value.length > 0 &&
temporaryAdvices.value[0]?.originalMedicine?.encounterId === row.visitId &&
!isRefreshAction.value
console.log('=== isSameEncounter ===', isSameEncounter)
if (isSameEncounter) {
console.log('=== 使用已保存的医嘱数据,避免重复创建 ===')
console.log('=== temporaryAdvices.value[0]?.originalMedicine?.requestId ===', temporaryAdvices.value[0]?.originalMedicine?.requestId)
// 直接打开弹窗,使用已保存的数据
showTemporaryMedical.value = true
temporaryMedicalLoading.value = false
isRefreshAction.value = false // 重置标志位
return
}
// 🔧 修复:每次打开临时医嘱时都重新加载数据,避免使用缓存数据导致数据重复
// 先清空旧数据
temporaryBillingMedicines.value = []
temporaryAdvices.value = []
temporaryMedicalLoading.value = true // 🔧 新增:开始加载
// 调用计费接口获取数据
getPrescriptionList(row.visitId).then((res) => {
console.log('=== 拉取计费数据返回结果 ===', res)
if (res.code === 200 && res.data) {
// 过滤数据,只保留 adviceType 值为 1 的药品
// 🔧 修复:显示所有药品请求数据,不管有没有计费项目
// 根据用户需求:已引用计费药品(待生成医嘱)和临时医嘱预览(已生成)显示的数据应该相同
// 在提交医嘱之前状态应该是"待签发",提交之后变为"已签发"
// 再次打开医嘱界面的时候能看到这两个状态的药品
const seenIds = new Set();
const filteredItems = res.data.filter(item => {
try {
// 尝试从 contentJson 中解析数据
const contentData = JSON.parse(item.contentJson)
const adviceType = Number(contentData.adviceType)
return adviceType === 1
} catch (e) {
// 如果解析失败,尝试使用顶层的 adviceType
const adviceType = Number(item.adviceType)
return adviceType === 1
}
// 匹配 encounterId
if (item.encounterId !== row.visitId) return false;
// 过滤掉名称为空的项目
const medicineName = item.adviceName || item.advice_name;
if (!medicineName || medicineName.trim() === '') return false;
// 根据药品请求ID去重避免重复显示
const itemId = item.requestId || item.id;
if (itemId && seenIds.has(itemId)) return false;
if (itemId) seenIds.add(itemId);
return true;
})
// 将过滤后的数据转换为临时医嘱需要的格式
// 🔧 修复限制返回数量最多显示前100条避免数据过多导致页面卡死
const maxItems = 100
if (filteredItems.length > maxItems) {
ElMessage.warning(`待签发医嘱数量过多(${filteredItems.length}条),仅显示前${maxItems}`)
filteredItems.length = maxItems
}
// 将过滤后的数据转换为临时医嘱需要的格式 - 兼容驼峰和下划线命名
// 对于从 adm_charge_item计费项目表查询来的项目特殊处理
temporaryBillingMedicines.value = filteredItems.map(item => {
try {
// 从 contentJson 中解析详细数据
const contentData = JSON.parse(item.contentJson)
// 从 contentJson 或 content_json 中解析详细数据 - 兼容下划线和驼峰命名
const jsonContent = item.contentJson || item.content_json;
const contentData = jsonContent ? JSON.parse(jsonContent) : {};
return {
medicineName: contentData.adviceName || item.adviceName || '',
specification: contentData.volume || contentData.specification || '',
medicineName: contentData.adviceName || contentData.advice_name || item.adviceName || item.advice_name || '',
specification: contentData.volume || contentData.specification || item.volume || item.specification || '',
quantity: contentData.quantity || item.quantity || 0,
batchNumber: contentData.lotNumber || item.lotNumber || '',
unitPrice: contentData.unitPrice || item.unitPrice || 0,
subtotal: contentData.totalPrice || item.totalPrice || 0,
insuranceType: contentData.insuranceType === 1 ? '医保' : '自费'
}
batchNumber: contentData.lotNumber || contentData.lot_number || item.lotNumber || item.lot_number || '',
unitPrice: contentData.unitPrice || contentData.unit_price || item.unitPrice || item.unit_price || 0,
subtotal: contentData.totalPrice || contentData.total_price || item.totalPrice || item.total_price ||
(contentData.unitPrice || contentData.unit_price || item.unitPrice || item.unit_price || 0) *
(contentData.quantity || item.quantity || 0),
insuranceType: (contentData.insuranceType || contentData.insurance_type) === 1 ? '医保' : (item.insuranceType === 1 || item.insurance_type === 1) ? '医保' : '自费',
// 添加医嘱定义ID和表名用于库存匹配
adviceDefinitionId: item.adviceDefinitionId || contentData.adviceDefinitionId || item.advice_definition_id || null,
adviceTableName: item.adviceTableName || contentData.adviceTableName || item.advice_table_name || null,
// 添加关键字段医嘱类型、费用项目ID、定价ID用于后端正确分类和保存
adviceType: item.adviceType || contentData.adviceType || item.advice_type || null,
chargeItemId: item.chargeItemId || contentData.chargeItemId || item.charge_item_id || null,
definitionId: item.definitionId || contentData.definitionId || item.definition_id || null,
definitionDetailId: item.definitionDetailId || contentData.definitionDetailId || item.definition_detail_id || null
};
} catch (e) {
// 如果解析失败,使用顶层数据
// 如果解析失败,使用顶层数据 - 兼容 snake_case 和 camelCase 以及后端不同字段名
return {
medicineName: item.adviceName || '',
specification: item.specification || '',
quantity: item.quantity || 0,
batchNumber: item.lotNumber || '',
unitPrice: item.unitPrice || 0,
subtotal: item.totalPrice || 0,
insuranceType: item.insuranceType === 1 ? '医保' : '自费'
}
medicineName: item.adviceName || item.advice_name || item.chargeName || '',
specification: item.specification || item.specification || item.volume || '',
quantity: item.quantity || item.quantity_value || item.quantityValue || 0,
batchNumber: item.lotNumber || item.lot_number || '',
unitPrice: item.unitPrice || item.unit_price || 0,
subtotal: item.totalPrice || item.total_price ||
(item.unitPrice || item.unit_price || 0) *
(item.quantity || item.quantity_value || item.quantityValue || 0),
insuranceType: (item.insuranceType || item.insurance_type) === 1 ? '医保' : '自费',
// 添加医嘱定义ID和表名用于库存匹配
adviceDefinitionId: item.adviceDefinitionId || item.advice_definition_id || null,
adviceTableName: item.adviceTableName || item.advice_table_name || null,
// 添加关键字段医嘱类型、费用项目ID、定价ID用于后端正确分类和保存
adviceType: item.adviceType || item.advice_type || null,
chargeItemId: item.chargeItemId || item.charge_item_id || null,
definitionId: item.definitionId || item.definition_id || null,
definitionDetailId: item.definitionDetailId || item.definition_detail_id || null
};
}
})
});
} else {
// 如果没有数据或接口调用失败,初始化空列表
temporaryBillingMedicines.value = []
@@ -1451,65 +1538,315 @@ function handleMedicalAdvice(row) {
const specMatch = medicine.specification ? medicine.specification.match(/(\d+)(\D+)/) : null
const specValue = specMatch ? parseInt(specMatch[1]) : 1
const specUnit = specMatch ? specMatch[2] : 'ml'
// 计算剂量 = 规格数值 × 数量
const dosage = specValue * (medicine.quantity || 1)
// 根据药品名称判断用法
let usage = '静脉注射'
if (medicine.medicineName && medicine.medicineName.includes('注射')) {
usage = '静脉注射'
} else if (medicine.medicineName && medicine.medicineName.includes('片')) {
usage = '口服'
} else if (medicine.medicineName && medicine.medicineName.includes('胶囊')) {
usage = '口服'
// 🔧 修复:优先从 contentJson 中读取已有的用法,如果没有则根据药品名称判断
let usageCode = 'iv' // 默认静脉注射编码
let usageLabel = '静脉注射' // 默认显示名称
// 尝试从 contentJson 中读取用法
try {
const jsonContent = medicine.contentJson || medicine.content_json;
if (jsonContent) {
const contentData = JSON.parse(jsonContent);
if (contentData.methodCode) {
usageCode = contentData.methodCode;
usageLabel = getUsageLabel(contentData.methodCode);
}
}
} catch (e) {
// 解析失败,继续使用默认值
}
// 如果没有从 contentJson 中读取到用法,根据药品名称判断
if (!usageCode || usageCode === 'iv') {
if (medicine.medicineName && medicine.medicineName.includes('注射液')) {
usageCode = 'iv'
usageLabel = '静脉注射'
} else if (medicine.medicineName && medicine.medicineName.includes('片')) {
usageCode = 'po'
usageLabel = '口服'
} else if (medicine.medicineName && medicine.medicineName.includes('胶囊')) {
usageCode = 'po'
usageLabel = '口服'
}
}
return {
id: index + 1,
adviceName: medicine.medicineName || '',
dosage: dosage,
unit: specUnit,
usage: usage,
usage: usageCode, // 🔧 修复:保存的是编码
usageLabel: usageLabel, // 🔧 新增:保存显示名称
frequency: '临时',
executeTime: new Date().toLocaleString('zh-CN'),
originalMedicine: medicine
// 🔧 关键修复:确保 originalMedicine 中包含 encounterId以便后续判断是否为同一患者
originalMedicine: {
...medicine,
encounterId: row.visitId // 添加 encounterId 字段
}
}
})
// 打开临时医嘱弹窗
showTemporaryMedical.value = true
}).catch(() => {
temporaryMedicalLoading.value = false // 🔧 新增:加载完成
}).catch((error) => {
temporaryBillingMedicines.value = []
temporaryAdvices.value = []
temporaryMedicalLoading.value = false // 🔧 新增:加载完成(即使失败也要关闭加载状态)
proxy.$modal.msgError('刷新数据失败,请重试')
console.error('Failed to refresh prescription list', error)
showTemporaryMedical.value = true
})
}
// 关闭临时医嘱弹窗
// 🔧 修复:清空数据,避免下次打开时使用缓存数据导致数据重复
function closeTemporaryMedical() {
showTemporaryMedical.value = false
temporaryPatientInfo.value = {}
temporaryBillingMedicines.value = []
temporaryAdvices.value = []
// 🔧 修复:关闭弹窗时不清空数据,保留用户可能已经修改过的数据
// 只有当用户点击"取消"按钮时才应该清空数据
}
// 处理临时医嘱提交
// 🔧 修复:提交成功后,更新 temporaryAdvices 中的 requestId以便下次提交时执行更新操作
function handleTemporaryMedicalSubmit(data) {
// 这里可以调用后端API保存临时医嘱数据
proxy.$modal.msgSuccess('临时医嘱提交成功')
closeTemporaryMedical()
console.log('=== handleTemporaryMedicalSubmit 被调用 ===')
console.log('=== data ===', data)
console.log('=== data.temporaryAdvices ===', data.temporaryAdvices)
console.log('=== data.temporaryAdvices[1]?.dosage ===', data.temporaryAdvices[1]?.dosage)
// 🔧 修复:使用用户修改后的数据,而不是重新加载数据
// 这样可以确保用户修改的内容(如剂量)在保存后仍然正确显示
if (data.temporaryAdvices && data.temporaryAdvices.length > 0) {
// 🔧 关键修复:更新 temporaryAdvices 中的数据,保留用户的修改
// 但是需要从后端返回的数据中获取 requestId以便下次提交时执行更新操作
// 如果后端返回了医嘱IDrequestId我们需要更新到 temporaryAdvices 中
temporaryAdvices.value = data.temporaryAdvices.map((advice, index) => {
const originalMedicine = advice.originalMedicine || {}
// 🔧 关键修复:从后端返回的数据中获取 requestId如果有
// 后端返回的医嘱ID可能需要通过某个字段获取这里暂时假设后端会返回
// 如果后端返回的 response 中包含医嘱ID需要更新到 originalMedicine 中
// 这里暂时保留原逻辑,等待用户提供后端返回的具体数据结构
return {
...advice,
// 确保 originalMedicine 包含所有必要字段
originalMedicine: {
...originalMedicine,
// 保留用户的修改
contentJson: originalMedicine.contentJson || JSON.stringify({
dose: advice.dosage,
methodCode: advice.usage,
rateCode: advice.frequency,
quantity: advice.quantity,
totalPrice: advice.totalPrice
})
}
}
})
// 同步更新计费药品列表,保持数据一致性
temporaryBillingMedicines.value = data.billingMedicines || []
console.log('=== 使用用户修改后的临时医嘱数据 ===', temporaryAdvices.value)
console.log('=== temporaryAdvices.value[1]?.dosage ===', temporaryAdvices.value[1]?.dosage)
} else {
// 如果没有传递数据,则清空
temporaryAdvices.value = []
temporaryBillingMedicines.value = []
}
// 关闭弹窗
showTemporaryMedical.value = false
}
// 处理临时医嘱取消
function handleTemporaryMedicalCancel() {
// 🔧 修复:用户点击取消时才清空数据,因为用户可能要放弃修改
temporaryPatientInfo.value = {}
temporaryBillingMedicines.value = []
temporaryAdvices.value = []
closeTemporaryMedical()
}
// 处理删除临时医嘱
// 处理删除临时医嘱 - 将删除的医嘱放回已引用计费药品列表
function handleDeleteTemporaryAdvice(index) {
const deletedAdvice = temporaryAdvices.value[index]
// 如果有原始药品数据,放回到计费药品列表
if (deletedAdvice.originalMedicine) {
temporaryBillingMedicines.value.push(deletedAdvice.originalMedicine)
}
temporaryAdvices.value.splice(index, 1)
proxy.$modal.msgSuccess('临时医嘱已删除')
proxy.$modal.msgSuccess('临时医嘱已删除,已放回待生成列表')
}
// 处理刷新按钮点击
function handleTemporaryMedicalRefresh() {
// 重新拉取计费药品数据
if (temporaryPatientInfo.value.visitId) {
handleMedicalAdvice(temporaryPatientInfo.value)
} else {
proxy.$modal.msgWarning('患者信息不完整,请关闭弹窗重新打开')
}
}
// 处理引用计费按钮点击
function handleQuoteBilling() {
// 重新拉取计费药品数据
if (temporaryPatientInfo.value.visitId) {
temporaryMedicalLoading.value = true // 🔧 新增:开始加载
getPrescriptionList(temporaryPatientInfo.value.visitId).then((res) => {
if (res.code === 200 && res.data) {
// 🔧 修复:先清空旧数据,避免数据累积
temporaryBillingMedicines.value = []
temporaryAdvices.value = []
// 🔧 修复:显示所有药品请求数据,不管有没有计费项目
const filteredItems = res.data.filter(item => {
// 匹配 encounterId
if (item.encounterId !== temporaryPatientInfo.value.visitId) return false;
// 过滤掉名称为空的项目
const medicineName = item.adviceName || item.advice_name;
return medicineName && medicineName.trim() !== '';
})
// 🔧 修复限制返回数量最多显示前100条避免数据过多导致页面卡死
const maxItems = 100
if (filteredItems.length > maxItems) {
ElMessage.warning(`待签发医嘱数量过多(${filteredItems.length}条),仅显示前${maxItems}`)
filteredItems.length = maxItems
}
// 将过滤后的数据转换为临时医嘱需要的格式
temporaryBillingMedicines.value = filteredItems.map(item => {
try {
// 从 contentJson 或 content_json 中解析详细数据 - 兼容下划线和驼峰命名
const jsonContent = item.contentJson || item.content_json;
const contentData = jsonContent ? JSON.parse(jsonContent) : {};
return {
medicineName: contentData.adviceName || contentData.advice_name || item.adviceName || item.advice_name || item.chargeName || '',
specification: contentData.volume || contentData.specification || item.volume || item.specification || '',
quantity: contentData.quantity || item.quantity || item.quantity_value || item.quantityValue || 0,
batchNumber: contentData.lotNumber || contentData.lot_number || item.lotNumber || item.lot_number || '',
unitPrice: contentData.unitPrice || contentData.unit_price || item.unitPrice || item.unit_price || 0,
subtotal: contentData.totalPrice || contentData.total_price || item.totalPrice || item.total_price ||
(contentData.unitPrice || contentData.unit_price || item.unitPrice || item.unit_price || 0) *
(contentData.quantity || item.quantity || item.quantity_value || item.quantityValue || 0),
insuranceType: (contentData.insuranceType || contentData.insurance_type) === 1 ? '医保' : (item.insuranceType === 1 || item.insurance_type === 1) ? '医保' : '自费',
orgId: contentData.orgId || item.orgId || contentData.positionId || item.positionId || userStore.orgId,
positionId: contentData.positionId || item.positionId || userStore.orgId,
definitionId: contentData.definitionId || item.definitionId,
definitionDetailId: contentData.definitionDetailId || item.definitionDetailId
}
} catch (e) {
// 如果解析失败,使用顶层数据 - 兼容 snake_case 和 camelCase
return {
medicineName: item.adviceName || item.advice_name || '',
specification: item.specification || item.specification || item.volume || '',
quantity: item.quantity || item.quantity_value || 0,
batchNumber: item.lotNumber || item.lot_number || '',
unitPrice: item.unitPrice || item.unit_price || 0,
subtotal: item.totalPrice || item.total_price ||
(item.unitPrice || item.unit_price || 0) *
(item.quantity || item.quantity_value || 0),
insuranceType: (item.insuranceType || item.insurance_type) === 1 ? '医保' : '自费',
orgId: item.orgId || item.positionId || userStore.orgId,
positionId: item.positionId || userStore.orgId,
definitionId: item.definitionId,
definitionDetailId: item.definitionDetailId
}
}
})
// 将计费药品转换为临时医嘱数据
temporaryAdvices.value = temporaryBillingMedicines.value.map((medicine, index) => {
// 解析规格中的数值和单位
const specMatch = medicine.specification ? medicine.specification.match(/(\d+)(\D+)/) : null
const specValue = specMatch ? parseInt(specMatch[1]) : 1
const specUnit = specMatch ? specMatch[2] : 'ml'
// 计算剂量 = 规格数值 × 数量
const dosage = specValue * (medicine.quantity || 1)
// 🔧 修复:优先从 contentJson 中读取已有的用法,如果没有则根据药品名称判断
let usageCode = 'iv' // 默认静脉注射编码
let usageLabel = '静脉注射' // 默认显示名称
// 尝试从 contentJson 中读取用法
try {
const jsonContent = medicine.contentJson || medicine.content_json;
if (jsonContent) {
const contentData = JSON.parse(jsonContent);
if (contentData.methodCode) {
usageCode = contentData.methodCode;
usageLabel = getUsageLabel(contentData.methodCode);
}
}
} catch (e) {
// 解析失败,继续使用默认值
}
// 如果没有从 contentJson 中读取到用法,根据药品名称判断
if (!usageCode || usageCode === 'iv') {
if (medicine.medicineName && medicine.medicineName.includes('注射液')) {
usageCode = 'iv'
usageLabel = '静脉注射'
} else if (medicine.medicineName && medicine.medicineName.includes('片')) {
usageCode = 'po'
usageLabel = '口服'
} else if (medicine.medicineName && medicine.medicineName.includes('胶囊')) {
usageCode = 'po'
usageLabel = '口服'
}
}
return {
id: index + 1,
adviceName: medicine.medicineName || '',
dosage: dosage,
unit: specUnit,
usage: usageCode, // 🔧 修复:保存的是编码
usageLabel: usageLabel, // 🔧 新增:保存显示名称
frequency: '临时',
executeTime: new Date().toLocaleString('zh-CN'),
// 🔧 关键修复:确保 originalMedicine 中包含 encounterId以便后续判断是否为同一患者
originalMedicine: {
...medicine,
encounterId: temporaryPatientInfo.value.visitId // 添加 encounterId 字段
}
}
})
temporaryMedicalLoading.value = false // 🔧 新增:加载完成
ElMessage.success('已成功引用最新计费药品信息!')
} else {
// 如果没有数据或接口调用失败,初始化空列表
temporaryBillingMedicines.value = []
temporaryAdvices.value = []
temporaryMedicalLoading.value = false // 🔧 新增:加载完成(即使失败也要关闭加载状态)
ElMessage.error('获取计费数据失败,请重试')
}
}).catch(() => {
temporaryBillingMedicines.value = []
temporaryAdvices.value = []
temporaryMedicalLoading.value = false // 🔧 新增:加载完成(即使失败也要关闭加载状态)
ElMessage.error('获取计费数据失败,请重试')
})
} else {
proxy.$modal.msgWarning('患者信息不完整,请关闭弹窗重新打开')
}
}
// 🔧 新增:根据用法编码获取对应的显示名称
function getUsageLabel(usageCode) {
if (!usageCode) return '-'
const dictItem = method_code.value?.find(item => item.value === usageCode)
return dictItem ? dictItem.label : usageCode
}
// 格式化计费弹窗中的日期
@@ -1591,7 +1928,7 @@ function resetForm() {
function submitForm() {
proxy.$refs['surgeryRef'].validate((valid) => {
if (valid) {
const submitData = { ...form }
const submitData = { ...form, orgId: userStore.orgId }
if (!form.scheduleId) {
// 新增手术安排
addSurgerySchedule(submitData).then((res) => {
@@ -1827,6 +2164,25 @@ function getRowClassName({ row, rowIndex }) {
</script>
<style scoped>
/* 🔧 新增:临时医嘱加载状态样式 */
.loading-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100px 0;
color: #409eff;
font-size: 16px;
}
.loading-container .el-icon {
font-size: 32px;
margin-bottom: 16px;
}
.loading-container span {
font-weight: 500;
}
.app-container {
padding: 20px;
}
@@ -1875,4 +2231,5 @@ function getRowClassName({ row, rowIndex }) {
:deep(.el-table .selected-row > td) {
border-bottom: 1px solid #d9ecff !important;
}
</style>