validate([ 'query' => 'required|string' ]); $searchText = $data['query']; $searchParts = preg_split('/\s+/', trim($searchText)); $query = SttMedicalHistory::query(); // Проверяем, начинается ли строка с цифры (вероятно, это номер карты) $isCardNumberSearch = is_numeric($searchParts[0]); if ($isCardNumberSearch) { // Паттерн: № Ф И О $query->where('MedCardNum', 'ILIKE', "$searchParts[0]%"); // ФИО начинается со второй части $fioStartIndex = 1; } else { // Паттерн: Ф И О (без номера) $fioStartIndex = 0; } // Ищем ФИО в зависимости от количества оставшихся частей $fioPartsCount = count($searchParts) - $fioStartIndex; if ($fioPartsCount === 1) { // Одно слово - ищем в фамилии, имени или отчестве $query->where(function ($q) use ($searchParts, $fioStartIndex) { $q->where('FAMILY', 'ILIKE', "{$searchParts[$fioStartIndex]}%") ->orWhere('Name', 'ILIKE', "{$searchParts[$fioStartIndex]}%") ->orWhere('OT', 'ILIKE', "{$searchParts[$fioStartIndex]}%"); }); } elseif ($fioPartsCount === 2) { // Два слова - фамилия и инициал имени $query->where(function ($q) use ($searchParts, $fioStartIndex) { $q->where('FAMILY', 'ILIKE', "{$searchParts[$fioStartIndex]}%") ->where('Name', 'ILIKE', "{$searchParts[$fioStartIndex + 1]}%"); }); } elseif ($fioPartsCount === 3) { // Три слова - полное ФИО $query->where(function ($q) use ($searchParts, $fioStartIndex) { $q->where('FAMILY', 'ILIKE', "{$searchParts[$fioStartIndex]}%") ->where('Name', 'ILIKE', "{$searchParts[$fioStartIndex + 1]}%") ->where('OT', 'ILIKE', "{$searchParts[$fioStartIndex + 2]}%"); }); } // Также ищем полную строку в объединенных полях $query->orWhereRaw("CONCAT(\"MedCardNum\", ' ', \"FAMILY\", ' ', \"Name\", ' ', \"OT\") ILIKE ?", ["{$searchText}%"]); $results = $query->select([ 'MedicalHistoryID', 'MedCardNum', 'FAMILY', 'Name', 'OT' ])->get()->map(function ($item) { return [ 'label' => "$item->MedCardNum - $item->FAMILY $item->Name $item->OT", 'value' => $item->MedicalHistoryID ]; }); return response()->json($results); } }