Профиль хирургии

This commit is contained in:
brusnitsyn
2026-03-25 17:37:32 +09:00
parent 52a80ccd3b
commit f566ab96df
75 changed files with 3841 additions and 1009 deletions

View File

@@ -1,12 +1,27 @@
<script setup>
import {NDataTable, NFlex, NText, NDatePicker, NBadge, NIcon, NPopover, NTag, NSpace} from 'naive-ui'
import {
NDataTable,
NFlex,
NText,
NDivider,
NBadge,
NIcon,
NPopover,
NTag,
NSpace,
NButton,
NNumberAnimation
} 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 {Link, router, usePage} from "@inertiajs/vue3";
import {TbAlertCircle, TbEye} from "vue-icons-plus/tb";
import {PiMicrosoftExcelLogo} from "vue-icons-plus/pi";
import ModalUnwantedEvents from "./Components/ModalUnwantedEvents.vue";
import ModalObservablePatients from "./Components/ModalObservablePatients.vue";
import StatisticRecipientPlanOfYear from "../../Layouts/Components/Statistic/StatisticRecipientPlanOfYear.vue";
import {percentType} from "../../Utils/numbers.js";
const props = defineProps({
data: {
@@ -21,6 +36,10 @@ const props = defineProps({
},
isOneDay: {
type: Boolean
},
recipientPlanOfYear: {
type: Object,
default: {}
}
})
@@ -28,15 +47,18 @@ const columns = ref([
{
title: 'Отделение',
key: 'department',
width: 240,
width: 200,
titleAlign: 'center',
cellProps: (row) => ({
style: '--n-merged-td-color: var(--n-merged-th-color); --n-merged-td-color-striped: var(--n-merged-th-color); --n-td-text-color: var(--color-zinc-400); --n-th-text-color: var(--color-zinc-400);'
}),
colSpan: (row) => row.colspan,
render(row) {
if (row.isGroupHeader) {
return h(NFlex, {
align: "center",
justify: "center"
}, h(NText, { style: 'font-weight: 600;' }, row.groupName))
}, h(NText, { style: 'font-weight: 600; color: var(--color-zinc-400)' }, row.groupName))
}
if (row.isTotalRow) {
@@ -61,6 +83,8 @@ const columns = ref([
if (endAt)
linkData.endAt = endAt
linkData.departmentId = row.department_id
return h(NFlex, {align: 'center', justify: 'start'}, [
h(NBadge, {
dot: true,
@@ -158,6 +182,23 @@ const columns = ref([
width: 84,
titleAlign: 'center',
align: 'center',
render(row) {
console.log(row)
return h(
'div',
{
class: 'relative'
},
[
h('div', {}, row.outcome),
!row.isTotalRow ? h('div', {
class: 'absolute -right-1.5 bottom-2.5 text-xs',
}, [
h(NTag, {size: 'tiny', round: true, bordered: false, type: percentType(row.percentPlanOfYear)}, `${row.percentPlanOfYear}%`)
]) : null
]
)
}
},
{
title: 'Состоит',
@@ -173,10 +214,24 @@ const columns = ref([
titleAlign: 'center',
align: 'center',
},
{
title: 'Пред. опер. койко-день',
key: 'preoperativeDays',
width: 82,
titleAlign: 'center',
align: 'center',
},
{
title: '% загруженности',
key: 'percentLoadedBeds',
width: 84,
width: 78,
titleAlign: 'center',
align: 'center',
},
{
title: '% летальности',
key: 'lethality',
width: 66,
titleAlign: 'center',
align: 'center',
},
@@ -188,14 +243,14 @@ const columns = ref([
{
title: 'Э',
key: 'surgical.emergency',
width: 60,
width: 44,
titleAlign: 'center',
align: 'center',
},
{
title: 'П',
key: 'surgical.plan',
width: 60,
width: 44,
titleAlign: 'center',
align: 'center',
},
@@ -204,14 +259,14 @@ const columns = ref([
{
title: 'Умерло',
key: 'deceased',
width: 84,
width: 48,
titleAlign: 'center',
align: 'center',
},
{
title: 'Мед. персонал',
key: 'countStaff',
width: 84,
width: 54,
titleAlign: 'center',
align: 'center',
},
@@ -242,12 +297,51 @@ const rowClassName = (row) => {
if (row.isTotalRow)
return `total-row`
}
const downloadReport = async () => {
try {
const response = await fetch(`/statistic/report?startAt=${props.date[0]}&endAt=${props.date[1]}`, {
method: 'GET',
headers: {
'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
},
})
if (!response.ok) {
throw new Error('Ошибка загрузки файла')
}
const blob = await response.blob()
const url = window.URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = 'Статистика по отделениям.xlsx'
document.body.appendChild(a)
a.click()
window.URL.revokeObjectURL(url)
document.body.removeChild(a)
} catch (error) {
console.error('Ошибка скачивания:', error)
}
}
</script>
<template>
<AppLayout>
<template #headerExtra>
<DatePickerQuery :is-head-or-admin="isHeadOrAdmin" :date="date" :is-one-day="isOneDay" />
<NSpace align="center">
<DatePickerQuery :is-head-or-admin="isHeadOrAdmin" :is-show-current-date-switch="true" :date="date" :is-one-day="isOneDay" />
<NDivider vertical />
<NButton type="info" secondary @click="downloadReport">
<template #icon>
<PiMicrosoftExcelLogo />
</template>
Сохранить в Excel
</NButton>
</NSpace>
</template>
<template #headerSuffix>
<StatisticRecipientPlanOfYear :plan="recipientPlanOfYear.plan" :progress="recipientPlanOfYear.progress" />
</template>
<NDataTable :columns="columns"
:data="data"
@@ -272,6 +366,10 @@ const rowClassName = (row) => {
font-size: var(--n-font-size);
}
:deep(.n-data-table-th) {
color: var(--color-zinc-400);
}
:deep(.total-row td) {
--n-td-text-color: var(--n-th-icon-color-active);
font-weight: 500;