Files
kartoteka/app/Services/ArchiveCardService.php
brusnitsyn c5c1a2b3e1 Новая логика поисковой выдачи
И добавлена кнопка Добавить карту в архив
2025-12-26 17:41:25 +09:00

141 lines
6.3 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\Services;
use App\Models\ArchiveInfo;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
class ArchiveCardService
{
public function get(?string $searchText,
?string $dateExtractFrom,
?string $dateExtractTo,
?int $status,
string $pageSize
) : LengthAwarePaginator
{
$query = ArchiveInfo::with(['misHistory', 'foxproHistory'])
->orderBy('post_in', 'desc');
// Поиск по тексту (если передан)
if (!empty($searchText)) {
$query->where(function ($q) use ($searchText) {
// Разбиваем строку поиска на части (по пробелам)
$searchParts = preg_split('/\s+/', trim($searchText));
$q->where(function ($subQuery) use ($searchParts, $searchText) {
// Сначала проверяем MIS историю
$subQuery->whereHas('misHistory', function ($misQuery) use ($searchParts, $searchText) {
$this->applySearchToHistory($misQuery, $searchParts, $searchText, 'mis');
});
// ИЛИ проверяем Foxpro историю (только если нет MIS истории)
$subQuery->orWhere(function ($orWhereSubQuery) use ($searchParts, $searchText) {
$orWhereSubQuery->whereNull('mis_history_id') // Нет MIS истории
->whereHas('foxproHistory', function ($foxproQuery) use ($searchParts, $searchText) {
$this->applySearchToHistory($foxproQuery, $searchParts, $searchText, 'foxpro');
});
});
})
// Ищем по архивным номерам
->orWhere('archive_num', 'ILIKE', "{$searchText}%")
->orWhere('mis_num', 'ILIKE', "{$searchText}%")
->orWhere('foxpro_num', 'ILIKE', "{$searchText}%");
});
}
// Фильтрация по дате выписки
if (!empty($dateExtractFrom)) {
$query->where(function ($q) use ($dateExtractFrom) {
$q->whereHas('misHistory', function ($misQuery) use ($dateExtractFrom) {
$misQuery->whereDate('DateExtract', '>=', $dateExtractFrom);
})->orWhereHas('foxproHistory', function ($foxproQuery) use ($dateExtractFrom) {
$foxproQuery->whereDate('menddate', '>=', $dateExtractFrom);
});
});
}
if (!empty($dateExtractTo)) {
$query->where(function ($q) use ($dateExtractTo) {
$q->whereHas('misHistory', function ($misQuery) use ($dateExtractTo) {
$misQuery->whereDate('DateExtract', '<=', $dateExtractTo);
})->orWhereHas('foxproHistory', function ($foxproQuery) use ($dateExtractTo) {
$foxproQuery->whereDate('menddate', '<=', $dateExtractTo);
});
});
}
// Фильтрация по статусу (если передан)
if (!empty($status)) {
$query->where('status_id', $status);
}
// Получаем результаты с пагинацией
$results = $query->paginate($pageSize)
->through(function ($archiveInfo) {
// Приоритет MIS истории
if ($archiveInfo->misHistory) {
$history = $archiveInfo->misHistory;
$history->history_type = 'mis';
} else {
$history = $archiveInfo->foxproHistory;
$history->history_type = 'foxpro';
}
return $history;
});
return $results;
}
private function applySearchToHistory($query, $searchParts, $searchText, $type)
{
if ($type === 'mis') {
$query->where('MedCardNum', 'ILIKE', "{$searchText}%");
// Ищем ФИО в зависимости от количества частей
if (count($searchParts) === 1) {
$query->orWhere('FAMILY', 'ILIKE', "{$searchParts[0]}%")
->orWhere('Name', 'ILIKE', "{$searchParts[0]}%")
->orWhere('OT', 'ILIKE', "{$searchParts[0]}%");
} elseif (count($searchParts) === 2) {
$query->orWhere(function ($subQuery) use ($searchParts) {
$subQuery->where('FAMILY', 'ILIKE', "{$searchParts[0]}%")
->where('Name', 'ILIKE', "{$searchParts[1]}%");
});
} elseif (count($searchParts) === 3) {
$query->orWhere(function ($subQuery) use ($searchParts) {
$subQuery->where('FAMILY', 'ILIKE', "{$searchParts[0]}%")
->where('Name', 'LIKE', "{$searchParts[1]}%")
->where('OT', 'ILIKE', "{$searchParts[2]}%");
});
}
$query->orWhereRaw("CONCAT(\"FAMILY\", ' ', \"Name\", ' ', \"OT\") ILIKE ?", ["{$searchText}%"]);
} else { // foxpro
$query->where('nkarta', 'ILIKE', "{$searchText}%");
if (count($searchParts) === 1) {
$query->orWhere('fam', 'ILIKE', "{$searchParts[0]}%")
->orWhere('im', 'ILIKE', "{$searchParts[0]}%")
->orWhere('ot', 'ILIKE', "{$searchParts[0]}%");
} elseif (count($searchParts) === 2) {
$query->orWhere(function ($subQuery) use ($searchParts) {
$subQuery->where('fam', 'ILIKE', "{$searchParts[0]}%")
->where('im', 'ILIKE', "{$searchParts[1]}%");
});
} elseif (count($searchParts) === 3) {
$query->orWhere(function ($subQuery) use ($searchParts) {
$subQuery->where('fam', 'ILIKE', "{$searchParts[0]}%")
->where('im', 'ILIKE', "{$searchParts[1]}%")
->where('ot', 'ILIKE', "{$searchParts[2]}%");
});
}
$query->orWhereRaw("CONCAT(fam, ' ', im, ' ', ot) ILIKE ?", ["{$searchText}%"]);
}
}
}