* доработал страницу отчета дежурного * переделал "действия" над пациентом * подключил виджеты на странице отчета дежурного
297 lines
14 KiB
Vue
297 lines
14 KiB
Vue
<script setup>
|
|
import AppLayout from "../../Layouts/AppLayout.vue";
|
|
import {useReportStore} from "../../Stores/report.js";
|
|
import {computed, h, onMounted, ref, watch} from "vue";
|
|
import {useAuthStore} from "../../Stores/auth.js";
|
|
import {
|
|
NFormItem,
|
|
NFlex,
|
|
NInputNumber,
|
|
NStatistic,
|
|
NTabPane,
|
|
NTabs,
|
|
NTag,
|
|
NNumberAnimation,
|
|
NSkeleton,
|
|
NRow, NCol, NDivider, NButton
|
|
} from "naive-ui";
|
|
import DatePickerQuery from "../../Components/DatePickerQuery.vue";
|
|
import AppPanel from "../../Components/AppPanel.vue";
|
|
import AppContainer from "../../Components/AppContainer.vue";
|
|
import PatientTypeSection from "./Components/PatientSection.vue";
|
|
import PatientTypeSectionItem from "./Components/PatientSectionItem.vue";
|
|
import PatientDataTable from "./Components/PatientDataTable.vue";
|
|
import {format, formatDistanceStrict} from 'date-fns';
|
|
import { ru } from 'date-fns/locale';
|
|
import TooltipColumn from "./Components/DataTableColumns/TooltipColumn.vue";
|
|
import ActionsColumn from "./Components/DataTableColumns/ActionsColumn.vue";
|
|
import OperationsColumn from "./Components/DataTableColumns/OperationsColumn.vue";
|
|
import ReportWidget from "./Components/ReportWidget.vue";
|
|
import OperationInfoModal from "./Components/OperationInfoModal.vue";
|
|
import {usePatientColumns} from "../../Composables/usePatientColumns.js";
|
|
import {router} from "@inertiajs/vue3";
|
|
|
|
const props = defineProps({
|
|
department: {
|
|
type: Object,
|
|
default: {}
|
|
},
|
|
report: {
|
|
type: Object,
|
|
default: {}
|
|
},
|
|
metrikaItems: {
|
|
type: Array,
|
|
default: []
|
|
},
|
|
patients: {
|
|
type: Array,
|
|
default: () => ([])
|
|
},
|
|
dates: {
|
|
type: Array,
|
|
default: []
|
|
}
|
|
})
|
|
|
|
const reportStore = useReportStore()
|
|
const authStore = useAuthStore()
|
|
const userDepartment = authStore.userDepartment
|
|
const loading = ref(false)
|
|
const operationsInModal = ref(null)
|
|
const showOperationsModal = ref(false)
|
|
|
|
const patientsByGroup = computed(() => {
|
|
const groups = {
|
|
urgent: [],
|
|
planned: [],
|
|
deceased: [],
|
|
in_department: [],
|
|
recipient: [],
|
|
discharged: [],
|
|
transferred: [],
|
|
};
|
|
|
|
for (const p of props.patients.data) {
|
|
// Группировка по срочности
|
|
if (p.patient_urgency === 'urgent') groups.urgent.push(p);
|
|
else if (p.patient_urgency === 'planned') groups.planned.push(p);
|
|
|
|
// Группировка по статусу (дублирование нужно, если один пациент может быть в двух таблицах)
|
|
if (groups.hasOwnProperty(p.patient_status)) {
|
|
groups[p.patient_status].push(p);
|
|
}
|
|
}
|
|
|
|
return groups;
|
|
})
|
|
|
|
const {
|
|
planOrEmergencyColumns, observableColumns, reanimationColumns, dischargedColumns,
|
|
deceasedColumns, transferredColumns,
|
|
} = usePatientColumns({
|
|
onAddObservable: (row) => {
|
|
console.log(row)
|
|
},
|
|
onShowOperationModal: (operations) => {
|
|
operationsInModal.value = operations
|
|
showOperationsModal.value = true
|
|
}
|
|
})
|
|
|
|
const submit = () => {
|
|
router.post('/duty/report/save', {}, {
|
|
onSuccess: () => {
|
|
alert('Сохранено')
|
|
}
|
|
})
|
|
}
|
|
|
|
const syncPageProps = () => reportStore.initializeFromPage(props)
|
|
|
|
onMounted(syncPageProps)
|
|
|
|
watch(() => props, (newProps) => {
|
|
reportStore.initializeFromPage(newProps)
|
|
}, {
|
|
deep: true,
|
|
immediate: true
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<AppLayout>
|
|
<!-- <template #headerSuffix>-->
|
|
<!-- <StatisticRecipientPlanOfYear :plan="reportStore.reportInfo.department.recipientPlanOfYear" :progress="reportStore.reportInfo.department.progressPlanOfYear" />-->
|
|
<!-- </template>-->
|
|
<!-- <ReportForm :mode />-->
|
|
|
|
<AppContainer>
|
|
<AppPanel>
|
|
<NFlex justify="space-between" align="center">
|
|
<NTag type="info" :bordered="false">
|
|
{{ userDepartment.name_full }}
|
|
</NTag>
|
|
<DatePickerQuery :date="dates" :is-head-or-admin="true" class="text-lg!" />
|
|
</NFlex>
|
|
<NDivider dashed class="my-4! mt-3!" />
|
|
<NRow class="grow space-x-2">
|
|
<NCol :span="3">
|
|
<AppPanel no-padding>
|
|
<div class="flex flex-col items-center justify-center text-center py-2">
|
|
<NStatistic label="Коек">
|
|
<template #default>
|
|
<NSkeleton v-if="reportStore.isLoadReportInfo" round class="w-[70px]! mt-2 h-[29px]!" />
|
|
<NNumberAnimation v-else :from="0" :to="reportStore.reportInfo?.department?.beds" />
|
|
</template>
|
|
</NStatistic>
|
|
</div>
|
|
</AppPanel>
|
|
</NCol>
|
|
<NCol :span="3">
|
|
<AppPanel no-padding>
|
|
<div class="flex flex-col items-center justify-center text-center py-2">
|
|
<NStatistic label="Загруженность">
|
|
<template #default>
|
|
<NNumberAnimation :from="0" :to="reportStore.reportInfo?.department?.percentLoadedBeds" />
|
|
<span>%</span>
|
|
</template>
|
|
</NStatistic>
|
|
</div>
|
|
</AppPanel>
|
|
</NCol>
|
|
<NCol :span="3">
|
|
<AppPanel no-padding>
|
|
<div class="flex flex-col items-center justify-center text-center py-2">
|
|
<NStatistic label="Состоит">
|
|
<NNumberAnimation :from="0" :to="patientsByGroup.in_department.length + patientsByGroup.recipient.length" />
|
|
</NStatistic>
|
|
</div>
|
|
</AppPanel>
|
|
</NCol>
|
|
<NCol :span="3">
|
|
<AppPanel no-padding>
|
|
<div class="flex flex-col items-center justify-center text-center py-2">
|
|
<NStatistic label="Поступило">
|
|
<NNumberAnimation :from="0" :to="patientsByGroup.recipient.length" />
|
|
</NStatistic>
|
|
</div>
|
|
</AppPanel>
|
|
</NCol>
|
|
<NCol :span="3">
|
|
<AppPanel no-padding>
|
|
<div class="flex flex-col items-center justify-center text-center py-2">
|
|
<NStatistic label="Выбыло">
|
|
<NNumberAnimation :from="0" :to="patientsByGroup.deceased.length + patientsByGroup.discharged.length" />
|
|
</NStatistic>
|
|
</div>
|
|
</AppPanel>
|
|
</NCol>
|
|
</NRow>
|
|
|
|
</AppPanel>
|
|
<div class="grid grid-cols-[1fr_auto] gap-x-2">
|
|
<AppPanel>
|
|
<NFlex align="center" :wrap="false">
|
|
<NFormItem label="Поступило" :show-feedback="false">
|
|
<NInputNumber :min="0" />
|
|
</NFormItem>
|
|
<NFormItem label="Выбыло" :show-feedback="false">
|
|
<NInputNumber :min="0" />
|
|
</NFormItem>
|
|
<NFormItem label="Состоит" :show-feedback="false">
|
|
<NInputNumber :min="0" />
|
|
</NFormItem>
|
|
<NFormItem label="Мед. персонал" :show-feedback="false">
|
|
<NInputNumber :min="0" />
|
|
</NFormItem>
|
|
</NFlex>
|
|
</AppPanel>
|
|
<NFlex :wrap="false" :size="8">
|
|
<ReportWidget :to="patientsByGroup.deceased.length">
|
|
Умерло
|
|
</ReportWidget>
|
|
<ReportWidget :to="patientsByGroup.deceased.length">
|
|
<NSpace vertical :size="0">
|
|
<div>Летальность</div>
|
|
<div>%</div>
|
|
</NSpace>
|
|
</ReportWidget>
|
|
<ReportWidget :to="patientsByGroup.deceased.length">
|
|
<NSpace vertical :size="0">
|
|
<div>Операций</div>
|
|
<div>Э / П</div>
|
|
</NSpace>
|
|
</ReportWidget>
|
|
</NFlex>
|
|
</div>
|
|
<AppPanel>
|
|
<NTabs type="segment">
|
|
<NTabPane name="mis" tab="МИС">
|
|
<PatientTypeSection>
|
|
<PatientTypeSectionItem label="Планово" :counter="patientsByGroup.planned.length">
|
|
<PatientDataTable :data="patientsByGroup.planned" :columns="planOrEmergencyColumns" />
|
|
</PatientTypeSectionItem>
|
|
<PatientTypeSectionItem label="Экстренно" :counter="patientsByGroup.urgent.length">
|
|
<PatientDataTable :data="patientsByGroup.urgent" :columns="planOrEmergencyColumns" />
|
|
</PatientTypeSectionItem>
|
|
<PatientTypeSectionItem label="Находятся на контроле" :counter="patientsByGroup.recipient.length">
|
|
<PatientDataTable :data="patientsByGroup.recipient" :columns="observableColumns" />
|
|
</PatientTypeSectionItem>
|
|
<PatientTypeSectionItem label="Находятся в реанимации" :counter="patientsByGroup.recipient.length">
|
|
<PatientDataTable :data="patientsByGroup.recipient" :columns="reanimationColumns" />
|
|
</PatientTypeSectionItem>
|
|
<PatientTypeSectionItem label="Выбывшие" :counter="patientsByGroup.discharged.length + patientsByGroup.deceased.length">
|
|
<NTabs type="segment" animated>
|
|
<NTabPane name="1" :tab="`Выписанные (${patientsByGroup.discharged.length})`">
|
|
<PatientDataTable :data="patientsByGroup.discharged" :columns="dischargedColumns" />
|
|
</NTabPane>
|
|
<NTabPane name="2" :tab="`Умершие (${patientsByGroup.deceased.length})`">
|
|
<PatientDataTable :data="patientsByGroup.deceased" :columns="deceasedColumns" />
|
|
</NTabPane>
|
|
<NTabPane name="3" :tab="`Переведенные (${patientsByGroup.transferred.length})`">
|
|
<PatientDataTable :data="patientsByGroup.transferred" :columns="transferredColumns" />
|
|
</NTabPane>
|
|
</NTabs>
|
|
</PatientTypeSectionItem>
|
|
</PatientTypeSection>
|
|
</NTabPane>
|
|
<NTabPane name="nurse" tab="Мед. сестра">
|
|
<PatientTypeSection>
|
|
<PatientTypeSectionItem label="Планово" :counter="patientsByGroup.planned.length">
|
|
<PatientDataTable :data="patientsByGroup.planned" :columns="planOrEmergencyColumns" />
|
|
</PatientTypeSectionItem>
|
|
<PatientTypeSectionItem label="Экстренно" :counter="patientsByGroup.urgent.length">
|
|
<PatientDataTable :data="patientsByGroup.urgent" :columns="planOrEmergencyColumns" />
|
|
</PatientTypeSectionItem>
|
|
<PatientTypeSectionItem label="Находятся на контроле" :counter="patientsByGroup.recipient.length">
|
|
<PatientDataTable :data="patientsByGroup.recipient" :columns="observableColumns" />
|
|
</PatientTypeSectionItem>
|
|
<PatientTypeSectionItem label="Находятся в реанимации" :counter="patientsByGroup.recipient.length">
|
|
<PatientDataTable :data="patientsByGroup.recipient" :columns="reanimationColumns" />
|
|
</PatientTypeSectionItem>
|
|
<PatientTypeSectionItem label="Выбывшие" :counter="patientsByGroup.discharged.length + patientsByGroup.deceased.length">
|
|
<NTabs type="segment" animated>
|
|
<NTabPane name="1" :tab="`Выписанные (${patientsByGroup.discharged.length})`">
|
|
<PatientDataTable :data="patientsByGroup.discharged" :columns="dischargedColumns" />
|
|
</NTabPane>
|
|
<NTabPane name="2" :tab="`Умершие (${patientsByGroup.deceased.length})`">
|
|
<PatientDataTable :data="patientsByGroup.deceased" :columns="deceasedColumns" />
|
|
</NTabPane>
|
|
<NTabPane name="3" :tab="`Переведенные (${patientsByGroup.transferred.length})`">
|
|
<PatientDataTable :data="patientsByGroup.transferred" :columns="transferredColumns" />
|
|
</NTabPane>
|
|
</NTabs>
|
|
</PatientTypeSectionItem>
|
|
</PatientTypeSection>
|
|
</NTabPane>
|
|
</NTabs>
|
|
</AppPanel>
|
|
<NButton secondary size="large" @click="submit" :loading="loading">
|
|
Сохранить отчет
|
|
</NButton>
|
|
</AppContainer>
|
|
</AppLayout>
|
|
<OperationInfoModal :operations="operationsInModal" v-model:show="showOperationsModal" />
|
|
</template>
|