Files
onboard/resources/js/Pages/Nurse/Components/AddMedicalHistoryModal.vue

287 lines
10 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import {NModal, NSteps, NStep, NTabs, NTabPane, NFlex, NGrid, NGi, NButton, NRadioGroup, NSelect, NInput, NFormItemGi, NDatePicker} from 'naive-ui'
import {computed, ref, watch} from "vue";
import AppRadio from "../../../Components/AppRadio.vue";
import {useDebounceFn} from "@vueuse/core";
import {format} from "date-fns";
import {router, usePage} from "@inertiajs/vue3";
import AppPanel from "../../../Components/AppPanel.vue"
const show = defineModel('show', { default: false })
const currentStep = ref(1)
const currentStatus = ref('process')
const isFinallyStep = computed(() => currentStep.value === 2)
const buttonLoading = ref(false)
const form = ref({
patient_source: 'mis',
id: null,
medical_card_number: null,
full_name: '',
urgency_id: 1,
visit_result_id: 0,
birth_date: null,
recipient_date: format(new Date(), 'yyyy-MM-dd HH:mm:ss'),
death_date: null,
extract_date: null,
mis_id: null
})
const resetForm = () => {
form.value = {
...form.value,
id: null,
medical_card_number: null,
full_name: '',
urgency_id: 1,
visit_result_id: 0,
birth_date: null,
recipient_date: format(new Date(), 'yyyy-MM-dd HH:mm:ss'),
death_date: null,
extract_date: null,
mis_id: null
}
}
const urgencyOptions = [
{
label: '0 - Не определено',
value: 0
},
{
label: '1 - Планово',
value: 1
},
{
label: '2 - Экстренно',
value: 2
}
]
const visitResultOptions = [
{
label: '0 - Не определено',
value: 0
},
{
label: '1 - Выписан',
value: 1
},
{
label: '2 - Переведён в др. ЛПУ',
value: 2
},
{
label: '3 - Переведён в дневной стационар',
value: 3
},
{
label: '4 - Переведён на другой профиль коек',
value: 4
},
{
label: '5 - Умер',
value: 5
},
{
label: '6 - Умер в приёмном покое',
value: 6
},
{
label: '7 - Лечение прервано по инициативе пациента',
value: 7
},
{
label: '8 - Лечение прервано по инициативе ЛПУ',
value: 8
},
{
label: '9 - Лечение продолжено',
value: 9
},
{
label: '10 - Самовольно прерванное лечение',
value: 10
},
]
const prev = () => {
if (currentStep.value === 0)
currentStep.value = null
else currentStep.value--
}
const next = () => {
if (currentStep.value === null)
currentStep.value = 1
else currentStep.value++
}
const submit = () => {
buttonLoading.value = true
const departmentId = usePage().props.selectedDepartmentId
const userId = usePage().props.selectedUserId
axios.post(`/api/nurse/patients?departmentId=${departmentId}&userId=${userId}`, {
...form.value
}).then(res => {
router.reload({
only: [
'inDepartmentHistories',
'recipientHistories',
'dischargedHistories',
'deceasedHistories',
'transferredHistories'
],
onSuccess: () => {
show.value = false
},
onFinish: () => {
buttonLoading.value = false
}
})
}).catch((e) => {
buttonLoading.value = false
})
}
const searchOptions = ref([])
const loadingSelect = ref(false)
const loadingChangeSelect = ref(false)
const debounceSearch = useDebounceFn((s) => {
if (s.length === 0 || s.length === 1) {
searchOptions.value = []
loadingSelect.value = false
}
loadingSelect.value = true
search(s)
}, 1000)
const search = (search) => {
axios.post('/api/nurse/patients/search', {
search
}).then(res => {
searchOptions.value = res.data
}).finally((e) => {
loadingSelect.value = false
})
}
const onChangeSearch = (historyId) => {
loadingChangeSelect.value = true
axios.get(`/api/nurse/patients/${historyId}?patient_source=mis`).then(res => {
form.value.medical_card_number = res.data.medical_card_number
form.value.full_name = res.data.full_name
form.value.urgency_id = res.data.urgency_id
form.value.visit_result_id = res.data.visit_result_id
form.value.birth_date = res.data.birth_date
form.value.death_date = res.data.death_date
form.value.extract_date = res.data.extract_date
form.value.recipient_date = res.data.recipient_date
}).finally((e) => {
loadingChangeSelect.value = false
})
}
watch(() => currentStep.value, (val) => {
if (val === 1) resetForm()
})
const onAfterLeave = () => {
resetForm()
currentStep.value = 1
searchOptions.value = []
}
</script>
<template>
<NModal v-model:show="show"
segmented
preset="card"
title="Добавление пациента"
class="max-w-xl min-h-[500px]"
draggable
:close-on-esc="!buttonLoading"
:closable="!buttonLoading"
@afterLeave="onAfterLeave"
>
<NSteps size="small" :current="currentStep" :status="currentStatus">
<NStep title="Тип пациента" description="Укажите тип пациента" />
<NStep title="Добавление пациента" description="Заполните базовую информацию" />
</NSteps>
<NTabs tab-class="hidden!" :value="currentStep">
<NTabPane :name="1" class="mt-4">
<NRadioGroup class="w-full space-y-2!" v-model:value="form.patient_source">
<AppRadio title="МИС" value="mis" description="Выберите, если пациента можно найти в системе МИС" />
<AppRadio title="Спец. контингент" value="special" description="Выберите, если пациента нет в системе МИС" />
</NRadioGroup>
</NTabPane>
<NTabPane :name="2">
<AppPanel :loading="loadingChangeSelect" class="border-none!" no-padding>
<NGrid cols="2" x-gap="8">
<NFormItemGi v-if="form.patient_source === 'mis'" span="2" label="Поиск пациента">
<NSelect v-model:value="form.mis_id"
filterable
placeholder="Найти пациента по ФИО"
remote
:loading="loadingSelect"
:options="searchOptions"
@search="debounceSearch"
@change="onChangeSearch"
/>
</NFormItemGi>
<NFormItemGi span="2" label="ФИО">
<NInput v-model:value="form.full_name" placeholder="Иванов Иван Иванович" />
</NFormItemGi>
<NFormItemGi span="2" label="№ карты">
<NInput v-model:value="form.medical_card_number" />
</NFormItemGi>
<NFormItemGi span="1" label="Срочность">
<NSelect filterable v-model:value="form.urgency_id" :options="urgencyOptions" />
</NFormItemGi>
<NFormItemGi span="1" label="Исход госпитализации">
<NSelect filterable v-model:value="form.visit_result_id" :options="visitResultOptions" />
</NFormItemGi>
<NFormItemGi span="1" label="Дата рождения">
<NDatePicker v-model:formatted-value="form.birth_date" class="w-full" format="dd.MM.yyyy" value-format="yyyy-MM-dd" clearable />
</NFormItemGi>
<NFormItemGi span="1" label="Дата и время госпитализации">
<NDatePicker v-model:formatted-value="form.recipient_date" type="datetime" class="w-full" format="dd.MM.yyyy HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" clearable />
</NFormItemGi>
<NFormItemGi span="1" label="Дата и время выписки">
<NDatePicker v-model:formatted-value="form.extract_date" type="datetime" class="w-full" format="dd.MM.yyyy HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" clearable />
</NFormItemGi>
<NFormItemGi span="1" label="Дата и время смерти">
<NDatePicker v-model:formatted-value="form.death_date" type="datetime" class="w-full" format="dd.MM.yyyy HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss" clearable />
</NFormItemGi>
</NGrid>
</AppPanel>
</NTabPane>
</NTabs>
<template #action>
<NGrid cols="2" justify="space-between">
<NGi>
<NButton v-if="currentStep > 1" secondary @click="prev" :loading="buttonLoading">
Назад
</NButton>
</NGi>
<NGi>
<NFlex justify="end">
<NButton v-if="isFinallyStep" secondary type="primary" @click="submit" :loading="buttonLoading">
Добавить
</NButton>
<NButton v-else secondary type="primary" @click="next">
Далее
</NButton>
</NFlex>
</NGi>
</NGrid>
</template>
</NModal>
</template>
<style scoped>
</style>