// 公共工具函数和API调用 // API 基础 URL const API_BASE_URL = ''; // 通用 API 调用函数 async function apiCall(url, options = {}) { try { const response = await fetch(`${API_BASE_URL}${url}`, { headers: { 'Content-Type': 'application/json', ...options.headers }, ...options }); const data = await response.json(); if (!response.ok) { throw new Error(data.error || `HTTP error! status: ${response.status}`); } return data; } catch (error) { console.error('API调用失败:', error); throw error; } } // GET 请求 async function apiGet(url) { return apiCall(url, { method: 'GET' }); } // POST 请求 async function apiPost(url, data) { return apiCall(url, { method: 'POST', body: JSON.stringify(data) }); } // PUT 请求 async function apiPut(url, data) { return apiCall(url, { method: 'PUT', body: JSON.stringify(data) }); } // DELETE 请求 async function apiDelete(url) { return apiCall(url, { method: 'DELETE' }); } // 显示成功消息 function showSuccess(message) { showNotification(message, 'success'); } // 显示错误消息 function showError(message) { showNotification(message, 'error'); } // 显示通知 function showNotification(message, type = 'info') { // 创建通知元素 const notification = document.createElement('div'); notification.className = `notification ${type}`; notification.innerHTML = ` ${message} `; // 添加到页面 document.body.appendChild(notification); // 自动隐藏 setTimeout(() => { if (notification.parentElement) { notification.remove(); } }, 5000); } // 格式化日期 function formatDate(dateString) { if (!dateString) return ''; const date = new Date(dateString); return date.toLocaleDateString('zh-CN'); } // 格式化日期时间 function formatDateTime(dateString) { if (!dateString) return ''; const date = new Date(dateString); return date.toLocaleString('zh-CN'); } // 获取今天的日期字符串 function getTodayString() { const today = new Date(); return today.toISOString().split('T')[0]; } // 获取本周的开始和结束日期 function getThisWeekRange() { const today = new Date(); const dayOfWeek = today.getDay(); const startOfWeek = new Date(today); startOfWeek.setDate(today.getDate() - dayOfWeek + 1); // 周一 const endOfWeek = new Date(startOfWeek); endOfWeek.setDate(startOfWeek.getDate() + 6); // 周日 return { start: startOfWeek.toISOString().split('T')[0], end: endOfWeek.toISOString().split('T')[0] }; } // 模态框控制 function showModal(modalId) { const modal = document.getElementById(modalId); if (modal) { modal.classList.add('show'); modal.style.display = 'flex'; } } function closeModal(modalId) { const modal = document.getElementById(modalId); if (modal) { modal.classList.remove('show'); modal.style.display = 'none'; } } // 表单重置 function resetForm(formId) { const form = document.getElementById(formId); if (form) { form.reset(); } } // 获取表单数据 function getFormData(formId) { const form = document.getElementById(formId); if (!form) return {}; const formData = new FormData(form); const data = {}; for (let [key, value] of formData.entries()) { data[key] = value; } return data; } // 填充表单数据 function fillForm(formId, data) { const form = document.getElementById(formId); if (!form) return; Object.keys(data).forEach(key => { const field = form.querySelector(`[name="${key}"]`); if (field) { field.value = data[key] || ''; } }); } // 工时格式化函数 function formatHours(hours) { if (!hours || hours === '-' || hours === '0:00') { return hours || '-'; } // 如果包含冒号,直接返回 if (hours.includes(':')) { return hours; } // 如果是小数格式,转换为时:分格式 const decimal = parseFloat(hours); if (!isNaN(decimal)) { const h = Math.floor(decimal); const m = Math.round((decimal - h) * 60); return `${h}:${m.toString().padStart(2, '0')}`; } return hours; } // 工时转换为小数 function hoursToDecimal(hours) { if (!hours || hours === '-') return 0; if (hours.includes(':')) { const [h, m] = hours.split(':').map(Number); return h + (m || 0) / 60; } return parseFloat(hours) || 0; } // 小数转换为工时格式 function decimalToHours(decimal) { if (decimal === 0) return '0:00'; const hours = Math.floor(decimal); const minutes = Math.round((decimal - hours) * 60); return `${hours}:${minutes.toString().padStart(2, '0')}`; } // 计算工时 function calculateHours(startTime, endTime) { if (!startTime || !endTime || startTime === '-' || endTime === '-') { return '-'; } try { const [startH, startM] = startTime.split(':').map(Number); const [endH, endM] = endTime.split(':').map(Number); let startMinutes = startH * 60 + startM; let endMinutes = endH * 60 + endM; // 处理跨日情况 if (endMinutes < startMinutes) { endMinutes += 24 * 60; } const diffMinutes = endMinutes - startMinutes; const hours = Math.floor(diffMinutes / 60); const minutes = diffMinutes % 60; return `${hours}:${minutes.toString().padStart(2, '0')}`; } catch (error) { console.error('计算工时失败:', error); return '0:00'; } } // 星期中文显示 function getDayOfWeekChinese(dateString) { const date = new Date(dateString); const days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; return days[date.getDay()]; } // 判断是否为今天 function isToday(dateString) { const today = new Date().toISOString().split('T')[0]; return dateString === today; } // 文件下载 function downloadFile(content, filename, type = 'text/plain') { const blob = new Blob([content], { type }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } // CSV 生成 function generateCSV(data, headers) { const csvContent = [ headers.join(','), ...data.map(row => headers.map(header => { const value = row[header] || ''; // 如果值包含逗号、引号或换行符,需要用引号包围 if (value.toString().includes(',') || value.toString().includes('"') || value.toString().includes('\n')) { return `"${value.toString().replace(/"/g, '""')}"`; } return value; }).join(',')) ].join('\n'); return csvContent; } // 页面加载完成后的初始化 document.addEventListener('DOMContentLoaded', function() { // 添加点击外部关闭模态框的功能 document.addEventListener('click', function(e) { if (e.target.classList.contains('modal')) { e.target.classList.remove('show'); e.target.style.display = 'none'; } }); // 添加ESC键关闭模态框的功能 document.addEventListener('keydown', function(e) { if (e.key === 'Escape') { const openModal = document.querySelector('.modal.show'); if (openModal) { openModal.classList.remove('show'); openModal.style.display = 'none'; } } }); }); // 添加通知样式到头部(如果不存在) if (!document.querySelector('#notification-styles')) { const style = document.createElement('style'); style.id = 'notification-styles'; style.textContent = ` .notification { position: fixed; top: 20px; right: 20px; padding: 15px 20px; border-radius: 5px; color: white; z-index: 10000; display: flex; align-items: center; gap: 15px; max-width: 400px; box-shadow: 0 4px 12px rgba(0,0,0,0.3); animation: slideIn 0.3s ease-out; } .notification.success { background-color: #27ae60; } .notification.error { background-color: #e74c3c; } .notification.info { background-color: #3498db; } .notification button { background: none; border: none; color: white; font-size: 18px; cursor: pointer; padding: 0; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center; } @keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } `; document.head.appendChild(style); }