* переписал функции прототипов в сервисы

* оптимизация доставки контента до клиента
* переписал запросы выборок
* убрал из подсчета переведенных
* добавил сохранение метрикам для вывода в дашборд
This commit is contained in:
brusnitsyn
2026-02-04 17:05:13 +09:00
parent 9ee33bc517
commit eab78a0291
16 changed files with 1644 additions and 737 deletions

View File

@@ -0,0 +1,198 @@
<?php
namespace App\Services;
use App\Models\MedicalHistorySnapshot;
use App\Models\MisMedicalHistory;
use App\Models\MisStationarBranch;
use App\Models\Report;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Support\Collection;
class SnapshotService
{
public function __construct(
protected PatientService $patientService
) {}
/**
* Создать снапшоты пациентов для отчета
*/
public function createPatientSnapshots(Report $report, User $user, array $dates): void
{
$branchId = $this->getBranchId($user->department->rf_mis_department_id);
[$startDate, $endDate] = $this->parseDates($dates);
// Плановые пациенты
$this->createSnapshotsForType(
$report,
'plan',
$this->patientService->getPlanOrEmergencyPatients(
'plan',
$user->isHeadOfDepartment() || $user->isAdmin(),
$branchId,
$startDate,
$endDate,
false,
true
)
);
// Экстренные пациенты
$this->createSnapshotsForType(
$report,
'emergency',
$this->patientService->getPlanOrEmergencyPatients(
'emergency',
$user->isHeadOfDepartment() || $user->isAdmin(),
$branchId,
$startDate,
$endDate,
false,
true
)
);
// Выписанные
$this->createSnapshotsForType(
$report,
'discharged',
$this->patientService->getOutcomePatients(
$branchId,
$startDate,
$endDate,
'discharged'
)->pluck('MedicalHistoryID')->toArray()
);
// Переведенные
$this->createSnapshotsForType(
$report,
'transferred',
$this->patientService->getOutcomePatients(
$branchId,
$startDate,
$endDate,
'transferred'
)->pluck('MedicalHistoryID')->toArray()
);
// Умершие
$this->createSnapshotsForType(
$report,
'deceased',
$this->patientService->getOutcomePatients(
$branchId,
$startDate,
$endDate,
'deceased'
)->pluck('MedicalHistoryID')->toArray()
);
// Поступившие
$recipientIds = $this->patientService->getPlanOrEmergencyPatients(
null,
$user->isHeadOfDepartment() || $user->isAdmin(),
$branchId,
$startDate,
$endDate,
false,
true
);
$this->createSnapshotsForType($report, 'recipient', $recipientIds);
}
/**
* Получить статистику из снапшотов
*/
public function getStatisticsFromSnapshots(array $reportIds): array
{
return [
'plan' => $this->getCountFromSnapshots('plan', $reportIds),
'emergency' => $this->getCountFromSnapshots('emergency', $reportIds),
'outcome' => $this->getCountFromSnapshots('outcome', $reportIds),
'deceased' => $this->getCountFromSnapshots('deceased', $reportIds),
'discharged' => $this->getCountFromSnapshots('discharged', $reportIds),
'transferred' => $this->getCountFromSnapshots('transferred', $reportIds),
'recipient' => $this->getCountFromSnapshots('recipient', $reportIds),
];
}
/**
* Получить пациентов из снапшотов по типу
*/
public function getPatientsFromSnapshots(
string $type,
array $reportIds,
?int $branchId = null
): Collection {
$medicalHistoryIds = MedicalHistorySnapshot::whereIn('rf_report_id', $reportIds)
->where('patient_type', $type)
->pluck('rf_medicalhistory_id')
->unique()
->toArray();
if (empty($medicalHistoryIds)) {
return collect();
}
return MisMedicalHistory::whereIn('MedicalHistoryID', $medicalHistoryIds)
->when($type === 'plan', fn($q) => $q->plan())
->when($type === 'emergency', fn($q) => $q->emergency())
->orderBy('DateRecipient', 'DESC')
->get();
}
/**
* Получить количество пациентов из снапшотов
*/
private function getCountFromSnapshots(string $type, array $reportIds): int
{
$query = MedicalHistorySnapshot::whereIn('rf_report_id', $reportIds);
if ($type === 'outcome') {
$query->whereIn('patient_type', ['discharged', 'deceased']);
} else {
$query->where('patient_type', $type);
}
return $query->distinct('rf_medicalhistory_id')
->count('rf_medicalhistory_id');
}
/**
* Создать снапшоты для определенного типа пациентов
*/
private function createSnapshotsForType(Report $report, string $type, array $medicalHistoryIds): void
{
foreach ($medicalHistoryIds as $id) {
MedicalHistorySnapshot::create([
'rf_report_id' => $report->report_id,
'rf_medicalhistory_id' => $id,
'patient_type' => $type,
]);
}
}
/**
* Получить ID отделения
*/
private function getBranchId(int $misDepartmentId): ?int
{
return MisStationarBranch::where('rf_DepartmentID', $misDepartmentId)
->value('StationarBranchID');
}
/**
* Разобрать даты
*/
private function parseDates(array $dates): array
{
return [
Carbon::createFromTimestampMs($dates[0])->setTimezone('Asia/Yakutsk'),
Carbon::createFromTimestampMs($dates[1])->setTimezone('Asia/Yakutsk'),
];
}
}