From 6cf1ffbb2b74e284ef286c576082c1dcb00f1fc3 Mon Sep 17 00:00:00 2001 From: brusnitsyn Date: Thu, 7 May 2026 22:37:07 +0900 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B0=D0=BD=D0=B8=D0=BC=D0=B0=D1=86=D0=B8=D1=8E=20?= =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BE=D0=BA=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Web/DutyReportController.php | 4 ++ app/Models/MedicalHistory.php | 5 ++ app/Models/MigrationPatient.php | 6 ++ app/Models/Reanimation.php | 56 +++++++++++++++++++ app/Services/MedicalHistoryService.php | 24 ++++++++ package-lock.json | 17 ++---- resources/js/Components/AppPanel.vue | 2 +- .../DataTableColumns/OperationsColumn.vue | 4 +- .../Report/Components/OperationInfoModal.vue | 39 +++++-------- .../Report/Components/PatientDataTable.vue | 6 +- resources/js/Pages/Report/Index.vue | 19 ++++++- 11 files changed, 137 insertions(+), 45 deletions(-) create mode 100644 app/Models/Reanimation.php diff --git a/app/Http/Controllers/Web/DutyReportController.php b/app/Http/Controllers/Web/DutyReportController.php index 56843fb..05373ad 100644 --- a/app/Http/Controllers/Web/DutyReportController.php +++ b/app/Http/Controllers/Web/DutyReportController.php @@ -84,6 +84,9 @@ class DutyReportController extends Controller $transferredHistories = MedicalHistoryResource::collection( $this->medicalHistoryService->getTransferredHistories($dateRange, $department->rf_mis_department_id) ); + $reanimationHistories = MedicalHistoryResource::collection( + $this->medicalHistoryService->getReanimationHistories($dateRange, $department->rf_mis_department_id) + ); } return Inertia::render('Report/Index', [ @@ -94,6 +97,7 @@ class DutyReportController extends Controller 'dischargedHistories' => $dischargedHistories, 'deceasedHistories' => $deceasedHistories, 'transferredHistories' => $transferredHistories, + 'reanimationHistories' => $reanimationHistories, 'dates' => [ $dateRange->startDate->getTimestampMs(), $dateRange->endDate->getTimestampMs(), diff --git a/app/Models/MedicalHistory.php b/app/Models/MedicalHistory.php index a769fe9..37bb19e 100644 --- a/app/Models/MedicalHistory.php +++ b/app/Models/MedicalHistory.php @@ -36,6 +36,11 @@ class MedicalHistory extends MaterializedViewModel ->latest('ingoing_date'); } + public function reanimations() + { + return $this->hasMany(Reanimation::class, 'medical_history_id', 'id'); + } + public function operationsInDepartment($query, $departmentId) { return $this->operations()->where('department_id', $departmentId); diff --git a/app/Models/MigrationPatient.php b/app/Models/MigrationPatient.php index b0c4af8..01170a9 100644 --- a/app/Models/MigrationPatient.php +++ b/app/Models/MigrationPatient.php @@ -31,6 +31,12 @@ class MigrationPatient extends MaterializedViewModel ->orderBy('end_date', 'desc'); } + public function reanimations() + { + return $this->hasMany(Reanimation::class, 'migration_patient_id', 'id') + ->orderBy('out_date', 'desc'); + } + // Пересечение с отчетным периодом public function scopeDateRange($query, string $from, string $to) { diff --git a/app/Models/Reanimation.php b/app/Models/Reanimation.php new file mode 100644 index 0000000..13469ba --- /dev/null +++ b/app/Models/Reanimation.php @@ -0,0 +1,56 @@ +belongsTo(MedicalHistory::class, 'medical_history_id', 'id'); + } + + public function migration() + { + return $this->belongsTo(MigrationPatient::class, 'migration_patient_id', 'id'); + } + + // Фильтр по подразделению + public function scopeDepartment($query, int $departmentId) + { + return $query->where('migration_department_id', $departmentId); + } + + public function scopeCurrentOrAdmitted($query, DateRange $dateRange) + { + return $query->where(function ($q) use ($dateRange) { + // Вариант А: Пациент уже лежит (текущий) + $q->whereNull('out_date') + ->whereNotNull('medical_history_id') + ->where('in_date', '<', $dateRange->startSql()); + }) + ->orWhere(function ($q) use ($dateRange) { + $q->where('in_date', '<=', $dateRange->endSql()) + ->where('in_date', '>', $dateRange->startSql()); + }); + } +} diff --git a/app/Services/MedicalHistoryService.php b/app/Services/MedicalHistoryService.php index fb5000a..be8f23e 100644 --- a/app/Services/MedicalHistoryService.php +++ b/app/Services/MedicalHistoryService.php @@ -76,6 +76,7 @@ class MedicalHistoryService ->sortByDesc(fn ($mh) => $mh->latestMigration->ingoing_date ?? $mh->recipient_date) ->values(); } + public function getEmergencyHistories(DateRange $dateRange, int $departmentId) { return MedicalHistory::query() @@ -146,4 +147,27 @@ class MedicalHistoryService }, 'latestMigration.operations']) ->get(); } + + public function getReanimationHistories(DateRange $dateRange, int $departmentId) + { + return MedicalHistory::query() + ->whereHas('migrations', function ($q) use ($departmentId, $dateRange) { + $q->department($departmentId)->currentOrAdmitted($dateRange); + }) + ->whereHas('latestMigration.reanimations', function ($q) use ($dateRange) { + $q->currentOrAdmitted($dateRange); + }) + ->with( + [ + 'latestMigration' => function ($q) use ($departmentId, $dateRange) { + $q->department($departmentId)->currentOrAdmitted($dateRange)->latest('ingoing_date'); // подгружаем только отфильтрованные движения + }, + 'latestMigration.operations', + 'latestMigration.reanimations' + ]) + ->get() + // Сортировка по дате поступления в отделение (поле дочерней таблицы) + ->sortByDesc(fn ($mh) => $mh->latestMigration->ingoing_date ?? $mh->recipient_date) + ->values(); + } } diff --git a/package-lock.json b/package-lock.json index e4716f0..2def047 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1366,13 +1366,6 @@ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "license": "MIT" }, - "node_modules/@types/katex": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", - "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.21.tgz", @@ -3085,15 +3078,14 @@ "license": "MIT" }, "node_modules/naive-ui": { - "version": "2.43.2", - "resolved": "https://registry.npmjs.org/naive-ui/-/naive-ui-2.43.2.tgz", - "integrity": "sha512-YlLMnGrwGTOc+zMj90sG3ubaH5/7czsgLgGcjTLA981IUaz8r6t4WIujNt8r9PNr+dqv6XNEr0vxkARgPPjfBQ==", + "version": "2.44.1", + "resolved": "https://registry.npmjs.org/naive-ui/-/naive-ui-2.44.1.tgz", + "integrity": "sha512-reo8Esw0p58liZwbUutC7meW24Xbn3EwNv91zReWKm2W4JPu+zfgJRn/F7aO0BFmvN+h2brA2M5lRvYqLq4kuA==", "dev": true, "license": "MIT", "dependencies": { "@css-render/plugin-bem": "^0.15.14", "@css-render/vue3-ssr": "^0.15.14", - "@types/katex": "^0.16.2", "@types/lodash": "^4.17.20", "@types/lodash-es": "^4.17.12", "async-validator": "^4.2.5", @@ -3111,6 +3103,9 @@ "vooks": "^0.2.12", "vueuc": "^0.4.65" }, + "engines": { + "node": ">=20" + }, "peerDependencies": { "vue": "^3.0.0" } diff --git a/resources/js/Components/AppPanel.vue b/resources/js/Components/AppPanel.vue index eeeb82f..b523e4a 100644 --- a/resources/js/Components/AppPanel.vue +++ b/resources/js/Components/AppPanel.vue @@ -76,7 +76,7 @@ watch(() => [props.minH, props.maxH], ([minH, maxH]) => { diff --git a/resources/js/Pages/Report/Components/DataTableColumns/OperationsColumn.vue b/resources/js/Pages/Report/Components/DataTableColumns/OperationsColumn.vue index a9164c7..21c1157 100644 --- a/resources/js/Pages/Report/Components/DataTableColumns/OperationsColumn.vue +++ b/resources/js/Pages/Report/Components/DataTableColumns/OperationsColumn.vue @@ -5,13 +5,15 @@ const props = defineProps({ operations: Array }) +const emits = defineEmits(['click']) + const firstOperation = computed(() => props.operations[0])