Files
his/openhis-ui-vue3/src/views/charge/patientSearch/PatientSearch.vue
2025-11-12 09:38:47 +08:00

342 lines
8.3 KiB
Vue
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="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>