- 后端从 Python FastAPI 重写为 Go Gin(端口 56789) - 多班级完全隔离 - 超级管理员独立登录 - 课代表作业管理、排行榜分项排行 - 角色加减分上下限可配置 - 家长改密功能(可开关) - 周度/月度重置功能 - MySQL 5.7 兼容 - 43轮代码审查+全部修复 - Apache 2.0 许可证
101 lines
4.1 KiB
JavaScript
101 lines
4.1 KiB
JavaScript
/**
|
|
* 多班级版班级管理系统 - 学生管理页JS
|
|
*
|
|
* 开发者: Canglan
|
|
* 版权归属: Sea Network Technology Studio
|
|
*
|
|
* 版权所有 © Sea Network Technology Studio
|
|
*/
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
const userRole = window.PAGE_CONFIG.role;
|
|
let currentPage = 1;
|
|
let totalPages = 1;
|
|
|
|
async function loadStudents(page = 1) {
|
|
currentPage = page;
|
|
const search = document.getElementById('searchInput').value;
|
|
const res = await apiGet('/api/admin/students', { page, page_size: 20, search });
|
|
|
|
if (res && res.success) {
|
|
let html = '';
|
|
res.data.students.forEach(student => {
|
|
html += `<tr>
|
|
<td><input type="checkbox" class="student-checkbox" data-id="${student.student_id}"></td>
|
|
<td>${escapeHtml(student.student_no)}</td>
|
|
<td><a href="/admin/history.php?student_id=${student.student_id}" class="link">${escapeHtml(student.name)}</a></td>
|
|
<td>${escapeHtml(student.dormitory_number || '-')}</td>
|
|
<td>${student.total_points}</td>
|
|
${userRole === '班主任' ? `<td>${student.parent_account ? student.parent_account.slice(0,3) + '******' + student.parent_account.slice(-2) : '-'}</td>` : ''}
|
|
<td>
|
|
<div class="action-dropdown">
|
|
<button class="btn btn-sm btn-outline" onclick="showSinglePointsModal(${student.student_id}, '${escapeHtml(student.name)}')">加减分</button>
|
|
${userRole === '班主任' ? `<button class="btn btn-sm action-dropdown-toggle" onclick="toggleActionDropdown(this)">更多 ▼</button>
|
|
<div class="action-dropdown-menu">
|
|
<a onclick="showEditStudentModal(${student.student_id}, '${escapeHtml(student.student_no)}', '${escapeHtml(student.name)}', '${escapeHtml(student.parent_account || '')}', '${escapeHtml(student.dormitory_number || '')}')">编辑</a>
|
|
<a onclick="showResetStudentPasswordModal(${student.student_id}, '${escapeHtml(student.name)}')">重置密码</a>
|
|
<a onclick="unlockStudent('${escapeHtml(student.student_no)}', '${escapeHtml(student.name)}')">解锁</a>
|
|
<a class="danger" onclick="deleteStudent(${student.student_id}, '${escapeHtml(student.name)}')">删除</a>
|
|
</div>` : ''}
|
|
</div>
|
|
</td>
|
|
</tr>`;
|
|
});
|
|
|
|
if (res.data.students.length === 0) {
|
|
html = `<tr><td colspan="${userRole === '班主任' ? '7' : '6'}" style="text-align:center;">暂无学生数据</td></tr>`;
|
|
}
|
|
|
|
document.getElementById('studentList').innerHTML = html;
|
|
|
|
totalPages = res.data.total_pages || 1;
|
|
renderPagination();
|
|
}
|
|
}
|
|
|
|
function renderPagination() {
|
|
renderSmartPagination('pagination', currentPage, totalPages, function(page) {
|
|
loadStudents(page);
|
|
});
|
|
}
|
|
|
|
function showSinglePointsModal(studentId, studentName) {
|
|
window.selectedStudentIds = [studentId];
|
|
document.getElementById('selectedStudentsCount').innerHTML = `${studentName} (1人)`;
|
|
document.getElementById('pointsChange').value = '';
|
|
document.getElementById('pointsReason').value = '';
|
|
document.getElementById('batchPointsModal').style.display = 'flex';
|
|
}
|
|
|
|
async function unlockStudent(studentNo, studentName) {
|
|
if (!confirm(`确定要解除学生 "${studentName}" 的登录锁定吗?\n(适用于多次登录失败被禁止登录的情况)`)) {
|
|
return;
|
|
}
|
|
|
|
const res = await apiPost('/api/admin/unlock-user', {
|
|
username: studentNo
|
|
});
|
|
|
|
if (res && res.success) {
|
|
showToast(res.message || '解锁成功');
|
|
} else {
|
|
showToast(res?.message || '解锁失败', 'error');
|
|
}
|
|
}
|
|
|
|
loadStudents();
|
|
|
|
let searchTimeout;
|
|
document.getElementById('searchInput').addEventListener('input', () => {
|
|
clearTimeout(searchTimeout);
|
|
searchTimeout = setTimeout(() => loadStudents(1), 500);
|
|
});
|
|
|
|
window.loadStudents = loadStudents;
|
|
window.showSinglePointsModal = showSinglePointsModal;
|
|
window.unlockStudent = unlockStudent;
|
|
|
|
})();
|