feat: 多班级版班级管理系统 v2.0
技术栈:Go (Gin + GORM) + PHP + MySQL 5.7 + Redis 主要功能: - 多班级完全隔离(class_id 贯穿全系统) - 后端 Go Gin(端口 56789),Nginx 反代 - 超级管理员独立登录(env 配置,默认账密 admin/Admin123) - bcrypt 密码加密(无 PASSWORD_SALT) - 科任老师/课代表新角色 - 课代表作业管理页面 - 排行榜分项排行(操行分/考勤/作业) - 角色加减分上下限由班主任配置 - 家长改密功能(可开关) - 班级角色按需开关 - 宿舍号格式:南0-000 - 周度/月度重置功能 - MySQL 5.7 兼容 - 43 轮代码审查 + 全部修复 开发者: Canglan 版权归属: Sea Network Technology Studio 许可证: Apache License 2.0
This commit is contained in:
120
frontend/assets/js/dashboard.js
Normal file
120
frontend/assets/js/dashboard.js
Normal file
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* 多班级版班级管理系统 - 管理端首页JS
|
||||
*
|
||||
* 开发者: Canglan
|
||||
* 版权归属: Sea Network Technology Studio
|
||||
*
|
||||
* 版权所有 © Sea Network Technology Studio
|
||||
*/
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
const role = window.PAGE_CONFIG.role;
|
||||
let totalStudents = 0;
|
||||
|
||||
async function loadDashboard() {
|
||||
// 并行加载学生数据和学期信息
|
||||
const [studentsRes, semesterRes] = await Promise.all([
|
||||
apiGet('/api/admin/students'),
|
||||
apiGet('/api/semester/active')
|
||||
]);
|
||||
|
||||
let statsHtml = '';
|
||||
if (studentsRes && studentsRes.success) {
|
||||
statsHtml += `
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">学生总数</div>
|
||||
<div class="stat-value">${studentsRes.data.total || 0}</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// 显示学期信息和当前周数
|
||||
if (semesterRes && semesterRes.success && semesterRes.data) {
|
||||
const sem = semesterRes.data;
|
||||
const weekNum = sem.current_week;
|
||||
let semesterInfo = escapeHtml(sem.semester_name);
|
||||
if (weekNum && weekNum > 0) {
|
||||
semesterInfo += ` · 第${weekNum}周`;
|
||||
}
|
||||
statsHtml += `
|
||||
<div class="stat-card">
|
||||
<div class="stat-label">当前学期</div>
|
||||
<div class="stat-value" style="font-size:20px;">${semesterInfo}</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
document.getElementById('dashboardStats').innerHTML = statsHtml;
|
||||
|
||||
let quickActions = '';
|
||||
if (role === '班主任' || role === '班长' || role === '学习委员' || role === '劳动委员' || role === '志愿委员') {
|
||||
quickActions += '<button class="btn btn-primary" onclick="location.href=\'/admin/conduct.php\'">操行分管理</button>';
|
||||
}
|
||||
if (role === '班主任' || role === '学习委员') {
|
||||
quickActions += '<button class="btn btn-primary" onclick="location.href=\'/admin/homework.php\'">作业扣分</button>';
|
||||
}
|
||||
if (role === '班主任' || role === '考勤委员') {
|
||||
quickActions += '<button class="btn btn-primary" onclick="location.href=\'/admin/attendance.php\'">考勤管理</button>';
|
||||
}
|
||||
if (role === '班主任') {
|
||||
quickActions += '<button class="btn btn-outline" onclick="location.href=\'/admin/students.php\'">导入学生</button>';
|
||||
quickActions += '<button class="btn btn-secondary" onclick="location.href=\'/admin/conduct.php\'">导出德育分记录</button>';
|
||||
}
|
||||
document.getElementById('quickActions').innerHTML = quickActions || '<p>暂无快捷操作</p>';
|
||||
|
||||
const rankingRes = await apiGet('/api/student/ranking', { limit: 100 });
|
||||
if (rankingRes && rankingRes.success) {
|
||||
totalStudents = rankingRes.data.total_students || 0;
|
||||
let html = '';
|
||||
rankingRes.data.ranking.forEach((student, index) => {
|
||||
const rank = index + 1;
|
||||
html += `<tr>
|
||||
<td>${rank}</td>
|
||||
<td>${escapeHtml(student.student_no)}</td>
|
||||
<td>${escapeHtml(student.name)}</td>
|
||||
<td>${student.total_points}</td>
|
||||
</tr>`;
|
||||
});
|
||||
if (rankingRes.data.ranking.length === 0) {
|
||||
html = '<tr><td colspan="4" style="text-align:center;">暂无数据</td></tr>';
|
||||
}
|
||||
document.getElementById('rankingList').innerHTML = html;
|
||||
}
|
||||
}
|
||||
|
||||
function applyPercentileFilter() {
|
||||
const input = document.getElementById('percentileFilter');
|
||||
const percentile = parseInt(input.value);
|
||||
if (isNaN(percentile) || percentile < 1 || percentile > 100) {
|
||||
showToast('请输入 1-100 之间的整数', 'error');
|
||||
return;
|
||||
}
|
||||
const rows = document.getElementById('rankingList').querySelectorAll('tr');
|
||||
if (rows.length === 0) return;
|
||||
const showCount = Math.max(1, Math.floor(totalStudents * (percentile / 100)));
|
||||
rows.forEach(function(row, index) {
|
||||
row.style.display = index < showCount ? '' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
function resetPercentileFilter() {
|
||||
document.getElementById('percentileFilter').value = 100;
|
||||
const rows = document.getElementById('rankingList').querySelectorAll('tr');
|
||||
rows.forEach(function(row) {
|
||||
row.style.display = '';
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('percentileFilter').addEventListener('keypress', function(e) {
|
||||
if (e.key === 'Enter') applyPercentileFilter();
|
||||
});
|
||||
|
||||
loadDashboard();
|
||||
|
||||
window.loadDashboard = loadDashboard;
|
||||
window.applyPercentileFilter = applyPercentileFilter;
|
||||
window.resetPercentileFilter = resetPercentileFilter;
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user