更新前端个人中心
This commit is contained in:
parent
d4017014f5
commit
e1e51c8c6f
@ -1,50 +1,87 @@
|
||||
<div class="basic-info">
|
||||
<h2 class="section-title">个人资料</h2>
|
||||
<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-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">账号</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="qq" name="qq" value="{$user.qq}" placeholder="请输入QQ号" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">QQ</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="qq" 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">
|
||||
<input type="tel" 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="tel" 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">
|
||||
<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 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>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@ -78,6 +115,95 @@
|
||||
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;
|
||||
@ -86,15 +212,30 @@
|
||||
.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>
|
||||
|
||||
<script>
|
||||
layui.use(['form', 'layer'], function () {
|
||||
layui.use(['form', 'layer', 'upload'], function () {
|
||||
var form = layui.form;
|
||||
var layer = layui.layer;
|
||||
var upload = layui.upload;
|
||||
|
||||
// 监听表单提交
|
||||
// 监听个人资料表单提交
|
||||
form.on('submit(saveBasic)', function (data) {
|
||||
// 发送AJAX请求保存数据
|
||||
fetch('/index/user/saveBasic', {
|
||||
@ -123,5 +264,122 @@
|
||||
|
||||
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>
|
||||
@ -1,28 +1,24 @@
|
||||
<div class="messages-section">
|
||||
<h2 class="section-title">我的消息</h2>
|
||||
|
||||
<div class="message-tabs">
|
||||
<div class="layui-tab layui-tab-brief" lay-filter="messageTabs">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">全部消息</li>
|
||||
<li>未读消息</li>
|
||||
<li>已读消息</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<div class="layui-tab-item layui-show">
|
||||
<div class="message-list" id="allMessages">
|
||||
<!-- 消息列表将通过JavaScript动态加载 -->
|
||||
</div>
|
||||
<div class="basic-info">
|
||||
<div class="layui-tab">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">全部消息</li>
|
||||
<li>未读消息</li>
|
||||
<li>已读消息</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<div class="layui-tab-item layui-show">
|
||||
<div class="message-list" id="allMessages">
|
||||
<!-- 消息列表将通过JavaScript动态加载 -->
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
<div class="message-list" id="unreadMessages">
|
||||
<!-- 未读消息列表 -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
<div class="message-list" id="unreadMessages">
|
||||
<!-- 未读消息列表 -->
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
<div class="message-list" id="readMessages">
|
||||
<!-- 已读消息列表 -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
<div class="message-list" id="readMessages">
|
||||
<!-- 已读消息列表 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -30,156 +26,176 @@
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.messages-section {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
.section-title {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 24px;
|
||||
padding-bottom: 16px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.message-tabs {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.layui-form-label {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.message-list {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.layui-input-block {
|
||||
margin-left: 130px;
|
||||
}
|
||||
|
||||
.message-item {
|
||||
padding: 16px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 16px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
.layui-form-item {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.message-item:hover {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
.layui-textarea {
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.message-item.unread {
|
||||
background-color: #f0f7ff;
|
||||
}
|
||||
.message-list {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.message-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.message-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.message-title {
|
||||
font-weight: 500;
|
||||
margin-bottom: 4px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.message-text {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.message-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.message-time {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.message-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.message-actions button {
|
||||
padding: 4px 8px;
|
||||
font-size: 12px;
|
||||
border-radius: 4px;
|
||||
background: none;
|
||||
border: 1px solid #d9d9d9;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.message-actions button:hover {
|
||||
border-color: #1677ff;
|
||||
color: #1677ff;
|
||||
}
|
||||
|
||||
.empty-message {
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.message-item {
|
||||
padding: 12px;
|
||||
padding: 16px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 16px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
|
||||
.message-item:hover {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.message-item.unread {
|
||||
background-color: #f0f7ff;
|
||||
}
|
||||
|
||||
.message-avatar {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.message-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.message-title {
|
||||
font-weight: 500;
|
||||
margin-bottom: 4px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.message-text {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.message-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.message-time {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.message-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.message-actions button {
|
||||
padding: 4px 8px;
|
||||
font-size: 12px;
|
||||
border-radius: 4px;
|
||||
background: none;
|
||||
border: 1px solid #d9d9d9;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.message-actions button:hover {
|
||||
border-color: #1677ff;
|
||||
color: #1677ff;
|
||||
}
|
||||
|
||||
.empty-message {
|
||||
text-align: center;
|
||||
padding: 40px 0;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.layui-form-label {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.layui-input-block {
|
||||
margin-left: 110px;
|
||||
}
|
||||
|
||||
.message-item {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.message-avatar {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
layui.use(['element', 'layer'], function(){
|
||||
var element = layui.element;
|
||||
var layer = layui.layer;
|
||||
|
||||
// 加载消息列表
|
||||
function loadMessages(type) {
|
||||
var container = document.getElementById(type + 'Messages');
|
||||
var loadIndex = layer.load(2);
|
||||
|
||||
fetch('/index/user/getMessages?type=' + type)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
layer.close(loadIndex);
|
||||
if(data.code === 0) {
|
||||
renderMessages(container, data.data);
|
||||
} else {
|
||||
layer.msg(data.msg || '加载失败', {icon: 2});
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
layer.close(loadIndex);
|
||||
layer.msg('加载失败,请重试', {icon: 2});
|
||||
});
|
||||
}
|
||||
|
||||
// 渲染消息列表
|
||||
function renderMessages(container, messages) {
|
||||
if(!messages || messages.length === 0) {
|
||||
container.innerHTML = '<div class="empty-message">暂无消息</div>';
|
||||
return;
|
||||
layui.use(['element', 'layer'], function () {
|
||||
var element = layui.element;
|
||||
var layer = layui.layer;
|
||||
|
||||
// 加载消息列表
|
||||
function loadMessages(type) {
|
||||
var container = document.getElementById(type + 'Messages');
|
||||
var loadIndex = layer.load(2);
|
||||
|
||||
fetch('/index/user/getMessages?type=' + type)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
layer.close(loadIndex);
|
||||
if (data.code === 0) {
|
||||
renderMessages(container, data.data);
|
||||
} else {
|
||||
layer.msg(data.msg || '加载失败', { icon: 2 });
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
layer.close(loadIndex);
|
||||
layer.msg('加载失败,请重试', { icon: 2 });
|
||||
});
|
||||
}
|
||||
|
||||
var html = '';
|
||||
messages.forEach(function(message) {
|
||||
html += `
|
||||
|
||||
// 渲染消息列表
|
||||
function renderMessages(container, messages) {
|
||||
if (!messages || messages.length === 0) {
|
||||
container.innerHTML = '<div class="empty-message">暂无消息</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
var html = '';
|
||||
messages.forEach(function (message) {
|
||||
html += `
|
||||
<div class="message-item ${message.is_read ? '' : 'unread'}" data-id="${message.id}">
|
||||
<img src="${message.avatar || '/static/images/avatar.png'}" class="message-avatar" alt="头像">
|
||||
<div class="message-content">
|
||||
@ -195,116 +211,116 @@ layui.use(['element', 'layer'], function(){
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
container.innerHTML = html;
|
||||
|
||||
// 绑定事件
|
||||
bindMessageEvents(container);
|
||||
}
|
||||
|
||||
// 绑定消息事件
|
||||
function bindMessageEvents(container) {
|
||||
});
|
||||
|
||||
container.innerHTML = html;
|
||||
|
||||
// 绑定事件
|
||||
bindMessageEvents(container);
|
||||
}
|
||||
|
||||
// 绑定消息事件
|
||||
function bindMessageEvents(container) {
|
||||
// 标记已读
|
||||
container.querySelectorAll('.mark-read').forEach(btn => {
|
||||
btn.addEventListener('click', function (e) {
|
||||
e.stopPropagation();
|
||||
var messageId = this.closest('.message-item').dataset.id;
|
||||
markAsRead(messageId);
|
||||
});
|
||||
});
|
||||
|
||||
// 删除消息
|
||||
container.querySelectorAll('.delete-message').forEach(btn => {
|
||||
btn.addEventListener('click', function (e) {
|
||||
e.stopPropagation();
|
||||
var messageId = this.closest('.message-item').dataset.id;
|
||||
deleteMessage(messageId);
|
||||
});
|
||||
});
|
||||
|
||||
// 点击消息
|
||||
container.querySelectorAll('.message-item').forEach(item => {
|
||||
item.addEventListener('click', function () {
|
||||
var messageId = this.dataset.id;
|
||||
viewMessage(messageId);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 标记已读
|
||||
container.querySelectorAll('.mark-read').forEach(btn => {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
var messageId = this.closest('.message-item').dataset.id;
|
||||
markAsRead(messageId);
|
||||
});
|
||||
});
|
||||
|
||||
// 删除消息
|
||||
container.querySelectorAll('.delete-message').forEach(btn => {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
var messageId = this.closest('.message-item').dataset.id;
|
||||
deleteMessage(messageId);
|
||||
});
|
||||
});
|
||||
|
||||
// 点击消息
|
||||
container.querySelectorAll('.message-item').forEach(item => {
|
||||
item.addEventListener('click', function() {
|
||||
var messageId = this.dataset.id;
|
||||
viewMessage(messageId);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 标记已读
|
||||
function markAsRead(messageId) {
|
||||
fetch('/index/user/markMessageRead', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({id: messageId})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if(data.code === 0) {
|
||||
layer.msg('已标记为已读', {icon: 1});
|
||||
// 重新加载消息列表
|
||||
loadMessages('all');
|
||||
loadMessages('unread');
|
||||
loadMessages('read');
|
||||
} else {
|
||||
layer.msg(data.msg || '操作失败', {icon: 2});
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
layer.msg('操作失败,请重试', {icon: 2});
|
||||
});
|
||||
}
|
||||
|
||||
// 删除消息
|
||||
function deleteMessage(messageId) {
|
||||
layer.confirm('确定要删除这条消息吗?', {
|
||||
btn: ['确定','取消']
|
||||
}, function(){
|
||||
fetch('/index/user/deleteMessage', {
|
||||
function markAsRead(messageId) {
|
||||
fetch('/index/user/markMessageRead', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({id: messageId})
|
||||
body: JSON.stringify({ id: messageId })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if(data.code === 0) {
|
||||
layer.msg('删除成功', {icon: 1});
|
||||
// 重新加载消息列表
|
||||
loadMessages('all');
|
||||
loadMessages('unread');
|
||||
loadMessages('read');
|
||||
} else {
|
||||
layer.msg(data.msg || '删除失败', {icon: 2});
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
layer.msg('删除失败,请重试', {icon: 2});
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.code === 0) {
|
||||
layer.msg('已标记为已读', { icon: 1 });
|
||||
// 重新加载消息列表
|
||||
loadMessages('all');
|
||||
loadMessages('unread');
|
||||
loadMessages('read');
|
||||
} else {
|
||||
layer.msg(data.msg || '操作失败', { icon: 2 });
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
layer.msg('操作失败,请重试', { icon: 2 });
|
||||
});
|
||||
}
|
||||
|
||||
// 删除消息
|
||||
function deleteMessage(messageId) {
|
||||
layer.confirm('确定要删除这条消息吗?', {
|
||||
btn: ['确定', '取消']
|
||||
}, function () {
|
||||
fetch('/index/user/deleteMessage', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ id: messageId })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.code === 0) {
|
||||
layer.msg('删除成功', { icon: 1 });
|
||||
// 重新加载消息列表
|
||||
loadMessages('all');
|
||||
loadMessages('unread');
|
||||
loadMessages('read');
|
||||
} else {
|
||||
layer.msg(data.msg || '删除失败', { icon: 2 });
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
layer.msg('删除失败,请重试', { icon: 2 });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 查看消息详情
|
||||
function viewMessage(messageId) {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '消息详情',
|
||||
area: ['500px', '400px'],
|
||||
content: '/index/user/messageDetail?id=' + messageId
|
||||
});
|
||||
}
|
||||
|
||||
// 监听标签切换
|
||||
element.on('tab(messageTabs)', function (data) {
|
||||
var type = ['all', 'unread', 'read'][data.index];
|
||||
loadMessages(type);
|
||||
});
|
||||
}
|
||||
|
||||
// 查看消息详情
|
||||
function viewMessage(messageId) {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '消息详情',
|
||||
area: ['500px', '400px'],
|
||||
content: '/index/user/messageDetail?id=' + messageId
|
||||
});
|
||||
}
|
||||
|
||||
// 监听标签切换
|
||||
element.on('tab(messageTabs)', function(data){
|
||||
var type = ['all', 'unread', 'read'][data.index];
|
||||
loadMessages(type);
|
||||
|
||||
// 初始加载全部消息
|
||||
loadMessages('all');
|
||||
});
|
||||
|
||||
// 初始加载全部消息
|
||||
loadMessages('all');
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
@ -1,6 +1,5 @@
|
||||
<div class="notifications-section">
|
||||
<h2 class="section-title">系统通知</h2>
|
||||
|
||||
|
||||
<div class="layui-tab layui-tab-brief" lay-filter="notificationTabs">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">全部通知</li>
|
||||
@ -22,99 +21,99 @@
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.notifications-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;
|
||||
}
|
||||
|
||||
.notification-list {
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.notification-item {
|
||||
padding: 16px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.notification-item:hover {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.notification-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.notification-title {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.notification-time {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.notification-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.notification-item.unread .notification-title {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.notification-item.unread::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: #1677ff;
|
||||
border-radius: 50%;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.notification-actions {
|
||||
flex-direction: column;
|
||||
.notifications-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;
|
||||
}
|
||||
|
||||
.notification-list {
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.notification-item {
|
||||
padding: 16px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.notification-item:hover {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.notification-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.notification-title {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.notification-time {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.notification-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.notification-item.unread .notification-title {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.notification-item.unread::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: #1677ff;
|
||||
border-radius: 50%;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.notification-actions {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
layui.use(['element', 'layer'], function(){
|
||||
var element = layui.element;
|
||||
var layer = layui.layer;
|
||||
|
||||
// 加载通知列表
|
||||
function loadNotifications(type) {
|
||||
var container = document.getElementById(type + 'Notifications');
|
||||
container.innerHTML = '<div class="layui-anim layui-anim-upbit layui-anim-loop layui-anim-shrink" style="text-align: center; padding: 20px;"><i class="layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop"></i></div>';
|
||||
|
||||
fetch('/index/user/getNotifications?type=' + type)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if(data.code === 0) {
|
||||
if(data.data.length === 0) {
|
||||
container.innerHTML = '<div class="layui-none">暂无通知</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
var html = '';
|
||||
data.data.forEach(function(notification) {
|
||||
html += `
|
||||
layui.use(['element', 'layer'], function () {
|
||||
var element = layui.element;
|
||||
var layer = layui.layer;
|
||||
|
||||
// 加载通知列表
|
||||
function loadNotifications(type) {
|
||||
var container = document.getElementById(type + 'Notifications');
|
||||
container.innerHTML = '<div class="layui-anim layui-anim-upbit layui-anim-loop layui-anim-shrink" style="text-align: center; padding: 20px;"><i class="layui-icon layui-icon-loading layui-anim layui-anim-rotate layui-anim-loop"></i></div>';
|
||||
|
||||
fetch('/index/user/getNotifications?type=' + type)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.code === 0) {
|
||||
if (data.data.length === 0) {
|
||||
container.innerHTML = '<div class="layui-none">暂无通知</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
var html = '';
|
||||
data.data.forEach(function (notification) {
|
||||
html += `
|
||||
<div class="notification-item ${notification.is_read ? '' : 'unread'}" data-id="${notification.id}">
|
||||
<div class="notification-content">
|
||||
<div class="notification-title">${notification.title}</div>
|
||||
@ -126,85 +125,85 @@ layui.use(['element', 'layer'], function(){
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
container.innerHTML = html;
|
||||
} else {
|
||||
layer.msg(data.msg || '加载失败', {icon: 2});
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
layer.msg('加载失败,请重试', {icon: 2});
|
||||
});
|
||||
}
|
||||
|
||||
// 查看通知
|
||||
window.viewNotification = function(notificationId) {
|
||||
fetch('/index/user/readNotification', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({id: notificationId})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if(data.code === 0) {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '通知详情',
|
||||
area: ['500px', '400px'],
|
||||
content: '/index/user/notificationDetail?id=' + notificationId
|
||||
});
|
||||
container.innerHTML = html;
|
||||
} else {
|
||||
layer.msg(data.msg || '加载失败', { icon: 2 });
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
layer.msg('加载失败,请重试', { icon: 2 });
|
||||
});
|
||||
// 重新加载通知列表
|
||||
loadNotifications('all');
|
||||
loadNotifications('unread');
|
||||
loadNotifications('read');
|
||||
} else {
|
||||
layer.msg(data.msg || '操作失败', {icon: 2});
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
layer.msg('操作失败,请重试', {icon: 2});
|
||||
});
|
||||
}
|
||||
|
||||
// 删除通知
|
||||
window.deleteNotification = function(notificationId) {
|
||||
layer.confirm('确定要删除这条通知吗?', {
|
||||
btn: ['确定','取消']
|
||||
}, function(){
|
||||
fetch('/index/user/deleteNotification', {
|
||||
}
|
||||
|
||||
// 查看通知
|
||||
window.viewNotification = function (notificationId) {
|
||||
fetch('/index/user/readNotification', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({id: notificationId})
|
||||
body: JSON.stringify({ id: notificationId })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if(data.code === 0) {
|
||||
layer.msg('删除成功', {icon: 1});
|
||||
// 重新加载通知列表
|
||||
loadNotifications('all');
|
||||
loadNotifications('unread');
|
||||
loadNotifications('read');
|
||||
} else {
|
||||
layer.msg(data.msg || '删除失败', {icon: 2});
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
layer.msg('删除失败,请重试', {icon: 2});
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.code === 0) {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '通知详情',
|
||||
area: ['500px', '400px'],
|
||||
content: '/index/user/notificationDetail?id=' + notificationId
|
||||
});
|
||||
// 重新加载通知列表
|
||||
loadNotifications('all');
|
||||
loadNotifications('unread');
|
||||
loadNotifications('read');
|
||||
} else {
|
||||
layer.msg(data.msg || '操作失败', { icon: 2 });
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
layer.msg('操作失败,请重试', { icon: 2 });
|
||||
});
|
||||
}
|
||||
|
||||
// 删除通知
|
||||
window.deleteNotification = function (notificationId) {
|
||||
layer.confirm('确定要删除这条通知吗?', {
|
||||
btn: ['确定', '取消']
|
||||
}, function () {
|
||||
fetch('/index/user/deleteNotification', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ id: notificationId })
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.code === 0) {
|
||||
layer.msg('删除成功', { icon: 1 });
|
||||
// 重新加载通知列表
|
||||
loadNotifications('all');
|
||||
loadNotifications('unread');
|
||||
loadNotifications('read');
|
||||
} else {
|
||||
layer.msg(data.msg || '删除失败', { icon: 2 });
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
layer.msg('删除失败,请重试', { icon: 2 });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 监听标签切换
|
||||
element.on('tab(notificationTabs)', function (data) {
|
||||
var type = ['all', 'unread', 'read'][data.index];
|
||||
loadNotifications(type);
|
||||
});
|
||||
}
|
||||
|
||||
// 监听标签切换
|
||||
element.on('tab(notificationTabs)', function(data){
|
||||
var type = ['all', 'unread', 'read'][data.index];
|
||||
loadNotifications(type);
|
||||
|
||||
// 初始加载全部通知
|
||||
loadNotifications('all');
|
||||
});
|
||||
|
||||
// 初始加载全部通知
|
||||
loadNotifications('all');
|
||||
});
|
||||
</script>
|
||||
</script>
|
||||
@ -12,9 +12,9 @@
|
||||
<i class="icon">👤</i>
|
||||
<span>个人资料</span>
|
||||
</a>
|
||||
<a href="javascript:;" class="menu-item" data-target="profile-avatar">
|
||||
<i class="icon">🖼️</i>
|
||||
<span>修改头像</span>
|
||||
<a href="javascript:;" class="menu-item" data-target="profile-wallet">
|
||||
<i class="icon">💰</i>
|
||||
<span>我的钱包</span>
|
||||
</a>
|
||||
<a href="javascript:;" class="menu-item" data-target="profile-messages">
|
||||
<i class="icon">✉️</i>
|
||||
@ -131,6 +131,10 @@
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
font-style: normal;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
||||
86
app/index/view/user/component/wallet.php
Normal file
86
app/index/view/user/component/wallet.php
Normal file
@ -0,0 +1,86 @@
|
||||
<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">
|
||||
<p>您当前的积分余额:<span id="points-balance">0</span></p>
|
||||
</div>
|
||||
<div class="layui-tab-item">
|
||||
<p>您当前的云币余额:<span id="cloud-coins-balance">0</span></p>
|
||||
<p>云币是真钱充值后获得的平台币。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
layui.use(['element'], function () {
|
||||
var element = layui.element;
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
// JavaScript 部分,处理 tab 切换
|
||||
const tabs = document.querySelectorAll('.tab');
|
||||
const contents = document.querySelectorAll('.content-item');
|
||||
|
||||
tabs.forEach(tab => {
|
||||
tab.addEventListener('click', () => {
|
||||
// 移除所有 tab 的 active 类
|
||||
tabs.forEach(t => t.classList.remove('active'));
|
||||
// 给当前点击的 tab 添加 active 类
|
||||
tab.classList.add('active');
|
||||
|
||||
const target = tab.dataset.target;
|
||||
// 隐藏所有内容项
|
||||
contents.forEach(content => {
|
||||
content.classList.remove('active');
|
||||
if (content.id === target) {
|
||||
content.classList.add('active');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<style>
|
||||
/* 样式部分 */
|
||||
.tab-container {
|
||||
display: flex;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.tab {
|
||||
padding: 10px 20px;
|
||||
cursor: pointer;
|
||||
border: 1px solid transparent;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
border-color: #ccc;
|
||||
border-bottom: 1px solid white;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
padding: 20px;
|
||||
border: 1px solid #ccc;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.content-item {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.content-item.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.layui-unselect.layui-tab-bar {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@ -13,9 +13,9 @@
|
||||
{include file="user/component/basic" /}
|
||||
</div>
|
||||
|
||||
<!-- 修改头像 -->
|
||||
<div id="profile-avatar" class="content-section">
|
||||
{include file="user/component/avatar" /}
|
||||
<!-- 我的钱包 -->
|
||||
<div id="profile-wallet" class="content-section">
|
||||
{include file="user/component/wallet" /}
|
||||
</div>
|
||||
|
||||
<!-- 我的消息 -->
|
||||
|
||||
@ -28,7 +28,8 @@
|
||||
"topthink/think-view": "^1.0",
|
||||
"topthink/think-captcha": "^3.0",
|
||||
"phpoffice/phpspreadsheet": "^1.25",
|
||||
"phpmailer/phpmailer": "^6.9"
|
||||
"phpmailer/phpmailer": "^6.9",
|
||||
"overtrue/wechat": "^5.36"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/var-dumper": "^4.2",
|
||||
@ -43,7 +44,10 @@
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"preferred-install": "dist"
|
||||
"preferred-install": "dist",
|
||||
"allow-plugins": {
|
||||
"easywechat-composer/easywechat-composer": true
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"post-autoload-dump": [
|
||||
|
||||
1882
composer.lock
generated
1882
composer.lock
generated
File diff suppressed because it is too large
Load Diff
5
config/wechat.php
Normal file
5
config/wechat.php
Normal file
@ -0,0 +1,5 @@
|
||||
return [
|
||||
'app_id' => env('wechat.app_id'),
|
||||
'secret' => env('wechat.secret'),
|
||||
// 其他配置项...
|
||||
];
|
||||
Loading…
x
Reference in New Issue
Block a user