/
kkkatsuko
/
Blog
Обзор
Документация
Войти
/
kkkatsuko
/
Blog
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
task2306/index.html
498 строк
23 KB
kkkatsuko
Update: index.html
23 июн 2026, 18:37
Верифицирован
23 июн 2026, 18:37
26a0e4d
Код
Авторство
О чём код?
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Помощник игрушек «Весна»</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Roboto, system-ui, sans-serif; } body { background: linear-gradient(145deg, #f6f0e7 0%, #e8dfd3 100%); min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 20px; } .chat-container { max-width: 700px; width: 100%; background: #fffaf2; border-radius: 40px 40px 30px 30px; box-shadow: 0 20px 50px rgba(0, 0, 0, 0.15), 0 8px 20px rgba(0, 0, 0, 0.05); overflow: hidden; backdrop-filter: blur(2px); transition: all 0.2s; } .chat-header { background: #d9c5b2; padding: 22px 28px; display: flex; align-items: center; gap: 12px; border-bottom: 1px solid #c5b09b; } .chat-header h1 { font-size: 1.7rem; font-weight: 500; color: #3d2c1f; letter-spacing: -0.5px; } .chat-header span { background: #b8a18b; padding: 5px 14px; border-radius: 40px; font-size: 0.8rem; color: #2d1e12; font-weight: 500; margin-left: auto; background: #e5d3c0; } .chat-messages { padding: 24px 20px 12px 20px; max-height: 460px; overflow-y: auto; display: flex; flex-direction: column; gap: 14px; background: #fcf7f0; } .message { display: flex; flex-direction: column; max-width: 85%; padding: 14px 18px; border-radius: 26px; font-size: 0.98rem; line-height: 1.5; word-break: break-word; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.02); animation: pop 0.2s ease; } .message-bot { align-self: flex-start; background: #ece2d6; color: #2d241b; border-bottom-left-radius: 6px; border: 1px solid #dfd0c0; } .message-user { align-self: flex-end; background: #d7c9bb; color: #1f1710; border-bottom-right-radius: 6px; border: 1px solid #cbb9a8; } .message a { color: #4f3a28; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; transition: 0.2s; display: inline-block; margin-top: 4px; } .message a:hover { color: #7a5b41; transform: scale(1.02); } .message .small-note { font-size: 0.8rem; opacity: 0.7; margin-top: 6px; border-top: 1px dashed #beaa99; padding-top: 6px; } .chat-input-area { padding: 16px 20px 24px; background: #f5ede4; border-top: 1px solid #dccfc1; } .input-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; } .input-row input, .input-row select { flex: 1 1 140px; padding: 14px 16px; border: 1px solid #d4c3b2; border-radius: 60px; background: white; font-size: 0.95rem; outline: none; transition: 0.2s; box-shadow: inset 0 1px 4px rgba(0,0,0,0.02); } .input-row input:focus, .input-row select:focus { border-color: #a58772; box-shadow: 0 0 0 3px rgba(165, 135, 114, 0.2); } .input-row button { background: #b8a087; border: none; color: white; padding: 14px 28px; border-radius: 60px; font-weight: 600; font-size: 1rem; cursor: pointer; transition: 0.2s; box-shadow: 0 4px 8px rgba(0,0,0,0.04); letter-spacing: 0.3px; border: 1px solid #a68970; } .input-row button:hover { background: #9f846b; transform: scale(0.97); box-shadow: 0 2px 6px rgba(0,0,0,0.1); } .input-row button:active { background: #8b725b; } .quick-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; justify-content: center; } .quick-btn { background: #e8dbcf; border: 1px solid #d2bfae; padding: 8px 16px; border-radius: 40px; font-size: 0.85rem; font-weight: 500; color: #2d1f14; cursor: pointer; transition: 0.15s; box-shadow: 0 2px 4px rgba(0,0,0,0.02); flex: 0 1 auto; } .quick-btn:hover { background: #dac9b8; border-color: #b69f8a; transform: translateY(-1px); } .footer-hint { font-size: 0.7rem; text-align: center; color: #a58d7a; margin-top: 12px; letter-spacing: 0.3px; } @keyframes pop { 0% { opacity: 0.4; transform: scale(0.97); } 100% { opacity: 1; transform: scale(1); } } /* стили скролла */ .chat-messages::-webkit-scrollbar { width: 6px; } .chat-messages::-webkit-scrollbar-track { background: #ede3d8; border-radius: 10px; } .chat-messages::-webkit-scrollbar-thumb { background: #cbb8a6; border-radius: 10px; } </style> </head> <body> <div class="chat-container"> <div class="chat-header"> <h1>🧸 Кукольный помощник</h1> <span>Весна</span> </div> <div class="chat-messages" id="chatMessages"> <div class="message message-bot"> 👋 Привет! Я помогу подобрать куклу для вашего ребёнка.<br> Укажите <strong>возраст</strong> и <strong>пол</strong>, а затем спросите: <br> «большая кукла», «маленькая», «милая», «красивая» или «шарнирная». </div> </div> <div class="chat-input-area"> <div class="input-row"> <input type="number" id="ageInput" placeholder="Возраст (лет)" min="1" max="16" value="6"> <select id="genderSelect"> <option value="девочка">Девочка</option> <option value="мальчик">Мальчик</option> <option value="унисекс">Унисекс</option> </select> <button id="sendBtn">Отправить</button> </div> <div class="quick-actions"> <button class="quick-btn" data-query="большая кукла">📏 Большая</button> <button class="quick-btn" data-query="маленькая кукла">🧸 Маленькая</button> <button class="quick-btn" data-query="милая кукла">🌸 Милая</button> <button class="quick-btn" data-query="красивая кукла">✨ Красивая</button> <button class="quick-btn" data-query="шарнирная кукла">🔄 Шарнирная</button> </div> <div class="footer-hint">⬆ нажмите на кнопку или введите запрос вручную</div> </div> </div> <script> (function() { const messagesContainer = document.getElementById('chatMessages'); const ageInput = document.getElementById('ageInput'); const genderSelect = document.getElementById('genderSelect'); const sendBtn = document.getElementById('sendBtn'); const quickBtns = document.querySelectorAll('.quick-btn'); // --- база ссылок на куклы фабрики "Весна" (реальные url) --- const DOLL_LINKS = { // большие куклы (рост ~50-60 см) big: { girl: 'https://vesna.toys/catalog/kukly/bolshie_kukly/', boy: 'https://vesna.toys/catalog/kukly/bolshie_kukly/', unisex: 'https://vesna.toys/catalog/kukly/bolshie_kukly/' }, // маленькие (рост ~30-40 см) small: { girl: 'https://vesna.toys/catalog/kukly/klassicheskie_kukly/malyshka_sonya_22_sm/', boy: 'https://vesna.toys/catalog/kukly/klassicheskie_kukly/malyshka_sonya_22_sm/', unisex: 'https://vesna.toys/catalog/kukly/klassicheskie_kukly/malyshka_sonya_22_sm/' }, // милые (куклы-малыши, ангельские лица) cute: { girl: 'https://vesna.toys/catalog/pupsy_1/18_sm/', boy: 'https://vesna.toys/catalog/pupsy_1/18_sm/', unisex: 'https://vesna.toys/catalog/pupsy_1/18_sm/' }, // красивые (нарядные, принцессы) beautiful: { girl: 'https://vesna.toys/catalog/kukly/klassicheskie_kukly/', boy: 'https://vesna.toys/catalog/kukly/klassicheskie_kukly/', unisex: 'https://vesna.toys/catalog/kukly/klassicheskie_kukly/' }, // шарнирные (подвижные, коллекционные) jointed: { girl: 'https://vesna.toys/catalog/subbrendy/mireya/', boy: 'https://vesna.toys/catalog/subbrendy/mireya/', unisex: 'https://vesna.toys/catalog/subbrendy/mireya/' } }; // --- вспомогательные функции --- function getGender() { return genderSelect.value; } function getAge() { const val = parseInt(ageInput.value, 10); if (isNaN(val) || val < 1) return 1; if (val > 16) return 16; return val; } // возрастная группа для уточнения рекомендации (не влияет на ссылку, но меняет текст) function ageGroup(age) { if (age <= 3) return 'ранний возраст (1–3)'; if (age <= 6) return 'дошкольный (4–6)'; if (age <= 10) return 'младший школьный (7–10)'; return 'средний/старший (11+)'; } // функция для получения ссылки по типу и полу function getDollLink(typeKey, gender) { const typeMap = { 'большая': 'big', 'маленькая': 'small', 'милая': 'cute', 'красивая': 'beautiful', 'шарнирная': 'jointed' }; const normalizedType = typeMap[typeKey]; if (!normalizedType) return null; const genderKey = (gender === 'девочка') ? 'girl' : (gender === 'мальчик' ? 'boy' : 'unisex'); const linkObj = DOLL_LINKS[normalizedType]; if (!linkObj) return null; return linkObj[genderKey] || linkObj['unisex']; } // --- добавить сообщение в чат --- function addMessage(text, sender = 'bot', link = null, linkText = null) { const messageDiv = document.createElement('div'); messageDiv.classList.add('message', sender === 'bot' ? 'message-bot' : 'message-user'); // если есть ссылка, вставляем как HTML if (link && linkText) { const linkHtml = `<a href="${link}" target="_blank" rel="noopener noreferrer">${linkText}</a>`; messageDiv.innerHTML = text + ' ' + linkHtml; } else if (link) { const linkHtml = `<a href="${link}" target="_blank" rel="noopener noreferrer">🔗 Перейти на сайт фабрики "Весна"</a>`; messageDiv.innerHTML = text + ' ' + linkHtml; } else { messageDiv.textContent = text; } messagesContainer.appendChild(messageDiv); messagesContainer.scrollTop = messagesContainer.scrollHeight; } // --- основной обработчик запроса --- function handleUserQuery(rawQuery) { const age = getAge(); const gender = getGender(); const ageStr = ageGroup(age); let query = rawQuery.trim().toLowerCase(); // Проверяем ключевые слова let matchedType = null; if (query.includes('большая')) matchedType = 'большая'; else if (query.includes('маленькая')) matchedType = 'маленькая'; else if (query.includes('милая')) matchedType = 'милая'; else if (query.includes('красивая')) matchedType = 'красивая'; else if (query.includes('шарнирная')) matchedType = 'шарнирная'; // Если не распознали — даём подсказку if (!matchedType) { addMessage(`❓ Я не понял запрос. Попробуйте сказать: "большая кукла", "маленькая кукла", "милая кукла", "красивая кукла" или "шарнирная кукла".`, 'bot'); return; } // Получаем ссылку const link = getDollLink(matchedType, gender); const genderDisplay = (gender === 'девочка') ? 'девочке' : (gender === 'мальчик' ? 'мальчику' : 'ребёнку'); const typeDisplay = matchedType.charAt(0).toUpperCase() + matchedType.slice(1); // Формируем ответ с учётом возраста и пола let responseText = `🧸 Для ${genderDisplay} ${age} лет (${ageStr}) рекомендую ${typeDisplay} куклу. `; let linkText = `Посмотреть на сайте фабрики "Весна"`; if (link) { // доп. информация по возрасту для больших/маленьких if (matchedType === 'большая' && age < 4) { responseText += `(Для малышей лучше выбирать куклы поменьше, но эта подойдёт под присмотром) `; } else if (matchedType === 'маленькая' && age > 10) { responseText += `(Для старшего возраста возможно будет интереснее большая кукла, но это на ваш выбор) `; } else if (matchedType === 'шарнирная' && age < 8) { responseText += `(Все шарнирные куклы требуют аккуратного обращения, рекомендуем для детей от 8 лет) `; } // добавим мягкую рекомендацию addMessage(responseText, 'bot', link, linkText); } else { // на случай, если ссылка не нашлась (запасной вариант) addMessage(`${responseText} К сожалению, точная ссылка не найдена, но вы можете поискать на сайте фабрики "Весна".`, 'bot'); } } // --- обработка отправки (текст из поля) --- function processInput() { // поле ввода отсутствует, используем заглушку: запрос из быстрых кнопок, // но для ручного ввода сделаем небольшой prompt (либо используем скрытое поле) // По заданию — «отвечать на запросы от родителя с формулировками ...» // мы используем быстрые кнопки, но также можно добавить текстовое поле для ввода. // Я добавлю невидимое поле для ввода? Лучше просто через модалку или alert. // Но сделаем более дружелюбно: добавим скрытый input? // Сделаем через простой prompt (для демонстрации) – но лучше использовать дополнительный инпут. // Реализуем через отдельное поле ввода, но у нас уже есть возраст и пол. // Добавим поле ввода запроса вручную. // Я переделаю: добавлю поле для ввода текста запроса. // Для простоты воспользуемся готовым решением: вводим через prompt. // Но для юзабилити лучше добавить поле. Создам его динамически? // Быстрое решение: добавим input в строку. // Так как у нас уже есть кнопки, я добавлю поле ввода в .input-row // Обновлю HTML: добавлю поле для запроса. Сделаю это через JS. } // --- ДОБАВЛЯЕМ поле для ручного ввода запроса (реализуем прямо сейчас) --- function createInputField() { const inputRow = document.querySelector('.input-row'); // уже есть input[type="number"], select, button // вставим перед кнопкой input для запроса const queryInput = document.createElement('input'); queryInput.type = 'text'; queryInput.id = 'queryInput'; queryInput.placeholder = 'Напишите запрос... (например, милая кукла)'; queryInput.style.flex = '2 1 180px'; // вставляем перед кнопкой const btn = document.getElementById('sendBtn'); inputRow.insertBefore(queryInput, btn); // обработчик на кнопку отправки btn.addEventListener('click', function() { const query = queryInput.value.trim(); if (query === '') { addMessage('✏️ Введите запрос или нажмите на кнопку-подсказку.', 'bot'); return; } // добавим сообщение пользователя addMessage(`👤 ${query}`, 'user'); handleUserQuery(query); queryInput.value = ''; }); // Enter на поле запроса queryInput.addEventListener('keydown', function(e) { if (e.key === 'Enter') { e.preventDefault(); btn.click(); } }); // быстрые кнопки quickBtns.forEach(btn => { btn.addEventListener('click', function() { const query = this.getAttribute('data-query'); // добавим сообщение пользователя addMessage(`👤 ${query}`, 'user'); handleUserQuery(query); }); }); } // Инициализация: добавить поле ввода и прочие обработчики window.addEventListener('DOMContentLoaded', function() { createInputField(); // также обработаем кнопку "Отправить" если уже есть, но мы переназначили // дополнительно можно показать приветствие }); // добавим приветственное сообщение при загрузке (уже есть) // и небольшая страховка: если пользователь не ввел возраст/пол – подскажем // при первом запросе возраст и пол уже установлены. // Для поддержки старых кнопок (если не сработает) - дублируем // также обработаем клик на быстрые кнопки повторно (уже назначено) // но если createInputField не сработает — сделаем резерв. // Проверяем, если кнопки не привязаны, привяжем. setTimeout(() => { if (quickBtns.length > 0) { quickBtns.forEach(btn => { if (!btn._listener) { btn.addEventListener('click', function() { const query = this.getAttribute('data-query'); addMessage(`👤 ${query}`, 'user'); handleUserQuery(query); }); btn._listener = true; } }); } }, 100); // также добавим обработку на кнопку sendBtn (если не переопределена) // но мы её переопределили в createInputField. // Оставим запасной вариант: const sendBtnBackup = document.getElementById('sendBtn'); if (sendBtnBackup) { // но чтобы не дублировать, сделаем через делегирование } console.log('Чат-бот готов! Используйте быстрые кнопки или введите запрос.'); })(); </script> </body> </html>