完成头像上传与更新

This commit is contained in:
李志强 2025-05-27 11:46:20 +08:00
parent b8d3757397
commit efa390294d
6 changed files with 239 additions and 240 deletions

View File

@ -374,7 +374,7 @@ class IndexController extends BaseController
try { try {
// 验证上传的文件 // 验证上传的文件
validate([ validate([
'image' => 'filesize:51200|fileExt:jpg,png,gif,jpeg' 'image' => 'filesize:51200|fileExt:jpg,png,gif,jpeg,webp'
])->check($file); ])->check($file);
// 存储文件到public磁盘的uploads目录 // 存储文件到public磁盘的uploads目录

View File

@ -140,34 +140,20 @@ class UserController extends BaseController
public function logout() public function logout()
{ {
try { try {
// 记录退出日志
Log::record('用户退出登录', 'info'); Log::record('用户退出登录', 'info');
// 1. 清除所有 session // 清除所有会话和缓存数据
session(null); session(null);
// 2. 清除所有 cookie
// 正确的删除 cookie 方式
cookie('user_id', null, ['expire' => -1]);
cookie('user_account', null, ['expire' => -1]);
cookie('user_name', null, ['expire' => -1]);
cookie('user_avatar', null, ['expire' => -1]);
cookie('expire_time', null, ['expire' => -1]);
cookie('is_auto_login', null, ['expire' => -1]);
cookie('auto_login_attempted', null, ['expire' => -1]);
// 3. 清除缓存
Cache::tag('user_cache')->clear(); Cache::tag('user_cache')->clear();
// 4. 返回成功状态,并告诉前端清除 localStorage // 清除所有cookie
return json([ $cookies = ['user_id', 'user_account', 'user_name', 'user_avatar',
'code' => 0, 'expire_time', 'is_auto_login', 'auto_login_attempted', 'PHPSESSID'];
'msg' => '退出成功', foreach ($cookies as $cookie) {
'data' => [ cookie($cookie, null, ['expire' => -1]);
'clear_storage' => true }
]
]);
return json(['code' => 0, 'msg' => '退出成功', 'data' => ['clear_storage' => true]]);
} catch (\Exception $e) { } catch (\Exception $e) {
Log::record('退出登录失败:' . $e->getMessage(), 'error'); Log::record('退出登录失败:' . $e->getMessage(), 'error');
return json(['code' => 1, 'msg' => '退出失败:' . $e->getMessage()]); return json(['code' => 1, 'msg' => '退出失败:' . $e->getMessage()]);
@ -395,8 +381,8 @@ class UserController extends BaseController
} }
$ext = strtolower($file->getOriginalExtension()); $ext = strtolower($file->getOriginalExtension());
if (!in_array($ext, ['jpg', 'jpeg', 'png', 'gif'])) { if (!in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'webp'])) {
return json(['code' => 1, 'msg' => '只支持jpg、jpeg、png、gif格式的图片']); return json(['code' => 1, 'msg' => '只支持jpg、jpeg、png、gif、webp格式的图片']);
} }
// 移动到指定目录 // 移动到指定目录

View File

@ -28,44 +28,44 @@
</div> </div>
<style> <style>
.avatar-section { .avatar-section {
max-width: 800px; max-width: 800px;
margin: 0 auto; margin: 0 auto;
} }
.section-title { .section-title {
font-size: 20px; font-size: 20px;
font-weight: 600; font-weight: 600;
color: #333; color: #333;
margin-bottom: 24px; margin-bottom: 24px;
padding-bottom: 16px; padding-bottom: 16px;
border-bottom: 1px solid #f0f0f0; border-bottom: 1px solid #f0f0f0;
} }
.avatar-upload-container { .avatar-upload-container {
display: flex; display: flex;
gap: 40px; gap: 40px;
margin-bottom: 32px; margin-bottom: 32px;
} }
.current-avatar { .current-avatar {
text-align: center; text-align: center;
} }
.current-avatar img { .current-avatar img {
width: 160px; width: 160px;
height: 160px; height: 160px;
border-radius: 50%; border-radius: 50%;
object-fit: cover; object-fit: cover;
border: 3px solid #f5f5f5; border: 3px solid #f5f5f5;
} }
.avatar-tip { .avatar-tip {
margin-top: 12px; margin-top: 12px;
color: #666; color: #666;
} }
.upload-area { .upload-area {
flex: 1; flex: 1;
border: 2px dashed #d9d9d9; border: 2px dashed #d9d9d9;
border-radius: 8px; border-radius: 8px;
@ -73,60 +73,60 @@
text-align: center; text-align: center;
cursor: pointer; cursor: pointer;
transition: all 0.3s; transition: all 0.3s;
} }
.upload-area:hover { .upload-area:hover {
border-color: #1677ff; border-color: #1677ff;
} }
.upload-area .layui-icon { .upload-area .layui-icon {
font-size: 48px; font-size: 48px;
color: #999; color: #999;
margin-bottom: 16px; margin-bottom: 16px;
} }
.upload-area p { .upload-area p {
margin: 8px 0; margin: 8px 0;
color: #666; color: #666;
} }
.upload-tip { .upload-tip {
font-size: 12px; font-size: 12px;
color: #999; color: #999;
} }
.avatar-preview { .avatar-preview {
margin-top: 32px; margin-top: 32px;
padding-top: 32px; padding-top: 32px;
border-top: 1px solid #f0f0f0; border-top: 1px solid #f0f0f0;
} }
.avatar-preview h3 { .avatar-preview h3 {
font-size: 16px; font-size: 16px;
color: #333; color: #333;
margin-bottom: 16px; margin-bottom: 16px;
} }
.preview-container { .preview-container {
text-align: center; text-align: center;
margin-bottom: 24px; margin-bottom: 24px;
} }
.preview-container img { .preview-container img {
max-width: 200px; max-width: 200px;
max-height: 200px; max-height: 200px;
border-radius: 8px; border-radius: 8px;
} }
.preview-actions { .preview-actions {
text-align: center; text-align: center;
} }
.preview-actions .layui-btn { .preview-actions .layui-btn {
margin: 0 8px; margin: 0 8px;
} }
@media (max-width: 768px) { @media (max-width: 768px) {
.avatar-upload-container { .avatar-upload-container {
flex-direction: column; flex-direction: column;
gap: 24px; gap: 24px;
@ -140,27 +140,27 @@
.upload-area { .upload-area {
padding: 24px; padding: 24px;
} }
} }
</style> </style>
<script> <script>
layui.use(['upload', 'layer'], function(){ layui.use(['upload', 'layer'], function () {
var upload = layui.upload; var upload = layui.upload;
var layer = layui.layer; var layer = layui.layer;
// 点击上传区域触发文件选择 // 点击上传区域触发文件选择
document.getElementById('uploadArea').addEventListener('click', function() { document.getElementById('uploadArea').addEventListener('click', function () {
document.getElementById('avatarFile').click(); document.getElementById('avatarFile').click();
}); });
// 处理文件选择 // 处理文件选择
document.getElementById('avatarFile').addEventListener('change', function(e) { document.getElementById('avatarFile').addEventListener('change', function (e) {
var file = e.target.files[0]; var file = e.target.files[0];
if (!file) return; if (!file) return;
// 检查文件类型 // 检查文件类型
if (!['image/jpeg', 'image/png', 'image/gif'].includes(file.type)) { if (!['image/jpeg', 'image/png', 'image/gif', 'image/webp'].includes(file.type)) {
layer.msg('请上传 jpg、png 或 gif 格式的图片'); layer.msg('请上传 jpg、png、webp 或 gif 格式的图片');
return; return;
} }
@ -172,7 +172,7 @@ layui.use(['upload', 'layer'], function(){
// 预览图片 // 预览图片
var reader = new FileReader(); var reader = new FileReader();
reader.onload = function(e) { reader.onload = function (e) {
document.getElementById('previewImage').src = e.target.result; document.getElementById('previewImage').src = e.target.result;
document.querySelector('.avatar-preview').style.display = 'block'; document.querySelector('.avatar-preview').style.display = 'block';
}; };
@ -180,7 +180,7 @@ layui.use(['upload', 'layer'], function(){
}); });
// 确认上传 // 确认上传
document.getElementById('confirmUpload').addEventListener('click', function() { document.getElementById('confirmUpload').addEventListener('click', function () {
var file = document.getElementById('avatarFile').files[0]; var file = document.getElementById('avatarFile').files[0];
if (!file) return; if (!file) return;
@ -199,25 +199,38 @@ layui.use(['upload', 'layer'], function(){
.then(data => { .then(data => {
layer.close(loadIndex); layer.close(loadIndex);
if (data.code === 0) { if (data.code === 0) {
layer.msg('头像上传成功', {icon: 1}); // 更新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.getElementById('currentAvatar').src = data.data.url;
// 隐藏预览区域 // 隐藏预览区域
document.querySelector('.avatar-preview').style.display = 'none'; document.querySelector('.avatar-preview').style.display = 'none';
// 清空文件输入 // 清空文件输入
document.getElementById('avatarFile').value = ''; document.getElementById('avatarFile').value = '';
// 刷新页面以更新所有显示的头像
window.location.reload();
});
} else { } else {
layer.msg(data.msg || '上传失败', {icon: 2}); layer.msg(data.msg || '上传失败', { icon: 2 });
} }
}) })
.catch(error => { .catch(error => {
layer.close(loadIndex); layer.close(loadIndex);
layer.msg('上传失败,请重试', {icon: 2}); layer.msg('上传失败,请重试', { icon: 2 });
}); });
}); });
// 取消上传 // 取消上传
document.getElementById('cancelUpload').addEventListener('click', function() { document.getElementById('cancelUpload').addEventListener('click', function () {
document.querySelector('.avatar-preview').style.display = 'none'; document.querySelector('.avatar-preview').style.display = 'none';
document.getElementById('avatarFile').value = ''; document.getElementById('avatarFile').value = '';
}); });
@ -225,17 +238,17 @@ layui.use(['upload', 'layer'], function(){
// 拖拽上传 // 拖拽上传
var uploadArea = document.getElementById('uploadArea'); var uploadArea = document.getElementById('uploadArea');
uploadArea.addEventListener('dragover', function(e) { uploadArea.addEventListener('dragover', function (e) {
e.preventDefault(); e.preventDefault();
this.style.borderColor = '#1677ff'; this.style.borderColor = '#1677ff';
}); });
uploadArea.addEventListener('dragleave', function(e) { uploadArea.addEventListener('dragleave', function (e) {
e.preventDefault(); e.preventDefault();
this.style.borderColor = '#d9d9d9'; this.style.borderColor = '#d9d9d9';
}); });
uploadArea.addEventListener('drop', function(e) { uploadArea.addEventListener('drop', function (e) {
e.preventDefault(); e.preventDefault();
this.style.borderColor = '#d9d9d9'; this.style.borderColor = '#d9d9d9';
@ -251,5 +264,5 @@ layui.use(['upload', 'layer'], function(){
var event = new Event('change'); var event = new Event('change');
document.getElementById('avatarFile').dispatchEvent(event); document.getElementById('avatarFile').dispatchEvent(event);
}); });
}); });
</script> </script>

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB