179 lines
5.3 KiB
Vue
Raw Normal View History

2025-07-24 18:26:49 +08:00
<template>
<div>
<el-button
@click="handleClick"
>查询病人</el-button>
<!-- 病人选择弹窗 -->
<el-dialog
v-model="dialogVisible"
:title="props.dialogTitle"
width="500px"
@close="handleDialogClose"
>
<el-input
v-model="searchKey"
placeholder="搜索(支持姓名、病人ID、简拼)..."
class="mb-4"
clearable
@clear="filteredPatData"
@input="filteredPatData"
@keyup.down="navigateTable('down')"
@keyup.up="navigateTable('up')"
@keyup.enter="selectActiveItem"
/>
<el-table
:data="filteredPatData"
height="300px"
border
@row-click="selectItem"
@row-dblclick="selectItem"
class="compact-form my-table"
>
<template #empty>
<div v-if="isPatLoading">加载中...</div>
<div v-else>没有匹配的病人数据</div>
</template>
<el-table-column prop="pid" label="病人ID" width="100" show-overflow-tooltip/>
<el-table-column prop="name" label="姓名" width="100" show-overflow-tooltip/>
<el-table-column prop="xb" label="性别" width="80" show-overflow-tooltip/>
<el-table-column prop="nl" label="年龄" width="80" show-overflow-tooltip/>
<el-table-column prop="ks" label="科室" width="100" show-overflow-tooltip/>
<el-table-column prop="ch" label="床号" width="80" show-overflow-tooltip/>
<el-table-column prop="pinyin" label="简拼" width="150" show-overflow-tooltip/>
</el-table>
</el-dialog>
</div>
</template>
<script setup>
import { ref, computed, watch, onMounted } from 'vue';
import {queryPatList} from "@/api/mzcx/cydj.js";
import { getFirstLetter } from '@/api/pinyin.js'; // 引入拼音处理工具
// 组件参数
const props = defineProps({
pidValue: { type: [String, Number], default: '' },
PatType: { type: String, required: true },
placeholder: { type: String, default: '请输入或双击选择' },
clearable: { type: Boolean, default: true },
disabled: { type: Boolean, default: false },
dialogTitle: { type: String, default: '选择病人' }
});
// 组件事件
const emit = defineEmits(['update:pidValue', 'select']);
// 内部状态
const dialogVisible = ref(false);
const searchKey = ref('');
const PatData = ref([]); // 存储带简拼的病人数据
const isPatLoading = ref(true);
const activeRowIndex = ref(-1); // 键盘导航选中行索引
// 加载病人数据
const loadPatData = async () => {
isPatLoading.value = true;
queryPatList().then(response => {
// console.log('response:', response.data);
PatData.value = (response.data || []).map(item => ({
...item,
pinyin: getFirstLetter(item.name)
}));
}).catch (() =>{
console.error(`加载病人列表失败:`, error);
PatData.value = [];
}).finally (() =>{
isPatLoading.value = false;
});
};
// 过滤病人数据(使用 computed 提高性能)
const filteredPatData = computed(() => {
const key = searchKey.value.trim().toLowerCase();
if (!key) return PatData.value;
return PatData.value.filter(item => {
const matchName = item.name.toLowerCase().includes(key);
const matchPid = String(item.pid).toLowerCase().includes(key);
const matchPinyin = item.pinyin.toLowerCase().includes(key);
return matchName || matchPid || matchPinyin;
});
});
// 点击按钮事件处理
const handleClick = () => {
loadPatData();
// if (!props.disabled && !isPatLoading.value) {
dialogVisible.value = true;
searchKey.value = '';
activeRowIndex.value = -1;
// }
};
// 选择病人项
const selectItem = (item) => {
emit('update:pidValue', item.pid);
emit('select', item.pid);
dialogVisible.value = false;
};
// 键盘导航
const navigateTable = (direction) => {
if (!filteredPatData.value.length) return;
if (direction === 'down') {
activeRowIndex.value = (activeRowIndex.value + 1) % filteredPatData.value.length;
} else if (direction === 'up') {
activeRowIndex.value = (activeRowIndex.value - 1 + filteredPatData.value.length) % filteredPatData.value.length;
}
};
// 选择当前活动行
const selectActiveItem = () => {
if (activeRowIndex.value >= 0 && activeRowIndex.value < filteredPatData.value.length) {
selectItem(filteredPatData.value[activeRowIndex.value]);
}
};
// 关闭弹窗
const handleDialogClose = () => {
dialogVisible.value = false;
activeRowIndex.value = -1;
};
</script>
<style scoped>
/* 可选:添加活动行样式 */
:deep(.el-table__row.active) {
background-color: #e6f7ff !important;
}
::v-deep .my-table .el-table__row td {
padding: 1px 0; /* 减小行高 */
}
::v-deep .my-table .el-table__header-wrapper th {
padding: 6px 0; /* 表头内边距 */
background-color: #b3d8ff !important; /* 表头背景色(保留之前的设置) */
color: #333; /* 文字颜色加深,提升可读性 */
font-weight: 500; /* 文字加粗 */
}
::v-deep .my-table .el-table__cell {
padding: 0 2px; /* 减小列间距 */
}
/* 可选:调整表格整体样式 */
::v-deep .my-table {
font-size: 13px; /* 适当减小字体 */
}
::v-deep .my-table .el-table__cell,
::v-deep .my-table .el-table__header-wrapper th {
border-width: 1px;
border-color: #ebeef5;
}
</style>