From c584dcac4eeba32be7a861935239fb90f95eeb87 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sat, 27 Sep 2025 23:20:14 +0000 Subject: [PATCH] 2 --- .gitignore | 1 + api.php | 110 ++++++++++++++++++++++++++ assets/css/custom.css | 163 ++++++++++++++++++++++++++++++++++++++ assets/js/main.js | 84 ++++++++++++++++++++ db/knowledge_base.txt | 1 + index.php | 180 +++++++++++++----------------------------- 6 files changed, 413 insertions(+), 126 deletions(-) create mode 100644 api.php create mode 100644 assets/css/custom.css create mode 100644 assets/js/main.js create mode 100644 db/knowledge_base.txt diff --git a/.gitignore b/.gitignore index e427ff3..d387093 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules/ */node_modules/ */build/ +.env diff --git a/api.php b/api.php new file mode 100644 index 0000000..c3823cc --- /dev/null +++ b/api.php @@ -0,0 +1,110 @@ + 'Ошибка: API-ключ не найден. Пожалуйста, добавьте его в файл .env']); + exit; +} + +// 2. Get user message from POST request +$input = json_decode(file_get_contents('php://input'), true); +$userMessage = trim($input['message'] ?? ''); + +if (empty($userMessage)) { + echo json_encode(['reply' => 'Пожалуйста, введите сообщение.']); + exit; +} + +// 3. Load the knowledge base +$knowledgeBasePath = __DIR__ . '/db/knowledge_base.txt'; +if (!file_exists($knowledgeBasePath)) { + echo json_encode(['reply' => 'Ошибка: База знаний не найдена.']); + exit; +} +$knowledgeBase = file_get_contents($knowledgeBasePath); + +// 4. Prepare the prompt for the AI +$prompt = "Ты — ИИ-ассистент, специалист по внутренней системе управления складом под названием HUB. Твоя задача — отвечать на вопросы пользователя, основываясь ИСКЛЮЧИТЕЛЬНО на предоставленной базе знаний. Не придумывай ничего от себя. Если ответа в базе знаний нет, вежливо сообщи, что ты можешь отвечать только на вопросы, связанные с системой HUB.\n\nВот база знаний:\n---\n" . $knowledgeBase . "\n---\n\nВопрос пользователя: \"" . $userMessage . "\""; + +// 5. Call the Gemini API +$url = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=' . $apiKey; + +$data = [ + 'contents' => [ + [ + 'parts' => [ + ['text' => $prompt] + ] + ] + ] +]; + +$options = [ + 'http' => [ + 'header' => "Content-type: application/json\r\n", + 'method' => 'POST', + 'content' => json_encode($data), + 'ignore_errors' => true // To see the error message from the API + ] +]; + +$context = stream_context_create($options); +$response = file_get_contents($url, false, $context); +$http_response_header = $http_response_header ?? []; + +// 6. Process the response +if ($response === FALSE) { + $error = 'Не удалось связаться с API. '; + // Check for more specific errors if possible + $last_error = error_get_last(); + if ($last_error) { + $error .= $last_error['message']; + } + // Try to get the HTTP status and response body + $status_line = $http_response_header[0] ?? 'HTTP/1.1 500 Internal Server Error'; + preg_match('{HTTP/\S+\s(\d+)}', $status_line, $match); + $status = $match[1] ?? 500; + + error_log("Gemini API Error: Status $status, Response: $response"); + + echo json_encode(['reply' => "Ошибка при обращении к сервису ИИ. Статус: $status. Пожалуйста, проверьте ключ API и настройки сервера."]); + +} else { + $result = json_decode($response, true); + + if (isset($result['candidates'][0]['content']['parts'][0]['text'])) { + $reply = $result['candidates'][0]['content']['parts'][0]['text']; + echo json_encode(['reply' => $reply]); + } else { + // Log the actual error response from the API for debugging + error_log("Gemini API - Unexpected response structure: " . $response); + echo json_encode(['reply' => 'Получен неожиданный ответ от сервиса ИИ. Возможно, проблема с конфигурацией или ключом API.']); + } +} \ No newline at end of file diff --git a/assets/css/custom.css b/assets/css/custom.css new file mode 100644 index 0000000..1aa7031 --- /dev/null +++ b/assets/css/custom.css @@ -0,0 +1,163 @@ + +:root { + --bg-color: #121212; + --surface-color: #1E1E1E; + --primary-color: #00FF9B; + --secondary-color: #00C2FF; + --text-color: #E0E0E0; + --text-muted-color: #888; + --border-radius-md: 12px; + --border-radius-sm: 8px; +} + +body { + background-color: var(--bg-color); + color: var(--text-color); + font-family: 'Roboto Mono', 'Consolas', 'Monaco', monospace; + margin: 0; + padding: 0; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + overflow: hidden; +} + +.chat-container { + width: 100%; + max-width: 800px; + height: 100vh; + max-height: 100vh; /* For mobile browsers */ + display: flex; + flex-direction: column; + background-color: var(--bg-color); + border-radius: 0; + box-shadow: 0 0 40px rgba(0, 255, 155, 0.1); + overflow: hidden; +} + +.chat-header { + padding: 16px 24px; + background-color: var(--surface-color); + border-bottom: 1px solid #333; + text-align: center; +} + +.chat-header h1 { + font-size: 1.5rem; + font-weight: 500; + margin: 0; + background: linear-gradient(90deg, var(--primary-color), var(--secondary-color)); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + text-fill-color: transparent; +} + +.chat-header .text-muted { + font-size: 0.85rem; + color: var(--text-muted-color); + margin: 0; +} + +.chat-messages { + flex-grow: 1; + padding: 24px; + overflow-y: auto; + display: flex; + flex-direction: column; + gap: 16px; +} + +/* Custom scrollbar for webkit browsers */ +.chat-messages::-webkit-scrollbar { + width: 6px; +} +.chat-messages::-webkit-scrollbar-track { + background: var(--bg-color); +} +.chat-messages::-webkit-scrollbar-thumb { + background-color: var(--surface-color); + border-radius: 6px; +} + +.message { + display: flex; + max-width: 75%; +} + +.message-content { + padding: 12px 16px; + border-radius: var(--border-radius-md); + line-height: 1.5; +} + +.message-content p { + margin: 0; +} + +.bot-message { + align-self: flex-start; +} + +.bot-message .message-content { + background-color: var(--surface-color); + border-top-left-radius: 0; +} + +.user-message { + align-self: flex-end; +} + +.user-message .message-content { + background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); + color: #000; + border-top-right-radius: 0; +} + +.chat-input-area { + padding: 16px 24px; + background-color: var(--surface-color); + border-top: 1px solid #333; +} + +#chat-form .form-control { + background-color: #333; + border: 1px solid #444; + color: var(--text-color); + border-radius: var(--border-radius-sm); + padding: 12px 16px; + height: 48px; +} + +#chat-form .form-control:focus { + background-color: #333; + color: var(--text-color); + box-shadow: 0 0 0 2px var(--primary-color); + border-color: var(--primary-color); +} + +#chat-form .form-control::placeholder { + color: var(--text-muted-color); +} + +#chat-form .btn { + background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); + border: none; + border-radius: var(--border-radius-sm); + margin-left: 12px; + width: 48px; + height: 48px; + display: flex; + justify-content: center; + align-items: center; + transition: transform 0.2s ease; +} + +#chat-form .btn:hover { + transform: scale(1.05); +} + +#chat-form .btn svg { + color: #000; +} diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..169545a --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1,84 @@ +document.addEventListener('DOMContentLoaded', () => { + const chatForm = document.getElementById('chat-form'); + const messageInput = document.getElementById('message-input'); + const chatMessages = document.getElementById('chat-messages'); + + chatForm.addEventListener('submit', (e) => { + e.preventDefault(); + const messageText = messageInput.value.trim(); + + if (messageText) { + appendMessage(messageText, 'user'); + messageInput.value = ''; + + showBotTyping(); + + // Send message to backend + fetch('api.php', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ message: messageText }) + }) + .then(response => response.json()) + .then(data => { + removeBotTyping(); + appendMessage(data.reply, 'bot'); + }) + .catch(error => { + removeBotTyping(); + console.error('Error:', error); + appendMessage('Извините, произошла ошибка. Попробуйте еще раз.', 'bot'); + }); + } + }); + + function appendMessage(text, sender) { + const messageWrapper = document.createElement('div'); + messageWrapper.classList.add('message', `${sender}-message`); + + const messageContent = document.createElement('div'); + messageContent.classList.add('message-content'); + + const paragraph = document.createElement('p'); + paragraph.innerHTML = text; // Use innerHTML to render potential HTML tags from response + + messageContent.appendChild(paragraph); + messageWrapper.appendChild(messageContent); + chatMessages.appendChild(messageWrapper); + + scrollToBottom(); + } + + function showBotTyping() { + const typingIndicator = document.createElement('div'); + typingIndicator.id = 'typing-indicator'; + typingIndicator.classList.add('message', 'bot-message'); + + const content = document.createElement('div'); + content.classList.add('message-content'); + + const p = document.createElement('p'); + p.textContent = '...'; + + content.appendChild(p); + typingIndicator.appendChild(content); + chatMessages.appendChild(typingIndicator); + scrollToBottom(); + } + + function removeBotTyping() { + const typingIndicator = document.getElementById('typing-indicator'); + if (typingIndicator) { + typingIndicator.remove(); + } + } + + function scrollToBottom() { + chatMessages.scrollTop = chatMessages.scrollHeight; + } + + // Initial scroll to bottom if content is already there + scrollToBottom(); +}); \ No newline at end of file diff --git a/db/knowledge_base.txt b/db/knowledge_base.txt new file mode 100644 index 0000000..0b869b4 --- /dev/null +++ b/db/knowledge_base.txt @@ -0,0 +1 @@ +Это БАЗА знаний 1. Введение в систему HUB Цель: Понять назначение HUB и его роль в управлении складскими данными. HUB — это система для управления складскими предметами (грузами, контейнерами, коробками и т.д.) и процессами их перемещения, хранения и инвентаризации. Она позволяет отслеживать состояние предметов, их историю, взаимодействие с контейнерами и логистическими точками, а также проводить пересчеты и настраивать складскую инфраструктуру. Ключевые понятия: Предмет: Объект хранения (например, ТЯ, коробка, отправление). Логистический контейнер (ЛК): Емкость для хранения/перемещения предметов (статусы: "Формируется", "Сформирован" и др.). Инвентаризация/пересчет: Проверка фактического наличия предметов на складе против учетных данных. КМО: Внутренний термин, предположительно связанный с документацией о материальных ошибках/недостачах (например, "Книга Материальных Остатков"). ЦМН: Цель доставки (место назначения предмета). Тайм-слот: Временной интервал для доставки. 2. Основы интерфейса HUB и карточка предмета Цель: Знакомство с интерфейсом HUB и структурой карточки предмета. HUB содержит главное меню, схему склада и таблицу со списком предметов. Основная работа ведется через карточку предмета — детализированное окно с информацией о конкретном объекте. 2.1 Структура карточки предмета Карточка доступна при клике на ID предмета в таблице "Предметы". Она включает следующие вкладки: Вкладка Описание Основные данные «О предмете» Основная информация о предмете. Тип, статус, ID, номенклатура, принадлежность, стоимость, адрес хранения. «Состав» Текущий и исторический состав контейнера (для предметов, являющихся контейнерами). Список предметов внутри, даты добавления/удаления, статусы элементов состава. «История (перемещения)» История перемещений предмета между ячейками, контейнерами и логистическими точками. Тип события (принято, перемещено, вошло/вышло из контейнера), дата, источник/цель. «Отгрузки» Запись о выдаче предмета (отгрузке) со склада. Дата отгрузки, получате \ No newline at end of file diff --git a/index.php b/index.php index 6f7ffab..ad38765 100644 --- a/index.php +++ b/index.php @@ -1,131 +1,59 @@ - - - + + - - - New Style - - - - + + + Your Logistic Koresh + + + + + + + + + + + + + + + + + + + -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

+ +
+
+

Your Logistic Koresh

+

AI Assistant for HUB System

+
+ +
+ +
+
+

Привет. Я — твой логистический кореш. Я здесь, чтобы помочь тебе с вопросами по системе HUB. Спрашивай, не стесняйся.

+
+
+
+ +
+
+ + +
+
-
- + + + + + - + \ No newline at end of file