🎨 UI улучшения: - Уменьшена высота синих панелей с 100vh до 70vh на главной - Добавлен класс .compact (25vh) для всех остальных страниц - Улучшена адаптивность для мобильных устройств - Обновлены все шаблоны с hero секциями 🚀 Инфраструктура: - Автоматическая инициализация базы данных при деплое - Улучшены мокапные данные (больше отзывов, бронирований, сообщений) - Добавлены настройки сайта в базу данных - Создан скрипт автоматического деплоя deploy.sh 📦 Система сборки: - Обновлен .gitignore с полным покрытием файлов - Добавлена папка для загрузок с .gitkeep - Улучшен README с инструкциями по запуску - ES модули для инициализации базы данных 🐛 Исправления: - Совместимость с ES модулями в Node.js - Правильная обработка ошибок инициализации БД - Корректные SQL запросы для PostgreSQL
73 lines
3.2 KiB
PL/PgSQL
73 lines
3.2 KiB
PL/PgSQL
-- Система лайков/дизлайков для туров, гидов и статей
|
||
CREATE TABLE ratings (
|
||
id SERIAL PRIMARY KEY,
|
||
user_ip VARCHAR(45) NOT NULL, -- IP адрес для анонимных пользователей
|
||
target_id INTEGER NOT NULL,
|
||
target_type VARCHAR(20) NOT NULL CHECK (target_type IN ('route', 'guide', 'article')),
|
||
rating INTEGER NOT NULL CHECK (rating IN (1, -1)), -- 1 = лайк, -1 = дизлайк
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
UNIQUE(user_ip, target_id, target_type) -- Один пользователь - один голос за объект
|
||
);
|
||
|
||
-- График работы гидов
|
||
CREATE TABLE guide_schedules (
|
||
id SERIAL PRIMARY KEY,
|
||
guide_id INTEGER NOT NULL REFERENCES guides(id) ON DELETE CASCADE,
|
||
monday BOOLEAN DEFAULT true,
|
||
tuesday BOOLEAN DEFAULT true,
|
||
wednesday BOOLEAN DEFAULT true,
|
||
thursday BOOLEAN DEFAULT true,
|
||
friday BOOLEAN DEFAULT true,
|
||
saturday BOOLEAN DEFAULT false,
|
||
sunday BOOLEAN DEFAULT false,
|
||
start_time TIME DEFAULT '09:00',
|
||
end_time TIME DEFAULT '18:00',
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
UNIQUE(guide_id)
|
||
);
|
||
|
||
-- Выходные дни (общие и индивидуальные)
|
||
CREATE TABLE holidays (
|
||
id SERIAL PRIMARY KEY,
|
||
date DATE NOT NULL,
|
||
title VARCHAR(255) NOT NULL,
|
||
type VARCHAR(20) NOT NULL CHECK (type IN ('public', 'guide_personal')), -- публичный или персональный
|
||
guide_id INTEGER REFERENCES guides(id) ON DELETE CASCADE, -- NULL для публичных выходных
|
||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||
UNIQUE(date, guide_id) -- Один выходной день для одного гида
|
||
);
|
||
|
||
-- Обновляем таблицу бронирований для связи с гидом
|
||
ALTER TABLE bookings ADD COLUMN guide_id INTEGER REFERENCES guides(id);
|
||
ALTER TABLE bookings ADD COLUMN route_id INTEGER REFERENCES routes(id);
|
||
|
||
-- Добавляем индексы для производительности
|
||
CREATE INDEX idx_ratings_target ON ratings(target_type, target_id);
|
||
CREATE INDEX idx_ratings_user_ip ON ratings(user_ip);
|
||
CREATE INDEX idx_bookings_date ON bookings(preferred_date);
|
||
CREATE INDEX idx_bookings_guide ON bookings(guide_id);
|
||
CREATE INDEX idx_holidays_date ON holidays(date);
|
||
|
||
-- Функция для подсчета рейтинга
|
||
CREATE OR REPLACE FUNCTION calculate_rating(target_type_param VARCHAR, target_id_param INTEGER)
|
||
RETURNS TABLE(
|
||
likes_count BIGINT,
|
||
dislikes_count BIGINT,
|
||
total_votes BIGINT,
|
||
rating_percentage NUMERIC(5,2)
|
||
) AS $$
|
||
BEGIN
|
||
RETURN QUERY
|
||
SELECT
|
||
COUNT(CASE WHEN rating = 1 THEN 1 END) as likes_count,
|
||
COUNT(CASE WHEN rating = -1 THEN 1 END) as dislikes_count,
|
||
COUNT(*) as total_votes,
|
||
CASE
|
||
WHEN COUNT(*) = 0 THEN 0
|
||
ELSE ROUND((COUNT(CASE WHEN rating = 1 THEN 1 END)::NUMERIC / COUNT(*)::NUMERIC) * 100, 2)
|
||
END as rating_percentage
|
||
FROM ratings
|
||
WHERE target_type = target_type_param AND target_id = target_id_param;
|
||
END;
|
||
$$ LANGUAGE plpgsql; |