Cài đặt quota cho các thành viên
This commit is contained in:
+95
-10
@@ -133,23 +133,107 @@ function applySystemSettings() {
|
||||
if (logoutBtn) logoutBtn.innerText = t.logout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hàm định dạng dung lượng file cho Frontend
|
||||
*/
|
||||
function formatBytes(bytes, decimals = 2) {
|
||||
if (!bytes || bytes === 0) return '0 Bytes';
|
||||
const k = 1024;
|
||||
const dm = decimals < 0 ? 0 : decimals;
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tải và hiển thị thống kê các tệp tin lớn nhất
|
||||
*/
|
||||
async function loadMediaStats() {
|
||||
const token = localStorage.getItem('jwt');
|
||||
const statsContainer = document.getElementById('media-library-stats');
|
||||
if (!statsContainer) return;
|
||||
|
||||
try {
|
||||
const res = await fetch(`${API_BASE_URL}/me/assets/top-large`, {
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
});
|
||||
const topFiles = await res.json();
|
||||
|
||||
if (topFiles && topFiles.length > 0) {
|
||||
let html = `
|
||||
<div class="top-files-section">
|
||||
<h4><i class="fas fa-database"></i> Tệp tin chiếm dụng lớn nhất</h4>
|
||||
<div class="top-files-list">
|
||||
`;
|
||||
topFiles.forEach(file => {
|
||||
const fileName = file.scene?.name || file.scene?.title || 'Ảnh chưa gắn Scene';
|
||||
html += `
|
||||
<div class="top-file-item">
|
||||
<span class="top-file-name">● ${fileName}</span>
|
||||
<span class="top-file-size">${formatBytes(file.fileSize)}</span>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
html += `</div></div>`;
|
||||
statsContainer.innerHTML = html;
|
||||
} else {
|
||||
statsContainer.innerHTML = '';
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn("Không thể nạp thống kê media:", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cập nhật nội dung tab Hồ sơ với thông tin người dùng
|
||||
*/
|
||||
function updateProfileTabContent() {
|
||||
async function updateProfileTabContent() {
|
||||
const token = localStorage.getItem('jwt');
|
||||
const username = localStorage.getItem('username');
|
||||
const role = localStorage.getItem('role');
|
||||
|
||||
if (username) {
|
||||
const avatar = document.getElementById('profile-avatar-initials');
|
||||
const userDisplay = document.getElementById('profile-username-display');
|
||||
const statusDisplay = document.getElementById('profile-status-display');
|
||||
const userInput = document.getElementById('profile-username');
|
||||
const avatar = document.getElementById('profile-avatar-initials');
|
||||
const userDisplay = document.getElementById('profile-username-display');
|
||||
const statusDisplay = document.getElementById('profile-status-display');
|
||||
const userInput = document.getElementById('profile-username');
|
||||
|
||||
if (avatar) avatar.innerText = username.charAt(0).toUpperCase();
|
||||
if (userDisplay) userDisplay.innerText = username;
|
||||
if (statusDisplay) statusDisplay.innerText = role || 'Thành viên';
|
||||
if (userInput) userInput.value = username;
|
||||
if (avatar && username) avatar.innerText = username.charAt(0).toUpperCase();
|
||||
if (userDisplay) userDisplay.innerText = username;
|
||||
if (statusDisplay) statusDisplay.innerText = role || 'Thành viên';
|
||||
if (userInput) userInput.value = username;
|
||||
|
||||
// Lấy dữ liệu dung lượng thực tế từ server
|
||||
try {
|
||||
const res = await fetch(`${API_BASE_URL}/me/profile`, {
|
||||
headers: { 'Authorization': `Bearer ${token}` }
|
||||
});
|
||||
const data = await res.json();
|
||||
|
||||
if (data.storage) {
|
||||
const { used, quota } = data.storage;
|
||||
const progress = document.getElementById('storage-progress-bar');
|
||||
const text = document.getElementById('storage-text');
|
||||
|
||||
if (progress && text) {
|
||||
const usedMB = (used / (1024 * 1024)).toFixed(1);
|
||||
const quotaMB = quota === -1 ? '∞' : (quota / (1024 * 1024)).toFixed(0);
|
||||
text.innerText = `${usedMB} MB / ${quotaMB} MB`;
|
||||
|
||||
if (quota !== -1) {
|
||||
const percent = Math.min((used / quota) * 100, 100);
|
||||
progress.style.width = percent + '%';
|
||||
// Đổi màu thanh tiến trình dựa trên mức độ sử dụng
|
||||
if (percent > 90) progress.style.background = '#dc3545'; // Đỏ (sắp hết)
|
||||
else if (percent > 75) progress.style.background = '#ffc107'; // Vàng (cảnh báo)
|
||||
else progress.style.background = '#28a745'; // Xanh (an toàn)
|
||||
} else {
|
||||
progress.style.width = '100%';
|
||||
progress.style.background = '#007bff'; // Màu xanh dương cho không giới hạn
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn("Không thể tải thông tin dung lượng:", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1953,6 +2037,7 @@ function openDashboardTab(tabName) {
|
||||
loadMyScenes();
|
||||
}
|
||||
if (tabName === 'media-library') {
|
||||
loadMediaStats();
|
||||
loadMyAssets();
|
||||
}
|
||||
if (tabName === 'user-management') {
|
||||
|
||||
Reference in New Issue
Block a user