更新v1.4版本,修复了一些已知问题

This commit is contained in:
2026-04-28 03:16:17 +08:00
parent 76088b0dd4
commit 3aac2395a0
26 changed files with 342 additions and 151 deletions

View File

@@ -227,7 +227,6 @@ async function submitEditAdmin() {
}
const res = await apiPut(`/api/admin/update/${currentEditUserId}`, {
user_id: currentEditUserId,
real_name: document.getElementById('editAdminRealName').value,
role_type: roleType
});

View File

@@ -47,10 +47,10 @@ include __DIR__ . '/../includes/header.php';
</select>
</div>
<div class="status-group">
<button class="status-btn active" data-status="absent" onclick="selectStatus(this)" data-default-deduction="3">缺勤</button>
<button class="status-btn" data-status="late" onclick="selectStatus(this)" data-default-deduction="1">迟到</button>
<button class="status-btn" data-status="leave" onclick="selectStatus(this)" data-default-deduction="0">请假</button>
<input type="number" id="customDeduction" placeholder="自定义扣分" min="0" max="10" style="width:100px;margin-left:10px;" title="留空或0使用默认值">
<button class="status-btn active" data-status="absent" onclick="selectStatus(this)" id="btnAbsent">缺勤</button>
<button class="status-btn" data-status="late" onclick="selectStatus(this)" id="btnLate">迟到</button>
<button class="status-btn" data-status="leave" onclick="selectStatus(this)" id="btnLeave">请假</button>
<input type="number" id="customDeduction" placeholder="自定义扣分" min="0" max="20" style="width:100px;margin-left:10px;" title="留空或0使用默认值">
</div>
<input type="text" id="attendanceReason" placeholder="原因(可选)" style="flex:1;min-width:150px;">
<button class="btn btn-primary" onclick="selectAllStudents()">全选</button>
@@ -92,14 +92,35 @@ let currentStatus = 'absent';
let studentsData = [];
let existingRecords = [];
// 考勤扣分配置映射(从后端配置注入)
const attendanceDeductionMap = {
absent: window.DEDUCTION_ATTENDANCE_ABSENT || 3,
late: window.DEDUCTION_ATTENDANCE_LATE || 1,
leave: window.DEDUCTION_ATTENDANCE_LEAVE || 0
};
// 初始化按钮文字
function initAttendanceButtons() {
const btnAbsent = document.getElementById('btnAbsent');
const btnLate = document.getElementById('btnLate');
const btnLeave = document.getElementById('btnLeave');
if (btnAbsent) btnAbsent.textContent = '缺勤(' + attendanceDeductionMap.absent + '分)';
if (btnLate) btnLate.textContent = '迟到(' + attendanceDeductionMap.late + '分)';
if (btnLeave) btnLeave.textContent = '请假(' + (attendanceDeductionMap.leave > 0 ? attendanceDeductionMap.leave + '分' : '不扣分') + ')';
// 默认选中缺勤,自动填入默认扣分
if (attendanceDeductionMap.absent > 0) {
document.getElementById('customDeduction').value = attendanceDeductionMap.absent;
}
}
// 选择考勤状态
function selectStatus(btn) {
document.querySelectorAll('.status-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
currentStatus = btn.dataset.status;
// 自动设置默认扣分值
const defaultDeduction = btn.dataset.defaultDeduction;
if (defaultDeduction && defaultDeduction !== '0') {
// 自动设置默认扣分值(从配置读取)
const defaultDeduction = attendanceDeductionMap[currentStatus] || 0;
if (defaultDeduction > 0) {
document.getElementById('customDeduction').value = defaultDeduction;
} else {
document.getElementById('customDeduction').value = '';
@@ -252,6 +273,7 @@ document.getElementById('attendanceSlot').addEventListener('change', function()
});
// 页面初始化
initAttendanceButtons();
loadStudents();
loadAttendanceRecords();
</script>

View File

@@ -20,7 +20,7 @@ if (!isset($_SESSION['user_id']) || $_SESSION['user_type'] !== 'admin') {
$page_title = '操行分管理';
$role = $_SESSION['role'] ?? '';
if (!in_array($role, ['班主任', '班长', '学习委员', '劳动委员', '志愿委员'])) {
if (!in_array($role, ['班主任', '班长', '学习委员', '考勤委员', '劳动委员', '志愿委员'])) {
header('Location: /admin/dashboard.php');
exit();
}

View File

@@ -65,7 +65,7 @@ include __DIR__ . '/../includes/header.php';
<th>分数变动</th>
<th>原因</th>
<th>操作人</th>
<?php if ($role === '班主任' || $role === '班长'): ?>
<?php if ($role === '班主任' || $role === '班长' || $role === '考勤委员'): ?>
<th>操作</th>
<?php endif; ?>
</tr>
@@ -80,6 +80,7 @@ include __DIR__ . '/../includes/header.php';
<script>
var currentHistoryPage = 1;
var totalHistoryPages = 1;
var currentUserId = <?php echo intval($_SESSION['user_id']); ?>;
async function loadStudentsForSelect() {
const res = await apiGet('/api/admin/students', {page_size: 1000});
@@ -134,12 +135,20 @@ async function loadHistory(page = 1) {
} else {
html += `<td><button class="btn btn-sm btn-danger" onclick="revokeRecord(${record.record_id})">撤销</button></td>`;
}
<?php elseif ($role === '考勤委员'): ?>
if (record.is_revoked == 1) {
html += `<td><span class="text-muted">已撤销</span></td>`;
} else if (record.recorder_id == currentUserId) {
html += `<td><button class="btn btn-sm btn-danger" onclick="revokeRecord(${record.record_id})">撤销</button></td>`;
} else {
html += `<td><span class="text-muted">-</span></td>`;
}
<?php endif; ?>
html += `</tr>`;
});
if (res.data.records.length === 0) {
const colSpan = <?php echo ($role === '班主任' || $role === '班长') ? '6' : '5'; ?>;
const colSpan = <?php echo ($role === '班主任' || $role === '班长' || $role === '考勤委员') ? '6' : '5'; ?>;
html = `<tr><td colspan="${colSpan}" style="text-align:center;">暂无记录</td></tr>`;
}
@@ -151,22 +160,9 @@ async function loadHistory(page = 1) {
}
function renderHistoryPagination() {
const container = document.getElementById('historyPagination');
if (!container) return;
if (totalHistoryPages <= 1) {
container.innerHTML = '';
return;
}
let html = '';
for (let i = 1; i <= totalHistoryPages; i++) {
if (i === currentHistoryPage) {
html += `<span class="active">${i}</span>`;
} else {
html += `<a href="#" onclick="loadHistory(${i}); return false;">${i}</a>`;
}
}
container.innerHTML = html;
renderSmartPagination('historyPagination', currentHistoryPage, totalHistoryPages, function(page) {
loadHistory(page);
});
}
// 导出历史记录

View File

@@ -457,21 +457,9 @@ async function viewArchiveData(semesterId, semesterName, page) {
}
function renderArchivePagination(semesterId, semesterName) {
const container = document.getElementById('archivePagination');
if (!container) return;
if (archiveTotalPages <= 1) {
container.innerHTML = '';
return;
}
let html = '';
for (let i = 1; i <= archiveTotalPages; i++) {
if (i === archivePage) {
html += `<span class="active">${i}</span>`;
} else {
html += `<a href="#" onclick="viewArchiveData(${semesterId}, '${escapeHtml(semesterName)}', ${i}); return false;">${i}</a>`;
}
}
container.innerHTML = html;
renderSmartPagination('archivePagination', archivePage, archiveTotalPages, function(page) {
viewArchiveData(semesterId, semesterName, page);
});
}
function closeModal(modalId) {

View File

@@ -201,22 +201,9 @@ async function loadStudents(page = 1) {
}
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;
renderSmartPagination('pagination', currentPage, totalPages, function(page) {
loadStudents(page);
});
}
function showSinglePointsModal(studentId, studentName) {
@@ -263,7 +250,16 @@ document.getElementById('searchInput').addEventListener('input', () => {
<div class="form-group">
<label>分数变动</label>
<input type="number" id="pointsChange" required placeholder="正数为加分,负数为扣分">
<small><?php echo $role === '班长' ? '班长单次±5分以内' : '班主任无限制'; ?></small>
<small><?php
$hints = [
'班长' => '班长单次±5分以内',
'学习委员' => '学习委员单次±5分以内',
'考勤委员' => '考勤委员仅限扣分单次最多扣8分',
'劳动委员' => '劳动委员单次±1分以内',
'志愿委员' => '志愿委员仅限加分,最多+5分',
];
echo $hints[$role] ?? '班主任无限制';
?></small>
</div>
<div class="form-group">
<label>原因</label>