refactor(frontend): 重构前端目录结构并优化认证流程
将前端文件从html目录迁移到views目录,按功能模块组织 重构认证中间件和路由处理,简化页面权限控制 更新静态资源引用路径,统一使用/public前缀 添加学生仪表板页面,优化移动端显示 移除旧版html和js文件,更新样式和脚本
This commit is contained in:
@@ -52,65 +52,72 @@ app.use(session({
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// 静态文件服务
|
// 静态文件服务 - 只公开 public 目录
|
||||||
app.use(express.static(path.join(__dirname, '../frontend')));
|
app.use('/public', express.static(path.join(__dirname, '../frontend/public')));
|
||||||
|
|
||||||
// 重定向旧路径 /frontend/html/* 到 /html/*
|
// 页面认证中间件
|
||||||
app.get('/frontend/html/*', (req, res) => {
|
const requirePageAuth = (req, res, next) => {
|
||||||
const path = req.params[0];
|
if (!req.session.user) {
|
||||||
res.redirect(`/html/${path}`);
|
return res.redirect('/login');
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
|
||||||
|
const requirePageRole = (allowedRoles) => {
|
||||||
|
return (req, res, next) => {
|
||||||
|
if (!req.session.user) return res.redirect('/login');
|
||||||
|
if (!allowedRoles.includes(req.session.user.role)) {
|
||||||
|
return res.status(403).send('<h1>403 Forbidden - 权限不足</h1><a href="/dashboard">返回首页</a>');
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// 页面路由
|
||||||
|
app.get('/', (req, res) => res.redirect('/login'));
|
||||||
|
app.get('/login', (req, res) => {
|
||||||
|
if (req.session.user) return res.redirect('/dashboard');
|
||||||
|
res.sendFile(path.join(__dirname, '../frontend/views/auth/login.html'));
|
||||||
|
});
|
||||||
|
app.get('/register', (req, res) => res.sendFile(path.join(__dirname, '../frontend/views/auth/register.html')));
|
||||||
|
|
||||||
|
app.get('/dashboard', requirePageAuth, (req, res) => {
|
||||||
|
const role = req.session.user?.role;
|
||||||
|
switch (role) {
|
||||||
|
case 'student': res.redirect('/student/dashboard'); break;
|
||||||
|
case 'teacher': res.redirect('/teacher/dashboard'); break;
|
||||||
|
case 'admin': res.redirect('/admin/dashboard'); break;
|
||||||
|
default: res.redirect('/login');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 路由
|
// 学生页面
|
||||||
|
app.get('/student/dashboard', requirePageAuth, requirePageRole(['student']), (req, res) => {
|
||||||
|
res.sendFile(path.join(__dirname, '../frontend/views/student/dashboard.html'));
|
||||||
|
});
|
||||||
|
|
||||||
|
// 教师页面
|
||||||
|
const teacherRouter = express.Router();
|
||||||
|
teacherRouter.use(requirePageAuth, requirePageRole(['teacher']));
|
||||||
|
teacherRouter.get('/dashboard', (req, res) => res.sendFile(path.join(__dirname, '../frontend/views/teacher/dashboard.html')));
|
||||||
|
teacherRouter.get('/grade_entry', (req, res) => res.sendFile(path.join(__dirname, '../frontend/views/teacher/grade_entry.html')));
|
||||||
|
teacherRouter.get('/grade_management', (req, res) => res.sendFile(path.join(__dirname, '../frontend/views/teacher/grade_management.html')));
|
||||||
|
app.use('/teacher', teacherRouter);
|
||||||
|
|
||||||
|
// 管理员页面
|
||||||
|
const adminRouter = express.Router();
|
||||||
|
adminRouter.use(requirePageAuth, requirePageRole(['admin']));
|
||||||
|
adminRouter.get('/dashboard', (req, res) => res.sendFile(path.join(__dirname, '../frontend/views/admin/dashboard.html')));
|
||||||
|
adminRouter.get('/student_management', (req, res) => res.sendFile(path.join(__dirname, '../frontend/views/admin/student_management.html')));
|
||||||
|
adminRouter.get('/user_management', (req, res) => res.sendFile(path.join(__dirname, '../frontend/views/admin/user_management.html')));
|
||||||
|
app.use('/admin', adminRouter);
|
||||||
|
|
||||||
|
// API 路由
|
||||||
app.use('/api/auth', authRoutes);
|
app.use('/api/auth', authRoutes);
|
||||||
app.use('/api/student', studentRoutes);
|
app.use('/api/student', studentRoutes);
|
||||||
app.use('/api/teacher', teacherRoutes);
|
app.use('/api/teacher', teacherRoutes);
|
||||||
app.use('/api/admin', adminRoutes);
|
app.use('/api/admin', adminRoutes);
|
||||||
|
|
||||||
// 认证中间件
|
|
||||||
const { requireAuth, requireRole } = require('./middleware/auth');
|
|
||||||
|
|
||||||
// 页面路由
|
|
||||||
app.get('/', (req, res) => {
|
|
||||||
res.sendFile(path.join(__dirname, '../frontend/html/login.html'));
|
|
||||||
});
|
|
||||||
|
|
||||||
app.get('/dashboard', requireAuth, (req, res) => {
|
|
||||||
// 根据用户角色重定向到不同的仪表板
|
|
||||||
const role = req.session.user?.role;
|
|
||||||
|
|
||||||
switch (role) {
|
|
||||||
case 'student':
|
|
||||||
res.redirect('/html/student_dashboard.html');
|
|
||||||
break;
|
|
||||||
case 'teacher':
|
|
||||||
res.redirect('/html/teacher_dashboard.html');
|
|
||||||
break;
|
|
||||||
case 'admin':
|
|
||||||
res.redirect('/html/admin_dashboard.html');
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// 如果没有角色信息,重定向到登录页面
|
|
||||||
res.redirect('/');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 学生页面路由
|
|
||||||
app.get('/student/*', requireAuth, requireRole(['student', 'admin', 'teacher']), (req, res, next) => {
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 教师页面路由
|
|
||||||
app.get('/teacher/*', requireAuth, requireRole(['teacher', 'admin']), (req, res, next) => {
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 管理员页面路由
|
|
||||||
app.get('/admin/*', requireAuth, requireRole(['admin']), (req, res, next) => {
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 404处理
|
// 404处理
|
||||||
app.use((req, res) => {
|
app.use((req, res) => {
|
||||||
res.status(404).json({ error: 'Not found' });
|
res.status(404).json({ error: 'Not found' });
|
||||||
|
|||||||
@@ -1,269 +0,0 @@
|
|||||||
class AuthManager {
|
|
||||||
constructor() {
|
|
||||||
// 动态设置API基础URL,支持file:///协议和localhost:3000访问
|
|
||||||
this.apiBase = window.location.protocol === 'file:' ? 'http://localhost:3000/api' : '/api';
|
|
||||||
this.initEventListeners();
|
|
||||||
this.checkAuthStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
async checkAuthStatus() {
|
|
||||||
try {
|
|
||||||
const response = await fetch(`${this.apiBase}/auth/me`);
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
if (data.success && data.user) {
|
|
||||||
// 用户已登录,根据角色重定向到正确的仪表板
|
|
||||||
const userRole = data.user.role;
|
|
||||||
let redirectUrl = '/dashboard';
|
|
||||||
|
|
||||||
if (userRole === 'student') {
|
|
||||||
redirectUrl = '/frontend/html/student_dashboard.html';
|
|
||||||
} else if (userRole === 'teacher') {
|
|
||||||
redirectUrl = '/frontend/html/teacher_dashboard.html';
|
|
||||||
} else if (userRole === 'admin') {
|
|
||||||
redirectUrl = '/frontend/html/admin_dashboard.html';
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果当前页面是登录或注册页面,则重定向到仪表板
|
|
||||||
const currentPath = window.location.pathname;
|
|
||||||
if (currentPath.includes('login.html') || currentPath.includes('register.html')) {
|
|
||||||
window.location.href = redirectUrl;
|
|
||||||
}
|
|
||||||
// 如果当前页面不是正确的仪表板页面,则重定向
|
|
||||||
else if (!currentPath.includes(redirectUrl) &&
|
|
||||||
currentPath !== '/' &&
|
|
||||||
!currentPath.includes('index.html')) {
|
|
||||||
window.location.href = redirectUrl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log('用户未登录');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
initEventListeners() {
|
|
||||||
// 登录表单提交
|
|
||||||
const loginForm = document.getElementById('loginForm');
|
|
||||||
if (loginForm) {
|
|
||||||
loginForm.addEventListener('submit', (e) => this.handleLogin(e));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注册表单提交
|
|
||||||
const registerForm = document.getElementById('registerForm');
|
|
||||||
if (registerForm) {
|
|
||||||
registerForm.addEventListener('submit', (e) => this.handleRegister(e));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 登出按钮
|
|
||||||
const logoutBtn = document.getElementById('logoutBtn');
|
|
||||||
if (logoutBtn) {
|
|
||||||
logoutBtn.addEventListener('click', (e) => this.handleLogout(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async handleLogin(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const form = e.target;
|
|
||||||
const formData = new FormData(form);
|
|
||||||
const data = Object.fromEntries(formData.entries());
|
|
||||||
|
|
||||||
const submitBtn = form.querySelector('button[type="submit"]');
|
|
||||||
const originalText = submitBtn.innerHTML;
|
|
||||||
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 登录中...';
|
|
||||||
submitBtn.disabled = true;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(`${this.apiBase}/auth/login`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify(data)
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await response.json();
|
|
||||||
|
|
||||||
if (result.success) {
|
|
||||||
this.showNotification('登录成功!正在跳转...', 'success');
|
|
||||||
|
|
||||||
// 根据用户角色跳转到不同的仪表板
|
|
||||||
const userRole = result.user?.role;
|
|
||||||
let redirectUrl = '/dashboard';
|
|
||||||
|
|
||||||
if (userRole === 'student') {
|
|
||||||
redirectUrl = '/frontend/html/student_dashboard.html';
|
|
||||||
} else if (userRole === 'teacher') {
|
|
||||||
redirectUrl = '/frontend/html/teacher_dashboard.html';
|
|
||||||
} else if (userRole === 'admin') {
|
|
||||||
redirectUrl = '/frontend/html/admin_dashboard.html';
|
|
||||||
}
|
|
||||||
|
|
||||||
// 延迟跳转以显示通知
|
|
||||||
setTimeout(() => {
|
|
||||||
window.location.href = redirectUrl;
|
|
||||||
}, 1500);
|
|
||||||
} else {
|
|
||||||
this.showNotification(result.message || '登录失败', 'error');
|
|
||||||
submitBtn.innerHTML = originalText;
|
|
||||||
submitBtn.disabled = false;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('登录错误:', error);
|
|
||||||
this.showNotification('网络错误,请重试', 'error');
|
|
||||||
submitBtn.innerHTML = originalText;
|
|
||||||
submitBtn.disabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async handleRegister(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const form = e.target;
|
|
||||||
const formData = new FormData(form);
|
|
||||||
const data = Object.fromEntries(formData.entries());
|
|
||||||
|
|
||||||
// 验证密码
|
|
||||||
if (data.password !== data.confirmPassword) {
|
|
||||||
this.showNotification('两次输入的密码不一致', 'error');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const submitBtn = form.querySelector('button[type="submit"]');
|
|
||||||
const originalText = submitBtn.innerHTML;
|
|
||||||
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 注册中...';
|
|
||||||
submitBtn.disabled = true;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(`${this.apiBase}/auth/register`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify(data)
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await response.json();
|
|
||||||
|
|
||||||
if (result.success) {
|
|
||||||
this.showNotification('注册成功!正在跳转到登录页面...', 'success');
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
window.location.href = '/html/login.html';
|
|
||||||
}, 1500);
|
|
||||||
} else {
|
|
||||||
this.showNotification(result.message || '注册失败', 'error');
|
|
||||||
submitBtn.innerHTML = originalText;
|
|
||||||
submitBtn.disabled = false;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('注册错误:', error);
|
|
||||||
this.showNotification('网络错误,请重试', 'error');
|
|
||||||
submitBtn.innerHTML = originalText;
|
|
||||||
submitBtn.disabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async handleLogout(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
if (!confirm('确定要退出登录吗?')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(`${this.apiBase}/auth/logout`, {
|
|
||||||
method: 'POST'
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await response.json();
|
|
||||||
|
|
||||||
if (result.success) {
|
|
||||||
this.showNotification('已成功退出登录', 'success');
|
|
||||||
setTimeout(() => {
|
|
||||||
window.location.href = '/';
|
|
||||||
}, 1000);
|
|
||||||
} else {
|
|
||||||
this.showNotification('退出登录失败', 'error');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('退出登录错误:', error);
|
|
||||||
this.showNotification('网络错误,请重试', 'error');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
showNotification(message, type = 'info') {
|
|
||||||
// 移除现有的通知
|
|
||||||
const existingNotification = document.querySelector('.notification');
|
|
||||||
if (existingNotification) {
|
|
||||||
existingNotification.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建新的通知
|
|
||||||
const notification = document.createElement('div');
|
|
||||||
notification.className = `notification notification-${type}`;
|
|
||||||
notification.innerHTML = `
|
|
||||||
<i class="fas fa-${type === 'success' ? 'check-circle' : 'exclamation-circle'}"></i>
|
|
||||||
<span>${message}</span>
|
|
||||||
`;
|
|
||||||
|
|
||||||
// 样式
|
|
||||||
notification.style.cssText = `
|
|
||||||
position: fixed;
|
|
||||||
top: 20px;
|
|
||||||
right: 20px;
|
|
||||||
background: ${type === 'success' ? '#10b981' : type === 'error' ? '#ef4444' : '#3b82f6'};
|
|
||||||
color: white;
|
|
||||||
padding: 15px 20px;
|
|
||||||
border-radius: 8px;
|
|
||||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
z-index: 1000;
|
|
||||||
animation: slideIn 0.3s ease;
|
|
||||||
`;
|
|
||||||
|
|
||||||
document.body.appendChild(notification);
|
|
||||||
|
|
||||||
// 3秒后自动移除
|
|
||||||
setTimeout(() => {
|
|
||||||
notification.style.animation = 'slideOut 0.3s ease';
|
|
||||||
setTimeout(() => notification.remove(), 300);
|
|
||||||
}, 3000);
|
|
||||||
|
|
||||||
// 添加动画关键帧
|
|
||||||
if (!document.querySelector('#notification-styles')) {
|
|
||||||
const style = document.createElement('style');
|
|
||||||
style.id = 'notification-styles';
|
|
||||||
style.textContent = `
|
|
||||||
@keyframes slideIn {
|
|
||||||
from {
|
|
||||||
transform: translateX(100%);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: translateX(0);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes slideOut {
|
|
||||||
from {
|
|
||||||
transform: translateX(0);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: translateX(100%);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
document.head.appendChild(style);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化认证管理器
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
window.authManager = new AuthManager();
|
|
||||||
});
|
|
||||||
47
frontend/public/css/notification.css
Normal file
47
frontend/public/css/notification.css
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/* 通知消息样式 */
|
||||||
|
.notification {
|
||||||
|
position: fixed;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
padding: 15px 25px;
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 1000;
|
||||||
|
transform: translateX(120%);
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
border-left: 4px solid #4e73df;
|
||||||
|
max-width: 350px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification.show {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification.success {
|
||||||
|
border-left-color: #2ecc71;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification.error {
|
||||||
|
border-left-color: #e74c3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification i {
|
||||||
|
margin-right: 10px;
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification.success i {
|
||||||
|
color: #2ecc71;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification.error i {
|
||||||
|
color: #e74c3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-content {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -11,9 +11,8 @@ class AdminDashboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
// 检查登录状态
|
// 璉<EFBFBD><EFBFBD>亦蒈敶閧𠶖<EFBFBD>? if (!await this.checkAuth()) {
|
||||||
if (!await this.checkAuth()) {
|
window.location.href = '/login';
|
||||||
window.location.href = '/frontend/html/login.html';
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,8 +31,7 @@ class AdminDashboard {
|
|||||||
// 更新界面
|
// 更新界面
|
||||||
this.updateUI();
|
this.updateUI();
|
||||||
|
|
||||||
// 初始化图表
|
// <EFBFBD>嘥<EFBFBD><EFBFBD>硋㦛銵? this.initCharts();
|
||||||
this.initCharts();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkAuth() {
|
async checkAuth() {
|
||||||
@@ -49,7 +47,7 @@ class AdminDashboard {
|
|||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
return data.success && data.user.role === 'admin';
|
return data.success && data.user.role === 'admin';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('认证检查失败:', error);
|
console.error('霈方<EFBFBD>璉<EFBFBD><EFBFBD>亙仃韐?', error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -234,8 +232,7 @@ class AdminDashboard {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 退出登录
|
// <EFBFBD><EFBFBD><EFBFBD>箇蒈敶? document.getElementById('logoutBtn')?.addEventListener('click', () => {
|
||||||
document.getElementById('logoutBtn')?.addEventListener('click', () => {
|
|
||||||
this.handleLogout();
|
this.handleLogout();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -247,23 +244,20 @@ class AdminDashboard {
|
|||||||
|
|
||||||
async loadPage(page) {
|
async loadPage(page) {
|
||||||
// 这里可以实现页面切换逻辑
|
// 这里可以实现页面切换逻辑
|
||||||
// 暂时使用简单跳转
|
// <EFBFBD><EFBFBD>𧒄雿輻鍂蝞<EFBFBD><EFBFBD>閗歲頧? switch (page) {
|
||||||
switch (page) {
|
|
||||||
case 'users':
|
case 'users':
|
||||||
window.location.href = '/frontend/html/user_management.html';
|
window.location.href = '/admin/user_management';
|
||||||
break;
|
break;
|
||||||
case 'students':
|
case 'students':
|
||||||
window.location.href = '/frontend/html/student_management.html';
|
window.location.href = '/admin/student_management';
|
||||||
break;
|
break;
|
||||||
case 'teachers':
|
case 'teachers':
|
||||||
// 可以跳转到教师管理页面
|
// <EFBFBD>臭誑頝唾蓮<EFBFBD>唳<EFBFBD>撣<EFBFBD>恣<EFBFBD><EFBFBD>△<EFBFBD>? break;
|
||||||
break;
|
|
||||||
case 'grades':
|
case 'grades':
|
||||||
window.location.href = '/frontend/html/grade_management.html';
|
window.location.href = '/teacher/grade_management';
|
||||||
break;
|
break;
|
||||||
case 'settings':
|
case 'settings':
|
||||||
// 可以跳转到系统设置页面
|
// <EFBFBD>臭誑頝唾蓮<EFBFBD>啁頂蝏蠘挽蝵桅△<EFBFBD>? break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,7 +268,7 @@ class AdminDashboard {
|
|||||||
const className = document.getElementById('classFilter')?.value || '';
|
const className = document.getElementById('classFilter')?.value || '';
|
||||||
|
|
||||||
// 这里可以实现搜索逻辑
|
// 这里可以实现搜索逻辑
|
||||||
this.showNotification('搜索功能待实现', 'info');
|
this.showNotification('<EFBFBD>𦦵揣<EFBFBD>蠘<EFBFBD>敺<EFBFBD><EFBFBD><EFBFBD>?, 'info');
|
||||||
}
|
}
|
||||||
|
|
||||||
resetFilters() {
|
resetFilters() {
|
||||||
@@ -291,10 +285,10 @@ class AdminDashboard {
|
|||||||
// 这里可以打开添加用户模态框
|
// 这里可以打开添加用户模态框
|
||||||
const userData = {
|
const userData = {
|
||||||
user_id: prompt('请输入用户ID:'),
|
user_id: prompt('请输入用户ID:'),
|
||||||
full_name: prompt('请输入姓名:'),
|
full_name: prompt('霂瑁<EFBFBD><EFBFBD>亙<EFBFBD><EFBFBD>?'),
|
||||||
role: prompt('请输入角色 (admin/teacher/student):'),
|
role: prompt('霂瑁<EFBFBD><EFBFBD>亥<EFBFBD><EFBFBD>?(admin/teacher/student):'),
|
||||||
email: prompt('请输入邮箱:'),
|
email: prompt('霂瑁<EFBFBD><EFBFBD>仿<EFBFBD>蝞?'),
|
||||||
class_name: prompt('请输入班级 (学生/教师可选):')
|
class_name: prompt('霂瑁<EFBFBD><EFBFBD>亦号蝥?(摮衣<E691AE>/<2F>坔<EFBFBD><E59D94>舫<EFBFBD>?:')
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!userData.user_id || !userData.full_name || !userData.role) {
|
if (!userData.user_id || !userData.full_name || !userData.role) {
|
||||||
@@ -353,7 +347,7 @@ class AdminDashboard {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!confirm(`确定要删除选中的 ${checkboxes.length} 个用户吗?`)) {
|
if (!confirm(`蝖桀<EFBFBD>閬<EFBFBD><EFBFBD><EFBFBD>日<EFBFBD>劐葉<EFBFBD>?${checkboxes.length} 銝芰鍂<EFBFBD>瑕<EFBFBD>嚗鬮)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -385,10 +379,10 @@ class AdminDashboard {
|
|||||||
if (!user) return;
|
if (!user) return;
|
||||||
|
|
||||||
// 这里可以打开编辑模态框
|
// 这里可以打开编辑模态框
|
||||||
const newName = prompt('请输入新的姓名:', user.full_name);
|
const newName = prompt('霂瑁<EFBFBD><EFBFBD>交鰵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?', user.full_name);
|
||||||
if (newName === null) return;
|
if (newName === null) return;
|
||||||
|
|
||||||
const newRole = prompt('请输入新的角色:', user.role);
|
const newRole = prompt('霂瑁<EFBFBD><EFBFBD>交鰵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?', user.role);
|
||||||
if (newRole === null) return;
|
if (newRole === null) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -418,7 +412,7 @@ class AdminDashboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async deleteUser(userId) {
|
async deleteUser(userId) {
|
||||||
if (!confirm('确定要删除这个用户吗?')) {
|
if (!confirm('蝖桀<EFBFBD>閬<EFBFBD><EFBFBD><EFBFBD>方<EFBFBD>銝芰鍂<EFBFBD>瑕<EFBFBD>嚗?)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -449,17 +443,17 @@ class AdminDashboard {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
window.location.href = '/html/login.html';
|
window.location.href = '/login';
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('退出登录失败:', error);
|
console.error('<EFBFBD><EFBFBD><EFBFBD>箇蒈敶訫仃韐?', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async refreshData() {
|
async refreshData() {
|
||||||
await this.loadStats();
|
await this.loadStats();
|
||||||
await this.loadUsers();
|
await this.loadUsers();
|
||||||
this.showNotification('数据已刷新', 'success');
|
this.showNotification('<EFBFBD>唳旿撌脣<EFBFBD><EFBFBD>?, 'success');
|
||||||
}
|
}
|
||||||
|
|
||||||
updateUI() {
|
updateUI() {
|
||||||
@@ -473,11 +467,9 @@ class AdminDashboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async initCharts() {
|
async initCharts() {
|
||||||
// 加载Chart.js库
|
// <EFBFBD>㰘蝸Chart.js摨? await this.loadChartLibrary();
|
||||||
await this.loadChartLibrary();
|
|
||||||
|
|
||||||
// 初始化用户分布饼图
|
// <EFBFBD>嘥<EFBFBD><EFBFBD>𣇉鍂<EFBFBD>瑕<EFBFBD>撣<EFBFBD>未<EFBFBD>? this.initUserDistributionChart();
|
||||||
this.initUserDistributionChart();
|
|
||||||
|
|
||||||
// 初始化成绩分布柱状图
|
// 初始化成绩分布柱状图
|
||||||
this.initGradeDistributionChart();
|
this.initGradeDistributionChart();
|
||||||
@@ -493,8 +485,7 @@ class AdminDashboard {
|
|||||||
<button class="notification-close">×</button>
|
<button class="notification-close">×</button>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// 添加到页面
|
// 瘛餃<EFBFBD><EFBFBD>圈△<EFBFBD>? document.body.appendChild(notification);
|
||||||
document.body.appendChild(notification);
|
|
||||||
|
|
||||||
// 添加关闭事件
|
// 添加关闭事件
|
||||||
notification.querySelector('.notification-close').addEventListener('click', () => {
|
notification.querySelector('.notification-close').addEventListener('click', () => {
|
||||||
@@ -527,7 +518,7 @@ class AdminDashboard {
|
|||||||
|
|
||||||
// 模拟数据
|
// 模拟数据
|
||||||
const data = {
|
const data = {
|
||||||
labels: ['学生', '教师', '管理员'],
|
labels: ['摮衣<EFBFBD>', '<EFBFBD>坔<EFBFBD>', '蝞∠<EFBFBD><EFBFBD>?],
|
||||||
datasets: [{
|
datasets: [{
|
||||||
data: [this.stats.totalStudents || 100, this.stats.totalTeachers || 20, 1],
|
data: [this.stats.totalStudents || 100, this.stats.totalTeachers || 20, 1],
|
||||||
backgroundColor: [
|
backgroundColor: [
|
||||||
@@ -589,3 +580,4 @@ class AdminDashboard {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
287
frontend/public/js/auth.js
Normal file
287
frontend/public/js/auth.js
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
/**
|
||||||
|
* 认证模块管理器
|
||||||
|
* 处理登录、注册、注销及权限检查
|
||||||
|
*/
|
||||||
|
class AuthManager {
|
||||||
|
constructor() {
|
||||||
|
this.apiBase = '/api';
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.createNotificationContainer();
|
||||||
|
this.initEventListeners();
|
||||||
|
this.checkAuthStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建通知容器
|
||||||
|
*/
|
||||||
|
createNotificationContainer() {
|
||||||
|
if (!document.getElementById('notification-container')) {
|
||||||
|
const container = document.createElement('div');
|
||||||
|
container.id = 'notification-container';
|
||||||
|
container.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
z-index: 9999;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
`;
|
||||||
|
document.body.appendChild(container);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查用户认证状态
|
||||||
|
*/
|
||||||
|
async checkAuthStatus() {
|
||||||
|
// 如果当前是公共页面,可以选择不检查,或者检查后更新UI
|
||||||
|
const currentPath = window.location.pathname;
|
||||||
|
const isAuthPage = currentPath.includes('/login') || currentPath.includes('/register');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${this.apiBase}/auth/me`);
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (data.success && data.user) {
|
||||||
|
// 用户已登录
|
||||||
|
const redirectUrl = this.getDashboardUrl(data.user.role);
|
||||||
|
|
||||||
|
// 如果在登录/注册页,跳转到仪表板
|
||||||
|
if (isAuthPage || currentPath === '/') {
|
||||||
|
window.location.href = redirectUrl;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 用户未登录,如果在受保护页面,跳转到登录页
|
||||||
|
// 注意:后端通常已经处理了重定向,这里是前端的额外保障
|
||||||
|
if (!isAuthPage && currentPath !== '/') {
|
||||||
|
// 可以在这里添加逻辑,但通常交给后端控制
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Auth check failed:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getDashboardUrl(role) {
|
||||||
|
switch(role) {
|
||||||
|
case 'student': return '/student/dashboard';
|
||||||
|
case 'teacher': return '/teacher/dashboard';
|
||||||
|
case 'admin': return '/admin/dashboard';
|
||||||
|
default: return '/dashboard';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initEventListeners() {
|
||||||
|
// 登录表单
|
||||||
|
const loginForm = document.getElementById('loginForm');
|
||||||
|
if (loginForm) {
|
||||||
|
loginForm.addEventListener('submit', (e) => this.handleLogin(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册表单
|
||||||
|
const registerForm = document.getElementById('registerForm');
|
||||||
|
if (registerForm) {
|
||||||
|
registerForm.addEventListener('submit', (e) => this.handleRegister(e));
|
||||||
|
|
||||||
|
// 角色选择联动
|
||||||
|
const roleSelect = document.getElementById('role');
|
||||||
|
if (roleSelect) {
|
||||||
|
roleSelect.addEventListener('change', (e) => this.handleRoleChange(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注销按钮 (可能有多个,例如在导航栏)
|
||||||
|
document.querySelectorAll('.btn-logout, #logoutBtn').forEach(btn => {
|
||||||
|
btn.addEventListener('click', (e) => this.handleLogout(e));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleRoleChange(e) {
|
||||||
|
const role = e.target.value;
|
||||||
|
const classField = document.getElementById('classField');
|
||||||
|
const classInput = document.getElementById('class');
|
||||||
|
|
||||||
|
if (classField && classInput) {
|
||||||
|
if (role === 'student' || role === 'teacher') {
|
||||||
|
classField.style.display = 'block';
|
||||||
|
classInput.required = true;
|
||||||
|
} else {
|
||||||
|
classField.style.display = 'none';
|
||||||
|
classInput.required = false;
|
||||||
|
classInput.value = ''; // 清空值
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleLogin(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const form = e.target;
|
||||||
|
const submitBtn = form.querySelector('button[type="submit"]');
|
||||||
|
|
||||||
|
if (this.setLoading(submitBtn, true, '登录中...')) {
|
||||||
|
try {
|
||||||
|
const formData = new FormData(form);
|
||||||
|
const data = Object.fromEntries(formData.entries());
|
||||||
|
|
||||||
|
const response = await fetch(`${this.apiBase}/auth/login`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
this.showNotification('登录成功,正在跳转...', 'success');
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = this.getDashboardUrl(result.user.role);
|
||||||
|
}, 1000);
|
||||||
|
} else {
|
||||||
|
this.showNotification(result.message || '登录失败', 'error');
|
||||||
|
this.setLoading(submitBtn, false);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Login error:', error);
|
||||||
|
this.showNotification('网络错误,请稍后重试', 'error');
|
||||||
|
this.setLoading(submitBtn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleRegister(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const form = e.target;
|
||||||
|
const submitBtn = form.querySelector('button[type="submit"]');
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
const formData = new FormData(form);
|
||||||
|
const data = Object.fromEntries(formData.entries());
|
||||||
|
|
||||||
|
// 简单验证
|
||||||
|
if (data.password !== data.confirmPassword) {
|
||||||
|
this.showNotification('两次输入的密码不一致', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.setLoading(submitBtn, true, '注册中...')) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${this.apiBase}/auth/register`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
this.showNotification('注册成功,请登录', 'success');
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = '/login';
|
||||||
|
}, 1500);
|
||||||
|
} else {
|
||||||
|
this.showNotification(result.message || '注册失败', 'error');
|
||||||
|
this.setLoading(submitBtn, false);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Register error:', error);
|
||||||
|
this.showNotification('网络错误,请稍后重试', 'error');
|
||||||
|
this.setLoading(submitBtn, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleLogout(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
if (confirm('确定要退出登录吗?')) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${this.apiBase}/auth/logout`, {
|
||||||
|
method: 'POST'
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
this.showNotification('已退出登录', 'success');
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = '/login';
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Logout error:', error);
|
||||||
|
// 即使出错也强制跳转到登录页
|
||||||
|
window.location.href = '/login';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置按钮加载状态
|
||||||
|
* @param {HTMLElement} btn 按钮元素
|
||||||
|
* @param {boolean} isLoading 是否正在加载
|
||||||
|
* @param {string} text 加载时的文本
|
||||||
|
* @returns {boolean} true表示状态设置成功
|
||||||
|
*/
|
||||||
|
setLoading(btn, isLoading, text = '') {
|
||||||
|
if (!btn) return false;
|
||||||
|
|
||||||
|
if (isLoading) {
|
||||||
|
if (btn.dataset.loading) return false; // 防止重复提交
|
||||||
|
btn.dataset.loading = 'true';
|
||||||
|
btn.dataset.originalText = btn.innerHTML;
|
||||||
|
btn.innerHTML = `<i class="fas fa-spinner fa-spin"></i> ${text}`;
|
||||||
|
btn.disabled = true;
|
||||||
|
} else {
|
||||||
|
btn.innerHTML = btn.dataset.originalText || btn.innerHTML;
|
||||||
|
delete btn.dataset.loading;
|
||||||
|
btn.disabled = false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示通知
|
||||||
|
* @param {string} message 消息内容
|
||||||
|
* @param {string} type 消息类型 'success' | 'error' | 'info'
|
||||||
|
*/
|
||||||
|
showNotification(message, type = 'info') {
|
||||||
|
const container = document.getElementById('notification-container');
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
const notification = document.createElement('div');
|
||||||
|
notification.className = `notification ${type}`;
|
||||||
|
|
||||||
|
let icon = 'info-circle';
|
||||||
|
if (type === 'success') icon = 'check-circle';
|
||||||
|
if (type === 'error') icon = 'exclamation-circle';
|
||||||
|
|
||||||
|
notification.innerHTML = `
|
||||||
|
<i class="fas fa-${icon}"></i>
|
||||||
|
<span class="notification-content">${message}</span>
|
||||||
|
`;
|
||||||
|
|
||||||
|
container.appendChild(notification);
|
||||||
|
|
||||||
|
// 动画显示
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
notification.classList.add('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 自动消失
|
||||||
|
setTimeout(() => {
|
||||||
|
notification.classList.remove('show');
|
||||||
|
notification.addEventListener('transitionend', () => {
|
||||||
|
notification.remove();
|
||||||
|
});
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
window.authManager = new AuthManager();
|
||||||
|
});
|
||||||
@@ -7,8 +7,7 @@ class MainPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
// 初始化所有功能
|
// åˆ<EFBFBD>始化所有功èƒ? this.initNavbar();
|
||||||
this.initNavbar();
|
|
||||||
this.initScrollEffects();
|
this.initScrollEffects();
|
||||||
this.initSmoothScroll();
|
this.initSmoothScroll();
|
||||||
this.initBackToTop();
|
this.initBackToTop();
|
||||||
@@ -30,8 +29,7 @@ class MainPage {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 初始化当前页面高亮
|
// åˆ<EFBFBD>始化当å‰<EFBFBD>页é<EFBFBD>¢é«˜äº? this.highlightCurrentPage();
|
||||||
this.highlightCurrentPage();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 高亮当前页面导航链接
|
// 高亮当前页面导航链接
|
||||||
@@ -47,9 +45,8 @@ class MainPage {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化滚动效果
|
// åˆ<EFBFBD>始化滚动效æž? initScrollEffects() {
|
||||||
initScrollEffects() {
|
// 滚动时显ç¤?éš<C3A9>è—<C3A8>å…ƒç´
|
||||||
// 滚动时显示/隐藏元素
|
|
||||||
const observerOptions = {
|
const observerOptions = {
|
||||||
root: null,
|
root: null,
|
||||||
rootMargin: '0px',
|
rootMargin: '0px',
|
||||||
@@ -70,8 +67,7 @@ class MainPage {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化平滑滚动
|
// åˆ<EFBFBD>始化平滑滚åŠ? initSmoothScroll() {
|
||||||
initSmoothScroll() {
|
|
||||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||||
anchor.addEventListener('click', (e) => {
|
anchor.addEventListener('click', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -89,15 +85,14 @@ class MainPage {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化返回顶部按钮
|
// åˆ<EFBFBD>始化返回顶部按é’? initBackToTop() {
|
||||||
initBackToTop() {
|
|
||||||
const backToTopBtn = document.createElement('button');
|
const backToTopBtn = document.createElement('button');
|
||||||
backToTopBtn.id = 'backToTop';
|
backToTopBtn.id = 'backToTop';
|
||||||
backToTopBtn.innerHTML = '<i class="fas fa-chevron-up"></i>';
|
backToTopBtn.innerHTML = '<i class="fas fa-chevron-up"></i>';
|
||||||
backToTopBtn.title = '返回顶部';
|
backToTopBtn.title = '返回顶部';
|
||||||
document.body.appendChild(backToTopBtn);
|
document.body.appendChild(backToTopBtn);
|
||||||
|
|
||||||
// 滚动时显示/隐藏按钮
|
// 滚动时显ç¤?éš<C3A9>è—<C3A8>按钮
|
||||||
window.addEventListener('scroll', () => {
|
window.addEventListener('scroll', () => {
|
||||||
if (window.scrollY > 300) {
|
if (window.scrollY > 300) {
|
||||||
backToTopBtn.classList.add('show');
|
backToTopBtn.classList.add('show');
|
||||||
@@ -136,8 +131,7 @@ class MainPage {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化认证按钮状态
|
// åˆ<EFBFBD>始化认è¯<EFBFBD>按钮状æ€? initAuthButtons() {
|
||||||
initAuthButtons() {
|
|
||||||
// 检查用户是否已登录
|
// 检查用户是否已登录
|
||||||
this.checkLoginStatus().then(user => {
|
this.checkLoginStatus().then(user => {
|
||||||
const loginBtn = document.getElementById('loginBtn');
|
const loginBtn = document.getElementById('loginBtn');
|
||||||
@@ -145,23 +139,22 @@ class MainPage {
|
|||||||
const heroLoginBtn = document.getElementById('heroLoginBtn');
|
const heroLoginBtn = document.getElementById('heroLoginBtn');
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
// 用户已登录,显示仪表板按钮
|
// 用户已登录,显示仪表æ<EFBFBD>¿æŒ‰é’? // æ ¹æ<C2B9>®ç”¨æˆ·è§’色设置æ£ç¡®çš„仪表æ<C2A8>¿è·¯å¾„
|
||||||
// 根据用户角色设置正确的仪表板路径
|
|
||||||
let dashboardUrl = '/dashboard';
|
let dashboardUrl = '/dashboard';
|
||||||
if (user.role === 'student') {
|
if (user.role === 'student') {
|
||||||
dashboardUrl = '/frontend/html/student_dashboard.html';
|
dashboardUrl = '/student/dashboard';
|
||||||
} else if (user.role === 'teacher') {
|
} else if (user.role === 'teacher') {
|
||||||
dashboardUrl = '/frontend/html/teacher_dashboard.html';
|
dashboardUrl = '/teacher/dashboard';
|
||||||
} else if (user.role === 'admin') {
|
} else if (user.role === 'admin') {
|
||||||
dashboardUrl = '/frontend/html/admin_dashboard.html';
|
dashboardUrl = '/admin/dashboard';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loginBtn) {
|
if (loginBtn) {
|
||||||
loginBtn.textContent = '进入仪表板';
|
loginBtn.textContent = '进入仪表æ<EFBFBD>?;
|
||||||
loginBtn.href = dashboardUrl;
|
loginBtn.href = dashboardUrl;
|
||||||
}
|
}
|
||||||
if (heroLoginBtn) {
|
if (heroLoginBtn) {
|
||||||
heroLoginBtn.textContent = '进入仪表板';
|
heroLoginBtn.textContent = '进入仪表æ<EFBFBD>?;
|
||||||
heroLoginBtn.href = dashboardUrl;
|
heroLoginBtn.href = dashboardUrl;
|
||||||
}
|
}
|
||||||
if (registerBtn) {
|
if (registerBtn) {
|
||||||
@@ -171,15 +164,14 @@ class MainPage {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查登录状态
|
// 检查登录状� async checkLoginStatus() {
|
||||||
async checkLoginStatus() {
|
|
||||||
try {
|
try {
|
||||||
const apiBase = window.location.protocol === 'file:' ? 'http://localhost:3000/api' : '/api';
|
const apiBase = window.location.protocol === 'file:' ? 'http://localhost:3000/api' : '/api';
|
||||||
const response = await fetch(`${apiBase}/auth/me`);
|
const response = await fetch(`${apiBase}/auth/me`);
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
return data.success && data.user;
|
return data.success && data.user;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('用户未登录');
|
console.log('用户未登�);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,8 +188,7 @@ class MainPage {
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// 添加到页面
|
// æ·»åŠ åˆ°é¡µé<EFBFBD>? document.body.appendChild(notification);
|
||||||
document.body.appendChild(notification);
|
|
||||||
|
|
||||||
// 显示通知
|
// 显示通知
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -219,4 +210,4 @@ class MainPage {
|
|||||||
// 页面加载完成后初始化
|
// 页面加载完成后初始化
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
new MainPage();
|
new MainPage();
|
||||||
});
|
});
|
||||||
@@ -19,10 +19,10 @@ class StudentManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (response.status === 401) {
|
if (response.status === 401) {
|
||||||
// 未登录,重定向到登录页
|
// <EFBFBD>芰蒈敶𤏪<EFBFBD><EFBFBD>滚<EFBFBD><EFBFBD>穃<EFBFBD><EFBFBD>餃<EFBFBD>憿?
|
||||||
this.showNotification('请先登录', 'error');
|
this.showNotification('请先登录', 'error');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.href = '/html/login.html';
|
window.location.href = '/login';
|
||||||
}, 1500);
|
}, 1500);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -113,14 +113,14 @@ class StudentManager {
|
|||||||
<i class="fas fa-star"></i>
|
<i class="fas fa-star"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-value">${statistics.totalCredits}</div>
|
<div class="stat-value">${statistics.totalCredits}</div>
|
||||||
<div class="stat-label">总学分</div>
|
<div class="stat-label"><EFBFBD>餃郎<EFBFBD>?/div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="stat-icon grade">
|
<div class="stat-icon grade">
|
||||||
<i class="fas fa-chart-line"></i>
|
<i class="fas fa-chart-line"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-value">${statistics.averageScore}</div>
|
<div class="stat-value">${statistics.averageScore}</div>
|
||||||
<div class="stat-label">平均分</div>
|
<div class="stat-label">撟喳<EFBFBD><EFBFBD>?/div>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
<div class="stat-icon teacher">
|
<div class="stat-icon teacher">
|
||||||
@@ -143,10 +143,10 @@ class StudentManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (response.status === 401) {
|
if (response.status === 401) {
|
||||||
// 未登录,重定向到登录页
|
// <EFBFBD>芰蒈敶𤏪<EFBFBD><EFBFBD>滚<EFBFBD><EFBFBD>穃<EFBFBD><EFBFBD>餃<EFBFBD>憿?
|
||||||
this.showNotification('请先登录', 'error');
|
this.showNotification('请先登录', 'error');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.href = '/html/login.html';
|
window.location.href = '/login';
|
||||||
}, 1500);
|
}, 1500);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -156,7 +156,7 @@ class StudentManager {
|
|||||||
if (data.success) {
|
if (data.success) {
|
||||||
const profile = data.profile;
|
const profile = data.profile;
|
||||||
|
|
||||||
// 更新学生仪表板顶部信息
|
// <EFBFBD>湔鰵摮衣<EFBFBD>隞芾”<EFBFBD>輸▲<EFBFBD>其縑<EFBFBD>?
|
||||||
const userNameElement = document.getElementById('userName');
|
const userNameElement = document.getElementById('userName');
|
||||||
const studentNameElement = document.getElementById('studentName');
|
const studentNameElement = document.getElementById('studentName');
|
||||||
const studentClassElement = document.getElementById('studentClass');
|
const studentClassElement = document.getElementById('studentClass');
|
||||||
@@ -168,7 +168,7 @@ class StudentManager {
|
|||||||
studentNameElement.textContent = profile.full_name || profile.username;
|
studentNameElement.textContent = profile.full_name || profile.username;
|
||||||
}
|
}
|
||||||
if (studentClassElement) {
|
if (studentClassElement) {
|
||||||
studentClassElement.textContent = profile.class_name || '未设置';
|
studentClassElement.textContent = profile.class_name || '<EFBFBD>芾挽蝵?;
|
||||||
}
|
}
|
||||||
|
|
||||||
profileElement.innerHTML = `
|
profileElement.innerHTML = `
|
||||||
@@ -202,14 +202,14 @@ class StudentManager {
|
|||||||
<i class="fas fa-book"></i>
|
<i class="fas fa-book"></i>
|
||||||
<div>
|
<div>
|
||||||
<h4>专业</h4>
|
<h4>专业</h4>
|
||||||
<p>${profile.major || '未设置'}</p>
|
<p>${profile.major || '<EFBFBD>芾挽蝵?}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-item">
|
<div class="detail-item">
|
||||||
<i class="fas fa-calendar-alt"></i>
|
<i class="fas fa-calendar-alt"></i>
|
||||||
<div>
|
<div>
|
||||||
<h4>入学年份</h4>
|
<h4>入学年份</h4>
|
||||||
<p>${profile.enrollment_year || '未设置'}</p>
|
<p>${profile.enrollment_year || '<EFBFBD>芾挽蝵?}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -258,14 +258,14 @@ class StudentManager {
|
|||||||
else if (grade.score >= 80) gradeDescription = '良好';
|
else if (grade.score >= 80) gradeDescription = '良好';
|
||||||
else if (grade.score >= 70) gradeDescription = '中等';
|
else if (grade.score >= 70) gradeDescription = '中等';
|
||||||
else if (grade.score >= 60) gradeDescription = '及格';
|
else if (grade.score >= 60) gradeDescription = '及格';
|
||||||
else gradeDescription = '不及格';
|
else gradeDescription = '銝滚<EFBFBD><EFBFBD>?;
|
||||||
|
|
||||||
container.innerHTML = `
|
container.innerHTML = `
|
||||||
<div class="grade-detail-card">
|
<div class="grade-detail-card">
|
||||||
<div class="grade-header">
|
<div class="grade-header">
|
||||||
<h2>${grade.course_name} (${grade.course_code})</h2>
|
<h2>${grade.course_name} (${grade.course_code})</h2>
|
||||||
<div class="grade-score ${grade.score >= 60 ? 'score-pass' : 'score-fail'}">
|
<div class="grade-score ${grade.score >= 60 ? 'score-pass' : 'score-fail'}">
|
||||||
${grade.score} 分
|
${grade.score} <EFBFBD>?
|
||||||
<span class="grade-description">${gradeDescription}</span>
|
<span class="grade-description">${gradeDescription}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -274,23 +274,23 @@ class StudentManager {
|
|||||||
<div class="detail-section">
|
<div class="detail-section">
|
||||||
<h3><i class="fas fa-info-circle"></i> 基本信息</h3>
|
<h3><i class="fas fa-info-circle"></i> 基本信息</h3>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span>学分:</span>
|
<span>摮血<EFBFBD>嚗?/span>
|
||||||
<strong>${grade.credit}</strong>
|
<strong>${grade.credit}</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span>学期:</span>
|
<span>摮行<EFBFBD>嚗?/span>
|
||||||
<strong>${grade.semester}</strong>
|
<strong>${grade.semester}</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span>考试日期:</span>
|
<span><EFBFBD><EFBFBD><EFBFBD><EFBFBD>交<EFBFBD>嚗?/span>
|
||||||
<strong>${new Date(grade.exam_date).toLocaleDateString()}</strong>
|
<strong>${new Date(grade.exam_date).toLocaleDateString()}</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span>等级:</span>
|
<span>蝑厩漣嚗?/span>
|
||||||
<strong class="grade-level-${grade.grade_level}">${grade.grade_level || '-'}</strong>
|
<strong class="grade-level-${grade.grade_level}">${grade.grade_level || '-'}</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span>绩点:</span>
|
<span>蝏拍<EFBFBD>嚗?/span>
|
||||||
<strong>${grade.grade_point || '-'}</strong>
|
<strong>${grade.grade_point || '-'}</strong>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -298,31 +298,31 @@ class StudentManager {
|
|||||||
<div class="detail-section">
|
<div class="detail-section">
|
||||||
<h3><i class="fas fa-user-graduate"></i> 学生信息</h3>
|
<h3><i class="fas fa-user-graduate"></i> 学生信息</h3>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span>姓名:</span>
|
<span>憪枏<EFBFBD>嚗?/span>
|
||||||
<strong>${grade.full_name}</strong>
|
<strong>${grade.full_name}</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span>学号:</span>
|
<span>摮血噡嚗?/span>
|
||||||
<strong>${grade.student_number}</strong>
|
<strong>${grade.student_number}</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span>班级:</span>
|
<span><EFBFBD>剔漣嚗?/span>
|
||||||
<strong>${grade.class_name}</strong>
|
<strong>${grade.class_name}</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span>专业:</span>
|
<span>銝㮖<EFBFBD>嚗?/span>
|
||||||
<strong>${grade.major || '未设置'}</strong>
|
<strong>${grade.major || '<EFBFBD>芾挽蝵?}</strong>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="detail-section">
|
<div class="detail-section">
|
||||||
<h3><i class="fas fa-chalkboard-teacher"></i> 教师信息</h3>
|
<h3><i class="fas fa-chalkboard-teacher"></i> 教师信息</h3>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span>任课教师:</span>
|
<span>隞餉紋<EFBFBD>坔<EFBFBD>嚗?/span>
|
||||||
<strong>${grade.teacher_name}</strong>
|
<strong>${grade.teacher_name}</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span>教师邮箱:</span>
|
<span><EFBFBD>坔<EFBFBD><EFBFBD>桃拳嚗?/span>
|
||||||
<strong>${grade.teacher_email}</strong>
|
<strong>${grade.teacher_email}</strong>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -337,7 +337,7 @@ class StudentManager {
|
|||||||
|
|
||||||
<div class="grade-actions">
|
<div class="grade-actions">
|
||||||
<button onclick="window.print()" class="btn btn-secondary">
|
<button onclick="window.print()" class="btn btn-secondary">
|
||||||
<i class="fas fa-print"></i> 打印成绩单
|
<i class="fas fa-print"></i> <EFBFBD>枏㫲<EFBFBD>鞟貍<EFBFBD>?
|
||||||
</button>
|
</button>
|
||||||
<button onclick="window.history.back()" class="btn btn-primary">
|
<button onclick="window.history.back()" class="btn btn-primary">
|
||||||
<i class="fas fa-arrow-left"></i> 返回
|
<i class="fas fa-arrow-left"></i> 返回
|
||||||
@@ -352,7 +352,7 @@ class StudentManager {
|
|||||||
if (!ctx) return;
|
if (!ctx) return;
|
||||||
|
|
||||||
if (typeof Chart === 'undefined') {
|
if (typeof Chart === 'undefined') {
|
||||||
// 如果没有Chart.js,延迟加载
|
// 憒<EFBFBD><EFBFBD>瘝⊥<EFBFBD>Chart.js嚗<EFBFBD>辣餈笔<EFBFBD>頧?
|
||||||
this.loadChartLibrary().then(() => this.updateChart(grades));
|
this.loadChartLibrary().then(() => this.updateChart(grades));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -360,7 +360,7 @@ class StudentManager {
|
|||||||
const courseNames = grades.map(g => g.course_name);
|
const courseNames = grades.map(g => g.course_name);
|
||||||
const scores = grades.map(g => g.score);
|
const scores = grades.map(g => g.score);
|
||||||
|
|
||||||
// 销毁现有图表实例
|
// <EFBFBD><EFBFBD>瘥<EFBFBD>緵<EFBFBD>匧㦛銵典<EFBFBD>靘?
|
||||||
if (window.gradeChart instanceof Chart) {
|
if (window.gradeChart instanceof Chart) {
|
||||||
window.gradeChart.destroy();
|
window.gradeChart.destroy();
|
||||||
}
|
}
|
||||||
@@ -421,7 +421,7 @@ class StudentManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showNotification(message, type = 'info') {
|
showNotification(message, type = 'info') {
|
||||||
// 使用AuthManager的通知系统或自己实现
|
// 雿輻鍂AuthManager<EFBFBD><EFBFBD><EFBFBD>𡁶䰻蝟餌<EFBFBD><EFBFBD>𤥁䌊撌勗<EFBFBD><EFBFBD>?
|
||||||
if (window.authManager && window.authManager.showNotification) {
|
if (window.authManager && window.authManager.showNotification) {
|
||||||
window.authManager.showNotification(message, type);
|
window.authManager.showNotification(message, type);
|
||||||
} else {
|
} else {
|
||||||
@@ -435,4 +435,4 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
if (window.location.pathname.includes('/student/')) {
|
if (window.location.pathname.includes('/student/')) {
|
||||||
window.studentManager = new StudentManager();
|
window.studentManager = new StudentManager();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -9,9 +9,8 @@ class TeacherDashboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
// 检查登录状态
|
// 璉<EFBFBD><EFBFBD>亦蒈敶閧𠶖<EFBFBD>? if (!await this.checkAuth()) {
|
||||||
if (!await this.checkAuth()) {
|
window.location.href = '/login';
|
||||||
window.location.href = '/frontend/html/login.html';
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +43,7 @@ class TeacherDashboard {
|
|||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
return data.success && data.user.role === 'teacher';
|
return data.success && data.user.role === 'teacher';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('认证检查失败:', error);
|
console.error('霈方<EFBFBD>璉<EFBFBD><EFBFBD>亙仃韐?', error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,8 +107,7 @@ class TeacherDashboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
populateCourseSelectors() {
|
populateCourseSelectors() {
|
||||||
// 填充课程选择器
|
// 憛怠<EFBFBD>霂曄<EFBFBD><EFBFBD>㗇𥋘<EFBFBD>? const courseSelectors = document.querySelectorAll('.course-selector');
|
||||||
const courseSelectors = document.querySelectorAll('.course-selector');
|
|
||||||
courseSelectors.forEach(select => {
|
courseSelectors.forEach(select => {
|
||||||
select.innerHTML = '<option value="">请选择课程</option>';
|
select.innerHTML = '<option value="">请选择课程</option>';
|
||||||
this.courses.forEach(course => {
|
this.courses.forEach(course => {
|
||||||
@@ -153,7 +151,7 @@ class TeacherDashboard {
|
|||||||
<span class="grade-score">${grade.score}</span>
|
<span class="grade-score">${grade.score}</span>
|
||||||
<span class="grade-level">${grade.grade_level}</span>
|
<span class="grade-level">${grade.grade_level}</span>
|
||||||
</td>
|
</td>
|
||||||
<td>${grade.exam_date ? new Date(grade.exam_date).toLocaleDateString() : '未设置'}</td>
|
<td>${grade.exam_date ? new Date(grade.exam_date).toLocaleDateString() : '<EFBFBD>芾挽蝵?}</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<button class="btn-edit" data-id="${grade.id}">
|
<button class="btn-edit" data-id="${grade.id}">
|
||||||
@@ -226,8 +224,7 @@ class TeacherDashboard {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 退出登录
|
// <EFBFBD><EFBFBD><EFBFBD>箇蒈敶? document.getElementById('logoutBtn')?.addEventListener('click', () => {
|
||||||
document.getElementById('logoutBtn')?.addEventListener('click', () => {
|
|
||||||
this.handleLogout();
|
this.handleLogout();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -275,7 +272,7 @@ class TeacherDashboard {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!confirm(`确定要删除选中的 ${checkboxes.length} 条成绩记录吗?`)) {
|
if (!confirm(`蝖桀<EFBFBD>閬<EFBFBD><EFBFBD><EFBFBD>日<EFBFBD>劐葉<EFBFBD>?${checkboxes.length} <EFBFBD>⊥<EFBFBD>蝏抵扇敶訫<EFBFBD>嚗鬮)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,12 +305,12 @@ class TeacherDashboard {
|
|||||||
|
|
||||||
// 这里可以打开编辑模态框
|
// 这里可以打开编辑模态框
|
||||||
// 暂时使用简单提示框
|
// 暂时使用简单提示框
|
||||||
const newScore = prompt('请输入新的分数:', grade.score);
|
const newScore = prompt('霂瑁<EFBFBD><EFBFBD>交鰵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?', grade.score);
|
||||||
if (newScore === null) return;
|
if (newScore === null) return;
|
||||||
|
|
||||||
const numericScore = parseFloat(newScore);
|
const numericScore = parseFloat(newScore);
|
||||||
if (isNaN(numericScore) || numericScore < 0 || numericScore > 100) {
|
if (isNaN(numericScore) || numericScore < 0 || numericScore > 100) {
|
||||||
this.showNotification('请输入0-100之间的有效分数', 'error');
|
this.showNotification('霂瑁<EFBFBD><EFBFBD>?-100銋钅𡢿<E99285><F0A1A2BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?, 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,7 +340,7 @@ class TeacherDashboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async deleteGrade(gradeId) {
|
async deleteGrade(gradeId) {
|
||||||
if (!confirm('确定要删除这条成绩记录吗?')) {
|
if (!confirm('蝖桀<EFBFBD>閬<EFBFBD><EFBFBD><EFBFBD>方<EFBFBD><EFBFBD>⊥<EFBFBD>蝏抵扇敶訫<EFBFBD>嚗?)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,10 +371,10 @@ class TeacherDashboard {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
window.location.href = '/frontend/html/login.html';
|
window.location.href = '/login';
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('退出登录失败:', error);
|
console.error('<EFBFBD><EFBFBD><EFBFBD>箇蒈敶訫仃韐?', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,4 +403,4 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
if (window.location.pathname.includes('/teacher/')) {
|
if (window.location.pathname.includes('/teacher/')) {
|
||||||
new TeacherDashboard();
|
new TeacherDashboard();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -4,33 +4,32 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>学生成绩管理系统 - 管理员仪表板</title>
|
<title>学生成绩管理系统 - 管理员仪表板</title>
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="/public/css/style.css">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||||
</head>
|
</head>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- 顶部导航栏 -->
|
<!-- 憿園<EFBFBD>撖潸⏛<EFBFBD>?-->
|
||||||
<nav class="navbar">
|
<nav class="navbar">
|
||||||
<div class="navbar-brand">
|
<div class="navbar-brand">
|
||||||
<i class="fas fa-graduation-cap"></i>
|
<i class="fas fa-graduation-cap"></i>
|
||||||
<span>XX学校成绩管理系统</span>
|
<span>XX学校成绩管理系统</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-menu">
|
<div class="navbar-menu">
|
||||||
<a href="index.html" class="btn btn-secondary">
|
<a href="/" class="btn btn-secondary">
|
||||||
<i class="fas fa-home"></i> 主页
|
<i class="fas fa-home"></i> 主页
|
||||||
</a>
|
</a>
|
||||||
<div class="navbar-user">
|
<div class="navbar-user">
|
||||||
<span class="user-name" id="userName">管理员</span>
|
<span class="user-name" id="userName">蝞∠<EFBFBD><EFBFBD>?/span>
|
||||||
<button id="logoutBtn" class="btn btn-primary">
|
<button id="logoutBtn" class="btn btn-primary">
|
||||||
<i class="fas fa-sign-out-alt"></i> 退出
|
<i class="fas fa-sign-out-alt"></i> <EFBFBD><EFBFBD><EFBFBD>? </button>
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<!-- 仪表板容器 -->
|
<!-- 隞芾”<EFBFBD>踹捆<EFBFBD>?-->
|
||||||
<div class="dashboard-container">
|
<div class="dashboard-container">
|
||||||
<!-- 左侧侧边栏 -->
|
<!-- 撌虫儒靘扯器<EFBFBD>?-->
|
||||||
<aside class="sidebar">
|
<aside class="sidebar">
|
||||||
<div class="sidebar-header">
|
<div class="sidebar-header">
|
||||||
<div class="user-info">
|
<div class="user-info">
|
||||||
@@ -38,8 +37,8 @@
|
|||||||
<i class="fas fa-user-shield"></i>
|
<i class="fas fa-user-shield"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="user-details">
|
<div class="user-details">
|
||||||
<h3 id="adminName">管理员</h3>
|
<h3 id="adminName">蝞∠<EFBFBD><EFBFBD>?/h3>
|
||||||
<p>系统管理员 | 权限:<span id="adminRole">超级管理员</span></p>
|
<p>蝟餌<EFBFBD>蝞∠<EFBFBD><EFBFBD>?| <20><><EFBFBD>嚗?span id="adminRole">頞<>漣蝞∠<E89D9E><E288A0>?/span></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -48,17 +47,17 @@
|
|||||||
<li>
|
<li>
|
||||||
<a href="#" class="active">
|
<a href="#" class="active">
|
||||||
<i class="fas fa-tachometer-alt"></i>
|
<i class="fas fa-tachometer-alt"></i>
|
||||||
<span>仪表板</span>
|
<span>隞芾”<EFBFBD>?/span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="user_management.html">
|
<a href="/admin/user_management">
|
||||||
<i class="fas fa-users"></i>
|
<i class="fas fa-users"></i>
|
||||||
<span>用户管理</span>
|
<span>用户管理</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="student_management.html">
|
<a href="/admin/student_management">
|
||||||
<i class="fas fa-user-graduate"></i>
|
<i class="fas fa-user-graduate"></i>
|
||||||
<span>学生管理</span>
|
<span>学生管理</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -102,7 +101,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<h1 class="page-title">管理员仪表板</h1>
|
<h1 class="page-title">管理员仪表板</h1>
|
||||||
<div class="breadcrumb">
|
<div class="breadcrumb">
|
||||||
<a href="index.html">主页</a>
|
<a href="/">銝駁△</a>
|
||||||
<i class="fas fa-chevron-right"></i>
|
<i class="fas fa-chevron-right"></i>
|
||||||
<span>管理员仪表板</span>
|
<span>管理员仪表板</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -146,8 +145,7 @@
|
|||||||
<div class="stat-value" id="totalTeachers">128</div>
|
<div class="stat-value" id="totalTeachers">128</div>
|
||||||
<div class="stat-label">教师总数</div>
|
<div class="stat-label">教师总数</div>
|
||||||
<div class="stat-change">
|
<div class="stat-change">
|
||||||
<i class="fas fa-minus"></i> 无变化
|
<i class="fas fa-minus"></i> <EFBFBD>惩<EFBFBD><EFBFBD>? </div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -173,8 +171,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<h3 class="function-title">用户管理</h3>
|
<h3 class="function-title">用户管理</h3>
|
||||||
<p class="function-description">
|
<p class="function-description">
|
||||||
管理所有用户账户,包括添加、编辑、删除用户,设置用户角色和权限。
|
蝞∠<EFBFBD><EFBFBD><EFBFBD><EFBFBD>厩鍂<EFBFBD>瑁揭<EFBFBD>瘀<EFBFBD><EFBFBD><EFBFBD>𡠺瘛餃<EFBFBD><EFBFBD><EFBFBD><EFBFBD>颲㻫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>斤鍂<EFBFBD>瘀<EFBFBD>霈曄蔭<EFBFBD>冽<EFBFBD>閫坿𠧧<EFBFBD>峕<EFBFBD><EFBFBD>僐<EFBFBD>? </p>
|
||||||
</p>
|
|
||||||
<button class="btn btn-primary">进入管理</button>
|
<button class="btn btn-primary">进入管理</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -184,8 +181,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<h3 class="function-title">学生管理</h3>
|
<h3 class="function-title">学生管理</h3>
|
||||||
<p class="function-description">
|
<p class="function-description">
|
||||||
管理学生信息,包括学籍管理、班级分配、信息维护和批量导入导出。
|
蝞∠<EFBFBD>摮衣<EFBFBD>靽⊥<EFBFBD>嚗<EFBFBD><EFBFBD><EFBFBD>砍郎蝐滨恣<EFBFBD><EFBFBD><EFBFBD><EFBFBD>号蝥批<EFBFBD><EFBFBD>溻<EFBFBD><EFBFBD>縑<EFBFBD>舐輕<EFBFBD>文<EFBFBD><EFBFBD>寥<EFBFBD>撖澆<EFBFBD>撖澆枂<EFBFBD>? </p>
|
||||||
</p>
|
|
||||||
<button class="btn btn-primary">进入管理</button>
|
<button class="btn btn-primary">进入管理</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -195,8 +191,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<h3 class="function-title">教师管理</h3>
|
<h3 class="function-title">教师管理</h3>
|
||||||
<p class="function-description">
|
<p class="function-description">
|
||||||
管理教师信息,包括教师分配、课程安排、权限设置和绩效考核。
|
蝞∠<EFBFBD><EFBFBD>坔<EFBFBD>靽⊥<EFBFBD>嚗<EFBFBD><EFBFBD><EFBFBD>祆<EFBFBD>撣<EFBFBD><EFBFBD><EFBFBD>溻<EFBFBD><EFBFBD>紋蝔见<EFBFBD><EFBFBD>鉝<EFBFBD><EFBFBD><EFBFBD><EFBFBD>鞱挽蝵桀<EFBFBD>蝏拇<EFBFBD><EFBFBD><EFBFBD>瓲<EFBFBD>? </p>
|
||||||
</p>
|
|
||||||
<button class="btn btn-primary">进入管理</button>
|
<button class="btn btn-primary">进入管理</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -206,30 +201,28 @@
|
|||||||
</div>
|
</div>
|
||||||
<h3 class="function-title">成绩统计</h3>
|
<h3 class="function-title">成绩统计</h3>
|
||||||
<p class="function-description">
|
<p class="function-description">
|
||||||
查看全校成绩统计,生成分析报告,支持图表展示和数据导出。
|
<EFBFBD>亦<EFBFBD><EFBFBD>冽嵗<EFBFBD>鞟貍蝏蠘恣嚗𣬚<EFBFBD><EFBFBD>𣂼<EFBFBD><EFBFBD>鞉𥁒<EFBFBD>𠺪<EFBFBD><EFBFBD>舀<EFBFBD><EFBFBD>曇”撅閧內<EFBFBD>峕㺭<EFBFBD>桀紡<EFBFBD>箝<EFBFBD>? </p>
|
||||||
</p>
|
|
||||||
<button class="btn btn-primary">查看统计</button>
|
<button class="btn btn-primary">查看统计</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 系统状态 -->
|
<!-- 蝟餌<EFBFBD><EFBFBD>嗆<EFBFBD>?-->
|
||||||
<div class="system-status">
|
<div class="system-status">
|
||||||
<h2 class="section-title">
|
<h2 class="section-title">
|
||||||
<i class="fas fa-server"></i>
|
<i class="fas fa-server"></i>
|
||||||
系统状态
|
蝟餌<EFBFBD><EFBFBD>嗆<EFBFBD>? </h2>
|
||||||
</h2>
|
|
||||||
<div class="status-list">
|
<div class="status-list">
|
||||||
<div class="status-item">
|
<div class="status-item">
|
||||||
<div class="status-indicator online"></div>
|
<div class="status-indicator online"></div>
|
||||||
<div>
|
<div>
|
||||||
<div class="status-label">数据库服务</div>
|
<div class="status-label"><EFBFBD>唳旿摨𤘪<EFBFBD><EFBFBD>?/div>
|
||||||
<div class="status-value">运行正常 | 响应时间: 12ms</div>
|
<div class="status-value">运行正常 | 响应时间: 12ms</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="status-item">
|
<div class="status-item">
|
||||||
<div class="status-indicator online"></div>
|
<div class="status-indicator online"></div>
|
||||||
<div>
|
<div>
|
||||||
<div class="status-label">Web服务器</div>
|
<div class="status-label">Web<EFBFBD>滚𦛚<EFBFBD>?/div>
|
||||||
<div class="status-value">运行正常 | 在线用户: 156</div>
|
<div class="status-value">运行正常 | 在线用户: 156</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -237,7 +230,7 @@
|
|||||||
<div class="status-indicator online"></div>
|
<div class="status-indicator online"></div>
|
||||||
<div>
|
<div>
|
||||||
<div class="status-label">文件存储</div>
|
<div class="status-label">文件存储</div>
|
||||||
<div class="status-value">使用率: 65% | 剩余: 35GB</div>
|
<div class="status-value">雿輻鍂<EFBFBD>? 65% | <EFBFBD>拐<EFBFBD>: 35GB</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="status-item">
|
<div class="status-item">
|
||||||
@@ -250,12 +243,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 最近活动 -->
|
<!-- <EFBFBD><EFBFBD>餈烐暑<EFBFBD>?-->
|
||||||
<div class="recent-activities">
|
<div class="recent-activities">
|
||||||
<h2 class="section-title">
|
<h2 class="section-title">
|
||||||
<i class="fas fa-history"></i>
|
<i class="fas fa-history"></i>
|
||||||
最近活动
|
<EFBFBD><EFBFBD>餈烐暑<EFBFBD>? </h2>
|
||||||
</h2>
|
|
||||||
<ul class="activity-list">
|
<ul class="activity-list">
|
||||||
<li class="activity-item">
|
<li class="activity-item">
|
||||||
<div class="activity-icon">
|
<div class="activity-icon">
|
||||||
@@ -263,7 +255,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="activity-content">
|
<div class="activity-content">
|
||||||
<div class="activity-title">新增学生用户</div>
|
<div class="activity-title">新增学生用户</div>
|
||||||
<div class="activity-time">10分钟前 | 操作人: 管理员</div>
|
<div class="activity-time">10<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?| <20>滢<EFBFBD>鈭? 蝞∠<E89D9E><E288A0>?/div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="activity-item">
|
<li class="activity-item">
|
||||||
@@ -272,7 +264,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="activity-content">
|
<div class="activity-content">
|
||||||
<div class="activity-title">修改教师信息</div>
|
<div class="activity-title">修改教师信息</div>
|
||||||
<div class="activity-time">1小时前 | 操作人: 管理员</div>
|
<div class="activity-time">1撠𤩺𧒄<EFBFBD>?| <20>滢<EFBFBD>鈭? 蝞∠<E89D9E><E288A0>?/div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="activity-item">
|
<li class="activity-item">
|
||||||
@@ -281,7 +273,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="activity-content">
|
<div class="activity-content">
|
||||||
<div class="activity-title">生成成绩统计报告</div>
|
<div class="activity-title">生成成绩统计报告</div>
|
||||||
<div class="activity-time">3小时前 | 操作人: 系统</div>
|
<div class="activity-time">3撠𤩺𧒄<EFBFBD>?| <20>滢<EFBFBD>鈭? 蝟餌<E89D9F></div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="activity-item">
|
<li class="activity-item">
|
||||||
@@ -290,7 +282,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="activity-content">
|
<div class="activity-content">
|
||||||
<div class="activity-title">导出用户数据</div>
|
<div class="activity-title">导出用户数据</div>
|
||||||
<div class="activity-time">5小时前 | 操作人: 管理员</div>
|
<div class="activity-time">5撠𤩺𧒄<EFBFBD>?| <20>滢<EFBFBD>鈭? 蝞∠<E89D9E><E288A0>?/div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="activity-item">
|
<li class="activity-item">
|
||||||
@@ -299,7 +291,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="activity-content">
|
<div class="activity-content">
|
||||||
<div class="activity-title">系统设置更新</div>
|
<div class="activity-title">系统设置更新</div>
|
||||||
<div class="activity-time">1天前 | 操作人: 管理员</div>
|
<div class="activity-time">1憭拙<EFBFBD> | <20>滢<EFBFBD>鈭? 蝞∠<E89D9E><E288A0>?/div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -328,16 +320,13 @@
|
|||||||
updateCurrentTime();
|
updateCurrentTime();
|
||||||
setInterval(updateCurrentTime, 1000);
|
setInterval(updateCurrentTime, 1000);
|
||||||
|
|
||||||
// 退出登录
|
// <EFBFBD><EFBFBD><EFBFBD>箇蒈敶? document.getElementById('logoutBtn').addEventListener('click', function() {
|
||||||
document.getElementById('logoutBtn').addEventListener('click', function() {
|
if (confirm('蝖桀<E89D96>閬<EFBFBD><E996AC><EFBFBD><EFBFBD>箇蒈敶訫<E695B6>嚗?)) {
|
||||||
if (confirm('确定要退出登录吗?')) {
|
// 皜<>膄<EFBFBD>餃<EFBFBD><E9A483>嗆<EFBFBD>? localStorage.removeItem('token');
|
||||||
// 清除登录状态
|
|
||||||
localStorage.removeItem('token');
|
|
||||||
localStorage.removeItem('userRole');
|
localStorage.removeItem('userRole');
|
||||||
localStorage.removeItem('userInfo');
|
localStorage.removeItem('userInfo');
|
||||||
|
|
||||||
// 跳转到登录页面
|
// 頝唾蓮<EFBFBD>啁蒈敶閖△<EFBFBD>? window.location.href = 'login.html';
|
||||||
window.location.href = 'login.html';
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -350,4 +339,4 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -4,55 +4,55 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>学生管理 - XX学校成绩管理系统</title>
|
<title>学生管理 - XX学校成绩管理系统</title>
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="/public/css/style.css">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- 导航栏 -->
|
<!-- 撖潸⏛<EFBFBD>?-->
|
||||||
<nav class="navbar">
|
<nav class="navbar">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="navbar-brand">
|
<div class="navbar-brand">
|
||||||
<a href="index.html">
|
<a href="/">
|
||||||
<i class="fas fa-graduation-cap"></i>
|
<i class="fas fa-graduation-cap"></i>
|
||||||
<span>XX学校成绩管理系统</span>
|
<span>XX学校成绩管理系统</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-menu">
|
<div class="navbar-menu">
|
||||||
<a href="index.html" class="navbar-item">
|
<a href="/" class="navbar-item">
|
||||||
<i class="fas fa-home"></i>
|
<i class="fas fa-home"></i>
|
||||||
<span>主页</span>
|
<span>主页</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="admin_dashboard.html" class="navbar-item">
|
<a href="/admin/dashboard" class="navbar-item">
|
||||||
<i class="fas fa-tachometer-alt"></i>
|
<i class="fas fa-tachometer-alt"></i>
|
||||||
<span>控制面板</span>
|
<span>控制面板</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="student_management.html" class="navbar-item active">
|
<a href="/admin/student_management" class="navbar-item active">
|
||||||
<i class="fas fa-users"></i>
|
<i class="fas fa-users"></i>
|
||||||
<span>学生管理</span>
|
<span>学生管理</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="grade_management.html" class="navbar-item">
|
<a href="/teacher/grade_management" class="navbar-item">
|
||||||
<i class="fas fa-chart-bar"></i>
|
<i class="fas fa-chart-bar"></i>
|
||||||
<span>成绩管理</span>
|
<span>成绩管理</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="user_management.html" class="navbar-item">
|
<a href="/admin/user_management" class="navbar-item">
|
||||||
<i class="fas fa-user-cog"></i>
|
<i class="fas fa-user-cog"></i>
|
||||||
<span>用户管理</span>
|
<span>用户管理</span>
|
||||||
</a>
|
</a>
|
||||||
<div class="navbar-user">
|
<div class="navbar-user">
|
||||||
<i class="fas fa-user-circle"></i>
|
<i class="fas fa-user-circle"></i>
|
||||||
<span>管理员</span>
|
<span>蝞∠<EFBFBD><EFBFBD>?/span>
|
||||||
<div class="user-dropdown">
|
<div class="user-dropdown">
|
||||||
<a href="#"><i class="fas fa-user"></i> 个人资料</a>
|
<a href="#"><i class="fas fa-user"></i> 个人资料</a>
|
||||||
<a href="#"><i class="fas fa-cog"></i> 设置</a>
|
<a href="#"><i class="fas fa-cog"></i> 设置</a>
|
||||||
<a href="login.html"><i class="fas fa-sign-out-alt"></i> 退出登录</a>
|
<a href="/login"><i class="fas fa-sign-out-alt"></i> <EFBFBD><EFBFBD><EFBFBD>箇蒈敶?/a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<!-- 主要内容区 -->
|
<!-- 銝餉<EFBFBD><EFBFBD><EFBFBD>捆<EFBFBD>?-->
|
||||||
<main class="main-content">
|
<main class="main-content">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="student-management">
|
<div class="student-management">
|
||||||
@@ -62,35 +62,35 @@
|
|||||||
<p>管理学生基本信息,支持添加、编辑、删除和查询学生信息</p>
|
<p>管理学生基本信息,支持添加、编辑、删除和查询学生信息</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 筛选区域 -->
|
<!-- 蝑偦<EFBFBD>匧躹<EFBFBD>?-->
|
||||||
<div class="filter-section">
|
<div class="filter-section">
|
||||||
<div class="filter-row">
|
<div class="filter-row">
|
||||||
<div class="filter-group">
|
<div class="filter-group">
|
||||||
<label for="student-id"><i class="fas fa-id-card"></i> 学号</label>
|
<label for="student-id"><i class="fas fa-id-card"></i> 学号</label>
|
||||||
<input type="text" id="student-id" placeholder="请输入学号">
|
<input type="text" id="student-id" placeholder="霂瑁<EFBFBD><EFBFBD>亙郎<EFBFBD>?>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-group">
|
<div class="filter-group">
|
||||||
<label for="student-name"><i class="fas fa-user"></i> 姓名</label>
|
<label for="student-name"><i class="fas fa-user"></i> 姓名</label>
|
||||||
<input type="text" id="student-name" placeholder="请输入姓名">
|
<input type="text" id="student-name" placeholder="霂瑁<EFBFBD><EFBFBD>亙<EFBFBD><EFBFBD>?>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-group">
|
<div class="filter-group">
|
||||||
<label for="class-select"><i class="fas fa-school"></i> 班级</label>
|
<label for="class-select"><i class="fas fa-school"></i> 班级</label>
|
||||||
<select id="class-select">
|
<select id="class-select">
|
||||||
<option value="">全部班级</option>
|
<option value="">全部班级</option>
|
||||||
<option value="计算机科学与技术1班">计算机科学与技术1班</option>
|
<option value="霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?>霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?/option>
|
||||||
<option value="计算机科学与技术2班">计算机科学与技术2班</option>
|
<option value="霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?>霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?/option>
|
||||||
<option value="软件工程1班">软件工程1班</option>
|
<option value="頧臭辣撌亦<EFBFBD>1<EFBFBD>?>頧臭辣撌亦<EFBFBD>1<EFBFBD>?/option>
|
||||||
<option value="软件工程2班">软件工程2班</option>
|
<option value="頧臭辣撌亦<EFBFBD>2<EFBFBD>?>頧臭辣撌亦<EFBFBD>2<EFBFBD>?/option>
|
||||||
<option value="网络工程1班">网络工程1班</option>
|
<option value="蝵𤑳<EFBFBD>撌亦<EFBFBD>1<EFBFBD>?>蝵𤑳<EFBFBD>撌亦<EFBFBD>1<EFBFBD>?/option>
|
||||||
<option value="网络工程2班">网络工程2班</option>
|
<option value="蝵𤑳<EFBFBD>撌亦<EFBFBD>2<EFBFBD>?>蝵𤑳<EFBFBD>撌亦<EFBFBD>2<EFBFBD>?/option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-group">
|
<div class="filter-group">
|
||||||
<label for="gender-select"><i class="fas fa-venus-mars"></i> 性别</label>
|
<label for="gender-select"><i class="fas fa-venus-mars"></i> 性别</label>
|
||||||
<select id="gender-select">
|
<select id="gender-select">
|
||||||
<option value="">全部性别</option>
|
<option value="">全部性别</option>
|
||||||
<option value="男">男</option>
|
<option value="<EFBFBD>?><EFBFBD>?/option>
|
||||||
<option value="女">女</option>
|
<option value="憟?>憟?/option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -131,7 +131,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="student-table-body">
|
<tbody id="student-table-body">
|
||||||
<!-- 数据将通过JavaScript动态加载 -->
|
<!-- <EFBFBD>唳旿撠<EFBFBD><EFBFBD>朞<EFBFBD>JavaScript<EFBFBD>冽<EFBFBD><EFBFBD><EFBFBD>頧?-->
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="8" class="loading">
|
<td colspan="8" class="loading">
|
||||||
<i class="fas fa-spinner fa-spin"></i>
|
<i class="fas fa-spinner fa-spin"></i>
|
||||||
@@ -146,14 +146,12 @@
|
|||||||
<div class="pagination" id="pagination">
|
<div class="pagination" id="pagination">
|
||||||
<button id="prev-btn" disabled>
|
<button id="prev-btn" disabled>
|
||||||
<i class="fas fa-chevron-left"></i>
|
<i class="fas fa-chevron-left"></i>
|
||||||
上一页
|
銝𠹺<EFBFBD>憿? </button>
|
||||||
</button>
|
|
||||||
<button class="active">1</button>
|
<button class="active">1</button>
|
||||||
<button>2</button>
|
<button>2</button>
|
||||||
<button>3</button>
|
<button>3</button>
|
||||||
<button id="next-btn">
|
<button id="next-btn">
|
||||||
下一页
|
銝衤<EFBFBD>憿? <i class="fas fa-chevron-right"></i>
|
||||||
<i class="fas fa-chevron-right"></i>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -163,8 +161,8 @@
|
|||||||
<!-- 页脚 -->
|
<!-- 页脚 -->
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<p>© 2023 XX学校成绩管理系统. 版权所有.</p>
|
<p>穢 2023 XX摮行嵗<EFBFBD>鞟貍蝞∠<EFBFBD>蝟餌<EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?</p>
|
||||||
<p>技术支持: 计算机科学与技术学院</p>
|
<p><EFBFBD><EFBFBD><EFBFBD>舀𣈲<EFBFBD>? 霈∠<E99C88><E288A0>箇<EFBFBD>摮虫<E691AE><E899AB><EFBFBD><EFBFBD>臬郎<E887AC>?/p>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
@@ -174,8 +172,8 @@
|
|||||||
{
|
{
|
||||||
id: '20230001',
|
id: '20230001',
|
||||||
name: '张三',
|
name: '张三',
|
||||||
gender: '男',
|
gender: '<EFBFBD>?,
|
||||||
class: '计算机科学与技术1班',
|
class: '霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?,
|
||||||
phone: '13800138001',
|
phone: '13800138001',
|
||||||
email: 'zhangsan@example.com',
|
email: 'zhangsan@example.com',
|
||||||
enrollmentDate: '2023-09-01'
|
enrollmentDate: '2023-09-01'
|
||||||
@@ -183,8 +181,8 @@
|
|||||||
{
|
{
|
||||||
id: '20230002',
|
id: '20230002',
|
||||||
name: '李四',
|
name: '李四',
|
||||||
gender: '女',
|
gender: '憟?,
|
||||||
class: '计算机科学与技术1班',
|
class: '霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?,
|
||||||
phone: '13800138002',
|
phone: '13800138002',
|
||||||
email: 'lisi@example.com',
|
email: 'lisi@example.com',
|
||||||
enrollmentDate: '2023-09-01'
|
enrollmentDate: '2023-09-01'
|
||||||
@@ -192,8 +190,8 @@
|
|||||||
{
|
{
|
||||||
id: '20230003',
|
id: '20230003',
|
||||||
name: '王五',
|
name: '王五',
|
||||||
gender: '男',
|
gender: '<EFBFBD>?,
|
||||||
class: '计算机科学与技术2班',
|
class: '霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?,
|
||||||
phone: '13800138003',
|
phone: '13800138003',
|
||||||
email: 'wangwu@example.com',
|
email: 'wangwu@example.com',
|
||||||
enrollmentDate: '2023-09-01'
|
enrollmentDate: '2023-09-01'
|
||||||
@@ -201,8 +199,8 @@
|
|||||||
{
|
{
|
||||||
id: '20230004',
|
id: '20230004',
|
||||||
name: '赵六',
|
name: '赵六',
|
||||||
gender: '女',
|
gender: '憟?,
|
||||||
class: '软件工程1班',
|
class: '頧臭辣撌亦<EFBFBD>1<EFBFBD>?,
|
||||||
phone: '13800138004',
|
phone: '13800138004',
|
||||||
email: 'zhaoliu@example.com',
|
email: 'zhaoliu@example.com',
|
||||||
enrollmentDate: '2023-09-01'
|
enrollmentDate: '2023-09-01'
|
||||||
@@ -210,8 +208,8 @@
|
|||||||
{
|
{
|
||||||
id: '20230005',
|
id: '20230005',
|
||||||
name: '钱七',
|
name: '钱七',
|
||||||
gender: '男',
|
gender: '<EFBFBD>?,
|
||||||
class: '软件工程2班',
|
class: '頧臭辣撌亦<EFBFBD>2<EFBFBD>?,
|
||||||
phone: '13800138005',
|
phone: '13800138005',
|
||||||
email: 'qianqi@example.com',
|
email: 'qianqi@example.com',
|
||||||
enrollmentDate: '2023-09-01'
|
enrollmentDate: '2023-09-01'
|
||||||
@@ -219,8 +217,8 @@
|
|||||||
{
|
{
|
||||||
id: '20230006',
|
id: '20230006',
|
||||||
name: '孙八',
|
name: '孙八',
|
||||||
gender: '男',
|
gender: '<EFBFBD>?,
|
||||||
class: '网络工程1班',
|
class: '蝵𤑳<EFBFBD>撌亦<EFBFBD>1<EFBFBD>?,
|
||||||
phone: '13800138006',
|
phone: '13800138006',
|
||||||
email: 'sunba@example.com',
|
email: 'sunba@example.com',
|
||||||
enrollmentDate: '2023-09-01'
|
enrollmentDate: '2023-09-01'
|
||||||
@@ -228,8 +226,8 @@
|
|||||||
{
|
{
|
||||||
id: '20230007',
|
id: '20230007',
|
||||||
name: '周九',
|
name: '周九',
|
||||||
gender: '女',
|
gender: '憟?,
|
||||||
class: '网络工程2班',
|
class: '蝵𤑳<EFBFBD>撌亦<EFBFBD>2<EFBFBD>?,
|
||||||
phone: '13800138007',
|
phone: '13800138007',
|
||||||
email: 'zhoujiu@example.com',
|
email: 'zhoujiu@example.com',
|
||||||
enrollmentDate: '2023-09-01'
|
enrollmentDate: '2023-09-01'
|
||||||
@@ -237,16 +235,15 @@
|
|||||||
{
|
{
|
||||||
id: '20230008',
|
id: '20230008',
|
||||||
name: '吴十',
|
name: '吴十',
|
||||||
gender: '男',
|
gender: '<EFBFBD>?,
|
||||||
class: '计算机科学与技术1班',
|
class: '霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?,
|
||||||
phone: '13800138008',
|
phone: '13800138008',
|
||||||
email: 'wushi@example.com',
|
email: 'wushi@example.com',
|
||||||
enrollmentDate: '2023-09-01'
|
enrollmentDate: '2023-09-01'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
// 当前页数据
|
// 敶枏<EFBFBD>憿菜㺭<EFBFBD>? let currentPage = 1;
|
||||||
let currentPage = 1;
|
|
||||||
const pageSize = 5;
|
const pageSize = 5;
|
||||||
let filteredStudents = [...mockStudents];
|
let filteredStudents = [...mockStudents];
|
||||||
|
|
||||||
@@ -272,7 +269,7 @@
|
|||||||
<td colspan="8" class="no-results">
|
<td colspan="8" class="no-results">
|
||||||
<i class="fas fa-user-slash"></i>
|
<i class="fas fa-user-slash"></i>
|
||||||
<h3>没有找到学生信息</h3>
|
<h3>没有找到学生信息</h3>
|
||||||
<p>请尝试调整筛选条件或添加新学生</p>
|
<p>霂瑕<EFBFBD>霂閗<EFBFBD><EFBFBD>渡<EFBFBD><EFBFBD>㗇辺隞嗆<EFBFBD>瘛餃<EFBFBD><EFBFBD>啣郎<EFBFBD>?/p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
`;
|
`;
|
||||||
@@ -325,13 +322,11 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 更新上一页/下一页按钮状态
|
// <EFBFBD>湔鰵銝𠹺<EFBFBD>憿?銝衤<E98A9D>憿菜<E686BF><E88F9C>桃𠶖<E6A183>? prevBtn.disabled = currentPage === 1;
|
||||||
prevBtn.disabled = currentPage === 1;
|
|
||||||
nextBtn.disabled = currentPage === totalPages || totalPages === 0;
|
nextBtn.disabled = currentPage === totalPages || totalPages === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 筛选学生
|
// 蝑偦<EFBFBD>匧郎<EFBFBD>? function filterStudents() {
|
||||||
function filterStudents() {
|
|
||||||
const studentId = document.getElementById('student-id').value.trim();
|
const studentId = document.getElementById('student-id').value.trim();
|
||||||
const studentName = document.getElementById('student-name').value.trim();
|
const studentName = document.getElementById('student-name').value.trim();
|
||||||
const selectedClass = document.getElementById('class-select').value;
|
const selectedClass = document.getElementById('class-select').value;
|
||||||
@@ -351,8 +346,7 @@
|
|||||||
updatePagination();
|
updatePagination();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重置筛选条件
|
// <EFBFBD>滨蔭蝑偦<EFBFBD>㗇辺隞? function resetFilters() {
|
||||||
function resetFilters() {
|
|
||||||
document.getElementById('student-id').value = '';
|
document.getElementById('student-id').value = '';
|
||||||
document.getElementById('student-name').value = '';
|
document.getElementById('student-name').value = '';
|
||||||
document.getElementById('class-select').value = '';
|
document.getElementById('class-select').value = '';
|
||||||
@@ -366,15 +360,13 @@
|
|||||||
|
|
||||||
// 添加学生
|
// 添加学生
|
||||||
function addStudent() {
|
function addStudent() {
|
||||||
alert('添加学生功能将在后端API完成后实现');
|
alert('瘛餃<EFBFBD>摮衣<EFBFBD><EFBFBD>蠘<EFBFBD>撠<EFBFBD>銁<EFBFBD>𡒊垢API摰峕<EFBFBD><EFBFBD>𤾸<EFBFBD><EFBFBD>?);
|
||||||
// 这里可以打开一个模态框来添加学生信息
|
// 餈䠷<EFBFBD><EFBFBD>臭誑<EFBFBD>枏<EFBFBD>銝<EFBFBD>銝芣芋<EFBFBD><EFBFBD><EFBFBD><EFBFBD>交溶<EFBFBD>惩郎<EFBFBD>煺縑<EFBFBD>? }
|
||||||
}
|
|
||||||
|
|
||||||
// 编辑学生
|
// 编辑学生
|
||||||
function editStudent(studentId) {
|
function editStudent(studentId) {
|
||||||
alert(`编辑学生 ${studentId} 功能将在后端API完成后实现`);
|
alert(`编辑学生 ${studentId} 功能将在后端API完成后实现`);
|
||||||
// 这里可以打开一个模态框来编辑学生信息
|
// 餈䠷<EFBFBD><EFBFBD>臭誑<EFBFBD>枏<EFBFBD>銝<EFBFBD>銝芣芋<EFBFBD><EFBFBD><EFBFBD><EFBFBD>亦<EFBFBD>颲穃郎<EFBFBD>煺縑<EFBFBD>? }
|
||||||
}
|
|
||||||
|
|
||||||
// 删除学生
|
// 删除学生
|
||||||
function deleteStudent(studentId) {
|
function deleteStudent(studentId) {
|
||||||
@@ -386,7 +378,7 @@
|
|||||||
|
|
||||||
// 导出数据
|
// 导出数据
|
||||||
function exportData() {
|
function exportData() {
|
||||||
alert('导出数据功能将在后端API完成后实现');
|
alert('撖澆枂<EFBFBD>唳旿<EFBFBD>蠘<EFBFBD>撠<EFBFBD>銁<EFBFBD>𡒊垢API摰峕<EFBFBD><EFBFBD>𤾸<EFBFBD><EFBFBD>?);
|
||||||
// 这里可以调用API导出Excel或CSV文件
|
// 这里可以调用API导出Excel或CSV文件
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,8 +389,7 @@
|
|||||||
updatePagination();
|
updatePagination();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化事件监听
|
// <EFBFBD>嘥<EFBFBD><EFBFBD>碶<EFBFBD>隞嗥<EFBFBD><EFBFBD>? function initEventListeners() {
|
||||||
function initEventListeners() {
|
|
||||||
searchBtn.addEventListener('click', filterStudents);
|
searchBtn.addEventListener('click', filterStudents);
|
||||||
resetBtn.addEventListener('click', resetFilters);
|
resetBtn.addEventListener('click', resetFilters);
|
||||||
addBtn.addEventListener('click', addStudent);
|
addBtn.addEventListener('click', addStudent);
|
||||||
@@ -427,8 +418,7 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 输入框回车搜索
|
// 颲枏<EFBFBD>獢<EFBFBD><EFBFBD>頧行<EFBFBD>蝝? document.getElementById('student-id').addEventListener('keypress', (e) => {
|
||||||
document.getElementById('student-id').addEventListener('keypress', (e) => {
|
|
||||||
if (e.key === 'Enter') filterStudents();
|
if (e.key === 'Enter') filterStudents();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -448,4 +438,4 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -4,35 +4,35 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>用户管理 - XX学校成绩管理系统</title>
|
<title>用户管理 - XX学校成绩管理系统</title>
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="/public/css/style.css">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- 导航栏 -->
|
<!-- 撖潸⏛<EFBFBD>?-->
|
||||||
<nav class="navbar">
|
<nav class="navbar">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="navbar-brand">
|
<div class="navbar-brand">
|
||||||
<a href="index.html">
|
<a href="/">
|
||||||
<i class="fas fa-graduation-cap"></i>
|
<i class="fas fa-graduation-cap"></i>
|
||||||
<span>XX学校成绩管理系统</span>
|
<span>XX学校成绩管理系统</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-menu">
|
<div class="navbar-menu">
|
||||||
<div class="navbar-start">
|
<div class="navbar-start">
|
||||||
<a href="admin_dashboard.html" class="navbar-item">
|
<a href="/admin/dashboard" class="navbar-item">
|
||||||
<i class="fas fa-tachometer-alt"></i>
|
<i class="fas fa-tachometer-alt"></i>
|
||||||
<span>仪表板</span>
|
<span>隞芾”<EFBFBD>?/span>
|
||||||
</a>
|
</a>
|
||||||
<a href="user_management.html" class="navbar-item active">
|
<a href="/admin/user_management" class="navbar-item active">
|
||||||
<i class="fas fa-users"></i>
|
<i class="fas fa-users"></i>
|
||||||
<span>用户管理</span>
|
<span>用户管理</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="student_management.html" class="navbar-item">
|
<a href="/admin/student_management" class="navbar-item">
|
||||||
<i class="fas fa-user-graduate"></i>
|
<i class="fas fa-user-graduate"></i>
|
||||||
<span>学生管理</span>
|
<span>学生管理</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="grade_management.html" class="navbar-item">
|
<a href="/teacher/grade_management" class="navbar-item">
|
||||||
<i class="fas fa-chart-bar"></i>
|
<i class="fas fa-chart-bar"></i>
|
||||||
<span>成绩统计</span>
|
<span>成绩统计</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -40,25 +40,23 @@
|
|||||||
<div class="navbar-end">
|
<div class="navbar-end">
|
||||||
<div class="navbar-item user-info">
|
<div class="navbar-item user-info">
|
||||||
<i class="fas fa-user-circle"></i>
|
<i class="fas fa-user-circle"></i>
|
||||||
<span>管理员</span>
|
<span>蝞∠<EFBFBD><EFBFBD>?/span>
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<a href="#" class="dropdown-toggle">
|
<a href="#" class="dropdown-toggle">
|
||||||
<i class="fas fa-caret-down"></i>
|
<i class="fas fa-caret-down"></i>
|
||||||
</a>
|
</a>
|
||||||
<div class="dropdown-menu">
|
<div class="dropdown-menu">
|
||||||
<a href="admin_dashboard.html" class="dropdown-item">
|
<a href="/admin/dashboard" class="dropdown-item">
|
||||||
<i class="fas fa-tachometer-alt"></i>
|
<i class="fas fa-tachometer-alt"></i>
|
||||||
仪表板
|
隞芾”<EFBFBD>? </a>
|
||||||
</a>
|
|
||||||
<a href="#" class="dropdown-item">
|
<a href="#" class="dropdown-item">
|
||||||
<i class="fas fa-cog"></i>
|
<i class="fas fa-cog"></i>
|
||||||
系统设置
|
系统设置
|
||||||
</a>
|
</a>
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<a href="index.html" class="dropdown-item">
|
<a href="/" class="dropdown-item">
|
||||||
<i class="fas fa-sign-out-alt"></i>
|
<i class="fas fa-sign-out-alt"></i>
|
||||||
退出登录
|
<EFBFBD><EFBFBD><EFBFBD>箇蒈敶? </a>
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -75,13 +73,13 @@
|
|||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h1>用户管理</h1>
|
<h1>用户管理</h1>
|
||||||
<div class="breadcrumb">
|
<div class="breadcrumb">
|
||||||
<a href="index.html">主页</a> >
|
<a href="/">銝駁△</a> >
|
||||||
<a href="admin_dashboard.html">管理员仪表板</a> >
|
<a href="/admin/dashboard">蝞∠<EFBFBD><EFBFBD>䀝貌銵冽踎</a> >
|
||||||
<span>用户管理</span>
|
<span>用户管理</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 筛选区域 -->
|
<!-- 蝑偦<EFBFBD>匧躹<EFBFBD>?-->
|
||||||
<div class="filter-section">
|
<div class="filter-section">
|
||||||
<form class="filter-form" id="filter-form">
|
<form class="filter-form" id="filter-form">
|
||||||
<div class="filter-group">
|
<div class="filter-group">
|
||||||
@@ -90,13 +88,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="filter-group">
|
<div class="filter-group">
|
||||||
<label for="user-name">姓名</label>
|
<label for="user-name">姓名</label>
|
||||||
<input type="text" id="user-name" placeholder="请输入姓名">
|
<input type="text" id="user-name" placeholder="霂瑁<EFBFBD><EFBFBD>亙<EFBFBD><EFBFBD>?>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-group">
|
<div class="filter-group">
|
||||||
<label for="role-select">角色</label>
|
<label for="role-select">角色</label>
|
||||||
<select id="role-select">
|
<select id="role-select">
|
||||||
<option value="">全部角色</option>
|
<option value="">全部角色</option>
|
||||||
<option value="admin">管理员</option>
|
<option value="admin">蝞∠<EFBFBD><EFBFBD>?/option>
|
||||||
<option value="teacher">教师</option>
|
<option value="teacher">教师</option>
|
||||||
<option value="student">学生</option>
|
<option value="student">学生</option>
|
||||||
</select>
|
</select>
|
||||||
@@ -105,12 +103,12 @@
|
|||||||
<label for="class-select">班级</label>
|
<label for="class-select">班级</label>
|
||||||
<select id="class-select">
|
<select id="class-select">
|
||||||
<option value="">全部班级</option>
|
<option value="">全部班级</option>
|
||||||
<option value="计算机科学与技术1班">计算机科学与技术1班</option>
|
<option value="霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?>霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?/option>
|
||||||
<option value="计算机科学与技术2班">计算机科学与技术2班</option>
|
<option value="霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?>霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?/option>
|
||||||
<option value="软件工程1班">软件工程1班</option>
|
<option value="頧臭辣撌亦<EFBFBD>1<EFBFBD>?>頧臭辣撌亦<EFBFBD>1<EFBFBD>?/option>
|
||||||
<option value="软件工程2班">软件工程2班</option>
|
<option value="頧臭辣撌亦<EFBFBD>2<EFBFBD>?>頧臭辣撌亦<EFBFBD>2<EFBFBD>?/option>
|
||||||
<option value="网络工程1班">网络工程1班</option>
|
<option value="蝵𤑳<EFBFBD>撌亦<EFBFBD>1<EFBFBD>?>蝵𤑳<EFBFBD>撌亦<EFBFBD>1<EFBFBD>?/option>
|
||||||
<option value="网络工程2班">网络工程2班</option>
|
<option value="蝵𤑳<EFBFBD>撌亦<EFBFBD>2<EFBFBD>?>蝵𤑳<EFBFBD>撌亦<EFBFBD>2<EFBFBD>?/option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-actions">
|
<div class="filter-actions">
|
||||||
@@ -150,7 +148,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="user-table-body">
|
<tbody id="user-table-body">
|
||||||
<!-- 数据将通过JavaScript动态加载 -->
|
<!-- <EFBFBD>唳旿撠<EFBFBD><EFBFBD>朞<EFBFBD>JavaScript<EFBFBD>冽<EFBFBD><EFBFBD><EFBFBD>頧?-->
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="8" class="loading">
|
<td colspan="8" class="loading">
|
||||||
<i class="fas fa-spinner fa-spin"></i>
|
<i class="fas fa-spinner fa-spin"></i>
|
||||||
@@ -165,16 +163,14 @@
|
|||||||
<div class="pagination" id="pagination">
|
<div class="pagination" id="pagination">
|
||||||
<button id="prev-btn" disabled>
|
<button id="prev-btn" disabled>
|
||||||
<i class="fas fa-chevron-left"></i>
|
<i class="fas fa-chevron-left"></i>
|
||||||
上一页
|
銝𠹺<EFBFBD>憿? </button>
|
||||||
</button>
|
|
||||||
<div id="page-numbers">
|
<div id="page-numbers">
|
||||||
<button class="active">1</button>
|
<button class="active">1</button>
|
||||||
<button>2</button>
|
<button>2</button>
|
||||||
<button>3</button>
|
<button>3</button>
|
||||||
</div>
|
</div>
|
||||||
<button id="next-btn">
|
<button id="next-btn">
|
||||||
下一页
|
銝衤<EFBFBD>憿? <i class="fas fa-chevron-right"></i>
|
||||||
<i class="fas fa-chevron-right"></i>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -184,8 +180,8 @@
|
|||||||
<!-- 页脚 -->
|
<!-- 页脚 -->
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<p>© 2023 XX学校成绩管理系统. 版权所有.</p>
|
<p>© 2023 XX摮行嵗<EFBFBD>鞟貍蝞∠<EFBFBD>蝟餌<EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?</p>
|
||||||
<p>技术支持: 信息技术中心 | 联系电话: 010-12345678</p>
|
<p><EFBFBD><EFBFBD><EFBFBD>舀𣈲<EFBFBD>? 靽⊥<E99DBD><E28AA5><EFBFBD><EFBFBD>臭葉敹?| <20>𠉛頂<F0A0899B>菔<EFBFBD>: 010-12345678</p>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
@@ -206,7 +202,7 @@
|
|||||||
id: 'teacher001',
|
id: 'teacher001',
|
||||||
name: '李老师',
|
name: '李老师',
|
||||||
role: 'teacher',
|
role: 'teacher',
|
||||||
className: '计算机科学与技术1班',
|
className: '霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?,
|
||||||
phone: '13800138002',
|
phone: '13800138002',
|
||||||
email: 'li.teacher@xxschool.edu.cn',
|
email: 'li.teacher@xxschool.edu.cn',
|
||||||
registerTime: '2023-02-10'
|
registerTime: '2023-02-10'
|
||||||
@@ -215,7 +211,7 @@
|
|||||||
id: 'teacher002',
|
id: 'teacher002',
|
||||||
name: '王老师',
|
name: '王老师',
|
||||||
role: 'teacher',
|
role: 'teacher',
|
||||||
className: '软件工程1班',
|
className: '頧臭辣撌亦<EFBFBD>1<EFBFBD>?,
|
||||||
phone: '13800138003',
|
phone: '13800138003',
|
||||||
email: 'wang.teacher@xxschool.edu.cn',
|
email: 'wang.teacher@xxschool.edu.cn',
|
||||||
registerTime: '2023-02-12'
|
registerTime: '2023-02-12'
|
||||||
@@ -224,7 +220,7 @@
|
|||||||
id: 'student001',
|
id: 'student001',
|
||||||
name: '张三',
|
name: '张三',
|
||||||
role: 'student',
|
role: 'student',
|
||||||
className: '计算机科学与技术1班',
|
className: '霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?,
|
||||||
phone: '13800138004',
|
phone: '13800138004',
|
||||||
email: 'zhangsan@xxschool.edu.cn',
|
email: 'zhangsan@xxschool.edu.cn',
|
||||||
registerTime: '2023-03-01'
|
registerTime: '2023-03-01'
|
||||||
@@ -233,7 +229,7 @@
|
|||||||
id: 'student002',
|
id: 'student002',
|
||||||
name: '李四',
|
name: '李四',
|
||||||
role: 'student',
|
role: 'student',
|
||||||
className: '计算机科学与技术1班',
|
className: '霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?,
|
||||||
phone: '13800138005',
|
phone: '13800138005',
|
||||||
email: 'lisi@xxschool.edu.cn',
|
email: 'lisi@xxschool.edu.cn',
|
||||||
registerTime: '2023-03-01'
|
registerTime: '2023-03-01'
|
||||||
@@ -242,7 +238,7 @@
|
|||||||
id: 'student003',
|
id: 'student003',
|
||||||
name: '王五',
|
name: '王五',
|
||||||
role: 'student',
|
role: 'student',
|
||||||
className: '软件工程1班',
|
className: '頧臭辣撌亦<EFBFBD>1<EFBFBD>?,
|
||||||
phone: '13800138006',
|
phone: '13800138006',
|
||||||
email: 'wangwu@xxschool.edu.cn',
|
email: 'wangwu@xxschool.edu.cn',
|
||||||
registerTime: '2023-03-02'
|
registerTime: '2023-03-02'
|
||||||
@@ -251,7 +247,7 @@
|
|||||||
id: 'student004',
|
id: 'student004',
|
||||||
name: '赵六',
|
name: '赵六',
|
||||||
role: 'student',
|
role: 'student',
|
||||||
className: '软件工程1班',
|
className: '頧臭辣撌亦<EFBFBD>1<EFBFBD>?,
|
||||||
phone: '13800138007',
|
phone: '13800138007',
|
||||||
email: 'zhaoliu@xxschool.edu.cn',
|
email: 'zhaoliu@xxschool.edu.cn',
|
||||||
registerTime: '2023-03-02'
|
registerTime: '2023-03-02'
|
||||||
@@ -260,7 +256,7 @@
|
|||||||
id: 'student005',
|
id: 'student005',
|
||||||
name: '钱七',
|
name: '钱七',
|
||||||
role: 'student',
|
role: 'student',
|
||||||
className: '网络工程1班',
|
className: '蝵𤑳<EFBFBD>撌亦<EFBFBD>1<EFBFBD>?,
|
||||||
phone: '13800138008',
|
phone: '13800138008',
|
||||||
email: 'qianqi@xxschool.edu.cn',
|
email: 'qianqi@xxschool.edu.cn',
|
||||||
registerTime: '2023-03-03'
|
registerTime: '2023-03-03'
|
||||||
@@ -269,7 +265,7 @@
|
|||||||
id: 'student006',
|
id: 'student006',
|
||||||
name: '孙八',
|
name: '孙八',
|
||||||
role: 'student',
|
role: 'student',
|
||||||
className: '网络工程2班',
|
className: '蝵𤑳<EFBFBD>撌亦<EFBFBD>2<EFBFBD>?,
|
||||||
phone: '13800138009',
|
phone: '13800138009',
|
||||||
email: 'sunba@xxschool.edu.cn',
|
email: 'sunba@xxschool.edu.cn',
|
||||||
registerTime: '2023-03-03'
|
registerTime: '2023-03-03'
|
||||||
@@ -278,15 +274,14 @@
|
|||||||
id: 'student007',
|
id: 'student007',
|
||||||
name: '周九',
|
name: '周九',
|
||||||
role: 'student',
|
role: 'student',
|
||||||
className: '计算机科学与技术2班',
|
className: '霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?,
|
||||||
phone: '13800138010',
|
phone: '13800138010',
|
||||||
email: 'zhoujiu@xxschool.edu.cn',
|
email: 'zhoujiu@xxschool.edu.cn',
|
||||||
registerTime: '2023-03-04'
|
registerTime: '2023-03-04'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
// 当前显示的用户数据
|
// 敶枏<EFBFBD><EFBFBD>曄內<EFBFBD><EFBFBD>鍂<EFBFBD>瑟㺭<EFBFBD>? let currentUsers = [...mockUsers];
|
||||||
let currentUsers = [...mockUsers];
|
|
||||||
let currentPage = 1;
|
let currentPage = 1;
|
||||||
const usersPerPage = 5;
|
const usersPerPage = 5;
|
||||||
|
|
||||||
@@ -305,15 +300,13 @@
|
|||||||
const roleSelect = document.getElementById('role-select');
|
const roleSelect = document.getElementById('role-select');
|
||||||
const classSelect = document.getElementById('class-select');
|
const classSelect = document.getElementById('class-select');
|
||||||
|
|
||||||
// 初始化
|
// <EFBFBD>嘥<EFBFBD><EFBFBD>? document.addEventListener('DOMContentLoaded', function() {
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
renderUserTable();
|
renderUserTable();
|
||||||
setupEventListeners();
|
setupEventListeners();
|
||||||
updatePagination();
|
updatePagination();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 设置事件监听器
|
// 霈曄蔭鈭衤辣<EFBFBD>穃𨯬<EFBFBD>? function setupEventListeners() {
|
||||||
function setupEventListeners() {
|
|
||||||
searchBtn.addEventListener('click', handleSearch);
|
searchBtn.addEventListener('click', handleSearch);
|
||||||
resetBtn.addEventListener('click', handleReset);
|
resetBtn.addEventListener('click', handleReset);
|
||||||
addBtn.addEventListener('click', handleAddUser);
|
addBtn.addEventListener('click', handleAddUser);
|
||||||
@@ -330,7 +323,7 @@
|
|||||||
<td colspan="8" class="no-results">
|
<td colspan="8" class="no-results">
|
||||||
<i class="fas fa-user-slash"></i>
|
<i class="fas fa-user-slash"></i>
|
||||||
<h3>没有找到用户</h3>
|
<h3>没有找到用户</h3>
|
||||||
<p>请尝试其他筛选条件或添加新用户</p>
|
<p>霂瑕<EFBFBD>霂訫<EFBFBD>隞𣇉<EFBFBD><EFBFBD>㗇辺隞嗆<EFBFBD>瘛餃<EFBFBD><EFBFBD>啁鍂<EFBFBD>?/p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
`;
|
`;
|
||||||
@@ -347,7 +340,7 @@
|
|||||||
// 角色徽章
|
// 角色徽章
|
||||||
let roleBadge = '';
|
let roleBadge = '';
|
||||||
if (user.role === 'admin') {
|
if (user.role === 'admin') {
|
||||||
roleBadge = '<span class="role-badge role-admin">管理员</span>';
|
roleBadge = '<span class="role-badge role-admin">蝞∠<EFBFBD><EFBFBD>?/span>';
|
||||||
} else if (user.role === 'teacher') {
|
} else if (user.role === 'teacher') {
|
||||||
roleBadge = '<span class="role-badge role-teacher">教师</span>';
|
roleBadge = '<span class="role-badge role-teacher">教师</span>';
|
||||||
} else {
|
} else {
|
||||||
@@ -359,7 +352,7 @@
|
|||||||
<td>${user.id}</td>
|
<td>${user.id}</td>
|
||||||
<td>${user.name}</td>
|
<td>${user.name}</td>
|
||||||
<td>${roleBadge}</td>
|
<td>${roleBadge}</td>
|
||||||
<td>${user.className || '—'}</td>
|
<td>${user.className || '<EFBFBD>?}</td>
|
||||||
<td>${user.phone}</td>
|
<td>${user.phone}</td>
|
||||||
<td>${user.email}</td>
|
<td>${user.email}</td>
|
||||||
<td>${user.registerTime}</td>
|
<td>${user.registerTime}</td>
|
||||||
@@ -386,15 +379,13 @@
|
|||||||
function updatePagination() {
|
function updatePagination() {
|
||||||
const totalPages = Math.ceil(currentUsers.length / usersPerPage);
|
const totalPages = Math.ceil(currentUsers.length / usersPerPage);
|
||||||
|
|
||||||
// 更新按钮状态
|
// <EFBFBD>湔鰵<EFBFBD>厰僼<EFBFBD>嗆<EFBFBD>? prevBtn.disabled = currentPage === 1;
|
||||||
prevBtn.disabled = currentPage === 1;
|
|
||||||
nextBtn.disabled = currentPage === totalPages || totalPages === 0;
|
nextBtn.disabled = currentPage === totalPages || totalPages === 0;
|
||||||
|
|
||||||
// 更新页码按钮
|
// 更新页码按钮
|
||||||
let pageButtonsHTML = '';
|
let pageButtonsHTML = '';
|
||||||
for (let i = 1; i <= totalPages; i++) {
|
for (let i = 1; i <= totalPages; i++) {
|
||||||
if (i <= 5) { // 最多显示5个页码
|
if (i <= 5) { // <EFBFBD><EFBFBD>憭𡁏遬蝷?銝芷△<E88AB7>? pageButtonsHTML += `<button class="${i === currentPage ? 'active' : ''}" onclick="goToPage(${i})">${i}</button>`;
|
||||||
pageButtonsHTML += `<button class="${i === currentPage ? 'active' : ''}" onclick="goToPage(${i})">${i}</button>`;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pageNumbers.innerHTML = pageButtonsHTML;
|
pageNumbers.innerHTML = pageButtonsHTML;
|
||||||
@@ -408,23 +399,19 @@
|
|||||||
const className = classSelect.value;
|
const className = classSelect.value;
|
||||||
|
|
||||||
currentUsers = mockUsers.filter(user => {
|
currentUsers = mockUsers.filter(user => {
|
||||||
// 用户ID筛选
|
// <EFBFBD>冽<EFBFBD>ID蝑偦<EFBFBD>? if (userId && !user.id.toLowerCase().includes(userId.toLowerCase())) {
|
||||||
if (userId && !user.id.toLowerCase().includes(userId.toLowerCase())) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 姓名筛选
|
// 憪枏<EFBFBD>蝑偦<EFBFBD>? if (userName && !user.name.toLowerCase().includes(userName.toLowerCase())) {
|
||||||
if (userName && !user.name.toLowerCase().includes(userName.toLowerCase())) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 角色筛选
|
// 閫坿𠧧蝑偦<EFBFBD>? if (role && user.role !== role) {
|
||||||
if (role && user.role !== role) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 班级筛选
|
// <EFBFBD>剔漣蝑偦<EFBFBD>? if (className && user.className !== className) {
|
||||||
if (className && user.className !== className) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,31 +438,29 @@
|
|||||||
|
|
||||||
// 处理添加用户
|
// 处理添加用户
|
||||||
function handleAddUser() {
|
function handleAddUser() {
|
||||||
alert('添加用户功能将在后端API完成后实现');
|
alert('瘛餃<EFBFBD><EFBFBD>冽<EFBFBD><EFBFBD>蠘<EFBFBD>撠<EFBFBD>銁<EFBFBD>𡒊垢API摰峕<EFBFBD><EFBFBD>𤾸<EFBFBD><EFBFBD>?);
|
||||||
// 这里可以打开一个模态框来添加新用户
|
// 这里可以打开一个模态框来添加新用户
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理导出
|
// 处理导出
|
||||||
function handleExport() {
|
function handleExport() {
|
||||||
alert('导出功能将在后端API完成后实现');
|
alert('撖澆枂<EFBFBD>蠘<EFBFBD>撠<EFBFBD>銁<EFBFBD>𡒊垢API摰峕<EFBFBD><EFBFBD>𤾸<EFBFBD><EFBFBD>?);
|
||||||
// 这里可以导出为Excel或CSV格式
|
// 这里可以导出为Excel或CSV格式
|
||||||
}
|
}
|
||||||
|
|
||||||
// 编辑用户
|
// 编辑用户
|
||||||
function editUser(userId) {
|
function editUser(userId) {
|
||||||
alert(`编辑用户 ${userId} - 功能将在后端API完成后实现`);
|
alert(`编辑用户 ${userId} - 功能将在后端API完成后实现`);
|
||||||
// 这里可以打开一个模态框来编辑用户信息
|
// 餈䠷<EFBFBD><EFBFBD>臭誑<EFBFBD>枏<EFBFBD>銝<EFBFBD>銝芣芋<EFBFBD><EFBFBD><EFBFBD><EFBFBD>亦<EFBFBD>颲𤑳鍂<EFBFBD>瑚縑<EFBFBD>? }
|
||||||
}
|
|
||||||
|
|
||||||
// 删除用户
|
// 删除用户
|
||||||
function deleteUser(userId) {
|
function deleteUser(userId) {
|
||||||
if (confirm(`确定要删除用户 ${userId} 吗?此操作不可撤销。`)) {
|
if (confirm(`蝖桀<EFBFBD>閬<EFBFBD><EFBFBD><EFBFBD>斤鍂<EFBFBD>?${userId} <20>梹<EFBFBD>甇斗<E79487>雿靝<E99BBF><E99D9D>舀伃<E88880><E4BC83><EFBFBD><EFBFBD>)) {
|
||||||
// 从模拟数据中删除
|
// 从模拟数据中删除
|
||||||
const index = mockUsers.findIndex(user => user.id === userId);
|
const index = mockUsers.findIndex(user => user.id === userId);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
mockUsers.splice(index, 1);
|
mockUsers.splice(index, 1);
|
||||||
// 更新当前显示的数据
|
// <EFBFBD>湔鰵敶枏<EFBFBD><EFBFBD>曄內<EFBFBD><EFBFBD>㺭<EFBFBD>? handleSearch();
|
||||||
handleSearch();
|
|
||||||
alert('用户删除成功');
|
alert('用户删除成功');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -506,4 +491,4 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -4,43 +4,41 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>学生成绩管理系统</title>
|
<title>学生成绩管理系统</title>
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="/public/css/style.css">
|
||||||
<link rel="stylesheet" href="../css/main.css">
|
<link rel="stylesheet" href="/public/css/main.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- 导航栏 -->
|
<!-- 撖潸⏛<EFBFBD>?-->
|
||||||
<nav class="navbar">
|
<nav class="navbar">
|
||||||
<div class="navbar-brand">
|
<div class="navbar-brand">
|
||||||
<i class="fas fa-graduation-cap"></i>
|
<i class="fas fa-graduation-cap"></i>
|
||||||
<span>XX学校成绩管理系统</span>
|
<span>XX学校成绩管理系统</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-menu">
|
<div class="navbar-menu">
|
||||||
<a href="index.html" class="btn btn-secondary">
|
<a href="/" class="btn btn-secondary">
|
||||||
<i class="fas fa-home"></i> 主页
|
<i class="fas fa-home"></i> 主页
|
||||||
</a>
|
</a>
|
||||||
<div class="navbar-user">
|
<div class="navbar-user">
|
||||||
<a href="login.html" class="btn btn-primary" id="loginBtn">
|
<a href="/login" class="btn btn-primary" id="loginBtn">
|
||||||
<i class="fas fa-sign-in-alt"></i> 登录
|
<i class="fas fa-sign-in-alt"></i> 登录
|
||||||
</a>
|
</a>
|
||||||
<a href="register.html" class="btn btn-secondary" id="registerBtn">
|
<a href="/register" class="btn btn-secondary" id="registerBtn">
|
||||||
<i class="fas fa-user-plus"></i> 注册
|
<i class="fas fa-user-plus"></i> 注册
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<!-- 主体内容区 -->
|
<!-- 銝颱<EFBFBD><EFBFBD><EFBFBD>捆<EFBFBD>?-->
|
||||||
<main>
|
<main>
|
||||||
<!-- 英雄区域 -->
|
<!-- 英雄区域 -->
|
||||||
<section class="hero-section">
|
<section class="hero-section">
|
||||||
<div class="hero-content">
|
<div class="hero-content">
|
||||||
<h1 class="hero-title">XX学校学生成绩管理系统</h1>
|
<h1 class="hero-title">XX学校学生成绩管理系统</h1>
|
||||||
<p class="hero-subtitle">
|
<p class="hero-subtitle">
|
||||||
高效、安全、智能的成绩管理平台,为学校师生提供全方位的成绩管理服务,
|
擃䀹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>具<EFBFBD><EFBFBD>惣<EFBFBD>賜<EFBFBD><EFBFBD>鞟貍蝞∠<EFBFBD>撟喳蝱嚗䔶蛹摮行嵗撣<EFBFBD><EFBFBD><EFBFBD>𣂷<EFBFBD><EFBFBD>冽䲮雿滨<EFBFBD><EFBFBD>鞟貍蝞∠<EFBFBD><EFBFBD>滚𦛚嚗? 摰䂿緵<E482BF>鞟貍敶訫<E695B6><E8A8AB><EFBFBD>䰻霂U<E99C82><EFBCB5><EFBFBD>霈∪<E99C88><E288AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>雿枏<E99BBF>閫<EFBFBD><E996AB><EFBFBD>寞<EFBFBD><E5AF9E>? </p>
|
||||||
实现成绩录入、查询、统计和分析的一体化解决方案。
|
|
||||||
</p>
|
|
||||||
<div class="cta-buttons">
|
<div class="cta-buttons">
|
||||||
<a href="login.html" class="btn btn-primary" id="heroLoginBtn">
|
<a href="/login" class="btn btn-primary" id="heroLoginBtn">
|
||||||
<i class="fas fa-sign-in-alt"></i> 立即登录
|
<i class="fas fa-sign-in-alt"></i> 立即登录
|
||||||
</a>
|
</a>
|
||||||
<a href="#features" class="btn btn-secondary">
|
<a href="#features" class="btn btn-secondary">
|
||||||
@@ -60,9 +58,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<h3 class="feature-title">学生成绩查询</h3>
|
<h3 class="feature-title">学生成绩查询</h3>
|
||||||
<p class="feature-description">
|
<p class="feature-description">
|
||||||
学生可随时查看个人成绩,包括各科成绩、平均分、排名等信息,
|
摮衣<EFBFBD><EFBFBD>舫<EFBFBD><EFBFBD>嗆䰻<EFBFBD>衤葵鈭箸<EFBFBD>蝏抬<EFBFBD><EFBFBD><EFBFBD>𡠺<EFBFBD><EFBFBD><EFBFBD><EFBFBD>鞟貍<EFBFBD><EFBFBD>像<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>滨<EFBFBD>靽⊥<EFBFBD>嚗? <20>舀<EFBFBD><E88880>鞟貍頞见飵<E8A781><E9A3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>脰扇敶閙䰻<E99699>卝<EFBFBD>? </p>
|
||||||
支持成绩趋势分析和历史记录查看。
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="feature-card">
|
<div class="feature-card">
|
||||||
@@ -72,19 +68,16 @@
|
|||||||
<h3 class="feature-title">教师成绩管理</h3>
|
<h3 class="feature-title">教师成绩管理</h3>
|
||||||
<p class="feature-description">
|
<p class="feature-description">
|
||||||
教师可便捷录入、修改、查询学生成绩,支持批量操作和成绩统计分析,
|
教师可便捷录入、修改、查询学生成绩,支持批量操作和成绩统计分析,
|
||||||
提供多种数据导出格式。
|
<EFBFBD>𣂷<EFBFBD>憭𡁶<EFBFBD><EFBFBD>唳旿撖澆枂<EFBFBD>澆<EFBFBD><EFBFBD>? </p>
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="feature-card">
|
<div class="feature-card">
|
||||||
<div class="feature-icon">
|
<div class="feature-icon">
|
||||||
<i class="fas fa-user-shield"></i>
|
<i class="fas fa-user-shield"></i>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="feature-title">管理员权限控制</h3>
|
<h3 class="feature-title">蝞∠<EFBFBD><EFBFBD>䀹<EFBFBD><EFBFBD>鞉綉<EFBFBD>?/h3>
|
||||||
<p class="feature-description">
|
<p class="feature-description">
|
||||||
管理员可管理用户账户、学生信息,查看系统统计报表,
|
蝞∠<EFBFBD><EFBFBD>睃虾蝞∠<EFBFBD><EFBFBD>冽<EFBFBD>韐行<EFBFBD><EFBFBD><EFBFBD>郎<EFBFBD>煺縑<EFBFBD>荔<EFBFBD><EFBFBD>亦<EFBFBD>蝟餌<EFBFBD>蝏蠘恣<EFBFBD>亥”嚗? 霈曄蔭<E69B84><E894AD><EFBFBD><EFBFBD>𣬚頂蝏笔<E89D8F><E7AC94>堆<EFBFBD>蝖桐<E89D96><E6A190>唳旿摰匧<E691B0><E58CA7>? </p>
|
||||||
设置权限和系统参数,确保数据安全。
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="feature-card">
|
<div class="feature-card">
|
||||||
@@ -93,9 +86,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<h3 class="feature-title">智能统计分析</h3>
|
<h3 class="feature-title">智能统计分析</h3>
|
||||||
<p class="feature-description">
|
<p class="feature-description">
|
||||||
提供丰富的图表统计功能,包括成绩分布、趋势分析、对比图表等,
|
<EFBFBD>𣂷<EFBFBD>銝啣<EFBFBD><EFBFBD><EFBFBD>㦛銵函<EFBFBD>霈∪<EFBFBD><EFBFBD>踝<EFBFBD><EFBFBD><EFBFBD>𡠺<EFBFBD>鞟貍<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>踹<EFBFBD><EFBFBD>僐<EFBFBD><EFBFBD>笆瘥𥪜㦛銵函<EFBFBD>嚗? 撣桀𨭌摮行嵗餈𥡝<E9A488><F0A5A19D>坔郎霂<E9838E>摯<EFBFBD><E691AF><EFBFBD>蝑𡝗𣈲<F0A19D97><F0A388B2><EFBFBD>? </p>
|
||||||
帮助学校进行教学评估和决策支持。
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -104,12 +95,10 @@
|
|||||||
<section class="cta-section">
|
<section class="cta-section">
|
||||||
<h2 class="cta-title">立即体验智能成绩管理</h2>
|
<h2 class="cta-title">立即体验智能成绩管理</h2>
|
||||||
<p style="font-size: 1.2rem; color: #666; margin-bottom: 40px; max-width: 600px; margin-left: auto; margin-right: auto;">
|
<p style="font-size: 1.2rem; color: #666; margin-bottom: 40px; max-width: 600px; margin-left: auto; margin-right: auto;">
|
||||||
加入XX学校成绩管理系统,体验高效、便捷的成绩管理服务。
|
<EFBFBD>惩<EFBFBD>XX摮行嵗<EFBFBD>鞟貍蝞∠<EFBFBD>蝟餌<EFBFBD>嚗䔶<EFBFBD>撉屸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>噶<EFBFBD>瑞<EFBFBD><EFBFBD>鞟貍蝞∠<EFBFBD><EFBFBD>滚𦛚<EFBFBD>? </p>
|
||||||
</p>
|
|
||||||
<div class="cta-buttons">
|
<div class="cta-buttons">
|
||||||
<a href="login.html" class="btn btn-primary">
|
<a href="/login" class="btn btn-primary">
|
||||||
<i class="fas fa-sign-in-alt"></i> 开始使用
|
<i class="fas fa-sign-in-alt"></i> 撘<EFBFBD>憪衤蝙<EFBFBD>? </a>
|
||||||
</a>
|
|
||||||
<a href="#" class="btn btn-secondary">
|
<a href="#" class="btn btn-secondary">
|
||||||
<i class="fas fa-book"></i> 查看文档
|
<i class="fas fa-book"></i> 查看文档
|
||||||
</a>
|
</a>
|
||||||
@@ -122,8 +111,7 @@
|
|||||||
<div class="footer-content">
|
<div class="footer-content">
|
||||||
<h3 style="margin-bottom: 20px;">XX学校学生成绩管理系统</h3>
|
<h3 style="margin-bottom: 20px;">XX学校学生成绩管理系统</h3>
|
||||||
<p style="color: #ccc; margin-bottom: 20px; max-width: 600px; margin-left: auto; margin-right: auto;">
|
<p style="color: #ccc; margin-bottom: 20px; max-width: 600px; margin-left: auto; margin-right: auto;">
|
||||||
致力于为学校提供专业、安全、高效的数字化成绩管理解决方案。
|
<EFBFBD>游<EFBFBD>鈭𦒘蛹摮行嵗<EFBFBD>𣂷<EFBFBD>銝㮖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>具<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>啣<EFBFBD><EFBFBD>𡝗<EFBFBD>蝏拍恣<EFBFBD><EFBFBD>圾<EFBFBD>單䲮獢<EFBFBD><EFBFBD>? </p>
|
||||||
</p>
|
|
||||||
<div class="footer-links">
|
<div class="footer-links">
|
||||||
<a href="#"><i class="fas fa-info-circle"></i> 关于我们</a>
|
<a href="#"><i class="fas fa-info-circle"></i> 关于我们</a>
|
||||||
<a href="#"><i class="fas fa-envelope"></i> 联系我们</a>
|
<a href="#"><i class="fas fa-envelope"></i> 联系我们</a>
|
||||||
@@ -131,12 +119,12 @@
|
|||||||
<a href="#"><i class="fas fa-file-contract"></i> 服务条款</a>
|
<a href="#"><i class="fas fa-file-contract"></i> 服务条款</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="copyright">
|
<div class="copyright">
|
||||||
<p>© 2023 XX学校学生成绩管理系统 版权所有</p>
|
<p>穢 2023 XX摮行嵗摮衣<EFBFBD><EFBFBD>鞟貍蝞∠<EFBFBD>蝟餌<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?/p>
|
||||||
<p>联系电话:010-12345678 | 邮箱:contact@school.edu.cn</p>
|
<p><EFBFBD>𠉛頂<EFBFBD>菔<EFBFBD>嚗?10-12345678 | <EFBFBD>桃拳嚗䬙ontact@school.edu.cn</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<script src="../js/main.js"></script>
|
<script src="/public/js/main.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>学生成绩管理系统 - 登录</title>
|
<title>学生成绩管理系统 - 登录</title>
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="/public/css/style.css">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
<i class="fas fa-user"></i> 学号/工号
|
<i class="fas fa-user"></i> 学号/工号
|
||||||
</label>
|
</label>
|
||||||
<input type="text" id="id" name="id" required
|
<input type="text" id="id" name="id" required
|
||||||
placeholder="请输入学号/工号">
|
placeholder="请输入学号/工号" autocomplete="username">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
<i class="fas fa-lock"></i> 密码
|
<i class="fas fa-lock"></i> 密码
|
||||||
</label>
|
</label>
|
||||||
<input type="password" id="password" name="password" required
|
<input type="password" id="password" name="password" required
|
||||||
placeholder="请输入密码">
|
placeholder="请输入密码" autocomplete="current-password">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -45,17 +45,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<button type="submit" class="btn btn-primary">
|
<button type="submit" class="btn btn-primary btn-block">
|
||||||
<i class="fas fa-sign-in-alt"></i> 登录
|
<i class="fas fa-sign-in-alt"></i> 登录
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="auth-footer">
|
<div class="auth-footer">
|
||||||
<p>没有账户? <a href="register.html">立即注册</a></p>
|
<p>没有账户? <a href="/register">立即注册</a></p>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<script src="../js/auth.js"></script>
|
|
||||||
|
<script src="/public/js/auth.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>学生成绩管理系统 - 注册</title>
|
<title>学生成绩管理系统 - 注册</title>
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="/public/css/style.css">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
<i class="fas fa-id-card"></i> 学号/工号
|
<i class="fas fa-id-card"></i> 学号/工号
|
||||||
</label>
|
</label>
|
||||||
<input type="text" id="id" name="id" required
|
<input type="text" id="id" name="id" required
|
||||||
placeholder="请输入学号或工号">
|
placeholder="请输入学号或工号" autocomplete="username">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
<i class="fas fa-lock"></i> 密码
|
<i class="fas fa-lock"></i> 密码
|
||||||
</label>
|
</label>
|
||||||
<input type="password" id="password" name="password" required
|
<input type="password" id="password" name="password" required
|
||||||
placeholder="请输入密码">
|
placeholder="请输入密码" autocomplete="new-password">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
<i class="fas fa-lock"></i> 确认密码
|
<i class="fas fa-lock"></i> 确认密码
|
||||||
</label>
|
</label>
|
||||||
<input type="password" id="confirmPassword" name="confirmPassword" required
|
<input type="password" id="confirmPassword" name="confirmPassword" required
|
||||||
placeholder="请再次输入密码">
|
placeholder="请再次输入密码" autocomplete="new-password">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -69,38 +69,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<button type="submit" class="btn btn-primary">
|
<button type="submit" class="btn btn-primary btn-block">
|
||||||
<i class="fas fa-user-plus"></i> 注册
|
<i class="fas fa-user-plus"></i> 注册
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="auth-footer">
|
<div class="auth-footer">
|
||||||
<p>已有账户? <a href="login.html">立即登录</a></p>
|
<p>已有账户? <a href="/login">立即登录</a></p>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<script src="../js/auth.js"></script>
|
|
||||||
<script>
|
<script src="/public/js/auth.js"></script>
|
||||||
// 显示/隐藏班级字段
|
|
||||||
document.getElementById('role').addEventListener('change', function() {
|
|
||||||
const role = this.value;
|
|
||||||
const classField = document.getElementById('classField');
|
|
||||||
const classInput = document.getElementById('class');
|
|
||||||
|
|
||||||
if (role === 'student' || role === 'teacher') {
|
|
||||||
classField.style.display = 'block';
|
|
||||||
classInput.required = true;
|
|
||||||
} else {
|
|
||||||
classField.style.display = 'none';
|
|
||||||
classInput.required = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初始化AuthManager
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
new AuthManager();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -3,34 +3,33 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>学生成绩管理系统 - 学生仪表板</title>
|
<title>摮衣<EFBFBD><EFBFBD>鞟貍蝞∠<EFBFBD>蝟餌<EFBFBD> - 摮衣<E691AE>隞芾”<E88ABE>?/title>
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="/public/css/style.css">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||||
</head>
|
</head>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- 顶部导航栏 -->
|
<!-- 憿園<EFBFBD>撖潸⏛<EFBFBD>?-->
|
||||||
<nav class="navbar">
|
<nav class="navbar">
|
||||||
<div class="navbar-brand">
|
<div class="navbar-brand">
|
||||||
<i class="fas fa-graduation-cap"></i>
|
<i class="fas fa-graduation-cap"></i>
|
||||||
<span>XX学校成绩管理系统</span>
|
<span>XX学校成绩管理系统</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-menu">
|
<div class="navbar-menu">
|
||||||
<a href="index.html" class="btn btn-secondary">
|
<a href="/" class="btn btn-secondary">
|
||||||
<i class="fas fa-home"></i> 主页
|
<i class="fas fa-home"></i> 主页
|
||||||
</a>
|
</a>
|
||||||
<div class="navbar-user">
|
<div class="navbar-user">
|
||||||
<span class="user-name" id="userName">加载中...</span>
|
<span class="user-name" id="userName"><EFBFBD>㰘蝸銝?..</span>
|
||||||
<button id="logoutBtn" class="btn btn-primary">
|
<button id="logoutBtn" class="btn btn-primary">
|
||||||
<i class="fas fa-sign-out-alt"></i> 退出
|
<i class="fas fa-sign-out-alt"></i> <EFBFBD><EFBFBD><EFBFBD>? </button>
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<!-- 仪表板容器 -->
|
<!-- 隞芾”<EFBFBD>踹捆<EFBFBD>?-->
|
||||||
<div class="dashboard-container">
|
<div class="dashboard-container">
|
||||||
<!-- 左侧侧边栏 -->
|
<!-- 撌虫儒靘扯器<EFBFBD>?-->
|
||||||
<aside class="sidebar">
|
<aside class="sidebar">
|
||||||
<div class="sidebar-header">
|
<div class="sidebar-header">
|
||||||
<div class="user-info">
|
<div class="user-info">
|
||||||
@@ -38,8 +37,8 @@
|
|||||||
<i class="fas fa-user-graduate"></i>
|
<i class="fas fa-user-graduate"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="user-details">
|
<div class="user-details">
|
||||||
<h3 id="studentName">加载中...</h3>
|
<h3 id="studentName"><EFBFBD>㰘蝸銝?..</h3>
|
||||||
<p>学生 | 班级:<span id="studentClass">加载中...</span></p>
|
<p>摮衣<EFBFBD> | <20>剔漣嚗?span id="studentClass"><3E>㰘蝸銝?..</span></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -48,7 +47,7 @@
|
|||||||
<li>
|
<li>
|
||||||
<a href="#" class="active">
|
<a href="#" class="active">
|
||||||
<i class="fas fa-tachometer-alt"></i>
|
<i class="fas fa-tachometer-alt"></i>
|
||||||
<span>仪表板</span>
|
<span>隞芾”<EFBFBD>?/span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@@ -88,11 +87,11 @@
|
|||||||
<main class="main-content">
|
<main class="main-content">
|
||||||
<div class="content-header">
|
<div class="content-header">
|
||||||
<div>
|
<div>
|
||||||
<h1 class="page-title">学生仪表板</h1>
|
<h1 class="page-title">摮衣<EFBFBD>隞芾”<EFBFBD>?/h1>
|
||||||
<div class="breadcrumb">
|
<div class="breadcrumb">
|
||||||
<a href="index.html">主页</a>
|
<a href="/">銝駁△</a>
|
||||||
<i class="fas fa-chevron-right"></i>
|
<i class="fas fa-chevron-right"></i>
|
||||||
<span>学生仪表板</span>
|
<span>摮衣<EFBFBD>隞芾”<EFBFBD>?/span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="current-time" id="currentTime"></div>
|
<div class="current-time" id="currentTime"></div>
|
||||||
@@ -121,7 +120,7 @@
|
|||||||
<i class="fas fa-certificate"></i>
|
<i class="fas fa-certificate"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-value" id="creditTotal">24</div>
|
<div class="stat-value" id="creditTotal">24</div>
|
||||||
<div class="stat-label">总学分</div>
|
<div class="stat-label"><EFBFBD>餃郎<EFBFBD>?/div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="stat-card">
|
<div class="stat-card">
|
||||||
@@ -136,16 +135,15 @@
|
|||||||
<!-- 成绩表格 -->
|
<!-- 成绩表格 -->
|
||||||
<div class="grades-table">
|
<div class="grades-table">
|
||||||
<div class="table-header">
|
<div class="table-header">
|
||||||
<h2 class="table-title">本学期成绩</h2>
|
<h2 class="table-title"><EFBFBD>砍郎<EFBFBD><EFBFBD><EFBFBD>蝏?/h2>
|
||||||
<div class="table-actions">
|
<div class="table-actions">
|
||||||
<select class="form-select" style="width: 150px;">
|
<select class="form-select" style="width: 150px;">
|
||||||
<option value="all">所有学期</option>
|
<option value="all"><EFBFBD><EFBFBD><EFBFBD>匧郎<EFBFBD>?/option>
|
||||||
<option value="2023-2" selected>2023-2024学年第二学期</option>
|
<option value="2023-2" selected>2023-2024学年第二学期</option>
|
||||||
<option value="2023-1">2023-2024学年第一学期</option>
|
<option value="2023-1">2023-2024学年第一学期</option>
|
||||||
</select>
|
</select>
|
||||||
<button class="btn btn-primary">
|
<button class="btn btn-primary">
|
||||||
<i class="fas fa-download"></i> 导出成绩单
|
<i class="fas fa-download"></i> 撖澆枂<EFBFBD>鞟貍<EFBFBD>? </button>
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -158,13 +156,13 @@
|
|||||||
<th>学分</th>
|
<th>学分</th>
|
||||||
<th>平时成绩</th>
|
<th>平时成绩</th>
|
||||||
<th>期末成绩</th>
|
<th>期末成绩</th>
|
||||||
<th>总成绩</th>
|
<th><EFBFBD>餅<EFBFBD>蝏?/th>
|
||||||
<th>绩点</th>
|
<th>绩点</th>
|
||||||
<th>操作</th>
|
<th>操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="gradesTableBody">
|
<tbody id="gradesTableBody">
|
||||||
<!-- 成绩数据将通过JavaScript动态加载 -->
|
<!-- <EFBFBD>鞟貍<EFBFBD>唳旿撠<EFBFBD><EFBFBD>朞<EFBFBD>JavaScript<EFBFBD>冽<EFBFBD><EFBFBD><EFBFBD>頧?-->
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@@ -172,8 +170,8 @@
|
|||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="../js/student.js"></script>
|
<script src="/public/js/student.js"></script>
|
||||||
<script src="../js/auth.js"></script>
|
<script src="/public/js/auth.js"></script>
|
||||||
<script>
|
<script>
|
||||||
// 更新当前时间
|
// 更新当前时间
|
||||||
function updateCurrentTime() {
|
function updateCurrentTime() {
|
||||||
@@ -192,4 +190,4 @@
|
|||||||
updateCurrentTime();
|
updateCurrentTime();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -3,8 +3,8 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>学生成绩管理系统 - 教师仪表板</title>
|
<title>摮衣<EFBFBD><EFBFBD>鞟貍蝞∠<EFBFBD>蝟餌<EFBFBD> - <20>坔<EFBFBD>隞芾”<E88ABE>?/title>
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="/public/css/style.css">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||||
</head>
|
</head>
|
||||||
/* 仪表板布局 */
|
/* 仪表板布局 */
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
min-height: calc(100vh - 80px);
|
min-height: calc(100vh - 80px);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 侧边栏 */
|
/* 靘扯器<EFBFBD>?*/
|
||||||
.sidebar {
|
.sidebar {
|
||||||
width: 250px;
|
width: 250px;
|
||||||
background: linear-gradient(180deg, #43e97b 0%, #38f9d7 100%);
|
background: linear-gradient(180deg, #43e97b 0%, #38f9d7 100%);
|
||||||
@@ -183,7 +183,7 @@
|
|||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 快速操作 */
|
/* 敹恍<EFBFBD><EFBFBD><EFBFBD>雿?*/
|
||||||
.quick-actions {
|
.quick-actions {
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
@@ -230,7 +230,7 @@
|
|||||||
border-color: #43e97b;
|
border-color: #43e97b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 最近活动 */
|
/* <EFBFBD><EFBFBD>餈烐暑<EFBFBD>?*/
|
||||||
.recent-activities {
|
.recent-activities {
|
||||||
background: white;
|
background: white;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
@@ -282,7 +282,7 @@
|
|||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 响应式设计 */
|
/* <EFBFBD>滚<EFBFBD>撘讛挽霈?*/
|
||||||
@media (max-width: 992px) {
|
@media (max-width: 992px) {
|
||||||
.dashboard-container {
|
.dashboard-container {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -344,28 +344,27 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- 顶部导航栏 -->
|
<!-- 憿園<EFBFBD>撖潸⏛<EFBFBD>?-->
|
||||||
<nav class="navbar">
|
<nav class="navbar">
|
||||||
<div class="navbar-brand">
|
<div class="navbar-brand">
|
||||||
<i class="fas fa-graduation-cap"></i>
|
<i class="fas fa-graduation-cap"></i>
|
||||||
<span>XX学校成绩管理系统</span>
|
<span>XX学校成绩管理系统</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-menu">
|
<div class="navbar-menu">
|
||||||
<a href="index.html" class="btn btn-secondary">
|
<a href="/" class="btn btn-secondary">
|
||||||
<i class="fas fa-home"></i> 主页
|
<i class="fas fa-home"></i> 主页
|
||||||
</a>
|
</a>
|
||||||
<div class="navbar-user">
|
<div class="navbar-user">
|
||||||
<span class="user-name" id="userName">李老师</span>
|
<span class="user-name" id="userName">李老师</span>
|
||||||
<button id="logoutBtn" class="btn btn-primary">
|
<button id="logoutBtn" class="btn btn-primary">
|
||||||
<i class="fas fa-sign-out-alt"></i> 退出
|
<i class="fas fa-sign-out-alt"></i> <EFBFBD><EFBFBD><EFBFBD>? </button>
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<!-- 仪表板容器 -->
|
<!-- 隞芾”<EFBFBD>踹捆<EFBFBD>?-->
|
||||||
<div class="dashboard-container">
|
<div class="dashboard-container">
|
||||||
<!-- 左侧侧边栏 -->
|
<!-- 撌虫儒靘扯器<EFBFBD>?-->
|
||||||
<aside class="sidebar">
|
<aside class="sidebar">
|
||||||
<div class="sidebar-header">
|
<div class="sidebar-header">
|
||||||
<div class="user-info">
|
<div class="user-info">
|
||||||
@@ -374,7 +373,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="user-details">
|
<div class="user-details">
|
||||||
<h3 id="teacherName">李老师</h3>
|
<h3 id="teacherName">李老师</h3>
|
||||||
<p>教师 | 部门:<span id="teacherDept">计算机学院</span></p>
|
<p><EFBFBD>坔<EFBFBD> | <20>券秄嚗?span id="teacherDept">霈∠<E99C88><E288A0>箏郎<E7AE8F>?/span></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -383,11 +382,11 @@
|
|||||||
<li>
|
<li>
|
||||||
<a href="#" class="active">
|
<a href="#" class="active">
|
||||||
<i class="fas fa-tachometer-alt"></i>
|
<i class="fas fa-tachometer-alt"></i>
|
||||||
<span>仪表板</span>
|
<span>隞芾”<EFBFBD>?/span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="grade_entry.html">
|
<a href="/teacher/grade_entry">
|
||||||
<i class="fas fa-edit"></i>
|
<i class="fas fa-edit"></i>
|
||||||
<span>成绩录入</span>
|
<span>成绩录入</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -429,11 +428,11 @@
|
|||||||
<main class="main-content">
|
<main class="main-content">
|
||||||
<div class="content-header">
|
<div class="content-header">
|
||||||
<div>
|
<div>
|
||||||
<h1 class="page-title">教师仪表板</h1>
|
<h1 class="page-title"><EFBFBD>坔<EFBFBD>隞芾”<EFBFBD>?/h1>
|
||||||
<div class="breadcrumb">
|
<div class="breadcrumb">
|
||||||
<a href="index.html">主页</a>
|
<a href="/">銝駁△</a>
|
||||||
<i class="fas fa-chevron-right"></i>
|
<i class="fas fa-chevron-right"></i>
|
||||||
<span>教师仪表板</span>
|
<span><EFBFBD>坔<EFBFBD>隞芾”<EFBFBD>?/span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="current-time" id="currentTime"></div>
|
<div class="current-time" id="currentTime"></div>
|
||||||
@@ -447,9 +446,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<h3 class="function-title">成绩录入</h3>
|
<h3 class="function-title">成绩录入</h3>
|
||||||
<p class="function-description">
|
<p class="function-description">
|
||||||
为学生录入新的课程成绩,支持批量导入和单个录入。
|
銝箏郎<EFBFBD>笔<EFBFBD><EFBFBD>交鰵<EFBFBD><EFBFBD>紋蝔𧢲<EFBFBD>蝏抬<EFBFBD><EFBFBD>舀<EFBFBD><EFBFBD>寥<EFBFBD>撖澆<EFBFBD><EFBFBD><EFBFBD><EFBFBD>銝芸<EFBFBD><EFBFBD>乓<EFBFBD>? </p>
|
||||||
</p>
|
<button class="btn btn-primary">撘<EFBFBD>憪见<EFBFBD><EFBFBD>?/button>
|
||||||
<button class="btn btn-primary">开始录入</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="function-card" onclick="window.location.href='grade_query.html'">
|
<div class="function-card" onclick="window.location.href='grade_query.html'">
|
||||||
@@ -458,9 +456,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<h3 class="function-title">成绩查询</h3>
|
<h3 class="function-title">成绩查询</h3>
|
||||||
<p class="function-description">
|
<p class="function-description">
|
||||||
查询学生成绩,支持按班级、课程、学期等多维度筛选。
|
<EFBFBD>亥砭摮衣<EFBFBD><EFBFBD>鞟貍嚗峕𣈲<EFBFBD><EFBFBD><EFBFBD><EFBFBD>剔漣<EFBFBD><EFBFBD>紋蝔卝<EFBFBD><EFBFBD>郎<EFBFBD>毺<EFBFBD>憭𡁶輕摨衣<EFBFBD><EFBFBD>剹<EFBFBD>? </p>
|
||||||
</p>
|
<button class="btn btn-primary">撘<EFBFBD>憪𧢲䰻霂?/button>
|
||||||
<button class="btn btn-primary">开始查询</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="function-card" onclick="window.location.href='grade_manage.html'">
|
<div class="function-card" onclick="window.location.href='grade_manage.html'">
|
||||||
@@ -469,9 +466,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<h3 class="function-title">成绩管理</h3>
|
<h3 class="function-title">成绩管理</h3>
|
||||||
<p class="function-description">
|
<p class="function-description">
|
||||||
修改或删除已录入的成绩,管理成绩记录和状态。
|
靽格㺿<EFBFBD>硋<EFBFBD><EFBFBD>文歇敶訫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝏抬<EFBFBD>蝞∠<EFBFBD><EFBFBD>鞟貍霈啣<EFBFBD><EFBFBD>𣬚𠶖<EFBFBD><EFBFBD><EFBFBD>? </p>
|
||||||
</p>
|
<button class="btn btn-primary">撘<EFBFBD>憪讠恣<EFBFBD>?/button>
|
||||||
<button class="btn btn-primary">开始管理</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="function-card" onclick="window.location.href='#'">
|
<div class="function-card" onclick="window.location.href='#'">
|
||||||
@@ -480,31 +476,27 @@
|
|||||||
</div>
|
</div>
|
||||||
<h3 class="function-title">统计分析</h3>
|
<h3 class="function-title">统计分析</h3>
|
||||||
<p class="function-description">
|
<p class="function-description">
|
||||||
查看成绩统计图表,分析教学效果和学生表现。
|
<EFBFBD>亦<EFBFBD><EFBFBD>鞟貍蝏蠘恣<EFBFBD>曇”嚗<EFBFBD><EFBFBD><EFBFBD>鞉<EFBFBD>摮行<EFBFBD><EFBFBD>𨅯<EFBFBD>摮衣<EFBFBD>銵函緵<EFBFBD>? </p>
|
||||||
</p>
|
|
||||||
<button class="btn btn-primary">查看统计</button>
|
<button class="btn btn-primary">查看统计</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 快速操作 -->
|
<!-- 敹恍<EFBFBD><EFBFBD><EFBFBD>雿?-->
|
||||||
<div class="quick-actions">
|
<div class="quick-actions">
|
||||||
<h2 class="section-title">
|
<h2 class="section-title">
|
||||||
<i class="fas fa-bolt"></i>
|
<i class="fas fa-bolt"></i>
|
||||||
快速操作
|
敹恍<EFBFBD><EFBFBD><EFBFBD>雿? </h2>
|
||||||
</h2>
|
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<a href="grade_entry.html" class="action-btn">
|
<a href="/teacher/grade_entry" class="action-btn">
|
||||||
<i class="fas fa-plus"></i>
|
<i class="fas fa-plus"></i>
|
||||||
录入新成绩
|
敶訫<EFBFBD><EFBFBD>唳<EFBFBD>蝏? </a>
|
||||||
</a>
|
|
||||||
<a href="grade_query.html" class="action-btn">
|
<a href="grade_query.html" class="action-btn">
|
||||||
<i class="fas fa-search"></i>
|
<i class="fas fa-search"></i>
|
||||||
查询成绩
|
查询成绩
|
||||||
</a>
|
</a>
|
||||||
<a href="#" class="action-btn">
|
<a href="#" class="action-btn">
|
||||||
<i class="fas fa-download"></i>
|
<i class="fas fa-download"></i>
|
||||||
导出成绩单
|
撖澆枂<EFBFBD>鞟貍<EFBFBD>? </a>
|
||||||
</a>
|
|
||||||
<a href="#" class="action-btn">
|
<a href="#" class="action-btn">
|
||||||
<i class="fas fa-chart-pie"></i>
|
<i class="fas fa-chart-pie"></i>
|
||||||
生成统计报告
|
生成统计报告
|
||||||
@@ -512,4 +504,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 最近活动
|
<!-- <EFBFBD><EFBFBD>餈烐暑<EFBFBD>
|
||||||
@@ -4,34 +4,34 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>成绩录入 - XX学校成绩管理系统</title>
|
<title>成绩录入 - XX学校成绩管理系统</title>
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="/public/css/style.css">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- 导航栏 -->
|
<!-- 撖潸⏛<EFBFBD>?-->
|
||||||
<nav class="navbar">
|
<nav class="navbar">
|
||||||
<div class="navbar-brand">
|
<div class="navbar-brand">
|
||||||
<a href="index.html"><i class="fas fa-graduation-cap"></i> XX学校成绩管理系统</a>
|
<a href="/"><i class="fas fa-graduation-cap"></i> XX摮行嵗<EFBFBD>鞟貍蝞∠<EFBFBD>蝟餌<EFBFBD></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-menu">
|
<div class="navbar-menu">
|
||||||
<a href="teacher_dashboard.html" class="navbar-item"><i class="fas fa-tachometer-alt"></i> 教师仪表板</a>
|
<a href="/teacher/dashboard" class="navbar-item"><i class="fas fa-tachometer-alt"></i> <EFBFBD>坔<EFBFBD>隞芾”<EFBFBD>?/a>
|
||||||
<a href="grade_entry.html" class="navbar-item active"><i class="fas fa-edit"></i> 成绩录入</a>
|
<a href="/teacher/grade_entry" class="navbar-item active"><i class="fas fa-edit"></i> <EFBFBD>鞟貍敶訫<EFBFBD></a>
|
||||||
<a href="grade_management.html" class="navbar-item"><i class="fas fa-list"></i> 成绩管理</a>
|
<a href="/teacher/grade_management" class="navbar-item"><i class="fas fa-list"></i> <EFBFBD>鞟貍蝞∠<EFBFBD></a>
|
||||||
<div class="user-info">
|
<div class="user-info">
|
||||||
<span class="user-name">李老师</span>
|
<span class="user-name">李老师</span>
|
||||||
<span class="user-role">教师</span>
|
<span class="user-role">教师</span>
|
||||||
<a href="login.html" class="btn btn-outline btn-small"><i class="fas fa-sign-out-alt"></i> 退出</a>
|
<a href="/login" class="btn btn-outline btn-small"><i class="fas fa-sign-out-alt"></i> <EFBFBD><EFBFBD><EFBFBD>?/a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<!-- 面包屑导航 -->
|
<!-- <EFBFBD>W<EFBFBD>撅穃紡<EFBFBD>?-->
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="breadcrumb">
|
<div class="breadcrumb">
|
||||||
<a href="index.html">主页</a>
|
<a href="/">銝駁△</a>
|
||||||
<i class="fas fa-chevron-right"></i>
|
<i class="fas fa-chevron-right"></i>
|
||||||
<a href="teacher_dashboard.html">教师仪表板</a>
|
<a href="/teacher/dashboard"><EFBFBD>坔<EFBFBD>隞芾”<EFBFBD>?/a>
|
||||||
<i class="fas fa-chevron-right"></i>
|
<i class="fas fa-chevron-right"></i>
|
||||||
<span>成绩录入</span>
|
<span>成绩录入</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<div class="grade-entry-container">
|
<div class="grade-entry-container">
|
||||||
<div class="entry-header">
|
<div class="entry-header">
|
||||||
<h1><i class="fas fa-edit"></i> 成绩录入</h1>
|
<h1><i class="fas fa-edit"></i> 成绩录入</h1>
|
||||||
<p>请选择班级和课程,然后为每个学生录入成绩</p>
|
<p>霂琿<EFBFBD>㗇𥋘<EFBFBD>剔漣<EFBFBD>諹紋蝔页<EFBFBD><EFBFBD>嗅<EFBFBD>銝箸<EFBFBD>銝芸郎<EFBFBD>笔<EFBFBD><EFBFBD>交<EFBFBD>蝏?/p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="entry-form">
|
<div class="entry-form">
|
||||||
@@ -50,11 +50,11 @@
|
|||||||
<label for="class-select"><i class="fas fa-users"></i> 选择班级</label>
|
<label for="class-select"><i class="fas fa-users"></i> 选择班级</label>
|
||||||
<select id="class-select" class="form-control">
|
<select id="class-select" class="form-control">
|
||||||
<option value="">请选择班级</option>
|
<option value="">请选择班级</option>
|
||||||
<option value="class1">计算机科学与技术2021级1班</option>
|
<option value="class1">霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?021蝥?<3F>?/option>
|
||||||
<option value="class2">计算机科学与技术2021级2班</option>
|
<option value="class2">霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?021蝥?<3F>?/option>
|
||||||
<option value="class3">软件工程2021级1班</option>
|
<option value="class3">頧臭辣撌亦<EFBFBD>2021蝥?<3F>?/option>
|
||||||
<option value="class4">软件工程2021级2班</option>
|
<option value="class4">頧臭辣撌亦<EFBFBD>2021蝥?<3F>?/option>
|
||||||
<option value="class5">网络工程2021级1班</option>
|
<option value="class5">蝵𤑳<EFBFBD>撌亦<EFBFBD>2021蝥?<3F>?/option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -71,12 +71,12 @@
|
|||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label><i class="fas fa-info-circle"></i> 备注说明(可选)</label>
|
<label><i class="fas fa-info-circle"></i> 备注说明(可选)</label>
|
||||||
<textarea id="remarks" rows="3" placeholder="可输入本次考试的说明信息,如:期中考试、期末考试等"></textarea>
|
<textarea id="remarks" rows="3" placeholder="<EFBFBD>航<EFBFBD><EFBFBD>交𧋦甈∟<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>秩<EFBFBD>𦒘縑<EFBFBD>荔<EFBFBD>憒<EFBFBD><EFBFBD><EFBFBD>煺葉<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>怨<EFBFBD><EFBFBD><EFBFBD>蝑?></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="students-table-container">
|
<div class="students-table-container">
|
||||||
<h3><i class="fas fa-user-graduate"></i> 学生成绩录入</h3>
|
<h3><i class="fas fa-user-graduate"></i> 学生成绩录入</h3>
|
||||||
<p class="text-muted">选择班级后,系统将自动加载该班级的学生列表</p>
|
<p class="text-muted"><EFBFBD>㗇𥋘<EFBFBD>剔漣<EFBFBD>𠬍<EFBFBD>蝟餌<EFBFBD>撠<EFBFBD>䌊<EFBFBD>典<EFBFBD>頧質砲<EFBFBD>剔漣<EFBFBD><EFBFBD>郎<EFBFBD>笔<EFBFBD>銵?/p>
|
||||||
|
|
||||||
<div id="students-loading" class="loading" style="display: none;">
|
<div id="students-loading" class="loading" style="display: none;">
|
||||||
<i class="fas fa-spinner"></i>
|
<i class="fas fa-spinner"></i>
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="students-tbody">
|
<tbody id="students-tbody">
|
||||||
<!-- 学生数据将通过JavaScript动态加载 -->
|
<!-- 摮衣<EFBFBD><EFBFBD>唳旿撠<EFBFBD><EFBFBD>朞<EFBFBD>JavaScript<EFBFBD>冽<EFBFBD><EFBFBD><EFBFBD>頧?-->
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@@ -118,11 +118,11 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<h3><i class="fas fa-lightbulb"></i> 使用说明</h3>
|
<h3><i class="fas fa-lightbulb"></i> 使用说明</h3>
|
||||||
<ul class="text-muted">
|
<ul class="text-muted">
|
||||||
<li>首先选择要录入成绩的班级和课程</li>
|
<li>擐硋<EFBFBD><EFBFBD>㗇𥋘閬<EFBFBD><EFBFBD><EFBFBD>交<EFBFBD>蝏拍<EFBFBD><EFBFBD>剔漣<EFBFBD>諹紋蝔?/li>
|
||||||
<li>系统会自动加载该班级的学生列表</li>
|
<li>蝟餌<EFBFBD>隡朞䌊<EFBFBD>典<EFBFBD>頧質砲<EFBFBD>剔漣<EFBFBD><EFBFBD>郎<EFBFBD>笔<EFBFBD>銵?/li>
|
||||||
<li>为每个学生输入平时成绩、期中成绩和期末成绩</li>
|
<li>为每个学生输入平时成绩、期中成绩和期末成绩</li>
|
||||||
<li>总评成绩将根据权重自动计算(默认权重:平时20%,期中30%,期末50%)</li>
|
<li><EFBFBD>餉<EFBFBD><EFBFBD>鞟貍撠<EFBFBD>覔<EFBFBD>格<EFBFBD><EFBFBD>滩䌊<EFBFBD>刻恣蝞梹<EFBFBD>暺䁅恕<EFBFBD><EFBFBD><EFBFBD>嚗𡁜像<EFBFBD>?0%嚗峕<E59A97>銝?0%嚗峕<E59A97><E5B395>?0%嚗?/li>
|
||||||
<li>确认无误后点击“提交成绩”按钮保存数据</li>
|
<li>蝖株恕<EFBFBD>㰘秤<EFBFBD>𡒊<EFBFBD><EFBFBD>領<EFBFBD>𨀣<EFBFBD>鈭斗<EFBFBD>蝏抽<EFBFBD>脲<EFBFBD><EFBFBD>桐<EFBFBD>摮䀹㺭<EFBFBD>?/li>
|
||||||
<li>提交后可以在“成绩管理”页面查看和修改已录入的成绩</li>
|
<li>提交后可以在“成绩管理”页面查看和修改已录入的成绩</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -154,8 +154,7 @@
|
|||||||
const cancelBtn = document.getElementById('cancel-btn');
|
const cancelBtn = document.getElementById('cancel-btn');
|
||||||
const submitBtn = document.getElementById('submit-btn');
|
const submitBtn = document.getElementById('submit-btn');
|
||||||
|
|
||||||
// 设置默认考试日期为今天
|
// 霈曄蔭暺䁅恕<EFBFBD><EFBFBD><EFBFBD><EFBFBD>交<EFBFBD>銝箔<EFBFBD>憭? const today = new Date().toISOString().split('T')[0];
|
||||||
const today = new Date().toISOString().split('T')[0];
|
|
||||||
examDateInput.value = today;
|
examDateInput.value = today;
|
||||||
|
|
||||||
// 班级选择变化事件
|
// 班级选择变化事件
|
||||||
@@ -168,8 +167,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 显示加载状态
|
// <EFBFBD>曄內<EFBFBD>㰘蝸<EFBFBD>嗆<EFBFBD>? showLoading();
|
||||||
showLoading();
|
|
||||||
|
|
||||||
// 模拟API调用延迟
|
// 模拟API调用延迟
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -194,8 +192,7 @@
|
|||||||
// 清空表格
|
// 清空表格
|
||||||
studentsTbody.innerHTML = '';
|
studentsTbody.innerHTML = '';
|
||||||
|
|
||||||
// 添加学生行
|
// 瘛餃<EFBFBD>摮衣<EFBFBD>銵? students.forEach((student, index) => {
|
||||||
students.forEach((student, index) => {
|
|
||||||
const row = document.createElement('tr');
|
const row = document.createElement('tr');
|
||||||
row.innerHTML = `
|
row.innerHTML = `
|
||||||
<td>${student.id}</td>
|
<td>${student.id}</td>
|
||||||
@@ -234,20 +231,17 @@
|
|||||||
addGradeInputListeners();
|
addGradeInputListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 显示加载状态
|
// <EFBFBD>曄內<EFBFBD>㰘蝸<EFBFBD>嗆<EFBFBD>? function showLoading() {
|
||||||
function showLoading() {
|
|
||||||
studentsLoading.style.display = 'block';
|
studentsLoading.style.display = 'block';
|
||||||
studentsTable.style.display = 'none';
|
studentsTable.style.display = 'none';
|
||||||
noStudents.style.display = 'none';
|
noStudents.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 隐藏加载状态
|
// <EFBFBD>鞱<EFBFBD><EFBFBD>㰘蝸<EFBFBD>嗆<EFBFBD>? function hideLoading() {
|
||||||
function hideLoading() {
|
|
||||||
studentsLoading.style.display = 'none';
|
studentsLoading.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
// 显示无学生数据
|
// <EFBFBD>曄內<EFBFBD>惩郎<EFBFBD><EFBFBD>㺭<EFBFBD>? function showNoStudents() {
|
||||||
function showNoStudents() {
|
|
||||||
hideLoading();
|
hideLoading();
|
||||||
studentsTable.style.display = 'none';
|
studentsTable.style.display = 'none';
|
||||||
noStudents.style.display = 'block';
|
noStudents.style.display = 'block';
|
||||||
@@ -293,11 +287,9 @@
|
|||||||
const midterm = parseFloat(midtermInput.value) || 0;
|
const midterm = parseFloat(midtermInput.value) || 0;
|
||||||
const final = parseFloat(finalInput.value) || 0;
|
const final = parseFloat(finalInput.value) || 0;
|
||||||
|
|
||||||
// 计算总评成绩(权重:平时20%,期中30%,期末50%)
|
// 霈∠<EFBFBD><EFBFBD>餉<EFBFBD><EFBFBD>鞟貍嚗<EFBFBD><EFBFBD><EFBFBD>㵪<EFBFBD>撟單𧒄20%嚗峕<E59A97>銝?0%嚗峕<E59A97><E5B395>?0%嚗? const total = (usual * 0.2) + (midterm * 0.3) + (final * 0.5);
|
||||||
const total = (usual * 0.2) + (midterm * 0.3) + (final * 0.5);
|
|
||||||
|
|
||||||
// 显示总评成绩(四舍五入到整数)
|
// <EFBFBD>曄內<EFBFBD>餉<EFBFBD><EFBFBD>鞟貍嚗<EFBFBD><EFBFBD><EFBFBD>滢<EFBFBD><EFBFBD>亙<EFBFBD><EFBFBD>湔㺭嚗? totalSpan.textContent = Math.round(total);
|
||||||
totalSpan.textContent = Math.round(total);
|
|
||||||
|
|
||||||
// 根据成绩范围设置颜色
|
// 根据成绩范围设置颜色
|
||||||
if (total >= 90) {
|
if (total >= 90) {
|
||||||
@@ -323,13 +315,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!courseName) {
|
if (!courseName) {
|
||||||
alert('请输入课程名称');
|
alert('霂瑁<EFBFBD><EFBFBD>亥紋蝔见<EFBFBD>蝘?);
|
||||||
courseNameInput.focus();
|
courseNameInput.focus();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否有学生成绩未填写
|
// 璉<EFBFBD><EFBFBD>交糓<EFBFBD>行<EFBFBD>摮衣<EFBFBD><EFBFBD>鞟貍<EFBFBD>芸‵<EFBFBD>? const usualGrades = document.querySelectorAll('.usual-grade');
|
||||||
const usualGrades = document.querySelectorAll('.usual-grade');
|
|
||||||
const midtermGrades = document.querySelectorAll('.midterm-grade');
|
const midtermGrades = document.querySelectorAll('.midterm-grade');
|
||||||
const finalGrades = document.querySelectorAll('.final-grade');
|
const finalGrades = document.querySelectorAll('.final-grade');
|
||||||
|
|
||||||
@@ -350,7 +341,7 @@
|
|||||||
if (usualNum < 0 || usualNum > 100 ||
|
if (usualNum < 0 || usualNum > 100 ||
|
||||||
midtermNum < 0 || midtermNum > 100 ||
|
midtermNum < 0 || midtermNum > 100 ||
|
||||||
finalNum < 0 || finalNum > 100) {
|
finalNum < 0 || finalNum > 100) {
|
||||||
alert(`第${i + 1}行学生的成绩必须在0-100之间`);
|
alert(`蝚?{i + 1}銵<EFBFBD>郎<EFBFBD>毺<EFBFBD><EFBFBD>鞟貍敹<EFBFBD>◆<EFBFBD>?-100銋钅𡢿`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -403,17 +394,15 @@
|
|||||||
|
|
||||||
const formData = collectFormData();
|
const formData = collectFormData();
|
||||||
|
|
||||||
// 显示提交中状态
|
// <EFBFBD>曄內<EFBFBD>𣂷漱銝剔𠶖<EFBFBD>? submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> <20>𣂷漱銝?..';
|
||||||
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 提交中...';
|
|
||||||
submitBtn.disabled = true;
|
submitBtn.disabled = true;
|
||||||
|
|
||||||
// 模拟API调用
|
// 模拟API调用
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// 模拟成功响应
|
// 模拟成功响应
|
||||||
alert(`成绩提交成功!\n班级:${formData.className}\n课程:${formData.courseName}\n共录入${formData.grades.length}名学生成绩`);
|
alert(`<EFBFBD>鞟貍<EFBFBD>𣂷漱<EFBFBD>𣂼<EFBFBD>嚗<EFBFBD>n<EFBFBD>剔漣嚗?{formData.className}\n霂曄<EFBFBD>嚗?{formData.courseName}\n<EFBFBD>勗<EFBFBD><EFBFBD>?{formData.grades.length}<EFBFBD>滚郎<EFBFBD><EFBFBD><EFBFBD>蝏奈);
|
||||||
|
|
||||||
// 重置按钮状态
|
// <EFBFBD>滨蔭<EFBFBD>厰僼<EFBFBD>嗆<EFBFBD>? submitBtn.innerHTML = '<i class="fas fa-check"></i> <20>𣂷漱<F0A382B7>鞟貍';
|
||||||
submitBtn.innerHTML = '<i class="fas fa-check"></i> 提交成绩';
|
|
||||||
submitBtn.disabled = false;
|
submitBtn.disabled = false;
|
||||||
|
|
||||||
// 重置表单
|
// 重置表单
|
||||||
@@ -439,7 +428,7 @@
|
|||||||
|
|
||||||
// 取消按钮事件
|
// 取消按钮事件
|
||||||
cancelBtn.addEventListener('click', function() {
|
cancelBtn.addEventListener('click', function() {
|
||||||
if (confirm('确定要取消吗?所有未保存的更改将会丢失。')) {
|
if (confirm('蝖桀<EFBFBD>閬<EFBFBD><EFBFBD>瘨<EFBFBD><EFBFBD>嚗<EFBFBD><EFBFBD><EFBFBD>㗇𧊋靽嘥<EFBFBD><EFBFBD><EFBFBD>凒<EFBFBD>孵<EFBFBD>隡帋腺憭晞<EFBFBD>?)) {
|
||||||
resetForm();
|
resetForm();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -449,11 +438,10 @@
|
|||||||
|
|
||||||
// 页面加载时初始化
|
// 页面加载时初始化
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
// 检查是否有必要的数据
|
// 璉<EFBFBD><EFBFBD>交糓<EFBFBD>行<EFBFBD>敹<EFBFBD><EFBFBD><EFBFBD><EFBFBD>㺭<EFBFBD>? if (!classSelect.value) {
|
||||||
if (!classSelect.value) {
|
|
||||||
submitBtn.disabled = true;
|
submitBtn.disabled = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -4,30 +4,30 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>成绩查询/管理 - 学生成绩管理系统</title>
|
<title>成绩查询/管理 - 学生成绩管理系统</title>
|
||||||
<link rel="stylesheet" href="../css/style.css">
|
<link rel="stylesheet" href="/public/css/style.css">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- 导航栏 -->
|
<!-- 撖潸⏛<EFBFBD>?-->
|
||||||
<nav class="navbar">
|
<nav class="navbar">
|
||||||
<div class="nav-container">
|
<div class="nav-container">
|
||||||
<div class="nav-brand">
|
<div class="nav-brand">
|
||||||
<a href="index.html">
|
<a href="/">
|
||||||
<i class="fas fa-graduation-cap"></i>
|
<i class="fas fa-graduation-cap"></i>
|
||||||
<span>XX学校成绩管理系统</span>
|
<span>XX学校成绩管理系统</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="nav-menu">
|
<div class="nav-menu">
|
||||||
<a href="teacher_dashboard.html" class="nav-link">
|
<a href="/teacher/dashboard" class="nav-link">
|
||||||
<i class="fas fa-tachometer-alt"></i>
|
<i class="fas fa-tachometer-alt"></i>
|
||||||
<span>教师仪表板</span>
|
<span><EFBFBD>坔<EFBFBD>隞芾”<EFBFBD>?/span>
|
||||||
</a>
|
</a>
|
||||||
<a href="grade_entry.html" class="nav-link">
|
<a href="/teacher/grade_entry" class="nav-link">
|
||||||
<i class="fas fa-edit"></i>
|
<i class="fas fa-edit"></i>
|
||||||
<span>成绩录入</span>
|
<span>成绩录入</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="grade_management.html" class="nav-link active">
|
<a href="/teacher/grade_management" class="nav-link active">
|
||||||
<i class="fas fa-search"></i>
|
<i class="fas fa-search"></i>
|
||||||
<span>成绩管理</span>
|
<span>成绩管理</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -37,9 +37,9 @@
|
|||||||
<i class="fas fa-user-circle"></i>
|
<i class="fas fa-user-circle"></i>
|
||||||
<span>张老师</span>
|
<span>张老师</span>
|
||||||
</div>
|
</div>
|
||||||
<a href="login.html" class="btn-logout">
|
<a href="/login" class="btn-logout">
|
||||||
<i class="fas fa-sign-out-alt"></i>
|
<i class="fas fa-sign-out-alt"></i>
|
||||||
<span>退出</span>
|
<span><EFBFBD><EFBFBD><EFBFBD>?/span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -48,11 +48,11 @@
|
|||||||
<!-- 主内容区 -->
|
<!-- 主内容区 -->
|
||||||
<main class="main-content">
|
<main class="main-content">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<!-- 面包屑导航 -->
|
<!-- <EFBFBD>W<EFBFBD>撅穃紡<EFBFBD>?-->
|
||||||
<div class="breadcrumb">
|
<div class="breadcrumb">
|
||||||
<a href="index.html">主页</a>
|
<a href="/">銝駁△</a>
|
||||||
<i class="fas fa-chevron-right"></i>
|
<i class="fas fa-chevron-right"></i>
|
||||||
<a href="teacher_dashboard.html">教师仪表板</a>
|
<a href="/teacher/dashboard"><EFBFBD>坔<EFBFBD>隞芾”<EFBFBD>?/a>
|
||||||
<i class="fas fa-chevron-right"></i>
|
<i class="fas fa-chevron-right"></i>
|
||||||
<span>成绩查询/管理</span>
|
<span>成绩查询/管理</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -63,22 +63,21 @@
|
|||||||
<p class="page-description">查询、修改和删除学生成绩记录</p>
|
<p class="page-description">查询、修改和删除学生成绩记录</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 筛选区域 -->
|
<!-- 蝑偦<EFBFBD>匧躹<EFBFBD>?-->
|
||||||
<div class="filter-section">
|
<div class="filter-section">
|
||||||
<h2 class="filter-title">
|
<h2 class="filter-title">
|
||||||
<i class="fas fa-filter"></i>
|
<i class="fas fa-filter"></i>
|
||||||
筛选条件
|
蝑偦<EFBFBD>㗇辺隞? </h2>
|
||||||
</h2>
|
|
||||||
<div class="filter-form">
|
<div class="filter-form">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="class-select">班级</label>
|
<label for="class-select">班级</label>
|
||||||
<select id="class-select" class="form-control">
|
<select id="class-select" class="form-control">
|
||||||
<option value="">全部班级</option>
|
<option value="">全部班级</option>
|
||||||
<option value="class1">计算机科学与技术1班</option>
|
<option value="class1">霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?/option>
|
||||||
<option value="class2">计算机科学与技术2班</option>
|
<option value="class2">霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?/option>
|
||||||
<option value="class3">软件工程1班</option>
|
<option value="class3">頧臭辣撌亦<EFBFBD>1<EFBFBD>?/option>
|
||||||
<option value="class4">软件工程2班</option>
|
<option value="class4">頧臭辣撌亦<EFBFBD>2<EFBFBD>?/option>
|
||||||
<option value="class5">网络工程1班</option>
|
<option value="class5">蝵𤑳<EFBFBD>撌亦<EFBFBD>1<EFBFBD>?/option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -87,8 +86,8 @@
|
|||||||
<option value="">全部课程</option>
|
<option value="">全部课程</option>
|
||||||
<option value="course1">数据结构</option>
|
<option value="course1">数据结构</option>
|
||||||
<option value="course2">操作系统</option>
|
<option value="course2">操作系统</option>
|
||||||
<option value="course3">计算机网络</option>
|
<option value="course3">霈∠<EFBFBD><EFBFBD>箇<EFBFBD>蝏?/option>
|
||||||
<option value="course4">数据库系统</option>
|
<option value="course4"><EFBFBD>唳旿摨梶頂蝏?/option>
|
||||||
<option value="course5">软件工程</option>
|
<option value="course5">软件工程</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@@ -147,7 +146,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="grade-table-body">
|
<tbody id="grade-table-body">
|
||||||
<!-- 数据将通过JavaScript动态加载 -->
|
<!-- <EFBFBD>唳旿撠<EFBFBD><EFBFBD>朞<EFBFBD>JavaScript<EFBFBD>冽<EFBFBD><EFBFBD><EFBFBD>頧?-->
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="11" class="loading">
|
<td colspan="11" class="loading">
|
||||||
<i class="fas fa-spinner fa-spin"></i>
|
<i class="fas fa-spinner fa-spin"></i>
|
||||||
@@ -160,11 +159,11 @@
|
|||||||
|
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<div class="pagination">
|
<div class="pagination">
|
||||||
<button id="prev-page" disabled>上一页</button>
|
<button id="prev-page" disabled>銝𠹺<EFBFBD>憿?/button>
|
||||||
<button class="active">1</button>
|
<button class="active">1</button>
|
||||||
<button>2</button>
|
<button>2</button>
|
||||||
<button>3</button>
|
<button>3</button>
|
||||||
<button id="next-page">下一页</button>
|
<button id="next-page">銝衤<EFBFBD>憿?/button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -173,8 +172,8 @@
|
|||||||
<!-- 页脚 -->
|
<!-- 页脚 -->
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<p>© 2023 XX学校成绩管理系统. 版权所有.</p>
|
<p>© 2023 XX摮行嵗<EFBFBD>鞟貍蝞∠<EFBFBD>蝟餌<EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?</p>
|
||||||
<p>技术支持: 计算机科学与技术学院</p>
|
<p><EFBFBD><EFBFBD><EFBFBD>舀𣈲<EFBFBD>? 霈∠<E99C88><E288A0>箇<EFBFBD>摮虫<E691AE><E899AB><EFBFBD><EFBFBD>臬郎<E887AC>?/p>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
@@ -185,7 +184,7 @@
|
|||||||
id: 1,
|
id: 1,
|
||||||
studentId: "20230001",
|
studentId: "20230001",
|
||||||
studentName: "张三",
|
studentName: "张三",
|
||||||
className: "计算机科学与技术1班",
|
className: "霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?,
|
||||||
courseName: "数据结构",
|
courseName: "数据结构",
|
||||||
regularScore: 85,
|
regularScore: 85,
|
||||||
midtermScore: 88,
|
midtermScore: 88,
|
||||||
@@ -197,7 +196,7 @@
|
|||||||
id: 2,
|
id: 2,
|
||||||
studentId: "20230002",
|
studentId: "20230002",
|
||||||
studentName: "李四",
|
studentName: "李四",
|
||||||
className: "计算机科学与技术1班",
|
className: "霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?,
|
||||||
courseName: "数据结构",
|
courseName: "数据结构",
|
||||||
regularScore: 78,
|
regularScore: 78,
|
||||||
midtermScore: 82,
|
midtermScore: 82,
|
||||||
@@ -209,7 +208,7 @@
|
|||||||
id: 3,
|
id: 3,
|
||||||
studentId: "20230003",
|
studentId: "20230003",
|
||||||
studentName: "王五",
|
studentName: "王五",
|
||||||
className: "计算机科学与技术2班",
|
className: "霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?,
|
||||||
courseName: "操作系统",
|
courseName: "操作系统",
|
||||||
regularScore: 92,
|
regularScore: 92,
|
||||||
midtermScore: 88,
|
midtermScore: 88,
|
||||||
@@ -221,7 +220,7 @@
|
|||||||
id: 4,
|
id: 4,
|
||||||
studentId: "20230004",
|
studentId: "20230004",
|
||||||
studentName: "赵六",
|
studentName: "赵六",
|
||||||
className: "计算机科学与技术2班",
|
className: "霈∠<EFBFBD><EFBFBD>箇<EFBFBD>摮虫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<3F>?,
|
||||||
courseName: "操作系统",
|
courseName: "操作系统",
|
||||||
regularScore: 65,
|
regularScore: 65,
|
||||||
midtermScore: 70,
|
midtermScore: 70,
|
||||||
@@ -233,8 +232,8 @@
|
|||||||
id: 5,
|
id: 5,
|
||||||
studentId: "20230005",
|
studentId: "20230005",
|
||||||
studentName: "钱七",
|
studentName: "钱七",
|
||||||
className: "软件工程1班",
|
className: "頧臭辣撌亦<EFBFBD>1<EFBFBD>?,
|
||||||
courseName: "数据库系统",
|
courseName: "<EFBFBD>唳旿摨梶頂蝏?,
|
||||||
regularScore: 88,
|
regularScore: 88,
|
||||||
midtermScore: 85,
|
midtermScore: 85,
|
||||||
finalScore: 90,
|
finalScore: 90,
|
||||||
@@ -245,8 +244,8 @@
|
|||||||
id: 6,
|
id: 6,
|
||||||
studentId: "20230006",
|
studentId: "20230006",
|
||||||
studentName: "孙八",
|
studentName: "孙八",
|
||||||
className: "软件工程1班",
|
className: "頧臭辣撌亦<EFBFBD>1<EFBFBD>?,
|
||||||
courseName: "数据库系统",
|
courseName: "<EFBFBD>唳旿摨梶頂蝏?,
|
||||||
regularScore: 75,
|
regularScore: 75,
|
||||||
midtermScore: 78,
|
midtermScore: 78,
|
||||||
finalScore: 80,
|
finalScore: 80,
|
||||||
@@ -257,7 +256,7 @@
|
|||||||
id: 7,
|
id: 7,
|
||||||
studentId: "20230007",
|
studentId: "20230007",
|
||||||
studentName: "周九",
|
studentName: "周九",
|
||||||
className: "软件工程2班",
|
className: "頧臭辣撌亦<EFBFBD>2<EFBFBD>?,
|
||||||
courseName: "软件工程",
|
courseName: "软件工程",
|
||||||
regularScore: 90,
|
regularScore: 90,
|
||||||
midtermScore: 92,
|
midtermScore: 92,
|
||||||
@@ -269,7 +268,7 @@
|
|||||||
id: 8,
|
id: 8,
|
||||||
studentId: "20230008",
|
studentId: "20230008",
|
||||||
studentName: "吴十",
|
studentName: "吴十",
|
||||||
className: "软件工程2班",
|
className: "頧臭辣撌亦<EFBFBD>2<EFBFBD>?,
|
||||||
courseName: "软件工程",
|
courseName: "软件工程",
|
||||||
regularScore: 82,
|
regularScore: 82,
|
||||||
midtermScore: 85,
|
midtermScore: 85,
|
||||||
@@ -294,8 +293,7 @@
|
|||||||
// 当前选中的成绩ID
|
// 当前选中的成绩ID
|
||||||
let selectedGradeIds = new Set();
|
let selectedGradeIds = new Set();
|
||||||
|
|
||||||
// 初始化页面
|
// <EFBFBD>嘥<EFBFBD><EFBFBD>㚚△<EFBFBD>? function initPage() {
|
||||||
function initPage() {
|
|
||||||
renderGradeTable(mockGrades);
|
renderGradeTable(mockGrades);
|
||||||
setupEventListeners();
|
setupEventListeners();
|
||||||
updateSelectedCount();
|
updateSelectedCount();
|
||||||
@@ -308,7 +306,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td colspan="11" class="no-results">
|
<td colspan="11" class="no-results">
|
||||||
<i class="fas fa-search"></i>
|
<i class="fas fa-search"></i>
|
||||||
<h3>未找到相关成绩记录</h3>
|
<h3><EFBFBD>芣𪄳<EFBFBD>啁㮾<EFBFBD>單<EFBFBD>蝏抵扇敶?/h3>
|
||||||
<p>请尝试调整筛选条件或添加新的成绩记录</p>
|
<p>请尝试调整筛选条件或添加新的成绩记录</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -319,8 +317,7 @@
|
|||||||
let tableHTML = '';
|
let tableHTML = '';
|
||||||
|
|
||||||
grades.forEach(grade => {
|
grades.forEach(grade => {
|
||||||
// 根据成绩确定CSS类
|
// <EFBFBD>寞旿<EFBFBD>鞟貍蝖桀<EFBFBD>CSS蝐? let gradeClass = 'grade-cell';
|
||||||
let gradeClass = 'grade-cell';
|
|
||||||
if (grade.totalScore >= 90) {
|
if (grade.totalScore >= 90) {
|
||||||
gradeClass += ' grade-excellent';
|
gradeClass += ' grade-excellent';
|
||||||
} else if (grade.totalScore >= 80) {
|
} else if (grade.totalScore >= 80) {
|
||||||
@@ -377,8 +374,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置事件监听器
|
// 霈曄蔭鈭衤辣<EFBFBD>穃𨯬<EFBFBD>? function setupEventListeners() {
|
||||||
function setupEventListeners() {
|
|
||||||
// 查询按钮
|
// 查询按钮
|
||||||
searchBtn.addEventListener('click', function() {
|
searchBtn.addEventListener('click', function() {
|
||||||
performSearch();
|
performSearch();
|
||||||
@@ -404,11 +400,11 @@
|
|||||||
// 批量删除按钮
|
// 批量删除按钮
|
||||||
batchDeleteBtn.addEventListener('click', function() {
|
batchDeleteBtn.addEventListener('click', function() {
|
||||||
if (selectedGradeIds.size === 0) {
|
if (selectedGradeIds.size === 0) {
|
||||||
alert('请先选择要删除的成绩记录!');
|
alert('霂瑕<EFBFBD><EFBFBD>㗇𥋘閬<EFBFBD><EFBFBD><EFBFBD>斤<EFBFBD><EFBFBD>鞟貍霈啣<EFBFBD>嚗?);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (confirm(`确定要删除选中的 ${selectedGradeIds.size} 条成绩记录吗?此操作不可撤销。`)) {
|
if (confirm(`蝖桀<EFBFBD>閬<EFBFBD><EFBFBD><EFBFBD>日<EFBFBD>劐葉<EFBFBD>?${selectedGradeIds.size} <EFBFBD>⊥<EFBFBD>蝏抵扇敶訫<EFBFBD>嚗<EFBFBD>迨<EFBFBD>滢<EFBFBD>銝滚虾<EFBFBD>日<EFBFBD><EFBFBD><EFBFBD>)) {
|
||||||
batchDeleteGrades();
|
batchDeleteGrades();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -445,8 +441,7 @@
|
|||||||
const studentId = studentIdInput.value.trim();
|
const studentId = studentIdInput.value.trim();
|
||||||
const studentName = studentNameInput.value.trim();
|
const studentName = studentNameInput.value.trim();
|
||||||
|
|
||||||
// 显示加载状态
|
// <EFBFBD>曄內<EFBFBD>㰘蝸<EFBFBD>嗆<EFBFBD>? gradeTableBody.innerHTML = `
|
||||||
gradeTableBody.innerHTML = `
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="11" class="loading">
|
<td colspan="11" class="loading">
|
||||||
<i class="fas fa-spinner fa-spin"></i>
|
<i class="fas fa-spinner fa-spin"></i>
|
||||||
@@ -458,23 +453,19 @@
|
|||||||
// 模拟API延迟
|
// 模拟API延迟
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
let filteredGrades = mockGrades.filter(grade => {
|
let filteredGrades = mockGrades.filter(grade => {
|
||||||
// 班级筛选
|
// <EFBFBD>剔漣蝑偦<EFBFBD>? if (selectedClass && grade.className !== selectedClass) {
|
||||||
if (selectedClass && grade.className !== selectedClass) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 课程筛选
|
// 霂曄<EFBFBD>蝑偦<EFBFBD>? if (selectedCourse && grade.courseName !== selectedCourse) {
|
||||||
if (selectedCourse && grade.courseName !== selectedCourse) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 学号筛选
|
// 摮血噡蝑偦<EFBFBD>? if (studentId && !grade.studentId.includes(studentId)) {
|
||||||
if (studentId && !grade.studentId.includes(studentId)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 姓名筛选
|
// 憪枏<EFBFBD>蝑偦<EFBFBD>? if (studentName && !grade.studentName.includes(studentName)) {
|
||||||
if (studentName && !grade.studentName.includes(studentName)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,10 +483,10 @@
|
|||||||
function exportGrades() {
|
function exportGrades() {
|
||||||
// 这里应该调用后端API导出成绩
|
// 这里应该调用后端API导出成绩
|
||||||
// 暂时使用模拟导出
|
// 暂时使用模拟导出
|
||||||
alert('成绩导出功能正在开发中,将支持Excel和CSV格式导出。');
|
alert('<EFBFBD>鞟貍撖澆枂<EFBFBD>蠘<EFBFBD>甇<EFBFBD>銁撘<EFBFBD><EFBFBD>睲葉嚗<EFBFBD><EFBFBD><EFBFBD>舀<EFBFBD>Excel<EFBFBD>龦SV<EFBFBD>澆<EFBFBD>撖澆枂<EFBFBD>?);
|
||||||
|
|
||||||
// 模拟导出过程
|
// 模拟导出过程
|
||||||
exportBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 导出中...';
|
exportBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 撖澆枂銝?..';
|
||||||
exportBtn.disabled = true;
|
exportBtn.disabled = true;
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -504,7 +495,7 @@
|
|||||||
|
|
||||||
// 在实际应用中,这里会触发文件下载
|
// 在实际应用中,这里会触发文件下载
|
||||||
// 暂时显示成功消息
|
// 暂时显示成功消息
|
||||||
showNotification('成绩导出成功!文件已开始下载。', 'success');
|
showNotification('<EFBFBD>鞟貍撖澆枂<EFBFBD>𣂼<EFBFBD>嚗<EFBFBD><EFBFBD>隞嗅歇撘<EFBFBD>憪衤<EFBFBD>頧賬<EFBFBD>?, 'success');
|
||||||
}, 1500);
|
}, 1500);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -512,12 +503,11 @@
|
|||||||
function batchDeleteGrades() {
|
function batchDeleteGrades() {
|
||||||
// 这里应该调用后端API删除成绩
|
// 这里应该调用后端API删除成绩
|
||||||
// 暂时使用模拟删除
|
// 暂时使用模拟删除
|
||||||
batchDeleteBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 删除中...';
|
batchDeleteBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> <EFBFBD>𣳇膄銝?..';
|
||||||
batchDeleteBtn.disabled = true;
|
batchDeleteBtn.disabled = true;
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// 从模拟数据中删除选中的成绩
|
// 隞擧芋<EFBFBD><EFBFBD>㺭<EFBFBD>桐葉<EFBFBD>𣳇膄<EFBFBD>劐葉<EFBFBD><EFBFBD><EFBFBD>蝏? selectedGradeIds.forEach(id => {
|
||||||
selectedGradeIds.forEach(id => {
|
|
||||||
const index = mockGrades.findIndex(grade => grade.id === id);
|
const index = mockGrades.findIndex(grade => grade.id === id);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
mockGrades.splice(index, 1);
|
mockGrades.splice(index, 1);
|
||||||
@@ -546,7 +536,7 @@
|
|||||||
|
|
||||||
// 删除单个成绩
|
// 删除单个成绩
|
||||||
function deleteGrade(gradeId) {
|
function deleteGrade(gradeId) {
|
||||||
if (confirm('确定要删除这条成绩记录吗?此操作不可撤销。')) {
|
if (confirm('蝖桀<EFBFBD>閬<EFBFBD><EFBFBD><EFBFBD>方<EFBFBD><EFBFBD>⊥<EFBFBD>蝏抵扇敶訫<EFBFBD>嚗<EFBFBD>迨<EFBFBD>滢<EFBFBD>銝滚虾<EFBFBD>日<EFBFBD><EFBFBD>?)) {
|
||||||
// 这里应该调用后端API删除成绩
|
// 这里应该调用后端API删除成绩
|
||||||
// 暂时使用模拟删除
|
// 暂时使用模拟删除
|
||||||
const index = mockGrades.findIndex(grade => grade.id === gradeId);
|
const index = mockGrades.findIndex(grade => grade.id === gradeId);
|
||||||
@@ -581,4 +571,4 @@
|
|||||||
document.addEventListener('DOMContentLoaded', initPage);
|
document.addEventListener('DOMContentLoaded', initPage);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user