fix
This commit is contained in:
@@ -1,13 +1,10 @@
|
|||||||
FROM php:8.2-apache
|
FROM php:8.2-apache
|
||||||
|
|
||||||
# Установка PostgreSQL драйвера
|
|
||||||
RUN apt-get update && apt-get install -y libpq-dev \
|
RUN apt-get update && apt-get install -y libpq-dev \
|
||||||
&& docker-php-ext-install pdo pdo_pgsql \
|
&& docker-php-ext-install pdo pdo_pgsql \
|
||||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Включить модули Apache
|
|
||||||
RUN a2enmod rewrite headers alias
|
RUN a2enmod rewrite headers alias
|
||||||
|
|
||||||
# Установка рабочей директории
|
|
||||||
WORKDIR /var/www/html
|
WORKDIR /var/www/html
|
||||||
|
|
||||||
|
|||||||
@@ -25,4 +25,3 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
cite_practica_network:
|
cite_practica_network:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Включаем модули Apache
|
|
||||||
a2enmod rewrite
|
a2enmod rewrite
|
||||||
a2enmod headers
|
a2enmod headers
|
||||||
|
|
||||||
# Добавляем admin в hosts
|
|
||||||
echo "127.0.0.1 admin" >> /etc/hosts
|
echo "127.0.0.1 admin" >> /etc/hosts
|
||||||
|
|
||||||
# Активируем виртуальный хост
|
|
||||||
a2ensite 000-default
|
a2ensite 000-default
|
||||||
|
|
||||||
# Запускаем Apache
|
|
||||||
exec apache2-foreground
|
exec apache2-foreground
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
ServerName admin
|
ServerName admin
|
||||||
ServerAlias localhost
|
ServerAlias localhost
|
||||||
DocumentRoot /var/www/html
|
DocumentRoot /var/www/html
|
||||||
|
|
||||||
# Alias для пути /cite_practica/
|
|
||||||
Alias /cite_practica /var/www/html/cite_practica
|
Alias /cite_practica /var/www/html/cite_practica
|
||||||
|
|
||||||
<Directory /var/www/html>
|
<Directory /var/www/html>
|
||||||
@@ -19,13 +17,10 @@
|
|||||||
DirectoryIndex cite_mebel.php index.php index.html
|
DirectoryIndex cite_mebel.php index.php index.html
|
||||||
</Directory>
|
</Directory>
|
||||||
|
|
||||||
# Настройка PHP
|
|
||||||
<FilesMatch \.php$>
|
<FilesMatch \.php$>
|
||||||
SetHandler application/x-httpd-php
|
SetHandler application/x-httpd-php
|
||||||
</FilesMatch>
|
</FilesMatch>
|
||||||
|
|
||||||
# Логи
|
|
||||||
ErrorLog ${APACHE_LOG_DIR}/cite_practica_error.log
|
ErrorLog ${APACHE_LOG_DIR}/cite_practica_error.log
|
||||||
CustomLog ${APACHE_LOG_DIR}/cite_practica_access.log combined
|
CustomLog ${APACHE_LOG_DIR}/cite_practica_access.log combined
|
||||||
</VirtualHost>
|
</VirtualHost>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
-- 001_initial_schema.sql
|
|
||||||
-- Создание базовых таблиц для AETERNA
|
|
||||||
|
|
||||||
-- Таблица пользователей
|
|
||||||
CREATE TABLE IF NOT EXISTS users (
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
user_id SERIAL PRIMARY KEY,
|
user_id SERIAL PRIMARY KEY,
|
||||||
email VARCHAR(255) UNIQUE NOT NULL,
|
email VARCHAR(255) UNIQUE NOT NULL,
|
||||||
@@ -16,7 +12,6 @@ CREATE TABLE IF NOT EXISTS users (
|
|||||||
is_admin BOOLEAN DEFAULT FALSE
|
is_admin BOOLEAN DEFAULT FALSE
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Таблица категорий
|
|
||||||
CREATE TABLE IF NOT EXISTS categories (
|
CREATE TABLE IF NOT EXISTS categories (
|
||||||
category_id SERIAL PRIMARY KEY,
|
category_id SERIAL PRIMARY KEY,
|
||||||
name VARCHAR(100) NOT NULL,
|
name VARCHAR(100) NOT NULL,
|
||||||
@@ -29,7 +24,6 @@ CREATE TABLE IF NOT EXISTS categories (
|
|||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Таблица подкатегорий
|
|
||||||
CREATE TABLE IF NOT EXISTS subcategories (
|
CREATE TABLE IF NOT EXISTS subcategories (
|
||||||
subcategory_id SERIAL PRIMARY KEY,
|
subcategory_id SERIAL PRIMARY KEY,
|
||||||
category_id INTEGER REFERENCES categories(category_id) ON DELETE CASCADE,
|
category_id INTEGER REFERENCES categories(category_id) ON DELETE CASCADE,
|
||||||
@@ -41,7 +35,6 @@ CREATE TABLE IF NOT EXISTS subcategories (
|
|||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Таблица товаров
|
|
||||||
CREATE TABLE IF NOT EXISTS products (
|
CREATE TABLE IF NOT EXISTS products (
|
||||||
product_id SERIAL PRIMARY KEY,
|
product_id SERIAL PRIMARY KEY,
|
||||||
category_id INTEGER REFERENCES categories(category_id) ON DELETE SET NULL,
|
category_id INTEGER REFERENCES categories(category_id) ON DELETE SET NULL,
|
||||||
@@ -64,10 +57,8 @@ CREATE TABLE IF NOT EXISTS products (
|
|||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Индексы для быстрого поиска
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_products_category ON products(category_id);
|
CREATE INDEX IF NOT EXISTS idx_products_category ON products(category_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_products_available ON products(is_available);
|
CREATE INDEX IF NOT EXISTS idx_products_available ON products(is_available);
|
||||||
CREATE INDEX IF NOT EXISTS idx_products_price ON products(price);
|
CREATE INDEX IF NOT EXISTS idx_products_price ON products(price);
|
||||||
CREATE INDEX IF NOT EXISTS idx_categories_parent ON categories(parent_id);
|
CREATE INDEX IF NOT EXISTS idx_categories_parent ON categories(parent_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_categories_active ON categories(is_active);
|
CREATE INDEX IF NOT EXISTS idx_categories_active ON categories(is_active);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
-- 002_add_cart_orders.sql
|
|
||||||
-- Таблицы для корзины и заказов
|
|
||||||
|
|
||||||
-- Таблица корзины
|
|
||||||
CREATE TABLE IF NOT EXISTS cart (
|
CREATE TABLE IF NOT EXISTS cart (
|
||||||
cart_id SERIAL PRIMARY KEY,
|
cart_id SERIAL PRIMARY KEY,
|
||||||
user_id INTEGER REFERENCES users(user_id) ON DELETE CASCADE,
|
user_id INTEGER REFERENCES users(user_id) ON DELETE CASCADE,
|
||||||
@@ -12,36 +8,23 @@ CREATE TABLE IF NOT EXISTS cart (
|
|||||||
UNIQUE(user_id, product_id)
|
UNIQUE(user_id, product_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Таблица заказов
|
|
||||||
CREATE TABLE IF NOT EXISTS orders (
|
CREATE TABLE IF NOT EXISTS orders (
|
||||||
order_id SERIAL PRIMARY KEY,
|
order_id SERIAL PRIMARY KEY,
|
||||||
order_number VARCHAR(50) UNIQUE NOT NULL,
|
order_number VARCHAR(50) UNIQUE NOT NULL,
|
||||||
user_id INTEGER REFERENCES users(user_id) ON DELETE SET NULL,
|
user_id INTEGER REFERENCES users(user_id) ON DELETE SET NULL,
|
||||||
|
|
||||||
-- Контактная информация
|
|
||||||
customer_name VARCHAR(100) NOT NULL,
|
customer_name VARCHAR(100) NOT NULL,
|
||||||
customer_email VARCHAR(255) NOT NULL,
|
customer_email VARCHAR(255) NOT NULL,
|
||||||
customer_phone VARCHAR(20) NOT NULL,
|
customer_phone VARCHAR(20) NOT NULL,
|
||||||
|
|
||||||
-- Адрес доставки
|
|
||||||
delivery_address TEXT NOT NULL,
|
delivery_address TEXT NOT NULL,
|
||||||
delivery_region VARCHAR(100),
|
delivery_region VARCHAR(100),
|
||||||
postal_code VARCHAR(20),
|
postal_code VARCHAR(20),
|
||||||
|
|
||||||
-- Способы
|
|
||||||
delivery_method VARCHAR(50) DEFAULT 'courier',
|
delivery_method VARCHAR(50) DEFAULT 'courier',
|
||||||
payment_method VARCHAR(50) DEFAULT 'card',
|
payment_method VARCHAR(50) DEFAULT 'card',
|
||||||
|
|
||||||
-- Суммы
|
|
||||||
subtotal DECIMAL(10, 2) NOT NULL,
|
subtotal DECIMAL(10, 2) NOT NULL,
|
||||||
discount_amount DECIMAL(10, 2) DEFAULT 0,
|
discount_amount DECIMAL(10, 2) DEFAULT 0,
|
||||||
delivery_price DECIMAL(10, 2) DEFAULT 0,
|
delivery_price DECIMAL(10, 2) DEFAULT 0,
|
||||||
final_amount DECIMAL(10, 2) NOT NULL,
|
final_amount DECIMAL(10, 2) NOT NULL,
|
||||||
|
|
||||||
-- Промокод
|
|
||||||
promo_code VARCHAR(50),
|
promo_code VARCHAR(50),
|
||||||
|
|
||||||
-- Статус и даты
|
|
||||||
status VARCHAR(30) DEFAULT 'pending',
|
status VARCHAR(30) DEFAULT 'pending',
|
||||||
notes TEXT,
|
notes TEXT,
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
@@ -49,7 +32,6 @@ CREATE TABLE IF NOT EXISTS orders (
|
|||||||
completed_at TIMESTAMP
|
completed_at TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Таблица позиций заказа
|
|
||||||
CREATE TABLE IF NOT EXISTS order_items (
|
CREATE TABLE IF NOT EXISTS order_items (
|
||||||
item_id SERIAL PRIMARY KEY,
|
item_id SERIAL PRIMARY KEY,
|
||||||
order_id INTEGER REFERENCES orders(order_id) ON DELETE CASCADE,
|
order_id INTEGER REFERENCES orders(order_id) ON DELETE CASCADE,
|
||||||
@@ -61,10 +43,8 @@ CREATE TABLE IF NOT EXISTS order_items (
|
|||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Индексы
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_cart_user ON cart(user_id);
|
CREATE INDEX IF NOT EXISTS idx_cart_user ON cart(user_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_orders_user ON orders(user_id);
|
CREATE INDEX IF NOT EXISTS idx_orders_user ON orders(user_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_orders_status ON orders(status);
|
CREATE INDEX IF NOT EXISTS idx_orders_status ON orders(status);
|
||||||
CREATE INDEX IF NOT EXISTS idx_orders_created ON orders(created_at);
|
CREATE INDEX IF NOT EXISTS idx_orders_created ON orders(created_at);
|
||||||
CREATE INDEX IF NOT EXISTS idx_order_items_order ON order_items(order_id);
|
CREATE INDEX IF NOT EXISTS idx_order_items_order ON order_items(order_id);
|
||||||
|
|
||||||
|
|||||||
@@ -1,57 +1,43 @@
|
|||||||
-- 003_add_product_fields.sql
|
|
||||||
-- Добавление дополнительных полей (если таблицы уже существуют)
|
|
||||||
|
|
||||||
-- Добавляем поля в products если их нет
|
|
||||||
DO $$
|
DO $$
|
||||||
BEGIN
|
BEGIN
|
||||||
-- color
|
|
||||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||||
WHERE table_name = 'products' AND column_name = 'color') THEN
|
WHERE table_name = 'products' AND column_name = 'color') THEN
|
||||||
ALTER TABLE products ADD COLUMN color VARCHAR(50);
|
ALTER TABLE products ADD COLUMN color VARCHAR(50);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- material
|
|
||||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||||
WHERE table_name = 'products' AND column_name = 'material') THEN
|
WHERE table_name = 'products' AND column_name = 'material') THEN
|
||||||
ALTER TABLE products ADD COLUMN material VARCHAR(100);
|
ALTER TABLE products ADD COLUMN material VARCHAR(100);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- card_size
|
|
||||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||||
WHERE table_name = 'products' AND column_name = 'card_size') THEN
|
WHERE table_name = 'products' AND column_name = 'card_size') THEN
|
||||||
ALTER TABLE products ADD COLUMN card_size VARCHAR(20) DEFAULT 'small';
|
ALTER TABLE products ADD COLUMN card_size VARCHAR(20) DEFAULT 'small';
|
||||||
END IF;
|
END IF;
|
||||||
END $$;
|
END $$;
|
||||||
|
|
||||||
-- Добавляем поля в users если их нет
|
|
||||||
DO $$
|
DO $$
|
||||||
BEGIN
|
BEGIN
|
||||||
-- city
|
|
||||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||||
WHERE table_name = 'users' AND column_name = 'city') THEN
|
WHERE table_name = 'users' AND column_name = 'city') THEN
|
||||||
ALTER TABLE users ADD COLUMN city VARCHAR(100);
|
ALTER TABLE users ADD COLUMN city VARCHAR(100);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- last_login
|
|
||||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||||
WHERE table_name = 'users' AND column_name = 'last_login') THEN
|
WHERE table_name = 'users' AND column_name = 'last_login') THEN
|
||||||
ALTER TABLE users ADD COLUMN last_login TIMESTAMP;
|
ALTER TABLE users ADD COLUMN last_login TIMESTAMP;
|
||||||
END IF;
|
END IF;
|
||||||
END $$;
|
END $$;
|
||||||
|
|
||||||
-- Добавляем поля в categories если их нет
|
|
||||||
DO $$
|
DO $$
|
||||||
BEGIN
|
BEGIN
|
||||||
-- updated_at
|
|
||||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||||
WHERE table_name = 'categories' AND column_name = 'updated_at') THEN
|
WHERE table_name = 'categories' AND column_name = 'updated_at') THEN
|
||||||
ALTER TABLE categories ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
ALTER TABLE categories ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- created_at
|
|
||||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||||
WHERE table_name = 'categories' AND column_name = 'created_at') THEN
|
WHERE table_name = 'categories' AND column_name = 'created_at') THEN
|
||||||
ALTER TABLE categories ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
ALTER TABLE categories ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||||
END IF;
|
END IF;
|
||||||
END $$;
|
END $$;
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
-- 004_grant_admin_to_admin_mail.sql
|
|
||||||
-- Миграция: Назначение прав администратора пользователю admin@mail.ru
|
|
||||||
|
|
||||||
-- Обновляем пользователя admin@mail.ru, давая ему права администратора
|
|
||||||
UPDATE users
|
UPDATE users
|
||||||
SET is_admin = TRUE,
|
SET is_admin = TRUE,
|
||||||
is_active = TRUE,
|
is_active = TRUE,
|
||||||
updated_at = CURRENT_TIMESTAMP
|
updated_at = CURRENT_TIMESTAMP
|
||||||
WHERE email = 'admin@mail.ru';
|
WHERE email = 'admin@mail.ru';
|
||||||
|
|
||||||
-- Проверяем результат
|
|
||||||
DO $$
|
DO $$
|
||||||
DECLARE
|
DECLARE
|
||||||
updated_count INTEGER;
|
updated_count INTEGER;
|
||||||
@@ -17,7 +12,6 @@ BEGIN
|
|||||||
GET DIAGNOSTICS updated_count = ROW_COUNT;
|
GET DIAGNOSTICS updated_count = ROW_COUNT;
|
||||||
|
|
||||||
IF updated_count > 0 THEN
|
IF updated_count > 0 THEN
|
||||||
-- Получаем информацию об обновленном пользователе
|
|
||||||
SELECT user_id, email, full_name, is_admin, is_active
|
SELECT user_id, email, full_name, is_admin, is_active
|
||||||
INTO user_info
|
INTO user_info
|
||||||
FROM users
|
FROM users
|
||||||
@@ -28,11 +22,10 @@ BEGIN
|
|||||||
RAISE NOTICE 'ФИО: %, Админ: %, Активен: %',
|
RAISE NOTICE 'ФИО: %, Админ: %, Активен: %',
|
||||||
user_info.full_name, user_info.is_admin, user_info.is_active;
|
user_info.full_name, user_info.is_admin, user_info.is_active;
|
||||||
ELSE
|
ELSE
|
||||||
-- Если пользователь не найден, создаем его с правами админа
|
|
||||||
INSERT INTO users (email, password_hash, full_name, phone, city, is_admin, is_active)
|
INSERT INTO users (email, password_hash, full_name, phone, city, is_admin, is_active)
|
||||||
VALUES (
|
VALUES (
|
||||||
'admin@mail.ru',
|
'admin@mail.ru',
|
||||||
'$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', -- admin123
|
'$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
|
||||||
'Администратор',
|
'Администратор',
|
||||||
'+79129991223',
|
'+79129991223',
|
||||||
'Москва',
|
'Москва',
|
||||||
@@ -47,4 +40,3 @@ BEGIN
|
|||||||
RAISE NOTICE 'Пользователь admin@mail.ru создан/обновлен с правами администратора';
|
RAISE NOTICE 'Пользователь admin@mail.ru создан/обновлен с правами администратора';
|
||||||
END IF;
|
END IF;
|
||||||
END $$;
|
END $$;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
-- seed_data.sql
|
|
||||||
-- Начальные данные для AETERNA
|
|
||||||
|
|
||||||
-- Администратор (пароль: admin123)
|
|
||||||
INSERT INTO users (email, password_hash, full_name, phone, city, is_admin, is_active)
|
INSERT INTO users (email, password_hash, full_name, phone, city, is_admin, is_active)
|
||||||
VALUES (
|
VALUES (
|
||||||
'admin@aeterna.ru',
|
'admin@aeterna.ru',
|
||||||
'$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', -- admin123
|
'$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
|
||||||
'Администратор AETERNA',
|
'Администратор AETERNA',
|
||||||
'+79129991223',
|
'+79129991223',
|
||||||
'Москва',
|
'Москва',
|
||||||
@@ -13,11 +9,10 @@ VALUES (
|
|||||||
TRUE
|
TRUE
|
||||||
) ON CONFLICT (email) DO NOTHING;
|
) ON CONFLICT (email) DO NOTHING;
|
||||||
|
|
||||||
-- Тестовый пользователь (пароль: user123)
|
|
||||||
INSERT INTO users (email, password_hash, full_name, phone, city, is_admin, is_active)
|
INSERT INTO users (email, password_hash, full_name, phone, city, is_admin, is_active)
|
||||||
VALUES (
|
VALUES (
|
||||||
'user@test.com',
|
'user@test.com',
|
||||||
'$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', -- user123
|
'$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm',
|
||||||
'Тестовый Пользователь',
|
'Тестовый Пользователь',
|
||||||
'+79111234567',
|
'+79111234567',
|
||||||
'Санкт-Петербург',
|
'Санкт-Петербург',
|
||||||
@@ -25,7 +20,6 @@ VALUES (
|
|||||||
TRUE
|
TRUE
|
||||||
) ON CONFLICT (email) DO NOTHING;
|
) ON CONFLICT (email) DO NOTHING;
|
||||||
|
|
||||||
-- Категории
|
|
||||||
INSERT INTO categories (name, slug, description, sort_order, is_active) VALUES
|
INSERT INTO categories (name, slug, description, sort_order, is_active) VALUES
|
||||||
('Диваны', 'divany', 'Прямые и угловые диваны для гостиной', 1, TRUE),
|
('Диваны', 'divany', 'Прямые и угловые диваны для гостиной', 1, TRUE),
|
||||||
('Кресла', 'kresla', 'Кресла для гостиной и офиса', 2, TRUE),
|
('Кресла', 'kresla', 'Кресла для гостиной и офиса', 2, TRUE),
|
||||||
@@ -35,7 +29,6 @@ INSERT INTO categories (name, slug, description, sort_order, is_active) VALUES
|
|||||||
('Светильники', 'svetilniki', 'Торшеры, люстры и настольные лампы', 6, TRUE)
|
('Светильники', 'svetilniki', 'Торшеры, люстры и настольные лампы', 6, TRUE)
|
||||||
ON CONFLICT (slug) DO NOTHING;
|
ON CONFLICT (slug) DO NOTHING;
|
||||||
|
|
||||||
-- Товары
|
|
||||||
INSERT INTO products (category_id, name, slug, description, price, old_price, sku, stock_quantity, is_available, image_url, color, material, card_size) VALUES
|
INSERT INTO products (category_id, name, slug, description, price, old_price, sku, stock_quantity, is_available, image_url, color, material, card_size) VALUES
|
||||||
(1, 'Светильник MINNIGHT', 'svetilnik-minnight', 'Настольный светильник в современном стиле', 7999, 9999, 'LAMP-MIN-001', 15, TRUE, 'img2/1_2.png', 'Черный', 'Металл', 'small'),
|
(1, 'Светильник MINNIGHT', 'svetilnik-minnight', 'Настольный светильник в современном стиле', 7999, 9999, 'LAMP-MIN-001', 15, TRUE, 'img2/1_2.png', 'Черный', 'Металл', 'small'),
|
||||||
(3, 'Кровать MODER', 'krovat-moder', 'Двуспальная кровать с мягким изголовьем', 45999, 55999, 'BED-MOD-001', 5, TRUE, 'img2/3_3.png', 'Серый', 'Дерево/Ткань', 'large'),
|
(3, 'Кровать MODER', 'krovat-moder', 'Двуспальная кровать с мягким изголовьем', 45999, 55999, 'BED-MOD-001', 5, TRUE, 'img2/3_3.png', 'Серый', 'Дерево/Ткань', 'large'),
|
||||||
@@ -48,7 +41,6 @@ INSERT INTO products (category_id, name, slug, description, price, old_price, sk
|
|||||||
(1, 'Диван HEMMINS', 'divan-hemmins', 'Большой модульный диван для всей семьи', 89999, 110000, 'SOFA-HEM-001', 2, TRUE, 'img2/9_9.png', 'Темно-серый', 'Ткань', 'full-width')
|
(1, 'Диван HEMMINS', 'divan-hemmins', 'Большой модульный диван для всей семьи', 89999, 110000, 'SOFA-HEM-001', 2, TRUE, 'img2/9_9.png', 'Темно-серый', 'Ткань', 'full-width')
|
||||||
ON CONFLICT (slug) DO NOTHING;
|
ON CONFLICT (slug) DO NOTHING;
|
||||||
|
|
||||||
-- Выводим статистику
|
|
||||||
DO $$
|
DO $$
|
||||||
DECLARE
|
DECLARE
|
||||||
users_count INTEGER;
|
users_count INTEGER;
|
||||||
@@ -62,4 +54,3 @@ BEGIN
|
|||||||
RAISE NOTICE 'Загружено: % пользователей, % категорий, % товаров',
|
RAISE NOTICE 'Загружено: % пользователей, % категорий, % товаров',
|
||||||
users_count, categories_count, products_count;
|
users_count, categories_count, products_count;
|
||||||
END $$;
|
END $$;
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ header('Content-Type: application/json; charset=utf-8');
|
|||||||
session_start();
|
session_start();
|
||||||
require_once __DIR__ . '/../config/database.php';
|
require_once __DIR__ . '/../config/database.php';
|
||||||
|
|
||||||
// Проверка прав администратора
|
|
||||||
if (!isset($_SESSION['isAdmin']) || !$_SESSION['isAdmin']) {
|
if (!isset($_SESSION['isAdmin']) || !$_SESSION['isAdmin']) {
|
||||||
echo json_encode(['success' => false, 'message' => 'Доступ запрещен']);
|
echo json_encode(['success' => false, 'message' => 'Доступ запрещен']);
|
||||||
exit();
|
exit();
|
||||||
@@ -21,7 +20,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
try {
|
try {
|
||||||
$db = Database::getInstance()->getConnection();
|
$db = Database::getInstance()->getConnection();
|
||||||
|
|
||||||
// Проверяем, есть ли товары в этой категории
|
|
||||||
$checkStmt = $db->prepare("SELECT COUNT(*) FROM products WHERE category_id = ?");
|
$checkStmt = $db->prepare("SELECT COUNT(*) FROM products WHERE category_id = ?");
|
||||||
$checkStmt->execute([$categoryId]);
|
$checkStmt->execute([$categoryId]);
|
||||||
$productCount = $checkStmt->fetchColumn();
|
$productCount = $checkStmt->fetchColumn();
|
||||||
@@ -31,7 +29,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Удаляем категорию
|
|
||||||
$stmt = $db->prepare("DELETE FROM categories WHERE category_id = ?");
|
$stmt = $db->prepare("DELETE FROM categories WHERE category_id = ?");
|
||||||
$stmt->execute([$categoryId]);
|
$stmt->execute([$categoryId]);
|
||||||
|
|
||||||
|
|||||||
@@ -150,7 +150,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
$material = trim($_POST['material'] ?? '');
|
$material = trim($_POST['material'] ?? '');
|
||||||
|
|
||||||
if ($category_id <= 0) {
|
if ($category_id <= 0) {
|
||||||
|
|
||||||
$firstCat = $db->query("SELECT category_id FROM categories LIMIT 1")->fetchColumn();
|
$firstCat = $db->query("SELECT category_id FROM categories LIMIT 1")->fetchColumn();
|
||||||
$category_id = $firstCat ?: 1;
|
$category_id = $firstCat ?: 1;
|
||||||
}
|
}
|
||||||
@@ -192,24 +191,18 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
$childCount = $checkChildren->fetchColumn();
|
$childCount = $checkChildren->fetchColumn();
|
||||||
|
|
||||||
if ($productCount > 0) {
|
if ($productCount > 0) {
|
||||||
|
|
||||||
$stmt = $db->prepare("UPDATE categories SET is_active = FALSE WHERE category_id = ?");
|
$stmt = $db->prepare("UPDATE categories SET is_active = FALSE WHERE category_id = ?");
|
||||||
$stmt->execute([$categoryId]);
|
$stmt->execute([$categoryId]);
|
||||||
|
|
||||||
header('Location: index.php?action=categories&message=Категория+скрыта+(содержит+товары)');
|
header('Location: index.php?action=categories&message=Категория+скрыта+(содержит+товары)');
|
||||||
exit();
|
exit();
|
||||||
} elseif ($childCount > 0) {
|
} elseif ($childCount > 0) {
|
||||||
|
|
||||||
$stmt = $db->prepare("UPDATE categories SET is_active = FALSE WHERE category_id = ?");
|
$stmt = $db->prepare("UPDATE categories SET is_active = FALSE WHERE category_id = ?");
|
||||||
$stmt->execute([$categoryId]);
|
$stmt->execute([$categoryId]);
|
||||||
|
|
||||||
header('Location: index.php?action=categories&message=Категория+скрыта+(имеет+дочерние+категории)');
|
header('Location: index.php?action=categories&message=Категория+скрыта+(имеет+дочерние+категории)');
|
||||||
exit();
|
exit();
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
$stmt = $db->prepare("DELETE FROM categories WHERE category_id = ?");
|
$stmt = $db->prepare("DELETE FROM categories WHERE category_id = ?");
|
||||||
$stmt->execute([$categoryId]);
|
$stmt->execute([$categoryId]);
|
||||||
|
|
||||||
header('Location: index.php?action=categories&message=Категория+удалена');
|
header('Location: index.php?action=categories&message=Категория+удалена');
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
@@ -224,7 +217,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
$stats = [
|
$stats = [
|
||||||
'total_products' => $db->query("SELECT COUNT(*) FROM products")->fetchColumn(),
|
'total_products' => $db->query("SELECT COUNT(*) FROM products")->fetchColumn(),
|
||||||
'active_products' => $db->query("SELECT COUNT(*) FROM products WHERE is_available = TRUE")->fetchColumn(),
|
'active_products' => $db->query("SELECT COUNT(*) FROM products WHERE is_available = TRUE")->fetchColumn(),
|
||||||
@@ -502,13 +494,11 @@ try {
|
|||||||
<td><?= htmlspecialchars($category['name']) ?></td>
|
<td><?= htmlspecialchars($category['name']) ?></td>
|
||||||
<td><?= htmlspecialchars($category['slug']) ?></td>
|
<td><?= htmlspecialchars($category['slug']) ?></td>
|
||||||
<td><?= htmlspecialchars($category['parent_name'] ?? '—') ?></td>
|
<td><?= htmlspecialchars($category['parent_name'] ?? '—') ?></td>
|
||||||
<td><?= $category['product_count'] ?></td>
|
<td><?= $category['product_count'] ?> </td>
|
||||||
<td class="action-buttons">
|
<td class="action-buttons">
|
||||||
|
|
||||||
<a href="index.php?action=edit_category&id=<?= $category['category_id'] ?>" class="btn btn-warning btn-sm">
|
<a href="index.php?action=edit_category&id=<?= $category['category_id'] ?>" class="btn btn-warning btn-sm">
|
||||||
<i class="fas fa-edit"></i> Редактировать
|
<i class="fas fa-edit"></i> Редактировать
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<button type="button" class="btn btn-danger btn-sm delete-category-btn"
|
<button type="button" class="btn btn-danger btn-sm delete-category-btn"
|
||||||
data-id="<?= $category['category_id'] ?>"
|
data-id="<?= $category['category_id'] ?>"
|
||||||
<?= $category['product_count'] > 0 ? 'disabled' : '' ?>>
|
<?= $category['product_count'] > 0 ? 'disabled' : '' ?>>
|
||||||
@@ -752,7 +742,6 @@ try {
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
$('.delete-category-btn').click(function() {
|
$('.delete-category-btn').click(function() {
|
||||||
const categoryId = $(this).data('id');
|
const categoryId = $(this).data('id');
|
||||||
const btn = $(this);
|
const btn = $(this);
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
||||||
let cart = {
|
let cart = {
|
||||||
items: [
|
items: [
|
||||||
{ id: 1, name: 'Кресло OPPORTUNITY', price: 16999, quantity: 1 },
|
{ id: 1, name: 'Кресло OPPORTUNITY', price: 16999, quantity: 1 },
|
||||||
@@ -44,9 +42,7 @@ $(document).ready(function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function validateFullName(name) {
|
function validateFullName(name) {
|
||||||
|
|
||||||
const nameRegex = /^[a-zA-Zа-яА-ЯёЁ\s\-']+$/;
|
const nameRegex = /^[a-zA-Zа-яА-ЯёЁ\s\-']+$/;
|
||||||
|
|
||||||
const words = name.trim().split(/\s+/);
|
const words = name.trim().split(/\s+/);
|
||||||
|
|
||||||
return nameRegex.test(name) && words.length >= 2;
|
return nameRegex.test(name) && words.length >= 2;
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// ===================================
|
|
||||||
// === ПЕРЕМЕННЫЕ И МИКСИНЫ AETERNA ===
|
|
||||||
// ===================================
|
|
||||||
@color-primary: #617365;
|
@color-primary: #617365;
|
||||||
@color-secondary: #D1D1D1;
|
@color-secondary: #D1D1D1;
|
||||||
@color-accent: #453227;
|
@color-accent: #453227;
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
@import "mixins.less";
|
@import "mixins.less";
|
||||||
// =======================
|
|
||||||
// === БАЗОВЫЕ СТИЛИ ===
|
|
||||||
// =======================
|
|
||||||
* {
|
* {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
// ===================================
|
|
||||||
// === ПЕРЕМЕННЫЕ И МИКСИНЫ AETERNA ===
|
|
||||||
// ===================================
|
|
||||||
@color-primary: #617365;
|
@color-primary: #617365;
|
||||||
@color-secondary: #D1D1D1;
|
@color-secondary: #D1D1D1;
|
||||||
@color-accent: #453227;
|
@color-accent: #453227;
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ try {
|
|||||||
$similarStmt->execute([$product['category_id'], $product_id]);
|
$similarStmt->execute([$product['category_id'], $product_id]);
|
||||||
$similarProducts = $similarStmt->fetchAll();
|
$similarProducts = $similarStmt->fetchAll();
|
||||||
|
|
||||||
// Отзывы временно отключены (таблица reviews не существует)
|
|
||||||
$reviews = [];
|
$reviews = [];
|
||||||
|
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
@@ -459,7 +458,6 @@ $(document).ready(function() {
|
|||||||
|
|
||||||
window.deleteProduct = function(productId) {
|
window.deleteProduct = function(productId) {
|
||||||
if (confirm('Вы уверены, что хотите удалить этот товар?')) {
|
if (confirm('Вы уверены, что хотите удалить этот товар?')) {
|
||||||
// Redirect to admin panel for deletion
|
|
||||||
window.location.href = 'admin/index.php?action=products';
|
window.location.href = 'admin/index.php?action=products';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ if (!isset($_SESSION['isLoggedIn']) || $_SESSION['isLoggedIn'] !== true) {
|
|||||||
$user_id = $_SESSION['user_id'] ?? 0;
|
$user_id = $_SESSION['user_id'] ?? 0;
|
||||||
$db = Database::getInstance()->getConnection();
|
$db = Database::getInstance()->getConnection();
|
||||||
|
|
||||||
// Загружаем данные пользователя
|
|
||||||
$user = null;
|
$user = null;
|
||||||
try {
|
try {
|
||||||
$stmt = $db->prepare("SELECT user_id, email, full_name, phone, city FROM users WHERE user_id = ?");
|
$stmt = $db->prepare("SELECT user_id, email, full_name, phone, city FROM users WHERE user_id = ?");
|
||||||
@@ -31,7 +30,6 @@ $update_success = $_SESSION['update_success'] ?? '';
|
|||||||
unset($_SESSION['update_errors']);
|
unset($_SESSION['update_errors']);
|
||||||
unset($_SESSION['update_success']);
|
unset($_SESSION['update_success']);
|
||||||
|
|
||||||
// Обработка обновления профиля
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
$full_name = trim($_POST['fio'] ?? '');
|
$full_name = trim($_POST['fio'] ?? '');
|
||||||
$city = trim($_POST['city'] ?? '');
|
$city = trim($_POST['city'] ?? '');
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
@import "mixins.less";
|
@import "mixins.less";
|
||||||
@import "стили_оформления.less";
|
@import "стили_оформления.less";
|
||||||
// =======================
|
|
||||||
// === БАЗОВЫЕ СТИЛИ ===
|
|
||||||
// =======================
|
|
||||||
* {
|
* {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@@ -52,10 +49,6 @@ p, li, span {
|
|||||||
font-family: @font-main;
|
font-family: @font-main;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =======================
|
|
||||||
// === КОМПОНЕНТЫ ===
|
|
||||||
// =======================
|
|
||||||
|
|
||||||
.logo, .footer-logo {
|
.logo, .footer-logo {
|
||||||
font: bold 32px/1 @font-logo;
|
font: bold 32px/1 @font-logo;
|
||||||
letter-spacing: 2px;
|
letter-spacing: 2px;
|
||||||
|
|||||||
Reference in New Issue
Block a user