update
This commit is contained in:
201
scripts/import-foreign-teachers.js
Normal file
201
scripts/import-foreign-teachers.js
Normal file
@@ -0,0 +1,201 @@
|
||||
const { sequelize } = require('../config/database');
|
||||
const UsersAuth = require('../models/UsersAuth');
|
||||
const UserProfile = require('../models/UserProfile');
|
||||
const TeacherDetail = require('../models/TeacherDetail');
|
||||
const School = require('../models/School');
|
||||
const bcrypt = require('bcrypt');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
/**
|
||||
* Script import giáo viên nước ngoài từ fteacher.txt
|
||||
* Chạy: node src/scripts/import-foreign-teachers.js
|
||||
*/
|
||||
|
||||
// Hàm hash password
|
||||
async function hashPassword(password) {
|
||||
const salt = await bcrypt.genSalt(10);
|
||||
const hash = await bcrypt.hash(password, salt);
|
||||
return { hash, salt };
|
||||
}
|
||||
|
||||
// Hàm parse tên từ username
|
||||
function parseNameFromUsername(username) {
|
||||
// tdv_altaf -> Altaf
|
||||
const name = username.replace('tdv_', '').replace(/_/g, ' ');
|
||||
return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
|
||||
}
|
||||
|
||||
// Hàm tạo email từ username
|
||||
function generateEmail(username) {
|
||||
// tdv_altaf -> altaf@senaai.edu.vn
|
||||
const name = username.replace('tdv_', '');
|
||||
return `${name}@senaai.edu.vn`;
|
||||
}
|
||||
|
||||
async function importForeignTeachers() {
|
||||
try {
|
||||
console.log('🚀 Bắt đầu import giáo viên nước ngoài...\n');
|
||||
|
||||
// Đọc file fteacher.txt
|
||||
const filePath = path.join(__dirname, '../../data/fteacher.txt');
|
||||
const fileContent = fs.readFileSync(filePath, 'utf8');
|
||||
const lines = fileContent.split('\n').filter(line => line.trim());
|
||||
|
||||
console.log(`📚 Tìm thấy ${lines.length} giáo viên trong file\n`);
|
||||
|
||||
// Kết nối database
|
||||
await sequelize.authenticate();
|
||||
console.log('✅ Kết nối database thành công\n');
|
||||
|
||||
// Lấy thông tin trung tâm SenaAI
|
||||
const senaAI = await School.findOne({
|
||||
where: { school_code: 'SENAAI' }
|
||||
});
|
||||
|
||||
if (!senaAI) {
|
||||
throw new Error('❌ Không tìm thấy trung tâm SenaAI trong database. Vui lòng chạy add-senaai-center.js trước!');
|
||||
}
|
||||
|
||||
let importedCount = 0;
|
||||
let skippedCount = 0;
|
||||
const errors = [];
|
||||
|
||||
// Parse từng dòng
|
||||
for (const line of lines) {
|
||||
try {
|
||||
// Parse: Created user: tdv_altaf with password: 13082025
|
||||
const match = line.match(/Created user: (\S+) with password: (\S+)/);
|
||||
|
||||
if (!match) {
|
||||
console.log(`⚠️ Bỏ qua dòng không hợp lệ: ${line}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const [, username, password] = match;
|
||||
const fullName = parseNameFromUsername(username);
|
||||
const email = generateEmail(username);
|
||||
const teacherCode = username.toUpperCase();
|
||||
|
||||
console.log(`📖 Đang xử lý: ${fullName} (${username})`);
|
||||
|
||||
// Kiểm tra user đã tồn tại
|
||||
const existingAuth = await UsersAuth.findOne({
|
||||
where: { username }
|
||||
});
|
||||
|
||||
if (existingAuth) {
|
||||
console.log(` ⚠️ User đã tồn tại, bỏ qua\n`);
|
||||
skippedCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Hash password
|
||||
const { hash, salt } = await hashPassword(password);
|
||||
|
||||
// Transaction để đảm bảo tính toàn vẹn dữ liệu
|
||||
await sequelize.transaction(async (t) => {
|
||||
// 1. Tạo UsersAuth
|
||||
const userAuth = await UsersAuth.create({
|
||||
username,
|
||||
email,
|
||||
password_hash: hash,
|
||||
salt,
|
||||
role: 'teacher',
|
||||
is_active: true,
|
||||
is_verified: true,
|
||||
}, { transaction: t });
|
||||
|
||||
// 2. Tạo UserProfile
|
||||
const userProfile = await UserProfile.create({
|
||||
user_id: userAuth.id,
|
||||
full_name: fullName,
|
||||
first_name: fullName.split(' ')[0],
|
||||
last_name: fullName.split(' ').slice(1).join(' ') || fullName,
|
||||
phone: '',
|
||||
school_id: senaAI.id,
|
||||
address: 'SenaAI Education Center',
|
||||
city: 'Thành phố Hồ Chí Minh',
|
||||
district: 'Đang cập nhật',
|
||||
}, { transaction: t });
|
||||
|
||||
// 3. Tạo TeacherDetail
|
||||
await TeacherDetail.create({
|
||||
user_id: userAuth.id,
|
||||
teacher_code: teacherCode,
|
||||
teacher_type: 'foreign',
|
||||
qualification: 'Native Speaker',
|
||||
specialization: 'English Language Teaching',
|
||||
hire_date: new Date(),
|
||||
status: 'active',
|
||||
skill_tags: [
|
||||
{ name: 'English Teaching', level: 'expert' },
|
||||
{ name: 'Communication', level: 'expert' }
|
||||
],
|
||||
certifications: [],
|
||||
training_hours: 0,
|
||||
}, { transaction: t });
|
||||
});
|
||||
|
||||
console.log(` ✅ Tạo thành công (Email: ${email})\n`);
|
||||
importedCount++;
|
||||
|
||||
} catch (error) {
|
||||
console.error(` ❌ Lỗi: ${error.message}\n`);
|
||||
errors.push({
|
||||
line,
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Tổng kết
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log('📊 KẾT QUẢ IMPORT');
|
||||
console.log('='.repeat(60));
|
||||
console.log(`✅ Giáo viên mới: ${importedCount}`);
|
||||
console.log(`⚠️ Đã tồn tại: ${skippedCount}`);
|
||||
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.line}`);
|
||||
console.log(` Lỗi: ${err.error}`);
|
||||
});
|
||||
}
|
||||
|
||||
// Thống kê giáo viên nước ngoài
|
||||
const foreignTeachersCount = await TeacherDetail.count({
|
||||
where: { teacher_type: 'foreign' }
|
||||
});
|
||||
|
||||
console.log('\n📊 THỐNG KÊ:');
|
||||
console.log(` Tổng số giáo viên nước ngoài: ${foreignTeachersCount}`);
|
||||
|
||||
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) {
|
||||
importForeignTeachers()
|
||||
.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 = { importForeignTeachers };
|
||||
Reference in New Issue
Block a user