修改体检登记样式以及增加删除患者信息的接口

This commit is contained in:
Euni4U 2025-02-27 16:45:58 +08:00
parent 0884335e59
commit d87da93abd
3 changed files with 233 additions and 104 deletions

View File

@ -58,6 +58,11 @@ export const PatientitemsApi = {
return await request.delete({ url: `/Inspect/patientitems/delete?id=` + id })
},
// 删除患者所有体检项目
deletePatientitemsAll: async (medicalSn: string) => {
return await request.delete({ url: `/Inspect/patientitems/deletemedicalSn?medicalSn=` + medicalSn })
},
// 导出患者体检项目 Excel
exportPatientitems: async (params) => {
return await request.download({ url: `/Inspect/patientitems/export-excel`, params })

View File

@ -446,18 +446,26 @@ const fetchPatientsByDate = async () => {
`${formatDate(startDate)} 00:00:00`,
`${formatDate(endDate)} 23:59:59`
],
//
chargeStatus: chargeStatus.value === 'unpaid' ? '0' : '1',
//
pname: searchQuery.value || undefined
}
const res = await PatientApi.getPatientPage(params)
patients.value = res.list
total.value = res.total
// chargeType
if (chargeStatus.value === 'unpaid') {
// chargeTypenullundefined
patients.value = res.list.filter(patient => !patient.chargeType || patient.chargeType === '')
} else {
// chargeType
patients.value = res.list.filter(patient => patient.chargeType && patient.chargeType !== '')
}
//
total.value = patients.value.length
//
if (!patients.value.length) {
if (patients.value.length === 0) {
selectedPatient.value = null
}
} catch (error) {

View File

@ -39,38 +39,6 @@
<el-radio-group v-model="searchForm_extra.passStatus">
<el-radio value="1">已登记</el-radio>
</el-radio-group>
<div>
<el-button
@click="handlePersonInfoCustomAdd"
size="default"
type="text"
style="
margin-left: 10px;
color: #67C23A;
font-size: 15px;
"
>
<Icon :size="15" class="mr-4px" />新增
</el-button>
<el-button
@click="handlePersonInfoIDCard2nd"
size="default"
type="text"
style="
margin-left: 10px;
color: #2d8cf0;
font-size: 15px;
"
:loading="btnPersonInfoIDCard2ndLoading"
>
<Icon
:size="15"
icon="ep:card"
class="mr-4px"
v-show="!btnPersonInfoIDCard2ndLoading"
/>
</el-button>
</div>
</div>
</el-col>
</el-row>
@ -89,11 +57,6 @@
<el-scrollbar
:view-style="[personData && personData.length > 0 ? { height: '99.6%' } : null]"
>
<el-empty
description="暂无数据"
image="/public/static/inspect/empty.png"
v-if="!personData || personData.length == 1"
/>
<el-table
ref="personTableRef"
size="default"
@ -109,6 +72,21 @@
:highlight-current-row="true"
:row-class-name="getRowClassName"
>
<template #empty>
<div class="empty-text">暂无数据</div>
</template>
<el-table-column width="60" align="center">
<template #default="scope">
<el-radio
v-model="selectedPatientId"
:label="scope.row.id"
@change="() => handlePatientSelect(scope.row)"
class="custom-radio"
>
<!-- 空标签只显示单选按钮 -->
</el-radio>
</template>
</el-table-column>
<el-table-column label="体检编号" width="90px" prop="medicalSn" show-overflow-tooltip />
<el-table-column label="患者信息" min-width="200px">
<template #default="scope">
@ -117,19 +95,18 @@
:span="24"
style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap"
>
<span :class="{ 'selected-patient': selectedPatient?.id === scope.row.id }">
姓名{{ scope.row.personName }}
<el-icon
v-if="selectedPatient?.id === scope.row.id"
color="#67C23A"
class="ml-4px"
>
<Check />
</el-icon>
</span>
</el-col>
</el-row>
<el-row>
<el-col :span="9">性别{{ scope.row.sex }}</el-col>
<el-col :span="9">年龄{{ scope.row.age }}</el-col>
<el-row style="display: flex; align-items: center; white-space: nowrap">
<el-col :span="12" style="display: flex; align-items: center">
<span>性别{{ scope.row.sex }}</span>
</el-col>
<el-col :span="12" style="display: flex; align-items: center">
<span style="white-space: nowrap">年龄{{ scope.row.age }}</span>
</el-col>
</el-row>
</template>
</el-table-column>
@ -312,6 +289,7 @@
'width: 110px'
]"
v-show="!personInfoCustomAdd && !isEditing"
:disabled="!selectedPatient"
>
<Icon :size="13.2" icon="ep:edit" class="mr-6px" />修改信息
</el-button>
@ -351,9 +329,55 @@
width: 126px;
"
v-show="!personInfoCustomAdd"
:disabled="!selectedPatient"
>
<Icon :size="13.2" icon="ep:printer" class="mr-6px" />打印导检单
</el-button>
<el-button
@click="handlePersonInfoCustomAdd"
style="
margin-left: 0;
margin-right: 6.4px;
background-color: #67C23A;
color: rgba(255, 255, 255, 1);
width: 84px;
"
>
<Icon :size="13.2" icon="ep:plus" class="mr-6px" />新增
</el-button>
<el-button
@click="handlePersonInfoIDCard2nd"
style="
margin-left: 0;
margin-right: 6.4px;
background-color: #2d8cf0;
color: rgba(255, 255, 255, 1);
width: 126px;
"
:loading="btnPersonInfoIDCard2ndLoading"
>
<Icon
:size="13.2"
icon="ep:card"
class="mr-6px"
v-show="!btnPersonInfoIDCard2ndLoading"
/>
</el-button>
<el-button
@click="handlePersonInfoDelete"
style="
margin-left: 0;
margin-right: 6.4px;
background-color: #F56C6C;
color: rgba(255, 255, 255, 1);
width: 84px;
"
v-show="!personInfoCustomAdd"
:disabled="!selectedPatient || selectedPatient?.chargeType"
:title="selectedPatient?.chargeType ? '已收费的记录不能删除' : ''"
>
<Icon :size="13.2" icon="ep:delete" class="mr-6px" />删除此人
</el-button>
</div>
</ContentWrap>
<ContentWrap
@ -412,7 +436,7 @@
"
v-show="personInfoCustomAdd || isEditing"
>
<Icon :size="13.2" icon="ep:delete" class="mr-4px" />删除
<Icon :size="13.2" icon="ep:delete" class="mr-4px" />删除项目
</el-button>
</template>
</el-alert>
@ -835,6 +859,7 @@ const checkInfoParam_extra = ref<any>({
})
//
const personData = ref<any[]>([])
const personDataOriginal = ref<any[]>([]) // ref
const personTotal = ref(0)
const projectTable = ref<any[]>([{}, {}, {}, {}])
const projectTable_extra = ref<any>({
@ -909,10 +934,6 @@ const handlePhotographRemove = () => {
}
const handlePersonInfoEdit = () => {
if (!selectedPatient.value) {
message.warning('请先在左侧选择一名患者')
return
}
isEditing.value = true
}
@ -920,6 +941,8 @@ const handlePersonInfoCustomAdd = () => {
personInfoCustomAdd.value = true
isEditing.value = true
//
selectedPatient.value = null
selectedPatientId.value = null
personParam.value = {
avatar: '',
testNum: '',
@ -930,8 +953,6 @@ const handlePersonInfoCustomAdd = () => {
mobile: ''
}
comboInfoTable1.value = []
//
selectedPatient.value = null
}
const handlePersonInfoIDCard2nd = () => {
@ -1039,7 +1060,8 @@ const handlePersonInfoCancel = () => {
if (selectedPatient.value) {
handlePatientSelect(selectedPatient.value)
} else {
//
//
selectedPatientId.value = null
personParam.value = {
avatar: '',
testNum: '',
@ -1064,13 +1086,11 @@ const getPatientData = async () => {
checkPersonLoading.value = true
const params = {
pageNo: searchForm.value.pageNumber,
pageSize: searchForm.value.pageSize,
//
...(searchForm.value.personName && { pname: searchForm.value.personName })
pageSize: searchForm.value.pageSize
}
const res = await PatientApi.getPatientPage(params)
personData.value = res.list.map(item => ({
const mappedData = res.list.map(item => ({
id: item.id,
medicalSn: item.medicalSn,
personName: item.pname,
@ -1082,10 +1102,14 @@ const getPatientData = async () => {
physicalType: item.chargeType,
status: item.status
}))
personDataOriginal.value = mappedData //
personData.value = mappedData
personTotal.value = res.total || 0
} catch (error) {
console.error('获取患者数据出错:', error)
message.error('获取患者数据出错')
personDataOriginal.value = []
personData.value = []
personTotal.value = 0
} finally {
@ -1106,10 +1130,18 @@ const calculateAge = (birthday) => {
return age.toString()
}
// 使
// 使
const debouncedSearch = debounce(() => {
searchForm.value.pageNumber = 1
getPatientData()
const keyword = searchForm.value.personName?.trim().toLowerCase()
if (!keyword) {
personData.value = personDataOriginal.value
} else {
personData.value = personDataOriginal.value.filter(item =>
item.personName.toLowerCase().includes(keyword)
)
}
//
personTotal.value = personData.value.length
}, 300)
// 使
@ -1130,6 +1162,7 @@ watch(() => searchForm_extra.value.passStatus, () => {
// ref
const selectedPatient = ref(null)
const selectedPatientId = ref(null)
// API
const loadPatientProjects = async (medicalSn) => {
@ -1177,11 +1210,12 @@ const loadPatientProjects = async (medicalSn) => {
//
const handlePatientSelect = async (row) => {
try {
console.log('选中患者:', row) //
//
//
if (selectedPatient.value?.id === row.id) {
selectedPatient.value = null
selectedPatientId.value = null
//
personParam.value = {
avatar: '',
testNum: '',
@ -1192,15 +1226,22 @@ const handlePatientSelect = async (row) => {
mobile: ''
}
comboInfoTable1.value = []
personInfoEdit.value = false
personInfoDelete.value = false
return
}
//
selectedPatient.value = row
selectedPatient.value = {
...row,
chargeType: row.chargeType
}
selectedPatientId.value = row.id
//
const res = await PatientApi.getPatient(row.id)
console.log('获取到患者详情:', res) //
if (res) {
personParam.value = {
@ -1220,17 +1261,15 @@ const handlePatientSelect = async (row) => {
//
if (res.medicalSn) {
console.log('开始加载患者体检项目, 体检编号:', res.medicalSn) //
await loadPatientProjects(res.medicalSn)
} else {
console.log('患者没有体检编号,不加载项目') //
comboInfoTable1.value = []
}
}
} catch (error) {
console.error('获取患者详情失败:', error)
ElMessage.error('获取患者详情失败')
message.error('获取患者详情失败')
selectedPatient.value = null
selectedPatientId.value = null
//
personParam.value = {
avatar: '',
@ -1310,7 +1349,6 @@ const handleComboInfoSearch = () => {
//
const handleComboInfoSelection = (selection) => {
console.log('套餐选择变化:', selection) //
comboInfoSelectedData.value = selection
}
@ -1368,11 +1406,10 @@ const handleCheckInfoSearch = () => {
//
const handleCheckInfoSelection = (selection) => {
console.log('检查项目选择变化:', selection) //
checkInfoSelectedData.value = selection
}
// - UI
//
const confirmSelectedProjects = async () => {
try {
let selectedProjects: ProjectDetail[] = []
@ -1384,14 +1421,10 @@ const confirmSelectedProjects = async () => {
processedItemCodes.add(item.itemCode)
})
console.log('现有项目的itemCode:', Array.from(processedItemCodes))
if (selectProjectDrawerTabName.value === 'comboInfo') {
//
for (const combo of comboInfoSelectedData.value) {
try {
console.log('处理选中的套餐:', combo)
//
const moduleItems = await ExammoduleApi.getListExammodule()
//
@ -1399,23 +1432,16 @@ const confirmSelectedProjects = async () => {
item.examModuleID === combo.examModuleID
)
console.log('当前套餐的项目:', filteredItems)
//
for (const moduleItem of filteredItems) {
// itemCode
if (processedItemCodes.has(moduleItem.itemCode)) {
console.log(`项目 ${moduleItem.itemCode} 已存在,跳过`)
continue
}
try {
// 使itemCode
console.log('查询项目详情itemCode:', moduleItem.itemCode)
// - 使itemCode
//
const itemDetail = await getItemDetailByCode(moduleItem.itemCode)
console.log('获取到项目详情:', itemDetail)
//
processedItemCodes.add(moduleItem.itemCode)
@ -1444,7 +1470,6 @@ const confirmSelectedProjects = async () => {
})
}
} catch (itemError) {
console.error('处理项目失败:', itemError)
// 使
if (!processedItemCodes.has(moduleItem.itemCode)) {
processedItemCodes.add(moduleItem.itemCode)
@ -1461,7 +1486,7 @@ const confirmSelectedProjects = async () => {
}
}
} catch (comboError) {
console.error('处理套餐失败:', comboError)
message.error('处理套餐失败')
}
}
} else if (selectProjectDrawerTabName.value === 'checkInfo') {
@ -1469,7 +1494,6 @@ const confirmSelectedProjects = async () => {
for (const item of checkInfoSelectedData.value) {
// itemCode
if (processedItemCodes.has(item.itemCode)) {
console.log(`项目 ${item.itemCode} 已存在,跳过`)
continue
}
@ -1488,8 +1512,6 @@ const confirmSelectedProjects = async () => {
}
}
console.log('最终要添加的项目:', selectedProjects)
if (selectedProjects.length > 0) {
//
comboInfoTable1.value = [...comboInfoTable1.value, ...selectedProjects]
@ -1500,7 +1522,6 @@ const confirmSelectedProjects = async () => {
selectProjectDrawerShow.value = false
} catch (error) {
console.error('添加项目失败:', error)
message.error('添加项目失败')
}
}
@ -1648,7 +1669,10 @@ const handleIdCardInput = (value) => {
//
const getRowClassName = ({ row }) => {
// /
return personInfoCustomAdd.value ? 'disabled-row' : ''
if (personInfoCustomAdd.value) return 'disabled-row'
//
if (selectedPatient.value?.id === row.id) return 'selected-row'
return ''
}
//
@ -1665,6 +1689,72 @@ watch(() => [comboInfoParam.value.pageNumber, comboInfoParam.value.pageSize], ()
const isEditable = computed(() => {
return personInfoCustomAdd.value || isEditing.value
})
// script setup
const handlePersonInfoDelete = async () => {
if (!selectedPatient.value) {
message.warning('请先选择要删除的人员')
return
}
//
const data = await PatientApi.getPatient(selectedPatient.value.id)
if (data.chargeType) {
ElMessage.error('已收费的记录不能删除')
return
}
try {
//
await ElMessageBox.confirm(
'删除后将无法恢复,是否确认删除该人员及其所有体检项目?',
'警告',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
)
// 1.
if (data.chargeType) {
ElMessage.error('已收费的记录不能删除')
}
else {
await PatientitemsApi.deletePatientitemsAll(selectedPatient.value.medicalSn)
}
// 2.
await PatientApi.deletePatient(selectedPatient.value.id)
message.success('删除成功')
// 3.
selectedPatient.value = null
selectedPatientId.value = null
// 4.
personParam.value = {
avatar: '',
testNum: '',
personName: '',
sex: '',
age: '',
idCard: '',
mobile: ''
}
comboInfoTable1.value = []
// 5.
await getPatientData()
} catch (error) {
if (error === 'cancel') {
return
}
message.error('删除失败')
}
}
</script>
<style lang="scss" scoped>
@ -1760,11 +1850,6 @@ const isEditable = computed(() => {
pointer-events: none;
}
//
// :deep(.el-table__row.current-row) {
// background-color: #ecf5ff !important;
// }
.physicalRegister {
width: 100%;
height: 100%;
@ -1887,4 +1972,35 @@ const isEditable = computed(() => {
.form-item-test-num .el-form-item__content {
width: calc(100% - 72px);
}
/* 添加禁用按钮的样式 */
.el-button.is-disabled {
background-color: #c0c4cc !important;
border-color: #c0c4cc !important;
color: #ffffff !important;
cursor: not-allowed;
}
.selected-patient {
font-weight: bold;
color: #409EFF;
background-color: #ecf5ff;
padding: 2px 6px;
border-radius: 4px;
display: inline-block;
}
:deep(.selected-row) {
background-color: #ecf5ff !important;
font-weight: 500;
}
/* 自定义单选按钮样式,隐藏标签文本 */
:deep(.custom-radio) {
margin-right: 0;
.el-radio__label {
display: none;
}
}
</style>