/
MashkoA
/
web-nodejs
Обзор
Документация
Войти
/
MashkoA
/
web-nodejs
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
public/lab9/task1/script.js
237 строк
9 KB
umarovazizjohn
9 labs omg
23 апр 2026, 09:57
23 апр 2026, 09:57
6dff9fc
Код
Авторство
О чём код?
'use strict'; const PRODUCTS_API = '/api/lab9/products'; const STOCK_API = '/api/lab9/task1/stock'; const SEARCH_API = '/api/lab9/task1/products'; // Форматирование цены: Копейки -> Рубли const formatPrice = (cents) => { return (cents / 100).toLocaleString('ru-RU', { style: 'currency', currency: 'RUB' }); }; // Показать сообщение function showMessage(message, type = 'error') { // Удалить предыдущие сообщения const existingMessage = document.querySelector('.message'); if (existingMessage) { existingMessage.remove(); } const messageDiv = document.createElement('div'); messageDiv.className = `message ${type}`; messageDiv.textContent = message; const contentContainer = document.querySelector('.content-container'); contentContainer.insertBefore(messageDiv, contentContainer.firstChild); // Автоматически скрыть через 5 секунд if (type === 'success') { setTimeout(() => { messageDiv.remove(); }, 5000); } } // Загрузка статистики склада async function loadStockStats() { try { document.getElementById('stockStats').innerHTML = '<div class="loading">Загрузка статистики...</div>'; const res = await fetch(STOCK_API); if (!res.ok) { throw new Error(`Ошибка загрузки статистики: ${res.status}`); } const stats = await res.json(); document.getElementById('stockStats').innerHTML = ` <div class="stat-item"> <div class="stat-value">${stats.total_products}</div> <div class="stat-label">Всего товаров</div> </div> <div class="stat-item"> <div class="stat-value">${stats.total_items}</div> <div class="stat-label">Единиц товара</div> </div> <div class="stat-item"> <div class="stat-value">${formatPrice(stats.total_value)}</div> <div class="stat-label">Общая стоимость</div> </div> `; } catch (error) { console.error('Ошибка загрузки статистики:', error); document.getElementById('stockStats').innerHTML = `<div class="error">Ошибка загрузки статистики: ${error.message}</div>`; } } // Загрузка товаров (обычная или с поиском) async function loadProducts(searchTerm = '') { try { document.getElementById('list').innerHTML = '<div class="loading">Загрузка товаров...</div>'; let url = PRODUCTS_API; if (searchTerm && searchTerm.length >= 1) { url = `${SEARCH_API}?q=${encodeURIComponent(searchTerm)}`; } const res = await fetch(url); if (!res.ok) { throw new Error(`Ошибка загрузки: ${res.status}`); } const products = await res.json(); if (products.length === 0) { const message = searchTerm ? `Товары по запросу "${searchTerm}" не найдены` : 'Товаров пока нет'; document.getElementById('list').innerHTML = `<div class="loading">${message}</div>`; return; } document.getElementById('list').innerHTML = products.map(product => ` <div class="product-card" data-id="${product.id}"> <div class="product-info"> <div class="product-title">${product.title}</div> <div class="product-details"> <span class="product-price">${formatPrice(product.price)}</span> <span class="product-amount">Остаток: ${product.amount} шт.</span> </div> </div> <div class="product-actions"> <button class="btn btn-delete" onclick="deleteProduct(${product.id})">Удалить</button> </div> </div> `).join(''); } catch (error) { console.error('Ошибка загрузки товаров:', error); document.getElementById('list').innerHTML = `<div class="error">Ошибка загрузки товаров: ${error.message}</div>`; } } // Удаление товара async function deleteProduct(id) { if (!confirm('Вы уверены, что хотите удалить этот товар?')) return; try { const res = await fetch(`${PRODUCTS_API}/${id}`, { method: 'DELETE' }); if (!res.ok) { throw new Error(`Ошибка удаления: ${res.status}`); } showMessage('Товар успешно удален', 'success'); loadProducts(); loadStockStats(); // Обновляем статистику после удаления } catch (error) { console.error('Ошибка удаления товара:', error); showMessage(`Ошибка удаления товара: ${error.message}`); } } // Обработчик формы добавления товара document.getElementById('addForm').addEventListener('submit', async (e) => { e.preventDefault(); const formData = new FormData(e.target); const submitButton = e.target.querySelector('button[type="submit"]'); const originalText = submitButton.textContent; try { // Показать состояние загрузки submitButton.textContent = 'Сохранение...'; submitButton.disabled = true; // Конвертация: Рубли -> Копейки const priceRub = parseFloat(formData.get('price')); const priceCents = Math.round(priceRub * 100); const data = { title: formData.get('title').trim(), price: priceCents, amount: parseInt(formData.get('amount')) }; // Валидация if (!data.title) { throw new Error('Название товара не может быть пустым'); } if (data.price <= 0) { throw new Error('Цена должна быть больше 0'); } if (data.amount < 0) { throw new Error('Количество не может быть отрицательным'); } const res = await fetch(PRODUCTS_API, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); if (!res.ok) { const errorData = await res.json().catch(() => ({})); throw new Error(errorData.message || `Ошибка сервера: ${res.status}`); } // Успешное сохранение e.target.reset(); showMessage('Товар успешно добавлен', 'success'); loadProducts(); loadStockStats(); // Обновляем статистику после добавления } catch (error) { console.error('Ошибка при сохранении:', error); showMessage(error.message); } finally { // Восстановить кнопку submitButton.textContent = originalText; submitButton.disabled = false; } }); // Обработчик поиска function setupSearch() { const searchInput = document.getElementById('searchInput'); const searchBtn = document.getElementById('searchBtn'); const clearBtn = document.getElementById('clearSearch'); // Поиск по кнопке searchBtn.addEventListener('click', () => { const searchTerm = searchInput.value.trim(); if (searchTerm.length >= 1) { loadProducts(searchTerm); } else { showMessage('Введите хотя бы 1 символ для поиска'); } }); // Поиск по Enter searchInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { searchBtn.click(); } }); // Очистка поиска clearBtn.addEventListener('click', () => { searchInput.value = ''; loadProducts(); }); } // Инициализация при загрузке страницы document.addEventListener('DOMContentLoaded', function() { loadProducts(); loadStockStats(); setupSearch(); });