Добавил базовые датасеты и агрегации для конструктора отчетов

This commit is contained in:
brusnitsyn
2026-06-22 17:00:58 +09:00
parent 71bd4b9d1a
commit 5bad7599cf
16 changed files with 1453 additions and 0 deletions

View File

@@ -0,0 +1,146 @@
<?php
namespace App\Services\Analytics\DataSets;
use App\Services\Analytics\AnalyticsQuery;
use App\Services\Analytics\AnalyticsResult;
use App\Services\Analytics\Column;
use App\Services\Analytics\Contracts\DataSet;
use App\Services\StatisticsService;
/**
* Фиксированный отчёт «Статистика по отделениям» переиспользует StatisticsService,
* поэтому цифры 1:1 совпадают со страницей /statistic (профили, под-итоги «ИТОГО»).
* Колонки заданы жёстко, выбор группировок/показателей не требуется.
*/
class DepartmentStatisticsDataSet implements DataSet
{
public function key(): string
{
return 'department_statistics';
}
public function label(): string
{
return 'Статистика по отделениям';
}
public function description(): string
{
return 'Сводная статистика по всем отделениям';
}
public function category(): string
{
return 'Сводные';
}
public function fixed(): bool
{
return true;
}
public function dimensions(): array
{
return [];
}
public function measures(): array
{
return [];
}
public function filters(): array
{
return [];
}
/** @return Column[] */
private function columns(): array
{
return [
new Column('department', 'Отделение', 'dimension', 'string'),
new Column('beds', 'Кол-во коек', 'measure', 'number', 'count'),
new Column('rec_all', 'Поступило: всего', 'measure', 'number', 'count'),
new Column('rec_plan', 'Поступило: план', 'measure', 'number', 'count'),
new Column('rec_emergency', 'Поступило: экстр', 'measure', 'number', 'count'),
new Column('rec_transferred', 'Поступило: перевод', 'measure', 'number', 'count'),
new Column('outcome', 'Выбыло', 'measure', 'number', 'count'),
new Column('consist', 'Состоит', 'measure', 'number', 'count'),
new Column('avg_bed_days', 'Ср. койко-день', 'measure', 'number', null),
new Column('preoperative_days', 'Пред. опер. койко-день', 'measure', 'number', null),
new Column('percent_loaded', '% загруженности', 'measure', 'number', 'percent'),
new Column('lethality', '% смертности', 'measure', 'number', 'percent'),
new Column('surgery_emergency', 'Операции Э', 'measure', 'number', 'count'),
new Column('surgery_plan', 'Операции П', 'measure', 'number', 'count'),
new Column('deceased', 'Умерло', 'measure', 'number', 'count'),
new Column('staff', 'Мед. персонал', 'measure', 'number', 'count'),
];
}
public function run(AnalyticsQuery $query): AnalyticsResult
{
$columns = $this->columns();
if ($query->user === null) {
return new AnalyticsResult($columns, []);
}
$payload = app(StatisticsService::class)->getStatisticsData(
$query->user,
$query->dateRange->startSql(),
$query->dateRange->endSql(),
$query->dateRange->isOneDay,
);
$rows = [];
foreach ($payload['data'] ?? [] as $item) {
$rows[] = ! empty($item['isGroupHeader'])
? $this->groupHeaderRow($columns, $item['groupName'] ?? '')
: $this->dataRow($item);
}
return new AnalyticsResult($columns, $rows);
}
/**
* @param Column[] $columns
* @return array<string,mixed>
*/
private function groupHeaderRow(array $columns, string $name): array
{
$row = [];
foreach ($columns as $column) {
$row[$column->key] = '';
}
$row['department'] = $name;
return $row;
}
/**
* @param array<string,mixed> $item
* @return array<string,mixed>
*/
private function dataRow(array $item): array
{
return [
'department' => $item['department'] ?? '',
'beds' => $item['beds'] ?? 0,
'rec_all' => $item['recipients']['all'] ?? 0,
'rec_plan' => $item['recipients']['plan'] ?? 0,
'rec_emergency' => $item['recipients']['emergency'] ?? 0,
'rec_transferred' => $item['recipients']['transferred'] ?? 0,
'outcome' => $item['outcome'] ?? 0,
'consist' => $item['consist'] ?? 0,
'avg_bed_days' => $item['averageBedDays'] ?? 0,
'preoperative_days' => $item['preoperativeDays'] ?? 0,
'percent_loaded' => $item['percentLoadedBeds'] ?? 0,
'lethality' => $item['lethality'] ?? 0,
'surgery_emergency' => $item['surgical']['emergency'] ?? 0,
'surgery_plan' => $item['surgical']['plan'] ?? 0,
'deceased' => $item['deceased'] ?? 0,
'staff' => $item['countStaff'] ?? 0,
];
}
}