forked from UKSOURCE/cms.hailearning.edu.vn
first commit
This commit is contained in:
192
scripts/2025_12_10_migrate_home.js
Normal file
192
scripts/2025_12_10_migrate_home.js
Normal file
@@ -0,0 +1,192 @@
|
||||
require('dotenv').config();
|
||||
const fs = require('fs').promises;
|
||||
const path = require('path');
|
||||
const mongoose = require('mongoose');
|
||||
const Home = require('../models/home'); // Đảm bảo đường dẫn đúng tới file model
|
||||
|
||||
// 1. Đọc file JSON
|
||||
async function loadHomeData() {
|
||||
// Đảm bảo đường dẫn đúng tới file json
|
||||
const filePath = path.join(__dirname, '..', 'data', 'home.json');
|
||||
const raw = await fs.readFile(filePath, 'utf8');
|
||||
return JSON.parse(raw);
|
||||
}
|
||||
|
||||
// 2. Hàm Transform: Đổ dữ liệu từ JSON (source) vào đúng Schema
|
||||
function transformHome(source) {
|
||||
return {
|
||||
// --- Hero Section ---
|
||||
hero: {
|
||||
title: source.hero?.title || "",
|
||||
description: source.hero?.description || "",
|
||||
backgroundImage: source.hero?.backgroundImage || "",
|
||||
button: {
|
||||
label: source.hero?.button?.label || "Book Now",
|
||||
href: source.hero?.button?.href || "/booking"
|
||||
},
|
||||
contactBox: {
|
||||
welcomeText: source.hero?.contactBox?.welcomeText || "",
|
||||
phone: {
|
||||
label: source.hero?.contactBox?.phone?.label || "Call us",
|
||||
number: source.hero?.contactBox?.phone?.number || "",
|
||||
href: source.hero?.contactBox?.phone?.href || ""
|
||||
},
|
||||
email: {
|
||||
label: source.hero?.contactBox?.email?.label || "Email",
|
||||
address: source.hero?.contactBox?.email?.address || "",
|
||||
href: source.hero?.contactBox?.email?.href || ""
|
||||
},
|
||||
workingHours: {
|
||||
label: source.hero?.contactBox?.workingHours?.label || "Working Hours",
|
||||
hours: source.hero?.contactBox?.workingHours?.hours || ""
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// --- About Section ---
|
||||
about: {
|
||||
title: source.about?.title || "",
|
||||
subtitle: source.about?.subtitle || "",
|
||||
description: source.about?.description || "",
|
||||
images: {
|
||||
mainImage1: source.about?.images?.mainImage1 || "",
|
||||
mainImage2: source.about?.images?.mainImage2 || "",
|
||||
avatars: Array.isArray(source.about?.images?.avatars) ? source.about.images.avatars : []
|
||||
},
|
||||
features: Array.isArray(source.about?.features) ? source.about.features : [],
|
||||
quote: source.about?.quote || "",
|
||||
button: {
|
||||
label: source.about?.button?.label || "",
|
||||
href: source.about?.button?.href || ""
|
||||
},
|
||||
stats: {
|
||||
customerCount: source.about?.stats?.customerCount || 0,
|
||||
customerLabel: source.about?.stats?.customerLabel || ""
|
||||
}
|
||||
},
|
||||
|
||||
// --- Mission & Vision ---
|
||||
missionVision: {
|
||||
title: source.missionVision?.title || "",
|
||||
subtitle: source.missionVision?.subtitle || "",
|
||||
backgroundImage: source.missionVision?.backgroundImage || "",
|
||||
cards: Array.isArray(source.missionVision?.cards) ? source.missionVision.cards : []
|
||||
},
|
||||
|
||||
// --- Why Choose Us ---
|
||||
whyChooseUs: {
|
||||
title: source.whyChooseUs?.title || "",
|
||||
subtitle: source.whyChooseUs?.subtitle || "",
|
||||
description: source.whyChooseUs?.description || "",
|
||||
button: source.whyChooseUs?.button || {},
|
||||
features: Array.isArray(source.whyChooseUs?.features) ? source.whyChooseUs.features : [],
|
||||
tags: Array.isArray(source.whyChooseUs?.tags) ? source.whyChooseUs.tags : [],
|
||||
cta: source.whyChooseUs?.cta || {}
|
||||
},
|
||||
|
||||
// --- Activities ---
|
||||
activities: {
|
||||
cards: Array.isArray(source.activities?.cards) ? source.activities.cards : []
|
||||
},
|
||||
|
||||
// --- FAQ ---
|
||||
faq: {
|
||||
title: source.faq?.title || "",
|
||||
subtitle: source.faq?.subtitle || "",
|
||||
description: source.faq?.description || "",
|
||||
image: source.faq?.image || "",
|
||||
contact: source.faq?.contact || {},
|
||||
questions: Array.isArray(source.faq?.questions) ? source.faq.questions : []
|
||||
},
|
||||
|
||||
// --- Partners ---
|
||||
partners: {
|
||||
title: source.partners?.title || "",
|
||||
subtitle: source.partners?.subtitle || "",
|
||||
backgroundImage: source.partners?.backgroundImage || "",
|
||||
logos: Array.isArray(source.partners?.logos) ? source.partners.logos : [],
|
||||
cta: source.partners?.cta || {}
|
||||
},
|
||||
|
||||
// --- Programs ---
|
||||
programs: {
|
||||
title: source.programs?.title || "",
|
||||
subtitle: source.programs?.subtitle || "",
|
||||
button: source.programs?.button || {},
|
||||
card: {
|
||||
pricePrefix: source.programs?.card?.pricePrefix || "from",
|
||||
priceSuffix: source.programs?.card?.priceSuffix || "USD",
|
||||
buttonLabel: source.programs?.card?.buttonLabel || "Camp Detail",
|
||||
buttonHref: source.programs?.card?.buttonHref || "/camp-profiles"
|
||||
},
|
||||
items: Array.isArray(source.programs?.items) ? source.programs.items : []
|
||||
},
|
||||
|
||||
|
||||
|
||||
// --- Newsletter ---
|
||||
newsletter: {
|
||||
title: source.newsletter?.title || "",
|
||||
subtitle: source.newsletter?.subtitle || "",
|
||||
description: source.newsletter?.description || "",
|
||||
image: source.newsletter?.image || "",
|
||||
decorativeImage: source.newsletter?.decorativeImage || "",
|
||||
button: {
|
||||
label: source.newsletter?.button?.label || "",
|
||||
placeholder: source.newsletter?.button?.placeholder || "",
|
||||
href: source.newsletter?.button?.href || ""
|
||||
}
|
||||
},
|
||||
|
||||
// --- Latest Posts ---
|
||||
latestPosts: {
|
||||
title: source.latestPosts?.title || "",
|
||||
subtitle: source.latestPosts?.subtitle || "",
|
||||
searchPlaceholder: source.latestPosts?.searchPlaceholder || "",
|
||||
sidebarTitle: source.latestPosts?.sidebarTitle || "",
|
||||
blogPosts: Array.isArray(source.latestPosts?.blogPosts) ? source.latestPosts.blogPosts : [],
|
||||
sidebarPosts: Array.isArray(source.latestPosts?.sidebarPosts) ? source.latestPosts.sidebarPosts : [],
|
||||
featuredCard: source.latestPosts?.featuredCard || {}
|
||||
},
|
||||
|
||||
updatedAt: new Date()
|
||||
};
|
||||
}
|
||||
|
||||
// 3. Chạy Migration
|
||||
async function migrate() {
|
||||
try {
|
||||
// Kết nối DB
|
||||
await mongoose.connect(process.env.MONGODB_URI);
|
||||
console.log('✅ Connected to MongoDB');
|
||||
|
||||
// A. Lấy dữ liệu thô
|
||||
const rawData = await loadHomeData();
|
||||
console.log('📖 Data loaded from JSON');
|
||||
|
||||
// B. Chuẩn hóa dữ liệu theo Schema
|
||||
const homeData = transformHome(rawData);
|
||||
|
||||
// C. Lưu vào DB (Upsert: Có rồi thì update, chưa có thì tạo)
|
||||
const existingDoc = await Home.findOne().sort({ updatedAt: -1 });
|
||||
|
||||
if (existingDoc) {
|
||||
console.log('📝 Updating existing Home document...');
|
||||
await Home.findByIdAndUpdate(existingDoc._id, { $set: homeData }, { new: true });
|
||||
} else {
|
||||
console.log('📝 Creating NEW Home document...');
|
||||
await Home.create(homeData);
|
||||
}
|
||||
|
||||
console.log('✨ Migration completed successfully!');
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Migration failed:', error);
|
||||
process.exit(1);
|
||||
} finally {
|
||||
await mongoose.connection.close();
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
migrate();
|
||||
Reference in New Issue
Block a user