提交merge1.3
This commit is contained in:
@@ -0,0 +1,305 @@
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<el-input placeholder="住院号/姓名" v-model="searchKey" @keyup.enter="handleSearch">
|
||||
<template #append>
|
||||
<el-button icon="Search" @click="handleSearch" />
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
:key="treeKey"
|
||||
:load="loadNode"
|
||||
lazy
|
||||
show-checkbox
|
||||
node-key="id"
|
||||
default-expand-all
|
||||
:props="{ label: 'name', children: 'children' }"
|
||||
@node-click="handleNodeClick"
|
||||
@check="handleCheckChange"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<div class="custom-tree-node" v-if="node.level === 2">
|
||||
<span>{{ data.bedName + ' / ' + node.label }}</span>
|
||||
<span class="tree-node-actions">
|
||||
{{ data.genderEnum_enumText + ' / ' + data.age }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-tree>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { getPatientList, getWardList } from './api';
|
||||
import { updatePatientInfoList } from './store/patient';
|
||||
import { ref, nextTick, inject, defineExpose } from 'vue';
|
||||
|
||||
const treeRef = ref(null);
|
||||
const searchKey = ref('');
|
||||
const treeKey = ref(0); // 用于强制重新渲染树组件
|
||||
const wardList = ref([]); // 存储病区列表
|
||||
const patientDataCache = ref(new Map()); // 缓存患者数据:key为wardId,value为患者列表
|
||||
|
||||
const handleGetPrescription = inject('handleGetPrescription');
|
||||
|
||||
/**
|
||||
* 加载树节点数据
|
||||
* @param {Object} node - 树节点对象
|
||||
* @param {Function} resolve - 解析函数,用于返回子节点数据
|
||||
*/
|
||||
function loadNode(node, resolve) {
|
||||
// 根节点:加载所有病区
|
||||
if (node.level === 0) {
|
||||
loadWardList(resolve);
|
||||
}
|
||||
// 病区节点:加载该病区下的患者列表
|
||||
else if (node.level === 1) {
|
||||
const wardId = node.data.id;
|
||||
loadPatientList(wardId, resolve);
|
||||
}
|
||||
// 其他层级返回空数组
|
||||
else {
|
||||
resolve([]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载病区列表
|
||||
* @param {Function} resolve - 解析函数
|
||||
*/
|
||||
function loadWardList(resolve) {
|
||||
getWardList()
|
||||
.then((res) => {
|
||||
// 格式化病区数据
|
||||
const wards = Array.isArray(res) ? res : res.data || [];
|
||||
wardList.value = wards;
|
||||
|
||||
// 将病区数据转换为树节点格式
|
||||
const wardNodes = wards.map((ward) => ({
|
||||
id: ward.id,
|
||||
name: ward.name || ward.wardName || '',
|
||||
leaf: false, // 病区节点不是叶子节点
|
||||
...ward,
|
||||
}));
|
||||
|
||||
resolve(wardNodes);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('加载病区列表失败:', error);
|
||||
resolve([]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载指定病区的患者列表
|
||||
* @param {String|Number} wardId - 病区ID
|
||||
* @param {Function} resolve - 解析函数
|
||||
*/
|
||||
function loadPatientList(wardId, resolve) {
|
||||
// 构建缓存键(包含搜索条件)
|
||||
const cacheKey = `${wardId}_${searchKey.value || ''}`;
|
||||
|
||||
// 如果缓存中存在且搜索条件为空,直接使用缓存(搜索时需要重新加载)
|
||||
if (!searchKey.value && patientDataCache.value.has(cacheKey)) {
|
||||
const cachedPatients = patientDataCache.value.get(cacheKey);
|
||||
resolve(cachedPatients);
|
||||
return;
|
||||
}
|
||||
|
||||
// 调用接口获取患者列表
|
||||
getPatientList({
|
||||
wardId: wardId,
|
||||
searchKey: searchKey.value || '',
|
||||
})
|
||||
.then((res) => {
|
||||
// 处理返回的患者数据
|
||||
const records = res?.data?.records || [];
|
||||
|
||||
// 格式化患者数据
|
||||
const patients = records.map((item) => ({
|
||||
id: item.id || item.encounterId,
|
||||
name: item.patientName || '',
|
||||
leaf: true, // 患者节点是叶子节点
|
||||
...item,
|
||||
}));
|
||||
|
||||
// 缓存患者数据(仅在没有搜索条件时缓存)
|
||||
if (!searchKey.value) {
|
||||
patientDataCache.value.set(cacheKey, patients);
|
||||
}
|
||||
|
||||
resolve(patients);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('加载患者列表失败:', error);
|
||||
resolve([]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新加载所有病区的患者列表
|
||||
*/
|
||||
function reloadAllPatients() {
|
||||
if (!treeRef.value) return;
|
||||
|
||||
// 清除患者数据缓存
|
||||
patientDataCache.value.clear();
|
||||
|
||||
nextTick(() => {
|
||||
const rootNode = treeRef.value?.store?.root;
|
||||
if (!rootNode?.childNodes) return;
|
||||
|
||||
// 遍历所有已展开的病区节点,重新加载患者列表
|
||||
rootNode.childNodes.forEach((wardNode) => {
|
||||
if (wardNode && wardNode.level === 1 && wardNode.key) {
|
||||
reloadWardNodePatients(wardNode);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新加载指定病区节点的患者列表
|
||||
* @param {Object} wardNode - 病区节点对象
|
||||
*/
|
||||
function reloadWardNodePatients(wardNode) {
|
||||
if (!wardNode?.key || !treeRef.value) return;
|
||||
|
||||
const wardId = wardNode.data.id;
|
||||
const cacheKey = `${wardId}_${searchKey.value || ''}`;
|
||||
|
||||
// 清除该病区的缓存
|
||||
patientDataCache.value.delete(cacheKey);
|
||||
|
||||
// 清除旧的子节点
|
||||
treeRef.value.updateKeyChildren(wardNode.key, []);
|
||||
|
||||
// 重置节点状态
|
||||
wardNode.loaded = false;
|
||||
wardNode.childNodes = [];
|
||||
|
||||
// 重新加载患者列表
|
||||
loadPatientList(wardId, (children) => {
|
||||
treeRef.value.updateKeyChildren(wardNode.key, children);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新加载指定病区的患者列表
|
||||
* @param {String|Number} wardId - 病区ID
|
||||
*/
|
||||
function reloadWardPatients(wardId) {
|
||||
if (!treeRef.value) return;
|
||||
|
||||
nextTick(() => {
|
||||
const rootNode = treeRef.value?.store?.root;
|
||||
if (!rootNode?.childNodes) return;
|
||||
|
||||
// 查找对应的病区节点
|
||||
const wardNode = rootNode.childNodes.find((node) => node.data.id === wardId);
|
||||
if (wardNode) {
|
||||
reloadWardNodePatients(wardNode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动触发加载节点
|
||||
* @param {Object} node - 节点对象,如果为null则重新加载整个树
|
||||
*/
|
||||
function manualLoadNode(node = null) {
|
||||
if (!node) {
|
||||
// 重新加载整个树
|
||||
treeKey.value += 1;
|
||||
patientDataCache.value.clear();
|
||||
} else if (node.key && treeRef.value) {
|
||||
// 重新加载指定节点
|
||||
if (node.level === 1) {
|
||||
// 病区节点:重新加载患者列表
|
||||
reloadWardNodePatients(node);
|
||||
} else if (node.level === 0) {
|
||||
// 根节点:重新加载病区列表
|
||||
loadWardList((wards) => {
|
||||
treeRef.value.updateKeyChildren(node.key, wards);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有选中的叶子节点(患者节点)
|
||||
* @returns {Array} 患者节点数组
|
||||
*/
|
||||
function getCheckedLeafNodes() {
|
||||
if (!treeRef.value) return [];
|
||||
|
||||
// 获取所有选中的节点数据
|
||||
const checkedNodes = treeRef.value.getCheckedNodes() || [];
|
||||
|
||||
// 只返回叶子节点(患者节点)
|
||||
return checkedNodes.filter((node) => node.leaf === true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理节点选中状态变化
|
||||
* @param {Object} data - 节点数据
|
||||
* @param {Object} checked - 选中状态对象
|
||||
*/
|
||||
function handleCheckChange(data, checked) {
|
||||
const checkedPatients = getCheckedLeafNodes();
|
||||
updatePatientInfoList(checkedPatients);
|
||||
|
||||
// 调用父组件的方法获取处方列表
|
||||
if (handleGetPrescription && typeof handleGetPrescription === 'function') {
|
||||
handleGetPrescription();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理节点点击事件
|
||||
* @param {Object} data - 节点数据
|
||||
* @param {Object} node - 节点对象
|
||||
*/
|
||||
function handleNodeClick(data, node) {
|
||||
// 节点点击处理逻辑(可根据需要添加)
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理搜索
|
||||
*/
|
||||
function handleSearch() {
|
||||
// 清除缓存(搜索时需要重新加载)
|
||||
patientDataCache.value.clear();
|
||||
|
||||
// 重新加载所有已展开病区的患者列表
|
||||
reloadAllPatients();
|
||||
}
|
||||
|
||||
// 暴露方法供外部调用
|
||||
defineExpose({
|
||||
manualLoadNode,
|
||||
reloadAllPatients,
|
||||
reloadWardPatients,
|
||||
handleSearch,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.custom-tree-node {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tree-node-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
:deep(.el-tree-node__content) {
|
||||
height: 35px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user