/** * 班级操行分管理系统 - 历史记录页JS * * 开发者: Canglan * 版权归属: Sea Network Technology Studio * * 版权所有 © Sea Network Technology Studio */ (function() { 'use strict'; const role = window.PAGE_CONFIG.role; const currentUserId = window.PAGE_CONFIG.userId; let currentHistoryPage = 1; let totalHistoryPages = 1; async function loadStudentsForSelect() { const res = await apiGet('/api/admin/students', {page_size: 1000}); if (res && res.success) { let html = ''; res.data.students.forEach(s => { html += ``; }); document.getElementById('historyStudentId').innerHTML = html; } } async function loadHistory(page = 1) { currentHistoryPage = page; const startDate = document.getElementById('historyStartDate').value; const endDate = document.getElementById('historyEndDate').value; const studentId = document.getElementById('historyStudentId').value; const reasonFilter = document.getElementById('historyReasonFilter').value; const isGrouped = document.getElementById('historyGrouped').checked; const statusFilter = document.getElementById('historyStatusFilter')?.value; const params = { page, page_size: 20, start_date: startDate, end_date: endDate }; if (studentId) params.student_id = studentId; if (reasonFilter) params.reason_prefix = reasonFilter; if (isGrouped) params.grouped = true; if (statusFilter !== undefined && statusFilter !== '') params.is_revoked = parseInt(statusFilter); const res = await apiGet('/api/admin/conduct/history', params); if (res && res.success) { const nowrapStyle = ' style="white-space: nowrap; min-width: 80px;"'; let headHtml = ''; if (isGrouped) { headHtml = '时间原因分值操作人涉及学生'; if (role === '班主任' || role === '班长') { headHtml += '操作'; } } else { headHtml = '时间学生分数变动原因操作人'; if (role === '班主任' || role === '班长' || role === '考勤委员') { headHtml += '操作'; } } document.getElementById('historyTableHead').innerHTML = headHtml; let html = ''; if (isGrouped) { res.data.records.forEach(record => { const pointsClass = record.points_change > 0 ? 'plus' : 'minus'; const names = record.student_names || ''; const allRevoked = record.all_revoked; const revokedStyle = allRevoked ? ' style="opacity:0.5; text-decoration:line-through;"' : ''; html += ` ${formatDateTime(record.created_at)} ${escapeHtml(record.reason)} ${record.points_change > 0 ? '+' : ''}${record.points_change}×${record.student_count} ${escapeHtml(record.recorder_name || '')} ${escapeHtml(names)}`; if (role === '班主任' || role === '班长') { if (allRevoked) { html += `已撤销`; } else { html += ``; } } html += ``; }); if (res.data.records.length === 0) { const colSpan = (role === '班主任' || role === '班长') ? 6 : 5; html = '暂无记录'; } } else { res.data.records.forEach(record => { const pointsClass = record.points_change > 0 ? 'plus' : 'minus'; const revokedStyle = record.is_revoked == 1 ? ' style="opacity:0.5; text-decoration:line-through;"' : ''; html += ` ${formatDateTime(record.created_at)} ${escapeHtml(record.student_name)} ${record.points_change > 0 ? '+' : ''}${record.points_change} ${escapeHtml(record.reason)} ${escapeHtml(record.recorder_name)}`; if (role === '班主任') { if (record.is_revoked == 1) { const revokerInfo = record.revoker_name ? `由 ${escapeHtml(record.revoker_name)} 撤销` : '已撤销'; html += `${revokerInfo}`; } else { html += ``; } } else if (role === '班长') { if (record.is_revoked == 1) { const revokerInfo = record.revoker_name ? `由 ${escapeHtml(record.revoker_name)} 撤销` : '已撤销'; html += `${revokerInfo}`; } else { html += ``; } } else if (role === '考勤委员') { if (record.is_revoked == 1) { html += `已撤销`; } else if (record.recorder_id == currentUserId) { html += ``; } else { html += `-`; } } html += ``; }); if (res.data.records.length === 0) { const colSpan = (role === '班主任' || role === '班长' || role === '考勤委员') ? 6 : 5; html = `暂无记录`; } } document.getElementById('historyList').innerHTML = html; totalHistoryPages = res.data.total_pages || 1; renderHistoryPagination(); } } function renderHistoryPagination() { renderSmartPagination('historyPagination', currentHistoryPage, totalHistoryPages, function(page) { loadHistory(page); }); } async function exportHistoryRecords() { const startDate = document.getElementById('historyStartDate').value; const endDate = document.getElementById('historyEndDate').value; const studentId = document.getElementById('historyStudentId').value; showToast('正在导出历史记录...', 'info'); try { const reasonFilter = document.getElementById('historyReasonFilter').value; const params = { page: 1, page_size: 1000 }; if (startDate) params.start_date = startDate; if (endDate) params.end_date = endDate; if (studentId) params.student_id = studentId; if (reasonFilter) params.reason_prefix = reasonFilter; const res = await apiGet('/api/admin/conduct/history', params); if (res && res.success && res.data.records) { const records = res.data.records; if (records.length === 0) { showToast('没有找到记录', 'warning'); return; } let csv = '\uFEFF'; csv += '时间,学号,姓名,分数变动,原因,操作人\n'; records.forEach(r => { csv += `${r.created_at || ''},${r.student_no || ''},${r.student_name || ''},${r.points_change > 0 ? '+' : ''}${r.points_change},${(r.reason || '').replace(/,/g, ';')},${r.recorder_name || ''}\n`; }); const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = `历史记录_${new Date().toISOString().slice(0,10)}.csv`; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); showToast(`导出成功,共${records.length}条记录`); } else { showToast('导出失败:' + (res?.message || '未知错误'), 'error'); } } catch (err) { showToast('导出失败:' + err.message, 'error'); } } // 批量撤销合并记录(按条件查找并撤销) async function batchRevokeGrouped(reason, pointsChange, recorderName, createdAt) { if (!confirm(`确定要撤销所有"${reason}"(${pointsChange > 0 ? '+' : ''}${pointsChange}分)的记录吗?`)) return; showToast('正在批量撤销...', 'info'); try { // 先查询匹配的记录 const params = { page: 1, page_size: 1000, start_date: document.getElementById('historyStartDate').value, end_date: document.getElementById('historyEndDate').value, reason_prefix: reason.substring(0, 4), grouped: false }; const res = await apiGet('/api/admin/conduct/history', params); if (!res || !res.success || !res.data.records) { showToast('查询记录失败', 'error'); return; } // 精确匹配 const matchedIds = []; res.data.records.forEach(r => { if (r.reason === reason && r.points_change === pointsChange && r.is_revoked == 0) { matchedIds.push(r.record_id); } }); if (matchedIds.length === 0) { showToast('没有找到可撤销的记录', 'warning'); return; } const revokeRes = await apiPost('/api/admin/conduct/batch-revoke', { record_ids: matchedIds }); if (revokeRes && revokeRes.success) { showToast(`批量撤销完成: ${revokeRes.data.success_count}条成功`); loadHistory(currentHistoryPage); } else { showToast(revokeRes?.message || '批量撤销失败', 'error'); } } catch (err) { showToast('批量撤销失败: ' + err.message, 'error'); } } loadStudentsForSelect().then(() => { const urlParams = new URLSearchParams(window.location.search); const preStudentId = urlParams.get('student_id'); if (preStudentId) { document.getElementById('historyStudentId').value = preStudentId; loadHistory(); } else { loadHistory(); } }); window.loadHistory = loadHistory; window.loadStudentsForSelect = loadStudentsForSelect; window.exportHistoryRecords = exportHistoryRecords; window.batchRevokeGrouped = batchRevokeGrouped; })();