Добавил список умерших в статистику #4
This commit is contained in:
160
resources/js/Pages/Statistic/Components/ModalDeathPatients.vue
Normal file
160
resources/js/Pages/Statistic/Components/ModalDeathPatients.vue
Normal file
@@ -0,0 +1,160 @@
|
||||
<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>
|
||||
@@ -23,6 +23,7 @@ import ModalObservablePatients from "./Components/ModalObservablePatients.vue";
|
||||
import StatisticRecipientPlanOfYear from "../../Layouts/Components/Statistic/StatisticRecipientPlanOfYear.vue";
|
||||
import {percentType} from "../../Utils/numbers.js";
|
||||
import OutcomeColumn from "./Components/OutcomeColumn.vue";
|
||||
import ModalDeathPatients from "./Components/ModalDeathPatients.vue";
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
@@ -248,6 +249,19 @@ const columns = ref([
|
||||
width: 48,
|
||||
titleAlign: 'center',
|
||||
align: 'center',
|
||||
render: (row) => {
|
||||
if (row.isTotalRow) {
|
||||
return h(
|
||||
'span',
|
||||
{
|
||||
onClick: () => onShowDeathPatientsModal()
|
||||
},
|
||||
row.deceased
|
||||
)
|
||||
}
|
||||
|
||||
return row.deceased
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Мед. персонал',
|
||||
@@ -261,6 +275,8 @@ const columns = ref([
|
||||
const currentDepartmentId = ref(null)
|
||||
const showUnwantedEventsModal = ref(false)
|
||||
const showObservablePatientsModal = ref(false)
|
||||
const showDeathPatientsModal = ref(false)
|
||||
|
||||
const onShowUnwantedEventsModal = (departmentId) => {
|
||||
currentDepartmentId.value = departmentId
|
||||
showUnwantedEventsModal.value = true
|
||||
@@ -269,6 +285,9 @@ const onShowObservablePatientsModal = (departmentId) => {
|
||||
currentDepartmentId.value = departmentId
|
||||
showObservablePatientsModal.value = true
|
||||
}
|
||||
const onShowDeathPatientsModal = () => {
|
||||
showDeathPatientsModal.value = true
|
||||
}
|
||||
|
||||
const rowProps = (row) => {
|
||||
if (row.isGroupHeader) return {
|
||||
@@ -371,6 +390,7 @@ const buildReportHref = (departmentId, startAt, endAt) => {
|
||||
</NDataTable>
|
||||
<ModalUnwantedEvents v-model:open="showUnwantedEventsModal" :start-at="date[0]" :end-at="date[1]" :department-id="currentDepartmentId" />
|
||||
<ModalObservablePatients v-model:open="showObservablePatientsModal" :start-at="date[0]" :end-at="date[1]" :department-id="currentDepartmentId" />
|
||||
<ModalDeathPatients v-model:open="showDeathPatientsModal" :start-at="date[0]" :end-at="date[1]" />
|
||||
</AppLayout>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user