133 lines
5.4 KiB
PHP
133 lines
5.4 KiB
PHP
|
|
<?php
|
|||
|
|
|
|||
|
|
// Настройки OpenAI API
|
|||
|
|
const OPENAI_API_KEY = 'sk-GS24OxHQYfq8ErW5CRLoN5F1CfJPxNsY';
|
|||
|
|
const OPENAI_ASSISTANT_API = 'https://api.proxyapi.ru/openai/v1/assistants';
|
|||
|
|
const OPENAI_FILES_API = 'https://api.proxyapi.ru/openai/v1/files';
|
|||
|
|
const OPENAI_THREADS_API = 'https://api.proxyapi.ru/openai/v1/threads';
|
|||
|
|
const OPENAI_CHAT_API = 'https://api.proxyapi.ru/openai/v1/chat/completions';
|
|||
|
|
const LOG_FILE = 'logs/script.log';
|
|||
|
|
|
|||
|
|
// Подключение к базе данных Vtiger CRM
|
|||
|
|
$dsn = 'mysql:host=localhost;port=3306;dbname=ci20465_72new;charset=utf8mb4';
|
|||
|
|
$user = 'ci20465_72new';
|
|||
|
|
$password = 'EcY979Rn';
|
|||
|
|
$pdo = new PDO($dsn, $user, $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
|
|||
|
|
|
|||
|
|
// ID ассистента OpenAI
|
|||
|
|
const OPENAI_ASSISTANT_ID = 'asst_suGt51aoepXUkJiC0t3vobeG';
|
|||
|
|
const OPENAI_ASSISTANT_NAME = 'Clientright';
|
|||
|
|
|
|||
|
|
// Функция логирования
|
|||
|
|
function logMessage($message) {
|
|||
|
|
file_put_contents(LOG_FILE, date('Y-m-d H:i:s') . " - " . $message . "\n", FILE_APPEND | LOCK_EX);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Функция для получения данных из базы Vtiger CRM
|
|||
|
|
function fetchDocumentData($pdo, $id) {
|
|||
|
|
logMessage("Получение данных документов из CRM по ID: $id");
|
|||
|
|
$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 = $pdo->prepare($sql);
|
|||
|
|
$stmt->execute([$id]);
|
|||
|
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Функция создания треда в OpenAI
|
|||
|
|
function createThread() {
|
|||
|
|
logMessage("Создание единого треда в OpenAI");
|
|||
|
|
$curl = curl_init();
|
|||
|
|
curl_setopt_array($curl, [
|
|||
|
|
CURLOPT_URL => OPENAI_THREADS_API,
|
|||
|
|
CURLOPT_RETURNTRANSFER => true,
|
|||
|
|
CURLOPT_POST => true,
|
|||
|
|
CURLOPT_HTTPHEADER => [
|
|||
|
|
'Authorization: Bearer ' . OPENAI_API_KEY,
|
|||
|
|
'Content-Type: application/json'
|
|||
|
|
]
|
|||
|
|
]);
|
|||
|
|
|
|||
|
|
$response = curl_exec($curl);
|
|||
|
|
curl_close($curl);
|
|||
|
|
$decodedResponse = json_decode($response, true);
|
|||
|
|
|
|||
|
|
if (isset($decodedResponse['id'])) {
|
|||
|
|
logMessage("✅ Тред создан, thread_id: " . $decodedResponse['id']);
|
|||
|
|
return $decodedResponse['id'];
|
|||
|
|
}
|
|||
|
|
logMessage("❌ Ошибка создания треда в OpenAI");
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Получение ID по POST-запросу
|
|||
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||
|
|
$input = json_decode(file_get_contents('php://input'), true);
|
|||
|
|
$id = $input['id'] ?? null;
|
|||
|
|
if (!$id) {
|
|||
|
|
logMessage("Ошибка: отсутствует ID проекта");
|
|||
|
|
die("Ошибка: отсутствует ID проекта");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logMessage("Начало обработки проекта с ID: $id");
|
|||
|
|
$documents = fetchDocumentData($pdo, $id);
|
|||
|
|
if (empty($documents)) {
|
|||
|
|
logMessage("Документы не найдены для ID: $id");
|
|||
|
|
die("Документы не найдены для ID: $id");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$filePaths = array_column($documents, 'filepath');
|
|||
|
|
logMessage("📂 Найдено " . count($filePaths) . " документов для анализа");
|
|||
|
|
|
|||
|
|
$threadId = createThread();
|
|||
|
|
if (!$threadId) {
|
|||
|
|
logMessage("Ошибка создания треда в OpenAI");
|
|||
|
|
die("Ошибка создания треда в OpenAI");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$fileIds = [];
|
|||
|
|
foreach ($filePaths as $filePath) {
|
|||
|
|
logMessage("📤 Отправка файла в OpenAI: " . $filePath);
|
|||
|
|
$fileId = uploadFileToOpenAI($filePath);
|
|||
|
|
if ($fileId) {
|
|||
|
|
logMessage("✅ Файл загружен в OpenAI, file_id: " . $fileId);
|
|||
|
|
$fileIds[] = $fileId;
|
|||
|
|
} else {
|
|||
|
|
logMessage("❌ Ошибка загрузки файла в OpenAI");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (empty($fileIds)) {
|
|||
|
|
logMessage("❌ Ошибка: Не удалось загрузить ни одного файла.");
|
|||
|
|
die("Ошибка: Не удалось загрузить ни одного файла.");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logMessage("🔍 Проверка истории анализов для проекта ID: $id");
|
|||
|
|
$previousResult = checkPreviousAnalysis($pdo, $id, $filePaths);
|
|||
|
|
if ($previousResult) {
|
|||
|
|
logMessage("🔄 Отправляем сохраненный результат.");
|
|||
|
|
echo json_encode($previousResult, JSON_UNESCAPED_UNICODE);
|
|||
|
|
exit;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
logMessage("🔍 Отправка всех документов на анализ в OpenAI");
|
|||
|
|
$analysis = analyzeDocument($threadId, OPENAI_ASSISTANT_ID, $fileIds);
|
|||
|
|
logMessage("🔍 Анализ завершен: " . json_encode($analysis, JSON_UNESCAPED_UNICODE));
|
|||
|
|
|
|||
|
|
echo json_encode($analysis, JSON_UNESCAPED_UNICODE);
|
|||
|
|
} else {
|
|||
|
|
logMessage("Ошибка: запрос должен быть POST");
|
|||
|
|
die("Ошибка: запрос должен быть POST");
|
|||
|
|
}
|
|||
|
|
?>
|