/** * 数据库初始化/升级API * 用于添加缺失的字段,确保表结构完整 */ import { NextRequest, NextResponse } from 'next/server' import { query } from '@/lib/db' /** * GET - 初始化/升级数据库表结构 */ export async function GET(request: NextRequest) { const results: string[] = [] try { console.log('[DB Init] 开始检查并升级数据库结构...') // 1. 检查users表是否存在 try { await query('SELECT 1 FROM users LIMIT 1') results.push('✅ users表已存在') } catch (e) { // 创建users表 await query(` CREATE TABLE IF NOT EXISTS users ( id VARCHAR(50) PRIMARY KEY, open_id VARCHAR(100) UNIQUE, session_key VARCHAR(100), nickname VARCHAR(100), avatar VARCHAR(500), phone VARCHAR(20), password VARCHAR(100), wechat_id VARCHAR(100), referral_code VARCHAR(20) UNIQUE, referred_by VARCHAR(50), purchased_sections JSON DEFAULT '[]', has_full_book BOOLEAN DEFAULT FALSE, is_admin BOOLEAN DEFAULT FALSE, earnings DECIMAL(10,2) DEFAULT 0, pending_earnings DECIMAL(10,2) DEFAULT 0, withdrawn_earnings DECIMAL(10,2) DEFAULT 0, referral_count INT DEFAULT 0, match_count_today INT DEFAULT 0, last_match_date DATE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci `) results.push('✅ 创建users表') } // 2. 修改open_id字段允许NULL(后台添加用户时可能没有openId) try { await query('ALTER TABLE users MODIFY COLUMN open_id VARCHAR(100) NULL') results.push('✅ 修改open_id允许NULL') } catch (e: any) { results.push(`⏭️ open_id字段: ${e.message?.includes('Duplicate') ? '已处理' : e.message}`) } // 3. 添加可能缺失的字段(用ALTER TABLE) const columnsToAdd = [ { name: 'password', type: 'VARCHAR(100)' }, { name: 'session_key', type: 'VARCHAR(100)' }, { name: 'referred_by', type: 'VARCHAR(50)' }, { name: 'is_admin', type: 'BOOLEAN DEFAULT FALSE' }, { name: 'match_count_today', type: 'INT DEFAULT 0' }, { name: 'last_match_date', type: 'DATE' }, { name: 'withdrawn_earnings', type: 'DECIMAL(10,2) DEFAULT 0' }, { name: 'avatar', type: 'VARCHAR(500)' }, { name: 'wechat_id', type: 'VARCHAR(100)' } ] for (const col of columnsToAdd) { try { // 先检查列是否存在 const checkResult = await query(` SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'users' AND COLUMN_NAME = ? `, [col.name]) as any[] if (checkResult.length === 0) { // 列不存在,添加 await query(`ALTER TABLE users ADD COLUMN ${col.name} ${col.type}`) results.push(`✅ 添加字段: ${col.name}`) } else { results.push(`⏭️ 字段已存在: ${col.name}`) } } catch (e: any) { results.push(`⚠️ 处理字段${col.name}时出错: ${e.message}`) } } // 3. 添加索引(如果不存在) const indexesToAdd = [ { name: 'idx_open_id', column: 'open_id' }, { name: 'idx_phone', column: 'phone' }, { name: 'idx_referral_code', column: 'referral_code' }, { name: 'idx_referred_by', column: 'referred_by' } ] for (const idx of indexesToAdd) { try { const checkResult = await query(` SHOW INDEX FROM users WHERE Key_name = ? `, [idx.name]) as any[] if (checkResult.length === 0) { await query(`CREATE INDEX ${idx.name} ON users(${idx.column})`) results.push(`✅ 添加索引: ${idx.name}`) } } catch (e: any) { // 忽略索引错误 } } // 4. 检查提现记录表 try { await query('SELECT 1 FROM withdrawals LIMIT 1') results.push('✅ withdrawals表已存在') } catch (e) { await query(` CREATE TABLE IF NOT EXISTS withdrawals ( id VARCHAR(50) PRIMARY KEY, user_id VARCHAR(50) NOT NULL, amount DECIMAL(10,2) NOT NULL, status ENUM('pending', 'processing', 'success', 'failed') DEFAULT 'pending', wechat_openid VARCHAR(100), transaction_id VARCHAR(100), error_message VARCHAR(500), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, processed_at TIMESTAMP, INDEX idx_user_id (user_id), INDEX idx_status (status) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci `) results.push('✅ 创建withdrawals表') } // 5. 检查系统配置表 try { await query('SELECT 1 FROM system_config LIMIT 1') results.push('✅ system_config表已存在') } catch (e) { await query(` CREATE TABLE IF NOT EXISTS system_config ( id INT AUTO_INCREMENT PRIMARY KEY, config_key VARCHAR(100) UNIQUE NOT NULL, config_value JSON NOT NULL, description VARCHAR(200), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci `) results.push('✅ 创建system_config表') } console.log('[DB Init] 数据库升级完成') return NextResponse.json({ success: true, message: '数据库初始化/升级完成', results }) } catch (error) { console.error('[DB Init] 错误:', error) return NextResponse.json({ success: false, error: '数据库初始化失败: ' + (error as Error).message, results }, { status: 500 }) } }