279 lines
12 KiB
SQL
279 lines
12 KiB
SQL
-- ============================================================
|
||
-- 经济系统建表脚本
|
||
-- 执行方式: psql -h <host> -U <user> -d <db> -f backend/scripts/20260513_economic_system.sql
|
||
-- 创建日期: 2026-05-13
|
||
-- 说明: 本脚本用于初始化经济系统相关的表和配置
|
||
-- - fan_profiles 表新增字段: revenue_boost_bps, like_bet_count
|
||
-- - 铸造消耗配置、用户铸爱累计
|
||
-- - 等级阈值、升级奖励配置
|
||
-- - 水晶/游戏币流水表
|
||
-- ============================================================
|
||
|
||
-- 1. Add revenue_boost_bps column to fan_profiles (if not exists)
|
||
DO $$
|
||
BEGIN
|
||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'fan_profiles' AND column_name = 'revenue_boost_bps') THEN
|
||
ALTER TABLE fan_profiles ADD COLUMN revenue_boost_bps INT NOT NULL DEFAULT 0;
|
||
END IF;
|
||
END $$;
|
||
|
||
-- 1.2 Add like_bet_count column to fan_profiles (if not exists)
|
||
DO $$
|
||
BEGIN
|
||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'fan_profiles' AND column_name = 'like_bet_count') THEN
|
||
ALTER TABLE fan_profiles ADD COLUMN like_bet_count INT NOT NULL DEFAULT 0;
|
||
END IF;
|
||
END $$;
|
||
|
||
-- 2. 铸造消耗配置表
|
||
CREATE TABLE IF NOT EXISTS mint_cost_config (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
mint_count INT NOT NULL UNIQUE,
|
||
cost_crystal BIGINT NOT NULL,
|
||
probability BIGINT DEFAULT 0,
|
||
reward_type VARCHAR(50) DEFAULT NULL,
|
||
reward_value BIGINT DEFAULT 0,
|
||
description VARCHAR(255),
|
||
updated_at BIGINT NOT NULL
|
||
);
|
||
COMMENT ON TABLE mint_cost_config IS '铸造消耗配置表,记录每次铸造的水晶消耗和保底概率';
|
||
|
||
-- 初始数据
|
||
INSERT INTO mint_cost_config (mint_count, cost_crystal, probability, reward_type, reward_value, description, updated_at) VALUES
|
||
(1, 2, 0, NULL, 0, '第1次铸造', ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(2, 4, 0, NULL, 0, '第2次铸造', ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(3, 8, 0, NULL, 0, '第3次铸造', ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(4, 16, 0, NULL, 0, '第4次铸造', ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(5, 32, 0, NULL, 0, '第5次铸造', ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(6, 64, 0, NULL, 0, '第6次铸造', ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(7, 128, 0, NULL, 0, '第7次铸造', ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(8, 256, 0, NULL, 0, '第8次铸造', ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(9, 512, 20, '收益提升', 500, '20%概率,获得500 bps(+5%)永久收益提升(小保底)', ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(10, 1024, 100, '收益提升', 500, '100%概率,获得500 bps(+5%)永久收益提升(大保底)', ROUND(EXTRACT(EPOCH FROM NOW()) * 1000))
|
||
ON CONFLICT (mint_count) DO NOTHING;
|
||
|
||
-- 3. 用户铸爱累计表
|
||
CREATE TABLE IF NOT EXISTS user_mint_count (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
user_id BIGINT NOT NULL,
|
||
star_id BIGINT NOT NULL,
|
||
mint_count INT NOT NULL DEFAULT 0,
|
||
revenue_boost_bps INT NOT NULL DEFAULT 0,
|
||
updated_at BIGINT NOT NULL,
|
||
CONSTRAINT uk_user_mint_star UNIQUE (user_id, star_id)
|
||
);
|
||
COMMENT ON TABLE user_mint_count IS '用户铸爱累计表,记录用户累计铸造次数和永久收益提升基点';
|
||
|
||
-- 4. 等级阈值配置表
|
||
CREATE TABLE IF NOT EXISTS level_thresholds (
|
||
level INT PRIMARY KEY,
|
||
max_exhibition_hours BIGINT NOT NULL,
|
||
like_bet_count INT NOT NULL,
|
||
description VARCHAR(100)
|
||
);
|
||
COMMENT ON TABLE level_thresholds IS '等级阈值配置表,记录升级到每个等级需要的累计上架时长和点赞押注次数';
|
||
|
||
-- 初始数据(20级满级)
|
||
INSERT INTO level_thresholds (level, max_exhibition_hours, like_bet_count, description) VALUES
|
||
(1, 0, 0, '1级新手'),
|
||
(2, 6, 6, '2级粉丝'),
|
||
(3, 12, 7, '3级真爱'),
|
||
(4, 18, 8, '4级铁粉'),
|
||
(5, 24, 9, '5级钻石粉'),
|
||
(6, 30, 9, '6级钻石粉'),
|
||
(7, 36, 10, '7级钻石粉'),
|
||
(8, 42, 11, '8级钻石粉'),
|
||
(9, 48, 12, '9级钻石粉'),
|
||
(10, 54, 13, '10级钻石粉'),
|
||
(11, 60, 13, '11级钻石粉'),
|
||
(12, 66, 13, '12级钻石粉'),
|
||
(13, 72, 14, '13级钻石粉'),
|
||
(14, 78, 15, '14级钻石粉'),
|
||
(15, 84, 16, '15级钻石粉'),
|
||
(16, 90, 16, '16级钻石粉'),
|
||
(17, 96, 17, '17级钻石粉'),
|
||
(18, 102, 18, '18级钻石粉'),
|
||
(19, 108, 19, '19级钻石粉'),
|
||
(20, 114, 20, '20级终极粉')
|
||
ON CONFLICT (level) DO NOTHING;
|
||
|
||
-- 5. 用户累计上架时长表
|
||
CREATE TABLE IF NOT EXISTS user_exhibition_hours (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
user_id BIGINT NOT NULL,
|
||
star_id BIGINT NOT NULL,
|
||
total_exhibition_hours BIGINT NOT NULL DEFAULT 0,
|
||
updated_at BIGINT NOT NULL,
|
||
CONSTRAINT uk_exhibition_user_star UNIQUE (user_id, star_id)
|
||
);
|
||
COMMENT ON TABLE user_exhibition_hours IS '用户累计上架时长表,记录用户累计上架时长';
|
||
|
||
-- 6. 等级上限配置表
|
||
CREATE TABLE IF NOT EXISTS level_cap_config (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
max_level INT NOT NULL DEFAULT 20,
|
||
updated_at BIGINT NOT NULL
|
||
);
|
||
COMMENT ON TABLE level_cap_config IS '等级上限配置表,记录最高等级';
|
||
|
||
INSERT INTO level_cap_config (max_level, updated_at) VALUES (20, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000))
|
||
ON CONFLICT DO NOTHING;
|
||
|
||
-- 7. 等级升级条件配置表(21级+)
|
||
CREATE TABLE IF NOT EXISTS level_upgrade_conditions (
|
||
level INT PRIMARY KEY,
|
||
require_total_hours BIGINT NOT NULL,
|
||
require_dazi_level INT DEFAULT 0,
|
||
description VARCHAR(100),
|
||
updated_at BIGINT NOT NULL
|
||
);
|
||
COMMENT ON TABLE level_upgrade_conditions IS '等级升级条件配置表,记录21级及以上的升级条件';
|
||
|
||
-- 8. 升级奖励配置表
|
||
CREATE TABLE IF NOT EXISTS level_up_reward_config (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
level INT NOT NULL,
|
||
reward_type VARCHAR(50) NOT NULL,
|
||
reward_value BIGINT NOT NULL DEFAULT 0,
|
||
is_enabled BOOLEAN DEFAULT true,
|
||
updated_at BIGINT NOT NULL,
|
||
CONSTRAINT uk_level_reward_type UNIQUE (level, reward_type)
|
||
);
|
||
COMMENT ON TABLE level_up_reward_config IS '升级奖励配置表,记录升级时发放的奖励类型和数值';
|
||
|
||
-- 初始数据(21级示例,后续可扩展更多等级)
|
||
INSERT INTO level_upgrade_conditions (level, require_total_hours, require_dazi_level, description, updated_at) VALUES
|
||
(21, 120, 21, '21级:总时长120h + 搭子21级', ROUND(EXTRACT(EPOCH FROM NOW()) * 1000))
|
||
ON CONFLICT (level) DO NOTHING;
|
||
|
||
-- 8. 升级奖励配置表
|
||
CREATE TABLE IF NOT EXISTS level_up_reward_config (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
level INT NOT NULL,
|
||
reward_type VARCHAR(50) NOT NULL,
|
||
reward_value BIGINT NOT NULL DEFAULT 0,
|
||
is_enabled BOOLEAN DEFAULT true,
|
||
updated_at BIGINT NOT NULL,
|
||
CONSTRAINT uk_level_reward_type UNIQUE (level, reward_type)
|
||
);
|
||
|
||
-- 初始数据示例
|
||
INSERT INTO level_up_reward_config (level, reward_type, reward_value, is_enabled, updated_at) VALUES
|
||
(2, 'crystal', 10, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(2, 'like_bet_count', 1, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(3, 'crystal', 20, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(3, 'like_bet_count', 1, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(4, 'crystal', 30, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(4, 'like_bet_count', 1, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(5, 'crystal', 50, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(5, 'like_bet_count', 1, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(6, 'crystal', 80, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(7, 'crystal', 120, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(8, 'crystal', 180, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(9, 'crystal', 280, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(10, 'crystal', 500, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(11, 'crystal', 500, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(12, 'crystal', 500, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(13, 'crystal', 500, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(14, 'crystal', 500, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(15, 'crystal', 500, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(16, 'crystal', 500, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(17, 'crystal', 500, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(18, 'crystal', 500, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(19, 'crystal', 500, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(20, 'crystal', 500, true, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000))
|
||
ON CONFLICT (level, reward_type) DO NOTHING;
|
||
|
||
-- 9. 搭子等级阈值配置表(预留)
|
||
CREATE TABLE IF NOT EXISTS dazi_level_thresholds (
|
||
level INT PRIMARY KEY,
|
||
upgrade_condition VARCHAR(100),
|
||
condition_param INT DEFAULT 0,
|
||
description VARCHAR(100)
|
||
);
|
||
COMMENT ON TABLE dazi_level_thresholds IS '搭子等级阈值配置表(预留)';
|
||
|
||
-- 10. 用户搭子等级表(预留)
|
||
CREATE TABLE IF NOT EXISTS user_dazi_level (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
user_id BIGINT NOT NULL,
|
||
star_id BIGINT NOT NULL,
|
||
dazi_level INT NOT NULL DEFAULT 1,
|
||
updated_at BIGINT NOT NULL,
|
||
CONSTRAINT uk_dazi_user_star UNIQUE (user_id, star_id)
|
||
);
|
||
COMMENT ON TABLE user_dazi_level IS '用户搭子等级表(预留)';
|
||
|
||
-- 11. 水晶交易流水表(预留)
|
||
CREATE TABLE IF NOT EXISTS crystal_transaction_records (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
user_id BIGINT NOT NULL,
|
||
star_id BIGINT NOT NULL,
|
||
change_type VARCHAR(30) NOT NULL,
|
||
delta BIGINT NOT NULL,
|
||
balance_before BIGINT NOT NULL,
|
||
balance_after BIGINT NOT NULL,
|
||
source_id VARCHAR(100),
|
||
description VARCHAR(255),
|
||
created_at BIGINT NOT NULL
|
||
);
|
||
COMMENT ON TABLE crystal_transaction_records IS '水晶交易流水表,记录水晶的收支明细(复式记账)';
|
||
|
||
CREATE INDEX IF NOT EXISTS ix_crystal_tx_user_star ON crystal_transaction_records(user_id, star_id);
|
||
CREATE INDEX IF NOT EXISTS ix_crystal_tx_created ON crystal_transaction_records(created_at DESC);
|
||
CREATE INDEX IF NOT EXISTS ix_crystal_tx_change_type ON crystal_transaction_records(change_type);
|
||
|
||
-- 12. 游戏币交易流水表(预留)
|
||
CREATE TABLE IF NOT EXISTS coin_transaction_records (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
user_id BIGINT NOT NULL,
|
||
star_id BIGINT NOT NULL,
|
||
change_type VARCHAR(30) NOT NULL,
|
||
delta BIGINT NOT NULL,
|
||
balance_before BIGINT NOT NULL,
|
||
balance_after BIGINT NOT NULL,
|
||
source_id VARCHAR(100),
|
||
description VARCHAR(255),
|
||
created_at BIGINT NOT NULL
|
||
);
|
||
COMMENT ON TABLE coin_transaction_records IS '游戏币交易流水表(预留)';
|
||
|
||
CREATE INDEX IF NOT EXISTS ix_coin_tx_user_star ON coin_transaction_records(user_id, star_id);
|
||
CREATE INDEX IF NOT EXISTS ix_coin_tx_created ON coin_transaction_records(created_at DESC);
|
||
|
||
-- 13. 铸造奖励配置表(预留)
|
||
CREATE TABLE IF NOT EXISTS mint_reward_config (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
star_id BIGINT NOT NULL UNIQUE,
|
||
base_reward BIGINT NOT NULL DEFAULT 0,
|
||
is_enabled BOOLEAN DEFAULT true,
|
||
updated_at BIGINT NOT NULL
|
||
);
|
||
COMMENT ON TABLE mint_reward_config IS '铸造奖励配置表(预留),记录每个明星的铸造基础奖励';
|
||
|
||
-- 初始数据(0=全服默认)
|
||
INSERT INTO mint_reward_config (star_id, base_reward, is_enabled, updated_at) VALUES (0, 0, false, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000))
|
||
ON CONFLICT (star_id) DO NOTHING;
|
||
|
||
-- 14. 铸造阶梯奖励配置表(预留)
|
||
CREATE TABLE IF NOT EXISTS mint_milestone_config (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
star_id BIGINT NOT NULL,
|
||
milestone_count INT NOT NULL,
|
||
bonus_reward BIGINT NOT NULL,
|
||
created_at BIGINT NOT NULL,
|
||
CONSTRAINT uk_milestone_star_count UNIQUE (star_id, milestone_count)
|
||
);
|
||
COMMENT ON TABLE mint_milestone_config IS '铸造阶梯奖励配置表(预留),记录铸造里程碑奖励';
|
||
|
||
-- 初始数据示例
|
||
INSERT INTO mint_milestone_config (star_id, milestone_count, bonus_reward, created_at) VALUES
|
||
(0, 10, 5, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(0, 30, 15, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000)),
|
||
(0, 100, 50, ROUND(EXTRACT(EPOCH FROM NOW()) * 1000))
|
||
ON CONFLICT (star_id, milestone_count) DO NOTHING;
|
||
|
||
-- ============================================================
|
||
-- 完成
|
||
-- ============================================================
|