280 lines
8.4 KiB
Vue
280 lines
8.4 KiB
Vue
<script setup>
|
||
import {NDataTable, NFlex, NText, NDatePicker, NBadge, NIcon, NPopover, NTag, NSpace} from 'naive-ui'
|
||
import AppLayout from "../../Layouts/AppLayout.vue";
|
||
import {h, ref} from "vue";
|
||
import DatePickerQuery from "../../Components/DatePickerQuery.vue";
|
||
import {Link, usePage} from "@inertiajs/vue3";
|
||
import {TbAlertCircle, TbEye} from "vue-icons-plus/tb";
|
||
import ModalUnwantedEvents from "./Components/ModalUnwantedEvents.vue";
|
||
import ModalObservablePatients from "./Components/ModalObservablePatients.vue";
|
||
|
||
const props = defineProps({
|
||
data: {
|
||
type: Object,
|
||
default: []
|
||
},
|
||
isHeadOrAdmin: {
|
||
type: Boolean
|
||
},
|
||
date: {
|
||
type: [Number, Array]
|
||
},
|
||
isOneDay: {
|
||
type: Boolean
|
||
}
|
||
})
|
||
|
||
const columns = ref([
|
||
{
|
||
title: 'Отделение',
|
||
key: 'department',
|
||
width: 240,
|
||
titleAlign: 'center',
|
||
colSpan: (row) => row.colspan,
|
||
render(row) {
|
||
if (row.isGroupHeader) {
|
||
return h(NFlex, {
|
||
align: "center",
|
||
justify: "center"
|
||
}, h(NText, { style: 'font-weight: 600;' }, row.groupName))
|
||
}
|
||
|
||
if (row.isTotalRow) {
|
||
return row.department
|
||
}
|
||
|
||
// Получаем текущие query параметры
|
||
const { url } = usePage()
|
||
const currentUrl = new URL(url, window.location.origin)
|
||
const searchParams = currentUrl.searchParams
|
||
|
||
// Берем startAt и endAt из текущего URL
|
||
const propsStartAt = Array.isArray(props.date) ? props.date[0] : props.date
|
||
const propsEndAt = Array.isArray(props.date) ? props.date[1] : props.date
|
||
const startAt = searchParams.get('startAt') ?? propsStartAt
|
||
const endAt = searchParams.get('endAt') ?? propsEndAt
|
||
|
||
const linkData = {}
|
||
|
||
if (startAt)
|
||
linkData.startAt = startAt
|
||
if (endAt)
|
||
linkData.endAt = endAt
|
||
|
||
return h(NFlex, {align: 'center', justify: 'start'}, [
|
||
h(NBadge, {
|
||
dot: true,
|
||
type: row.isReportToday ? 'success' : 'error'
|
||
}),
|
||
h(Link, {
|
||
href: `/report`,
|
||
data: linkData,
|
||
class: 'underline decoration-dashed'
|
||
}, row.department),
|
||
h(NSpace, {align: 'center', size: 'small'}, [
|
||
h(NPopover, {
|
||
trigger: 'hover',
|
||
}, {
|
||
trigger: h(NTag, {
|
||
round: true,
|
||
size: 'small',
|
||
bordered: false,
|
||
class: 'cursor-pointer!',
|
||
onClick: () => onShowUnwantedEventsModal(row.department_id)
|
||
}, {
|
||
icon: h(NIcon, { }, {
|
||
default: () => h(TbAlertCircle)
|
||
}),
|
||
default: row.countUnwanted
|
||
}),
|
||
default: 'Нежелательные события'
|
||
}),
|
||
h(NPopover, {
|
||
trigger: 'hover',
|
||
}, {
|
||
trigger: h(NTag, {
|
||
round: true,
|
||
size: 'small',
|
||
bordered: false,
|
||
class: 'cursor-pointer!',
|
||
onClick: () => onShowObservablePatientsModal(row.department_id)
|
||
}, {
|
||
icon: h(NIcon, { }, {
|
||
default: () => h(TbEye)
|
||
}),
|
||
default: row.countObservable
|
||
}),
|
||
default: 'Пациенты на контроле'
|
||
}),
|
||
])
|
||
])
|
||
}
|
||
},
|
||
{
|
||
title: 'Кол-во коек',
|
||
key: 'beds',
|
||
width: 60,
|
||
titleAlign: 'center',
|
||
align: 'center',
|
||
},
|
||
{
|
||
title: 'Поступило',
|
||
key: 'recipients',
|
||
titleAlign: 'center',
|
||
children: [
|
||
{
|
||
title: 'Всего',
|
||
key: 'recipients.all',
|
||
width: 60,
|
||
titleAlign: 'center',
|
||
align: 'center',
|
||
},
|
||
{
|
||
title: 'План',
|
||
key: 'recipients.plan',
|
||
width: 60,
|
||
titleAlign: 'center',
|
||
align: 'center',
|
||
},
|
||
{
|
||
title: 'Экстр',
|
||
key: 'recipients.emergency',
|
||
width: 60,
|
||
titleAlign: 'center',
|
||
align: 'center',
|
||
},
|
||
{
|
||
title: 'Перевод',
|
||
key: 'recipients.transferred',
|
||
width: 84,
|
||
titleAlign: 'center',
|
||
align: 'center',
|
||
},
|
||
]
|
||
},
|
||
{
|
||
title: 'Выбыло',
|
||
key: 'outcome',
|
||
width: 84,
|
||
titleAlign: 'center',
|
||
align: 'center',
|
||
},
|
||
{
|
||
title: 'Состоит',
|
||
key: 'consist',
|
||
width: 84,
|
||
titleAlign: 'center',
|
||
align: 'center',
|
||
},
|
||
{
|
||
title: 'Ср. койко-день',
|
||
key: 'averageBedDays',
|
||
width: 44,
|
||
titleAlign: 'center',
|
||
align: 'center',
|
||
},
|
||
{
|
||
title: '% загруженности',
|
||
key: 'percentLoadedBeds',
|
||
width: 84,
|
||
titleAlign: 'center',
|
||
align: 'center',
|
||
},
|
||
{
|
||
title: 'Операции',
|
||
key: 'surgical',
|
||
titleAlign: 'center',
|
||
children: [
|
||
{
|
||
title: 'Э',
|
||
key: 'surgical.emergency',
|
||
width: 60,
|
||
titleAlign: 'center',
|
||
align: 'center',
|
||
},
|
||
{
|
||
title: 'П',
|
||
key: 'surgical.plan',
|
||
width: 60,
|
||
titleAlign: 'center',
|
||
align: 'center',
|
||
},
|
||
]
|
||
},
|
||
{
|
||
title: 'Умерло',
|
||
key: 'deceased',
|
||
width: 84,
|
||
titleAlign: 'center',
|
||
align: 'center',
|
||
},
|
||
{
|
||
title: 'Мед. персонал',
|
||
key: 'countStaff',
|
||
width: 84,
|
||
titleAlign: 'center',
|
||
align: 'center',
|
||
},
|
||
])
|
||
|
||
const currentDepartmentId = ref(null)
|
||
const showUnwantedEventsModal = ref(false)
|
||
const showObservablePatientsModal = ref(false)
|
||
const onShowUnwantedEventsModal = (departmentId) => {
|
||
currentDepartmentId.value = departmentId
|
||
showUnwantedEventsModal.value = true
|
||
}
|
||
const onShowObservablePatientsModal = (departmentId) => {
|
||
currentDepartmentId.value = departmentId
|
||
showObservablePatientsModal.value = true
|
||
}
|
||
|
||
const rowProps = (row) => {
|
||
if (row.isGroupHeader) return {
|
||
style: `--n-merged-td-color: var(--n-merged-th-color)`
|
||
}
|
||
if (row.isTotalRow) return {
|
||
style: `--n-merged-td-color: var(--n-merged-th-color);`
|
||
}
|
||
}
|
||
|
||
const rowClassName = (row) => {
|
||
if (row.isTotalRow)
|
||
return `total-row`
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<AppLayout>
|
||
<template #headerExtra>
|
||
<DatePickerQuery :is-head-or-admin="isHeadOrAdmin" :date="date" :is-one-day="isOneDay" />
|
||
</template>
|
||
<NDataTable :columns="columns"
|
||
:data="data"
|
||
size="small"
|
||
:single-line="false"
|
||
striped
|
||
min-height="calc(100vh - 48px - 70px)"
|
||
max-height="calc(100vh - 48px - 70px)"
|
||
:row-props="rowProps"
|
||
:row-class-name="rowClassName"
|
||
>
|
||
|
||
</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" />
|
||
</AppLayout>
|
||
</template>
|
||
|
||
<style scoped>
|
||
:deep(.n-data-table-th),
|
||
:deep(.n-data-table-td) {
|
||
font-size: var(--n-font-size);
|
||
}
|
||
|
||
:deep(.total-row td) {
|
||
--n-td-text-color: var(--n-th-icon-color-active);
|
||
font-weight: 500;
|
||
}
|
||
</style>
|