/
ParaD
/
Server
Обзор
Документация
Войти
/
ParaD
/
Server
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
RZD.html
461 строка
24 KB
Rayfaga
first_commit
01 мар 2025, 20:02
01 мар 2025, 20:02
c75de2b
Код
Авторство
О чём код?
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Ассортимент товаров</title> <style> /* Стили для таблицы и элементов */ body { font-family: Arial, sans-serif; color: #333; font-weight: bolder; } table { width: 100%; border-collapse: collapse; margin-bottom: 20px; } thead { background-color: #d32f2f; } thead th:last-child { width: 190px; } th { color: white; font-size: 1.2em; font-weight: bold; padding: 12px; } td { border: 1px solid black; padding: 10px; text-align: center; vertical-align: middle; } img { width: 100%; max-width: 150px; height: auto; object-fit: cover; } .counter-container { width: 180px; display: flex; flex-direction: row; justify-content: center; align-items: center; } .counter-button { width: 30px; height: 30px; text-align: center; line-height: 30px; border: 1px solid #000; cursor: pointer; } .counter-label { width: 149px; text-align: center; margin: 0 5px; font-weight: bold; } #cartButton { display: none; position: fixed; bottom: 20px; right: 20px; border: 2px solid #d32f2f; background-color: #d32f2f; color: white; font-weight: bold; text-align: center; cursor: pointer; padding: 10px; } #languageToggle { position: fixed; bottom: 10px; left: 10px; width: 50px; height: 50px; border-radius: 50%; background-color: #d32f2f; color: white; font-weight: bold; font-size: 18px; text-align: center; line-height: 50px; cursor: pointer; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); } /* Стили для блока статуса заказа */ #statusContainer { margin-top: 20px; padding: 15px; border: 1px solid #ccc; display: none; text-align: center; } </style> </head> <body> <!-- Таблица товаров --> <table id="productTable"> <thead> <tr> <th id="categoryHeader">Категория</th> <th id="productHeader">Товар</th> <th id="photoHeader">Фото</th> <th id="priceHeader">Цена (руб.)</th> <th id="quantityHeader">Количество</th> </tr> </thead> <tbody> <!-- В начало tbody добавляем кнопку "Статус заказа" --> <tr> <td colspan="5"> <button id="orderStatusButton" onclick="checkOrderStatus()">Статус заказа</button> </td> </tr> <!-- Здесь динамически добавятся остальные строки товаров --> </tbody> </table> <!-- Кнопка корзины --> <div id="cartButton" onclick="showCartSummary()">Корзина</div> <!-- Кнопка смены языка --> <div id="languageToggle" onclick="toggleLanguage()">RUS</div> <!-- Блок для отображения статуса заказа --> <div id="statusContainer"></div> <script> const cartState = {}; const products = [ { categoryRUS: "В заснеженный день", categoryENG: "On a snowy day", items: [ { nameRUS: "Кофе, приготовленный в автоматической кофемашине", nameENG: "Coffee prepared in an automatic coffee machine", price: 175, img: "auto_coffee_machine.png" }, { nameRUS: "Какао-напиток, растворимый, пакетированный", nameENG: "Packetized cacao instant drink", price: 55, img: "instant_cocoa.png" }, { nameRUS: "Кофе 3 в 1, растворимый, пакетированный", nameENG: "Three-in-one packetized instant coffee", price: 55, img: "3in1_coffee.png" } ] }, { categoryRUS: "Горячие напитки: MacCoffee", categoryENG: "Hot drinks: MacCoffee", items: [ { nameRUS: "Кофе 3 в 1, растворимый, пакетированный MacCoffee", nameENG: "Three-in-one packetized instant Mac Coffee", price: 55, img: "3in1_coffeeMAC.png" }, { nameRUS: "Капучино, напиток кофейный, растворимый", nameENG: "Сappuccino instant coffee drink", price: 150, img: "cappuccino.png" }, { nameRUS: "Латте, напиток кофейный, растворимый", nameENG: "Latte instant coffee drink", price: 150, img: "latte.png" } ] }, { categoryRUS: "Горячие напитки: Жокей", categoryENG: "Hot drinks: Жокей", items: [ { nameRUS: "Черный кофе, пакетированный", nameENG: "Packetized black coffee", price: 55, img: "black_coffee.png" }, { nameRUS: "Кофе 3 в 1, растворимый, пакетированный Жокей", nameENG: "Three-in-one packetized instant Жокей coffee", price: 55, img: "3in1_coffeeJOKEY.png" } ] }, { categoryRUS: "Десерты и горячие напитки", categoryENG: "Desserts and hot drinks", items: [ { nameRUS: "Чай крупнолистовой в термосаше в ассортименте", nameENG: "Assorted whole-leaf tea in thermo-sachet", price: 70, img: "loose_leaf_tea.png" }, { nameRUS: "Чай пакетированный в ассортименте", nameENG: "Assorted packetized tea", price: 50, img: "bagged_tea.png" }, { nameRUS: "Сахар пакетированный", nameENG: "Packetized sugar", price: 5, img: "sugar_packet.png" }, { nameRUS: "Сливки 10% жирности", nameENG: "10% cream", price: 30, img: "cream.png" }, { nameRUS: "Вафли венские \"Акульчев\" в ассортименте", nameENG: "Assorted Akulchev Vienna waffles", price: 105, img: "viennese_waffles.png" }, { nameRUS: "Вафли в ассортименте", nameENG: "Assorted waffles", price: 115, img: "assorted_waffles.png" }, { nameRUS: "Печенье в ассортименте", nameENG: "Assorted cookies", price: 145, img: "cookies.png" }, { nameRUS: "Конфета вафельная \"Степ MIX\"", nameENG: "Assorted waffle candy", price: 120, img: "step_mix_candy.png" }, { nameRUS: "Шоколад молочный с начинкой \"МЕГА ДРАЙВ\"", nameENG: "MEGA DRIVE filled milk chocolate", price: 130, img: "mega_drive_chocolate.png" }, { nameRUS: "Пряник в ассортименте", nameENG: "Assorted gingerbread", price: 140, img: "gingerbread.png" } ] }, { categoryRUS: "Мороженое", categoryENG: "Ice Cream", items: [ { nameRUS: "Мороженое эскимо \"Жемчужина России\"", nameENG: "Pearl of Russia Eskimo ice cream", price: 200, img: "pearl_russia.png" }, { nameRUS: "Мороженое ванильное в рожке \"От Деда Мороза\"", nameENG: "From Father Frost vanilla ice cream cone", price: 190, img: "santa_vanilla_cone.png" }, { nameRUS: "Мороженое пломбир в стаканчике \"От Деда Мороза\"", nameENG: "From Father Frost plombieres wafer ice cream", price: 150, img: "santa_cup_icecream.png" }, { nameRUS: "Мороженое эскимо \"От Деда Мороза\"", nameENG: "From Father Frost Eskimo ice cream", price: 150, img: "santa_icecream_bar.png" }, { nameRUS: "Мороженое пломбир \"Филевский стаканчик\"", nameENG: "Filevsky Cone plombieres ice cream", price: 190, img: "filevsky_cup.png" }, { nameRUS: "Мороженое с ароматом дыни \"От Деда Мороза\"", nameENG: "From Father Frost melon-flavored ice cream", price: 150, img: "santa_melon.png" }, { nameRUS: "Десерт взбитый замороженный \"Щербет из манго\"", nameENG: "Mango Sherbet frozen whipped dessert", price: 200, img: "mango_sherbet.png" } ] }, { categoryRUS: "Напитки", categoryENG: "Cold drinks", items: [ { nameRUS: "Сок (нектар) в ассортименте", nameENG: "Assorted juice (nectar)", price: 85, img: "juice.png" }, { nameRUS: "Пиво \"Халзан\" безалкогольное", nameENG: "Soft beer Halzan", price: 200, img: "halzan_beer.png" }, { nameRUS: "Вода в ассортименте", nameENG: "Assorted water", price: 85, img: "water.png" }, { nameRUS: "Газированный напиток в ассортименте", nameENG: "Assorted carbonated drinks", price: 130, img: "carbonated_drink.png" }, { nameRUS: "Газированный напиток \"Добрый\" в ассортименте", nameENG: "Assorted Dobry carbonated drinks", price: 205, img: "dobry_drink.png" }, { nameRUS: "Безалкогольный освежающий напиток в ассортименте", nameENG: "Assorted soft refreshing drink", price: 170, img: "refreshing_drink.png" } ] }, { categoryRUS: "Здоровое питание", categoryENG: "Healthy food", items: [ { nameRUS: "Коктейль смесь орехов и сухофруктов в ассортименте", nameENG: "Assroted nuts and dried fruit mix cocktail", price: 370, img: "nut_mix.png" }, { nameRUS: "Злаковый батончик в ассортименте", nameENG: "Assorted cereal bars", price: 85, img: "cereal_bar.png" }, { nameRUS: "Пастила \"Белевская\" в ассортименте", nameENG: "Assorted Belevskaya fruit leather", price: 475, img: "pastila.png" } ] }, { categoryRUS: "Снеки и продукты быстрого приготовления", categoryENG: "Snacks and instant Food", items: [ { nameRUS: "\"Московский картофель\" в ассортименте", nameENG: "Assorted Moscow Potato", price: 275, img: "moscow_potatoes.png" }, { nameRUS: "Арахис в ассортименте", nameENG: "Assorted peanuts", price: 70, img: "peanuts.png" }, { nameRUS: "Сухарики в ассортименте", nameENG: "Assorted croutons", price: 65, img: "croutons.png" }, { nameRUS: "Чипсы в ассортименте", nameENG: "Assorted chips", price: 150, img: "chips.png" }, { nameRUS: "Лапша \"Роллтон\" быстрого приготовления в ассортименте", nameENG: "Assorted Rollton instant noodles", price: 145, img: "rollton_noodles.png" }, { nameRUS: "Картофельное пюре \"Роллтон\" быстрого приготовления в ассортименте", nameENG: "Assorted Rollton instant mashed potatoes", price: 125, img: "rollton_mashed.png" }, { nameRUS: "Лапша \"Биг Бон\" быстрого приготовления в ассортименте", nameENG: "Assorted Big Bon instant noodles", price: 210, img: "bigbon_noodles.png" } ] }, { categoryRUS: "Сувениры", categoryENG: "Souvenirs", items: [ { nameRUS: "Подстаканник со стаканом \"Классический\" в ассортименте", nameENG: "Assorted classic glass holders with a glass", price: 2500, img: "classic_glass_holder.png" }, { nameRUS: "Подстаканник со стаканом \"Россия\" в ассортименте", nameENG: "Assorted Russia glass holders with a glass", price: 3675, img: "russia_glass_holder.png" }, { nameRUS: "Подстаканник со стаканом (подарочный) с позолотой в ассортименте", nameENG: "Assorted (gift) gold-plated glass holders with a glass", price: 5980, img: "gift_glass_holder.png" } ] }, { categoryRUS: "Сезонное предложение", categoryENG: "Seasonal offer", items: [ { nameRUS: "Набор для вышивания на пластиковой канве в ассортименте", nameENG: "Assorted embroidery set on plastic canvas", price: 1100, img: "plastic_canvas_embroidery_set.png" }, { nameRUS: "Набор для создания игольницы в ассортименте", nameENG: "Assorted pinkeep creation set", price: 1300, img: "plastic_igla_embroidery_set.png" }, { nameRUS: "Набор для создания игрушки, шар на ёлку в ассортименте", nameENG: "Assorted set for creating a toy, a ball for the Christmas tree", price: 1500, img: "christmas_ball_creation_set.png" } ] }, { categoryRUS: "Для творчества", categoryENG: "For creative", items: [ { nameRUS: "Мандалы исполнения желаний в ассортименте", nameENG: "Wish fulfilment mandalas assorted", price: 350, img: "wish_mandalas.png" }, { nameRUS: "Книжка с наклейками \"Дорожные истории\" в ассортименте", nameENG: "Sticker book \"Road Stories\" (assorted)", price: 350, img: "kniga.png" }, { nameRUS: "Флексагон, веселые мордашки в ассортименте", nameENG: "Flexagon, funny faces (assorted)", price: 200, img: "flexagon.png" } ] }, { categoryRUS: "Товары в дорогу", categoryENG: "Travel goods", items: [ { nameRUS: "Маска для глаз в ассортименте", nameENG: "Assorted eye masks", price: 140, img: "eye_mask.png" }, { nameRUS: "Подушка для путешествий в ассортименте", nameENG: "Assorted travel pillows", price: 750, img: "travel_pillow.png" }, { nameRUS: "Дорожные тапочки в ассортименте", nameENG: "Assorted travel slippers", price: 315, img: "travel_slippers.png" }, { nameRUS: "Пассажирский санитарно-гигиенический набор бизнес-класса (мужской, женский)", nameENG: "Business class (men's, women's) passenger hygienic kit", price: 315, img: "buisness_class.png" } ] } ]; let currentLanguage = 'RUS'; const translations = { category: { RUS: 'Категория', ENG: 'Category' }, product: { RUS: 'Товар', ENG: 'Product' }, photo: { RUS: 'Фото', ENG: 'Photo' }, price: { RUS: 'Цена (руб.)', ENG: 'Price (rub.)' }, quantity: { RUS: 'Количество', ENG: 'Quantity' }, added: { RUS: 'Добавлено', ENG: 'Added' }, cart: { RUS: 'Корзина', ENG: 'Cart' } }; // Функция смены языка function toggleLanguage() { currentLanguage = currentLanguage === 'RUS' ? 'ENG' : 'RUS'; document.getElementById('languageToggle').textContent = currentLanguage; document.getElementById('cartButton').textContent = translations.cart[currentLanguage]; document.querySelectorAll('.counter-label').forEach(label => { let count = parseInt(label.textContent.replace(/\D/g, '')) || 0; label.textContent = `${translations.added[currentLanguage]}: ${count}`; }); if (document.getElementById('cartContainer')) { document.getElementById('cartContainer').remove(); showCartSummary(); } renderProducts(); } // Функция отрисовки товаров function renderProducts() { const tbody = document.querySelector('#productTable tbody'); // Очищаем tbody и добавляем строку с кнопкой "Статус заказа" tbody.innerHTML = ` <tr> <td colspan="5"> <button id="orderStatusButton" onclick="checkOrderStatus()">Статус заказа</button> </td> </tr> `; products.forEach(category => { category.items.forEach((item, index) => { const row = document.createElement('tr'); row.innerHTML = ` ${index === 0 ? `<td rowspan="${category.items.length}">${currentLanguage === 'RUS' ? category.categoryRUS : category.categoryENG}</td>` : ''} <td>${currentLanguage === 'RUS' ? item.nameRUS : item.nameENG}</td> <td><img src="./site_photo/${item.img}" alt="${item.nameRUS}"></td> <td>${item.price}</td> <td> <div class="counter-container"> <div class="counter-button" onclick="updateCounter('counter_${item.nameRUS}', -1, ${products.indexOf(category)}, ${category.items.indexOf(item)})">-</div> <div class="counter-label" id="counter_${item.nameRUS}">${translations.added[currentLanguage]}: 0</div> <div class="counter-button" onclick="updateCounter('counter_${item.nameRUS}', 1, ${products.indexOf(category)}, ${category.items.indexOf(item)})">+</div> </div> </td> `; tbody.appendChild(row); }); }); } // Функция изменения количества товара function updateCounter(counterId, delta, categoryIndex, itemIndex) { const counter = document.getElementById(counterId); let count = parseInt(counter.textContent.replace(/\D/g, '')) || 0; count += delta; if (count < 0) count = 0; counter.textContent = `Добавлено: ${count}`; const uniqueIndex = `${categoryIndex}-${itemIndex}`; cartState[uniqueIndex] = count; toggleCartButton(); } // Отображение кнопки корзины, если в заказе есть товары function toggleCartButton() { const cartButton = document.getElementById('cartButton'); if (!cartButton) { console.error("Ошибка: кнопка корзины не найдена в DOM"); return; } const hasItems = Object.values(cartState).some(count => count > 0); cartButton.style.display = hasItems ? 'block' : 'none'; } // Отображение корзины с заказом function showCartSummary() { document.getElementById('productTable').style.display = 'none'; document.getElementById('cartButton').style.display = 'none'; let cartItems = []; let totalPrice = 0; for (const uniqueIndex in cartState) { if (cartState[uniqueIndex] > 0) { if (!uniqueIndex.includes('-')) continue; const [catIndex, itemIndex] = uniqueIndex.split('-').map(Number); if (isNaN(catIndex) || isNaN(itemIndex)) continue; if (!products[catIndex] || !products[catIndex].items[itemIndex]) continue; const item = products[catIndex].items[itemIndex]; const itemName = currentLanguage === 'RUS' ? item.nameRUS : item.nameENG; const itemPrice = item.price; cartItems.push(`${itemName} x${cartState[uniqueIndex]}`); totalPrice += itemPrice * cartState[uniqueIndex]; } } let cartContent = ` <h2>${currentLanguage === 'RUS' ? 'Ваш заказ' : 'Your Order'}</h2> <p>${cartItems.join('; ')}</p> <p><strong>${currentLanguage === 'RUS' ? 'Итого' : 'Total'}: ${totalPrice} руб.</strong></p> <label>${currentLanguage === 'RUS' ? 'ФИО' : 'Full Name'}: <input type="text" id="name" placeholder="${currentLanguage === 'RUS' ? 'Введите ФИО' : 'Enter your full name'}"> </label><br> <label>${currentLanguage === 'RUS' ? 'Вагон' : 'Carriage'}: <input type="text" id="seat" placeholder="${currentLanguage === 'RUS' ? 'Введите номер вагона' : 'Enter carriage number'}"> </label><br> <label>${currentLanguage === 'RUS' ? 'Номер сиденья' : 'Seat Number'}: <input type="text" id="seatNumber" placeholder="${currentLanguage === 'RUS' ? 'Введите номер сиденья' : 'Enter seat number'}"> </label><br> <button onclick="goBack()">${currentLanguage === 'RUS' ? 'Вернуться назад' : 'Go back'}</button> <button onclick="submitOrder()">${currentLanguage === 'RUS' ? 'Отправить заказ' : 'Submit order'}</button> `; const cartContainer = document.createElement('div'); cartContainer.id = 'cartContainer'; cartContainer.innerHTML = cartContent; document.body.appendChild(cartContainer); } // Функция возврата из корзины к списку товаров function goBack() { document.getElementById('cartContainer').remove(); document.getElementById('productTable').style.display = 'table'; document.getElementById('cartButton').style.display = 'block'; } // Отправка заказа на сервер и запись заказа в файл function submitOrder() { const name = document.getElementById('name').value; const seat = document.getElementById('seat').value; const seatNumber = document.getElementById('seatNumber').value; document.cookie = `userName=${encodeURIComponent(name)}; path=/; max-age=86400`; if (!name || !seat || !seatNumber) { alert(currentLanguage === 'RUS' ? 'Пожалуйста, заполните все поля' : 'Please fill in all fields'); return; } const orderData = { name: name, seat: seat, seatNumber: seatNumber, cartItems: document.querySelector('#cartContainer p').innerText }; fetch('/submit_order', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(orderData) }) .then(response => response.text()) .then(data => { alert(data); }) .catch(error => { console.error('Ошибка:', error); }); } // Функция проверки статуса заказа по ФИО через prompt function checkOrderStatus() { let name = prompt("Введите ФИО:"); if (!name) return; fetch(`/get_order_status?name=${encodeURIComponent(name)}`) .then(response => response.text()) .then(data => { console.log("Ответ сервера:", data); if (data.includes("Заказ не найден") || data.includes("Файл заказов не найден")) { alert(data); } else { showOrderStatus(name, data.trim()); } }) .catch(error => console.error("Ошибка запроса:", error)); } // Отображение статуса заказа и добавление кнопок "Закрыть" и "Открыть крышку" при необходимости function showOrderStatus(name, status) { let statusContainer = document.getElementById("statusContainer"); statusContainer.style.display = "block"; statusContainer.innerHTML = `<h3>${name}</h3><p>Статус: <strong>${status}</strong></p>`; statusContainer.innerHTML += `<br><button onclick="closeStatus()">Закрыть</button>`; if (status === "ЗАВЕРШЕНО") { statusContainer.innerHTML += `<br><button onclick="openLid()">Открыть крышку</button>`; } } // Функция для отправки запроса на сервер для открытия крышки (запись "1" в файл) function openLid() { fetch('/open_lid', { method: 'POST' }) .then(response => response.text()) .then(data => alert(data)) .catch(error => console.error("Ошибка:", error)); } // Скрыть блок статуса заказа function closeStatus() { document.getElementById("statusContainer").style.display = "none"; } // Инициализация отрисовки товаров renderProducts(); </script> </body> </html>