Добавлен сервис AI

Добавлен ai агент для формирования и проверки статистики
Добавлен ai агент для поддержки
This commit is contained in:
brusnitsyn
2026-07-20 16:58:21 +09:00
parent 6350159943
commit a9e032f658
21 changed files with 1546 additions and 4 deletions

View File

@@ -0,0 +1,98 @@
<?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'),
];
}
}