From 8bd904af6c1746f5a57c81be13513e48c31f312d Mon Sep 17 00:00:00 2001 From: Vladless Date: Sun, 18 May 2025 00:27:39 +0300 Subject: [PATCH] tariffs view in cluster menu --- assets/schema.sql | 161 +++++++++----------- handlers/admin/clusters/clusters_handler.py | 25 ++- 2 files changed, 95 insertions(+), 91 deletions(-) diff --git a/assets/schema.sql b/assets/schema.sql index bbed31cb..f3c1d063 100644 --- a/assets/schema.sql +++ b/assets/schema.sql @@ -1,16 +1,15 @@ - -CREATE TABLE IF NOT EXISTS users -( +CREATE TABLE IF NOT EXISTS users ( tg_id BIGINT PRIMARY KEY NOT NULL, username TEXT, first_name TEXT, last_name TEXT, language_code TEXT, - is_bot BOOLEAN DEFAULT FALSE, + is_bot BOOLEAN DEFAULT FALSE, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, - balance REAL NOT NULL DEFAULT 0.0, - trial INTEGER NOT NULL DEFAULT 0 + balance REAL NOT NULL DEFAULT 0.0, + trial INTEGER NOT NULL DEFAULT 0, + source_code TEXT REFERENCES tracking_sources (code) ); DO $$ @@ -28,44 +27,43 @@ BEGIN ) THEN ALTER TABLE users ADD COLUMN trial INTEGER NOT NULL DEFAULT 0; END IF; + + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'users' AND column_name = 'source_code' + ) THEN + ALTER TABLE users ADD COLUMN source_code TEXT REFERENCES tracking_sources (code); + END IF; END$$; - -CREATE TABLE IF NOT EXISTS payments -( +CREATE TABLE IF NOT EXISTS payments ( id SERIAL PRIMARY KEY, tg_id BIGINT NOT NULL, amount REAL NOT NULL, payment_system TEXT NOT NULL, - status TEXT DEFAULT 'success', + status TEXT DEFAULT 'success', created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (tg_id) REFERENCES users (tg_id) ); -CREATE TABLE IF NOT EXISTS keys -( +CREATE TABLE IF NOT EXISTS keys ( tg_id BIGINT NOT NULL, client_id TEXT NOT NULL, email TEXT NOT NULL, created_at BIGINT NOT NULL, expiry_time BIGINT NOT NULL, - key TEXT NOT NULL, + key TEXT, server_id TEXT NOT NULL DEFAULT 'cluster1', notified BOOLEAN NOT NULL DEFAULT FALSE, notified_24h BOOLEAN NOT NULL DEFAULT FALSE, + remnawave_link TEXT, + is_frozen BOOLEAN DEFAULT FALSE, + alias TEXT, PRIMARY KEY (tg_id, client_id) ); DO $$ BEGIN - IF EXISTS ( - SELECT 1 - FROM information_schema.columns - WHERE table_name = 'keys' AND column_name = 'key' AND is_nullable = 'NO' - ) THEN - ALTER TABLE keys ALTER COLUMN key DROP NOT NULL; - END IF; - IF NOT EXISTS ( SELECT 1 FROM information_schema.columns WHERE table_name = 'keys' AND column_name = 'remnawave_link' @@ -88,22 +86,20 @@ BEGIN END IF; END$$; -CREATE TABLE IF NOT EXISTS referrals -( +CREATE TABLE IF NOT EXISTS referrals ( referred_tg_id BIGINT PRIMARY KEY NOT NULL, - referrer_tg_id BIGINT NOT NULL, + referrer_tg_id BIGINT NOT NULL, reward_issued BOOLEAN DEFAULT FALSE ); -CREATE TABLE IF NOT EXISTS coupons -( +CREATE TABLE IF NOT EXISTS coupons ( id SERIAL PRIMARY KEY, code TEXT UNIQUE NOT NULL, - amount INTEGER NOT NULL, + amount INTEGER NOT NULL, days INTEGER CHECK (days > 0 OR days IS NULL), - usage_limit INTEGER NOT NULL DEFAULT 1, - usage_count INTEGER NOT NULL DEFAULT 0, - is_used BOOLEAN NOT NULL DEFAULT FALSE + usage_limit INTEGER NOT NULL DEFAULT 1, + usage_count INTEGER NOT NULL DEFAULT 0, + is_used BOOLEAN NOT NULL DEFAULT FALSE ); DO $$ @@ -116,24 +112,21 @@ BEGIN END IF; END$$; -CREATE TABLE IF NOT EXISTS coupon_usages -( - coupon_id INTEGER NOT NULL REFERENCES coupons (id) ON DELETE CASCADE, - user_id BIGINT NOT NULL, +CREATE TABLE IF NOT EXISTS coupon_usages ( + coupon_id INTEGER NOT NULL REFERENCES coupons (id) ON DELETE CASCADE, + user_id BIGINT NOT NULL, used_at TIMESTAMP NOT NULL DEFAULT NOW(), PRIMARY KEY (coupon_id, user_id) ); -CREATE TABLE IF NOT EXISTS notifications -( - tg_id BIGINT NOT NULL, +CREATE TABLE IF NOT EXISTS notifications ( + tg_id BIGINT NOT NULL, last_notification_time TIMESTAMP NOT NULL DEFAULT NOW(), - notification_type TEXT NOT NULL, + notification_type TEXT NOT NULL, PRIMARY KEY (tg_id, notification_type) ); -CREATE TABLE IF NOT EXISTS servers -( +CREATE TABLE IF NOT EXISTS servers ( id SERIAL PRIMARY KEY, cluster_name TEXT NOT NULL, server_name TEXT NOT NULL, @@ -143,28 +136,19 @@ CREATE TABLE IF NOT EXISTS servers panel_type TEXT NOT NULL DEFAULT '3x-ui', enabled BOOLEAN NOT NULL DEFAULT TRUE, max_keys INTEGER, - UNIQUE (cluster_name, server_name) + tariff_group TEXT, + UNIQUE (cluster_name, server_name) ); -ALTER TABLE servers ADD COLUMN IF NOT EXISTS panel_type TEXT NOT NULL DEFAULT '3x-ui'; - ALTER TABLE servers - ALTER COLUMN subscription_url DROP NOT NULL; - ALTER TABLE servers - ADD COLUMN IF NOT EXISTS enabled BOOLEAN NOT NULL DEFAULT TRUE; - ALTER TABLE servers ADD COLUMN IF NOT EXISTS max_keys INTEGER; - -CREATE TABLE IF NOT EXISTS gifts -( - gift_id TEXT PRIMARY KEY NOT NULL, - sender_tg_id BIGINT NOT NULL, - selected_months INTEGER NOT NULL, - expiry_time TIMESTAMP WITH TIME ZONE NOT NULL, - gift_link TEXT NOT NULL, - created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, - is_used BOOLEAN NOT NULL DEFAULT FALSE, - recipient_tg_id BIGINT, - CONSTRAINT fk_sender FOREIGN KEY (sender_tg_id) REFERENCES users (tg_id), - CONSTRAINT fk_recipient FOREIGN KEY (recipient_tg_id) REFERENCES users (tg_id) +CREATE TABLE IF NOT EXISTS gifts ( + gift_id TEXT PRIMARY KEY NOT NULL, + sender_tg_id BIGINT NOT NULL REFERENCES users (tg_id), + selected_months INTEGER NOT NULL, + expiry_time TIMESTAMP WITH TIME ZONE NOT NULL, + gift_link TEXT NOT NULL, + created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, + is_used BOOLEAN NOT NULL DEFAULT FALSE, + recipient_tg_id BIGINT REFERENCES users (tg_id) ); CREATE TABLE IF NOT EXISTS temporary_data ( @@ -175,41 +159,42 @@ CREATE TABLE IF NOT EXISTS temporary_data ( ); CREATE TABLE IF NOT EXISTS blocked_users ( - tg_id BIGINT PRIMARY KEY, - blocked_at TIMESTAMP DEFAULT NOW() + tg_id BIGINT PRIMARY KEY, + blocked_at TIMESTAMP DEFAULT NOW() ); - CREATE TABLE IF NOT EXISTS tracking_sources ( - id SERIAL PRIMARY KEY, - code TEXT UNIQUE NOT NULL, - type TEXT NOT NULL, - name TEXT NOT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - created_by BIGINT, - is_active BOOLEAN DEFAULT TRUE + id SERIAL PRIMARY KEY, + code TEXT UNIQUE NOT NULL, + type TEXT NOT NULL, + name TEXT NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + created_by BIGINT, + is_active BOOLEAN DEFAULT TRUE ); - -ALTER TABLE users ADD COLUMN IF NOT EXISTS source_code TEXT REFERENCES tracking_sources (code); - CREATE TABLE IF NOT EXISTS tariffs ( - id SERIAL PRIMARY KEY, - name TEXT NOT NULL, - group_code TEXT NOT NULL, - duration_days INTEGER NOT NULL CHECK (duration_days > 0), - price_rub INTEGER NOT NULL CHECK (price_rub >= 0), - traffic_limit BIGINT, - device_limit INTEGER, - is_active BOOLEAN NOT NULL DEFAULT TRUE, - created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() + id SERIAL PRIMARY KEY, + name TEXT NOT NULL, + group_code TEXT NOT NULL, + duration_days INTEGER NOT NULL CHECK (duration_days > 0), + price_rub INTEGER NOT NULL CHECK (price_rub >= 0), + traffic_limit BIGINT, + device_limit INTEGER, + is_active BOOLEAN NOT NULL DEFAULT TRUE, + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -ALTER TABLE servers ADD COLUMN IF NOT EXISTS tariff_group TEXT; -ALTER TABLE tariffs -ADD COLUMN IF NOT EXISTS device_limit INTEGER; - +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'tariffs' AND column_name = 'device_limit' + ) THEN + ALTER TABLE tariffs ADD COLUMN device_limit INTEGER; + END IF; +END$$; DO $$ BEGIN @@ -227,4 +212,4 @@ BEGIN EXECUTE 'DROP TABLE connections'; END IF; -END$$; \ No newline at end of file +END$$; diff --git a/handlers/admin/clusters/clusters_handler.py b/handlers/admin/clusters/clusters_handler.py index 36e5429d..70063fbf 100644 --- a/handlers/admin/clusters/clusters_handler.py +++ b/handlers/admin/clusters/clusters_handler.py @@ -242,10 +242,15 @@ async def handle_panel_type_selection( inbound_id = user_data.get("inbound_id") conn = await asyncpg.connect(DATABASE_URL) + tariff_group = await conn.fetchval( + "SELECT tariff_group FROM servers WHERE cluster_name = $1 LIMIT 1", + cluster_name, + ) + await conn.execute( """ - INSERT INTO servers (cluster_name, server_name, api_url, subscription_url, inbound_id, panel_type) - VALUES ($1, $2, $3, $4, $5, $6) + INSERT INTO servers (cluster_name, server_name, api_url, subscription_url, inbound_id, panel_type, tariff_group) + VALUES ($1, $2, $3, $4, $5, $6, $7) """, cluster_name, server_name, @@ -253,7 +258,9 @@ async def handle_panel_type_selection( subscription_url, inbound_id, panel_type, + tariff_group, ) + await conn.close() await callback_query.message.edit_text( @@ -269,8 +276,20 @@ async def handle_clusters_manage( ): cluster_name = callback_data.data + row = await session.fetchrow( + "SELECT tariff_group FROM servers WHERE cluster_name = $1 AND tariff_group IS NOT NULL LIMIT 1", + cluster_name, + ) + + tariff_group = row["tariff_group"] if row else "—" + + text = ( + f"🔧 Управление кластером {cluster_name}\n\n" + f"📁 Тарифная группа: {tariff_group}\n" + ) + await callback_query.message.edit_text( - text=f"🔧 Управление кластером {cluster_name}", + text=text, reply_markup=build_cluster_management_kb(cluster_name), )