first commit
Some checks failed
tests / ci (8.5) (push) Has been cancelled
linter / quality (push) Has been cancelled
tests / ci (8.3) (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled

This commit is contained in:
brusnitsyn
2026-04-03 17:20:05 +09:00
commit 3edc8e667e
358 changed files with 39258 additions and 0 deletions

View File

@@ -0,0 +1,293 @@
<script setup lang="ts">
import { Head, Link } from '@inertiajs/vue3';
import MedicalReportController from '@/actions/App/Http/Controllers/MedicalReportController';
import Heading from '@/components/Heading.vue';
import type {
MedicalReport,
MedicalReportEconomistAnalysis,
MedicalReportEconomistIssues,
MedicalReportEconomistSummary,
} from '@/types';
type Props = {
report: MedicalReport;
summarySheet?: MedicalReportEconomistSummary | null;
analysisSheet?: MedicalReportEconomistAnalysis | null;
analysisIssues?: MedicalReportEconomistIssues | null;
};
defineProps<Props>();
</script>
<template>
<Head :title="`${report.name} - Экономисты`" />
<div class="flex flex-col gap-6 p-4 md:p-6">
<section
class="rounded-3xl border border-slate-200 bg-linear-to-br from-white via-slate-50 to-amber-50 p-6 shadow-sm"
>
<div class="flex flex-col gap-4 md:flex-row md:items-end md:justify-between">
<div class="space-y-3">
<div class="inline-flex w-fit rounded-full bg-amber-100 px-3 py-1 text-xs font-semibold tracking-[0.18em] text-amber-700 uppercase">
Страница экономистов
</div>
<Heading
title="Свод по первой таблице Excel"
description="Отделения вводят только свои показатели, а здесь собирается первая сводная таблица для экономистов."
/>
</div>
<div class="flex flex-wrap gap-2">
<Link
:href="MedicalReportController.show({ medicalReport: report.id })"
class="rounded-full border border-slate-200 bg-white px-4 py-2 text-sm text-slate-700 transition-colors hover:border-slate-300"
>
Ввод отделений
</Link>
<Link
:href="MedicalReportController.builder({ medicalReport: report.id })"
class="rounded-full border border-slate-200 bg-white px-4 py-2 text-sm text-slate-700 transition-colors hover:border-slate-300"
>
Конструктор форм
</Link>
<div class="rounded-full border border-slate-950 bg-slate-950 px-4 py-2 text-sm text-white">
Свод экономистов
</div>
</div>
</div>
</section>
<section class="rounded-3xl border border-slate-200 bg-white p-5 shadow-sm">
<div
v-if="analysisIssues && analysisIssues.total_count > 0"
class="mb-8 rounded-2xl border border-amber-200 bg-amber-50 p-5 text-sm text-amber-950"
>
<div class="flex flex-col gap-3 md:flex-row md:items-start md:justify-between">
<div>
<div class="text-xs uppercase tracking-[0.16em] text-amber-700">
Требует настройки
</div>
<div class="mt-2 text-lg font-semibold">
Есть неполные связи для свода экономистов
</div>
<div class="mt-1 text-amber-900/80">
Не все сокращения и экспортные показатели привязаны к строкам и колонкам анализа.
</div>
</div>
<div class="rounded-2xl border border-amber-300 bg-white px-4 py-3 text-center">
<div class="text-xs uppercase tracking-[0.16em] text-amber-700">
Всего проблем
</div>
<div class="mt-1 text-2xl font-semibold">
{{ analysisIssues.total_count }}
</div>
</div>
</div>
<div
v-if="analysisIssues.unmapped_departments.length > 0"
class="mt-5 overflow-x-auto rounded-2xl border border-amber-200 bg-white"
>
<table class="min-w-full text-sm">
<thead class="bg-amber-100/60 text-left text-amber-900">
<tr>
<th class="px-4 py-3 font-semibold">Отчетчик</th>
<th class="px-4 py-3 font-semibold">Секция</th>
<th class="px-4 py-3 font-semibold">Источник</th>
<th class="px-4 py-3 font-semibold">Причина</th>
</tr>
</thead>
<tbody>
<tr
v-for="issue in analysisIssues.unmapped_departments"
:key="`${issue.department}-${issue.section}-${issue.source_department}`"
class="border-t border-amber-100"
>
<td class="px-4 py-3">{{ issue.department }}</td>
<td class="px-4 py-3">{{ issue.section }}</td>
<td class="px-4 py-3">{{ issue.source_department }}</td>
<td class="px-4 py-3">{{ issue.reason }}</td>
</tr>
</tbody>
</table>
</div>
<div
v-if="analysisIssues.unmapped_metrics.length > 0"
class="mt-5 overflow-x-auto rounded-2xl border border-amber-200 bg-white"
>
<table class="min-w-full text-sm">
<thead class="bg-amber-100/60 text-left text-amber-900">
<tr>
<th class="px-4 py-3 font-semibold">Отчетчик</th>
<th class="px-4 py-3 font-semibold">Секция</th>
<th class="px-4 py-3 font-semibold">Метрика</th>
<th class="px-4 py-3 font-semibold">Причина</th>
</tr>
</thead>
<tbody>
<tr
v-for="issue in analysisIssues.unmapped_metrics"
:key="`${issue.department}-${issue.section}-${issue.metric}`"
class="border-t border-amber-100"
>
<td class="px-4 py-3">{{ issue.department }}</td>
<td class="px-4 py-3">{{ issue.section }}</td>
<td class="px-4 py-3">{{ issue.metric }}</td>
<td class="px-4 py-3">{{ issue.reason }}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div v-if="analysisSheet" class="mb-8 border-b border-slate-100 pb-8">
<div class="mb-6 flex flex-col gap-4 md:flex-row md:items-end md:justify-between">
<div>
<div class="text-xs uppercase tracking-[0.16em] text-slate-500">
Матрица
</div>
<h1 class="mt-2 text-2xl font-semibold text-slate-950">
{{ analysisSheet.name }}
</h1>
</div>
<div class="grid gap-3 sm:grid-cols-2">
<div class="rounded-2xl border border-slate-200 bg-slate-50 p-4">
<div class="text-xs uppercase tracking-[0.16em] text-slate-500">
Подразделений с данными
</div>
<div class="mt-2 text-xl font-semibold text-slate-900">
{{ analysisSheet.filled_units }}
</div>
</div>
<div class="rounded-2xl border border-slate-200 bg-slate-50 p-4">
<div class="text-xs uppercase tracking-[0.16em] text-slate-500">
Заполненных ячеек
</div>
<div class="mt-2 text-xl font-semibold text-slate-900">
{{ analysisSheet.filled_cells }}
</div>
</div>
</div>
</div>
<div class="overflow-x-auto">
<table class="min-w-full border-separate border-spacing-0 text-sm">
<thead>
<tr>
<th class="sticky left-0 z-10 border-b border-slate-200 bg-white px-4 py-3 text-left font-semibold text-slate-900">
Подразделение
</th>
<th
v-for="column in analysisSheet.columns"
:key="column.key"
class="border-b border-slate-200 bg-white px-4 py-3 text-left font-semibold text-slate-900"
>
<div>{{ column.coordinate }}</div>
<div class="text-xs font-normal text-slate-500">
{{ column.name }}
</div>
</th>
</tr>
</thead>
<tbody>
<tr
v-for="row in analysisSheet.rows"
:key="row.unit_name"
class="odd:bg-slate-50/70"
>
<td class="sticky left-0 z-10 border-b border-slate-100 bg-inherit px-4 py-3 font-medium text-slate-900">
<div class="text-[11px] uppercase tracking-[0.16em] text-slate-400">
{{ row.profile_name ?? 'Без профиля' }}
</div>
<div>{{ row.unit_name }}</div>
</td>
<td
v-for="value in row.values"
:key="`${row.unit_name}-${value.key}`"
class="border-b border-slate-100 px-4 py-3 text-slate-700"
>
{{ value.value || '0' }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div v-if="!summarySheet" class="rounded-2xl bg-slate-50 p-6 text-sm text-slate-500">
В шаблоне не найдена первая таблица для формирования свода.
</div>
<template v-else>
<div class="mb-6 flex flex-col gap-4 border-b border-slate-100 pb-5 md:flex-row md:items-end md:justify-between">
<div>
<div class="text-xs uppercase tracking-[0.16em] text-slate-500">
Таблица
</div>
<h1 class="mt-2 text-2xl font-semibold text-slate-950">
{{ summarySheet.name }}
</h1>
</div>
<div class="grid gap-3 sm:grid-cols-2">
<div class="rounded-2xl border border-slate-200 bg-slate-50 p-4">
<div class="text-xs uppercase tracking-[0.16em] text-slate-500">
Отделений с данными
</div>
<div class="mt-2 text-xl font-semibold text-slate-900">
{{ summarySheet.filled_departments }}
</div>
</div>
<div class="rounded-2xl border border-slate-200 bg-slate-50 p-4">
<div class="text-xs uppercase tracking-[0.16em] text-slate-500">
Заполненных ячеек
</div>
<div class="mt-2 text-xl font-semibold text-slate-900">
{{ summarySheet.filled_cells }}
</div>
</div>
</div>
</div>
<div class="overflow-x-auto">
<table class="min-w-full border-separate border-spacing-0 text-sm">
<thead>
<tr>
<th class="sticky left-0 z-10 border-b border-slate-200 bg-white px-4 py-3 text-left font-semibold text-slate-900">
Отделение
</th>
<th
v-for="column in summarySheet.columns"
:key="column.coordinate"
class="border-b border-slate-200 bg-white px-4 py-3 text-left font-semibold text-slate-900"
>
{{ column.name }}
</th>
</tr>
</thead>
<tbody>
<tr
v-for="row in summarySheet.rows"
:key="row.department"
class="odd:bg-slate-50/70"
>
<td class="sticky left-0 z-10 border-b border-slate-100 bg-inherit px-4 py-3 font-medium text-slate-900">
{{ row.department }}
</td>
<td
v-for="value in row.values"
:key="`${row.department}-${value.name}`"
class="border-b border-slate-100 px-4 py-3 text-slate-700"
>
{{ value.value || '0' }}
</td>
</tr>
</tbody>
</table>
</div>
</template>
</section>
</div>
</template>