161 lines
4.5 KiB
Vue
161 lines
4.5 KiB
Vue
<script setup>
|
|
import {
|
|
NModal, NDataTable, NEmpty, NSpin, NDrawer, NDrawerContent, NInput, NIcon, NTooltip, NFlex, NText
|
|
} from 'naive-ui'
|
|
import { TbEye } from 'vue-icons-plus/tb'
|
|
import { format, formatDistanceStrict } from 'date-fns'
|
|
import { ru } from 'date-fns/locale'
|
|
import { computed, h, ref, watch } from 'vue'
|
|
import TooltipColumn from '../../Report/Components/DataTableColumns/TooltipColumn.vue'
|
|
|
|
const props = defineProps({
|
|
startAt: { required: true },
|
|
endAt: { required: true },
|
|
})
|
|
|
|
const open = defineModel('open')
|
|
const loading = ref(true)
|
|
const deadPatients = ref([])
|
|
const currentPatient = ref(null)
|
|
const showDrawer = ref(false)
|
|
|
|
// Получаем уникальные отделения для фильтра
|
|
const departmentOptions = computed(() => {
|
|
const departments = new Set()
|
|
deadPatients.value.forEach(patient => {
|
|
if (patient.department_name) {
|
|
departments.add(patient.department_name)
|
|
}
|
|
})
|
|
return Array.from(departments).map(dept => ({
|
|
label: dept,
|
|
value: dept
|
|
}))
|
|
})
|
|
|
|
// Состояние для выбранных фильтров
|
|
const filteredDepartments = ref([])
|
|
|
|
// Отфильтрованные данные
|
|
const filteredPatients = computed(() => {
|
|
if (!filteredDepartments.value || filteredDepartments.value.length === 0) {
|
|
return deadPatients.value
|
|
}
|
|
return deadPatients.value.filter(
|
|
patient => filteredDepartments.value.includes(patient.department_name)
|
|
)
|
|
})
|
|
|
|
const columns = computed(() => [
|
|
{
|
|
title: '№',
|
|
key: 'index',
|
|
width: 30,
|
|
wrap: false,
|
|
render: (_, i) => i + 1,
|
|
},
|
|
{
|
|
title: 'ФИО',
|
|
key: 'full_name',
|
|
width: 200,
|
|
ellipsis: { tooltip: { arrow: false } },
|
|
},
|
|
{
|
|
title: 'Возраст',
|
|
key: 'age',
|
|
width: 80,
|
|
render: (row) => row.birth_date
|
|
? formatDistanceStrict(new Date(row.birth_date), new Date(), { locale: ru })
|
|
: '—',
|
|
},
|
|
{
|
|
title: 'Диагноз',
|
|
key: 'diagnosis',
|
|
width: 90,
|
|
render: (row) => {
|
|
return row.diagnosis_code
|
|
? h(TooltipColumn, { triggerText: row.diagnosis_code, contentText: row.diagnosis_name })
|
|
: '—'
|
|
},
|
|
},
|
|
{
|
|
title: 'Отделение',
|
|
key: 'department_name',
|
|
width: 220,
|
|
// Добавляем фильтр для множественного выбора
|
|
filterMultiple: true,
|
|
filterOptions: departmentOptions.value,
|
|
// Функция onFilter обновляет состояние фильтра
|
|
filter: (value, row) => {
|
|
return !!~row.department_name.indexOf(value)
|
|
},
|
|
},
|
|
])
|
|
|
|
const fetch = () => {
|
|
loading.value = true
|
|
axios.get('/api/statistics/reports/dead-patients', {
|
|
params: { startAt: props.startAt, endAt: props.endAt }
|
|
}).then((res) => {
|
|
deadPatients.value = res.data ?? []
|
|
|
|
// Сбрасываем фильтр при загрузке новых данных
|
|
filteredDepartments.value = []
|
|
}).finally(() => {
|
|
loading.value = false
|
|
})
|
|
}
|
|
|
|
watch(open, (isOpen) => {
|
|
if (isOpen && props.endAt && props.startAt) {
|
|
fetch()
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<NModal
|
|
v-model:show="open"
|
|
title="Умершие"
|
|
preset="card"
|
|
:mask-closable="false"
|
|
:close-on-esc="false"
|
|
class="max-w-5xl h-[calc(100vh-220px)]"
|
|
id="modal-observable-patients"
|
|
>
|
|
<template v-if="loading">
|
|
<div class="flex items-center justify-center h-full">
|
|
<NSpin />
|
|
</div>
|
|
</template>
|
|
<template v-else-if="deadPatients.length">
|
|
<NDataTable
|
|
:columns="columns"
|
|
:data="filteredPatients"
|
|
table-layout="fixed"
|
|
size="small"
|
|
:loading="loading"
|
|
max-height="calc(100vh - 350px)"
|
|
:row-key="(row) => row.id"
|
|
/>
|
|
</template>
|
|
<template v-else>
|
|
<div class="h-full flex items-center justify-center">
|
|
<NEmpty description="Нет данных!" />
|
|
</div>
|
|
</template>
|
|
</NModal>
|
|
</template>
|
|
|
|
<style scoped>
|
|
:deep(.n-data-table-th),
|
|
:deep(.n-data-table-td) {
|
|
font-size: var(--n-font-size);
|
|
}
|
|
|
|
:deep(.n-modal .v-binder-follower-content) {
|
|
position: fixed;
|
|
inset: auto auto auto auto;
|
|
}
|
|
</style>
|