Sửa lỗi cập nhật thông tin hồ sơ
@@ -943,7 +943,14 @@ router.get('/me/profile', protect, async (req, res) => {
|
||||
try {
|
||||
const user = await User.findById(req.user._id).select('-password').lean();
|
||||
|
||||
// Đảm bảo các trường này luôn tồn tại để frontend không bị lỗi undefined
|
||||
user.fullName = user.fullName || '';
|
||||
user.email = user.email || '';
|
||||
user.avatarUrl = user.avatarUrl || '';
|
||||
|
||||
// Tính toán dung lượng thực tế của người dùng
|
||||
// Logic này đã được tối ưu hóa bằng Aggregation ở các bước trước
|
||||
// và được giữ nguyên để trả về thông tin storage cho frontend
|
||||
const usageResult = await Asset.aggregate([
|
||||
{ $match: { uploadedBy: req.user._id } },
|
||||
{
|
||||
@@ -1010,21 +1017,59 @@ router.get('/me/assets/top-large', protect, async (req, res) => {
|
||||
* @desc Cập nhật hồ sơ (đổi tên, mật khẩu)
|
||||
* @access Private
|
||||
*/
|
||||
router.put('/me/profile', protect, async (req, res) => {
|
||||
router.put('/me/profile', protect, upload.single('avatar'), async (req, res, next) => {
|
||||
try {
|
||||
const user = await User.findById(req.user._id);
|
||||
if (!user) return res.status(404).json({ message: 'User not found' });
|
||||
|
||||
if (req.body.username) user.username = req.body.username;
|
||||
if (req.body.password) user.password = req.body.password; // Hook pre-save sẽ tự hash
|
||||
const { fullName, email, username, password } = req.body;
|
||||
|
||||
if (fullName) user.fullName = fullName;
|
||||
if (email) user.email = email;
|
||||
// Chỉ cho phép cập nhật username nếu nó khác với username hiện tại
|
||||
if (username && user.username !== username) {
|
||||
user.username = username;
|
||||
} else if (username && user.username === username) {
|
||||
// Nếu username không đổi, không cần gán lại để tránh trigger unique validation không cần thiết
|
||||
} else if (!username) {
|
||||
// Nếu frontend gửi username rỗng, có thể là lỗi hoặc cố ý xóa, cần xử lý tùy theo business logic
|
||||
}
|
||||
if (password && password.trim() !== '') user.password = password;
|
||||
|
||||
// Xử lý ảnh đại diện nếu có upload
|
||||
if (req.file) {
|
||||
// Xóa avatar cũ nếu có và không phải là avatar mặc định
|
||||
if (user.avatarUrl && user.avatarUrl.startsWith('/api/assets/view_avatar/')) {
|
||||
const oldAvatarName = user.avatarUrl.split('/').pop();
|
||||
const oldAvatarPath = path.join(uploadDir, oldAvatarName);
|
||||
if (fs.existsSync(oldAvatarPath)) fs.unlinkSync(oldAvatarPath);
|
||||
}
|
||||
|
||||
const avatarName = `avatar_${user._id}${path.extname(req.file.originalname)}`;
|
||||
const avatarPath = path.join(uploadDir, avatarName);
|
||||
|
||||
await sharp(req.file.path)
|
||||
.resize(200, 200) // Resize avatar về kích thước nhỏ (200x200)
|
||||
.toFile(avatarPath);
|
||||
user.avatarUrl = `/api/assets/view_avatar/${avatarName}`; // Lưu đường dẫn ảnh vào DB
|
||||
if (fs.existsSync(req.file.path)) fs.unlinkSync(req.file.path); // Xóa file tạm
|
||||
}
|
||||
|
||||
// Sử dụng validateBeforeSave: false để bỏ qua validation cho các trường không được gửi lên
|
||||
// hoặc các trường không liên quan đến việc cập nhật hồ sơ cá nhân như agreedToRules, role.
|
||||
// Tuy nhiên, các validation cho các trường được cập nhật (như email, username unique) vẫn sẽ chạy.
|
||||
await user.save({ validateBeforeSave: false });
|
||||
|
||||
await user.save();
|
||||
res.json({
|
||||
message: 'Hồ sơ đã được cập nhật',
|
||||
user: { id: user._id, username: user.username, role: user.role }
|
||||
});
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: error.message });
|
||||
// Xử lý lỗi validation của Mongoose
|
||||
if (error.name === 'ValidationError') {
|
||||
return res.status(400).json({ message: error.message });
|
||||
}
|
||||
next(error); // Chuyển lỗi khác cho middleware xử lý lỗi chung
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 3.1 MiB |
|
After Width: | Height: | Size: 5.7 MiB |
|
After Width: | Height: | Size: 6.9 MiB |
|
After Width: | Height: | Size: 5.3 MiB |
|
After Width: | Height: | Size: 4.4 MiB |
|
After Width: | Height: | Size: 3.5 MiB |
|
After Width: | Height: | Size: 3.0 MiB |
@@ -307,6 +307,10 @@ async function updateProfile(e) {
|
||||
const form = document.getElementById('profile-form');
|
||||
const formData = new FormData(form);
|
||||
|
||||
// Xóa các trường không cần thiết khi cập nhật hồ sơ cá nhân
|
||||
formData.delete('agreedToRules'); // Không cần khi cập nhật
|
||||
formData.delete('role'); // Role chỉ được thay đổi bởi Admin
|
||||
|
||||
try {
|
||||
const res = await fetch(`${API_BASE_URL}/me/profile`, {
|
||||
method: 'PUT',
|
||||
|
||||