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

View File

@@ -0,0 +1,184 @@
<?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'] ?? '';
if (!in_array($role, ['班主任', '考勤委员'])) {
header('Location: /admin/dashboard.php');
exit();
}
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">学生管理</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; ?>
<a href="/admin/attendance.php" class="nav-item active">考勤管理</a>
<?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">
<button class="btn btn-primary" onclick="showAddAttendanceModal()">添加考勤</button>
<div class="search-bar">
<input type="date" id="attendanceDate" value="<?php echo date('Y-m-d'); ?>">
<button class="btn btn-primary" onclick="loadAttendanceRecords()">查询</button>
</div>
</div>
<div class="table-wrapper">
<table class="table">
<thead>
<tr><th>学号</th><th>姓名</th><th>状态</th><th>原因</th><th>记录人</th><th>扣分</th></tr>
</thead>
<tbody id="attendanceList"></tbody>
</table>
</div>
</div>
</div>
<!-- 添加考勤模态框 -->
<div id="addAttendanceModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h3>添加考勤记录</h3>
<button class="modal-close" onclick="closeModal('addAttendanceModal')">&times;</button>
</div>
<form onsubmit="event.preventDefault(); submitAddAttendance()">
<div class="form-group">
<label>学生</label>
<select id="attendanceStudentId" required></select>
</div>
<div class="form-group">
<label>日期</label>
<input type="date" id="attAttendanceDate" required>
</div>
<div class="form-group">
<label>状态</label>
<select id="attendanceStatus" required>
<option value="present">出勤</option>
<option value="absent">缺勤</option>
<option value="late">迟到</option>
<option value="leave">请假</option>
</select>
</div>
<div class="form-group">
<label>原因</label>
<input type="text" id="attendanceReason" placeholder="缺勤/迟到/请假原因">
</div>
<div class="form-group">
<label><input type="checkbox" id="attendanceDeduct"> 同时扣分</label>
<small>扣分规则:缺勤-5分迟到-2分请假-1分</small>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">提交</button>
<button type="button" class="btn" onclick="closeModal('addAttendanceModal')">取消</button>
</div>
</form>
</div>
</div>
<script>
async function loadAttendanceRecords() {
const date = document.getElementById('attendanceDate').value;
const res = await apiGet('/api/admin/attendance/records', { date });
if (res && res.success) {
let html = '';
res.data.records.forEach(record => {
html += `<tr>
<td>${escapeHtml(record.student_no)}</td>
<td>${escapeHtml(record.student_name)}</td>
<td>${getStatusBadge(record.status, 'attendance')}</td>
<td>${escapeHtml(record.reason || '-')}</td>
<td>${escapeHtml(record.recorder_name || '-')}</td>
<td>${record.deduction_applied ? '已扣分' : '-'}</td>
</tr>`;
});
if (res.data.records.length === 0) {
html = '<tr><td colspan="6" style="text-align:center;">暂无考勤记录</td></tr>';
}
document.getElementById('attendanceList').innerHTML = html;
}
}
async function loadStudentsForSelect() {
const res = await apiGet('/api/admin/students');
if (res && res.success) {
let html = '<option value="">请选择学生</option>';
res.data.students.forEach(s => {
html += `<option value="${s.student_id}">${escapeHtml(s.student_no)} - ${escapeHtml(s.name)}</option>`;
});
document.getElementById('attendanceStudentId').innerHTML = html;
}
}
async function showAddAttendanceModal() {
await loadStudentsForSelect();
document.getElementById('addAttendanceModal').style.display = 'flex';
document.getElementById('attAttendanceDate').value = new Date().toISOString().split('T')[0];
}
async function submitAddAttendance() {
const studentId = document.getElementById('attendanceStudentId').value;
const date = document.getElementById('attAttendanceDate').value;
const status = document.getElementById('attendanceStatus').value;
const reason = document.getElementById('attendanceReason').value;
const applyDeduction = document.getElementById('attendanceDeduct').checked;
if (!studentId || !date || !status) {
showToast('请填写完整信息', 'warning');
return;
}
const res = await apiPost('/api/admin/attendance', {
student_id: parseInt(studentId),
date: date,
status: status,
reason: reason,
apply_deduction: applyDeduction
});
if (res && res.success) {
showToast('考勤记录添加成功');
closeModal('addAttendanceModal');
loadAttendanceRecords();
} else {
showToast(res?.message || '添加失败', 'error');
}
}
loadAttendanceRecords();
</script>
<script src="/assets/js/admin.js"></script>
<?php include __DIR__ . '/../includes/footer.php'; ?>