2025-07-24 18:26:49 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<div>
|
2025-10-30 18:16:57 +08:00
|
|
|
|
<el-button @click="handleClick">查询病人</el-button>
|
2025-07-24 18:26:49 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 病人选择弹窗 -->
|
2025-10-30 18:16:57 +08:00
|
|
|
|
<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">
|
2025-07-24 18:26:49 +08:00
|
|
|
|
<template #empty>
|
|
|
|
|
|
<div v-if="isPatLoading">加载中...</div>
|
|
|
|
|
|
<div v-else>没有匹配的病人数据</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
2025-10-30 18:16:57 +08:00
|
|
|
|
<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 />
|
2025-07-24 18:26:49 +08:00
|
|
|
|
</el-table>
|
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
|
import { ref, computed, watch, onMounted } from 'vue';
|
2025-10-30 18:16:57 +08:00
|
|
|
|
import { queryPatList } from "@/api/mzcx/cydj.js";
|
|
|
|
|
|
import { getFirstLetter } from '@/utils/pinyin.js'; // 引入拼音处理工具
|
2025-07-24 18:26:49 +08:00
|
|
|
|
// 组件参数
|
|
|
|
|
|
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 () => {
|
2025-10-30 18:16:57 +08:00
|
|
|
|
isPatLoading.value = true;
|
|
|
|
|
|
queryPatList().then(response => {
|
2025-07-24 18:26:49 +08:00
|
|
|
|
// console.log('response:', response.data);
|
|
|
|
|
|
PatData.value = (response.data || []).map(item => ({
|
|
|
|
|
|
...item,
|
|
|
|
|
|
pinyin: getFirstLetter(item.name)
|
|
|
|
|
|
}));
|
2025-10-30 18:16:57 +08:00
|
|
|
|
}).catch(() => {
|
2025-07-24 18:26:49 +08:00
|
|
|
|
console.error(`加载病人列表失败:`, error);
|
|
|
|
|
|
PatData.value = [];
|
2025-10-30 18:16:57 +08:00
|
|
|
|
}).finally(() => {
|
2025-07-24 18:26:49 +08:00
|
|
|
|
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();
|
2025-10-30 18:16:57 +08:00
|
|
|
|
// if (!props.disabled && !isPatLoading.value) {
|
|
|
|
|
|
dialogVisible.value = true;
|
|
|
|
|
|
searchKey.value = '';
|
|
|
|
|
|
activeRowIndex.value = -1;
|
|
|
|
|
|
// }
|
2025-07-24 18:26:49 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 选择病人项
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
2025-10-30 18:16:57 +08:00
|
|
|
|
|
2025-07-24 18:26:49 +08:00
|
|
|
|
::v-deep .my-table .el-table__row td {
|
2025-10-30 18:16:57 +08:00
|
|
|
|
padding: 1px 0;
|
|
|
|
|
|
/* 减小行高 */
|
2025-07-24 18:26:49 +08:00
|
|
|
|
}
|
2025-10-30 18:16:57 +08:00
|
|
|
|
|
2025-07-24 18:26:49 +08:00
|
|
|
|
::v-deep .my-table .el-table__header-wrapper th {
|
2025-10-30 18:16:57 +08:00
|
|
|
|
padding: 6px 0;
|
|
|
|
|
|
/* 表头内边距 */
|
|
|
|
|
|
background-color: #b3d8ff !important;
|
|
|
|
|
|
/* 表头背景色(保留之前的设置) */
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
/* 文字颜色加深,提升可读性 */
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
/* 文字加粗 */
|
2025-07-24 18:26:49 +08:00
|
|
|
|
}
|
2025-10-30 18:16:57 +08:00
|
|
|
|
|
2025-07-24 18:26:49 +08:00
|
|
|
|
::v-deep .my-table .el-table__cell {
|
2025-10-30 18:16:57 +08:00
|
|
|
|
padding: 0 2px;
|
|
|
|
|
|
/* 减小列间距 */
|
2025-07-24 18:26:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 可选:调整表格整体样式 */
|
|
|
|
|
|
::v-deep .my-table {
|
2025-10-30 18:16:57 +08:00
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
/* 适当减小字体 */
|
2025-07-24 18:26:49 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
::v-deep .my-table .el-table__cell,
|
|
|
|
|
|
::v-deep .my-table .el-table__header-wrapper th {
|
|
|
|
|
|
border-width: 1px;
|
|
|
|
|
|
border-color: #ebeef5;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|