184 lines
6.2 KiB
JavaScript
184 lines
6.2 KiB
JavaScript
const { sequelize } = require('../config/database');
|
||
const School = require('../models/School');
|
||
const Class = require('../models/Class');
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
/**
|
||
* Script import dữ liệu trường và lớp học từ schools.json
|
||
* Chạy: node src/scripts/import-schools.js
|
||
*/
|
||
|
||
async function importSchoolsData() {
|
||
try {
|
||
console.log('🚀 Bắt đầu import dữ liệu trường học...\n');
|
||
|
||
// Đọc file schools.json
|
||
const schoolsDataPath = path.join(__dirname, '../../data/schools.json');
|
||
const schoolsData = JSON.parse(fs.readFileSync(schoolsDataPath, 'utf8'));
|
||
|
||
console.log(`📚 Tìm thấy ${schoolsData.length} trường học trong file\n`);
|
||
|
||
// Kết nối database
|
||
await sequelize.authenticate();
|
||
console.log('✅ Kết nối database thành công\n');
|
||
|
||
// Đồng bộ models (tạo bảng nếu chưa có)
|
||
await sequelize.sync({ alter: false });
|
||
console.log('✅ Đồng bộ database models thành công\n');
|
||
|
||
let importedSchools = 0;
|
||
let importedClasses = 0;
|
||
let skippedSchools = 0;
|
||
const errors = [];
|
||
|
||
// Import từng trường
|
||
for (const schoolData of schoolsData) {
|
||
try {
|
||
console.log(`📖 Đang xử lý: ${schoolData.school_name} (${schoolData.school_code})`);
|
||
|
||
// Kiểm tra trường đã tồn tại chưa
|
||
let school = await School.findOne({
|
||
where: { school_code: schoolData.school_code }
|
||
});
|
||
|
||
if (school) {
|
||
console.log(` ⚠️ Trường đã tồn tại, cập nhật thông tin...`);
|
||
|
||
// Cập nhật thông tin trường
|
||
await school.update({
|
||
school_name: schoolData.school_name,
|
||
school_type: schoolData.school_type,
|
||
address: schoolData.address,
|
||
city: schoolData.city,
|
||
district: schoolData.district,
|
||
phone: schoolData.phone,
|
||
});
|
||
skippedSchools++;
|
||
} else {
|
||
// Tạo mới trường
|
||
school = await School.create({
|
||
school_code: schoolData.school_code,
|
||
school_name: schoolData.school_name,
|
||
school_type: schoolData.school_type,
|
||
address: schoolData.address,
|
||
city: schoolData.city,
|
||
district: schoolData.district,
|
||
phone: schoolData.phone,
|
||
is_active: true,
|
||
});
|
||
importedSchools++;
|
||
console.log(` ✅ Tạo mới trường thành công`);
|
||
}
|
||
|
||
// Import các lớp học
|
||
if (schoolData.classes && Array.isArray(schoolData.classes)) {
|
||
console.log(` 📝 Đang import ${schoolData.classes.length} lớp học...`);
|
||
|
||
for (const classData of schoolData.classes) {
|
||
try {
|
||
// Xử lý định dạng classes khác nhau trong JSON
|
||
let classNames = [];
|
||
let gradeLevel = null;
|
||
|
||
if (classData.name) {
|
||
// Format 1: { "grade": 1, "name": "1A" }
|
||
classNames = [classData.name];
|
||
gradeLevel = classData.grade;
|
||
} else if (classData.names) {
|
||
// Format 2: { "grade": 3, "names": ["3,1", "3,2", ...] }
|
||
classNames = classData.names;
|
||
gradeLevel = classData.grade;
|
||
}
|
||
|
||
// Tạo từng lớp
|
||
for (const className of classNames) {
|
||
// Tạo class_code duy nhất
|
||
const classCode = `${schoolData.school_code}_${className.replace(/[\/,\s.]/g, '_')}`;
|
||
|
||
// Kiểm tra lớp đã tồn tại chưa
|
||
const existingClass = await Class.findOne({
|
||
where: { class_code: classCode }
|
||
});
|
||
|
||
if (!existingClass) {
|
||
await Class.create({
|
||
class_code: classCode,
|
||
class_name: className,
|
||
school_id: school.id,
|
||
academic_year_id: '00000000-0000-0000-0000-000000000000', // Temporary UUID
|
||
grade_level: gradeLevel,
|
||
max_students: 35,
|
||
current_students: 0,
|
||
});
|
||
importedClasses++;
|
||
}
|
||
}
|
||
} catch (classError) {
|
||
console.error(` ❌ Lỗi import lớp: ${classError.message}`);
|
||
errors.push({
|
||
school: schoolData.school_name,
|
||
class: classData,
|
||
error: classError.message
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
console.log('');
|
||
} catch (schoolError) {
|
||
console.error(` ❌ Lỗi import trường: ${schoolError.message}\n`);
|
||
errors.push({
|
||
school: schoolData.school_name,
|
||
error: schoolError.message
|
||
});
|
||
}
|
||
}
|
||
|
||
// Tổng kết
|
||
console.log('\n' + '='.repeat(60));
|
||
console.log('📊 KẾT QUẢ IMPORT');
|
||
console.log('='.repeat(60));
|
||
console.log(`✅ Trường học mới: ${importedSchools}`);
|
||
console.log(`⚠️ Trường đã tồn tại: ${skippedSchools}`);
|
||
console.log(`✅ Lớp học mới: ${importedClasses}`);
|
||
console.log(`❌ Lỗi: ${errors.length}`);
|
||
console.log('='.repeat(60));
|
||
|
||
if (errors.length > 0) {
|
||
console.log('\n⚠️ CHI TIẾT LỖI:');
|
||
errors.forEach((err, index) => {
|
||
console.log(`\n${index + 1}. ${err.school || 'Unknown'}`);
|
||
console.log(` Lỗi: ${err.error}`);
|
||
if (err.class) {
|
||
console.log(` Lớp: ${JSON.stringify(err.class)}`);
|
||
}
|
||
});
|
||
}
|
||
|
||
console.log('\n✅ Hoàn thành import dữ liệu!\n');
|
||
|
||
} catch (error) {
|
||
console.error('❌ Lỗi nghiêm trọng:', error);
|
||
throw error;
|
||
} finally {
|
||
await sequelize.close();
|
||
console.log('🔌 Đã đóng kết nối database');
|
||
}
|
||
}
|
||
|
||
// Chạy script
|
||
if (require.main === module) {
|
||
importSchoolsData()
|
||
.then(() => {
|
||
console.log('\n🎉 Script hoàn thành thành công!');
|
||
process.exit(0);
|
||
})
|
||
.catch((error) => {
|
||
console.error('\n💥 Script thất bại:', error);
|
||
process.exit(1);
|
||
});
|
||
}
|
||
|
||
module.exports = { importSchoolsData };
|