v1.7版本更新
This commit is contained in:
199
frontend/assets/js/history.js
Normal file
199
frontend/assets/js/history.js
Normal file
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
* 班级操行分管理系统 - 历史记录页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 = '<option value="">全部</option>';
|
||||
res.data.students.forEach(s => {
|
||||
html += `<option value="${s.student_id}">${escapeHtml(s.student_no)} - ${escapeHtml(s.name)}</option>`;
|
||||
});
|
||||
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 relatedType = document.getElementById('historyRelatedType').value;
|
||||
const isGrouped = document.getElementById('historyGrouped').checked;
|
||||
|
||||
const params = {
|
||||
page, page_size: 20,
|
||||
start_date: startDate,
|
||||
end_date: endDate
|
||||
};
|
||||
if (studentId) params.student_id = studentId;
|
||||
if (relatedType && !isGrouped) params.related_type = relatedType;
|
||||
if (isGrouped) params.grouped = true;
|
||||
|
||||
const res = await apiGet('/api/admin/conduct/history', params);
|
||||
|
||||
if (res && res.success) {
|
||||
let headHtml = '';
|
||||
if (isGrouped) {
|
||||
headHtml = '<th>时间</th><th>原因</th><th>分值</th><th>操作人</th><th>涉及学生</th>';
|
||||
} else {
|
||||
headHtml = '<th>时间</th><th>学生</th><th>分数变动</th><th>原因</th><th>操作人</th>';
|
||||
if (role === '班主任' || role === '班长' || role === '考勤委员') {
|
||||
headHtml += '<th>操作</th>';
|
||||
}
|
||||
}
|
||||
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 ? record.student_names.split(', ') : [];
|
||||
let tagsHtml = '<div class="student-tags-container">';
|
||||
names.forEach(name => {
|
||||
tagsHtml += `<span class="student-tag">${escapeHtml(name)}</span>`;
|
||||
});
|
||||
tagsHtml += '</div>';
|
||||
html += `<tr>
|
||||
<td>${formatDateTime(record.created_at)}</td>
|
||||
<td class="preserve-newlines">${escapeHtml(record.reason)}</td>
|
||||
<td class="${pointsClass}">${record.points_change > 0 ? '+' : ''}${record.points_change}×${record.student_count}</td>
|
||||
<td>${escapeHtml(record.recorder_name || '')}</td>
|
||||
<td>${tagsHtml}</td>
|
||||
</tr>`;
|
||||
});
|
||||
if (res.data.records.length === 0) {
|
||||
html = '<tr><td colspan="5" style="text-align:center;">暂无记录</td></tr>';
|
||||
}
|
||||
} 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 += `<tr${revokedStyle}>
|
||||
<td>${formatDateTime(record.created_at)}</td>
|
||||
<td>${escapeHtml(record.student_name)}</td>
|
||||
<td class="${pointsClass}">${record.points_change > 0 ? '+' : ''}${record.points_change}</td>
|
||||
<td class="preserve-newlines">${escapeHtml(record.reason)}</td>
|
||||
<td>${escapeHtml(record.recorder_name)}</td>`;
|
||||
if (role === '班主任') {
|
||||
if (record.is_revoked == 1) {
|
||||
const revokerInfo = record.revoker_name ? `由 ${escapeHtml(record.revoker_name)} 撤销` : '已撤销';
|
||||
html += `<td><span class="text-muted" style="margin-right:4px;">${revokerInfo}</span><button class="btn btn-sm btn-secondary" onclick="restoreRecord(${record.record_id})">反撤销</button></td>`;
|
||||
} else {
|
||||
html += `<td><button class="btn btn-sm btn-danger" onclick="revokeRecord(${record.record_id})">撤销</button></td>`;
|
||||
}
|
||||
} else if (role === '班长') {
|
||||
if (record.is_revoked == 1) {
|
||||
const revokerInfo = record.revoker_name ? `由 ${escapeHtml(record.revoker_name)} 撤销` : '已撤销';
|
||||
html += `<td><span class="text-muted">${revokerInfo}</span></td>`;
|
||||
} else {
|
||||
html += `<td><button class="btn btn-sm btn-danger" onclick="revokeRecord(${record.record_id})">撤销</button></td>`;
|
||||
}
|
||||
} else if (role === '考勤委员') {
|
||||
if (record.is_revoked == 1) {
|
||||
html += `<td><span class="text-muted">已撤销</span></td>`;
|
||||
} else if (record.recorder_id == currentUserId) {
|
||||
html += `<td><button class="btn btn-sm btn-danger" onclick="revokeRecord(${record.record_id})">撤销</button></td>`;
|
||||
} else {
|
||||
html += `<td><span class="text-muted">-</span></td>`;
|
||||
}
|
||||
}
|
||||
html += `</tr>`;
|
||||
});
|
||||
|
||||
if (res.data.records.length === 0) {
|
||||
const colSpan = (role === '班主任' || role === '班长' || role === '考勤委员') ? 6 : 5;
|
||||
html = `<tr><td colspan="${colSpan}" style="text-align:center;">暂无记录</td></tr>`;
|
||||
}
|
||||
}
|
||||
|
||||
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 relatedType = document.getElementById('historyRelatedType').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 (relatedType) params.related_type = relatedType;
|
||||
|
||||
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');
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user