342 lines
8.3 KiB
Vue
342 lines
8.3 KiB
Vue
<template>
|
||
<div class="patient-search-container">
|
||
<!-- 标题栏 -->
|
||
<div class="title-bar">
|
||
<h2>病人档案查询</h2>
|
||
<div class="button-bar">
|
||
<el-button
|
||
type="primary"
|
||
@click="handleQuery"
|
||
:loading="loading"
|
||
size="large"
|
||
icon="el-icon-check"
|
||
>
|
||
确认(Q)
|
||
</el-button>
|
||
<el-button
|
||
type="danger"
|
||
@click="handleClose"
|
||
size="large"
|
||
icon="el-icon-close"
|
||
>
|
||
关闭(C)
|
||
</el-button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 查询表单 -->
|
||
<div class="search-form">
|
||
<el-row :gutter="20">
|
||
<el-col :span="8">
|
||
<div class="form-item">
|
||
<label>病人姓名:</label>
|
||
<el-input
|
||
v-model="searchForm.patientName"
|
||
placeholder="请输入病人姓名"
|
||
clearable
|
||
@keyup.enter="handleQuery"
|
||
/>
|
||
</div>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<div class="form-item">
|
||
<label>身份证号码:</label>
|
||
<el-input
|
||
v-model="searchForm.idCard"
|
||
placeholder="请输入身份证号码"
|
||
clearable
|
||
@keyup.enter="handleQuery"
|
||
/>
|
||
</div>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<div class="form-item">
|
||
<label>手机号码:</label>
|
||
<el-input
|
||
v-model="searchForm.phoneNumber"
|
||
placeholder="请输入手机号码"
|
||
clearable
|
||
@keyup.enter="handleQuery"
|
||
/>
|
||
</div>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
|
||
<!-- 查询结果表格 -->
|
||
<div class="result-table">
|
||
<el-table
|
||
:data="patientList"
|
||
style="width: 100%"
|
||
stripe
|
||
@row-click="handleRowClick"
|
||
highlight-current-row
|
||
row-key="id"
|
||
:current-row-key="selectedPatient?.id"
|
||
>
|
||
<el-table-column label="序号" type="index" width="80" align="center">
|
||
</el-table-column>
|
||
<el-table-column label="病人姓名" width="120" align="center">
|
||
<template #default="scope">
|
||
{{ scope.row.patientName }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="门诊号码" width="150" align="center">
|
||
<template #default="scope">
|
||
{{ scope.row.outpatientNo || '-' }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="身份证号码" width="200" align="center">
|
||
<template #default="scope">
|
||
{{ scope.row.idCard || '-' }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="手机号码" width="120" align="center">
|
||
<template #default="scope">
|
||
{{ scope.row.phoneNumber || '-' }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="性别" width="80" align="center">
|
||
<template #default="scope">
|
||
{{ scope.row.gender }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="年龄" width="80" align="center">
|
||
<template #default="scope">
|
||
{{ scope.row.age }}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="出生年月" width="120" align="center">
|
||
<template #default="scope">
|
||
{{ scope.row.birthDate }}
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, reactive, onMounted, onUnmounted, computed, watch } from 'vue'
|
||
import { ElMessage } from 'element-plus'
|
||
import { getOutpatientRegistrationList } from '../outpatientregistration/components/outpatientregistration'
|
||
|
||
// 搜索表单
|
||
const searchForm = reactive({
|
||
patientName: '',
|
||
idCard: '',
|
||
phoneNumber: ''
|
||
})
|
||
|
||
// 患者列表
|
||
const patientList = ref([])
|
||
|
||
// 加载状态
|
||
const loading = ref(false)
|
||
|
||
// API调用相关变量
|
||
const queryParams = ref({
|
||
pageNum: 1,
|
||
pageSize: 50
|
||
})
|
||
|
||
// 当前选中的患者
|
||
const selectedPatient = ref(null)
|
||
|
||
// 定义事件
|
||
const emit = defineEmits(['selectPatient', 'close'])
|
||
|
||
// 计算搜索关键字,合并三个字段为一个searchKey
|
||
const searchKey = computed(() => {
|
||
return searchForm.patientName || searchForm.idCard || searchForm.phoneNumber
|
||
})
|
||
|
||
// 监听搜索关键字变化,自动查询
|
||
watch(searchKey, (newValue) => {
|
||
// 当搜索关键字变化时,延迟查询,避免频繁请求
|
||
const timer = setTimeout(() => {
|
||
if (newValue) {
|
||
queryParams.value.searchKey = newValue
|
||
handleQuery()
|
||
}
|
||
}, 300)
|
||
return () => clearTimeout(timer)
|
||
})
|
||
|
||
// 处理行点击
|
||
const handleRowClick = (row) => {
|
||
selectedPatient.value = row
|
||
ElMessage.success(`已选择患者:${row.patientName}`)
|
||
}
|
||
|
||
// 查询患者信息和确认选择
|
||
const handleQuery = async () => {
|
||
// 如果已经选中了患者,则确认选择
|
||
if (selectedPatient.value) {
|
||
// 发射选择患者事件
|
||
emit('selectPatient', selectedPatient.value)
|
||
ElMessage.success(`已确认选择患者:${selectedPatient.value.patientName}`)
|
||
return
|
||
}
|
||
|
||
// 检查是否至少填写了一个查询条件
|
||
if (!searchKey.value) {
|
||
ElMessage.warning('请至少输入一个查询条件')
|
||
return
|
||
}
|
||
|
||
loading.value = true
|
||
try {
|
||
// 调用门诊挂号的API获取患者列表
|
||
const response = await getOutpatientRegistrationList(queryParams.value)
|
||
|
||
if (response.data && response.data.records) {
|
||
// 映射字段,使其与表格展示需求匹配
|
||
patientList.value = response.data.records.map(record => ({
|
||
id: record.id,
|
||
patientName: record.name,
|
||
outpatientNo: record.identifierNo,
|
||
idCard: record.idCard,
|
||
phoneNumber: record.phone,
|
||
gender: record.genderEnum_enumText || '-',
|
||
age: record.age || '-',
|
||
birthDate: record.birthDate || '-' // 如果后端没有提供,需要计算或显示为'-'
|
||
}))
|
||
|
||
if (patientList.value.length === 0) {
|
||
ElMessage.warning('未找到符合条件的患者信息')
|
||
}
|
||
} else {
|
||
ElMessage.error('查询失败')
|
||
patientList.value = []
|
||
}
|
||
} catch (error) {
|
||
ElMessage.error('查询失败,请稍后重试')
|
||
console.error('查询失败:', error)
|
||
patientList.value = []
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
// 关闭窗口
|
||
const handleClose = () => {
|
||
// 发射关闭事件
|
||
emit('close')
|
||
}
|
||
|
||
// 键盘事件处理
|
||
const handleKeydown = (event) => {
|
||
// Alt + Q 查询
|
||
if (event.altKey && event.key.toLowerCase() === 'q') {
|
||
event.preventDefault()
|
||
handleQuery()
|
||
}
|
||
// Alt + C 关闭
|
||
if (event.altKey && event.key.toLowerCase() === 'c') {
|
||
event.preventDefault()
|
||
handleClose()
|
||
}
|
||
}
|
||
|
||
// 组件挂载时添加键盘事件监听
|
||
onMounted(() => {
|
||
document.addEventListener('keydown', handleKeydown)
|
||
})
|
||
|
||
// 组件卸载时移除键盘事件监听
|
||
onUnmounted(() => {
|
||
document.removeEventListener('keydown', handleKeydown)
|
||
})
|
||
</script>
|
||
|
||
<style scoped>
|
||
.patient-search-container {
|
||
width: 100%;
|
||
background-color: #fff;
|
||
border: 1px solid #b3d4ff;
|
||
border-radius: 4px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.title-bar {
|
||
background-color: #d6e9ff;
|
||
padding: 10px 20px;
|
||
border-bottom: 1px solid #b3d4ff;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.title-bar h2 {
|
||
margin: 0;
|
||
font-size: 18px;
|
||
color: #303133;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.button-bar {
|
||
padding: 10px 20px;
|
||
display: flex;
|
||
gap: 10px;
|
||
}
|
||
|
||
.button-bar .el-button {
|
||
padding: 12px 24px;
|
||
font-size: 16px;
|
||
}
|
||
|
||
.search-form {
|
||
padding: 20px;
|
||
border-bottom: 1px solid #dcdfe6;
|
||
}
|
||
|
||
.form-item {
|
||
margin-bottom: 15px;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.form-item label {
|
||
display: inline-block;
|
||
width: 100px;
|
||
text-align: right;
|
||
margin-right: 10px;
|
||
font-weight: 500;
|
||
color: #303133;
|
||
}
|
||
|
||
.form-item .el-input {
|
||
width: 250px;
|
||
}
|
||
|
||
.result-table {
|
||
padding: 10px;
|
||
}
|
||
|
||
.el-table {
|
||
border: 1px solid #dcdfe6;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.el-table th {
|
||
background-color: #f2f6fc;
|
||
font-weight: 600;
|
||
color: #303133;
|
||
border-bottom: 1px solid #e6e8eb;
|
||
}
|
||
|
||
.el-table td {
|
||
padding: 10px 0;
|
||
font-size: 14px;
|
||
border-bottom: 1px solid #ebeef5;
|
||
}
|
||
|
||
.el-table--striped .el-table__body tr:nth-child(2n) {
|
||
background-color: #f8f9fa;
|
||
}
|
||
|
||
.el-table__row:hover {
|
||
background-color: #f5f7fa;
|
||
}
|
||
</style> |