Refactor giai đoạn 1: test các tính năng vừa thay đổi như tour, scene...

This commit is contained in:
2026-06-10 21:58:45 +07:00
parent 3f1b31b233
commit 358a98b21b
31 changed files with 1391 additions and 638 deletions
+27 -43
View File
@@ -1,57 +1,41 @@
const Asset = require('../models/Asset');
const fs = require('fs');
const fs = require('fs').promises;
const path = require('path');
// Cấu hình Quota cho từng nhóm người dùng (đơn vị: Bytes)
const ROLE_QUOTAS = {
'Thành viên': 2 * 1024 * 1024 * 1024, // 2GB
'editor': 10 * 1024 * 1024 * 1024, // 10GB
'admin': 100 * 1024 * 1024 * 1024, // 100GB (hoặc Infinity)
'Chủ sở hữu': Infinity // Không giới hạn
};
/**
* Middleware kiểm tra giới hạn lưu trữ của người dùng
* Dựa trên cấu trúc storage (used/quota) và role mới.
*/
const checkQuota = async (req, res, next) => {
if (!req.user) return res.status(401).json({ message: 'Unauthorized' });
if (!req.user) return res.status(401).json({ message: 'Vui lòng đăng nhập' });
const userRole = req.user.role || 'Thành viên';
const quota = ROLE_QUOTAS[userRole] || ROLE_QUOTAS['Thành viên'];
// Admin được miễn trừ kiểm tra dung lượng
if (req.user.role === 'admin') return next();
// Nếu không giới hạn thì đi tiếp
if (quota === Infinity) return next();
// Lấy dữ liệu từ req.user (đã được authMiddleware nạp từ DB)
const used = req.user.storage?.used || 0;
const quota = req.user.storage?.quota || 0;
const newFileSize = req.file ? req.file.size : 0;
try {
// Sử dụng MongoDB Aggregation để tính tổng dung lượng ngay trên database
const usageResult = await Asset.aggregate([
{ $match: { uploadedBy: req.user._id } },
{
$group: {
_id: null,
totalUsage: { $sum: { $ifNull: ["$fileSize", 0] } }
}
}
]);
const currentUsage = usageResult.length > 0 ? usageResult[0].totalUsage : 0;
const newFileSize = req.file ? req.file.size : 0;
if (currentUsage + newFileSize > quota) {
// Xóa file tạm vừa upload lên nếu vượt định mức
if (req.file && fs.existsSync(req.file.path)) fs.unlinkSync(req.file.path);
return res.status(403).json({
message: `Vượt quá giới hạn lưu trữ. Định mức của bạn là ${(quota / (1024**3)).toFixed(1)}GB. Bạn đã sử dụng ${(currentUsage / (1024**3)).toFixed(2)}GB.`
});
// Kiểm tra nếu tổng dung lượng sau khi upload vượt quá hạn mức
if (used + newFileSize > quota) {
// Xóa ngay file tạm vừa được multer lưu vào disk để giải phóng tài nguyên server
if (req.file && req.file.path) {
await fs.unlink(req.file.path).catch(err =>
console.error('[Quota Middleware] Lỗi xóa file tạm:', err.message)
);
}
next();
} catch (error) {
console.error('[Quota Check Error]:', error);
next(); // Cho phép đi tiếp nếu lỗi logic kiểm tra để tránh chặn người dùng oan
return res.status(403).json({
message: 'Dung lượng lưu trữ của bạn đã hết hoặc không đủ để thực hiện thao tác này.',
storage: {
used: `${(used / (1024 * 1024)).toFixed(2)} MB`,
quota: `${(quota / (1024 * 1024)).toFixed(2)} MB`,
required: `${(newFileSize / (1024 * 1024)).toFixed(2)} MB`
}
});
}
next();
};
module.exports = { checkQuota, ROLE_QUOTAS };
module.exports = { checkQuota };