371 lines
12 KiB
JavaScript
371 lines
12 KiB
JavaScript
// 用户管理页面JavaScript
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
// 初始化
|
||
initializeUserManagement();
|
||
});
|
||
|
||
// 初始化用户管理功能
|
||
function initializeUserManagement() {
|
||
// 添加事件监听器
|
||
setupEventListeners();
|
||
|
||
// 初始化头像显示
|
||
initializeAvatars();
|
||
|
||
// 强制设置头像样式
|
||
forceAvatarStyles();
|
||
}
|
||
|
||
// 设置事件监听器
|
||
function setupEventListeners() {
|
||
// 搜索表单提交
|
||
const searchForm = document.querySelector('form[method="GET"]');
|
||
if (searchForm) {
|
||
searchForm.addEventListener('submit', function(e) {
|
||
// 可以在这里添加搜索前的验证
|
||
});
|
||
}
|
||
|
||
// 状态筛选变更
|
||
const statusSelect = document.getElementById('status');
|
||
if (statusSelect) {
|
||
statusSelect.addEventListener('change', function() {
|
||
// 自动提交表单
|
||
this.form.submit();
|
||
});
|
||
}
|
||
}
|
||
|
||
// 初始化头像显示
|
||
function initializeAvatars() {
|
||
const avatars = document.querySelectorAll('.user-avatar');
|
||
avatars.forEach(avatar => {
|
||
avatar.onerror = function() {
|
||
// 如果头像加载失败,替换为默认头像
|
||
this.style.display = 'none';
|
||
const placeholder = this.parentElement.querySelector('.user-avatar-placeholder');
|
||
if (placeholder) {
|
||
placeholder.style.display = 'flex';
|
||
}
|
||
};
|
||
});
|
||
}
|
||
|
||
// 强制设置头像样式,覆盖Bootstrap
|
||
function forceAvatarStyles() {
|
||
// 设置表格中的头像样式
|
||
const tableAvatars = document.querySelectorAll('.table .user-avatar');
|
||
tableAvatars.forEach(avatar => {
|
||
setAvatarStyles(avatar, '48px');
|
||
});
|
||
}
|
||
|
||
// 设置单个头像样式
|
||
function setAvatarStyles(avatar, size) {
|
||
if (!avatar) return;
|
||
|
||
// 强制设置所有相关样式
|
||
avatar.style.setProperty('width', size, 'important');
|
||
avatar.style.setProperty('height', size, 'important');
|
||
avatar.style.setProperty('max-width', size, 'important');
|
||
avatar.style.setProperty('max-height', size, 'important');
|
||
avatar.style.setProperty('min-width', size, 'important');
|
||
avatar.style.setProperty('min-height', size, 'important');
|
||
avatar.style.setProperty('border-radius', '50%', 'important');
|
||
avatar.style.setProperty('object-fit', 'cover', 'important');
|
||
avatar.style.setProperty('border', '2px solid #f8f9fa', 'important');
|
||
avatar.style.setProperty('display', 'block', 'important');
|
||
avatar.style.setProperty('flex-shrink', '0', 'important');
|
||
avatar.style.setProperty('flex-grow', '0', 'important');
|
||
|
||
// 移除可能影响的Bootstrap类
|
||
avatar.classList.remove('img-fluid', 'img-responsive', 'img-thumbnail');
|
||
|
||
// 设置父元素样式
|
||
if (avatar.parentElement) {
|
||
avatar.parentElement.style.setProperty('width', size, 'important');
|
||
avatar.parentElement.style.setProperty('height', size, 'important');
|
||
avatar.parentElement.style.setProperty('overflow', 'hidden', 'important');
|
||
avatar.parentElement.style.setProperty('flex-shrink', '0', 'important');
|
||
avatar.parentElement.style.setProperty('flex-grow', '0', 'important');
|
||
}
|
||
}
|
||
|
||
// 查看用户详情
|
||
function viewUser(userId) {
|
||
// 显示模态框
|
||
const modal = new bootstrap.Modal(document.getElementById('userDetailModal'));
|
||
const content = document.getElementById('userDetailContent');
|
||
|
||
// 显示加载状态
|
||
content.innerHTML = `
|
||
<div class="loading">
|
||
<i class="bi bi-hourglass-split"></i>
|
||
<div>加载中...</div>
|
||
</div>
|
||
`;
|
||
|
||
modal.show();
|
||
|
||
// 发送AJAX请求获取用户详情
|
||
fetch(`/admin/users/${userId}/detail`)
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
if (data.success) {
|
||
renderUserDetail(data.user);
|
||
// 立即强制设置头像样式
|
||
setTimeout(() => {
|
||
forceModalAvatarStyles();
|
||
}, 50);
|
||
// 再次确保样式正确应用
|
||
setTimeout(() => {
|
||
forceModalAvatarStyles();
|
||
}, 200);
|
||
} else {
|
||
showError('获取用户详情失败: ' + data.message);
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('Error:', error);
|
||
showError('网络错误,请重试');
|
||
});
|
||
}
|
||
|
||
// 渲染用户详情
|
||
function renderUserDetail(user) {
|
||
const content = document.getElementById('userDetailContent');
|
||
|
||
content.innerHTML = `
|
||
<div class="user-detail">
|
||
<div class="row">
|
||
<div class="col-md-3 text-center">
|
||
<div class="user-avatar-large-wrapper">
|
||
${user.avatar_url ?
|
||
`<img src="${user.avatar_url}" alt="用户头像" class="avatar-large" id="modalAvatar">` :
|
||
`<div class="avatar-placeholder-large"><i class="bi bi-person"></i></div>`
|
||
}
|
||
</div>
|
||
<h5 class="mt-3">${user.nickname || user.username}</h5>
|
||
<span class="badge bg-${user.status === 1 ? 'success' : 'danger'}">
|
||
${user.status === 1 ? '正常' : '禁用'}
|
||
</span>
|
||
</div>
|
||
<div class="col-md-9">
|
||
<div class="user-info-list">
|
||
<div class="user-info-item">
|
||
<span class="user-info-label">用户ID:</span>
|
||
<span class="user-info-value">#${user.id}</span>
|
||
</div>
|
||
<div class="user-info-item">
|
||
<span class="user-info-label">用户名:</span>
|
||
<span class="user-info-value">${user.username}</span>
|
||
</div>
|
||
<div class="user-info-item">
|
||
<span class="user-info-label">昵称:</span>
|
||
<span class="user-info-value">${user.nickname || '未设置'}</span>
|
||
</div>
|
||
<div class="user-info-item">
|
||
<span class="user-info-label">邮箱:</span>
|
||
<span class="user-info-value">${user.email || '未设置'}</span>
|
||
</div>
|
||
<div class="user-info-item">
|
||
<span class="user-info-label">手机号:</span>
|
||
<span class="user-info-value">${user.phone || '未设置'}</span>
|
||
</div>
|
||
<div class="user-info-item">
|
||
<span class="user-info-label">性别:</span>
|
||
<span class="user-info-value">${getGenderText(user.gender)}</span>
|
||
</div>
|
||
<div class="user-info-item">
|
||
<span class="user-info-label">生日:</span>
|
||
<span class="user-info-value">${user.birthday || '未设置'}</span>
|
||
</div>
|
||
<div class="user-info-item">
|
||
<span class="user-info-label">注册时间:</span>
|
||
<span class="user-info-value">${formatDateTime(user.created_at)}</span>
|
||
</div>
|
||
<div class="user-info-item">
|
||
<span class="user-info-label">最后更新:</span>
|
||
<span class="user-info-value">${formatDateTime(user.updated_at)}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
// 强制设置模态框中的头像样式
|
||
function forceModalAvatarStyles() {
|
||
const modalAvatar = document.getElementById('modalAvatar');
|
||
if (modalAvatar) {
|
||
setAvatarStyles(modalAvatar, '80px');
|
||
|
||
// 设置容器样式
|
||
const wrapper = document.querySelector('.user-avatar-large-wrapper');
|
||
if (wrapper) {
|
||
wrapper.style.setProperty('width', '80px', 'important');
|
||
wrapper.style.setProperty('height', '80px', 'important');
|
||
wrapper.style.setProperty('margin', '0 auto', 'important');
|
||
wrapper.style.setProperty('overflow', 'hidden', 'important');
|
||
wrapper.style.setProperty('border-radius', '50%', 'important');
|
||
wrapper.style.setProperty('position', 'relative', 'important');
|
||
wrapper.style.setProperty('flex-shrink', '0', 'important');
|
||
wrapper.style.setProperty('flex-grow', '0', 'important');
|
||
}
|
||
}
|
||
|
||
// 通用的模态框头像处理
|
||
const modalAvatars = document.querySelectorAll('.modal .avatar-large');
|
||
modalAvatars.forEach(avatar => {
|
||
setAvatarStyles(avatar, '80px');
|
||
});
|
||
}
|
||
|
||
// 切换用户状态
|
||
function toggleUserStatus(userId, currentStatus) {
|
||
const action = currentStatus === 1 ? '禁用' : '启用';
|
||
const newStatus = currentStatus === 1 ? 0 : 1;
|
||
|
||
if (!confirm(`确定要${action}此用户吗?`)) {
|
||
return;
|
||
}
|
||
|
||
// 显示加载状态
|
||
showLoading();
|
||
|
||
// 发送AJAX请求
|
||
fetch(`/admin/users/${userId}/toggle-status`, {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({
|
||
status: newStatus
|
||
})
|
||
})
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
hideLoading();
|
||
if (data.success) {
|
||
showSuccess(data.message);
|
||
// 刷新页面
|
||
setTimeout(() => {
|
||
location.reload();
|
||
}, 1000);
|
||
} else {
|
||
showError(data.message);
|
||
}
|
||
})
|
||
.catch(error => {
|
||
hideLoading();
|
||
console.error('Error:', error);
|
||
showError('网络错误,请重试');
|
||
});
|
||
}
|
||
|
||
// 获取性别文本
|
||
function getGenderText(gender) {
|
||
switch (gender) {
|
||
case 1: return '男';
|
||
case 2: return '女';
|
||
default: return '未知';
|
||
}
|
||
}
|
||
|
||
// 格式化日期时间
|
||
function formatDateTime(dateTimeString) {
|
||
if (!dateTimeString) return '未知';
|
||
|
||
const date = new Date(dateTimeString);
|
||
return date.toLocaleString('zh-CN');
|
||
}
|
||
|
||
// 显示成功消息
|
||
function showSuccess(message) {
|
||
showAlert(message, 'success');
|
||
}
|
||
|
||
// 显示错误消息
|
||
function showError(message) {
|
||
showAlert(message, 'danger');
|
||
}
|
||
|
||
// 显示提示消息
|
||
function showAlert(message, type) {
|
||
const alertDiv = document.createElement('div');
|
||
alertDiv.className = `alert alert-${type} alert-dismissible fade show`;
|
||
alertDiv.innerHTML = `
|
||
${message}
|
||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||
`;
|
||
|
||
// 插入到页面顶部
|
||
const container = document.querySelector('.admin-content');
|
||
container.insertBefore(alertDiv, container.firstChild);
|
||
|
||
// 3秒后自动关闭
|
||
setTimeout(() => {
|
||
alertDiv.remove();
|
||
}, 3000);
|
||
}
|
||
|
||
// 显示加载状态
|
||
function showLoading() {
|
||
const loadingDiv = document.createElement('div');
|
||
loadingDiv.id = 'loading-overlay';
|
||
loadingDiv.innerHTML = `
|
||
<div class="loading-spinner">
|
||
<i class="bi bi-hourglass-split"></i>
|
||
<div>处理中...</div>
|
||
</div>
|
||
`;
|
||
loadingDiv.style.cssText = `
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: rgba(0,0,0,0.5);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
z-index: 9999;
|
||
color: white;
|
||
`;
|
||
|
||
document.body.appendChild(loadingDiv);
|
||
}
|
||
|
||
// 隐藏加载状态
|
||
function hideLoading() {
|
||
const loadingDiv = document.getElementById('loading-overlay');
|
||
if (loadingDiv) {
|
||
loadingDiv.remove();
|
||
}
|
||
}
|
||
|
||
// 页面加载完成后强制设置头像样式
|
||
window.addEventListener('load', function() {
|
||
forceAvatarStyles();
|
||
});
|
||
|
||
// 定时检查并修复头像样式
|
||
setInterval(function() {
|
||
// 检查并修复表格头像
|
||
const tableAvatars = document.querySelectorAll('.table .user-avatar');
|
||
tableAvatars.forEach(avatar => {
|
||
if (avatar.offsetWidth > 60 || avatar.offsetHeight > 60) {
|
||
setAvatarStyles(avatar, '48px');
|
||
}
|
||
});
|
||
|
||
// 检查并修复模态框头像
|
||
const modalAvatars = document.querySelectorAll('.modal .avatar-large');
|
||
modalAvatars.forEach(avatar => {
|
||
if (avatar.offsetWidth > 100 || avatar.offsetHeight > 100) {
|
||
setAvatarStyles(avatar, '80px');
|
||
}
|
||
});
|
||
}, 500);
|