Разработка модуля отзывов и рейтингов 1С-Битрикс
В Битрикс есть компонент bitrix:catalog.element.vote для голосования и bitrix:forum с привязкой к элементам — это то, из чего обычно собирают отзывы. Результат ожидаемый: форум без модерации, рейтинг без верификации покупки, отсутствие структурированных данных для Schema.org. Полноценный модуль отзывов — это другая история: верифицированные отзывы, многокритериальный рейтинг, модерация, ответы продавца, агрегированные звёзды в микроразметке.
Модель данных
Модуль vendor.reviews:
-
b_vendor_review— отзывы: id, entity_type (product/service/company), entity_id, user_id, author_name, author_email, order_id, title, body, pros, cons, rating (1-5), status (pending/approved/rejected/spam), is_verified_purchase, created_at, updated_at -
b_vendor_review_criteria— критерии оценки: id, entity_type, name, sort -
b_vendor_review_rating— оценки по критериям: id, review_id, criteria_id, value -
b_vendor_review_vote— голоса «полезный/бесполезный»: id, review_id, user_id, ip, value (1/-1), created_at -
b_vendor_review_reply— ответы администратора: id, review_id, author_id, body, created_at
Верификация покупки
Самое ценное в отзыве — пометка «проверенный покупатель». Проверяем по b_sale_order:
public function isVerifiedPurchase(int $userId, int $productId): bool
{
// Ищем оплаченный заказ этого пользователя с данным товаром
$order = \Bitrix\Sale\Internals\BasketTable::getList([
'select' => ['ORDER_ID'],
'filter' => [
'=PRODUCT_ID' => $productId,
'=ORDER.USER_ID' => $userId,
'=ORDER.PAYED' => 'Y',
'=ORDER.CANCELED' => 'N',
],
'limit' => 1,
])->fetch();
return (bool)$order;
}
При создании отзыва order_id можно передать явно — тогда проверка однозначная. Без order_id — проверяем по любому оплаченному заказу с этим товаром.
Модерация
Все отзывы создаются со статусом pending и попадают в очередь модерации. Возможны два режима:
- Ручная модерация — модератор одобряет/отклоняет каждый отзыв
- Автоодобрение — отзывы верифицированных покупателей публикуются автоматически, остальные — в очередь
Фильтр спама работает через простые эвристики: ссылки в теле отзыва, порог заглавных букв, дублирующиеся тексты, стоп-слова. Подозрительные отзывы получают статус spam.
class SpamDetector
{
public function check(string $text): SpamResult
{
if (preg_match('/https?:\/\//i', $text)) return SpamResult::spam('Ссылки запрещены');
if (similar_text($text, $this->getLastReview($text)) > 80) return SpamResult::spam('Дубликат');
foreach ($this->stopWords as $word) {
if (mb_stripos($text, $word) !== false) return SpamResult::suspicious();
}
return SpamResult::clean();
}
}
Многокритериальный рейтинг
Для товаров можно задать несколько критериев оценки (например: «Качество», «Соответствие описанию», «Скорость доставки»). Итоговый рейтинг — среднее по всем критериям:
SELECT
entity_id,
AVG(rr.value) AS avg_rating,
COUNT(DISTINCT r.id) AS review_count
FROM b_vendor_review r
JOIN b_vendor_review_rating rr ON rr.review_id = r.id
WHERE r.entity_type = 'product'
AND r.status = 'approved'
GROUP BY entity_id;
Агрегированные данные кешируются тегом review_entity_{entity_id} и сбрасываются при одобрении нового отзыва.
Schema.org микроразметка
Для SEO-эффекта важно вывести агрегированный рейтинг в микроразметке:
<div itemscope itemtype="https://schema.org/Product">
<span itemprop="name">Название товара</span>
<div itemprop="aggregateRating" itemscope itemtype="https://schema.org/AggregateRating">
<span itemprop="ratingValue">4.7</span>
<span itemprop="reviewCount">143</span>
</div>
</div>
Компонент vendor:reviews.aggregate генерирует этот блок на основе данных из кеша.
Голосование за полезность
Пользователи могут отметить отзыв как «полезный» или «бесполезный». Механизм защиты от накрутки:
- Один голос с одного IP в сутки
- Авторизованные пользователи — один голос на отзыв навсегда
- Рейтинг полезности влияет на порядок отображения отзывов
Сроки разработки
| Этап | Срок |
|---|---|
| ORM-таблицы, модель отзывов | 1 день |
| Верификация покупки, интеграция с sale | 1 день |
| Модерация, спам-фильтр | 2 дня |
| Многокритериальный рейтинг, агрегация | 1 день |
| Schema.org микроразметка | 0.5 дня |
| Голосование за полезность | 0.5 дня |
| Ответы продавца, уведомления | 1 день |
| Компоненты для сайта | 2 дня |
| Административный интерфейс + очередь модерации | 1 день |
| Тестирование | 1 день |
Итого: 11 рабочих дней. Импорт отзывов из Яндекс.Маркета или других площадок — дополнительно 1–2 дня.







