/** * Import Context (status=5) → Sentences * * Logic: * 1. Lấy tất cả Context có status = 5 * 2. So sánh Context.title với Sentences.text * - Nếu chưa có → tạo mới Sentence * - Nếu đã có → cập nhật image vào đúng mảng * 3. Xác định slot image dựa vào Context.image.split("_")[1]: * - "square" → image_square * - "small" → image_small * - "normal" → image_normal * 4. Chuyển Context.status → 6 */ const { sequelize } = require('./config/database'); const Context = require('./models/Context'); const Sentences = require('./models/Sentences'); // ─── helper: thêm URL vào mảng JSON (không trùng lặp) ─────────────────────── function addToArray(existing, url) { const arr = Array.isArray(existing) ? [...existing] : []; if (!arr.includes(url)) arr.push(url); return arr; } // ─── helper: xác định slot image từ tên file/URL ──────────────────────────── function resolveImageSlot(imageUrl) { if (!imageUrl) return null; // Lấy phần tên file (bỏ path/query) const filename = imageUrl.split('/').pop().split('?')[0]; const parts = filename.split('_'); // Duyệt tất cả phần tử, tìm keyword for (const part of parts) { const key = part.toLowerCase(); if (key === 'square') return 'image_square'; if (key === 'small') return 'image_small'; if (key === 'normal') return 'image_normal'; } return null; // không xác định được } // ─── main ──────────────────────────────────────────────────────────────────── async function run() { try { await sequelize.authenticate(); console.log('✅ Database connected\n'); // 1. Lấy tất cả Context có status = 5 const contexts = await Context.findAll({ where: { status: 5 } }); console.log(`📦 Tìm thấy ${contexts.length} Context(s) có status = 5\n`); if (contexts.length === 0) { console.log('Không có gì để xử lý.'); process.exit(0); } let created = 0; let updated = 0; let skipped = 0; for (const ctx of contexts) { const text = ctx.context; // so sánh với Sentences.text const imageUrl = ctx.image; const imageSlot = resolveImageSlot(imageUrl); if (!text) { console.warn(` ⚠️ Context [${ctx.uuid}] không có context — bỏ qua`); skipped++; continue; } // 2. Tìm Sentence có text khớp let sentence = await Sentences.findOne({ where: { text } }); if (!sentence) { // ── Tạo mới ────────────────────────────────────────────────────────── const newData = { text, is_active: true, image_small: [], image_square: [], image_normal: [], }; // Gán image vào đúng slot if (imageUrl && imageSlot) { newData[imageSlot] = [imageUrl]; } else if (imageUrl) { console.warn(` ⚠️ Không xác định slot image từ URL: "${imageUrl}" — bỏ qua image`); } await Sentences.create(newData); console.log(` ✅ [TẠO MỚI] "${text}"${imageSlot ? ` → ${imageSlot}` : ''}`); created++; } else { // ── Cập nhật image ─────────────────────────────────────────────────── if (imageUrl && imageSlot) { const updatedArr = addToArray(sentence[imageSlot], imageUrl); await sentence.update({ [imageSlot]: updatedArr }); console.log(` 🔄 [CẬP NHẬT] "${text}" → ${imageSlot} (+1 ảnh)`); updated++; } else { console.warn(` ⚠️ [BỎ QUA IMAGE] "${text}" — URL trống hoặc không xác định slot`); skipped++; } } // 3. Chuyển Context.status → 6 await ctx.update({ status: 6 }); } console.log('\n─────────────────────────────────────'); console.log(`📊 Kết quả:`); console.log(` ✅ Tạo mới : ${created}`); console.log(` 🔄 Cập nhật : ${updated}`); console.log(` ⚠️ Bỏ qua : ${skipped}`); console.log(` 📌 Tổng : ${contexts.length}`); console.log('─────────────────────────────────────'); process.exit(0); } catch (error) { console.error('❌ Lỗi:', error.message); console.error(error.stack); process.exit(1); } } run();