'localhost', 'db_port' => '3306', 'db_username' => 'ci20465_72new', 'db_password' => 'EcY979Rn', 'db_name' => 'ci20465_72new', 'db_type' => 'mysqli' ]; $conn = new mysqli( $dbconfig['db_server'], $dbconfig['db_username'], $dbconfig['db_password'], $dbconfig['db_name'], $dbconfig['db_port'] ); if ($conn->connect_error) { logMessage("Ошибка подключения к БД: " . $conn->connect_error); die(json_encode(["status" => "error", "message" => "Ошибка подключения к БД."])); } // Устанавливаем кодировку UTF-8 $conn->set_charset("utf8mb4"); // ✅ Получаем `$id` из POST-запроса $id = $_POST['id'] ?? null; if (!$id || !is_numeric($id)) { logMessage("Ошибка: Некорректный ID."); die(json_encode(["status" => "error", "message" => "Некорректный ID."])); } logMessage("Получен ID: $id"); // 🔹 SQL-запрос для получения файлов $sql = " SELECT n.title, CASE WHEN a.storedname IS NOT NULL THEN CONCAT(a.path, a.attachmentsid, '_', a.storedname) ELSE CONCAT(a.path, a.attachmentsid, '_', a.name) END AS filepath FROM vtiger_senotesrel r LEFT JOIN vtiger_notes n ON n.notesid = r.notesid LEFT JOIN vtiger_crmentity e ON e.crmid = r.notesid LEFT JOIN vtiger_seattachmentsrel r2 ON r2.crmid = r.notesid LEFT JOIN vtiger_attachments a ON a.attachmentsid = r2.attachmentsid WHERE r.crmid = ? AND e.deleted = 0 AND (a.type = 'application/pdf' OR a.type = 'application/octet-stream') "; $stmt = $conn->prepare($sql); $stmt->bind_param("i", $id); $stmt->execute(); $result = $stmt->get_result(); if ($result->num_rows == 0) { logMessage("Ошибка: Данные не найдены в БД."); die(json_encode(["status" => "error", "message" => "Нет данных."])); } // 🔹 Функция временного переименования файла function renameFileForProcessing($filePath) { $pathInfo = pathinfo($filePath); $newName = "file_" . uniqid() . "." . $pathInfo['extension']; $newPath = $pathInfo['dirname'] . "/" . $newName; if (rename($filePath, $newPath)) { logMessage("Файл переименован: $filePath -> $newPath"); return $newPath; } else { logMessage("Ошибка при переименовании файла: $filePath"); return $filePath; } } // 🔹 Функция восстановления оригинального имени файла function restoreOriginalFileName($originalPath, $tempPath) { if (rename($tempPath, $originalPath)) { logMessage("Файл восстановлен: $tempPath -> $originalPath"); } else { logMessage("Ошибка при восстановлении имени файла: $tempPath"); } } // 🔹 Функция анализа текста через GPT-4-Turbo function analyzeDocumentsWithGPT($documents) { logMessage("Отправка запроса в GPT-4-Turbo..."); $task = "🔹 Отвечай по шаблону. **Задача**: Проанализируй загруженные документы, выполнив следующие действия: 1️⃣ **Список файлов и проверка соответствия названий** - Перечисли все загруженные файлы. - Определи их содержимое (например, \"договор\", \"претензия\", \"ответ на претензию\", \"подтверждение оплаты\" и т. д.). - Проверь, соответствует ли название файла его реальному содержимому. - Если обнаружено несоответствие, укажи, в чем именно проблема. 2️⃣ **Краткий анализ спора** - Определи **истца** (потребителя) и **ответчика** (компанию, на которую подана жалоба). - Опиши **суть спора** (что произошло и какая проблема заявлена). - Укажи **основные аргументы сторон** (что заявляет потребитель и какие возражения возможны у компании). 3️⃣ **Проверка на цензуру** - Проверь документы на наличие **ненормативной лексики** и **нецензурных изображений**. - Если обнаружены изображения, укажи, требуется ли их ручная проверка. 4️⃣ **Выдача итогового вердикта** - **Прошло модерацию** – если всё соответствует названию и нет проблем. - **Не прошло модерацию (требуется участие человека)** – если есть несоответствия или потенциальные проблемы (укажи, что именно требует ручной проверки). 5️⃣ **Характер спора** - Дай краткую характеристику дела (например, \"некачественный товар\", \"товар не привезли\", \"не возвращают деньги\", \"некачественная услуга\" и т. д.). 📌 **Важно**: Отчет должен быть структурированным, четким и лаконичным. Укажи, какими нормами права РФ будет регулироваться рассмотение данного спора. Если требуется ручная проверка, укажи приоритетные файлы для проверки."; /* $task = "🔹 **Анализ загруженных документов**:\n" . "1️⃣ Перечисли все загруженные файлы и проверь соответствие названий.\n" . "2️⃣ Определи истца и ответчика (если применимо).\n" . "3️⃣ Опиши суть спора и возможные аргументы сторон.\n" . "4️⃣ Проверь на нецензурную лексику и изображения.\n" . "5️⃣ Дай итоговый вердикт ('Прошло модерацию' или 'Требуется проверка')."; */ $body = json_encode([ // "model" => "o1-mini", "model" => "gpt-4-turbo", "messages" => [ ["role" => "system", "content" => "Ты юридический аналитик. Анализируй документы согласно задаче."], ["role" => "user", "content" => $task], ["role" => "user", "content" => json_encode($documents, JSON_UNESCAPED_UNICODE)] ], "max_completion_tokens" => 4000 ]); logMessage("Запрос к GPT-4-Turbo: " . substr($body, 0, 1000)); $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => OPENAI_API_URL, CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $body, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'Authorization: Bearer ' . OPENAI_API_KEY ] ]); $response = curl_exec($curl); curl_close($curl); return json_decode($response, true); } // 🔹 Обработка всех файлов $files_data = []; while ($row = $result->fetch_assoc()) { $title = $row["title"]; $filePath = $row["filepath"]; logMessage("Обрабатываем файл: " . $filePath); if (!file_exists($filePath)) { logMessage("Ошибка: Файл $filePath не найден."); continue; } // 🔹 Временно переименовываем файл $tempFilePath = renameFileForProcessing($filePath); // 🔹 Извлекаем текст из PDF $pdfText = shell_exec("pdftotext -layout -enc UTF-8 " . escapeshellarg($tempFilePath) . " -"); if (empty(trim($pdfText))) { logMessage("Файл $tempFilePath содержит только изображения или пуст. Запускаем OCR..."); $pdfText = shell_exec("tesseract " . escapeshellarg($tempFilePath) . " stdout -l rus+eng"); } if (empty(trim($pdfText))) { logMessage("OCR не смог извлечь текст из $tempFilePath."); restoreOriginalFileName($filePath, $tempFilePath); continue; } // 🔹 Добавляем в список для анализа $files_data[] = ["title" => $title, "text" => $pdfText]; restoreOriginalFileName($filePath, $tempFilePath); } // 🔹 Отправка всех файлов в GPT $gptAnalysis = analyzeDocumentsWithGPT($files_data); logMessage("Ответ от GPT-4-Turbo: " . json_encode($gptAnalysis, JSON_UNESCAPED_UNICODE)); // Логируем JSON-ответ перед отправкой в CRM //logMessage("JSON-ответ в CRM: " . json_encode(["status" => "complete", "content" => $gptAnalysis['choices'][0]['message']['content']], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); logMessage("Полный JSON-ответ от GPT: " . json_encode($gptAnalysis, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)); // Проверяем, является ли $gptAnalysis строкой JSON или массивом if (!is_string($gptAnalysis)) { logMessage("DEBUG: GPT-ответ уже является массивом."); $gptResponse = $gptAnalysis; } else { logMessage("DEBUG: Декодируем JSON-ответ от GPT."); $gptResponse = json_decode($gptAnalysis, true); } // Проверяем, корректно ли распарсился JSON if (!is_array($gptResponse)) { logMessage("Ошибка: JSON-декодирование не удалось."); die(json_encode(["status" => "error", "message" => "Ошибка: JSON-декодирование не удалось."])); } // Проверяем, есть ли ключ 'choices' if (!isset($gptResponse['choices']) || empty($gptResponse['choices'])) { logMessage("Ошибка: в JSON-ответе отсутствует ключ 'choices'."); die(json_encode(["status" => "error", "message" => "Ошибка: в JSON-ответе отсутствует ключ 'choices'."])); } // Получаем контент $content = $gptResponse['choices'][0]['message']['content'] ?? null; if (!$content) { logMessage("Ошибка: контент не найден в ответе от GPT."); die(json_encode(["status" => "error", "message" => "Ошибка: контент не найден в ответе от GPT."])); } logMessage("DEBUG: Извлеченный контент: " . $content); // Возвращаем JSON с контентом echo json_encode(["status" => "complete", "content" => $content], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); //echo $content; ?>