d1/sqlite支持
This commit is contained in:
170
migrations/001_initial_schema.sql
Normal file
170
migrations/001_initial_schema.sql
Normal file
@@ -0,0 +1,170 @@
|
||||
-- ============================================
|
||||
-- MoonTV Plus - Cloudflare D1 数据库结构
|
||||
-- 版本: 1.0.0
|
||||
-- 创建时间: 2026-01-30
|
||||
-- ============================================
|
||||
|
||||
-- 1. 用户表
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
username TEXT PRIMARY KEY,
|
||||
password_hash TEXT NOT NULL,
|
||||
role TEXT NOT NULL CHECK(role IN ('owner', 'admin', 'user')),
|
||||
banned INTEGER DEFAULT 0,
|
||||
tags TEXT, -- JSON array: ["vip", "premium"]
|
||||
oidc_sub TEXT UNIQUE,
|
||||
enabled_apis TEXT, -- JSON array: ["api1", "api2"]
|
||||
created_at INTEGER NOT NULL,
|
||||
playrecord_migrated INTEGER DEFAULT 0,
|
||||
favorite_migrated INTEGER DEFAULT 0,
|
||||
skip_migrated INTEGER DEFAULT 0,
|
||||
last_movie_request_time INTEGER,
|
||||
email TEXT,
|
||||
email_notifications INTEGER DEFAULT 1
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_users_role ON users(role);
|
||||
CREATE INDEX IF NOT EXISTS idx_users_oidc_sub ON users(oidc_sub) WHERE oidc_sub IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_users_created_at ON users(created_at);
|
||||
|
||||
-- 2. 播放记录表
|
||||
CREATE TABLE IF NOT EXISTS play_records (
|
||||
username TEXT NOT NULL,
|
||||
key TEXT NOT NULL, -- format: "source+id" (e.g., "tmdb+12345")
|
||||
title TEXT NOT NULL,
|
||||
source_name TEXT NOT NULL,
|
||||
cover TEXT,
|
||||
year TEXT,
|
||||
episode_index INTEGER NOT NULL,
|
||||
total_episodes INTEGER NOT NULL,
|
||||
play_time INTEGER NOT NULL, -- 播放进度(秒)
|
||||
total_time INTEGER NOT NULL, -- 总时长(秒)
|
||||
save_time INTEGER NOT NULL, -- 保存时间戳
|
||||
search_title TEXT,
|
||||
PRIMARY KEY (username, key),
|
||||
FOREIGN KEY (username) REFERENCES users(username) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_play_records_save_time ON play_records(username, save_time DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_play_records_source ON play_records(username, source_name);
|
||||
|
||||
-- 3. 收藏表
|
||||
CREATE TABLE IF NOT EXISTS favorites (
|
||||
username TEXT NOT NULL,
|
||||
key TEXT NOT NULL, -- format: "source+id"
|
||||
source_name TEXT NOT NULL,
|
||||
total_episodes INTEGER NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
year TEXT,
|
||||
cover TEXT,
|
||||
save_time INTEGER NOT NULL,
|
||||
search_title TEXT,
|
||||
origin TEXT CHECK(origin IN ('vod', 'live')),
|
||||
is_completed INTEGER DEFAULT 0,
|
||||
vod_remarks TEXT,
|
||||
PRIMARY KEY (username, key),
|
||||
FOREIGN KEY (username) REFERENCES users(username) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_favorites_save_time ON favorites(username, save_time DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_favorites_source ON favorites(username, source_name);
|
||||
|
||||
-- 4. 搜索历史表
|
||||
CREATE TABLE IF NOT EXISTS search_history (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT NOT NULL,
|
||||
keyword TEXT NOT NULL,
|
||||
timestamp INTEGER NOT NULL,
|
||||
FOREIGN KEY (username) REFERENCES users(username) ON DELETE CASCADE,
|
||||
UNIQUE(username, keyword)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_search_history_user_time ON search_history(username, timestamp DESC);
|
||||
|
||||
-- 5. 跳过配置表(片头片尾)
|
||||
CREATE TABLE IF NOT EXISTS skip_configs (
|
||||
username TEXT NOT NULL,
|
||||
key TEXT NOT NULL, -- format: "source+id"
|
||||
enable INTEGER NOT NULL DEFAULT 1,
|
||||
intro_time INTEGER NOT NULL DEFAULT 0, -- 片头时长(秒)
|
||||
outro_time INTEGER NOT NULL DEFAULT 0, -- 片尾时长(秒)
|
||||
PRIMARY KEY (username, key),
|
||||
FOREIGN KEY (username) REFERENCES users(username) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- 6. 弹幕过滤配置表
|
||||
CREATE TABLE IF NOT EXISTS danmaku_filter_configs (
|
||||
username TEXT PRIMARY KEY,
|
||||
rules TEXT NOT NULL, -- JSON array: [{"keyword": "xxx", "type": "normal", "enabled": true}]
|
||||
FOREIGN KEY (username) REFERENCES users(username) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- 7. 通知表
|
||||
CREATE TABLE IF NOT EXISTS notifications (
|
||||
id TEXT PRIMARY KEY,
|
||||
username TEXT NOT NULL,
|
||||
type TEXT NOT NULL CHECK(type IN ('favorite_update', 'system', 'announcement', 'movie_request', 'request_fulfilled')),
|
||||
title TEXT NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
timestamp INTEGER NOT NULL,
|
||||
read INTEGER DEFAULT 0,
|
||||
metadata TEXT, -- JSON object
|
||||
FOREIGN KEY (username) REFERENCES users(username) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_notifications_user_time ON notifications(username, timestamp DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_notifications_user_read ON notifications(username, read, timestamp DESC);
|
||||
|
||||
-- 8. 求片请求表
|
||||
CREATE TABLE IF NOT EXISTS movie_requests (
|
||||
id TEXT PRIMARY KEY,
|
||||
tmdb_id INTEGER,
|
||||
title TEXT NOT NULL,
|
||||
year TEXT,
|
||||
media_type TEXT NOT NULL CHECK(media_type IN ('movie', 'tv')),
|
||||
season INTEGER,
|
||||
poster TEXT,
|
||||
overview TEXT,
|
||||
requested_by TEXT NOT NULL, -- JSON array: ["user1", "user2"]
|
||||
request_count INTEGER NOT NULL DEFAULT 1,
|
||||
status TEXT NOT NULL CHECK(status IN ('pending', 'fulfilled')) DEFAULT 'pending',
|
||||
created_at INTEGER NOT NULL,
|
||||
updated_at INTEGER NOT NULL,
|
||||
fulfilled_at INTEGER,
|
||||
fulfilled_source TEXT,
|
||||
fulfilled_id TEXT
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_movie_requests_status ON movie_requests(status, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_movie_requests_tmdb ON movie_requests(tmdb_id) WHERE tmdb_id IS NOT NULL;
|
||||
|
||||
-- 9. 用户求片关联表(用于快速查询用户的求片记录)
|
||||
CREATE TABLE IF NOT EXISTS user_movie_requests (
|
||||
username TEXT NOT NULL,
|
||||
request_id TEXT NOT NULL,
|
||||
PRIMARY KEY (username, request_id),
|
||||
FOREIGN KEY (username) REFERENCES users(username) ON DELETE CASCADE,
|
||||
FOREIGN KEY (request_id) REFERENCES movie_requests(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_user_movie_requests_user ON user_movie_requests(username);
|
||||
|
||||
-- 10. 全局配置表(键值对存储)
|
||||
CREATE TABLE IF NOT EXISTS global_config (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT NOT NULL,
|
||||
updated_at INTEGER NOT NULL
|
||||
);
|
||||
|
||||
-- 11. 管理员配置表(单例)
|
||||
CREATE TABLE IF NOT EXISTS admin_config (
|
||||
id INTEGER PRIMARY KEY CHECK(id = 1), -- 确保只有一条记录
|
||||
config TEXT NOT NULL, -- JSON object
|
||||
updated_at INTEGER NOT NULL
|
||||
);
|
||||
|
||||
-- 12. 收藏更新检查时间表
|
||||
CREATE TABLE IF NOT EXISTS favorite_check_times (
|
||||
username TEXT PRIMARY KEY,
|
||||
last_check_time INTEGER NOT NULL,
|
||||
FOREIGN KEY (username) REFERENCES users(username) ON DELETE CASCADE
|
||||
);
|
||||
Reference in New Issue
Block a user