268 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			268 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <div class="avatar-section">
 | |
|     <h2 class="section-title">修改头像</h2>
 | |
| 
 | |
|     <div class="avatar-upload-container">
 | |
|         <div class="current-avatar">
 | |
|             <img src="{$user.avatar|default='/static/images/avatar.png'}" alt="当前头像" id="currentAvatar">
 | |
|             <p class="avatar-tip">当前头像</p>
 | |
|         </div>
 | |
| 
 | |
|         <div class="upload-area" id="uploadArea">
 | |
|             <i class="layui-icon layui-icon-upload"></i>
 | |
|             <p>点击或拖拽图片到此处上传</p>
 | |
|             <p class="upload-tip">支持 jpg、png、gif 格式,大小不超过 2MB</p>
 | |
|             <input type="file" id="avatarFile" accept="image/*" style="display: none;">
 | |
|         </div>
 | |
|     </div>
 | |
| 
 | |
|     <div class="avatar-preview" style="display: none;">
 | |
|         <h3>预览</h3>
 | |
|         <div class="preview-container">
 | |
|             <img src="" alt="预览图" id="previewImage">
 | |
|         </div>
 | |
|         <div class="preview-actions">
 | |
|             <button class="layui-btn" id="confirmUpload">确认上传</button>
 | |
|             <button class="layui-btn layui-btn-primary" id="cancelUpload">取消</button>
 | |
|         </div>
 | |
|     </div>
 | |
| </div>
 | |
| 
 | |
| <style>
 | |
|     .avatar-section {
 | |
|         max-width: 800px;
 | |
|         margin: 0 auto;
 | |
|     }
 | |
| 
 | |
|     .section-title {
 | |
|         font-size: 20px;
 | |
|         font-weight: 600;
 | |
|         color: #333;
 | |
|         margin-bottom: 24px;
 | |
|         padding-bottom: 16px;
 | |
|         border-bottom: 1px solid #f0f0f0;
 | |
|     }
 | |
| 
 | |
|     .avatar-upload-container {
 | |
|         display: flex;
 | |
|         gap: 40px;
 | |
|         margin-bottom: 32px;
 | |
|     }
 | |
| 
 | |
|     .current-avatar {
 | |
|         text-align: center;
 | |
|     }
 | |
| 
 | |
|     .current-avatar img {
 | |
|         width: 160px;
 | |
|         height: 160px;
 | |
|         border-radius: 50%;
 | |
|         object-fit: cover;
 | |
|         border: 3px solid #f5f5f5;
 | |
|     }
 | |
| 
 | |
|     .avatar-tip {
 | |
|         margin-top: 12px;
 | |
|         color: #666;
 | |
|     }
 | |
| 
 | |
|     .upload-area {
 | |
|         flex: 1;
 | |
|         border: 2px dashed #d9d9d9;
 | |
|         border-radius: 8px;
 | |
|         padding: 40px;
 | |
|         text-align: center;
 | |
|         cursor: pointer;
 | |
|         transition: all 0.3s;
 | |
|     }
 | |
| 
 | |
|     .upload-area:hover {
 | |
|         border-color: #1677ff;
 | |
|     }
 | |
| 
 | |
|     .upload-area .layui-icon {
 | |
|         font-size: 48px;
 | |
|         color: #999;
 | |
|         margin-bottom: 16px;
 | |
|     }
 | |
| 
 | |
|     .upload-area p {
 | |
|         margin: 8px 0;
 | |
|         color: #666;
 | |
|     }
 | |
| 
 | |
|     .upload-tip {
 | |
|         font-size: 12px;
 | |
|         color: #999;
 | |
|     }
 | |
| 
 | |
|     .avatar-preview {
 | |
|         margin-top: 32px;
 | |
|         padding-top: 32px;
 | |
|         border-top: 1px solid #f0f0f0;
 | |
|     }
 | |
| 
 | |
|     .avatar-preview h3 {
 | |
|         font-size: 16px;
 | |
|         color: #333;
 | |
|         margin-bottom: 16px;
 | |
|     }
 | |
| 
 | |
|     .preview-container {
 | |
|         text-align: center;
 | |
|         margin-bottom: 24px;
 | |
|     }
 | |
| 
 | |
|     .preview-container img {
 | |
|         max-width: 200px;
 | |
|         max-height: 200px;
 | |
|         border-radius: 8px;
 | |
|     }
 | |
| 
 | |
|     .preview-actions {
 | |
|         text-align: center;
 | |
|     }
 | |
| 
 | |
|     .preview-actions .layui-btn {
 | |
|         margin: 0 8px;
 | |
|     }
 | |
| 
 | |
|     @media (max-width: 768px) {
 | |
|         .avatar-upload-container {
 | |
|             flex-direction: column;
 | |
|             gap: 24px;
 | |
|         }
 | |
| 
 | |
|         .current-avatar img {
 | |
|             width: 120px;
 | |
|             height: 120px;
 | |
|         }
 | |
| 
 | |
|         .upload-area {
 | |
|             padding: 24px;
 | |
|         }
 | |
|     }
 | |
| </style>
 | |
