v0.1测试

This commit is contained in:
2026-04-07 17:07:13 +08:00
parent 593973f598
commit 6b1b586fe3
80 changed files with 9073 additions and 32 deletions

243
frontend/admin/students.php Normal file
View File

@@ -0,0 +1,243 @@
<?php
/**
* 班级操行分管理系统 - 管理端学生管理
*
* 开发者: Canglan
* 联系方式: admin@sea-studio.top
* 版权归属: Sea Network Technology Studio
* 许可证: MIT License
*
* 版权所有 © Sea Network Technology Studio
*/
require_once __DIR__ . '/../config.php';
if (!isset($_SESSION['user_id']) || $_SESSION['user_type'] !== 'admin') {
header('Location: /index.php');
exit();
}
$page_title = '学生管理';
$role = $_SESSION['role'] ?? '';
include __DIR__ . '/../includes/header.php';
?>
<div class="nav">
<a href="/admin/dashboard.php" class="nav-item">首页</a>
<a href="/admin/students.php" class="nav-item active">学生管理</a>
<?php if ($role === '班主任' || $role === '班长'): ?>
<a href="/admin/conduct.php" class="nav-item">操行分管理</a>
<?php endif; ?>
<?php if ($role === '班主任' || $role === '科代表'): ?>
<a href="/admin/homework.php" class="nav-item">作业管理</a>
<?php endif; ?>
<?php if ($role === '班主任' || $role === '考勤委员'): ?>
<a href="/admin/attendance.php" class="nav-item">考勤管理</a>
<?php endif; ?>
<?php if ($role === '班主任'): ?>
<a href="/admin/subjects.php" class="nav-item">科目管理</a>
<a href="/admin/admins.php" class="nav-item">管理员管理</a>
<?php endif; ?>
<a href="/admin/history.php" class="nav-item">历史记录</a>
<a href="/admin/password.php" class="nav-item">修改密码</a>
</div>
<div class="container">
<div class="card">
<div class="action-bar">
<div class="action-buttons">
<?php if ($role === '班主任'): ?>
<button class="btn btn-primary" onclick="showImportModal()">导入学生</button>
<button class="btn btn-success" onclick="showAddStudentModal()">新增学生</button>
<?php endif; ?>
</div>
<div class="search-bar">
<input type="text" id="searchInput" placeholder="搜索姓名/学号">
<button class="btn btn-primary" onclick="loadStudents(1)">搜索</button>
</div>
</div>
<div class="table-wrapper">
<table class="table">
<thead>
<tr>
<th><input type="checkbox" id="selectAll" onclick="toggleSelectAll()"></th>
<th>学号</th>
<th>姓名</th>
<th>操行分</th>
<th>家长手机号</th>
<th>操作</th>
</tr>
</thead>
<tbody id="studentList"></tbody>
</table>
</div>
<div class="pagination" id="pagination"></div>
</div>
</div>
<!-- 导入学生模态框 -->
<div id="importModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3>导入学生</h3>
<button class="modal-close" onclick="closeModal('importModal')">&times;</button>
</div>
<div class="import-area" onclick="document.getElementById('importFile').click()">
<p>点击选择JSON文件</p>
<p class="import-label">或点击此处上传</p>
<input type="file" id="importFile" accept=".json">
<p style="margin-top: 10px; font-size: 12px; color: #999;">
<a href="/assets/uploads/sample_import.json" download style="color: #667eea;">下载示例文件</a>
</p>
</div>
<div id="importPreview" class="preview-table" style="display: none;"></div>
<div class="modal-footer">
<button class="btn btn-primary" onclick="doImport()" id="importBtn" style="display: none;">确认导入</button>
</div>
</div>
</div>
<!-- 新增学生模态框 -->
<div id="addStudentModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3>新增学生</h3>
<button class="modal-close" onclick="closeModal('addStudentModal')">&times;</button>
</div>
<form onsubmit="event.preventDefault(); submitAddStudent()">
<div class="form-group">
<label>学号 <span style="color:red;">*</span></label>
<input type="text" id="studentNo" required placeholder="4-20位字母数字组合">
<small>学号将作为学生登录账号</small>
</div>
<div class="form-group">
<label>姓名 <span style="color:red;">*</span></label>
<input type="text" id="studentName" required>
</div>
<div class="form-group">
<label>家长手机号</label>
<input type="tel" id="parentPhone" placeholder="11位手机号">
<small>填写后将自动创建家长账号密码同学生初始密码123456</small>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">确认添加</button>
<button type="button" class="btn" onclick="closeModal('addStudentModal')">取消</button>
</div>
</form>
</div>
</div>
<script>
let currentPage = 1;
let totalPages = 1;
async function loadStudents(page = 1) {
currentPage = page;
const search = document.getElementById('searchInput').value;
const res = await apiGet('/api/admin/students', { page, page_size: 20, search });
if (res && res.success) {
let html = '';
res.data.students.forEach(student => {
html += `<tr>
<td><input type="checkbox" class="student-checkbox" data-id="${student.student_id}"></td>
<td>${escapeHtml(student.student_no)}</td>
<td>${escapeHtml(student.name)}</td>
<td>${student.total_points}</td>
<td>${student.parent_phone || '-'}</td>
<td>
<button class="btn btn-sm btn-primary" onclick="showSinglePointsModal(${student.student_id}, '${escapeHtml(student.name)}')">加减分</button>
</td>
</tr>`;
});
if (res.data.students.length === 0) {
html = '<tr><td colspan="6" style="text-align:center;">暂无学生数据</td></tr>';
}
document.getElementById('studentList').innerHTML = html;
totalPages = res.data.total_pages || 1;
renderPagination();
}
}
function renderPagination() {
const container = document.getElementById('pagination');
if (!container) return;
if (totalPages <= 1) {
container.innerHTML = '';
return;
}
let html = '';
for (let i = 1; i <= totalPages; i++) {
if (i === currentPage) {
html += `<span class="active">${i}</span>`;
} else {
html += `<a href="#" onclick="loadStudents(${i}); return false;">${i}</a>`;
}
}
container.innerHTML = html;
}
function showSinglePointsModal(studentId, studentName) {
selectedStudentIds = [studentId];
document.getElementById('selectedStudentsCount').innerHTML = `${studentName} (1人)`;
document.getElementById('pointsChange').value = '';
document.getElementById('pointsReason').value = '';
document.getElementById('batchPointsModal').style.display = 'flex';
}
function toggleSelectAll() {
const selectAll = document.getElementById('selectAll');
if (selectAll) {
document.querySelectorAll('.student-checkbox').forEach(cb => {
cb.checked = selectAll.checked;
});
}
}
// 页面加载
loadStudents();
// 搜索防抖
let searchTimeout;
document.getElementById('searchInput').addEventListener('input', () => {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => loadStudents(1), 500);
});
</script>
<script src="/assets/js/admin.js"></script>
<!-- 批量加减分模态框(共用) -->
<div id="batchPointsModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3>批量加减分</h3>
<button class="modal-close" onclick="closeModal('batchPointsModal')">&times;</button>
</div>
<form onsubmit="event.preventDefault(); submitBatchPoints()">
<div class="form-group">
<label>选中学生</label>
<div id="selectedStudentsCount">0 人</div>
</div>
<div class="form-group">
<label>分数变动</label>
<input type="number" id="pointsChange" required placeholder="正数为加分,负数为扣分">
<small><?php echo $role === '班长' ? '班长单次±5分以内' : '班主任无限制'; ?></small>
</div>
<div class="form-group">
<label>原因</label>
<textarea id="pointsReason" required rows="3" placeholder="请填写加减分原因"></textarea>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">确认提交</button>
<button type="button" class="btn" onclick="closeModal('batchPointsModal')">取消</button>
</div>
</form>
</div>
</div>
<?php include __DIR__ . '/../includes/footer.php'; ?>