/** * Migration 006 — Settings 表 + products.generated_aff_url * * - settings: 键值对存储系统配置(TG_BOT_TOKEN, TG_DEFAULT_CHANNEL_ID 等) * - products.generated_aff_url: 缓存自动生成的 aff 链接,方便查询 */ const Database = require('better-sqlite3'); const path = require('path'); require('dotenv').config({ path: path.join(__dirname, '..', '.env') }); const dbPath = path.resolve(__dirname, '..', process.env.DB_PATH || 'db/monitor.sqlite'); const db = new Database(dbPath); db.pragma('journal_mode = WAL'); // ── 创建 settings 表 ── db.exec(` CREATE TABLE IF NOT EXISTS settings ( key TEXT PRIMARY KEY, value TEXT, updated_at TEXT DEFAULT (datetime('now')) ); `); console.log('+ settings table'); // ── products 加 generated_aff_url 列 ── function ensureColumn(table, column, sql) { const cols = db.prepare(`PRAGMA table_info(${table})`).all().map(c => c.name); if (!cols.includes(column)) { db.exec(`ALTER TABLE ${table} ADD COLUMN ${sql}`); console.log(`+ ${table}.${column}`); } else { console.log(` ${table}.${column} (already exists)`); } } ensureColumn('products', 'generated_aff_url', 'generated_aff_url TEXT'); // ── 回填 generated_aff_url(兼容老库:aff_code/aff_param 可能还不存在) ── const cols = db.prepare(`PRAGMA table_info(products)`).all().map(c => c.name); const hasAffCode = cols.includes('aff_code'); const hasAffParam = cols.includes('aff_param'); if (hasAffCode) { const { buildAffUrl } = require('../src/utils/affHelper'); const selectSql = hasAffParam ? "SELECT id, buy_url, aff_code, aff_param FROM products WHERE aff_code IS NOT NULL AND aff_code != ''" : "SELECT id, buy_url, aff_code, NULL as aff_param FROM products WHERE aff_code IS NOT NULL AND aff_code != ''"; const products = db.prepare(selectSql).all(); const updateStmt = db.prepare('UPDATE products SET generated_aff_url = ? WHERE id = ?'); db.transaction(() => { for (const p of products) { const baseUrl = p.buy_url; if (!baseUrl) continue; const affUrl = buildAffUrl(baseUrl, p.aff_code, p.aff_param || 'aff'); updateStmt.run(affUrl, p.id); console.log(` product #${p.id}: generated_aff_url=${affUrl}`); } })(); } else { console.log(' skip backfill: products.aff_code not found yet'); } console.log('✅ migration-006 done:', dbPath); db.close();