// 自定义JavaScript函数 // 设置前端域名全局变量 if (typeof FRONTEND_DOMAIN !== 'undefined') { window.FRONTEND_DOMAIN = FRONTEND_DOMAIN; } // 显示加载动画 function showLoading() { const loadingElement = document.getElementById('loading'); if (loadingElement) { loadingElement.style.display = 'block'; } } // 隐藏加载动画 function hideLoading() { const loadingElement = document.getElementById('loading'); if (loadingElement) { loadingElement.style.display = 'none'; } } // 格式化日期 function formatDate(dateString) { if (!dateString) return '-'; const date = new Date(dateString); return date.toLocaleDateString('zh-CN') + ' ' + date.toLocaleTimeString('zh-CN'); } // 格式化文件大小 function formatFileSize(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } // 显示通知 - 统一的消息弹窗函数 function showNotification(message, type = 'info') { // 创建通知元素 const alertDiv = document.createElement('div'); const alertType = type === 'error' ? 'danger' : type; alertDiv.className = `alert alert-${alertType} alert-dismissible fade show`; alertDiv.innerHTML = ` ${message} `; alertDiv.style.marginBottom = '10px'; // 插入到通知容器中 const container = document.getElementById('notification-container') || document.querySelector('main'); if (container) { container.insertBefore(alertDiv, container.firstChild); // 自动隐藏 setTimeout(() => { if (alertDiv.parentNode) { alertDiv.remove(); } }, 5000); } else { // 如果找不到容器,使用console输出作为备选方案 console.log(`[${type.toUpperCase()}] ${message}`); } } // API请求函数 - 添加认证支持 function apiRequest(url, options = {}) { // 自动构建完整的API URL let fullUrl = url; // 检查是否配置了前端域名 const frontendDomain = window.FRONTEND_DOMAIN || ''; // 修复URL构建逻辑,避免重复域名问题 if (url.startsWith('/')) { // 如果是绝对路径,则使用配置的域名或当前主机 if (frontendDomain && !url.startsWith(frontendDomain)) { // 确保frontendDomain不包含路径部分 let cleanDomain = frontendDomain; try { const urlObj = new URL(frontendDomain.startsWith('http') ? frontendDomain : 'http://' + frontendDomain); cleanDomain = urlObj.origin; } catch (e) { // 如果解析失败,使用原始值 if (frontendDomain.includes('/')) { cleanDomain = frontendDomain.split('/')[0]; } } fullUrl = cleanDomain + url; } else if (!frontendDomain) { fullUrl = window.location.origin + url; } } else if (!url.startsWith('http')) { // 如果不是完整URL且不以http开头,则添加API前缀 if (frontendDomain) { // 确保frontendDomain不包含路径部分 let cleanDomain = frontendDomain; try { const urlObj = new URL(frontendDomain.startsWith('http') ? frontendDomain : 'http://' + frontendDomain); cleanDomain = urlObj.origin; } catch (e) { // 如果解析失败,使用原始值 if (frontendDomain.includes('/')) { cleanDomain = frontendDomain.split('/')[0]; } } fullUrl = cleanDomain + '/api/v1/' + url; } else { fullUrl = window.location.origin + '/api/v1/' + url; } } // 设置默认选项 const defaultOptions = { headers: { 'Content-Type': 'application/json', }, credentials: 'same-origin' // 确保发送cookies进行认证 }; // 合并选项 const mergedOptions = { ...defaultOptions, ...options, headers: { ...defaultOptions.headers, ...options.headers } }; // 显示加载动画 showLoading(); // 发起请求 return fetch(fullUrl, mergedOptions) .then(response => { // 隐藏加载动画 hideLoading(); // 检查响应状态 if (response.status === 401) { // 未授权,重定向到登录页面 window.location.href = '/login'; throw new Error('未授权访问'); } return response.json().catch(() => ({})); }) .catch(error => { // 隐藏加载动画 hideLoading(); // 处理网络错误 console.error('API请求失败:', error); throw error; }); }