v1.7版本更新

This commit is contained in:
2026-05-21 20:15:56 +08:00
parent 74a71ddaf5
commit cb0c367eb7
54 changed files with 2292 additions and 1785 deletions

View File

@@ -0,0 +1,53 @@
/**
* 班级操行分管理系统 - 管理员管理函数
*
* 开发者: Canglan
* 联系方式: admin@sea-studio.top
* 版权归属: Sea Network Technology Studio
* 许可证: MIT License
*
* 版权所有 © Sea Network Technology Studio
*/
(function() {
'use strict';
// 显示添加管理员模态框
function showAddAdminModal() {
document.getElementById('addAdminModal').style.display = 'flex';
document.getElementById('addAdminForm')?.reset();
}
// 提交添加管理员
async function submitAddAdmin() {
const username = document.getElementById('adminUsername').value.trim();
const realName = document.getElementById('adminRealName').value.trim();
const password = document.getElementById('adminPassword').value;
const roleType = document.getElementById('adminRole').value;
if (!username || !realName || !roleType) {
showToast('请填写完整信息', 'warning');
return;
}
const res = await apiPost('/api/admin/add', {
username: username,
real_name: realName,
password: password || undefined,
role_type: roleType
});
if (res && res.success) {
let msg = `管理员 ${res.data.username} 添加成功`;
if (res.data.password) msg += `,密码: ${res.data.password}`;
showToast(msg);
closeModal('addAdminModal');
loadAdmins();
} else {
showToast(res?.message || '添加失败', 'error');
}
}
window.showAddAdminModal = showAddAdminModal;
window.submitAddAdmin = submitAddAdmin;
})();

View File

@@ -0,0 +1,24 @@
/**
* 班级操行分管理系统 - 模态框工具函数
*
* 开发者: Canglan
* 联系方式: admin@sea-studio.top
* 版权归属: Sea Network Technology Studio
* 许可证: MIT License
*
* 版权所有 © Sea Network Technology Studio
*/
(function() {
'use strict';
// 关闭模态框
function closeModal(modalId) {
const modal = document.getElementById(modalId);
if (modal) {
modal.style.display = 'none';
}
}
window.closeModal = closeModal;
})();

View File

@@ -0,0 +1,98 @@
/**
* 班级操行分管理系统 - 加减分管理函数
*
* 开发者: Canglan
* 联系方式: admin@sea-studio.top
* 版权归属: Sea Network Technology Studio
* 许可证: MIT License
*
* 版权所有 © Sea Network Technology Studio
*/
(function() {
'use strict';
// 全局变量
var selectedStudentIds = [];
var currentHistoryPage = 1;
// 显示批量加减分模态框
function showBatchPointsModal() {
selectedStudentIds = [];
document.querySelectorAll('.student-checkbox:checked').forEach(cb => {
selectedStudentIds.push(parseInt(cb.dataset.id));
});
if (selectedStudentIds.length === 0) {
showToast('请先选择学生', 'warning');
return;
}
document.getElementById('selectedStudentsCount').innerHTML = `${selectedStudentIds.length}`;
document.getElementById('pointsChange').value = '';
document.getElementById('pointsReason').value = '';
document.getElementById('batchPointsModal').style.display = 'flex';
}
// 提交批量加减分
async function submitBatchPoints() {
const pointsChange = parseInt(document.getElementById('pointsChange').value);
const reason = document.getElementById('pointsReason').value;
if (isNaN(pointsChange) || pointsChange === 0) {
showToast('分值不能为0', 'error');
return;
}
if (!reason.trim()) {
showToast('请填写原因', 'error');
return;
}
const res = await apiPost('/api/admin/conduct/add', {
student_ids: selectedStudentIds,
points_change: pointsChange,
reason: reason
});
if (res && res.success) {
showToast(`操作成功: ${res.data.success_count} 人成功`);
closeModal('batchPointsModal');
loadStudents();
if (typeof loadConductStudents === 'function') loadConductStudents();
} else {
showToast(res?.message || '操作失败', 'error');
}
}
// 撤销扣分记录
async function revokeRecord(recordId) {
if (!confirm('确定要撤销这条记录吗?撤销后学生分数将恢复。')) return;
const res = await apiPost('/api/admin/conduct/revoke', { record_id: recordId });
if (res && res.success) {
showToast('撤销成功');
loadHistory(currentHistoryPage);
} else {
showToast(res?.message || '撤销失败', 'error');
}
}
// 反撤销(恢复)记录
async function restoreRecord(recordId) {
if (!confirm('确定要反撤销这条记录吗?分数变动将重新生效。')) return;
const res = await apiPost('/api/admin/conduct/restore', { record_id: recordId });
if (res && res.success) {
showToast('反撤销成功');
loadHistory(currentHistoryPage);
} else {
showToast(res?.message || '反撤销失败', 'error');
}
}
window.showBatchPointsModal = showBatchPointsModal;
window.submitBatchPoints = submitBatchPoints;
window.revokeRecord = revokeRecord;
window.restoreRecord = restoreRecord;
})();

