Обновлен стартовый экран

Переписаны запросы для статистики, отчетов
Добавлена интеграция отчета сестры
This commit is contained in:
brusnitsyn
2026-05-28 22:10:00 +09:00
parent 90e0d04dfd
commit 739168d427
96 changed files with 6663 additions and 1465 deletions

View File

@@ -1,106 +1,127 @@
<script setup>
import {NButton, NFlex, NGi, NGrid, NH2, NForm, NFormItem, NInput, NTransfer, NSwitch} from "naive-ui";
import AppLayout from "../../../Layouts/AppLayout.vue";
import AppContainer from "../../../Components/AppContainer.vue";
import AppPanel from "../../../Components/AppPanel.vue";
import {useForm} from "@inertiajs/vue3";
import {computed, ref} from "vue";
import {
NButton, NFlex, NForm, NFormItem, NInput,
NTransfer, NSwitch, NSelect, NText, NEl, NIcon,
} from 'naive-ui'
import { TbUser, TbAt, TbLock, TbBuildingHospital, TbUserShield, TbLayoutDashboard, TbUsers } from 'vue-icons-plus/tb'
import AppLayout from '../../../Layouts/AppLayout.vue'
import AppContainer from '../../../Components/AppContainer.vue'
import SectionCard from '../../../Components/SectionCard.vue'
import PageBanner from '../../../Components/PageBanner.vue'
import { useForm, Link } from '@inertiajs/vue3'
import { computed } from 'vue'
const props = defineProps({
departments: {
type: Array,
default: []
},
roles: {
type: Array,
default: []
}
departments: { type: Array, default: () => [] },
roles: { type: Array, default: () => [] },
})
const departmentOptions = computed(() => props.departments.map(itm => ({
label: itm.name_full,
value: itm.department_id
})))
const roleOptions = computed(() => props.roles.map(itm => ({
label: itm.name,
value: itm.role_id
const departmentOptions = computed(() => props.departments.map(d => ({
label: d.name_full,
value: d.department_id,
})))
const form = ref({
'name': '',
'login': '',
'password': '',
'is_active': true,
const roleOptions = computed(() => props.roles.map(r => ({
label: r.name,
value: r.role_id,
})))
const form = useForm({
name: '',
login: '',
password: '',
is_active: true,
department_id: null,
departments: [],
roles: [],
})
const submit = () => form.post('/admin/users/new')
</script>
<template>
<AppLayout>
<template #header>
<NFlex align="center" justify="space-between" class="max-w-6xl mx-auto mt-6 mb-4 w-full">
<NH2>
Создание учетной записи
</NH2>
</NFlex>
</template>
<AppContainer>
<NGrid cols="2" x-gap="16">
<NGi>
<AppPanel header="Основная информация">
<NForm v-model:model="form">
<NFormItem label="Имя">
<NInput v-model:value="form.name" />
</NFormItem>
<NFormItem label="Привязка к ресурсу МИС">
<NInput v-model:value="form.password" />
</NFormItem>
<NFormItem label="Основное отделение">
<NInput v-model:value="form.password" />
</NFormItem>
<NFormItem label-placement="left" label-width="auto" label-style="align-items: center;" label="Пользователь заблокирован">
<NSwitch />
</NFormItem>
</NForm>
</AppPanel>
</NGi>
<NGi>
<AppPanel header="Данные для входа">
<NForm v-model:model="form">
<NFormItem label="Логин">
<NInput v-model:value="form.login" />
</NFormItem>
<NFormItem label="Пароль">
<NInput type="password" v-model:value="form.password" show-password-toggle />
</NFormItem>
</NForm>
</AppPanel>
</NGi>
</NGrid>
<AppPanel no-padding header="Привязка к отделениям">
<NTransfer
v-model:value="form.departments"
virtual-scroll
:options="departmentOptions"
source-filterable
target-filterable
/>
</AppPanel>
<PageBanner
title="Новый пользователь"
:icon="TbUser"
color="default"
:breadcrumbs="[
{ label: 'Администратор', href: '/admin', icon: TbLayoutDashboard, tag: Link },
{ label: 'Учётные записи', href: '/admin/users', icon: TbUsers, tag: Link },
]"
>
<template #meta>
<NText depth="3" style="font-size: 13px;">
Заполните данные для создания учётной записи
</NText>
</template>
<template #actions>
<NButton :tag="Link" href="/admin/users">Отмена</NButton>
<NButton type="primary" :loading="form.processing" @click="submit">
Создать пользователя
</NButton>
</template>
</PageBanner>
<NEl style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px;">
<SectionCard title="Личные данные" :icon="TbUser">
<NForm label-placement="top">
<NFormItem label="Имя" :feedback="form.errors.name" :validation-status="form.errors.name ? 'error' : undefined">
<NInput v-model:value="form.name" placeholder="Иванов Иван Иванович">
<template #prefix><NIcon depth="3"><TbUser /></NIcon></template>
</NInput>
</NFormItem>
<NFormItem label="Основное отделение" :feedback="form.errors.department_id" :validation-status="form.errors.department_id ? 'error' : undefined">
<NSelect v-model:value="form.department_id" :options="departmentOptions" filterable placeholder="Выберите отделение" />
</NFormItem>
<NFormItem label="Статус" style="margin-bottom: 0;">
<NFlex align="center" justify="space-between" style="width: 100%;">
<div>
<NText style="font-size: 14px; display: block;">
{{ form.is_active ? 'Пользователь активен' : 'Пользователь заблокирован' }}
</NText>
<NText depth="3" style="font-size: 12px;">
{{ form.is_active ? 'Может входить в систему' : 'Вход запрещён' }}
</NText>
</div>
<NSwitch v-model:value="form.is_active" />
</NFlex>
</NFormItem>
</NForm>
</SectionCard>
<SectionCard title="Данные для входа" :icon="TbLock">
<NForm label-placement="top">
<NFormItem label="Логин" :feedback="form.errors.login" :validation-status="form.errors.login ? 'error' : undefined">
<NInput v-model:value="form.login" placeholder="ivanov_i">
<template #prefix><NIcon depth="3"><TbAt /></NIcon></template>
</NInput>
</NFormItem>
<NFormItem label="Пароль" :feedback="form.errors.password" :validation-status="form.errors.password ? 'error' : undefined" style="margin-bottom: 0;">
<NInput v-model:value="form.password" type="password" show-password-toggle placeholder="Минимум 6 символов">
<template #prefix><NIcon depth="3"><TbLock /></NIcon></template>
</NInput>
</NFormItem>
</NForm>
</SectionCard>
</NEl>
<SectionCard title="Роли" :icon="TbUserShield" no-padding>
<NTransfer v-model:value="form.roles" :options="roleOptions" source-filterable source-title="Доступные роли" target-title="Назначенные роли" />
</SectionCard>
<SectionCard title="Дополнительные отделения" :icon="TbBuildingHospital" no-padding>
<NTransfer v-model:value="form.departments" virtual-scroll :options="departmentOptions" source-filterable target-filterable source-title="Все отделения" target-title="Доступные отделения" />
</SectionCard>
<AppPanel no-padding header="Роли">
<NTransfer
v-model:value="form.roles"
virtual-scroll
:options="roleOptions"
source-filterable
target-filterable
/>
</AppPanel>
</AppContainer>
</AppLayout>
</template>
<style scoped>
:deep(.n-transfer) { border: none !important; border-radius: 0 !important; }
</style>