584 lines
23 KiB
HTML
584 lines
23 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>成绩查询/管理 - 学生成绩管理系统</title>
|
||
<link rel="stylesheet" href="../css/style.css">
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||
|
||
</head>
|
||
<body>
|
||
<!-- 导航栏 -->
|
||
<nav class="navbar">
|
||
<div class="nav-container">
|
||
<div class="nav-brand">
|
||
<a href="index.html">
|
||
<i class="fas fa-graduation-cap"></i>
|
||
<span>XX学校成绩管理系统</span>
|
||
</a>
|
||
</div>
|
||
<div class="nav-menu">
|
||
<a href="teacher_dashboard.html" class="nav-link">
|
||
<i class="fas fa-tachometer-alt"></i>
|
||
<span>教师仪表板</span>
|
||
</a>
|
||
<a href="grade_entry.html" class="nav-link">
|
||
<i class="fas fa-edit"></i>
|
||
<span>成绩录入</span>
|
||
</a>
|
||
<a href="grade_management.html" class="nav-link active">
|
||
<i class="fas fa-search"></i>
|
||
<span>成绩管理</span>
|
||
</a>
|
||
</div>
|
||
<div class="nav-user">
|
||
<div class="user-info">
|
||
<i class="fas fa-user-circle"></i>
|
||
<span>张老师</span>
|
||
</div>
|
||
<a href="login.html" class="btn-logout">
|
||
<i class="fas fa-sign-out-alt"></i>
|
||
<span>退出</span>
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
|
||
<!-- 主内容区 -->
|
||
<main class="main-content">
|
||
<div class="container">
|
||
<!-- 面包屑导航 -->
|
||
<div class="breadcrumb">
|
||
<a href="index.html">主页</a>
|
||
<i class="fas fa-chevron-right"></i>
|
||
<a href="teacher_dashboard.html">教师仪表板</a>
|
||
<i class="fas fa-chevron-right"></i>
|
||
<span>成绩查询/管理</span>
|
||
</div>
|
||
|
||
<!-- 页面标题 -->
|
||
<div class="page-header">
|
||
<h1 class="page-title">成绩查询/管理</h1>
|
||
<p class="page-description">查询、修改和删除学生成绩记录</p>
|
||
</div>
|
||
|
||
<!-- 筛选区域 -->
|
||
<div class="filter-section">
|
||
<h2 class="filter-title">
|
||
<i class="fas fa-filter"></i>
|
||
筛选条件
|
||
</h2>
|
||
<div class="filter-form">
|
||
<div class="form-group">
|
||
<label for="class-select">班级</label>
|
||
<select id="class-select" class="form-control">
|
||
<option value="">全部班级</option>
|
||
<option value="class1">计算机科学与技术1班</option>
|
||
<option value="class2">计算机科学与技术2班</option>
|
||
<option value="class3">软件工程1班</option>
|
||
<option value="class4">软件工程2班</option>
|
||
<option value="class5">网络工程1班</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="course-select">课程</label>
|
||
<select id="course-select" class="form-control">
|
||
<option value="">全部课程</option>
|
||
<option value="course1">数据结构</option>
|
||
<option value="course2">操作系统</option>
|
||
<option value="course3">计算机网络</option>
|
||
<option value="course4">数据库系统</option>
|
||
<option value="course5">软件工程</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="student-id">学生学号</label>
|
||
<input type="text" id="student-id" class="form-control" placeholder="输入学生学号">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="student-name">学生姓名</label>
|
||
<input type="text" id="student-name" class="form-control" placeholder="输入学生姓名">
|
||
</div>
|
||
<div class="filter-actions">
|
||
<button id="search-btn" class="btn-search">
|
||
<i class="fas fa-search"></i>
|
||
查询
|
||
</button>
|
||
<button id="reset-btn" class="btn-reset">
|
||
<i class="fas fa-redo"></i>
|
||
重置
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 结果区域 -->
|
||
<div class="results-section">
|
||
<div class="results-header">
|
||
<h2 class="results-title">查询结果</h2>
|
||
<div class="results-actions">
|
||
<button id="export-btn" class="btn-export">
|
||
<i class="fas fa-file-export"></i>
|
||
导出成绩
|
||
</button>
|
||
<button id="batch-delete-btn" class="btn-batch-delete">
|
||
<i class="fas fa-trash-alt"></i>
|
||
批量删除
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="table-responsive">
|
||
<table class="grade-table">
|
||
<thead>
|
||
<tr>
|
||
<th><input type="checkbox" id="select-all"></th>
|
||
<th>学号</th>
|
||
<th>姓名</th>
|
||
<th>班级</th>
|
||
<th>课程</th>
|
||
<th>平时成绩</th>
|
||
<th>期中成绩</th>
|
||
<th>期末成绩</th>
|
||
<th>总评成绩</th>
|
||
<th>等级</th>
|
||
<th>操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="grade-table-body">
|
||
<!-- 数据将通过JavaScript动态加载 -->
|
||
<tr>
|
||
<td colspan="11" class="loading">
|
||
<i class="fas fa-spinner fa-spin"></i>
|
||
<p>正在加载成绩数据...</p>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- 分页 -->
|
||
<div class="pagination">
|
||
<button id="prev-page" disabled>上一页</button>
|
||
<button class="active">1</button>
|
||
<button>2</button>
|
||
<button>3</button>
|
||
<button id="next-page">下一页</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
|
||
<!-- 页脚 -->
|
||
<footer class="footer">
|
||
<div class="container">
|
||
<p>© 2023 XX学校成绩管理系统. 版权所有.</p>
|
||
<p>技术支持: 计算机科学与技术学院</p>
|
||
</div>
|
||
</footer>
|
||
|
||
<script>
|
||
// 模拟成绩数据
|
||
const mockGrades = [
|
||
{
|
||
id: 1,
|
||
studentId: "20230001",
|
||
studentName: "张三",
|
||
className: "计算机科学与技术1班",
|
||
courseName: "数据结构",
|
||
regularScore: 85,
|
||
midtermScore: 88,
|
||
finalScore: 90,
|
||
totalScore: 88.5,
|
||
grade: "优秀"
|
||
},
|
||
{
|
||
id: 2,
|
||
studentId: "20230002",
|
||
studentName: "李四",
|
||
className: "计算机科学与技术1班",
|
||
courseName: "数据结构",
|
||
regularScore: 78,
|
||
midtermScore: 82,
|
||
finalScore: 85,
|
||
totalScore: 82.3,
|
||
grade: "良好"
|
||
},
|
||
{
|
||
id: 3,
|
||
studentId: "20230003",
|
||
studentName: "王五",
|
||
className: "计算机科学与技术2班",
|
||
courseName: "操作系统",
|
||
regularScore: 92,
|
||
midtermScore: 88,
|
||
finalScore: 95,
|
||
totalScore: 91.8,
|
||
grade: "优秀"
|
||
},
|
||
{
|
||
id: 4,
|
||
studentId: "20230004",
|
||
studentName: "赵六",
|
||
className: "计算机科学与技术2班",
|
||
courseName: "操作系统",
|
||
regularScore: 65,
|
||
midtermScore: 70,
|
||
finalScore: 68,
|
||
totalScore: 67.9,
|
||
grade: "及格"
|
||
},
|
||
{
|
||
id: 5,
|
||
studentId: "20230005",
|
||
studentName: "钱七",
|
||
className: "软件工程1班",
|
||
courseName: "数据库系统",
|
||
regularScore: 88,
|
||
midtermScore: 85,
|
||
finalScore: 90,
|
||
totalScore: 87.9,
|
||
grade: "良好"
|
||
},
|
||
{
|
||
id: 6,
|
||
studentId: "20230006",
|
||
studentName: "孙八",
|
||
className: "软件工程1班",
|
||
courseName: "数据库系统",
|
||
regularScore: 75,
|
||
midtermScore: 78,
|
||
finalScore: 80,
|
||
totalScore: 78.1,
|
||
grade: "中等"
|
||
},
|
||
{
|
||
id: 7,
|
||
studentId: "20230007",
|
||
studentName: "周九",
|
||
className: "软件工程2班",
|
||
courseName: "软件工程",
|
||
regularScore: 90,
|
||
midtermScore: 92,
|
||
finalScore: 88,
|
||
totalScore: 89.6,
|
||
grade: "优秀"
|
||
},
|
||
{
|
||
id: 8,
|
||
studentId: "20230008",
|
||
studentName: "吴十",
|
||
className: "软件工程2班",
|
||
courseName: "软件工程",
|
||
regularScore: 82,
|
||
midtermScore: 85,
|
||
finalScore: 87,
|
||
totalScore: 85.1,
|
||
grade: "良好"
|
||
}
|
||
];
|
||
|
||
// DOM元素
|
||
const searchBtn = document.getElementById('search-btn');
|
||
const resetBtn = document.getElementById('reset-btn');
|
||
const exportBtn = document.getElementById('export-btn');
|
||
const batchDeleteBtn = document.getElementById('batch-delete-btn');
|
||
const selectAllCheckbox = document.getElementById('select-all');
|
||
const gradeTableBody = document.getElementById('grade-table-body');
|
||
const classSelect = document.getElementById('class-select');
|
||
const courseSelect = document.getElementById('course-select');
|
||
const studentIdInput = document.getElementById('student-id');
|
||
const studentNameInput = document.getElementById('student-name');
|
||
|
||
// 当前选中的成绩ID
|
||
let selectedGradeIds = new Set();
|
||
|
||
// 初始化页面
|
||
function initPage() {
|
||
renderGradeTable(mockGrades);
|
||
setupEventListeners();
|
||
updateSelectedCount();
|
||
}
|
||
|
||
// 渲染成绩表格
|
||
function renderGradeTable(grades) {
|
||
if (grades.length === 0) {
|
||
gradeTableBody.innerHTML = `
|
||
<tr>
|
||
<td colspan="11" class="no-results">
|
||
<i class="fas fa-search"></i>
|
||
<h3>未找到相关成绩记录</h3>
|
||
<p>请尝试调整筛选条件或添加新的成绩记录</p>
|
||
</td>
|
||
</tr>
|
||
`;
|
||
return;
|
||
}
|
||
|
||
let tableHTML = '';
|
||
|
||
grades.forEach(grade => {
|
||
// 根据成绩确定CSS类
|
||
let gradeClass = 'grade-cell';
|
||
if (grade.totalScore >= 90) {
|
||
gradeClass += ' grade-excellent';
|
||
} else if (grade.totalScore >= 80) {
|
||
gradeClass += ' grade-good';
|
||
} else if (grade.totalScore < 60) {
|
||
gradeClass += ' grade-poor';
|
||
}
|
||
|
||
// 根据总评成绩确定等级
|
||
let gradeLevel = grade.grade;
|
||
|
||
tableHTML += `
|
||
<tr data-grade-id="${grade.id}">
|
||
<td>
|
||
<input type="checkbox" class="grade-checkbox" data-id="${grade.id}">
|
||
</td>
|
||
<td>${grade.studentId}</td>
|
||
<td>${grade.studentName}</td>
|
||
<td>${grade.className}</td>
|
||
<td>${grade.courseName}</td>
|
||
<td>${grade.regularScore}</td>
|
||
<td>${grade.midtermScore}</td>
|
||
<td>${grade.finalScore}</td>
|
||
<td class="${gradeClass}">${grade.totalScore.toFixed(1)}</td>
|
||
<td>${gradeLevel}</td>
|
||
<td>
|
||
<div class="action-buttons">
|
||
<button class="btn-edit" onclick="editGrade(${grade.id})">
|
||
<i class="fas fa-edit"></i> 修改
|
||
</button>
|
||
<button class="btn-delete" onclick="deleteGrade(${grade.id})">
|
||
<i class="fas fa-trash"></i> 删除
|
||
</button>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
`;
|
||
});
|
||
|
||
gradeTableBody.innerHTML = tableHTML;
|
||
|
||
// 重新绑定复选框事件
|
||
document.querySelectorAll('.grade-checkbox').forEach(checkbox => {
|
||
checkbox.addEventListener('change', function() {
|
||
const gradeId = parseInt(this.getAttribute('data-id'));
|
||
if (this.checked) {
|
||
selectedGradeIds.add(gradeId);
|
||
} else {
|
||
selectedGradeIds.delete(gradeId);
|
||
selectAllCheckbox.checked = false;
|
||
}
|
||
updateSelectedCount();
|
||
});
|
||
});
|
||
}
|
||
|
||
// 设置事件监听器
|
||
function setupEventListeners() {
|
||
// 查询按钮
|
||
searchBtn.addEventListener('click', function() {
|
||
performSearch();
|
||
});
|
||
|
||
// 重置按钮
|
||
resetBtn.addEventListener('click', function() {
|
||
classSelect.value = '';
|
||
courseSelect.value = '';
|
||
studentIdInput.value = '';
|
||
studentNameInput.value = '';
|
||
renderGradeTable(mockGrades);
|
||
selectedGradeIds.clear();
|
||
selectAllCheckbox.checked = false;
|
||
updateSelectedCount();
|
||
});
|
||
|
||
// 导出按钮
|
||
exportBtn.addEventListener('click', function() {
|
||
exportGrades();
|
||
});
|
||
|
||
// 批量删除按钮
|
||
batchDeleteBtn.addEventListener('click', function() {
|
||
if (selectedGradeIds.size === 0) {
|
||
alert('请先选择要删除的成绩记录!');
|
||
return;
|
||
}
|
||
|
||
if (confirm(`确定要删除选中的 ${selectedGradeIds.size} 条成绩记录吗?此操作不可撤销。`)) {
|
||
batchDeleteGrades();
|
||
}
|
||
});
|
||
|
||
// 全选复选框
|
||
selectAllCheckbox.addEventListener('change', function() {
|
||
const checkboxes = document.querySelectorAll('.grade-checkbox');
|
||
checkboxes.forEach(checkbox => {
|
||
checkbox.checked = this.checked;
|
||
const gradeId = parseInt(checkbox.getAttribute('data-id'));
|
||
if (this.checked) {
|
||
selectedGradeIds.add(gradeId);
|
||
} else {
|
||
selectedGradeIds.delete(gradeId);
|
||
}
|
||
});
|
||
updateSelectedCount();
|
||
});
|
||
|
||
// 输入框回车键搜索
|
||
[studentIdInput, studentNameInput].forEach(input => {
|
||
input.addEventListener('keypress', function(e) {
|
||
if (e.key === 'Enter') {
|
||
performSearch();
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
// 执行搜索
|
||
function performSearch() {
|
||
const selectedClass = classSelect.value;
|
||
const selectedCourse = courseSelect.value;
|
||
const studentId = studentIdInput.value.trim();
|
||
const studentName = studentNameInput.value.trim();
|
||
|
||
// 显示加载状态
|
||
gradeTableBody.innerHTML = `
|
||
<tr>
|
||
<td colspan="11" class="loading">
|
||
<i class="fas fa-spinner fa-spin"></i>
|
||
<p>正在搜索成绩数据...</p>
|
||
</td>
|
||
</tr>
|
||
`;
|
||
|
||
// 模拟API延迟
|
||
setTimeout(() => {
|
||
let filteredGrades = mockGrades.filter(grade => {
|
||
// 班级筛选
|
||
if (selectedClass && grade.className !== selectedClass) {
|
||
return false;
|
||
}
|
||
|
||
// 课程筛选
|
||
if (selectedCourse && grade.courseName !== selectedCourse) {
|
||
return false;
|
||
}
|
||
|
||
// 学号筛选
|
||
if (studentId && !grade.studentId.includes(studentId)) {
|
||
return false;
|
||
}
|
||
|
||
// 姓名筛选
|
||
if (studentName && !grade.studentName.includes(studentName)) {
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
});
|
||
|
||
renderGradeTable(filteredGrades);
|
||
selectedGradeIds.clear();
|
||
selectAllCheckbox.checked = false;
|
||
updateSelectedCount();
|
||
}, 500);
|
||
}
|
||
|
||
// 导出成绩
|
||
function exportGrades() {
|
||
// 这里应该调用后端API导出成绩
|
||
// 暂时使用模拟导出
|
||
alert('成绩导出功能正在开发中,将支持Excel和CSV格式导出。');
|
||
|
||
// 模拟导出过程
|
||
exportBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 导出中...';
|
||
exportBtn.disabled = true;
|
||
|
||
setTimeout(() => {
|
||
exportBtn.innerHTML = '<i class="fas fa-file-export"></i> 导出成绩';
|
||
exportBtn.disabled = false;
|
||
|
||
// 在实际应用中,这里会触发文件下载
|
||
// 暂时显示成功消息
|
||
showNotification('成绩导出成功!文件已开始下载。', 'success');
|
||
}, 1500);
|
||
}
|
||
|
||
// 批量删除成绩
|
||
function batchDeleteGrades() {
|
||
// 这里应该调用后端API删除成绩
|
||
// 暂时使用模拟删除
|
||
batchDeleteBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 删除中...';
|
||
batchDeleteBtn.disabled = true;
|
||
|
||
setTimeout(() => {
|
||
// 从模拟数据中删除选中的成绩
|
||
selectedGradeIds.forEach(id => {
|
||
const index = mockGrades.findIndex(grade => grade.id === id);
|
||
if (index !== -1) {
|
||
mockGrades.splice(index, 1);
|
||
}
|
||
});
|
||
|
||
// 重新渲染表格
|
||
renderGradeTable(mockGrades);
|
||
selectedGradeIds.clear();
|
||
selectAllCheckbox.checked = false;
|
||
|
||
batchDeleteBtn.innerHTML = '<i class="fas fa-trash-alt"></i> 批量删除';
|
||
batchDeleteBtn.disabled = false;
|
||
|
||
showNotification(`成功删除 ${selectedGradeIds.size} 条成绩记录!`, 'success');
|
||
updateSelectedCount();
|
||
}, 1000);
|
||
}
|
||
|
||
// 编辑成绩
|
||
function editGrade(gradeId) {
|
||
// 这里应该跳转到编辑页面或打开编辑模态框
|
||
// 暂时显示提示
|
||
alert(`编辑成绩 ID: ${gradeId}\n在实际应用中,这里会打开编辑表单。`);
|
||
}
|
||
|
||
// 删除单个成绩
|
||
function deleteGrade(gradeId) {
|
||
if (confirm('确定要删除这条成绩记录吗?此操作不可撤销。')) {
|
||
// 这里应该调用后端API删除成绩
|
||
// 暂时使用模拟删除
|
||
const index = mockGrades.findIndex(grade => grade.id === gradeId);
|
||
if (index !== -1) {
|
||
mockGrades.splice(index, 1);
|
||
renderGradeTable(mockGrades);
|
||
selectedGradeIds.delete(gradeId);
|
||
updateSelectedCount();
|
||
showNotification('成绩记录已删除!', 'success');
|
||
}
|
||
}
|
||
}
|
||
|
||
// 更新选中计数
|
||
function updateSelectedCount() {
|
||
const count = selectedGradeIds.size;
|
||
if (count > 0) {
|
||
batchDeleteBtn.innerHTML = `<i class="fas fa-trash-alt"></i> 批量删除 (${count})`;
|
||
} else {
|
||
batchDeleteBtn.innerHTML = '<i class="fas fa-trash-alt"></i> 批量删除';
|
||
}
|
||
}
|
||
|
||
// 显示通知
|
||
function showNotification(message, type = 'info') {
|
||
// 在实际应用中,这里会显示一个美观的通知组件
|
||
// 暂时使用alert
|
||
alert(message);
|
||
}
|
||
|
||
// 页面加载完成后初始化
|
||
document.addEventListener('DOMContentLoaded', initPage);
|
||
</script>
|
||
</body>
|
||
</html> |