From bd905e997c18a7a7ea312404937791796d3fa45e Mon Sep 17 00:00:00 2001 From: zerosaturation Date: Mon, 25 May 2026 11:31:44 +0800 Subject: [PATCH] feat: add asset level system database migration Co-Authored-By: Claude Opus 4.7 --- .../2026-05-25_create_asset_level_tables.sql | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 backend/docs/migrations/2026-05-25_create_asset_level_tables.sql diff --git a/backend/docs/migrations/2026-05-25_create_asset_level_tables.sql b/backend/docs/migrations/2026-05-25_create_asset_level_tables.sql new file mode 100644 index 0000000..2db16e3 --- /dev/null +++ b/backend/docs/migrations/2026-05-25_create_asset_level_tables.sql @@ -0,0 +1,91 @@ +-- 藏品等级配置表 +CREATE TABLE IF NOT EXISTS asset_levels ( + id BIGSERIAL PRIMARY KEY, + level VARCHAR(10) NOT NULL UNIQUE, + level_order INT NOT NULL, + hourly_revenue INT NOT NULL, + require_hours INT NOT NULL, + require_likes INT NOT NULL, + is_initial BOOLEAN DEFAULT FALSE, + created_at BIGINT NOT NULL, + updated_at BIGINT NOT NULL +); + +-- 藏品等级记录表 +CREATE TABLE IF NOT EXISTS asset_level_records ( + id BIGSERIAL PRIMARY KEY, + asset_id BIGINT NOT NULL UNIQUE, + current_level VARCHAR(10) NOT NULL DEFAULT 'N', + season_exhibition_hours INT NOT NULL DEFAULT 0, + season_likes INT NOT NULL DEFAULT 0, + lifetime_exhibition_hours INT NOT NULL DEFAULT 0, + lifetime_likes INT NOT NULL DEFAULT 0, + season_id VARCHAR(50), + updated_at BIGINT NOT NULL +); + +CREATE INDEX IF NOT EXISTS idx_asset_level_season ON asset_level_records(season_id); +CREATE INDEX IF NOT EXISTS idx_asset_level_current_level ON asset_level_records(current_level); + +-- 藏品等级变化日志表 +CREATE TABLE IF NOT EXISTS asset_level_change_logs ( + id BIGSERIAL PRIMARY KEY, + asset_id BIGINT NOT NULL, + from_level VARCHAR(10), + to_level VARCHAR(10) NOT NULL, + trigger_type VARCHAR(20) NOT NULL, + trigger_hours INT DEFAULT 0, + trigger_likes INT DEFAULT 0, + change_reason VARCHAR(255), + created_at BIGINT NOT NULL +); + +CREATE INDEX IF NOT EXISTS idx_asset_level_log_asset ON asset_level_change_logs(asset_id); +CREATE INDEX IF NOT EXISTS idx_asset_level_log_created ON asset_level_change_logs(created_at DESC); + +-- 赛季配置表 +CREATE TABLE IF NOT EXISTS seasons ( + id VARCHAR(50) PRIMARY KEY, + name VARCHAR(100) NOT NULL, + duration_days INT NOT NULL DEFAULT 84, + start_time BIGINT NOT NULL, + end_time BIGINT NOT NULL, + reset_strategy VARCHAR(20) DEFAULT 'percentage_decay', + reset_level BOOLEAN DEFAULT TRUE, + status VARCHAR(20) DEFAULT 'active', + created_at BIGINT NOT NULL, + updated_at BIGINT NOT NULL +); + +-- 赛季降序百分比配置表 +CREATE TABLE IF NOT EXISTS season_decay_config ( + id BIGSERIAL PRIMARY KEY, + season_id VARCHAR(50) NOT NULL, + level VARCHAR(10) NOT NULL, + preserve_percent INT NOT NULL DEFAULT 100, + updated_at BIGINT NOT NULL, + CONSTRAINT uk_season_level UNIQUE (season_id, level) +); + +-- 初始化藏品等级配置数据 +INSERT INTO asset_levels (level, level_order, hourly_revenue, require_hours, require_likes, is_initial, created_at, updated_at) VALUES +('N', 1, 5, 0, 0, TRUE, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000), ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)), +('R', 2, 7, 24, 20, FALSE, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000), ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)), +('SR', 3, 12, 120, 500, FALSE, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000), ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)), +('SSR', 4, 18, 360, 10000, FALSE, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000), ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)), +('UR', 5, 30, 720, 100000, FALSE, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000), ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)) +ON CONFLICT (level) DO NOTHING; + +-- 初始化赛季配置数据 +INSERT INTO seasons (id, name, duration_days, start_time, end_time, reset_strategy, reset_level, status, created_at, updated_at) VALUES +('season_1', '第一赛季', 84, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000), ROUND(EXTRACT(EPOCH FROM NOW()) * 1000) + 86400000 * 84, 'percentage_decay', TRUE, 'active', ROUND(EXTRACT(EPOCH FROM NOW()) * 1000), ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)) +ON CONFLICT (id) DO NOTHING; + +-- 初始化赛季降序百分比配置 +INSERT INTO season_decay_config (season_id, level, preserve_percent, updated_at) VALUES +('season_1', 'N', 100, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)), +('season_1', 'R', 80, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)), +('season_1', 'SR', 70, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)), +('season_1', 'SSR', 60, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)), +('season_1', 'UR', 50, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)) +ON CONFLICT (season_id, level) DO NOTHING; \ No newline at end of file