426 lines
14 KiB
PHP
426 lines
14 KiB
PHP
<div class="basic-info">
|
|
<div class="layui-tab">
|
|
<ul class="layui-tab-title">
|
|
<li class="layui-this">个人资料</li>
|
|
<li>修改头像</li>
|
|
</ul>
|
|
<div class="layui-tab-content">
|
|
<div class="layui-tab-item layui-show">
|
|
<form class="layui-form" lay-filter="basicForm">
|
|
<div class="layui-form-item">
|
|
<label class="layui-form-label">用户名</label>
|
|
<div class="layui-input-block">
|
|
<input type="text" name="name" value="{$user.name}" placeholder="请输入用户名"
|
|
class="layui-input">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="layui-form-item">
|
|
<label class="layui-form-label">账号</label>
|
|
<div class="layui-input-block">
|
|
<input type="text" value="{$user.account}" class="layui-input" disabled>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="layui-form-item">
|
|
<label class="layui-form-label">QQ</label>
|
|
<div class="layui-input-block">
|
|
<input type="text" name="qq" value="{$user.qq}" placeholder="请输入QQ号" class="layui-input">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="layui-form-item">
|
|
<label class="layui-form-label">微信</label>
|
|
<div class="layui-input-block">
|
|
{if $user.wechat}
|
|
<input type="text" name="wechat" value="{$user.wechat}" placeholder="请输入微信号"
|
|
class="layui-input">
|
|
{else}
|
|
<button class="layui-btn" id="bindWechat">绑定微信号</button>
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="layui-form-item">
|
|
<label class="layui-form-label">手机号</label>
|
|
<div class="layui-input-block">
|
|
<input type="text" name="phone" value="{$user.phone}" placeholder="请输入手机号"
|
|
class="layui-input">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="layui-form-item">
|
|
<label class="layui-form-label">性别</label>
|
|
<div class="layui-input-block">
|
|
<input type="radio" name="sex" value="1" title="男" {if $user.sex==1}checked{/if}>
|
|
<input type="radio" name="sex" value="2" title="女" {if $user.sex==2}checked{/if}>
|
|
<input type="radio" name="sex" value="0" title="保密" {if $user.sex==0}checked{/if}>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="layui-form-item">
|
|
<div class="layui-input-block">
|
|
<button class="layui-btn" lay-submit lay-filter="saveBasic">保存修改</button>
|
|
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="layui-tab-item">
|
|
<div class="avatar-section">
|
|
<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>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<script>
|
|
layui.use(['form', 'layer', 'upload'], function () {
|
|
var form = layui.form;
|
|
var layer = layui.layer;
|
|
var upload = layui.upload;
|
|
|
|
// 绑定微信号按钮点击事件
|
|
document.getElementById('bindWechat').addEventListener('click', function () {
|
|
// 发送 AJAX 请求调用 qrcode 接口
|
|
fetch('/index/user/qrcode')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.code === 0) {
|
|
// 二维码生成成功,这里可以添加显示二维码的逻辑,例如弹出一个窗口显示二维码
|
|
layer.open({
|
|
type: 1,
|
|
title: '微信绑定二维码',
|
|
content: `<img src="${data.data.qrcode_url}" alt="微信绑定二维码">`,
|
|
area: ['300px', '300px']
|
|
});
|
|
} else {
|
|
// 二维码生成失败,提示用户
|
|
layer.msg(data.msg, { icon: 2 });
|
|
}
|
|
})
|
|
.catch(error => {
|
|
// 请求出错,提示用户
|
|
layer.msg('请求出错,请稍后重试', { icon: 2 });
|
|
});
|
|
});
|
|
|
|
// 监听个人资料表单提交
|
|
form.on('submit(saveBasic)', function (data) {
|
|
// 发送AJAX请求保存数据
|
|
fetch('/index/user/saveBasic', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
},
|
|
body: JSON.stringify(data.field)
|
|
})
|
|
.then(response => response.json())
|
|
.then(result => {
|
|
if (result.code === 0) {
|
|
layer.msg(result.msg, { icon: 1 }, function () {
|
|
// 保存成功后刷新页面
|
|
window.location.reload();
|
|
});
|
|
} else {
|
|
layer.msg(result.msg, { icon: 2 });
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('保存失败:', error);
|
|
layer.msg('保存失败,请稍后重试', { icon: 2 });
|
|
});
|
|
|
|
return false; // 阻止表单默认提交
|
|
});
|
|
|
|
// 点击上传区域触发文件选择
|
|
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>
|
|
|
|
|
|
<style>
|
|
.basic-info {
|
|
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;
|
|
}
|
|
|
|
.layui-form-label {
|
|
width: 100px;
|
|
}
|
|
|
|
.layui-input-block {
|
|
margin-left: 130px;
|
|
}
|
|
|
|
.layui-form-item {
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.layui-textarea {
|
|
min-height: 120px;
|
|
}
|
|
|
|
.avatar-section {
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.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) {
|
|
.layui-form-label {
|
|
width: 80px;
|
|
}
|
|
|
|
.layui-input-block {
|
|
margin-left: 110px;
|
|
}
|
|
|
|
.avatar-upload-container {
|
|
flex-direction: column;
|
|
gap: 24px;
|
|
}
|
|
|
|
.current-avatar img {
|
|
width: 120px;
|
|
height: 120px;
|
|
}
|
|
|
|
.upload-area {
|
|
padding: 24px;
|
|
}
|
|
}
|
|
</style> |