View File

@@ -0,0 +1,233 @@
/**
* 班级操行分管理系统 - 学生管理函数
*
* 开发者: Canglan
* 联系方式: admin@sea-studio.top
* 版权归属: Sea Network Technology Studio
* 许可证: MIT License
*
* 版权所有 © Sea Network Technology Studio
*/
(function() {
'use strict';
// 显示新增学生模态框
function showAddStudentModal() {
document.getElementById('addStudentModal').style.display = 'flex';
document.getElementById('addStudentForm').reset();
}
// 提交新增学生
async function submitAddStudent() {
const studentNo = document.getElementById('studentNo').value.trim();
const name = document.getElementById('studentName').value.trim();
const parentPhone = document.getElementById('parentPhone').value.trim();
if (!studentNo || !name) {
showToast('请填写学号和姓名', 'warning');
return;
}
const res = await apiPost('/api/admin/students', {
student_no: studentNo,
name: name,
parent_phone: parentPhone,
dormitory_number: document.getElementById('addDormitoryNumber').value.trim()
});
if (res && res.success) {
showToast('学生添加成功');
closeModal('addStudentModal');
loadStudents();
} else {
showToast(res?.message || '添加失败', 'error');
}
}
// 显示编辑学生模态框
function showEditStudentModal(studentId, studentNo, name, phone, dormitoryNumber) {
document.getElementById('editStudentId').value = studentId;
document.getElementById('editStudentNo').value = studentNo;
document.getElementById('editStudentName').value = name;
document.getElementById('editStudentPhone').value = phone || '';
document.getElementById('editDormitoryNumber').value = dormitoryNumber || '';
document.getElementById('editStudentModal').style.display = 'flex';
}
// 提交编辑学生
async function submitEditStudent() {
const studentId = document.getElementById('editStudentId').value;
const name = document.getElementById('editStudentName').value.trim();
const phone = document.getElementById('editStudentPhone').value.trim();
if (!name) {
showToast('请输入姓名', 'warning');
return;
}
const res = await apiPut(`/api/admin/students/${studentId}`, {
name: name,
parent_phone: phone || null,
dormitory_number: document.getElementById('editDormitoryNumber').value.trim()
});
if (res && res.success) {
showToast('学生信息更新成功');
closeModal('editStudentModal');
location.reload();
} else {
showToast(res?.message || '更新失败', 'error');
}
}
// 显示重置学生密码模态框
function showResetStudentPasswordModal(studentId, name) {
document.getElementById('resetStudentId').value = studentId;
document.getElementById('resetStudentInfo').textContent = `正在重置学生 "${name}" 的密码`;
document.getElementById('newStudentPassword').value = '';
document.getElementById('resetStudentPasswordModal').style.display = 'flex';
}
// 提交重置学生密码
async function submitResetStudentPassword() {
const studentId = document.getElementById('resetStudentId').value;
const newPassword = document.getElementById('newStudentPassword').value;
if (!newPassword || newPassword.length < 6) {
showToast('密码至少6位', 'warning');
return;
}
const res = await apiPost(`/api/admin/students/reset-password/${studentId}`, {
new_password: newPassword
});
if (res && res.success) {
showToast('密码重置成功');
closeModal('resetStudentPasswordModal');
} else {
showToast(res?.message || '重置失败', 'error');
}
}
// 删除学生
async function deleteStudent(studentId, name) {
if (!confirm(`确定要删除学生 "${name}" 吗?删除后学生账号将被禁用。`)) return;
const res = await apiDelete(`/api/admin/students/${studentId}`);
if (res && res.success) {
showToast('学生删除成功');
location.reload();
} else {
showToast(res?.message || '删除失败', 'error');
}
}
// 显示导入模态框
function showImportModal() {
document.getElementById('importModal').style.display = 'flex';
document.getElementById('importPreview').style.display = 'none';
document.getElementById('importPreview').innerHTML = '';
document.getElementById('importBtn').style.display = 'none';
document.getElementById('importFile').value = '';
}
// 预览导入文件
function previewImportFile() {
const file = document.getElementById('importFile').files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function(e) {
try {
const data = JSON.parse(e.target.result);
const students = data.students || [];
let html = '<h4>预览数据</h4><div class="table-wrapper"><table><thead><tr>';
html += '<th>学号</th><th>姓名</th><th>家长手机号</th><th>初始密码</th>';
html += '</tr></thead><tbody>';
students.forEach(s => {
html += `<tr>
<td>${escapeHtml(s.student_no || '')}</td>
<td>${escapeHtml(s.name || '')}</td>
<td>${escapeHtml(s.parent_phone || '')}</td>
<td>${escapeHtml(s.password || '123456')}</td>
</tr>`;
});
html += `</tbody></table></div><p>共 ${students.length} 条记录初始操行分默认为60分</p>`;
document.getElementById('importPreview').innerHTML = html;
document.getElementById('importPreview').style.display = 'block';
document.getElementById('importBtn').style.display = 'inline-block';
} catch (error) {
showToast('JSON格式错误', 'error');
}
};
reader.readAsText(file);
}
// 执行导入
async function doImport() {
const file = document.getElementById('importFile').files[0];
if (!file) {
showToast('请选择文件', 'warning');
return;
}
const formData = new FormData();
formData.append('file', file);
const token = getToken();
const response = await fetch(`${API_BASE_URL}/api/admin/students/import`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`
},
body: formData
});
const result = await response.json();
if (result.success) {
showToast(result.message);
closeModal('importModal');
loadStudents();
// 显示详细导入结果
if (result.data && result.data.results) {
const failedList = result.data.results.filter(r => !r.success);
if (failedList.length > 0) {
let detail = '失败详情:\n';
failedList.forEach(r => {
detail += `${r.student_no || '未知'}: ${r.error}\n`;
});
alert(detail);
}
}
} else {
showToast(result.message, 'error');
}
}
// 绑定文件选择事件
document.addEventListener('DOMContentLoaded', () => {
const fileInput = document.getElementById('importFile');
if (fileInput) {
fileInput.addEventListener('change', previewImportFile);
}
});
window.showAddStudentModal = showAddStudentModal;
window.submitAddStudent = submitAddStudent;
window.showEditStudentModal = showEditStudentModal;
window.submitEditStudent = submitEditStudent;
window.showResetStudentPasswordModal = showResetStudentPasswordModal;
window.submitResetStudentPassword = submitResetStudentPassword;
window.deleteStudent = deleteStudent;
window.showImportModal = showImportModal;
window.previewImportFile = previewImportFile;
window.doImport = doImport;
})();

View File

@@ -0,0 +1,47 @@
/**
* 班级操行分管理系统 - 科目管理函数
*
* 开发者: Canglan
* 联系方式: admin@sea-studio.top
* 版权归属: Sea Network Technology Studio
* 许可证: MIT License
*
* 版权所有 © Sea Network Technology Studio
*/
(function() {
'use strict';
// 显示添加科目模态框
function showAddSubjectModal() {
document.getElementById('addSubjectModal').style.display = 'flex';
document.getElementById('addSubjectForm').reset();
}
// 提交添加科目
async function submitAddSubject() {
const subjectName = document.getElementById('subjectName').value.trim();
const subjectCode = document.getElementById('subjectCode').value.trim();
if (!subjectName) {
showToast('请填写科目名称', 'warning');
return;
}
const res = await apiPost('/api/subject/create', {
subject_name: subjectName,
subject_code: subjectCode
});
if (res && res.success) {
showToast('科目添加成功');
closeModal('addSubjectModal');
loadSubjects();
} else {
showToast(res?.message || '添加失败', 'error');
}
}
window.showAddSubjectModal = showAddSubjectModal;
window.submitAddSubject = submitAddSubject;
})();

View File

@@ -0,0 +1,38 @@
/**
* 班级操行分管理系统 - 通用工具函数
*
* 开发者: Canglan
* 联系方式: admin@sea-studio.top
* 版权归属: Sea Network Technology Studio
* 许可证: MIT License
*
* 版权所有 © Sea Network Technology Studio
*/
(function() {
'use strict';
// HTML转义
function escapeHtml(str) {
if (!str) return '';
return str.replace(/[&<>]/g, function(m) {
if (m === '&') return '&';
if (m === '<') return '<';
if (m === '>') return '>';
return m;
});
}
// 全选功能
function toggleSelectAll() {
const selectAll = document.getElementById('selectAll');
if (selectAll) {
document.querySelectorAll('.student-checkbox').forEach(cb => {
cb.checked = selectAll.checked;
});
}
}
window.escapeHtml = escapeHtml;
window.toggleSelectAll = toggleSelectAll;
})();