Обновлен стартовый экран
Переписаны запросы для статистики, отчетов Добавлена интеграция отчета сестры
This commit is contained in:
@@ -1,127 +1,114 @@
|
||||
<script setup>
|
||||
import {
|
||||
NModal,
|
||||
NList,
|
||||
NListItem,
|
||||
NThing,
|
||||
NAvatar,
|
||||
NIcon,
|
||||
NText,
|
||||
NDivider,
|
||||
NFlex,
|
||||
NButton,
|
||||
NScrollbar,
|
||||
NEmpty,
|
||||
NDataTable,
|
||||
NBadge,
|
||||
NForm,
|
||||
NDrawerContent,
|
||||
NInput,
|
||||
NSpin,
|
||||
NDrawer
|
||||
NModal, NDataTable, NEmpty, NSpin, NDrawer, NDrawerContent, NInput, NIcon, NTooltip, NFlex, NText
|
||||
} from 'naive-ui'
|
||||
import {useReportStore} from "../../../Stores/report.js";
|
||||
import {TbAlertCircle, TbCheck, TbEye, TbGripVertical, TbPencil, TbTrashX, TbX} from 'vue-icons-plus/tb'
|
||||
import {computed, h, ref, watch} from "vue";
|
||||
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({
|
||||
departmentId: {
|
||||
required: true
|
||||
},
|
||||
startAt: {
|
||||
required: true
|
||||
},
|
||||
endAt: {
|
||||
required: true
|
||||
}
|
||||
departmentId: { required: true },
|
||||
startAt: { required: true },
|
||||
endAt: { required: true },
|
||||
})
|
||||
|
||||
const reportStore = useReportStore()
|
||||
const open = defineModel('open')
|
||||
const loading = ref(true)
|
||||
const baseColumns = reportStore.getColumnsByKey(['num', 'fullname', 'age', 'birth_date', 'mkb.ds'])
|
||||
|
||||
const currentPatient = ref(null)
|
||||
const showMoveDrawer = ref(false)
|
||||
|
||||
const columns = computed(() => {
|
||||
// if (!isFillableMode.value) return baseColumns
|
||||
|
||||
const newColumns = []
|
||||
|
||||
const expandColumn = {
|
||||
title: '',
|
||||
width: '30',
|
||||
render: (rowData) => {
|
||||
return h(
|
||||
NIcon,
|
||||
{
|
||||
onClick: () => {
|
||||
currentPatient.value = rowData
|
||||
showMoveDrawer.value = true
|
||||
}
|
||||
},
|
||||
{
|
||||
default: h(TbEye)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const fillableColumn = {
|
||||
title: '',
|
||||
key: 'fillable',
|
||||
width: '20',
|
||||
render: (row) => h(
|
||||
NBadge,
|
||||
{
|
||||
dot: true,
|
||||
color: (row.comment && row.comment.trim()) ? '#7fe7c4' : '#e88080'
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
newColumns.push(expandColumn)
|
||||
newColumns.push(fillableColumn)
|
||||
newColumns.push(...baseColumns)
|
||||
|
||||
return newColumns
|
||||
})
|
||||
|
||||
const observablePatients = ref([])
|
||||
const fetchUnwantedEvents = () => {
|
||||
const currentPatient = ref(null)
|
||||
const showDrawer = ref(false)
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '№',
|
||||
key: 'index',
|
||||
width: 50,
|
||||
render: (_, i) => i + 1,
|
||||
},
|
||||
{
|
||||
title: 'ФИО',
|
||||
key: 'full_name',
|
||||
width: 280,
|
||||
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: 'birth_date',
|
||||
width: 100,
|
||||
render: (row) => row.birth_date ? format(new Date(row.birth_date), 'dd.MM.yyyy') : '—',
|
||||
},
|
||||
{
|
||||
title: 'Д/п',
|
||||
key: 'ingoing_date',
|
||||
width: 134,
|
||||
render: (row) => {
|
||||
const d = row.migrations?.[0]?.ingoing_date
|
||||
return d ? format(new Date(d), 'dd.MM.yyyy HH:mm') : '—'
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Диагноз',
|
||||
key: 'diagnosis',
|
||||
width: 90,
|
||||
render: (row) => {
|
||||
const m = row.migrations?.[0]
|
||||
return m?.diagnosis_code
|
||||
? h(TooltipColumn, { triggerText: m.diagnosis_code, contentText: m.diagnosis_name })
|
||||
: '—'
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
key: 'actions',
|
||||
width: 44,
|
||||
align: 'center',
|
||||
render: (row) => h(
|
||||
NIcon,
|
||||
{
|
||||
style: 'cursor:pointer',
|
||||
size: 18,
|
||||
onClick: () => { currentPatient.value = row; showDrawer.value = true },
|
||||
},
|
||||
() => h(TbEye)
|
||||
),
|
||||
},
|
||||
]
|
||||
|
||||
const fetch = () => {
|
||||
loading.value = true
|
||||
const data = {
|
||||
status: 'observation',
|
||||
startAt: props.startAt,
|
||||
endAt: props.endAt,
|
||||
departmentId: props.departmentId
|
||||
}
|
||||
axios.post('/api/mis/patients', data).then((res) => {
|
||||
observablePatients.value = reportStore.addRowNumbers(res.data?.data ?? res.data ?? [])
|
||||
axios.get('/api/statistics/reports/observable-patients', {
|
||||
params: { startAt: props.startAt, endAt: props.endAt, departmentId: props.departmentId }
|
||||
}).then((res) => {
|
||||
observablePatients.value = res.data ?? []
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
watch(() => [props.departmentId, props.endAt, props.startAt], () => {
|
||||
if (props.departmentId && props.endAt && props.startAt) {
|
||||
fetchUnwantedEvents()
|
||||
}
|
||||
}, {
|
||||
immediate: true,
|
||||
deep: true
|
||||
})
|
||||
if (props.departmentId && props.endAt && props.startAt) fetch()
|
||||
}, { immediate: true, deep: true })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NModal v-model:show="open"
|
||||
title="Пациенты на контроле"
|
||||
preset="card"
|
||||
:mask-closable="false"
|
||||
:close-on-esc="false"
|
||||
class="max-w-4xl overflow-clip h-[calc(100vh-220px)]"
|
||||
id="modal-observation-patients"
|
||||
<NModal
|
||||
v-model:show="open"
|
||||
title="Пациенты на контроле"
|
||||
preset="card"
|
||||
:mask-closable="false"
|
||||
:close-on-esc="false"
|
||||
class="max-w-5xl overflow-clip h-[calc(100vh-220px)]"
|
||||
id="modal-observable-patients"
|
||||
>
|
||||
<template v-if="loading">
|
||||
<div class="flex items-center justify-center h-full">
|
||||
@@ -129,16 +116,15 @@ watch(() => [props.departmentId, props.endAt, props.startAt], () => {
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="observablePatients.length">
|
||||
<NDataTable :columns="columns"
|
||||
ref="tableRef"
|
||||
:data="observablePatients"
|
||||
size="small"
|
||||
:loading="loading"
|
||||
max-height="200"
|
||||
min-height="200"
|
||||
:row-key="(row, index) => row.id"
|
||||
class="text-sm!">
|
||||
</NDataTable>
|
||||
<NDataTable
|
||||
:columns="columns"
|
||||
:data="observablePatients"
|
||||
table-layout="fixed"
|
||||
size="small"
|
||||
:loading="loading"
|
||||
max-height="calc(100vh - 320px)"
|
||||
:row-key="(row) => row.id"
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="h-full flex items-center justify-center">
|
||||
@@ -147,7 +133,7 @@ watch(() => [props.departmentId, props.endAt, props.startAt], () => {
|
||||
</template>
|
||||
|
||||
<NDrawer
|
||||
v-model:show="showMoveDrawer"
|
||||
v-model:show="showDrawer"
|
||||
placement="bottom"
|
||||
:min-height="400"
|
||||
:max-height="600"
|
||||
@@ -155,10 +141,27 @@ watch(() => [props.departmentId, props.endAt, props.startAt], () => {
|
||||
resizable
|
||||
:trap-focus="false"
|
||||
:block-scroll="false"
|
||||
to="#modal-observation-patients"
|
||||
to="#modal-observable-patients"
|
||||
>
|
||||
<NDrawerContent title="Причина постановки на контроль" closable>
|
||||
<NInput type="textarea" readonly :rows="8" v-model:value="currentPatient.comment" />
|
||||
<NFlex vertical :size="12">
|
||||
<NInput
|
||||
type="textarea"
|
||||
readonly
|
||||
:rows="5"
|
||||
:value="currentPatient?.observable_reason"
|
||||
placeholder="Причина не указана"
|
||||
/>
|
||||
<template v-if="currentPatient?.comment">
|
||||
<NText depth="3" style="font-size:12px;">Комментарий:</NText>
|
||||
<NInput
|
||||
type="textarea"
|
||||
readonly
|
||||
:rows="4"
|
||||
:value="currentPatient?.comment"
|
||||
/>
|
||||
</template>
|
||||
</NFlex>
|
||||
</NDrawerContent>
|
||||
</NDrawer>
|
||||
</NModal>
|
||||
@@ -167,7 +170,6 @@ watch(() => [props.departmentId, props.endAt, props.startAt], () => {
|
||||
<style scoped>
|
||||
:deep(.n-data-table-th),
|
||||
:deep(.n-data-table-td) {
|
||||
white-space: nowrap !important;
|
||||
font-size: var(--n-font-size);
|
||||
}
|
||||
</style>
|
||||
|
||||
67
resources/js/Pages/Statistic/Components/OutcomeColumn.vue
Normal file
67
resources/js/Pages/Statistic/Components/OutcomeColumn.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<script setup>
|
||||
import {NFlex, NTag, NTooltip} from 'naive-ui'
|
||||
import {percentType} from "../../../Utils/numbers.js";
|
||||
|
||||
const props = defineProps({
|
||||
isTotalRow: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
value: {
|
||||
type: [Number, String],
|
||||
default: ''
|
||||
},
|
||||
needCompletedToPlan: {
|
||||
type: [Number, String],
|
||||
default: null
|
||||
},
|
||||
progressCompletedToPlan: {
|
||||
type: [Number, String],
|
||||
default: null
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NFlex align="center" justify="center" class="relative!">
|
||||
<NTooltip v-if="needCompletedToPlan && !isTotalRow"
|
||||
trigger="hover"
|
||||
:arrow="false"
|
||||
>
|
||||
<template #trigger>
|
||||
<NTag :type="percentType(needCompletedToPlan)"
|
||||
round
|
||||
:bordered="false"
|
||||
size="tiny"
|
||||
class="absolute! -left-1.5 bottom-2.5 text-xs"
|
||||
>
|
||||
{{ needCompletedToPlan }}
|
||||
</NTag>
|
||||
</template>
|
||||
Требуется выписать для выполнения плана
|
||||
</NTooltip>
|
||||
<div>
|
||||
{{ value }}
|
||||
</div>
|
||||
<NTooltip v-if="progressCompletedToPlan && !isTotalRow"
|
||||
trigger="hover"
|
||||
:arrow="false"
|
||||
>
|
||||
<template #trigger>
|
||||
<NTag :type="percentType(progressCompletedToPlan)"
|
||||
round
|
||||
:bordered="false"
|
||||
size="tiny"
|
||||
class="absolute! -right-1.5 bottom-2.5 text-xs"
|
||||
>
|
||||
{{ progressCompletedToPlan }}%
|
||||
</NTag>
|
||||
</template>
|
||||
Прогресс выполнения плана
|
||||
</NTooltip>
|
||||
</NFlex>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user