亿和考勤管理

📝 记录
📅 日历
💰 工资
⚙️ 管理
🍱 餐补
⚡ 加班

最近记录

员工管理

薪资调整(预支/扣款)

`); w.document.close(); w.print(); } // ========== 管理 ========== async function loadEmployeeList() { const res = await fetch(API + '/api/employees'); const list = await res.json(); const el = document.getElementById('employee-list'); el.innerHTML = list.map(e => `
👤
${e.name}
月薪 ¥${e.monthly_salary} · ${e.work_days_per_month}天制 · ${e.phone||'无电话'}
`).join(''); } function showAddEmployee() { document.getElementById('emp-modal-title').textContent = '添加员工'; document.getElementById('emp-edit-id').value = ''; document.getElementById('emp-name').value = ''; document.getElementById('emp-phone').value = ''; document.getElementById('emp-salary').value = 7500; document.getElementById('emp-workdays').value = 27; document.getElementById('emp-overtime').value = 50; document.getElementById('emp-meal').value = 15; document.getElementById('modal-employee').classList.add('show'); } async function editEmployee(id) { const emp = employees.find(e => e.id === id); if (!emp) return; document.getElementById('emp-modal-title').textContent = '编辑员工'; document.getElementById('emp-edit-id').value = id; document.getElementById('emp-name').value = emp.name; document.getElementById('emp-phone').value = emp.phone; document.getElementById('emp-salary').value = emp.monthly_salary; document.getElementById('emp-workdays').value = emp.work_days_per_month; document.getElementById('emp-overtime').value = emp.overtime_pay; document.getElementById('emp-meal').value = emp.meal_allowance; document.getElementById('modal-employee').classList.add('show'); } async function saveEmployee() { const id = document.getElementById('emp-edit-id').value; const data = { name: document.getElementById('emp-name').value, phone: document.getElementById('emp-phone').value, monthly_salary: parseFloat(document.getElementById('emp-salary').value), work_days_per_month: parseInt(document.getElementById('emp-workdays').value), overtime_pay: parseFloat(document.getElementById('emp-overtime').value), meal_allowance: parseFloat(document.getElementById('emp-meal').value), }; if (!data.name) return toast('请填写姓名'); const url = id ? API + '/api/employees/' + id : API + '/api/employees'; const method = id ? 'PUT' : 'POST'; const res = await fetch(url, { method, headers: {'Content-Type':'application/json'}, body: JSON.stringify(data) }); if (res.ok) { toast('✅ 保存成功'); closeModal('modal-employee'); loadEmployees(); loadEmployeeList(); } else { const e = await res.json(); toast(e.error || '保存失败'); } } async function loadAdjustments() { const res = await fetch(API + '/api/adjustments'); const list = await res.json(); const el = document.getElementById('adjustment-list'); if (list.length === 0) { el.innerHTML = '
暂无调整记录
'; return; } el.innerHTML = list.map(a => { const typeLabel = a.type === 'advance' ? '💰 预支' : a.type === 'overage' ? '📉 超支' : '📌 其他'; return `
💸
${a.employee_name} · ${typeLabel}
${a.date}${a.note ? ' · '+a.note : ''}
-¥${a.amount}
`; }).join(''); } function showAddAdjustment() { document.getElementById('adj-date').value = new Date().toISOString().split('T')[0]; document.getElementById('adj-amount').value = ''; document.getElementById('adj-note').value = ''; document.getElementById('modal-adjustment').classList.add('show'); } async function saveAdjustment() { const data = { employee_id: parseInt(document.getElementById('adj-employee').value), date: document.getElementById('adj-date').value, type: document.getElementById('adj-type').value, amount: parseFloat(document.getElementById('adj-amount').value), note: document.getElementById('adj-note').value, }; if (!data.amount || data.amount <= 0) return toast('请填写金额'); const res = await fetch(API + '/api/adjustments', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify(data) }); if (res.ok) { toast('✅ 已添加'); closeModal('modal-adjustment'); loadAdjustments(); } else toast('保存失败'); } async function deleteAdj(id) { if (!confirm('确认删除?')) return; await fetch(API + '/api/adjustments/' + id, { method: 'DELETE' }); toast('已删除'); loadAdjustments(); } function showDayDetail(id) { /* 可展开 */ }