// 个人中心页面JavaScript功能
let selectedFile = null;
// 强制设置头像样式的函数
function forceAvatarStyle(imgElement) {
if (!imgElement) return;
// 强制设置所有样式属性
imgElement.style.width = '120px';
imgElement.style.height = '120px';
imgElement.style.borderRadius = '50%';
imgElement.style.border = '3px solid #ddd';
imgElement.style.objectFit = 'cover';
imgElement.style.cursor = 'pointer';
imgElement.style.transition = 'all 0.3s ease';
imgElement.style.display = 'block';
imgElement.style.maxWidth = '120px';
imgElement.style.maxHeight = '120px';
imgElement.style.minWidth = '120px';
imgElement.style.minHeight = '120px';
// 设置属性避免被覆盖
imgElement.setAttribute('width', '120');
imgElement.setAttribute('height', '120');
}
// 页面加载完成后的处理
document.addEventListener('DOMContentLoaded', function() {
// 隐藏进度条
const progressContainer = document.getElementById('uploadProgress');
if (progressContainer) {
progressContainer.classList.remove('show');
progressContainer.style.display = 'none';
}
// *** 关键:强制设置已存在的头像样式 ***
const existingAvatar = document.getElementById('avatarPreview');
if (existingAvatar) {
forceAvatarStyle(existingAvatar);
// 图片加载完成后再次强制设置
if (existingAvatar.complete) {
forceAvatarStyle(existingAvatar);
} else {
existingAvatar.onload = function() {
forceAvatarStyle(existingAvatar);
};
}
}
// 添加拖拽上传支持
initDragAndDrop();
});
// 触发文件选择
function triggerFileInput() {
document.getElementById('avatarInput').click();
}
// 处理文件选择
function handleFileSelect(event) {
const file = event.target.files[0];
if (!file) return;
// 验证文件类型
if (!file.type.match('image.*')) {
showAlert('请选择图片文件!', 'error');
return;
}
// 验证文件大小 (2MB)
if (file.size > 2 * 1024 * 1024) {
showAlert('图片大小不能超过 2MB!', 'error');
return;
}
selectedFile = file;
// 预览图片
const reader = new FileReader();
reader.onload = function(e) {
const previewImage = document.getElementById('previewImage');
previewImage.src = e.target.result;
// 更新文件信息
updateFileInfo(file);
// 确保图片加载完成后再显示模态框
previewImage.onload = function() {
// *** 强制设置预览图片样式 ***
previewImage.style.maxWidth = '280px';
previewImage.style.maxHeight = '280px';
previewImage.style.width = 'auto';
previewImage.style.height = 'auto';
previewImage.style.objectFit = 'contain';
previewImage.style.borderRadius = '12px';
previewImage.style.boxShadow = '0 8px 25px rgba(0,0,0,0.15)';
previewImage.style.border = '3px solid #fff';
// 更新图片尺寸信息
document.getElementById('imageWidth').textContent = previewImage.naturalWidth;
document.getElementById('imageHeight').textContent = previewImage.naturalHeight;
const modal = new bootstrap.Modal(document.getElementById('imagePreviewModal'));
modal.show();
};
};
reader.readAsDataURL(file);
}
// 更新文件信息
function updateFileInfo(file) {
// 文件大小
const sizeInMB = (file.size / 1024 / 1024).toFixed(2);
document.getElementById('imageSize').textContent = sizeInMB + ' MB';
// 文件类型
const fileType = file.type.split('/')[1].toUpperCase();
document.getElementById('imageType').textContent = fileType;
}
// 确认上传
function confirmUpload() {
if (!selectedFile) return;
// 关闭模态框
const modal = bootstrap.Modal.getInstance(document.getElementById('imagePreviewModal'));
modal.hide();
// 开始上传
uploadAvatar(selectedFile);
}
// 上传头像
function uploadAvatar(file) {
const formData = new FormData();
formData.append('avatar', file);
// 显示上传进度
const progressContainer = document.getElementById('uploadProgress');
const progressBar = progressContainer.querySelector('.progress-bar');
progressContainer.style.display = 'block';
progressContainer.classList.add('show');
progressBar.style.width = '0%';
progressBar.textContent = '0%';
// 创建XMLHttpRequest以支持进度显示
const xhr = new XMLHttpRequest();
// 上传进度
xhr.upload.addEventListener('progress', function(e) {
if (e.lengthComputable) {
const percentComplete = (e.loaded / e.total) * 100;
progressBar.style.width = percentComplete + '%';
progressBar.textContent = Math.round(percentComplete) + '%';
}
});
// 上传完成
xhr.addEventListener('load', function() {
// 隐藏进度条
progressContainer.style.display = 'none';
progressContainer.classList.remove('show');
if (xhr.status === 200) {
try {
const response = JSON.parse(xhr.responseText);
if (response.success) {
// 更新头像显示
updateAvatarDisplay(response.avatar_url);
showAlert('头像上传成功!', 'success');
} else {
showAlert(response.message || '上传失败', 'error');
}
} catch (e) {
showAlert('服务器响应错误', 'error');
}
} else {
showAlert('上传失败,请重试', 'error');
}
// 清理文件输入
document.getElementById('avatarInput').value = '';
selectedFile = null;
});
// 上传错误
xhr.addEventListener('error', function() {
progressContainer.style.display = 'none';
progressContainer.classList.remove('show');
showAlert('网络错误,请重试', 'error');
// 清理文件输入
document.getElementById('avatarInput').value = '';
selectedFile = null;
});
// 发送请求
xhr.open('POST', '/upload/avatar');
xhr.send(formData);
}
// *** 关键:更新头像显示函数 ***
function updateAvatarDisplay(avatarUrl) {
const avatarPreview = document.getElementById('avatarPreview');
const avatarPlaceholder = document.getElementById('avatarPlaceholder');
if (avatarPreview) {
// 更新现有头像
avatarPreview.src = avatarUrl + '?t=' + new Date().getTime();
// *** 强制设置头像样式 ***
avatarPreview.onload = function() {
forceAvatarStyle(avatarPreview);
// 延迟再次确保样式生效
setTimeout(function() {
forceAvatarStyle(avatarPreview);
}, 100);
};
} else if (avatarPlaceholder) {
// 替换占位符为头像
const avatarUpload = avatarPlaceholder.parentElement;
avatarPlaceholder.remove();
const img = document.createElement('img');
img.src = avatarUrl + '?t=' + new Date().getTime();
img.alt = '头像';
img.className = 'avatar-preview';
img.id = 'avatarPreview';
// *** 创建新头像时强制设置样式 ***
img.onload = function() {
forceAvatarStyle(img);
// 延迟再次确保样式生效
setTimeout(function() {
forceAvatarStyle(img);
}, 100);
};
avatarUpload.insertBefore(img, avatarUpload.firstChild);
}
}
// 显示提示信息
function showAlert(message, type = 'info') {
// 移除现有的提示框
const existingAlerts = document.querySelectorAll('.alert.position-fixed');
existingAlerts.forEach(alert => alert.remove());
// 创建提示框
const alertDiv = document.createElement('div');
alertDiv.className = `alert alert-${type === 'error' ? 'danger' : type} alert-dismissible fade show position-fixed`;
alertDiv.style.cssText = 'top: 20px; right: 20px; z-index: 9999; min-width: 300px; max-width: 400px;';
const icon = type === 'success' ? 'check-circle' : type === 'error' ? 'exclamation-triangle' : 'info-circle';
alertDiv.innerHTML = `
${message}
`;
document.body.appendChild(alertDiv);
// 3秒后自动消失
setTimeout(() => {
if (alertDiv.parentElement) {
alertDiv.classList.remove('show');
setTimeout(() => {
if (alertDiv.parentElement) {
alertDiv.remove();
}
}, 150);
}
}, 3000);
}
// 初始化拖拽上传功能
function initDragAndDrop() {
const avatarUpload = document.querySelector('.avatar-upload');
if (avatarUpload) {
// 防止默认拖拽行为
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
avatarUpload.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
// 拖拽进入和离开的视觉反馈
['dragenter', 'dragover'].forEach(eventName => {
avatarUpload.addEventListener(eventName, highlight, false);
});
['dragleave', 'drop'].forEach(eventName => {
avatarUpload.addEventListener(eventName, unhighlight, false);
});
function highlight(e) {
avatarUpload.style.transform = 'scale(1.05)';
avatarUpload.style.boxShadow = '0 0 20px rgba(0,123,255,0.5)';
}
function unhighlight(e) {
avatarUpload.style.transform = '';
avatarUpload.style.boxShadow = '';
}
// 处理文件拖拽
avatarUpload.addEventListener('drop', handleDrop, false);
function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
if (files.length > 0) {
const file = files[0];
// 模拟文件输入事件
const event = { target: { files: [file] } };
handleFileSelect(event);
}
}
}
}
// 额外的保险措施:定期检查并修正头像样式
setInterval(function() {
const avatar = document.getElementById('avatarPreview');
if (avatar) {
// 检查头像是否超出预期尺寸
const rect = avatar.getBoundingClientRect();
if (rect.width > 125 || rect.height > 125) {
forceAvatarStyle(avatar);
}
}
}, 1000); // 每秒检查一次