Исправление багов авторизации, корзины и админки
- Исправлено выпадающее меню профиля (hover-баг с margin-top) - Исправлена авторизация: правильные пути к API (api/auth.php) - Исправлены ссылки на админку (admin/index.php вместо admin_panel.php) - Исправлены пути API корзины в catalog.php и checkout.php - Добавлена форма добавления/редактирования товаров в админке - Исправлены кнопки +/- в корзине (улучшена обработка AJAX) - Исправлена регистрация: правильные пути и обработка boolean в PostgreSQL - Добавлена миграция для назначения прав админа пользователю admin@mail.ru - Удален тестовый блок 'Быстрый вход' для неавторизованных пользователей - Улучшена обработка ошибок во всех API-эндпоинтах
This commit is contained in:
73
migrations/001_initial_schema.sql
Normal file
73
migrations/001_initial_schema.sql
Normal file
@@ -0,0 +1,73 @@
|
||||
-- 001_initial_schema.sql
|
||||
-- Создание базовых таблиц для AETERNA
|
||||
|
||||
-- Таблица пользователей
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
user_id SERIAL PRIMARY KEY,
|
||||
email VARCHAR(255) UNIQUE NOT NULL,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
full_name VARCHAR(100) NOT NULL,
|
||||
phone VARCHAR(20),
|
||||
city VARCHAR(100),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
last_login TIMESTAMP,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
is_admin BOOLEAN DEFAULT FALSE
|
||||
);
|
||||
|
||||
-- Таблица категорий
|
||||
CREATE TABLE IF NOT EXISTS categories (
|
||||
category_id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
slug VARCHAR(100) UNIQUE NOT NULL,
|
||||
parent_id INTEGER REFERENCES categories(category_id) ON DELETE SET NULL,
|
||||
description TEXT,
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Таблица подкатегорий
|
||||
CREATE TABLE IF NOT EXISTS subcategories (
|
||||
subcategory_id SERIAL PRIMARY KEY,
|
||||
category_id INTEGER REFERENCES categories(category_id) ON DELETE CASCADE,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
slug VARCHAR(100) UNIQUE NOT NULL,
|
||||
description TEXT,
|
||||
sort_order INTEGER DEFAULT 0,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Таблица товаров
|
||||
CREATE TABLE IF NOT EXISTS products (
|
||||
product_id SERIAL PRIMARY KEY,
|
||||
category_id INTEGER REFERENCES categories(category_id) ON DELETE SET NULL,
|
||||
name VARCHAR(200) NOT NULL,
|
||||
slug VARCHAR(200) UNIQUE NOT NULL,
|
||||
description TEXT,
|
||||
price DECIMAL(10, 2) NOT NULL,
|
||||
old_price DECIMAL(10, 2),
|
||||
sku VARCHAR(50) UNIQUE,
|
||||
stock_quantity INTEGER DEFAULT 0,
|
||||
is_available BOOLEAN DEFAULT TRUE,
|
||||
is_featured BOOLEAN DEFAULT FALSE,
|
||||
rating DECIMAL(3, 2) DEFAULT 0,
|
||||
review_count INTEGER DEFAULT 0,
|
||||
image_url VARCHAR(500),
|
||||
color VARCHAR(50),
|
||||
material VARCHAR(100),
|
||||
card_size VARCHAR(20) DEFAULT 'small',
|
||||
created_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_available ON products(is_available);
|
||||
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_active ON categories(is_active);
|
||||
|
||||
70
migrations/002_add_cart_orders.sql
Normal file
70
migrations/002_add_cart_orders.sql
Normal file
@@ -0,0 +1,70 @@
|
||||
-- 002_add_cart_orders.sql
|
||||
-- Таблицы для корзины и заказов
|
||||
|
||||
-- Таблица корзины
|
||||
CREATE TABLE IF NOT EXISTS cart (
|
||||
cart_id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES users(user_id) ON DELETE CASCADE,
|
||||
product_id INTEGER REFERENCES products(product_id) ON DELETE CASCADE,
|
||||
quantity INTEGER DEFAULT 1 CHECK (quantity > 0),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(user_id, product_id)
|
||||
);
|
||||
|
||||
-- Таблица заказов
|
||||
CREATE TABLE IF NOT EXISTS orders (
|
||||
order_id SERIAL PRIMARY KEY,
|
||||
order_number VARCHAR(50) UNIQUE NOT NULL,
|
||||
user_id INTEGER REFERENCES users(user_id) ON DELETE SET NULL,
|
||||
|
||||
-- Контактная информация
|
||||
customer_name VARCHAR(100) NOT NULL,
|
||||
customer_email VARCHAR(255) NOT NULL,
|
||||
customer_phone VARCHAR(20) NOT NULL,
|
||||
|
||||
-- Адрес доставки
|
||||
delivery_address TEXT NOT NULL,
|
||||
delivery_region VARCHAR(100),
|
||||
postal_code VARCHAR(20),
|
||||
|
||||
-- Способы
|
||||
delivery_method VARCHAR(50) DEFAULT 'courier',
|
||||
payment_method VARCHAR(50) DEFAULT 'card',
|
||||
|
||||
-- Суммы
|
||||
subtotal DECIMAL(10, 2) NOT NULL,
|
||||
discount_amount DECIMAL(10, 2) DEFAULT 0,
|
||||
delivery_price DECIMAL(10, 2) DEFAULT 0,
|
||||
final_amount DECIMAL(10, 2) NOT NULL,
|
||||
|
||||
-- Промокод
|
||||
promo_code VARCHAR(50),
|
||||
|
||||
-- Статус и даты
|
||||
status VARCHAR(30) DEFAULT 'pending',
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
completed_at TIMESTAMP
|
||||
);
|
||||
|
||||
-- Таблица позиций заказа
|
||||
CREATE TABLE IF NOT EXISTS order_items (
|
||||
item_id SERIAL PRIMARY KEY,
|
||||
order_id INTEGER REFERENCES orders(order_id) ON DELETE CASCADE,
|
||||
product_id INTEGER REFERENCES products(product_id) ON DELETE SET NULL,
|
||||
product_name VARCHAR(200) NOT NULL,
|
||||
product_price DECIMAL(10, 2) NOT NULL,
|
||||
quantity INTEGER NOT NULL CHECK (quantity > 0),
|
||||
total_price DECIMAL(10, 2) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Индексы
|
||||
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_status ON orders(status);
|
||||
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);
|
||||
|
||||
57
migrations/003_add_product_fields.sql
Normal file
57
migrations/003_add_product_fields.sql
Normal file
@@ -0,0 +1,57 @@
|
||||
-- 003_add_product_fields.sql
|
||||
-- Добавление дополнительных полей (если таблицы уже существуют)
|
||||
|
||||
-- Добавляем поля в products если их нет
|
||||
DO $$
|
||||
BEGIN
|
||||
-- color
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'products' AND column_name = 'color') THEN
|
||||
ALTER TABLE products ADD COLUMN color VARCHAR(50);
|
||||
END IF;
|
||||
|
||||
-- material
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'products' AND column_name = 'material') THEN
|
||||
ALTER TABLE products ADD COLUMN material VARCHAR(100);
|
||||
END IF;
|
||||
|
||||
-- card_size
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'products' AND column_name = 'card_size') THEN
|
||||
ALTER TABLE products ADD COLUMN card_size VARCHAR(20) DEFAULT 'small';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- Добавляем поля в users если их нет
|
||||
DO $$
|
||||
BEGIN
|
||||
-- city
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'users' AND column_name = 'city') THEN
|
||||
ALTER TABLE users ADD COLUMN city VARCHAR(100);
|
||||
END IF;
|
||||
|
||||
-- last_login
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'users' AND column_name = 'last_login') THEN
|
||||
ALTER TABLE users ADD COLUMN last_login TIMESTAMP;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- Добавляем поля в categories если их нет
|
||||
DO $$
|
||||
BEGIN
|
||||
-- updated_at
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'categories' AND column_name = 'updated_at') THEN
|
||||
ALTER TABLE categories ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||
END IF;
|
||||
|
||||
-- created_at
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'categories' AND column_name = 'created_at') THEN
|
||||
ALTER TABLE categories ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
50
migrations/004_grant_admin_to_admin_mail.sql
Normal file
50
migrations/004_grant_admin_to_admin_mail.sql
Normal file
@@ -0,0 +1,50 @@
|
||||
-- 004_grant_admin_to_admin_mail.sql
|
||||
-- Миграция: Назначение прав администратора пользователю admin@mail.ru
|
||||
|
||||
-- Обновляем пользователя admin@mail.ru, давая ему права администратора
|
||||
UPDATE users
|
||||
SET is_admin = TRUE,
|
||||
is_active = TRUE,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE email = 'admin@mail.ru';
|
||||
|
||||
-- Проверяем результат
|
||||
DO $$
|
||||
DECLARE
|
||||
updated_count INTEGER;
|
||||
user_info RECORD;
|
||||
BEGIN
|
||||
GET DIAGNOSTICS updated_count = ROW_COUNT;
|
||||
|
||||
IF updated_count > 0 THEN
|
||||
-- Получаем информацию об обновленном пользователе
|
||||
SELECT user_id, email, full_name, is_admin, is_active
|
||||
INTO user_info
|
||||
FROM users
|
||||
WHERE email = 'admin@mail.ru';
|
||||
|
||||
RAISE NOTICE 'Пользователь % (ID: %) успешно получил права администратора',
|
||||
user_info.email, user_info.user_id;
|
||||
RAISE NOTICE 'ФИО: %, Админ: %, Активен: %',
|
||||
user_info.full_name, user_info.is_admin, user_info.is_active;
|
||||
ELSE
|
||||
-- Если пользователь не найден, создаем его с правами админа
|
||||
INSERT INTO users (email, password_hash, full_name, phone, city, is_admin, is_active)
|
||||
VALUES (
|
||||
'admin@mail.ru',
|
||||
'$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', -- admin123
|
||||
'Администратор',
|
||||
'+79129991223',
|
||||
'Москва',
|
||||
TRUE,
|
||||
TRUE
|
||||
)
|
||||
ON CONFLICT (email) DO UPDATE
|
||||
SET is_admin = TRUE,
|
||||
is_active = TRUE,
|
||||
updated_at = CURRENT_TIMESTAMP;
|
||||
|
||||
RAISE NOTICE 'Пользователь admin@mail.ru создан/обновлен с правами администратора';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
94
migrations/grant_admin.php
Normal file
94
migrations/grant_admin.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* Быстрый скрипт для назначения прав администратора пользователю admin@mail.ru
|
||||
* Запуск: php migrations/grant_admin.php
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/../config/database.php';
|
||||
|
||||
echo "===========================================\n";
|
||||
echo " Назначение прав администратора\n";
|
||||
echo "===========================================\n\n";
|
||||
|
||||
try {
|
||||
$db = Database::getInstance()->getConnection();
|
||||
echo "[OK] Подключение к базе данных успешно\n\n";
|
||||
|
||||
$email = 'admin@mail.ru';
|
||||
|
||||
// Проверяем, существует ли пользователь
|
||||
$checkStmt = $db->prepare("SELECT user_id, email, full_name, is_admin, is_active FROM users WHERE email = ?");
|
||||
$checkStmt->execute([$email]);
|
||||
$user = $checkStmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($user) {
|
||||
echo "[INFO] Найден пользователь:\n";
|
||||
echo " Email: {$user['email']}\n";
|
||||
echo " ФИО: {$user['full_name']}\n";
|
||||
echo " Админ: " . ($user['is_admin'] ? 'ДА' : 'НЕТ') . "\n";
|
||||
echo " Активен: " . ($user['is_active'] ? 'ДА' : 'НЕТ') . "\n\n";
|
||||
|
||||
if ($user['is_admin']) {
|
||||
echo "[INFO] Пользователь уже имеет права администратора\n";
|
||||
} else {
|
||||
// Обновляем права
|
||||
$updateStmt = $db->prepare("
|
||||
UPDATE users
|
||||
SET is_admin = TRUE,
|
||||
is_active = TRUE,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE email = ?
|
||||
");
|
||||
$updateStmt->execute([$email]);
|
||||
|
||||
echo "[SUCCESS] Права администратора успешно назначены!\n";
|
||||
}
|
||||
} else {
|
||||
echo "[WARN] Пользователь с email $email не найден\n";
|
||||
echo "[INFO] Создаю нового пользователя с правами администратора...\n";
|
||||
|
||||
// Создаем пользователя с правами админа
|
||||
// Пароль по умолчанию: admin123
|
||||
$password_hash = password_hash('admin123', PASSWORD_DEFAULT);
|
||||
|
||||
$insertStmt = $db->prepare("
|
||||
INSERT INTO users (email, password_hash, full_name, phone, city, is_admin, is_active)
|
||||
VALUES (?, ?, ?, ?, ?, CAST(? AS boolean), TRUE)
|
||||
RETURNING user_id
|
||||
");
|
||||
|
||||
$insertStmt->execute([
|
||||
$email,
|
||||
$password_hash,
|
||||
'Администратор',
|
||||
'+79129991223',
|
||||
'Москва',
|
||||
'true'
|
||||
]);
|
||||
|
||||
$user_id = $insertStmt->fetchColumn();
|
||||
echo "[SUCCESS] Пользователь создан с ID: $user_id\n";
|
||||
echo "[INFO] Email: $email\n";
|
||||
echo "[INFO] Пароль по умолчанию: admin123\n";
|
||||
echo "[WARN] Рекомендуется сменить пароль после первого входа!\n";
|
||||
}
|
||||
|
||||
// Проверяем результат
|
||||
$verifyStmt = $db->prepare("SELECT user_id, email, full_name, is_admin, is_active FROM users WHERE email = ?");
|
||||
$verifyStmt->execute([$email]);
|
||||
$finalUser = $verifyStmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
echo "\n===========================================\n";
|
||||
echo " Итоговый статус:\n";
|
||||
echo "===========================================\n";
|
||||
echo " Email: {$finalUser['email']}\n";
|
||||
echo " ФИО: {$finalUser['full_name']}\n";
|
||||
echo " Админ: " . ($finalUser['is_admin'] ? 'ДА ✓' : 'НЕТ ✗') . "\n";
|
||||
echo " Активен: " . ($finalUser['is_active'] ? 'ДА ✓' : 'НЕТ ✗') . "\n";
|
||||
echo "===========================================\n";
|
||||
|
||||
} catch (PDOException $e) {
|
||||
echo "[ERROR] Ошибка: " . $e->getMessage() . "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
109
migrations/migrate.php
Normal file
109
migrations/migrate.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
* Простой раннер миграций для PostgreSQL
|
||||
* Запуск: php migrations/migrate.php
|
||||
*/
|
||||
|
||||
// Подключаем конфиг базы данных
|
||||
require_once __DIR__ . '/../config/database.php';
|
||||
|
||||
echo "===========================================\n";
|
||||
echo " AETERNA - Система миграций базы данных\n";
|
||||
echo "===========================================\n\n";
|
||||
|
||||
try {
|
||||
$db = Database::getInstance()->getConnection();
|
||||
echo "[OK] Подключение к базе данных успешно\n\n";
|
||||
|
||||
// 1. Создаем таблицу для отслеживания миграций
|
||||
$db->exec("
|
||||
CREATE TABLE IF NOT EXISTS migrations (
|
||||
id SERIAL PRIMARY KEY,
|
||||
filename VARCHAR(255) NOT NULL UNIQUE,
|
||||
applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
");
|
||||
echo "[OK] Таблица migrations готова\n";
|
||||
|
||||
// 2. Получаем список уже примененных миграций
|
||||
$stmt = $db->query("SELECT filename FROM migrations ORDER BY filename");
|
||||
$applied = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
||||
echo "[INFO] Уже применено миграций: " . count($applied) . "\n\n";
|
||||
|
||||
// 3. Сканируем папку на SQL-файлы
|
||||
$migrationFiles = glob(__DIR__ . '/*.sql');
|
||||
sort($migrationFiles);
|
||||
|
||||
$newMigrations = 0;
|
||||
|
||||
foreach ($migrationFiles as $file) {
|
||||
$filename = basename($file);
|
||||
|
||||
// Пропускаем seed_data.sql - он запускается отдельно
|
||||
if ($filename === 'seed_data.sql') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Проверяем, была ли миграция уже применена
|
||||
if (in_array($filename, $applied)) {
|
||||
echo "[SKIP] $filename (уже применена)\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Применяем миграцию
|
||||
echo "[RUN] Применяю $filename... ";
|
||||
|
||||
$sql = file_get_contents($file);
|
||||
|
||||
try {
|
||||
$db->exec($sql);
|
||||
|
||||
// Записываем в таблицу миграций
|
||||
$stmt = $db->prepare("INSERT INTO migrations (filename) VALUES (?)");
|
||||
$stmt->execute([$filename]);
|
||||
|
||||
echo "OK\n";
|
||||
$newMigrations++;
|
||||
} catch (PDOException $e) {
|
||||
echo "ОШИБКА!\n";
|
||||
echo " Причина: " . $e->getMessage() . "\n";
|
||||
echo "\n[!] Миграция остановлена из-за ошибки\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
echo "\n-------------------------------------------\n";
|
||||
|
||||
if ($newMigrations > 0) {
|
||||
echo "[SUCCESS] Применено новых миграций: $newMigrations\n";
|
||||
} else {
|
||||
echo "[INFO] Все миграции уже применены\n";
|
||||
}
|
||||
|
||||
// 4. Спрашиваем про seed_data
|
||||
$seedFile = __DIR__ . '/seed_data.sql';
|
||||
if (file_exists($seedFile)) {
|
||||
echo "\n[?] Хотите загрузить начальные данные (seed_data.sql)?\n";
|
||||
echo " Запустите: php migrations/migrate.php --seed\n";
|
||||
|
||||
if (isset($argv[1]) && $argv[1] === '--seed') {
|
||||
echo "\n[RUN] Загружаю seed_data.sql... ";
|
||||
try {
|
||||
$sql = file_get_contents($seedFile);
|
||||
$db->exec($sql);
|
||||
echo "OK\n";
|
||||
} catch (PDOException $e) {
|
||||
echo "ОШИБКА: " . $e->getMessage() . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo "\n===========================================\n";
|
||||
echo " Миграции завершены!\n";
|
||||
echo "===========================================\n";
|
||||
|
||||
} catch (PDOException $e) {
|
||||
echo "[ERROR] Ошибка подключения к БД: " . $e->getMessage() . "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
65
migrations/seed_data.sql
Normal file
65
migrations/seed_data.sql
Normal file
@@ -0,0 +1,65 @@
|
||||
-- seed_data.sql
|
||||
-- Начальные данные для AETERNA
|
||||
|
||||
-- Администратор (пароль: admin123)
|
||||
INSERT INTO users (email, password_hash, full_name, phone, city, is_admin, is_active)
|
||||
VALUES (
|
||||
'admin@aeterna.ru',
|
||||
'$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', -- admin123
|
||||
'Администратор AETERNA',
|
||||
'+79129991223',
|
||||
'Москва',
|
||||
TRUE,
|
||||
TRUE
|
||||
) ON CONFLICT (email) DO NOTHING;
|
||||
|
||||
-- Тестовый пользователь (пароль: user123)
|
||||
INSERT INTO users (email, password_hash, full_name, phone, city, is_admin, is_active)
|
||||
VALUES (
|
||||
'user@test.com',
|
||||
'$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', -- user123
|
||||
'Тестовый Пользователь',
|
||||
'+79111234567',
|
||||
'Санкт-Петербург',
|
||||
FALSE,
|
||||
TRUE
|
||||
) ON CONFLICT (email) DO NOTHING;
|
||||
|
||||
-- Категории
|
||||
INSERT INTO categories (name, slug, description, sort_order, is_active) VALUES
|
||||
('Диваны', 'divany', 'Прямые и угловые диваны для гостиной', 1, TRUE),
|
||||
('Кресла', 'kresla', 'Кресла для гостиной и офиса', 2, TRUE),
|
||||
('Кровати', 'krovati', 'Односпальные и двуспальные кровати', 3, TRUE),
|
||||
('Столы', 'stoly', 'Обеденные и рабочие столы', 4, TRUE),
|
||||
('Стулья', 'stulya', 'Стулья для кухни и офиса', 5, TRUE),
|
||||
('Светильники', 'svetilniki', 'Торшеры, люстры и настольные лампы', 6, TRUE)
|
||||
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
|
||||
(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'),
|
||||
(6, 'Торшер MARCIA', 'torsher-marcia', 'Напольный торшер с регулируемой высотой', 11999, 14999, 'LAMP-MAR-001', 8, TRUE, 'img2/2_2.png', 'Золотой', 'Металл', 'tall'),
|
||||
(6, 'Светильник POLET', 'svetilnik-polet', 'Подвесной светильник для гостиной', 5499, NULL, 'LAMP-POL-001', 20, TRUE, 'img2/4.jpg', 'Белый', 'Стекло', 'wide'),
|
||||
(4, 'Стол NORD', 'stol-nord', 'Обеденный стол в скандинавском стиле', 23999, 28999, 'TABLE-NOR-001', 7, TRUE, 'img2/5_5.png', 'Натуральный', 'Дерево', 'small1'),
|
||||
(1, 'Диван ROYALTY', 'divan-royalty', 'Роскошный угловой диван с велюровой обивкой', 78999, 95999, 'SOFA-ROY-001', 3, TRUE, 'img2/6_6.png', 'Зеленый', 'Велюр', 'wide2'),
|
||||
(2, 'Кресло MINIMAL', 'kreslo-minimal', 'Кресло в минималистичном стиле', 29999, 35999, 'ARM-MIN-001', 10, TRUE, 'img2/7_7.png', 'Бежевый', 'Ткань', 'wide3'),
|
||||
(4, 'Стол LONKI', 'stol-lonki', 'Журнальный столик с мраморной столешницей', 34999, NULL, 'TABLE-LON-001', 12, TRUE, 'img2/8_8.png', 'Белый мрамор', 'Мрамор/Металл', 'wide2_1'),
|
||||
(1, 'Диван HEMMINS', 'divan-hemmins', 'Большой модульный диван для всей семьи', 89999, 110000, 'SOFA-HEM-001', 2, TRUE, 'img2/9_9.png', 'Темно-серый', 'Ткань', 'full-width')
|
||||
ON CONFLICT (slug) DO NOTHING;
|
||||
|
||||
-- Выводим статистику
|
||||
DO $$
|
||||
DECLARE
|
||||
users_count INTEGER;
|
||||
categories_count INTEGER;
|
||||
products_count INTEGER;
|
||||
BEGIN
|
||||
SELECT COUNT(*) INTO users_count FROM users;
|
||||
SELECT COUNT(*) INTO categories_count FROM categories;
|
||||
SELECT COUNT(*) INTO products_count FROM products;
|
||||
|
||||
RAISE NOTICE 'Загружено: % пользователей, % категорий, % товаров',
|
||||
users_count, categories_count, products_count;
|
||||
END $$;
|
||||
|
||||
Reference in New Issue
Block a user