Files
his/openhis-ui-vue3/src/views/inpatientDoctor/home/index.vue
关羽 c2941f5948 Fix Bug #510: [住院医生工作站] 进入页面报错
修复模板中的 Markdown 代码块标记污染(```vue/``` 作为文本渲染),
并恢复被意外移除的 SummaryDrugApplication 组件导入及 ref 声明,
解决页面加载时组件未定义错误和页面渲染异常。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 15:28:06 +08:00

243 lines
7.2 KiB
Vue
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="inpatientDoctor-home-container">
<el-container>
<PatientList :selected-patient="patientInfo" :on-select="handleItemClick" />
<el-container class="inpatientDoctor-home-main">
<el-header height="auto"><inPatientBarDoctorFold /></el-header>
<el-main>
<el-tabs v-model="activeTabName" type="card" class="patient-tabs">
<el-tab-pane label="住院病历" name="inhospitalEmr">
<Emr ref="inhospitalEmrRef" />
</el-tab-pane>
<el-tab-pane label="诊断录入" name="diagnosis">
<Diagnose ref="diagnosisRef" :patientInfo="currentPatientInfo" />
</el-tab-pane>
<el-tab-pane label="临床医嘱" name="prescription">
<Advice ref="adviceRef" />
</el-tab-pane>
<!-- <el-tab-pane label="医技报告" name="fourth">Task</el-tab-pane> -->
<el-tab-pane label="检验申请" name="test">
<TestApplication ref="testApplicationRef" :show-status-column="true" />
</el-tab-pane>
<el-tab-pane label="检查申请" name="examine">
<ExamineApplication ref="examineApplicationRef" />
</el-tab-pane>
<el-tab-pane label="汇总发药申请" name="summaryDrug">
<SummaryDrugApplication ref="summaryDrugApplicationRef" />
</el-tab-pane>
<el-tab-pane label="手术申请" name="surgery">
<SurgeryApplication ref="surgeryApplicationRef" />
</el-tab-pane>
<el-tab-pane label="输血申请" name="blood">
<BloodTtransfusionAapplication ref="bloodTtransfusionAapplicationRef" />
</el-tab-pane>
<el-tab-pane label="报告查询" name="report">
<ReportQuery />
</el-tab-pane>
<!-- <el-tab-pane label="护理状态" name="nursing">
<NursingStatus />
</el-tab-pane> -->
</el-tabs>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script setup>
import {computed, onBeforeMount, onMounted, provide, reactive, ref, watch,} from 'vue';
import Emr from './emr/index.vue';
import SummaryDrugApplication from './components/applicationShow/summaryDrugApplication.vue';
import inPatientBarDoctorFold from '@/components/patientBar/inPatientBarDoctorFold.vue';
import PatientList from '@/components/PatientList/patient-list.vue';
import {localPatientInfo, updateLocalPatientInfo} from './store/localPatient';
import {patientInfo, updatePatientInfo} from './store/patient';
import {getPatientList} from './components/api';
import {
Advice,
BloodTtransfusionAapplication,
Diagnose,
ExamineApplication,
ReportQuery,
SurgeryApplication,
TestApplication,
} from './index.js';
const state = reactive({});
onBeforeMount(() => {});
onMounted(() => {
// 如果 store 中已有患者信息,使用 store 中的
if (patientInfo.value?.encounterId) {
cardId.value = patientInfo.value.encounterId;
isFirstLoad.value = false;
}
queryPatientData();
getList();
});
defineExpose({ state });
const activeTabName = ref('inhospitalEmr');
const diagnosisRef = ref();
const adviceRef = ref();
const patientAside = ref(true);
const currentPatientInfo = ref({});
const testApplicationRef = ref();
const examineApplicationRef = ref();
const surgeryApplicationRef = ref();
const summaryDrugApplicationRef = ref();
const bloodTtransfusionAapplicationRef = ref();
// 患者列表相关逻辑
const searchData = reactive({
keyword: '',
patientType: 1,
type: 1,
timeLimit: 3,
});
const cardId = ref('');
const cardAllData = ref([]);
const isFirstLoad = ref(true);
const filteredCardData = computed(() => {
return cardAllData.value;
});
const queryloading = ref(false);
const getList = () => {
queryloading.value = true;
getPatientList({ status: 5, searchKey: searchData.keyword })
.then((res) => {
cardAllData.value = res.data.records || [];
})
.finally(() => {
queryloading.value = false;
});
};
watch(
() => filteredCardData.value,
(newData) => {
// 如果有数据且当前没有选中患者,且是首次加载,默认选择第一条
if (
newData &&
newData.length > 0 &&
!cardId.value &&
isFirstLoad.value &&
!patientInfo.value?.encounterId
) {
const firstPatient = newData[0];
if (firstPatient?.encounterId) {
// 使用防抖处理默认选择
if (debounceTimer) {
clearTimeout(debounceTimer);
}
debounceTimer = setTimeout(() => {
handleItemClick(firstPatient);
isFirstLoad.value = false;
}, 100);
}
}
},
{ immediate: true }
);
// 防抖函数,防止快速点击导致状态冲突
let debounceTimer = null;
const handleItemClick = (node) => {
// 清除之前的计时器
if (debounceTimer) {
clearTimeout(debounceTimer);
}
// 设置新的计时器
debounceTimer = setTimeout(() => {
cardId.value = node.encounterId;
// 同时更新本地和全局状态,确保模块内组件和跨模块组件都能正确响应
updatePatientInfo(node);
updateLocalPatientInfo(node);
// 关键修复:同步更新 currentPatientInfo确保诊断组件能获取到 patientId 和 encounterId
currentPatientInfo.value = node;
diagnosisRef.value?.getList();
diagnosisRef.value?.getDetail(node?.encounterId);
adviceRef.value?.getListInfo();
adviceRef.value?.getDiagnosisInfo();
}, 100); // 100ms 防抖延迟
};
const handleSearch = (keyword) => {
searchData.keyword = keyword;
getList();
};
const queryPatientData = async () => {
if (queryloading.value) return;
try {
} catch (error) {
cardAllData.value = [];
} finally {
queryloading.value = false;
}
};
// 监听 tab 切换,刷新对应的列表
watch(activeTabName, (newTab) => {
if (newTab === 'test' && testApplicationRef.value?.refresh) {
testApplicationRef.value.refresh();
} else if (newTab === 'examine' && examineApplicationRef.value?.refresh) {
examineApplicationRef.value.refresh();
} else if (newTab === 'surgery' && surgeryApplicationRef.value?.refresh) {
surgeryApplicationRef.value.refresh();
} else if (newTab === 'blood' && bloodTtransfusionAapplicationRef.value?.refresh) {
bloodTtransfusionAapplicationRef.value.refresh();
}
});
provide('diagnosisInit', (value) => {
currentPatientInfo.value = value;
diagnosisRef.value.getList();
diagnosisRef.value.getDetail(value?.encounterId);
});
provide('getAdviceList', (value) => {
adviceRef.value.getListInfo();
});
provide('adviceDiagnoInit', (value) => {
adviceRef.value.getDiagnosisInfo();
});
</script>
<style lang="scss" scoped>
.inpatientDoctor-home-container {
height: 100%;
height: calc(100vh - 84px);
.el-container {
height: 100%;
}
:deep(.el-aside) {
padding: 0;
}
.inpatientDoctor-home-main {
background-color: #ffffff;
:deep(.el-header) {
padding: 0px;
margin-bottom: 0px;
}
.el-main {
padding: 0px 8px;
}
:deep(.patient-tabs) {
height: 100%;
.el-tabs__header {
margin: 0;
}
.el-tabs__content {
height: calc(100% - 40px);
}
.el-tab-pane {
height: 100%;
}
}
}
}
</style>