From 741781dcb38badc87b9115292947203224738a0a Mon Sep 17 00:00:00 2001 From: brusnitsyn Date: Fri, 6 Feb 2026 15:15:03 +0900 Subject: [PATCH] =?UTF-8?q?=D0=9D=D0=B5=D1=81=D0=BA=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D0=BA=D0=BE=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B9=20=D0=B4=D0=BB=D1=8F=20=D0=B2=D1=80=D0=B0=D1=87=D0=B5?= =?UTF-8?q?=D0=B9=20=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=B4=D1=81=D1=87=D0=B5=D1=82=20=D0=BE=D0=BF=D0=B5?= =?UTF-8?q?=D1=80=D0=B0=D1=86=D0=B8=D0=B9=20=D0=97=D0=B0=D0=BA=D0=BE=D0=BD?= =?UTF-8?q?=D1=87=D0=B8=D0=BB=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8E?= =?UTF-8?q?=20=D0=BD=D0=B0=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=20=D0=BE=D1=82=D1=87=D0=B5=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Console/Commands/FillReportsFromDate.php | 9 ++-- .../Controllers/Web/StatisticController.php | 22 +++++---- app/Models/LifeMisMigrationPatient.php | 6 +-- app/Models/User.php | 10 ++++ app/Models/UserDepartment.php | 26 ++++++++++ app/Services/AutoReportService.php | 47 +++++++++---------- app/Services/PatientService.php | 15 +++--- ...6_112905_create_user_departments_table.php | 29 ++++++++++++ resources/js/Pages/Index.vue | 3 +- 9 files changed, 117 insertions(+), 50 deletions(-) create mode 100644 app/Models/UserDepartment.php create mode 100644 database/migrations/2026_02_06_112905_create_user_departments_table.php diff --git a/app/Console/Commands/FillReportsFromDate.php b/app/Console/Commands/FillReportsFromDate.php index 65f43ae..3533502 100644 --- a/app/Console/Commands/FillReportsFromDate.php +++ b/app/Console/Commands/FillReportsFromDate.php @@ -49,11 +49,13 @@ class FillReportsFromDate extends Command $totalErrors = 0; foreach ($departments as $department) { - $this->info("Обработка отделения: {$department->name}"); + $this->info("Обработка отделения: {$department->name_short}"); // Получаем пользователей отделения $users = $userId - ? User::where('id', $userId)->where('rf_department_id', $department->department_id)->get() + ? User::where('id', $userId)->whereHas('departments', function ($query) use ($department) { + $query->where('rf_department_id', $department->department_id); + })->get() : $this->getDepartmentUsers($department); if ($users->isEmpty()) { @@ -67,7 +69,8 @@ class FillReportsFromDate extends Command $user, $startDate, $endDate, - $force + $departmentId, + $force, ); $totalReports += $created; diff --git a/app/Http/Controllers/Web/StatisticController.php b/app/Http/Controllers/Web/StatisticController.php index 7c37153..4be8b4c 100644 --- a/app/Http/Controllers/Web/StatisticController.php +++ b/app/Http/Controllers/Web/StatisticController.php @@ -59,21 +59,23 @@ class StatisticController extends Controller if ($isRangeOneDay) { // Статистика выводится с нарастающим числом - $reports = $department->reports() - ->whereDate('created_at', $dateReport) + $query = $department->reports(); + $reports = $query->whereDate('created_at', $dateReport) ->get(); + $lastReport = $query->whereDate('created_at', $dateReport)->first(); } else { - $reports = $department->reports() - ->whereBetween('created_at', $dateReport)->get(); + $query = $department->reports(); + $reports = $query->clone()->whereBetween('created_at', $dateReport) + ->get(); + $lastReport = $query->clone()->whereDate('created_at', $dateReport[1])->first(); } + // Метрики зависищие от отчетов - $allCount = 0; $outcomeCount = 0; $currentCount = 0; $occupiedBeds = 0; $planCount = 0; + $allCount = 0; $outcomeCount = 0; $currentCount = 0; $planCount = 0; $emergencyCount = 0; $planSurgical = 0; $emergencySurgical = 0; $transferredCount = 0; $deceasedCount = 0; + $currentCount = $lastReport ? $this->getMetrikaResultFromReport($lastReport, 8, false) : 0; // Состоит foreach ($reports as $report) { - $allCount += $this->getMetrikaResultFromReport($report, 3, $isRangeOneDay); // Поступило - $currentCount += $this->getMetrikaResultFromReport($report, 8, false); // Состоит - $occupiedBeds += $this->getMetrikaResultFromReport($report, 8, $isRangeOneDay); // Состоит $planCount += $this->getMetrikaResultFromReport($report, 4, $isRangeOneDay); // Поступление - Планово $emergencyCount += $this->getMetrikaResultFromReport($report, 12, $isRangeOneDay); // Поступление - Экстренно $planSurgical += $this->getMetrikaResultFromReport($report, 11, $isRangeOneDay); // Операции - Планово @@ -83,11 +85,13 @@ class StatisticController extends Controller $deceasedCount += $this->getMetrikaResultFromReport($report, 9, $isRangeOneDay); // Умерло } + $allCount = $planCount + $emergencyCount; // Поступило + // Независимые метрики (установки по умолчанию и т.п.) $bedsCount = $department->metrikaDefault() ->where('rf_metrika_item_id', 1)->value('value'); - $percentLoadedBeds = $bedsCount > 0 ? round($occupiedBeds * 100 / $bedsCount) : 0; + $percentLoadedBeds = $bedsCount > 0 ? round($currentCount * 100 / $bedsCount) : 0; $groupedData[$departmentType][] = [ 'department' => $department->name_short, diff --git a/app/Models/LifeMisMigrationPatient.php b/app/Models/LifeMisMigrationPatient.php index 8c6f718..141f72b 100644 --- a/app/Models/LifeMisMigrationPatient.php +++ b/app/Models/LifeMisMigrationPatient.php @@ -38,9 +38,9 @@ class LifeMisMigrationPatient extends Model $query->where('rf_kl_VisitResultID', 0) ->where('rf_kl_StatCureResultID', 0) ->whereBetween('DateIngoing', [$dateRange->startSql(), $dateRange->endSql()]) - ->whereHas('medicalHistory', function ($query) use ($branchId, $dateRange) { - $query->whereDate('DateExtract', '1900-01-01'); - }) +// ->whereHas('medicalHistory', function ($query) use ($branchId, $dateRange) { +// $query->whereDate('DateExtract', '1900-01-01'); +// }) ->where('rf_MedicalHistoryID', '<>', 0); if ($branchId) { diff --git a/app/Models/User.php b/app/Models/User.php index 2bb88ca..bdc4504 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -59,6 +59,16 @@ class User extends Authenticatable return $this->belongsTo(Department::class, 'rf_department_id'); } + public function departments() + { + return $this->hasMany(UserDepartment::class, 'rf_user_id', 'id'); + } + + public function favoriteDepartment() + { + return $this->department()->where('is_favorited', true); + } + public function userRoles(): HasMany { return $this->hasMany(UserRole::class, 'rf_user_id', 'id'); diff --git a/app/Models/UserDepartment.php b/app/Models/UserDepartment.php new file mode 100644 index 0000000..78051fe --- /dev/null +++ b/app/Models/UserDepartment.php @@ -0,0 +1,26 @@ +belongsTo(User::class, 'rf_user_id'); + } + + public function department() + { + return $this->belongsTo(Department::class, 'rf_department_id'); + } +} diff --git a/app/Services/AutoReportService.php b/app/Services/AutoReportService.php index f27242d..4657550 100644 --- a/app/Services/AutoReportService.php +++ b/app/Services/AutoReportService.php @@ -3,6 +3,8 @@ namespace App\Services; use App\Models\Department; +use App\Models\MedicalHistorySnapshot; +use App\Models\MetrikaResult; use App\Models\MisStationarBranch; use App\Models\Report; use App\Models\User; @@ -26,6 +28,7 @@ class AutoReportService User $user, string $startDate, string $endDate, + $departmentId, bool $force = false ): int { $createdCount = 0; @@ -35,7 +38,7 @@ class AutoReportService foreach ($period as $date) { try { - $reportCreated = $this->createReportForDate($user, $date, $force); + $reportCreated = $this->createReportForDate($user, $date, $departmentId, $force); if ($reportCreated) { $createdCount++; @@ -52,10 +55,11 @@ class AutoReportService /** * Создать отчет для конкретной даты */ - public function createReportForDate(User $user, Carbon $date, bool $force = false): bool + public function createReportForDate(User $user, Carbon $date, $departmentId, bool $force = false): bool { + $user->rf_department_id = $departmentId; // Проверяем, существует ли уже отчет на эту дату - $existingReport = Report::where('rf_department_id', $user->rf_department_id) + $existingReport = Report::where('rf_department_id', $departmentId) ->whereDate('created_at', $date) ->whereDate('sent_at', $date) ->first(); @@ -66,6 +70,8 @@ class AutoReportService // Если есть существующий отчет и force=true - удаляем его if ($existingReport && $force) { + MetrikaResult::where('rf_report_id', $existingReport->report_id)->delete(); + MedicalHistorySnapshot::where('rf_report_id', $existingReport->report_id)->delete(); $existingReport->delete(); } @@ -77,7 +83,7 @@ class AutoReportService $dateRange = $this->dateRangeService->createDateRangeForDate($date, $user); // Получаем данные для отчета - $reportData = $this->prepareReportData($user, $dateRange, $date); + $reportData = $this->prepareReportData($user, $dateRange, $date, $departmentId); // Создаем отчет DB::transaction(function () use ($user, $reportData, $date) { @@ -90,9 +96,9 @@ class AutoReportService /** * Подготовить данные для отчета */ - private function prepareReportData(User $user, DateRange $dateRange, Carbon $date): array + private function prepareReportData(User $user, DateRange $dateRange, Carbon $date, $departmentId): array { - $department = $user->department; + $department = Department::where('department_id', $departmentId)->first(); $branchId = $this->getBranchId($department->rf_mis_department_id); $isHeadOrAdmin = $user->isHeadOfDepartment() || $user->isAdmin(); @@ -118,7 +124,7 @@ class AutoReportService 'sent_at' => $this->dateRangeService->toSqlFormat($date), 'created_at' => $this->dateRangeService->toSqlFormat($date), 'metrics' => $this->formatMetrics($metrics), - 'observationPatients' => $this->getObservationPatients($user->rf_department_id, $date), + 'observationPatients' => $this->getObservationPatients($departmentId, $date), 'unwantedEvents' => [], ]; } @@ -146,17 +152,6 @@ class AutoReportService true ); - Log::info($this->patientQueryService->getPlanOrEmergencyPatients( - 'plan', - $isHeadOrAdmin, - $branchId, - $dateRange, - false, - false, - true, - true - )); - // 2. Экстренные пациенты $metrics['emergency'] = $this->patientQueryService->getPlanOrEmergencyPatients( 'emergency', @@ -235,17 +230,17 @@ class AutoReportService private function formatMetrics(array $metrics): array { return [ - 'metrika_item_3' => $metrics['plan'] ?? 0, // плановые - 'metrika_item_4' => $metrics['emergency'] ?? 0, // экстренные - 'metrika_item_5' => $metrics['recipient'] ?? 0, // поступившие - 'metrika_item_6' => ($metrics['plan_surgery'] ?? 0) + ($metrics['emergency_surgery'] ?? 0), // всего операций + 'metrika_item_4' => $metrics['plan'] ?? 0, // плановые + 'metrika_item_12' => $metrics['emergency'] ?? 0, // экстренные + 'metrika_item_3' => $metrics['recipient'] ?? 0, // поступившие + // 'metrika_item_6' => ($metrics['plan_surgery'] ?? 0) + ($metrics['emergency_surgery'] ?? 0), // всего операций 'metrika_item_7' => $metrics['discharged'] ?? 0, // выписанные 'metrika_item_8' => $metrics['current'] ?? 0, // текущие 'metrika_item_9' => $metrics['deceased'] ?? 0, // умершие - 'metrika_item_10' => $metrics['plan_surgery'] ?? 0, // плановые операции - 'metrika_item_11' => $metrics['emergency_surgery'] ?? 0, // экстренные операции - 'metrika_item_12' => $metrics['transferred'] ?? 0, // переведенные - 'metrika_item_13' => 0, // под наблюдением (будет заполнено отдельно) + 'metrika_item_11' => $metrics['plan_surgery'] ?? 0, // плановые операции + 'metrika_item_10' => $metrics['emergency_surgery'] ?? 0, // экстренные операции + 'metrika_item_13' => $metrics['transferred'] ?? 0, // переведенные + 'metrika_item_14' => 0, // под наблюдением (будет заполнено отдельно) ]; } diff --git a/app/Services/PatientService.php b/app/Services/PatientService.php index 57e56ea..a6d6a2b 100644 --- a/app/Services/PatientService.php +++ b/app/Services/PatientService.php @@ -5,6 +5,7 @@ namespace App\Services; use App\Models\LifeMisMigrationPatient; use App\Models\MisMedicalHistory; use App\Models\MisMigrationPatient; +use App\Models\MisSurgicalOperation; use App\Models\ObservationPatient; use Carbon\Carbon; @@ -219,16 +220,14 @@ class PatientService DateRange $dateRange, bool $countOnly = false ) { - $query = MisMedicalHistory::whereHas('surgicalOperations', function ($q) use ($type, $branchId, $dateRange) { - $q->where('rf_StationarBranchID', $branchId) + $query = MisSurgicalOperation::where('rf_StationarBranchID', $branchId) ->whereBetween('Date', [$dateRange->startSql(), $dateRange->endSql()]); - if ($type === 'plan') { - $q->where('rf_TypeSurgOperationInTimeID', 6); - } else { - $q->whereIn('rf_TypeSurgOperationInTimeID', [4, 5]); - } - }); + if ($type === 'plan') { + $query->where('rf_TypeSurgOperationInTimeID', 6); + } else { + $query->whereIn('rf_TypeSurgOperationInTimeID', [4, 5]); + } if ($countOnly) { return $query->count(); diff --git a/database/migrations/2026_02_06_112905_create_user_departments_table.php b/database/migrations/2026_02_06_112905_create_user_departments_table.php new file mode 100644 index 0000000..b4efa3c --- /dev/null +++ b/database/migrations/2026_02_06_112905_create_user_departments_table.php @@ -0,0 +1,29 @@ +id('user_department_id'); + $table->foreignIdFor(\App\Models\User::class, 'rf_user_id'); + $table->foreignIdFor(\App\Models\Department::class, 'rf_department_id'); + $table->boolean('is_favorite')->default(false); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('user_departments'); + } +}; diff --git a/resources/js/Pages/Index.vue b/resources/js/Pages/Index.vue index 373d6f8..40c5fb1 100644 --- a/resources/js/Pages/Index.vue +++ b/resources/js/Pages/Index.vue @@ -52,7 +52,8 @@ const reportButtonType = computed(() => authStore.isDoctor ? 'button' : Link) @click="onShowSelectUserModal" :icon="TbArticle" /> -