const Database = require('better-sqlite3') const path = require('path') const dbPath = process.env.DB_PATH || path.join(__dirname, 'data.db') const db = new Database(dbPath) // 启用外键 db.pragma('journal_mode = WAL') // 建表 db.exec(` CREATE TABLE IF NOT EXISTS situation ( id INTEGER PRIMARY KEY CHECK (id = 1), data TEXT NOT NULL, updated_at TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE TABLE IF NOT EXISTS force_summary ( side TEXT PRIMARY KEY CHECK (side IN ('us', 'iran')), total_assets INTEGER NOT NULL, personnel INTEGER NOT NULL, naval_ships INTEGER NOT NULL, aircraft INTEGER NOT NULL, ground_units INTEGER NOT NULL, uav INTEGER NOT NULL, missile_consumed INTEGER NOT NULL, missile_stock INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS power_index ( side TEXT PRIMARY KEY CHECK (side IN ('us', 'iran')), overall INTEGER NOT NULL, military_strength INTEGER NOT NULL, economic_power INTEGER NOT NULL, geopolitical_influence INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS force_asset ( id TEXT PRIMARY KEY, side TEXT NOT NULL CHECK (side IN ('us', 'iran')), name TEXT NOT NULL, type TEXT NOT NULL, count INTEGER NOT NULL, status TEXT NOT NULL CHECK (status IN ('active', 'standby', 'alert')), lat REAL, lng REAL ); CREATE TABLE IF NOT EXISTS key_location ( id INTEGER PRIMARY KEY AUTOINCREMENT, side TEXT NOT NULL CHECK (side IN ('us', 'iran')), name TEXT NOT NULL, lat REAL NOT NULL, lng REAL NOT NULL, type TEXT, region TEXT ); CREATE TABLE IF NOT EXISTS combat_losses ( side TEXT PRIMARY KEY CHECK (side IN ('us', 'iran')), bases_destroyed INTEGER NOT NULL, bases_damaged INTEGER NOT NULL, personnel_killed INTEGER NOT NULL, personnel_wounded INTEGER NOT NULL, aircraft INTEGER NOT NULL, warships INTEGER NOT NULL, armor INTEGER NOT NULL, vehicles INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS wall_street_trend ( id INTEGER PRIMARY KEY AUTOINCREMENT, time TEXT NOT NULL, value INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS retaliation_current ( id INTEGER PRIMARY KEY CHECK (id = 1), value INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS retaliation_history ( id INTEGER PRIMARY KEY AUTOINCREMENT, time TEXT NOT NULL, value INTEGER NOT NULL ); CREATE TABLE IF NOT EXISTS situation_update ( id TEXT PRIMARY KEY, timestamp TEXT NOT NULL, category TEXT NOT NULL, summary TEXT NOT NULL, severity TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS gdelt_events ( event_id TEXT PRIMARY KEY, event_time TEXT NOT NULL, title TEXT NOT NULL, lat REAL NOT NULL, lng REAL NOT NULL, impact_score INTEGER NOT NULL, url TEXT, created_at TEXT DEFAULT (datetime('now')) ); CREATE TABLE IF NOT EXISTS conflict_stats ( id INTEGER PRIMARY KEY CHECK (id = 1), total_events INTEGER NOT NULL DEFAULT 0, high_impact_events INTEGER NOT NULL DEFAULT 0, estimated_casualties INTEGER NOT NULL DEFAULT 0, estimated_strike_count INTEGER NOT NULL DEFAULT 0, updated_at TEXT NOT NULL ); `) // 迁移:为已有 key_location 表添加 type、region、status、damage_level 列 try { const cols = db.prepare('PRAGMA table_info(key_location)').all() const names = cols.map((c) => c.name) if (!names.includes('type')) db.exec('ALTER TABLE key_location ADD COLUMN type TEXT') if (!names.includes('region')) db.exec('ALTER TABLE key_location ADD COLUMN region TEXT') if (!names.includes('status')) db.exec('ALTER TABLE key_location ADD COLUMN status TEXT DEFAULT "operational"') if (!names.includes('damage_level')) db.exec('ALTER TABLE key_location ADD COLUMN damage_level INTEGER') } catch (_) {} // 迁移:combat_losses 添加平民伤亡、updated_at try { const lossCols = db.prepare('PRAGMA table_info(combat_losses)').all() const lossNames = lossCols.map((c) => c.name) if (!lossNames.includes('civilian_killed')) db.exec('ALTER TABLE combat_losses ADD COLUMN civilian_killed INTEGER NOT NULL DEFAULT 0') if (!lossNames.includes('civilian_wounded')) db.exec('ALTER TABLE combat_losses ADD COLUMN civilian_wounded INTEGER NOT NULL DEFAULT 0') if (!lossNames.includes('updated_at')) db.exec('ALTER TABLE combat_losses ADD COLUMN updated_at TEXT DEFAULT (datetime("now"))') } catch (_) {} // 迁移:所有表添加 updated_at 用于数据回放 const addUpdatedAt = (table) => { try { const cols = db.prepare(`PRAGMA table_info(${table})`).all() if (!cols.some((c) => c.name === 'updated_at')) { db.exec(`ALTER TABLE ${table} ADD COLUMN updated_at TEXT DEFAULT (datetime("now"))`) } } catch (_) {} } addUpdatedAt('force_summary') addUpdatedAt('power_index') addUpdatedAt('force_asset') addUpdatedAt('key_location') addUpdatedAt('retaliation_current') // 来访统计:visits 用于在看(近期活跃 IP),visitor_count 用于累积人次(每次接入 +1) try { db.exec(` CREATE TABLE IF NOT EXISTS visits ( ip TEXT PRIMARY KEY, last_seen TEXT NOT NULL DEFAULT (datetime('now')) ); CREATE TABLE IF NOT EXISTS visitor_count ( id INTEGER PRIMARY KEY CHECK (id = 1), total INTEGER NOT NULL DEFAULT 0 ); INSERT OR IGNORE INTO visitor_count (id, total) VALUES (1, 0); `) } catch (_) {} // 后台留言:供开发者收集用户反馈 try { db.exec(` CREATE TABLE IF NOT EXISTS feedback ( id INTEGER PRIMARY KEY AUTOINCREMENT, content TEXT NOT NULL, ip TEXT, created_at TEXT NOT NULL DEFAULT (datetime('now')) ) `) } catch (_) {} module.exports = db