Для начала необходимо узнать ID чата, обычно это 1:
|
1 |
SELECT ID, TITLE, ENTITY_TYPE FROM b_im_chat WHERE ENTITY_TYPE = 'GENERAL'; |
Проверяем какие именно сообщения попадают под выборку:
|
1 2 3 |
SELECT * FROM b_im_message WHERE CHAT_ID = 1 AND MESSAGE = 'Я с вами в команде!' |
Для удаление эту команду:
|
1 2 3 |
DELETE FROM b_im_message WHERE CHAT_ID = 1 AND MESSAGE = 'Я с вами в команде!' |
Исправление счетчиков (Обязательно)
После удаления конкретных строк в БД могут «сломаться» уведомления или отображение последнего сообщения. Чтобы Битрикс24 пересчитал актуальное состояние чата, выполните:
|
1 2 3 |
UPDATE b_im_chat SET LAST_MESSAGE_ID = (SELECT MAX(ID) FROM b_im_message WHERE CHAT_ID = 1) WHERE ID = 1; |
Далее создаем фай со следующим содержимым, например по пути http://your-site.ru/local/tools/fix_general_chat.php и открываем его в браузере.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
<?php /** * Починка общего чата после прямого удаления сообщений через SQL. * Пересчитывает все счётчики и ссылки на сообщения. * * Запуск: http://your-site.ru/local/tools/fix_general_chat.php * После выполнения — удалить файл. */ define('NOT_CHECK_PERMISSIONS', true); define('NO_AGENT_CHECK', true); require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php'; use Bitrix\Main\Loader; use Bitrix\Main\Application; if (!Loader::includeModule('im')) { die('Module "im" not found'); } $connection = Application::getConnection(); echo "<pre>\n"; echo "=== Починка общего чата ===\n\n"; // 1. Находим общий чат $chat = $connection->query("SELECT ID, LAST_MESSAGE_ID, PREV_MESSAGE_ID, MESSAGE_COUNT FROM b_im_chat WHERE ENTITY_TYPE = 'GENERAL' LIMIT 1")->fetch(); if (!$chat) { die("Общий чат (ENTITY_TYPE=GENERAL) не найден\n"); } $chatId = (int)$chat['ID']; echo "Чат ID: {$chatId}\n"; echo "Текущий LAST_MESSAGE_ID: {$chat['LAST_MESSAGE_ID']}\n"; echo "Текущий PREV_MESSAGE_ID: {$chat['PREV_MESSAGE_ID']}\n"; echo "Текущий MESSAGE_COUNT: {$chat['MESSAGE_COUNT']}\n\n"; // 2. Вычисляем реальные значения $realCount = $connection->query("SELECT COUNT(*) as CNT FROM b_im_message WHERE CHAT_ID = {$chatId}")->fetch(); $realLast = $connection->query("SELECT MAX(ID) as MAX_ID FROM b_im_message WHERE CHAT_ID = {$chatId}")->fetch(); $newLastId = (int)$realLast['MAX_ID']; $realPrev = $connection->query("SELECT MAX(ID) as PREV_ID FROM b_im_message WHERE CHAT_ID = {$chatId} AND ID < {$newLastId}")->fetch(); $newCount = (int)$realCount['CNT']; $newPrevId = (int)$realPrev['PREV_ID']; $minMsg = $connection->query("SELECT MIN(ID) as MIN_ID FROM b_im_message WHERE CHAT_ID = {$chatId}")->fetch(); $minMsgId = (int)$minMsg['MIN_ID']; echo "Реальный MESSAGE_COUNT: {$newCount}\n"; echo "Реальный LAST_MESSAGE_ID: {$newLastId}\n"; echo "Реальный PREV_MESSAGE_ID: {$newPrevId}\n"; echo "Мин. MESSAGE_ID: {$minMsgId}\n\n"; // 3. Обновляем b_im_chat $connection->queryExecute(" UPDATE b_im_chat SET LAST_MESSAGE_ID = {$newLastId}, PREV_MESSAGE_ID = {$newPrevId}, MESSAGE_COUNT = {$newCount} WHERE ID = {$chatId} "); echo "[OK] b_im_chat обновлён\n"; // 4. Чиним b_im_relation — ссылки на удалённые сообщения $connection->queryExecute(" UPDATE b_im_relation r SET r.LAST_ID = {$newLastId} WHERE r.CHAT_ID = {$chatId} AND r.LAST_ID > 0 AND r.LAST_ID NOT IN (SELECT m.ID FROM b_im_message m WHERE m.CHAT_ID = {$chatId}) "); echo "[OK] b_im_relation.LAST_ID исправлен\n"; $connection->queryExecute(" UPDATE b_im_relation r SET r.LAST_SEND_ID = {$newLastId} WHERE r.CHAT_ID = {$chatId} AND r.LAST_SEND_ID > 0 AND r.LAST_SEND_ID NOT IN (SELECT m.ID FROM b_im_message m WHERE m.CHAT_ID = {$chatId}) "); echo "[OK] b_im_relation.LAST_SEND_ID исправлен\n"; $connection->queryExecute(" UPDATE b_im_relation r SET r.UNREAD_ID = 0 WHERE r.CHAT_ID = {$chatId} AND r.UNREAD_ID > 0 AND r.UNREAD_ID NOT IN (SELECT m.ID FROM b_im_message m WHERE m.CHAT_ID = {$chatId}) "); echo "[OK] b_im_relation.UNREAD_ID исправлен\n"; $connection->queryExecute(" UPDATE b_im_relation r SET r.LAST_SEND_MESSAGE_ID = {$newLastId} WHERE r.CHAT_ID = {$chatId} AND r.LAST_SEND_MESSAGE_ID > 0 AND r.LAST_SEND_MESSAGE_ID NOT IN (SELECT m.ID FROM b_im_message m WHERE m.CHAT_ID = {$chatId}) "); echo "[OK] b_im_relation.LAST_SEND_MESSAGE_ID исправлен\n"; $connection->queryExecute(" UPDATE b_im_relation r SET r.START_ID = {$minMsgId} WHERE r.CHAT_ID = {$chatId} AND r.START_ID > 0 AND r.START_ID NOT IN (SELECT m.ID FROM b_im_message m WHERE m.CHAT_ID = {$chatId}) "); echo "[OK] b_im_relation.START_ID исправлен\n"; // Пересчёт COUNTER $connection->queryExecute(" UPDATE b_im_relation SET COUNTER = 0 WHERE CHAT_ID = {$chatId} "); echo "[OK] b_im_relation.COUNTER сброшен\n"; // 5. Чиним b_im_recent $connection->queryExecute(" UPDATE b_im_recent SET ITEM_MID = {$newLastId} WHERE ITEM_CID = {$chatId} AND ITEM_MID NOT IN (SELECT m.ID FROM b_im_message m WHERE m.CHAT_ID = {$chatId}) "); echo "[OK] b_im_recent.ITEM_MID исправлен\n"; $connection->queryExecute(" UPDATE b_im_recent SET MARKED_ID = 0 WHERE ITEM_CID = {$chatId} AND MARKED_ID > 0 AND MARKED_ID NOT IN (SELECT m.ID FROM b_im_message m WHERE m.CHAT_ID = {$chatId}) "); echo "[OK] b_im_recent.MARKED_ID исправлен\n"; // 6. Удаляем осиротевшие параметры сообщений $connection->queryExecute(" DELETE mp FROM b_im_message_param mp LEFT JOIN b_im_message m ON m.ID = mp.MESSAGE_ID WHERE m.ID IS NULL "); echo "[OK] b_im_message_param: осиротевшие записи удалены\n"; // 7. Чистим кеш $managedCache = Application::getInstance()->getManagedCache(); $managedCache->cleanAll(); $taggedCache = Application::getInstance()->getTaggedCache(); $taggedCache->clearByTag('im_chat_' . $chatId); if (is_dir($_SERVER['DOCUMENT_ROOT'] . '/bitrix/cache/im/')) { DeleteDirFilesEx('/bitrix/cache/im/'); } echo "[OK] Кеш очищен\n"; echo "\n=== Готово! Перезагрузите страницу чата (Ctrl+F5) ===\n"; echo "</pre>\n"; |
После выполнения запросов обязательно очистите весь кеш в административной панели, иначе пользователи будут видеть эти сообщения в своих приложениях еще долго.
