* работа над функционалом автоматического заполнения

* исправил фантомный сдвиг даты
* переделал получение ФИО врачей из отделений
* добавил возможность поиска врача
* переписал сохранение отчета
This commit is contained in:
brusnitsyn
2026-02-05 17:11:43 +09:00
parent eab78a0291
commit 10fb138c30
22 changed files with 1192 additions and 654 deletions

View File

@@ -75,22 +75,32 @@ const formattedValue = computed(() => {
}
})
watch(() => modelValue.value, (newVal, oldVal) => {
if (!newVal) return
const handleDateUpdate = (value) => {
console.log('Получено значение:', value)
if (Array.isArray(newVal)) {
if (newVal.length === 2 &&
(!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
queryDate.value = newVal
setQueryDate()
// Устанавливаем новое значение
modelValue.value = value
// Для диапазона: отправляем только если обе даты заполнены
if (isUseDateRange.value) {
if (Array.isArray(value) && value[0] && value[1]) {
// Дебаунс для предотвращения двойной отправки
setTimeout(() => {
// Проверяем что значение не изменилось за время таймаута
if (JSON.stringify(modelValue.value) === JSON.stringify(value)) {
queryDate.value = value
setQueryDate()
}
}, 100)
}
} else {
if (newVal !== oldVal) {
queryDate.value = newVal
// Для одиночной даты отправляем сразу
if (value) {
queryDate.value = [value, value]
setQueryDate()
}
}
})
}
</script>
<template>
@@ -106,7 +116,7 @@ watch(() => modelValue.value, (newVal, oldVal) => {
placement="top-start"
input-readonly
bind-calendar-months
update-value-on-close
@update:value="value => handleDateUpdate(value)"
:type="dateType" />
<div class="cursor-pointer p-2 flex items-center justify-center" @click="showCalendar = true">
<NIcon size="20">

View File

@@ -109,6 +109,7 @@ const handleForgotPassword = async () => {
<!-- Email -->
<n-form-item label="Логин" path="login">
<n-input
id="login"
v-model:value="form.login"
placeholder="Ваш логин"
size="large"
@@ -123,6 +124,7 @@ const handleForgotPassword = async () => {
<!-- Пароль -->
<n-form-item label="Пароль" path="password">
<n-input
id="password"
v-model:value="form.password"
type="password"
placeholder="Ваш пароль"

View File

@@ -61,13 +61,16 @@ const currentDate = computed(() => {
{{ authStore.userDepartment.name_full }}
</NTag>
<DepartmentSelect v-if="isReadonlyMode" />
<NTag v-if="reportStore.reportInfo?.userName" type="warning">
Ответственный: {{ reportStore.reportInfo?.userName }}
<NTag v-if="reportStore.reportInfo?.report?.userName" type="warning">
Ответственный: {{ reportStore.reportInfo?.report.userName }}
</NTag>
</NSpace>
<div class="col-3 w-full">
<DatePickerQuery :is-head-or-admin="reportStore.reportInfo.report?.isHeadOrAdmin" v-model:date="reportStore.timestampCurrentRange" :is-one-day="reportStore.reportInfo.report?.isOneDay" />
<DatePickerQuery class="text-lg!"
:is-head-or-admin="reportStore.reportInfo.report?.isHeadOrAdmin"
v-model:date="reportStore.timestampCurrentRange"
:is-one-day="reportStore.reportInfo.report?.isOneDay" />
</div>
</div>

View File

@@ -82,15 +82,6 @@ const isReadonlyMode = computed(() => props.mode.toLowerCase() === 'readonly')
<ReportSectionHeader title="Выбывшие" status="outcome" />
</template>
<NTabs type="segment" animated>
<NTabPane name="transferred">
<template #tab>
<ReportSectionHeader title="Переведённые" status="outcome-transferred" />
</template>
<ReportSectionItem status="outcome-transferred"
@item-dragged="handleItemDragged"
@item-dropped="handleItemDropped"
/>
</NTabPane>
<NTabPane name="discharged">
<template #tab>
<ReportSectionHeader title="Выписанные" status="outcome-discharged" />
@@ -109,6 +100,15 @@ const isReadonlyMode = computed(() => props.mode.toLowerCase() === 'readonly')
@item-dropped="handleItemDropped"
/>
</NTabPane>
<NTabPane name="transferred">
<template #tab>
<ReportSectionHeader title="Переведённые" status="outcome-transferred" />
</template>
<ReportSectionItem status="outcome-transferred"
@item-dragged="handleItemDragged"
@item-dropped="handleItemDropped"
/>
</NTabPane>
</NTabs>
</NCollapseItem>
</NCollapse>

View File

@@ -244,7 +244,6 @@ function rowProps(row) {
style.push(props.isDraggable ? 'cursor: grab;' : 'cursor: arrow;')
if (props.accentIds.length) {
console.log(props.accentIds.includes(row.id))
if (props.accentIds.includes(row.id)) {
style.push('--n-merged-td-color: #047857')
}

View File

@@ -63,7 +63,10 @@ const onAfterLeave = () => {
>
<NForm id="select-user-form" ref="formRef" :model="reportStore.reportInfo" :rules="rules">
<NFormItem label="Выберите ответственного" path="userId">
<NSelect :options="users" v-model:value="reportStore.reportInfo.userId" />
<NSelect :options="users"
v-model:value="reportStore.reportInfo.userId"
filterable
/>
</NFormItem>
</NForm>
<template #action>

View File

@@ -34,7 +34,10 @@ onMounted(() => {
reportStore.reportInfo.userId = userId
reportStore.reportInfo = props
reportStore.reportInfo = {
...reportStore.reportInfo,
...props
}
reportStore.reportForm.metrika_item_3 = props.department.recipientCount
reportStore.reportForm.metrika_item_7 = props.department.extractCount
@@ -46,10 +49,17 @@ onMounted(() => {
reportStore.unwantedEvents = props.report.unwantedEvents
reportStore.timestampCurrentRange = [
props.dates.startAt,
props.dates.endAt,
]
if (props.report.isHeadOrAdmin) {
reportStore.timestampCurrentRange = [
props.dates.startAt,
props.dates.endAt,
]
} else {
reportStore.timestampCurrentRange = [
props.dates.endAt,
props.dates.endAt
]
}
// reportStore.getReportInfo()
})
@@ -63,8 +73,14 @@ const mode = computed(() => {
})
watch(() => props, (newProps) => {
reportStore.reportInfo = {
...reportStore.reportInfo,
...newProps
}
reportStore.reportInfo = newProps
if (newProps.report.isHeadOrAdmin) {
reportStore.reportInfo.userId = newProps.report.userId
}
reportStore.reportForm.metrika_item_3 = newProps.department.recipientCount
reportStore.reportForm.metrika_item_7 = newProps.department.extractCount
@@ -76,10 +92,17 @@ watch(() => props, (newProps) => {
reportStore.unwantedEvents = newProps.report.unwantedEvents
reportStore.timestampCurrentRange = [
newProps.dates.startAt,
newProps.dates.endAt,
]
if (props.report.isHeadOrAdmin) {
reportStore.timestampCurrentRange = [
props.dates.startAt,
props.dates.endAt,
]
} else {
reportStore.timestampCurrentRange = [
props.dates.endAt,
props.dates.endAt
]
}
}, {
deep: true, // важно для глубокого отслеживания
immediate: true // выполнить сразу при создании

View File

@@ -86,18 +86,27 @@ export const useReportStore = defineStore('reportStore', () => {
metrics: reportForm.value,
observationPatients: patientsData.value['observation'],
unwantedEvents: unwantedEvents.value,
dates: timestampCurrentRange.value,
userId: reportInfo.value.userId,
dates: [
timestampCurrentRange.value[0],
timestampCurrentRange.value[1]
],
userId: reportInfo.value.report.userId,
reportId: reportInfo.value.report.report_id,
...assignForm
}
axios.post('/api/report', form)
.then(r => {
router.post('/report', form, {
onSuccess: () => {
window.$message.success('Отчет сохранен')
resetReportForm()
router.visit('/')
})
}
})
// axios.post('/api/report', form)
// .then(r => {
// window.$message.success('Отчет сохранен')
// resetReportForm()
// router.visit('/')
// })
}
const resetReportForm = () => {