Files
sena_db_api_layer/controllers/teacherController.js
silverpro89 3791b7cae1
All checks were successful
Deploy to Production / deploy (push) Successful in 21s
update
2026-01-28 11:21:21 +07:00

290 lines
7.6 KiB
JavaScript

const { TeacherDetail, UserProfile, UsersAuth } = require('../models');
const { cacheUtils } = require('../config/redis');
const teacherProfileService = require('../services/teacherProfileService');
/**
* Teacher Controller - Quản lý giáo viên
*/
class TeacherController {
/**
* Get all teachers with pagination and caching
*/
async getAllTeachers(req, res, next) {
try {
const { page = 1, limit = 20, status, teacher_type, school_id } = req.query;
const offset = (page - 1) * limit;
const cacheKey = `teachers:list:${page}:${limit}:${status || 'all'}:${teacher_type || 'all'}:${school_id || 'all'}`;
const cached = await cacheUtils.get(cacheKey);
if (cached) {
return res.json({
success: true,
data: cached,
cached: true,
});
}
const where = {};
if (status) where.status = status;
if (teacher_type) where.teacher_type = teacher_type;
// Query teachers
const { count, rows } = await TeacherDetail.findAndCountAll({
where,
limit: parseInt(limit),
offset: parseInt(offset),
order: [['created_at', 'DESC']],
});
// Manually fetch profiles for each teacher
const teachersWithProfiles = await Promise.all(
rows.map(async (teacher) => {
const profile = await UserProfile.findOne({
where: { user_id: teacher.user_id },
attributes: ['id', 'full_name', 'phone', 'date_of_birth', 'gender', 'address', 'school_id', 'city', 'district', 'avatar_url'],
});
// Filter by school_id if provided
if (school_id && (!profile || profile.school_id !== school_id)) {
return null;
}
return {
...teacher.toJSON(),
profile: profile ? profile.toJSON() : null,
};
})
);
// Filter out nulls (teachers not matching school_id)
const filteredTeachers = teachersWithProfiles.filter(t => t !== null);
const result = {
teachers: filteredTeachers,
pagination: {
total: school_id ? filteredTeachers.length : count,
page: parseInt(page),
limit: parseInt(limit),
totalPages: Math.ceil((school_id ? filteredTeachers.length : count) / limit),
},
};
await cacheUtils.set(cacheKey, result, 1800);
res.json({
success: true,
data: result,
cached: false,
});
} catch (error) {
next(error);
}
}
/**
* Get teacher by ID with manual profile fetch
*/
async getTeacherById(req, res, next) {
try {
const { id } = req.params;
const cacheKey = `teacher:${id}`;
const cached = await cacheUtils.get(cacheKey);
if (cached) {
return res.json({
success: true,
data: cached,
cached: true,
});
}
const teacher = await TeacherDetail.findByPk(id);
if (!teacher) {
return res.status(404).json({
success: false,
message: 'Teacher not found',
});
}
// Manually fetch profile
const profile = await UserProfile.findOne({
where: { user_id: teacher.user_id },
});
const teacherData = {
...teacher.toJSON(),
profile: profile ? profile.toJSON() : null,
};
await cacheUtils.set(cacheKey, teacherData, 3600);
res.json({
success: true,
data: teacherData,
cached: false,
});
} catch (error) {
next(error);
}
}
/**
* Create new teacher with full profile (users_auth + user_profile + teacher_detail)
*/
async createTeacher(req, res, next) {
try {
const teacherData = req.body;
// Use service to create full teacher profile
const result = await teacherProfileService.createTeacherWithProfile(teacherData);
// Clear cache
await cacheUtils.deletePattern('teachers:list:*');
res.status(201).json({
success: true,
message: 'Teacher created successfully',
data: {
user_id: result.user_id,
username: result.username,
email: result.email,
temporary_password: result.temporary_password, // null if user provided password
teacher_code: result.teacher_detail.teacher_code,
teacher_type: result.teacher_detail.teacher_type,
profile: {
full_name: result.profile.full_name,
needs_update: result.profile.etc?.needs_profile_update || false,
}
},
});
} catch (error) {
next(error);
}
}
/**
* Update teacher profile (cho phép user tự cập nhật)
*/
async updateTeacherProfile(req, res, next) {
try {
const { id } = req.params; // user_id or teacher_id
const profileData = req.body;
// Nếu id là teacher_id, tìm user_id
let userId = id;
if (profileData.teacher_id) {
const teacher = await TeacherDetail.findByPk(profileData.teacher_id);
if (!teacher) {
return res.status(404).json({
success: false,
message: 'Teacher not found',
});
}
userId = teacher.user_id;
}
// Update profile
const updatedProfile = await teacherProfileService.updateTeacherProfile(userId, profileData);
// Clear cache
await cacheUtils.delete(`teacher:${id}`);
await cacheUtils.delete(`user:profile:${userId}`);
await cacheUtils.deletePattern('teachers:list:*');
res.json({
success: true,
message: 'Teacher profile updated successfully',
data: updatedProfile,
});
} catch (error) {
next(error);
}
}
/**
* Update teacher
*/
async updateTeacher(req, res, next) {
try {
const { id } = req.params;
const updates = req.body;
const teacher = await TeacherDetail.findByPk(id);
if (!teacher) {
return res.status(404).json({
success: false,
message: 'Teacher not found',
});
}
await teacher.update(updates);
await cacheUtils.delete(`teacher:${id}`);
await cacheUtils.deletePattern('teachers:list:*');
res.status(200).json({
success: true,
message: 'Teacher updated successfully',
data: teacher,
});
} catch (error) {
next(error);
}
}
/**
* Delete teacher (update status to resigned)
*/
async deleteTeacher(req, res, next) {
try {
const { id } = req.params;
const teacher = await TeacherDetail.findByPk(id);
if (!teacher) {
return res.status(404).json({
success: false,
message: 'Teacher not found',
});
}
await teacher.update({ status: 'resigned' });
await cacheUtils.delete(`teacher:${id}`);
await cacheUtils.deletePattern('teachers:list:*');
res.status(200).json({
success: true,
message: 'Teacher status updated to resigned',
data: teacher,
});
} catch (error) {
next(error);
}
}
jobId: job.id,
});
} catch (error) {
next(error);
}
}
/**
* Get teacher datatypes
*/
async getTeacherDatatypes(req, res, next) {
try {
const datatypes = TeacherDetail.rawAttributes;
res.json({
success: true,
data: datatypes,
});
} catch (error) {
next(error);
}
}
}
module.exports = new TeacherController();