| 
 | |
| <script>
 | |
|     layui.use(['upload', 'layer'], function () {
 | |
|         var upload = layui.upload;
 | |
|         var layer = layui.layer;
 | |
| 
 | |
|         // 点击上传区域触发文件选择
 | |
|         document.getElementById('uploadArea').addEventListener('click', function () {
 | |
|             document.getElementById('avatarFile').click();
 | |
|         });
 | |
| 
 | |
|         // 处理文件选择
 | |
|         document.getElementById('avatarFile').addEventListener('change', function (e) {
 | |
|             var file = e.target.files[0];
 | |
|             if (!file) return;
 | |
| 
 | |
|             // 检查文件类型
 | |
|             if (!['image/jpeg', 'image/png', 'image/gif', 'image/webp'].includes(file.type)) {
 | |
|                 layer.msg('请上传 jpg、png、webp 或 gif 格式的图片');
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             // 检查文件大小
 | |
|             if (file.size > 2 * 1024 * 1024) {
 | |
|                 layer.msg('图片大小不能超过 2MB');
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             // 预览图片
 | |
|             var reader = new FileReader();
 | |
|             reader.onload = function (e) {
 | |
|                 document.getElementById('previewImage').src = e.target.result;
 | |
|                 document.querySelector('.avatar-preview').style.display = 'block';
 | |
|             };
 | |
|             reader.readAsDataURL(file);
 | |
|         });
 | |
| 
 | |
|         // 确认上传
 | |
|         document.getElementById('confirmUpload').addEventListener('click', function () {
 | |
|             var file = document.getElementById('avatarFile').files[0];
 | |
|             if (!file) return;
 | |
| 
 | |
|             var formData = new FormData();
 | |
|             formData.append('avatar', file);
 | |
| 
 | |
|             // 显示上传中
 | |
|             var loadIndex = layer.load(2);
 | |
| 
 | |
|             // 发送上传请求
 | |
|             fetch('/index/user/update_avatar', {
 | |
|                 method: 'POST',
 | |
|                 body: formData
 | |
|             })
 | |
|                 .then(response => response.json())
 | |
|                 .then(data => {
 | |
|                     layer.close(loadIndex);
 | |
|                     if (data.code === 0) {
 | |
|                         // 更新cookie中的头像
 | |
|                         document.cookie = "user_avatar=" + data.data.url + "; path=/";
 | |
| 
 | |
|                         // 更新localStorage中的头像
 | |
|                         localStorage.setItem('user_avatar', data.data.url);
 | |
| 
 | |
|                         layer.msg('头像上传成功', {
 | |
|                             icon: 1,
 | |
|                             time: 1000
 | |
|                         }, function () {
 | |
|                             // 更新当前头像显示
 | |
|                             document.getElementById('currentAvatar').src = data.data.url;
 | |
|                             // 隐藏预览区域
 | |
|                             document.querySelector('.avatar-preview').style.display = 'none';
 | |
|                             // 清空文件输入
 | |
|                             document.getElementById('avatarFile').value = '';
 | |
| 
 | |
|                             // 刷新页面以更新所有显示的头像
 | |
|                             window.location.reload();
 | |
|                         });
 | |
|                     } else {
 | |
|                         layer.msg(data.msg || '上传失败', { icon: 2 });
 | |
|                     }
 | |
|                 })
 | |
|                 .catch(error => {
 | |
|                     layer.close(loadIndex);
 | |
|                     layer.msg('上传失败,请重试', { icon: 2 });
 | |
|                 });
 | |
|         });
 | |
| 
 | |
|         // 取消上传
 | |
|         document.getElementById('cancelUpload').addEventListener('click', function () {
 | |
|             document.querySelector('.avatar-preview').style.display = 'none';
 | |
|             document.getElementById('avatarFile').value = '';
 | |
|         });
 | |
| 
 | |
|         // 拖拽上传
 | |
|         var uploadArea = document.getElementById('uploadArea');
 | |
| 
 | |
|         uploadArea.addEventListener('dragover', function (e) {
 | |
|             e.preventDefault();
 | |
|             this.style.borderColor = '#1677ff';
 | |
|         });
 | |
| 
 | |
|         uploadArea.addEventListener('dragleave', function (e) {
 | |
|             e.preventDefault();
 | |
|             this.style.borderColor = '#d9d9d9';
 | |
|         });
 | |
| 
 | |
|         uploadArea.addEventListener('drop', function (e) {
 | |
|             e.preventDefault();
 | |
|             this.style.borderColor = '#d9d9d9';
 | |
| 
 | |
|             var file = e.dataTransfer.files[0];
 | |
|             if (!file) return;
 | |
| 
 | |
|             // 触发文件选择事件
 | |
|             var dataTransfer = new DataTransfer();
 | |
|             dataTransfer.items.add(file);
 | |
|             document.getElementById('avatarFile').files = dataTransfer.files;
 | |
| 
 | |
|             // 手动触发change事件
 | |
|             var event = new Event('change');
 | |
|             document.getElementById('avatarFile').dispatchEvent(event);
 | |
|         });
 | |
|     });
 | |
| </script> |