Files
onboard/app/Ai/Tools/GetDepartmentStatsTool.php
brusnitsyn a9e032f658 Добавлен сервис AI
Добавлен ai агент для формирования и проверки статистики
Добавлен ai агент для поддержки
2026-07-20 16:58:21 +09:00

99 lines
5.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Ai\Tools;
use App\Models\ReportDuty;
use Illuminate\Contracts\JsonSchema\JsonSchema;
use App\Services\DutyReportService;
use Laravel\Ai\Contracts\Tool;
use Laravel\Ai\Tools\Request;
use Stringable;
class GetDepartmentStatsTool implements Tool
{
public function __construct(
private readonly DutyReportService $reportService
) {}
/**
* Get the description of the tool's purpose.
*/
public function description(): Stringable|string
{
return 'Получить статистику по конкретному отделению за указанный период. ' .
'Возвращает: название отделения, количество коек, поступивших, выбывших, ' .
'средний койко-день, процент загруженности и т.д.' .
'Средний койко-день считается по формуле: total_bed_days / (patient_outcome + patients_in_department)';
}
/**
* Execute the tool.
*/
public function handle(Request $request): Stringable|string
{
// 1. Получаем параметры из запроса агента
$departmentName = $request['department_name'];
$startDate = $request['start_date'];
$endDate = $request['end_date'];
// 2. Здесь вы используете вашу существующую логику для получения отчета.
// Например, вы можете найти ID отделения по имени и вызвать ваш DutyReportService.
// Это упрощенный пример, вам нужно адаптировать его под вашу архитектуру.
// Пример: получаем последний отчет для этого отделения за период.
$report = ReportDuty::query()
->whereHas('department', function ($query) use ($departmentName) {
$query->where('name_full', 'ilike', "$departmentName%");
})
->where('period_start', '>=', $startDate)
->where('period_end', '<=', $endDate)
->latest()
->first();
if (!$report) {
return "Данные по отделению '{$departmentName}' за указанный период не найдены.";
}
// dd($report, $report->metrikaResult);
// 3. Возвращаем агенту структурированные данные (например, в JSON).
// Агент проанализирует эти цифры и даст ответ.
return json_encode([
'department' => $departmentName,
'beds' => $report->metrikaResult->where('rf_metrika_item_id', 1)->first()?->value ?? 0,
'patients_in_department' => $report->metrikaResult->where('rf_metrika_item_id', 8)->first()?->value ?? 0,
'patient_outcome' => $report->metrikaResult->where('rf_metrika_item_id', 7)->first()?->value ?? 0,
'avg_bed_day' => $report->metrikaResult->where('rf_metrika_item_id', 18)->first()?->value ?? 0,
'occupancy_percent' => $report->metrikaResult->where('rf_metrika_item_id', 22)->first()?->value ?? 0,
'patients_is_recipient' => $report->metrikaResult->where('rf_metrika_item_id', 3)->first()?->value ?? 0,
'patients_is_discharged' => $report->metrikaResult->where('rf_metrika_item_id', 15)->first()?->value ?? 0,
'patients_is_transferred' => $report->metrikaResult->where('rf_metrika_item_id', 13)->first()?->value ?? 0,
'patients_is_deceased' => $report->metrikaResult->where('rf_metrika_item_id', 9)->first()?->value ?? 0,
'planned_patients' => $report->metrikaResult->where('rf_metrika_item_id', 4)->first()?->value ?? 0,
'urgent_patients' => $report->metrikaResult->where('rf_metrika_item_id', 12)->first()?->value ?? 0,
'total_bed_days' => $report->metrikaResult->where('rf_metrika_item_id', 25)->first()?->value ?? 0,
'total_pre_op_days' => $report->metrikaResult->where('rf_metrika_item_id', 26)->first()?->value ?? 0,
'patients_with_ops' => $report->metrikaResult->where('rf_metrika_item_id', 27)->first()?->value ?? 0,
'avg_pre_op_bed_day' => $report->metrikaResult->where('rf_metrika_item_id', 21)->first()?->value ?? 0,
'mortality_percent' => $report->metrikaResult->where('rf_metrika_item_id', 19)->first()?->value ?? 0,
'planned_operations' => $report->metrikaResult->where('rf_metrika_item_id', 11)->first()?->value ?? 0,
'urgent_operations' => $report->metrikaResult->where('rf_metrika_item_id', 10)->first()?->value ?? 0,
'staff' => $report->metrikaResult->where('rf_metrika_item_id', 17)->first()?->value ?? 0,
// $this->saveMetric($reportDuty->id, 18, $avgBedDay); // Ср. койко-день
]);
}
/**
* Get the tool's schema definition.
*/
public function schema(JsonSchema $schema): array
{
return [
'department_name' => $schema->string()->required()->description('Название отделения, например: "Отоларингологическое"'),
'start_date' => $schema->string()->required()->description('Дата начала периода в формате YYYY-MM-DD HH:mm'),
'end_date' => $schema->string()->required()->description('Дата окончания периода в формате YYYY-MM-DD HH:mm'),
];
}
}