const mysql = require('mysql2/promise'); const dbConfig = { host: process.env.DB_HOST || 'mysql.theaken.com', port: parseInt(process.env.DB_PORT || '33306'), user: process.env.DB_USER || 'AI_Platform', password: process.env.DB_PASSWORD || 'Aa123456', database: process.env.DB_NAME || 'db_AI_Platform', charset: 'utf8mb4', timezone: '+08:00' }; // Type mapping for converting old types to new types const typeMapping = { 'web_app': 'productivity', 'mobile_app': 'productivity', 'desktop_app': 'productivity', 'api_service': 'automation', 'ai_model': 'ai_model', 'data_analysis': 'data_analysis', 'automation': 'automation', 'other': 'other' }; async function updateAppTypes() { let connection; try { console.log('šŸ”„ é–‹å§‹ę›“ę–°ę‡‰ē”ØēØ‹å¼é”žåž‹...'); connection = await mysql.createConnection(dbConfig); console.log('āœ… č³‡ę–™åŗ«é€£ęŽ„ęˆåŠŸ'); // 1. ęŖ¢ęŸ„ē¾ęœ‰ēš„é”žåž‹åˆ†ä½ˆ console.log('\nšŸ“Š ęŖ¢ęŸ„ē¾ęœ‰é”žåž‹åˆ†ä½ˆ:'); const [typeStats] = await connection.execute(` SELECT type, COUNT(*) as count FROM apps WHERE type IS NOT NULL GROUP BY type `); typeStats.forEach(row => { console.log(` ${row.type}: ${row.count} å€‹ę‡‰ē”ØēØ‹å¼`); }); // 2. ę›“ę–°ē¾ęœ‰ę•øę“šēš„é”žåž‹ console.log('\nšŸ”„ ę›“ę–°ē¾ęœ‰ę‡‰ē”ØēØ‹å¼ēš„é”žåž‹...'); for (const [oldType, newType] of Object.entries(typeMapping)) { if (oldType !== newType) { const [result] = await connection.execute( 'UPDATE apps SET type = ? WHERE type = ?', [newType, oldType] ); if (result.affectedRows > 0) { console.log(` āœ… 將 ${oldType} 曓新為 ${newType}: ${result.affectedRows} å€‹ę‡‰ē”ØēØ‹å¼`); } } } // 3. 修改 type ę¬„ä½ēš„ ENUM 定義 console.log('\nšŸ”§ ꛓꖰ type ę¬„ä½ēš„ ENUM 定義...'); try { // å…ˆåˆŖé™¤čˆŠēš„ ENUM ē“„ęŸ await connection.execute(` ALTER TABLE apps MODIFY COLUMN type VARCHAR(50) DEFAULT 'other' `); console.log(' āœ… ē§»é™¤čˆŠēš„ ENUM ē“„ęŸ'); // ę·»åŠ ę–°ēš„ ENUM ē“„ęŸ await connection.execute(` ALTER TABLE apps MODIFY COLUMN type ENUM( 'productivity', 'ai_model', 'automation', 'data_analysis', 'educational', 'healthcare', 'finance', 'iot_device', 'blockchain', 'ar_vr', 'machine_learning', 'computer_vision', 'nlp', 'robotics', 'cybersecurity', 'cloud_service', 'other' ) DEFAULT 'other' `); console.log(' āœ… ę·»åŠ ę–°ēš„ ENUM ē“„ęŸ'); } catch (error) { console.error(' āŒ ꛓꖰ ENUM ē“„ęŸå¤±ę•—:', error.message); } // 4. ęŖ¢ęŸ„ę›“ę–°å¾Œēš„é”žåž‹åˆ†ä½ˆ console.log('\nšŸ“Š ę›“ę–°å¾Œēš„é”žåž‹åˆ†ä½ˆ:'); const [newTypeStats] = await connection.execute(` SELECT type, COUNT(*) as count FROM apps WHERE type IS NOT NULL GROUP BY type `); newTypeStats.forEach(row => { console.log(` ${row.type}: ${row.count} å€‹ę‡‰ē”ØēØ‹å¼`); }); // 5. ęŖ¢ęŸ„č”Øę ¼ēµę§‹ console.log('\nšŸ“‹ apps 蔨格結構:'); const [columns] = await connection.execute('DESCRIBE apps'); columns.forEach(col => { if (col.Field === 'type') { console.log(` ${col.Field}: ${col.Type} ${col.Null === 'YES' ? 'NULL' : 'NOT NULL'} ${col.Default ? `DEFAULT ${col.Default}` : ''}`); } }); console.log('\nāœ… ę‡‰ē”ØēØ‹å¼é”žåž‹ę›“ę–°å®Œęˆļ¼'); } catch (error) { console.error('āŒ ę›“ę–°ę‡‰ē”ØēØ‹å¼é”žåž‹å¤±ę•—:', error); } finally { if (connection) { await connection.end(); console.log('šŸ”Œ č³‡ę–™åŗ«é€£ęŽ„å·²é—œé–‰'); } } } updateAppTypes().catch(console.error);