-- ============================================ -- AI LiaoWang Web App 数据库迁移脚本 -- 数据库: PostgreSQL -- 生成时间: 2026-05-18 -- 说明: 包含所有表的完整建表语句,含 SSO 新增字段 -- ============================================ -- 1. 用户表 (User) — 已新增 SSO 字段 CREATE TABLE IF NOT EXISTS "user" ( id SERIAL PRIMARY KEY, username VARCHAR(64) NOT NULL, password_hash VARCHAR(256), sso_sub VARCHAR(256) UNIQUE, real_name VARCHAR(100), roles TEXT, email VARCHAR(120), phone VARCHAR(30), avatar_url VARCHAR(500) ); CREATE INDEX IF NOT EXISTS ix_user_username ON "user" (username); -- 插入默认管理员账号 (密码: admin) INSERT INTO "user" (username, password_hash, sso_sub, real_name, roles) SELECT 'admin', 'scrypt:32768:8:1$A9gQwDOkl3PLfi5f$fd967bd171fe965bbb1530b036a5003d83ee61b6463dc273479538584ce39c2e778be3e2e8d17b26b8890df31724eda49edb5cd91096ee3a7093c64a135b519e', NULL, '管理员', '["super_admin"]' WHERE NOT EXISTS (SELECT 1 FROM "user" WHERE username = 'admin'); -- 2. 爬虫源表 (SpiderSource) CREATE TABLE IF NOT EXISTS spider_source ( id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL UNIQUE, code_identifier VARCHAR(100) NOT NULL UNIQUE, description TEXT, status VARCHAR(20) DEFAULT 'active', created_at TIMESTAMP DEFAULT NOW(), type VARCHAR(20) DEFAULT 'script', url VARCHAR(500), method VARCHAR(10) DEFAULT 'GET', headers TEXT, params TEXT, search_param_key VARCHAR(50) DEFAULT 'q', selectors TEXT, has_pagination BOOLEAN DEFAULT FALSE, pagination_param VARCHAR(50), pagination_step INTEGER DEFAULT 10, pagination_start INTEGER DEFAULT 0 ); -- 3. 采集任务表 (SpiderTask) CREATE TABLE IF NOT EXISTS collection_task ( id SERIAL PRIMARY KEY, keyword VARCHAR(100) NOT NULL, spider_source_id INTEGER NOT NULL REFERENCES spider_source(id), pages INTEGER DEFAULT 1, status VARCHAR(20) DEFAULT 'pending', created_at TIMESTAMP DEFAULT NOW(), finished_at TIMESTAMP ); -- 4. 采集结果表 (SpiderResult) CREATE TABLE IF NOT EXISTS spider_result ( id SERIAL PRIMARY KEY, task_id INTEGER REFERENCES collection_task(id), title VARCHAR(500), abstract TEXT, source VARCHAR(200), cover VARCHAR(500), link VARCHAR(500), published_at VARCHAR(50), has_deep_collection BOOLEAN DEFAULT FALSE, created_at TIMESTAMP DEFAULT NOW() ); -- 5. 深度采集表 (DeepCollection) CREATE TABLE IF NOT EXISTS deep_collection ( id SERIAL PRIMARY KEY, title VARCHAR(500), url VARCHAR(500) NOT NULL UNIQUE, content TEXT, summary TEXT, status VARCHAR(20) DEFAULT 'pending', progress INTEGER DEFAULT 0, progress_msg VARCHAR(200) DEFAULT '', error_msg TEXT, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- 6. AI 模型表 (AIModel) CREATE TABLE IF NOT EXISTS ai_model ( id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL, provider VARCHAR(50) DEFAULT 'openai', api_base VARCHAR(500) NOT NULL, api_key VARCHAR(500) NOT NULL, model_name VARCHAR(200) NOT NULL, system_prompt TEXT, is_active BOOLEAN DEFAULT TRUE, total_tokens BIGINT DEFAULT 0, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- 7. Token 使用日志表 (TokenUsageLog) CREATE TABLE IF NOT EXISTS token_usage_log ( id SERIAL PRIMARY KEY, model_id INTEGER REFERENCES ai_model(id), prompt_tokens INTEGER DEFAULT 0, completion_tokens INTEGER DEFAULT 0, total_tokens INTEGER DEFAULT 0, request_type VARCHAR(50) DEFAULT 'test', created_at TIMESTAMP DEFAULT NOW() ); -- 8. AI 对话表 (AIConversation) CREATE TABLE IF NOT EXISTS ai_conversation ( id SERIAL PRIMARY KEY, title VARCHAR(200) DEFAULT 'New Chat', user_id INTEGER REFERENCES "user"(id), created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- 9. AI 消息表 (AIMessage) CREATE TABLE IF NOT EXISTS ai_message ( id SERIAL PRIMARY KEY, conversation_id INTEGER NOT NULL REFERENCES ai_conversation(id) ON DELETE CASCADE, role VARCHAR(20) NOT NULL, content TEXT, meta_data TEXT, created_at TIMESTAMP DEFAULT NOW() );