/**
* 班级操行分管理系统 - 考勤管理页JS
*
* 开发者: Canglan
* 版权归属: Sea Network Technology Studio
*
* 版权所有 © Sea Network Technology Studio
*/
(function() {
'use strict';
let currentStatus = 'absent';
let studentsData = [];
let existingRecords = [];
// 考勤扣分配置映射(从后端配置注入)
const attendanceDeductionMap = {
absent: window.DEDUCTION_ATTENDANCE_ABSENT || 3,
late: window.DEDUCTION_ATTENDANCE_LATE || 1,
leave: window.DEDUCTION_ATTENDANCE_LEAVE || 0
};
// 初始化按钮文字
function initAttendanceButtons() {
const btnAbsent = document.getElementById('btnAbsent');
const btnLate = document.getElementById('btnLate');
const btnLeave = document.getElementById('btnLeave');
if (btnAbsent) btnAbsent.textContent = '缺勤(' + attendanceDeductionMap.absent + '分)';
if (btnLate) btnLate.textContent = '迟到(' + attendanceDeductionMap.late + '分)';
if (btnLeave) btnLeave.textContent = '请假(' + (attendanceDeductionMap.leave > 0 ? attendanceDeductionMap.leave + '分' : '不扣分') + ')';
if (attendanceDeductionMap.absent > 0) {
document.getElementById('customDeduction').value = attendanceDeductionMap.absent;
}
}
function selectStatus(btn) {
document.querySelectorAll('.status-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
currentStatus = btn.dataset.status;
const defaultDeduction = attendanceDeductionMap[currentStatus] || 0;
if (defaultDeduction > 0) {
document.getElementById('customDeduction').value = defaultDeduction;
} else {
document.getElementById('customDeduction').value = '';
}
}
async function loadStudents() {
const res = await apiGet('/api/admin/students', {page_size: 1000});
if (res && res.success) {
studentsData = res.data.students;
renderStudentGrid();
await loadExistingRecords();
} else {
document.getElementById('studentGrid').innerHTML = '
加载学生列表失败
';
}
}
function renderStudentGrid() {
const currentSlot = document.getElementById('attendanceSlot').value;
let html = '';
studentsData.forEach(student => {
const hasRecord = existingRecords.some(r => r.student_id === student.student_id && r.slot === currentSlot);
html += `
${escapeHtml(student.name)}
${escapeHtml(student.student_no)}
`;
});
if (studentsData.length === 0) {
html = '暂无学生数据
';
}
document.getElementById('studentGrid').innerHTML = html;
}
function toggleStudent(cell) {
cell.classList.toggle('selected');
}
function selectAllStudents() {
document.querySelectorAll('.student-cell:not(.has-record)').forEach(cell => {
cell.classList.add('selected');
});
}
function deselectAllStudents() {
document.querySelectorAll('.student-cell').forEach(cell => {
cell.classList.remove('selected');
});
}
async function loadExistingRecords() {
const date = document.getElementById('attendanceDate').value;
const slot = document.getElementById('attendanceSlot').value;
const res = await apiGet('/api/admin/attendance/records', { date, slot });
if (res && res.success) {
existingRecords = res.data.records || [];
renderStudentGrid();
}
}
async function submitAttendance() {
const selectedCells = document.querySelectorAll('.student-cell.selected');
if (selectedCells.length === 0) {
showToast('请先选择有考勤异常的学生', 'warning');
return;
}
const date = document.getElementById('attendanceDate').value;
const slot = document.getElementById('attendanceSlot').value;
const reason = document.getElementById('attendanceReason').value;
const customDeduction = document.getElementById('customDeduction').value;
const customDeductionValue = customDeduction ? parseInt(customDeduction) : null;
const promises = [];
selectedCells.forEach(cell => {
const studentId = parseInt(cell.dataset.id);
const payload = {
student_id: studentId,
date: date,
slot: slot,
status: currentStatus,
reason: reason,
apply_deduction: true
};
if (customDeductionValue !== null && customDeductionValue > 0) {
payload.custom_deduction = customDeductionValue;
}
promises.push(apiPost('/api/admin/attendance', payload));
});
const results = await Promise.allSettled(promises);
const succeeded = results.filter(r => r.status === 'fulfilled' && r.value?.success).length;
const failed = results.length - succeeded;
if (failed === 0) {
showToast(`考勤提交成功(${succeeded}条)`);
} else {
showToast(`提交完成:成功${succeeded}条,失败${failed}条`, 'error');
}
deselectAllStudents();
await loadExistingRecords();
loadAttendanceRecords();
}
async function loadAttendanceRecords() {
const date = document.getElementById('attendanceDate').value;
const res = await apiGet('/api/admin/attendance/records', { date });
if (res && res.success) {
let html = '';
const records = res.data.records || [];
records.forEach(record => {
html += `
| ${escapeHtml(record.student_no)} |
${escapeHtml(record.student_name)} |
${getStatusBadge(record.status, 'attendance')} |
${escapeHtml(record.reason || '-')} |
${escapeHtml(record.recorder_name || '-')} |
${record.deduction_applied ? '已扣分' : '-'} |
`;
});
if (records.length === 0) {
html = '| 暂无考勤记录 |
';
}
document.getElementById('attendanceList').innerHTML = html;
}
}
// 日期或时段变化时重新加载
document.getElementById('attendanceDate').addEventListener('change', function() {
loadExistingRecords();
loadAttendanceRecords();
});
document.getElementById('attendanceSlot').addEventListener('change', function() {
loadExistingRecords();
});
// 页面初始化
initAttendanceButtons();
loadStudents();
loadAttendanceRecords();
window.selectStatus = selectStatus;
window.loadStudents = loadStudents;
window.toggleStudent = toggleStudent;
window.selectAllStudents = selectAllStudents;
window.deselectAllStudents = deselectAllStudents;
window.submitAttendance = submitAttendance;
window.loadAttendanceRecords = loadAttendanceRecords;
})();