/**
* 班级操行分管理系统 - 历史记录页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;
function escapeHtml(str) {
if (!str) return '';
var el = document.createElement('span');
el.appendChild(document.createTextNode(str));
return el.innerHTML;
}
function typeMap(relatedType) {
var map = { manual: '手动', homework: '作业', attendance: '考勤' };
return map[relatedType] || '手动';
}
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 loadSubjectsForFilter() {
var subjectSelect = document.getElementById('historySubjectFilter');
if (!subjectSelect) return;
var res = await apiGet('/api/subject/list', { is_active: true });
if (res && res.success && res.data && res.data.subjects) {
let html = '';
res.data.subjects.forEach(s => {
html += '';
});
subjectSelect.innerHTML = html;
}
}
// 筛选学生时自动取消合并记录
function onStudentFilterChange() {
var studentId = document.getElementById('historyStudentId').value;
if (studentId) {
var grouped = document.getElementById('historyGrouped');
if (grouped) grouped.checked = false;
}
}
// 科目筛选变化时,取消扣分类型筛选(互斥)
function onSubjectFilterChange() {
var subjectVal = document.getElementById('historySubjectFilter').value;
if (subjectVal) {
document.getElementById('historyReasonFilter').value = '';
}
}
// 折叠/展开筛选面板
function toggleFilterPanel() {
var panel = document.getElementById('advancedFilters');
var btn = document.getElementById('filterToggleBtn');
if (!panel || !btn) return;
if (panel.style.display === 'none') {
panel.style.display = 'block';
btn.textContent = '收起筛选 ▲';
} else {
panel.style.display = 'none';
btn.textContent = '展开筛选 ▼';
}
}
async function loadHistory(page) {
page = page || 1;
currentHistoryPage = page;
var startDate = document.getElementById('historyStartDate').value;
var endDate = document.getElementById('historyEndDate').value;
var studentId = document.getElementById('historyStudentId').value;
var reasonFilter = document.getElementById('historyReasonFilter').value;
var subjectFilter = document.getElementById('historySubjectFilter').value;
var reasonSearch = document.getElementById('historyReasonSearch').value.trim();
var isGrouped = document.getElementById('historyGrouped').checked;
var statusFilter = document.getElementById('historyStatusFilter') ? document.getElementById('historyStatusFilter').value : '';
// 筛选学生时强制取消合并
if (studentId) isGrouped = false;
var params = {
page: page, page_size: 20,
start_date: startDate,
end_date: endDate
};
if (studentId) params.student_id = studentId;
// 科目筛选优先于扣分类型筛选
if (subjectFilter) {
params.reason_prefix = '[' + subjectFilter + ']';
} else if (reasonFilter) {
params.reason_prefix = reasonFilter;
}
if (reasonSearch) params.reason_search = reasonSearch;
if (isGrouped) params.grouped = true;
if (statusFilter !== '') params.is_revoked = parseInt(statusFilter);
var res = await apiGet('/api/admin/conduct/history', params);
if (res && res.success) {
var nowrapStyle = ' style="white-space:nowrap;min-width:80px;"';
var headHtml = '';
if (isGrouped) {
headHtml = '
类型 | 分值 | 原因 | 学生名单 | 操作人 | 时间 | ';
if (role === '班主任' || role === '班长') {
headHtml += '操作 | ';
}
} else {
headHtml = '类型 | 分值 | 原因 | 学生 | 操作人 | 时间 | ';
if (role === '班主任' || role === '班长' || role === '考勤委员') {
headHtml += '操作 | ';
}
}
document.getElementById('historyTableHead').innerHTML = headHtml;
var html = '';
if (isGrouped) {
res.data.records.forEach(function(record) {
var pointsClass = record.points_change > 0 ? 'plus' : 'minus';
var typeLabel = typeMap(record.related_type);
var names = record.student_names || '';
var allRevoked = record.all_revoked;
var revokedStyle = allRevoked ? ' style="opacity:0.5;text-decoration:line-through;"' : '';
html += '' +
'| ' + typeLabel + ' | ' +
'' + (record.points_change > 0 ? '+' : '') + record.points_change + '×' + record.student_count + ' | ' +
'' + escapeHtml(record.reason) + ' | ' +
'' + escapeHtml(names) + ' | ' +
'' + escapeHtml(record.recorder_name || '') + ' | ' +
'' + formatDateTime(record.created_at) + ' | ';
if (role === '班主任' || role === '班长') {
if (allRevoked) {
html += '已撤销 | ';
} else {
html += ' | ';
}
}
html += '
';
});
if (res.data.records.length === 0) {
var colSpan = (role === '班主任' || role === '班长') ? 7 : 6;
html = '| 暂无记录 |
';
}
} else {
res.data.records.forEach(function(record) {
var pointsClass = record.points_change > 0 ? 'plus' : 'minus';
var typeLabel = typeMap(record.related_type);
var revokedStyle = record.is_revoked == 1 ? ' style="opacity:0.5;text-decoration:line-through;"' : '';
html += '' +
'| ' + typeLabel + ' | ' +
'' + (record.points_change > 0 ? '+' : '') + record.points_change + ' | ' +
'' + escapeHtml(record.reason) + ' | ' +
'' + escapeHtml(record.student_name) + ' | ' +
'' + escapeHtml(record.recorder_name) + ' | ' +
'' + formatDateTime(record.created_at) + ' | ';
if (role === '班主任') {
if (record.is_revoked == 1) {
var revokerInfo = record.revoker_name ? '由 ' + escapeHtml(record.revoker_name) + ' 撤销' : '已撤销';
html += '' + revokerInfo + ' | ';
} else {
html += ' | ';
}
} else if (role === '班长') {
if (record.is_revoked == 1) {
var 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) {
var colSpan = (role === '班主任' || role === '班长' || role === '考勤委员') ? 7 : 6;
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() {
var startDate = document.getElementById('historyStartDate').value;
var endDate = document.getElementById('historyEndDate').value;
var studentId = document.getElementById('historyStudentId').value;
showToast('正在导出历史记录...', 'info');
try {
var reasonFilter = document.getElementById('historyReasonFilter').value;
var subjectFilter = document.getElementById('historySubjectFilter').value;
var reasonSearch = document.getElementById('historyReasonSearch').value.trim();
var 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 (subjectFilter) {
params.reason_prefix = '[' + subjectFilter + ']';
} else if (reasonFilter) {
params.reason_prefix = reasonFilter;
}
if (reasonSearch) params.reason_search = reasonSearch;
var res = await apiGet('/api/admin/conduct/history', params);
if (res && res.success && res.data.records) {
var records = res.data.records;
if (records.length === 0) {
showToast('没有找到记录', 'warning');
return;
}
var csv = '\uFEFF';
csv += '时间,学号,姓名,分数变动,原因,操作人\n';
records.forEach(function(r) {
if (r.is_revoked == 1) return;
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';
});
var blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
var url = URL.createObjectURL(blob);
var 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 && 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 {
var 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
};
var res = await apiGet('/api/admin/conduct/history', params);
if (!res || !res.success || !res.data.records) {
showToast('查询记录失败', 'error');
return;
}
var matchedIds = [];
res.data.records.forEach(function(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;
}
var revokeRes = await apiPost('/api/admin/conduct/batch-revoke', { record_ids: matchedIds });
if (revokeRes && revokeRes.success) {
showToast('批量撤销完成: ' + (revokeRes.data ? revokeRes.data.success_count : 0) + '条成功');
loadHistory(currentHistoryPage);
} else {
showToast(revokeRes && revokeRes.message || '批量撤销失败', 'error');
}
} catch (err) {
showToast('批量撤销失败: ' + err.message, 'error');
}
}
// 初始化:并行加载学生和科目列表,然后加载历史记录
Promise.all([loadStudentsForSelect(), loadSubjectsForFilter()]).then(function() {
var urlParams = new URLSearchParams(window.location.search);
var preStudentId = urlParams.get('student_id');
if (preStudentId) {
document.getElementById('historyStudentId').value = preStudentId;
onStudentFilterChange();
}
loadHistory();
});
window.loadHistory = loadHistory;
window.loadStudentsForSelect = loadStudentsForSelect;
window.exportHistoryRecords = exportHistoryRecords;
window.batchRevokeGrouped = batchRevokeGrouped;
window.onStudentFilterChange = onStudentFilterChange;
window.onSubjectFilterChange = onSubjectFilterChange;
window.toggleFilterPanel = toggleFilterPanel;
})();