×

Битрикс: не работает поиск по обращениям в модуле техподдержки

Если ваш сайт работает на какой-нибудь из редакций 1С-Битрикс: Управление сайтом и вы активно используете модуль Техподдержка, то наверняка сталкивались со следующей проблемой:

Сотрудники техподдержки не могут найти старые обращения

Воспроизвести это довольно легко. Открываем старое обращение от клиента и пробуем найти все похожие обращения по каким-нибудь более-менее уникальным данным (например по ИНН).

Искать будем в административном интерфейсе указав текст в поле Заголовок и Текст сообщения. Если вы пользуетесь модулем техподдержки достаточно давно и накопили большое количество обращений, то велика вероятность, что поиск завершится неудачей.

поиск обращений в модуле техподдержки битрикса

Вот об этом поле идёт речь

Вы либо найдёте не все обращения, либо ответ вообще будет пустым. То есть даже исходное обращение, из которого мы только что скопировали информацию, не будет найдено.

В тоже время, если поискать вручную по таблице b_ticket_message, то обращения найдутся, но процесс поиска будет не быстрым. Очевидно, что проблема заключается в том, как и где ищутся обращения в административном интерфейсе.

Первое решение: через штатный функционал

Если изучить код модуля, то несложно выяснить, что начиная с версии 12 поиск по тексту сообщений в обращениях производится с использованием индекса в модуле поиска.

Чтобы наполнить этот индекс существует специальная форма Переиндексация обращений в настройках модуля Техподдержка.

переиндексация тикетов в модуле техподдержки битрикс

Тут можно задать только величину таймаута для шага

Но если у вас больше миллиона обращений, то переиндексация не завершится никогда, потому что сессия оборвётся раньше. И начать её с предыдущего места не получится.

Второе решение: периодический агент ленивой переиндексации

Фактически, мы уже знаем как решить проблему, но не можем из-за того, что это решение занимает очень много времени и требует внимания.

В этой ситуации нам поможет периодический агент, работающий на стороне сервера. С его помощью мы можем разбить задачу на несколько небольших подзадач, каждая из которых уложится в ограничения на время исполнения скриптов.

Идея простая: находим код, который отвечает за переиндексирование в административной части и запускаем его в агенте, запоминая то место, на котором он остановился. Нужная нам функция называется CSupportSearch:: reindexAllTickets и принимает два аргумента: с какого тикета продолжить индексацию и сколько времени она может занять. Возвращается при этом последний обработанный тикет.

Код решения

Зарегистрируйте в системе агент с вот таким кодом:


/**
 * Агент переиндексации тикетов
 * @param int $ticketId id начального тикета для переобхода
 * @return string | bool
 */
public static function reindexAgent(int $ticketId = 0){
	//мы используем код из админки, поэтому нужно подключать эти файлы
	require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_admin_before.php");
	require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/support/classes/general/search.php");
	
	//шаг - 55 секунд, чтобы не попасть на блокировку по времени исполнения
	$lastTicketId = (New CSupportSearch())->reindexAllTickets($ticketId, 55);
	
	//если тикеты закончились, то функция возвращает -1
	//это значит, что нам больше не нужны дочерние агенты и можно завершить скрипт
	if($lastTicketId <= 0){
		return false;
	}
	
	//регистрируем временный агент для распараллеливания задачи
	//он вызовет эту же функцию, но с другим id тикета
	CAgent::AddAgent(
		"CITicket::reindexAgent({$lastTicketId});",
		'ci.cimodule',
		'N',
		70 //выполнится через 70 секунд
	);
	
	//первый запуск c id=0 всегда возвращает корректное текстовое значение
	if($ticketId === 0){
		return "CITicket::reindexAgent();";
		
	//если не передадим корректное значение - агент выполнится лишь один раз и удалится
	//таким нехитрым способом мы избавимся от следов временных агентов
	}else{
		return false;
	}
}

Тут стоит пояснить, что только первый запуск с нулевым id тикета вернёт корректную строку для дальнейшего перезапуска агента. Все остальные генерируемые скриптом временные задания будут возвращать false и удаляться из расписания. Таким образом, после обработки всех тикетов, в списке агентов останется только один исходный агент, а временные удалятся.

На нашем сайте переиндексация заняла 4 дня, поэтому я не рекомендую запускать этот агент чаще, чем раз в месяц.

Итог

В итоге получаем костыль для ленивого переобхода тикетов штатными средствами не требующий внимания с нашей стороны. А сотрудники техподдержки теперь смогут найти всё, что им потребуется.

logo