v0.1测试
This commit is contained in:
184
frontend/admin/attendance.php
Normal file
184
frontend/admin/attendance.php
Normal 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')">×</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'; ?>
|
||||
Reference in New Issue
Block a user