242 lines
6.1 KiB
JavaScript
242 lines
6.1 KiB
JavaScript
/**
|
||
* 班级操行分管理系统 - 公共JS
|
||
*
|
||
* 开发者: Canglan
|
||
* 联系方式: admin@sea-studio.top
|
||
* 版权归属: Sea Network Technology Studio
|
||
* 许可证: MIT License
|
||
*
|
||
* 版权所有 © Sea Network Technology Studio
|
||
*/
|
||
|
||
// API基础地址
|
||
const API_BASE_URL = window.API_BASE_URL || 'http://localhost:8000';
|
||
const JWT_STORAGE_KEY = 'class_system_token';
|
||
const USER_STORAGE_KEY = 'class_system_user';
|
||
|
||
// 获取Token
|
||
function getToken() {
|
||
return localStorage.getItem(JWT_STORAGE_KEY);
|
||
}
|
||
|
||
// 获取用户信息
|
||
function getUserInfo() {
|
||
const userStr = localStorage.getItem(USER_STORAGE_KEY);
|
||
if (!userStr) return null;
|
||
try {
|
||
return JSON.parse(userStr);
|
||
} catch {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// 保存用户信息
|
||
function setUserInfo(user) {
|
||
localStorage.setItem(USER_STORAGE_KEY, JSON.stringify(user));
|
||
}
|
||
|
||
// 清除登录信息
|
||
function clearAuth() {
|
||
localStorage.removeItem(JWT_STORAGE_KEY);
|
||
localStorage.removeItem(USER_STORAGE_KEY);
|
||
}
|
||
|
||
// 检查登录状态
|
||
function checkAuth() {
|
||
const token = getToken();
|
||
if (!token) {
|
||
window.location.href = '/index.php';
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
// API请求封装
|
||
async function apiRequest(url, options = {}) {
|
||
const token = getToken();
|
||
|
||
const headers = {
|
||
'Content-Type': 'application/json',
|
||
...options.headers
|
||
};
|
||
|
||
if (token) {
|
||
headers['Authorization'] = `Bearer ${token}`;
|
||
}
|
||
|
||
const config = {
|
||
...options,
|
||
headers
|
||
};
|
||
|
||
try {
|
||
const response = await fetch(`${API_BASE_URL}${url}`, config);
|
||
const data = await response.json();
|
||
|
||
if (response.status === 401) {
|
||
clearAuth();
|
||
window.location.href = '/index.php';
|
||
return null;
|
||
}
|
||
|
||
return data;
|
||
} catch (error) {
|
||
console.error('API请求错误:', error);
|
||
showToast('网络错误,请稍后重试', 'error');
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// GET请求
|
||
async function apiGet(url, params = {}) {
|
||
const queryString = new URLSearchParams(params).toString();
|
||
const fullUrl = queryString ? `${url}?${queryString}` : url;
|
||
return apiRequest(fullUrl, { method: 'GET' });
|
||
}
|
||
|
||
// POST请求
|
||
async function apiPost(url, data = {}) {
|
||
return apiRequest(url, {
|
||
method: 'POST',
|
||
body: JSON.stringify(data)
|
||
});
|
||
}
|
||
|
||
// PUT请求
|
||
async function apiPut(url, data = {}) {
|
||
return apiRequest(url, {
|
||
method: 'PUT',
|
||
body: JSON.stringify(data)
|
||
});
|
||
}
|
||
|
||
// DELETE请求
|
||
async function apiDelete(url) {
|
||
return apiRequest(url, { method: 'DELETE' });
|
||
}
|
||
|
||
// 显示提示消息
|
||
function showToast(message, type = 'success') {
|
||
const toast = document.createElement('div');
|
||
toast.className = `toast toast-${type}`;
|
||
toast.textContent = message;
|
||
document.body.appendChild(toast);
|
||
|
||
setTimeout(() => {
|
||
toast.remove();
|
||
}, 3000);
|
||
}
|
||
|
||
// 格式化日期
|
||
function formatDate(dateStr) {
|
||
if (!dateStr) return '-';
|
||
const date = new Date(dateStr);
|
||
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
|
||
}
|
||
|
||
// 格式化日期时间
|
||
function formatDateTime(dateStr) {
|
||
if (!dateStr) return '-';
|
||
const date = new Date(dateStr);
|
||
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;
|
||
}
|
||
|
||
// 获取状态标签HTML
|
||
function getStatusBadge(status, type = 'homework') {
|
||
const statusMap = {
|
||
homework: {
|
||
'submitted': '已提交',
|
||
'not_submitted': '未提交',
|
||
'late': '迟交'
|
||
},
|
||
attendance: {
|
||
'present': '出勤',
|
||
'absent': '缺勤',
|
||
'late': '迟到',
|
||
'leave': '请假'
|
||
}
|
||
};
|
||
|
||
const texts = statusMap[type] || statusMap.homework;
|
||
const text = texts[status] || status;
|
||
|
||
let className = 'status-badge ';
|
||
switch (status) {
|
||
case 'submitted':
|
||
case 'present':
|
||
className += 'status-submitted';
|
||
break;
|
||
case 'not_submitted':
|
||
case 'absent':
|
||
className += 'status-not_submitted';
|
||
break;
|
||
case 'late':
|
||
className += 'status-late';
|
||
break;
|
||
case 'leave':
|
||
className += 'status-leave';
|
||
break;
|
||
default:
|
||
className += 'status-not_submitted';
|
||
}
|
||
|
||
return `<span class="${className}">${text}</span>`;
|
||
}
|
||
|
||
// 退出登录
|
||
async function logout() {
|
||
await apiPost('/api/auth/logout');
|
||
clearAuth();
|
||
window.location.href = '/index.php';
|
||
}
|
||
|
||
// 加载用户信息
|
||
function loadUserInfo() {
|
||
const user = getUserInfo();
|
||
const userNameSpan = document.getElementById('userName');
|
||
if (userNameSpan && user) {
|
||
userNameSpan.textContent = user.real_name || user.username;
|
||
}
|
||
}
|
||
|
||
// 检查是否需要修改密码
|
||
function checkNeedChangePassword() {
|
||
const user = getUserInfo();
|
||
if (user && user.need_change_password) {
|
||
const newPassword = prompt('首次登录,请设置新密码(6-20位,需包含字母和数字):');
|
||
if (newPassword) {
|
||
changePassword(newPassword);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 修改密码
|
||
async function changePassword(newPassword) {
|
||
const res = await apiPost('/api/auth/change-password', {
|
||
old_password: newPassword,
|
||
new_password: newPassword
|
||
});
|
||
|
||
if (res && res.success) {
|
||
showToast('密码修改成功,请重新登录');
|
||
setTimeout(() => logout(), 1500);
|
||
} else {
|
||
showToast(res?.message || '密码修改失败', 'error');
|
||
checkNeedChangePassword();
|
||
}
|
||
}
|
||
|
||
// 页面加载时初始化
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
loadUserInfo();
|
||
|
||
const logoutBtn = document.getElementById('logoutBtn');
|
||
if (logoutBtn) {
|
||
logoutBtn.addEventListener('click', logout);
|
||
}
|
||
|
||
// 学生端检查强制修改密码
|
||
if (window.location.pathname.includes('/student/')) {
|
||
checkNeedChangePassword();
|
||
}
|
||
}); |