Разработка модуля базы знаний 1С-Битрикс
База знаний отличается от FAQ глубиной структуры: это иерархия разделов, полноценные статьи с форматированием, поиском и версионированием. FAQ — плоский список ответов на конкретные вопросы. База знаний — это документация, руководства, инструкции с перекрёстными ссылками. Строить её на инфоблоках можно, но раздел «История изменений», «Печатная версия», «Оценка полезности» и интеграция с поддержкой — это уже отдельная разработка.
Модель данных
Модуль vendor.knowledgebase:
-
b_vendor_kb_section— разделы: id, parent_id, name, slug, description, sort, icon, access_level (public/registered/group), is_active -
b_vendor_kb_article— статьи: id, section_id, title, slug, body (HTML/Markdown), excerpt, author_id, status (draft/review/published), views, helpful_count, not_helpful_count, created_at, updated_at, published_at -
b_vendor_kb_revision— версии статей: id, article_id, body, author_id, created_at, change_summary -
b_vendor_kb_attachment— файлы к статьям: id, article_id, file_id, name -
b_vendor_kb_tagиb_vendor_kb_article_tag— теги и связи
Версионирование статей
При каждом сохранении создаётся новая ревизия:
class ArticleService
{
public function update(int $articleId, array $fields, int $editorId, string $changeSummary = ''): void
{
$current = ArticleTable::getById($articleId)->fetch();
// Сохраняем предыдущую версию
RevisionTable::add([
'ARTICLE_ID' => $articleId,
'BODY' => $current['BODY'],
'AUTHOR_ID' => $editorId,
'CHANGE_SUMMARY' => $changeSummary ?: 'Обновление',
'CREATED_AT' => new DateTime(),
]);
// Обновляем основную запись
ArticleTable::update($articleId, array_merge($fields, [
'UPDATED_AT' => new DateTime(),
]));
}
public function rollback(int $articleId, int $revisionId): void
{
$revision = RevisionTable::getById($revisionId)->fetch();
$this->update($articleId, ['BODY' => $revision['BODY']], 0, 'Откат к ревизии #' . $revisionId);
}
}
История версий хранится бессрочно. Для экономии места старые ревизии можно архивировать агентом (оставлять N последних + ежемесячные снимки).
Иерархия разделов и навигация
Разделы строят дерево неограниченной вложенности (смежные списки, parent_id). Breadcrumbs и боковая навигация строятся рекурсивно по дереву. Для производительности дерево целиком кешируется с тегом kb_tree:
$tree = \Vendor\KB\TreeBuilder::getTree(); // из кеша или из БД
// При изменении любого раздела: Cache::invalidateTag('kb_tree')
Полнотекстовый поиск
Поиск по заголовкам и телу статей через PostgreSQL:
-- При публикации/обновлении статьи
UPDATE b_vendor_kb_article
SET fts_vector = to_tsvector('russian', title || ' ' || strip_tags(body))
WHERE id = :id;
-- Поисковый запрос
SELECT id, title, ts_headline('russian', body, q) AS excerpt
FROM b_vendor_kb_article, to_tsquery('russian', :query) q
WHERE fts_vector @@ q AND status = 'published'
ORDER BY ts_rank(fts_vector, q) DESC
LIMIT 20;
Результат выдаётся с автоматически сформированным excerpt с подсветкой совпадений (ts_headline).
Разграничение доступа
Раздел access_level:
-
public— доступно всем -
registered— только авторизованным пользователям -
group— только пользователям из указанной группы Битрикс (полеaccess_groupsв разделе)
Наследование: если раздел ограничен, все его дочерние разделы и статьи автоматически ограничены. Проверка при отображении — в middleware компонента.
Печатная версия и PDF
Компонент vendor:kb.article.print отдаёт страницу без навигации, оптимизированную для печати. Генерация PDF — через mPDF, ссылка «Скачать PDF» добавляется к каждой статье. PDF кешируется в файловой системе и сбрасывается при обновлении статьи.
Интеграция с тикет-системой
При просмотре статьи — блок «Не нашли ответ? Открыть тикет». Тикет создаётся в vendor.tickets (модуль тикет-системы) с предзаполненным полем «ссылка на статью KB». Это позволяет поддержке видеть контекст обращения.
Сроки разработки
| Этап | Срок |
|---|---|
| ORM-таблицы, иерархия разделов | 1 день |
| Версионирование статей, откат | 2 дня |
| Полнотекстовый поиск (PostgreSQL tsvector) | 2 дня |
| Разграничение доступа | 1 день |
| Печатная версия, PDF | 1 день |
| Компоненты сайта (список, статья, поиск) | 2 дня |
| Административный интерфейс | 2 дня |
| Тестирование | 1 день |
Итого: 12 рабочих дней. Интеграция с тикет-системой — +1 день.







