继续完善前端登录模块
This commit is contained in:
parent
9352fd2a75
commit
b8d3757397
@ -12,6 +12,7 @@ use think\facade\View;
|
|||||||
use think\facade\Env;
|
use think\facade\Env;
|
||||||
use think\facade\Config;
|
use think\facade\Config;
|
||||||
use app\admin\controller\Log;
|
use app\admin\controller\Log;
|
||||||
|
use \think\facade\Filesystem;
|
||||||
|
|
||||||
use app\admin\model\AdminUserGroup;
|
use app\admin\model\AdminUserGroup;
|
||||||
use app\admin\model\AdminSysMenu;
|
use app\admin\model\AdminSysMenu;
|
||||||
@ -358,7 +359,7 @@ class IndexController extends Base{
|
|||||||
])->check($file);
|
])->check($file);
|
||||||
|
|
||||||
// 存储文件到public磁盘的uploads目录
|
// 存储文件到public磁盘的uploads目录
|
||||||
$info = \think\facade\Filesystem::disk('public')->putFile('uploads', $files);
|
$info = Filesystem::disk('public')->putFile('uploads', $files);
|
||||||
|
|
||||||
// 处理文件路径,统一使用正斜杠
|
// 处理文件路径,统一使用正斜杠
|
||||||
$info = str_replace("\\", "/", $info);
|
$info = str_replace("\\", "/", $info);
|
||||||
@ -408,7 +409,7 @@ class IndexController extends Base{
|
|||||||
'file'=>'fileExt:doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,rar,7z'
|
'file'=>'fileExt:doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,rar,7z'
|
||||||
])->check($file);
|
])->check($file);
|
||||||
|
|
||||||
$info = \think\facade\Filesystem::disk('public')->putFile('uploads/files', $files);
|
$info = Filesystem::disk('public')->putFile('uploads/files', $files);
|
||||||
|
|
||||||
// 处理文件路径
|
// 处理文件路径
|
||||||
$info = str_replace("\\", "/", $info);
|
$info = str_replace("\\", "/", $info);
|
||||||
@ -442,7 +443,7 @@ class IndexController extends Base{
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
validate(['video'=>'filesize:102400|fileExt:mp4,avi,mov,wmv,flv'])->check($file);
|
validate(['video'=>'filesize:102400|fileExt:mp4,avi,mov,wmv,flv'])->check($file);
|
||||||
$info = \think\facade\Filesystem::disk('public')->putFile('uploads/videos', $files);
|
$info = Filesystem::disk('public')->putFile('uploads/videos', $files);
|
||||||
|
|
||||||
// 处理文件路径
|
// 处理文件路径
|
||||||
$info = str_replace("\\", "/", $info);
|
$info = str_replace("\\", "/", $info);
|
||||||
@ -474,7 +475,7 @@ class IndexController extends Base{
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
validate(['audio'=>'filesize:51200|fileExt:mp3,wav,ogg,m4a'])->check($file);
|
validate(['audio'=>'filesize:51200|fileExt:mp3,wav,ogg,m4a'])->check($file);
|
||||||
$info = \think\facade\Filesystem::disk('public')->putFile('uploads/audios', $files);
|
$info = Filesystem::disk('public')->putFile('uploads/audios', $files);
|
||||||
|
|
||||||
// 处理文件路径
|
// 处理文件路径
|
||||||
$info = str_replace("\\", "/", $info);
|
$info = str_replace("\\", "/", $info);
|
||||||
|
|||||||
@ -14,6 +14,8 @@ use app\index\model\Articles\ArticlesCategory;
|
|||||||
use app\index\model\Resources\Resources;
|
use app\index\model\Resources\Resources;
|
||||||
use app\index\model\Articles\Articles;
|
use app\index\model\Articles\Articles;
|
||||||
use app\index\model\MailConfig;
|
use app\index\model\MailConfig;
|
||||||
|
use \think\facade\Filesystem;
|
||||||
|
use app\index\model\Attachments;
|
||||||
|
|
||||||
|
|
||||||
class IndexController extends BaseController
|
class IndexController extends BaseController
|
||||||
@ -343,5 +345,66 @@ class IndexController extends BaseController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//保存附件信息到数据库
|
||||||
|
private function saveAttachment($name, $type, $size, $src)
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'name' => $name,
|
||||||
|
'type' => $type,
|
||||||
|
'size' => $size,
|
||||||
|
'src' => $src,
|
||||||
|
'create_time' => time(),
|
||||||
|
'update_time' => time()
|
||||||
|
];
|
||||||
|
return Attachments::insertGetId($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//上传图片接口
|
||||||
|
public function update_imgs()
|
||||||
|
{
|
||||||
|
// 获取上传的文件
|
||||||
|
$file = request()->file();
|
||||||
|
$files = request()->file('file');
|
||||||
|
|
||||||
|
// 检查是否有文件上传
|
||||||
|
if (empty($file)) {
|
||||||
|
return json(['code' => 1, 'msg' => '没有文件上传']);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 验证上传的文件
|
||||||
|
validate([
|
||||||
|
'image' => 'filesize:51200|fileExt:jpg,png,gif,jpeg'
|
||||||
|
])->check($file);
|
||||||
|
|
||||||
|
// 存储文件到public磁盘的uploads目录
|
||||||
|
$info = Filesystem::disk('public')->putFile('uploads', $files);
|
||||||
|
|
||||||
|
// 处理文件路径,统一使用正斜杠
|
||||||
|
$info = str_replace("\\", "/", $info);
|
||||||
|
$img = '/storage/' . $info;
|
||||||
|
|
||||||
|
// 保存附件信息
|
||||||
|
$fileName = $files->getOriginalName();
|
||||||
|
$fileSize = $files->getSize();
|
||||||
|
$attachmentId = $this->saveAttachment($fileName, 1, $fileSize, $img); // 1: 图片
|
||||||
|
|
||||||
|
// 返回成功信息
|
||||||
|
return json([
|
||||||
|
'code' => 0,
|
||||||
|
'data' => [
|
||||||
|
'url' => $img
|
||||||
|
],
|
||||||
|
'msg' => '上传成功'
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (\think\exception\ValidateException $e) {
|
||||||
|
// 捕获验证异常并返回错误信息
|
||||||
|
return json(['code' => 1, 'msg' => $e->getMessage()]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
// 捕获其他异常
|
||||||
|
return json(['code' => 1, 'msg' => '上传失败:' . $e->getMessage()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ namespace app\index\controller;
|
|||||||
use think\Controller;
|
use think\Controller;
|
||||||
use app\index\model\Users;
|
use app\index\model\Users;
|
||||||
use think\facade\Redirect;
|
use think\facade\Redirect;
|
||||||
|
use think\facade\View;
|
||||||
use \think\facade\Log;
|
use \think\facade\Log;
|
||||||
use \think\facade\Cache;
|
use \think\facade\Cache;
|
||||||
use PHPMailer\PHPMailer\PHPMailer;
|
use PHPMailer\PHPMailer\PHPMailer;
|
||||||
@ -48,12 +49,20 @@ class UserController extends BaseController
|
|||||||
session('user_name', $user->name);
|
session('user_name', $user->name);
|
||||||
session('user_avatar', $user->avatar ?? '/static/images/avatar.png');
|
session('user_avatar', $user->avatar ?? '/static/images/avatar.png');
|
||||||
|
|
||||||
|
// 设置cookie,有效期7天
|
||||||
|
$expire = 7 * 24 * 3600;
|
||||||
|
cookie('user_id', $user->id, ['expire' => $expire]);
|
||||||
|
cookie('user_account', $user->account, ['expire' => $expire]);
|
||||||
|
cookie('user_name', $user->name, ['expire' => $expire]);
|
||||||
|
cookie('user_avatar', $user->avatar ?? '/static/images/avatar.png', ['expire' => $expire]);
|
||||||
|
|
||||||
// 记录登录日志
|
// 记录登录日志
|
||||||
Log::record('用户登录成功:' . $user->account, 'info');
|
Log::record('用户登录成功:' . $user->account, 'info');
|
||||||
|
|
||||||
return json(['code' => 0, 'msg' => '登录成功']);
|
return json(['code' => 0, 'msg' => '登录成功']);
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
|
Log::record('登录失败:' . $e->getMessage(), 'error');
|
||||||
return json(['code' => 1, 'msg' => '登录失败:' . $e->getMessage()]);
|
return json(['code' => 1, 'msg' => '登录失败:' . $e->getMessage()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,25 +139,39 @@ class UserController extends BaseController
|
|||||||
*/
|
*/
|
||||||
public function logout()
|
public function logout()
|
||||||
{
|
{
|
||||||
// 增加日志记录,记录用户退出登录操作
|
try {
|
||||||
Log::record('用户退出登录', 'info');
|
// 记录退出日志
|
||||||
|
Log::record('用户退出登录', 'info');
|
||||||
|
|
||||||
// 销毁当前会话中的所有数据
|
// 1. 清除所有 session
|
||||||
session(null);
|
session(null);
|
||||||
|
|
||||||
// 清除缓存中的用户信息
|
// 2. 清除所有 cookie
|
||||||
Cache::tag('user_cache')->clear();
|
// 正确的删除 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]);
|
||||||
|
|
||||||
// 清除cookie
|
// 3. 清除缓存
|
||||||
cookie('user_id', null);
|
Cache::tag('user_cache')->clear();
|
||||||
cookie('user_name', null);
|
|
||||||
cookie('user_avatar', null);
|
|
||||||
cookie('expire_time', null);
|
|
||||||
cookie('is_auto_login', null);
|
|
||||||
cookie('auto_login_attempted', null);
|
|
||||||
|
|
||||||
// 返回成功状态
|
// 4. 返回成功状态,并告诉前端清除 localStorage
|
||||||
return json(['code' => 0, 'msg' => '退出成功']);
|
return json([
|
||||||
|
'code' => 0,
|
||||||
|
'msg' => '退出成功',
|
||||||
|
'data' => [
|
||||||
|
'clear_storage' => true
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::record('退出登录失败:' . $e->getMessage(), 'error');
|
||||||
|
return json(['code' => 1, 'msg' => '退出失败:' . $e->getMessage()]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成随机用户名
|
// 生成随机用户名
|
||||||
@ -276,4 +299,127 @@ class UserController extends BaseController
|
|||||||
return json(['code' => 1, 'msg' => '发送失败:' . $result]);
|
return json(['code' => 1, 'msg' => '发送失败:' . $result]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//个人中心
|
||||||
|
public function profile()
|
||||||
|
{
|
||||||
|
// 检查用户是否登录
|
||||||
|
if (!cookie('user_account')) {
|
||||||
|
return redirect('/index/user/login');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取用户信息
|
||||||
|
$user = Users::where('account', cookie('user_account'))->find();
|
||||||
|
// var_dump($user);
|
||||||
|
if (!$user) {
|
||||||
|
return redirect('/index/user/login');
|
||||||
|
}
|
||||||
|
|
||||||
|
View::assign('user', $user);
|
||||||
|
return $this->fetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveBasic()
|
||||||
|
{
|
||||||
|
// 检查用户是否登录
|
||||||
|
if (!cookie('user_account')) {
|
||||||
|
return json(['code' => 1, 'msg' => '请先登录']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取用户信息
|
||||||
|
$user = Users::where('account', cookie('user_account'))->find();
|
||||||
|
if (!$user) {
|
||||||
|
return json(['code' => 1, 'msg' => '用户不存在']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取表单数据
|
||||||
|
$data = $this->request->post();
|
||||||
|
|
||||||
|
// 验证用户名
|
||||||
|
if (empty($data['name'])) {
|
||||||
|
return json(['code' => 1, 'msg' => '用户名不能为空']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证手机号格式
|
||||||
|
if (!empty($data['phone']) && !preg_match('/^1[3-9]\d{9}$/', $data['phone'])) {
|
||||||
|
return json(['code' => 1, 'msg' => '请检查手机号']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查用户名是否已被使用(排除当前用户)
|
||||||
|
$existingUser = Users::where('name', $data['name'])
|
||||||
|
->where('uid', '<>', $user->uid) // 排除当前用户
|
||||||
|
->find();
|
||||||
|
|
||||||
|
if ($existingUser) {
|
||||||
|
return json(['code' => 1, 'msg' => '该用户名已被使用']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新用户信息
|
||||||
|
$user->name = $data['name'];
|
||||||
|
$user->phone = $data['phone'] ?? '';
|
||||||
|
$user->sex = $data['sex'] ?? 0;
|
||||||
|
$user->qq = $data['qq'] ?? '';
|
||||||
|
$user->update_time = time();
|
||||||
|
|
||||||
|
if ($user->save()) {
|
||||||
|
return json(['code' => 0, 'msg' => '保存成功']);
|
||||||
|
} else {
|
||||||
|
return json(['code' => 1, 'msg' => '保存失败']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//更新头像
|
||||||
|
public function update_avatar()
|
||||||
|
{
|
||||||
|
// 检查用户是否登录
|
||||||
|
if (!cookie('user_account')) {
|
||||||
|
return json(['code' => 1, 'msg' => '请先登录']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取用户信息
|
||||||
|
$user = Users::where('account', cookie('user_account'))->find();
|
||||||
|
if (!$user) {
|
||||||
|
return json(['code' => 1, 'msg' => '用户不存在']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取上传的文件
|
||||||
|
$file = $this->request->file('avatar');
|
||||||
|
if (!$file) {
|
||||||
|
return json(['code' => 1, 'msg' => '请选择要上传的头像']);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 验证文件大小和类型
|
||||||
|
if ($file->getSize() > 2097152) { // 2MB
|
||||||
|
return json(['code' => 1, 'msg' => '图片大小不能超过2MB']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$ext = strtolower($file->getOriginalExtension());
|
||||||
|
if (!in_array($ext, ['jpg', 'jpeg', 'png', 'gif'])) {
|
||||||
|
return json(['code' => 1, 'msg' => '只支持jpg、jpeg、png、gif格式的图片']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移动到指定目录
|
||||||
|
$savename = \think\facade\Filesystem::disk('public')->putFile('avatar', $file);
|
||||||
|
if (!$savename) {
|
||||||
|
return json(['code' => 1, 'msg' => '图片上传失败']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取文件URL
|
||||||
|
$avatarUrl = '/storage/' . $savename;
|
||||||
|
|
||||||
|
// 更新用户头像
|
||||||
|
$user->avatar = $avatarUrl;
|
||||||
|
$user->update_time = time();
|
||||||
|
|
||||||
|
if ($user->save()) {
|
||||||
|
return json(['code' => 0, 'msg' => '头像更新成功', 'data' => ['url' => $avatarUrl]]);
|
||||||
|
} else {
|
||||||
|
return json(['code' => 1, 'msg' => '头像更新失败']);
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return json(['code' => 1, 'msg' => '系统错误:' . $e->getMessage()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,21 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
// 获取当前登录状态
|
// 获取当前登录状态
|
||||||
$isLoggedIn = false;
|
$isLoggedIn = false;
|
||||||
|
$userInfo = [
|
||||||
|
'is_login' => false,
|
||||||
|
'name' => '',
|
||||||
|
'avatar' => '/static/images/avatar.png' // 默认头像
|
||||||
|
];
|
||||||
|
|
||||||
// 检查session
|
// 检查cookie
|
||||||
if (session('user_id')) {
|
$userAccount = cookie('user_account');
|
||||||
|
if ($userAccount) {
|
||||||
$isLoggedIn = true;
|
$isLoggedIn = true;
|
||||||
}
|
$userInfo = [
|
||||||
// 如果session未登录,检查cookie
|
'is_login' => true,
|
||||||
else {
|
'name' => cookie('user_name'),
|
||||||
$userAccount = cookie('user_account');
|
'avatar' => cookie('user_avatar') ? cookie('user_avatar') : '/static/images/avatar.png'
|
||||||
if ($userAccount) {
|
];
|
||||||
// 恢复session
|
|
||||||
session('user_id', cookie('user_id'));
|
|
||||||
session('user_name', cookie('user_name'));
|
|
||||||
session('user_avatar', cookie('user_avatar'));
|
|
||||||
$isLoggedIn = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加一个隐藏的div来存储登录状态
|
// 添加一个隐藏的div来存储登录状态
|
||||||
@ -23,44 +23,13 @@ $loginStatus = [
|
|||||||
'isLoggedIn' => $isLoggedIn,
|
'isLoggedIn' => $isLoggedIn,
|
||||||
'userAccount' => $userAccount ?? ''
|
'userAccount' => $userAccount ?? ''
|
||||||
];
|
];
|
||||||
|
|
||||||
$userInfo = [
|
|
||||||
'is_login' => $isLoggedIn,
|
|
||||||
'name' => session('user_name'),
|
|
||||||
'avatar' => session('user_avatar') ? '/static/uploads/avatar/' . session('user_avatar') : '/static/images/avatar.png'
|
|
||||||
];
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<!-- 添加一个隐藏的div来存储登录状态 -->
|
<!-- 添加一个隐藏的div来存储登录状态 -->
|
||||||
<div id="loginStatus" style="display: none;"
|
<div id="loginStatus" style="display: none;" data-is-logged-in="{$isLoggedIn}" data-user-account="{$userAccount ?? ''}">
|
||||||
data-is-logged-in="{$isLoggedIn}"
|
|
||||||
data-user-account="{$userAccount ?? ''}">
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="display: flex;flex-direction: column;">
|
<div style="display: flex;flex-direction: column;">
|
||||||
<div class="topbar-one">
|
|
||||||
<div class="container">
|
|
||||||
<div style="width: 70%;">
|
|
||||||
<ul class="list-unstyled topbar-one__info">
|
|
||||||
<li class="topbar-one__info__item">
|
|
||||||
<span class="topbar-one__info__icon fas fa-phone-alt" style="margin-right: 10px;"></span>
|
|
||||||
<a href="{$config['admin_phone']}">{$config['admin_phone']}</a>
|
|
||||||
</li>
|
|
||||||
<li class="topbar-one__info__item">
|
|
||||||
<span class="topbar-one__info__icon fas fa-envelope" style="margin-right: 10px;"></span>
|
|
||||||
<a href="mailto:{$config['admin_email']}">{$config['admin_email']}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="topbar-one__social" style="width: 30%;">
|
|
||||||
<a href="javascript:;" class="qrcode-trigger"><i class="layui-icon layui-icon-qrcode"></i> 公众号</a>
|
|
||||||
<div class="qrcode-popup"
|
|
||||||
style="display:none;position:absolute;right:54px;top:32px;background:#fff;padding:10px;box-shadow:0 0 10px rgba(0,0,0,0.1); z-index: 1000;">
|
|
||||||
<img src="{$config['admin_wechat']}" alt="公众号二维码" style="width:180px;height:180px;">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 导航栏 -->
|
<!-- 导航栏 -->
|
||||||
<div class="main-menu">
|
<div class="main-menu">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@ -76,11 +45,16 @@ $userInfo = [
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="main-menu__right">
|
<div class="main-menu__right">
|
||||||
|
<div class="username">
|
||||||
|
<?php if ($userInfo['is_login']): ?>
|
||||||
|
<span class="username-text">{$userInfo.name}</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
<!-- 根据登录状态显示不同的内容 -->
|
<!-- 根据登录状态显示不同的内容 -->
|
||||||
<?php if ($isLoggedIn): ?>
|
<?php if ($isLoggedIn): ?>
|
||||||
<div class="layui-inline" style="position: relative;">
|
<div class="layui-inline" style="position: relative;margin-left:20px;">
|
||||||
<img src="/static/images/avatar.png" class="layui-circle"
|
<img src="{$userInfo.avatar}" class="layui-circle"
|
||||||
style="width: 40px; height: 40px; cursor: pointer;" id="userAvatarSticky">
|
style="width: 40px; height: 40px; cursor: pointer;" id="userAvatarSticky">
|
||||||
<div class="user-dropdown" id="userDropdownSticky">
|
<div class="user-dropdown" id="userDropdownSticky">
|
||||||
<ul>
|
<ul>
|
||||||
@ -127,11 +101,16 @@ $userInfo = [
|
|||||||
</div>
|
</div>
|
||||||
<div class="sticky-nav__right">
|
<div class="sticky-nav__right">
|
||||||
<div class="main-menu__right">
|
<div class="main-menu__right">
|
||||||
|
<div class="username">
|
||||||
|
<?php if ($userInfo['is_login']): ?>
|
||||||
|
<span class="username-text">{$userInfo.name}</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
<!-- 根据登录状态显示不同的内容 -->
|
<!-- 根据登录状态显示不同的内容 -->
|
||||||
<?php if ($isLoggedIn): ?>
|
<?php if ($isLoggedIn): ?>
|
||||||
<div class="layui-inline" style="position: relative;">
|
<div class="layui-inline" style="position: relative;margin-left:20px;">
|
||||||
<img src="/static/images/avatar.png" class="layui-circle"
|
<img src="{$userInfo.avatar}" class="layui-circle"
|
||||||
style="width: 40px; height: 40px; cursor: pointer;" id="userAvatarSticky">
|
style="width: 40px; height: 40px; cursor: pointer;" id="userAvatarSticky">
|
||||||
<div class="user-dropdown" id="userDropdownSticky">
|
<div class="user-dropdown" id="userDropdownSticky">
|
||||||
<ul>
|
<ul>
|
||||||
@ -361,11 +340,21 @@ $userInfo = [
|
|||||||
#test10 [carousel-item]>* {
|
#test10 [carousel-item]>* {
|
||||||
background: none !important;
|
background: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.main-menu__right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// 在页面加载时立即执行
|
// 在页面加载时立即执行
|
||||||
(function() {
|
(function () {
|
||||||
// 检查是否已经刷新过
|
// 检查是否已经刷新过
|
||||||
if (sessionStorage.getItem('has_refreshed') === 'true') {
|
if (sessionStorage.getItem('has_refreshed') === 'true') {
|
||||||
return;
|
return;
|
||||||
@ -453,46 +442,6 @@ $userInfo = [
|
|||||||
// 页面加载时检查自动登录
|
// 页面加载时检查自动登录
|
||||||
checkAutoLogin();
|
checkAutoLogin();
|
||||||
|
|
||||||
// 加载banner数据
|
|
||||||
$.ajax({
|
|
||||||
url: '/index/index/bannerlist',
|
|
||||||
type: 'GET',
|
|
||||||
success: function (res) {
|
|
||||||
if (res.code === 1) {
|
|
||||||
var bannerHtml = '';
|
|
||||||
res.banner.forEach(function (banner) {
|
|
||||||
bannerHtml += '<div>' +
|
|
||||||
'<div class="banner-content">' +
|
|
||||||
'<div class="banner-image">' +
|
|
||||||
'<img src="' + banner.image + '" alt="' + (banner.title || '') + '">' +
|
|
||||||
'</div>' +
|
|
||||||
'<div class="banner-text">' +
|
|
||||||
'<span class="banner-title">' + (banner.title || '') + '</span>' +
|
|
||||||
'<span class="banner-desc">' + (banner.desc || '') + '</span>' +
|
|
||||||
'<a href="' + (banner.url || 'javascript:;') + '" class="banner-slide">' +
|
|
||||||
'<span class="banner-btn">查看详情</span>' +
|
|
||||||
'</a>' +
|
|
||||||
'</div>' +
|
|
||||||
'</div>' +
|
|
||||||
'</div>';
|
|
||||||
});
|
|
||||||
$('#test10 div[carousel-item]').html(bannerHtml);
|
|
||||||
|
|
||||||
// 图片轮播
|
|
||||||
carousel.render({
|
|
||||||
elem: '#test10',
|
|
||||||
width: '100%',
|
|
||||||
height: '100vh',
|
|
||||||
interval: 4000,
|
|
||||||
anim: 'fade',
|
|
||||||
autoplay: true,
|
|
||||||
full: false,
|
|
||||||
arrow: 'hover'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
// 主导航头像
|
// 主导航头像
|
||||||
$("#userAvatarMain").click(function (e) {
|
$("#userAvatarMain").click(function (e) {
|
||||||
|
|||||||
@ -1,21 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
// 获取当前登录状态
|
// 获取当前登录状态
|
||||||
$isLoggedIn = false;
|
$isLoggedIn = false;
|
||||||
|
$userInfo = [
|
||||||
|
'is_login' => false,
|
||||||
|
'name' => '',
|
||||||
|
'avatar' => '/static/images/avatar.png' // 默认头像
|
||||||
|
];
|
||||||
|
|
||||||
// 检查session
|
// 检查cookie
|
||||||
if (session('user_id')) {
|
$userAccount = cookie('user_account');
|
||||||
|
if ($userAccount) {
|
||||||
$isLoggedIn = true;
|
$isLoggedIn = true;
|
||||||
}
|
$userInfo = [
|
||||||
// 如果session未登录,检查cookie
|
'is_login' => true,
|
||||||
else {
|
'name' => cookie('user_name'),
|
||||||
$userAccount = cookie('user_account');
|
'avatar' => cookie('user_avatar') ? cookie('user_avatar') : '/static/images/avatar.png'
|
||||||
if ($userAccount) {
|
];
|
||||||
// 恢复session
|
|
||||||
session('user_id', cookie('user_id'));
|
|
||||||
session('user_name', cookie('user_name'));
|
|
||||||
session('user_avatar', cookie('user_avatar'));
|
|
||||||
$isLoggedIn = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加一个隐藏的div来存储登录状态
|
// 添加一个隐藏的div来存储登录状态
|
||||||
@ -23,12 +23,6 @@ $loginStatus = [
|
|||||||
'isLoggedIn' => $isLoggedIn,
|
'isLoggedIn' => $isLoggedIn,
|
||||||
'userAccount' => $userAccount ?? ''
|
'userAccount' => $userAccount ?? ''
|
||||||
];
|
];
|
||||||
|
|
||||||
$userInfo = [
|
|
||||||
'is_login' => $isLoggedIn,
|
|
||||||
'name' => session('user_name'),
|
|
||||||
'avatar' => session('user_avatar') ? '/static/uploads/avatar/' . session('user_avatar') : '/static/images/avatar.png'
|
|
||||||
];
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<!-- 添加一个隐藏的div来存储登录状态 -->
|
<!-- 添加一个隐藏的div来存储登录状态 -->
|
||||||
@ -74,10 +68,15 @@ $userInfo = [
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="main-menu__right">
|
<div class="main-menu__right">
|
||||||
|
<div class="username">
|
||||||
|
<?php if ($userInfo['is_login']): ?>
|
||||||
|
<span class="username-text">{$userInfo.name}</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
<!-- 根据登录状态显示不同的内容 -->
|
<!-- 根据登录状态显示不同的内容 -->
|
||||||
<?php if ($userInfo['is_login']): ?>
|
<?php if ($userInfo['is_login']): ?>
|
||||||
<div class="layui-inline" style="position: relative;">
|
<div class="layui-inline" style="position: relative;margin-left:20px;">
|
||||||
<img src="{$userInfo.avatar}" class="layui-circle"
|
<img src="{$userInfo.avatar}" class="layui-circle"
|
||||||
style="width: 40px; height: 40px; cursor: pointer;" id="userAvatarMain">
|
style="width: 40px; height: 40px; cursor: pointer;" id="userAvatarMain">
|
||||||
<div class="user-dropdown" id="userDropdownMain">
|
<div class="user-dropdown" id="userDropdownMain">
|
||||||
@ -140,7 +139,7 @@ $userInfo = [
|
|||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
<!-- 根据登录状态显示不同的内容 -->
|
<!-- 根据登录状态显示不同的内容 -->
|
||||||
<?php if ($userInfo['is_login']): ?>
|
<?php if ($userInfo['is_login']): ?>
|
||||||
<div class="layui-inline" style="position: relative;">
|
<div class="layui-inline" style="position: relative;margin-left:20px;">
|
||||||
<img src="{$userInfo.avatar}" class="layui-circle"
|
<img src="{$userInfo.avatar}" class="layui-circle"
|
||||||
style="width: 40px; height: 40px; cursor: pointer;" id="userAvatarSticky">
|
style="width: 40px; height: 40px; cursor: pointer;" id="userAvatarSticky">
|
||||||
<div class="user-dropdown" id="userDropdownSticky">
|
<div class="user-dropdown" id="userDropdownSticky">
|
||||||
@ -371,6 +370,16 @@ $userInfo = [
|
|||||||
#test10 [carousel-item]>* {
|
#test10 [carousel-item]>* {
|
||||||
background: none !important;
|
background: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.main-menu__right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
255
app/index/view/user/component/avatar.php
Normal file
255
app/index/view/user/component/avatar.php
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
<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'].includes(file.type)) {
|
||||||
|
layer.msg('请上传 jpg、png 或 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) {
|
||||||
|
layer.msg('头像上传成功', {icon: 1});
|
||||||
|
// 更新当前头像显示
|
||||||
|
document.getElementById('currentAvatar').src = data.data.url;
|
||||||
|
// 隐藏预览区域
|
||||||
|
document.querySelector('.avatar-preview').style.display = 'none';
|
||||||
|
// 清空文件输入
|
||||||
|
document.getElementById('avatarFile').value = '';
|
||||||
|
} 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>
|
||||||
127
app/index/view/user/component/basic.php
Normal file
127
app/index/view/user/component/basic.php
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
<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-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">手机号</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">
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.layui-form-label {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-input-block {
|
||||||
|
margin-left: 110px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
layui.use(['form', 'layer'], function () {
|
||||||
|
var form = layui.form;
|
||||||
|
var layer = layui.layer;
|
||||||
|
|
||||||
|
// 监听表单提交
|
||||||
|
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; // 阻止表单默认提交
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
310
app/index/view/user/component/messages.php
Normal file
310
app/index/view/user/component/messages.php
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
<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>
|
||||||
|
<div class="layui-tab-item">
|
||||||
|
<div class="message-list" id="unreadMessages">
|
||||||
|
<!-- 未读消息列表 -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-tab-item">
|
||||||
|
<div class="message-list" id="readMessages">
|
||||||
|
<!-- 已读消息列表 -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.messages-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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-tabs {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-list {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-item {
|
||||||
|
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: 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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">
|
||||||
|
<div class="message-title">${message.title}</div>
|
||||||
|
<div class="message-text">${message.content}</div>
|
||||||
|
<div class="message-meta">
|
||||||
|
<span class="message-time">${message.create_time}</span>
|
||||||
|
<div class="message-actions">
|
||||||
|
${!message.is_read ? '<button class="mark-read">标记已读</button>' : ''}
|
||||||
|
<button class="delete-message">删除</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标记已读
|
||||||
|
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', {
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始加载全部消息
|
||||||
|
loadMessages('all');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
210
app/index/view/user/component/notifications.php
Normal file
210
app/index/view/user/component/notifications.php
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
<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>
|
||||||
|
<li>未读通知</li>
|
||||||
|
<li>已读通知</li>
|
||||||
|
</ul>
|
||||||
|
<div class="layui-tab-content">
|
||||||
|
<div class="layui-tab-item layui-show">
|
||||||
|
<div class="notification-list" id="allNotifications"></div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-tab-item">
|
||||||
|
<div class="notification-list" id="unreadNotifications"></div>
|
||||||
|
</div>
|
||||||
|
<div class="layui-tab-item">
|
||||||
|
<div class="notification-list" id="readNotifications"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</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 += `
|
||||||
|
<div class="notification-item ${notification.is_read ? '' : 'unread'}" data-id="${notification.id}">
|
||||||
|
<div class="notification-content">
|
||||||
|
<div class="notification-title">${notification.title}</div>
|
||||||
|
<div class="notification-time">${notification.create_time}</div>
|
||||||
|
</div>
|
||||||
|
<div class="notification-actions">
|
||||||
|
<button class="layui-btn layui-btn-xs" onclick="viewNotification(${notification.id})">查看</button>
|
||||||
|
<button class="layui-btn layui-btn-xs layui-btn-danger" onclick="deleteNotification(${notification.id})">删除</button>
|
||||||
|
</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
|
||||||
|
});
|
||||||
|
// 重新加载通知列表
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始加载全部通知
|
||||||
|
loadNotifications('all');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
111
app/index/view/user/component/password.php
Normal file
111
app/index/view/user/component/password.php
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<div class="password-section">
|
||||||
|
<h2 class="section-title">修改密码</h2>
|
||||||
|
|
||||||
|
<form class="layui-form" lay-filter="passwordForm">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">当前密码</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="password" name="oldPassword" placeholder="请输入当前密码" class="layui-input" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">新密码</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="password" name="newPassword" placeholder="请输入新密码" class="layui-input" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">确认密码</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="password" name="confirmPassword" placeholder="请再次输入新密码" class="layui-input" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<button class="layui-btn" lay-submit lay-filter="savePassword">保存修改</button>
|
||||||
|
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.password-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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-form-label {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-input-block {
|
||||||
|
margin-left: 130px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-form-item {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.layui-form-label {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-input-block {
|
||||||
|
margin-left: 110px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
layui.use(['form', 'layer'], function(){
|
||||||
|
var form = layui.form;
|
||||||
|
var layer = layui.layer;
|
||||||
|
|
||||||
|
// 监听表单提交
|
||||||
|
form.on('submit(savePassword)', function(data){
|
||||||
|
// 验证两次密码是否一致
|
||||||
|
if(data.field.newPassword !== data.field.confirmPassword) {
|
||||||
|
layer.msg('两次输入的密码不一致', {icon: 2});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送AJAX请求修改密码
|
||||||
|
fetch('/index/user/changePassword', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data.field)
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if(data.code === 0) {
|
||||||
|
layer.msg('密码修改成功', {icon: 1});
|
||||||
|
// 清空表单
|
||||||
|
document.querySelector('form').reset();
|
||||||
|
} else {
|
||||||
|
layer.msg(data.msg || '修改失败', {icon: 2});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
layer.msg('修改失败,请重试', {icon: 2});
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
170
app/index/view/user/component/security.php
Normal file
170
app/index/view/user/component/security.php
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
<div class="security-section">
|
||||||
|
<h2 class="section-title">安全设置</h2>
|
||||||
|
|
||||||
|
<form class="layui-form" lay-filter="securityForm">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">登录密码</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<button type="button" class="layui-btn" onclick="changePassword()">修改密码</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">手机绑定</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<div class="phone-info">
|
||||||
|
<span id="phoneNumber">未绑定</span>
|
||||||
|
<button type="button" class="layui-btn layui-btn-primary" onclick="bindPhone()">绑定手机</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">邮箱绑定</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<div class="email-info">
|
||||||
|
<span id="emailAddress">未绑定</span>
|
||||||
|
<button type="button" class="layui-btn layui-btn-primary" onclick="bindEmail()">绑定邮箱</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">两步验证</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="checkbox" name="twoFactor" lay-skin="switch" lay-text="开启|关闭">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.security-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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phone-info, .email-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-form-label {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-input-block {
|
||||||
|
margin-left: 130px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.layui-form-label {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-input-block {
|
||||||
|
margin-left: 110px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
layui.use(['form', 'layer'], function(){
|
||||||
|
var form = layui.form;
|
||||||
|
var layer = layui.layer;
|
||||||
|
|
||||||
|
// 加载用户安全信息
|
||||||
|
loadSecurityInfo();
|
||||||
|
|
||||||
|
// 监听两步验证开关
|
||||||
|
form.on('switch(twoFactor)', function(data){
|
||||||
|
updateTwoFactor(data.elem.checked);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 加载安全信息
|
||||||
|
function loadSecurityInfo() {
|
||||||
|
fetch('/index/user/getSecurityInfo')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if(data.code === 0) {
|
||||||
|
document.getElementById('phoneNumber').textContent = data.data.phone || '未绑定';
|
||||||
|
document.getElementById('emailAddress').textContent = data.data.email || '未绑定';
|
||||||
|
// 设置两步验证开关状态
|
||||||
|
layui.form.val('securityForm', {
|
||||||
|
twoFactor: data.data.twoFactor
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改密码
|
||||||
|
function changePassword() {
|
||||||
|
layer.open({
|
||||||
|
type: 2,
|
||||||
|
title: '修改密码',
|
||||||
|
area: ['500px', '400px'],
|
||||||
|
content: '/index/user/component/password'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绑定手机
|
||||||
|
function bindPhone() {
|
||||||
|
layer.open({
|
||||||
|
type: 2,
|
||||||
|
title: '绑定手机',
|
||||||
|
area: ['500px', '400px'],
|
||||||
|
content: '/index/user/component/bindPhone'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绑定邮箱
|
||||||
|
function bindEmail() {
|
||||||
|
layer.open({
|
||||||
|
type: 2,
|
||||||
|
title: '绑定邮箱',
|
||||||
|
area: ['500px', '400px'],
|
||||||
|
content: '/index/user/component/bindEmail'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新两步验证状态
|
||||||
|
function updateTwoFactor(enabled) {
|
||||||
|
fetch('/index/user/updateTwoFactor', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({enabled: enabled})
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if(data.code === 0) {
|
||||||
|
layer.msg(enabled ? '两步验证已开启' : '两步验证已关闭', {icon: 1});
|
||||||
|
} else {
|
||||||
|
layer.msg(data.msg || '操作失败', {icon: 2});
|
||||||
|
// 恢复开关状态
|
||||||
|
layui.form.val('securityForm', {
|
||||||
|
twoFactor: !enabled
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
layer.msg('操作失败,请重试', {icon: 2});
|
||||||
|
// 恢复开关状态
|
||||||
|
layui.form.val('securityForm', {
|
||||||
|
twoFactor: !enabled
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
109
app/index/view/user/component/settings.php
Normal file
109
app/index/view/user/component/settings.php
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<div class="settings-section">
|
||||||
|
<h2 class="section-title">基本设置</h2>
|
||||||
|
|
||||||
|
<form class="layui-form" lay-filter="settingsForm">
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">用户名</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="text" name="username" value="{$user.username}" class="layui-input" lay-verify="required" placeholder="请输入用户名">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">邮箱</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<input type="email" name="email" value="{$user.email}" class="layui-input" lay-verify="required|email" placeholder="请输入邮箱">
|
||||||
|
</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}" class="layui-input" lay-verify="phone" placeholder="请输入手机号">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<label class="layui-form-label">个人简介</label>
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<textarea name="bio" placeholder="请输入个人简介" class="layui-textarea">{$user.bio}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="layui-form-item">
|
||||||
|
<div class="layui-input-block">
|
||||||
|
<button class="layui-btn" lay-submit lay-filter="saveSettings">保存设置</button>
|
||||||
|
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.settings-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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-form-item {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-form-label {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-input-block {
|
||||||
|
margin-left: 130px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.layui-form-label {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layui-input-block {
|
||||||
|
margin-left: 110px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
layui.use(['form', 'layer'], function(){
|
||||||
|
var form = layui.form;
|
||||||
|
var layer = layui.layer;
|
||||||
|
|
||||||
|
// 监听表单提交
|
||||||
|
form.on('submit(saveSettings)', function(data){
|
||||||
|
fetch('/index/user/updateSettings', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data.field)
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if(data.code === 0) {
|
||||||
|
layer.msg('设置保存成功', {icon: 1});
|
||||||
|
} else {
|
||||||
|
layer.msg(data.msg || '保存失败', {icon: 2});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
layer.msg('保存失败,请重试', {icon: 2});
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
158
app/index/view/user/component/sidebar.php
Normal file
158
app/index/view/user/component/sidebar.php
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
<div class="sidebar">
|
||||||
|
<div class="user-info">
|
||||||
|
<div class="avatar-wrapper">
|
||||||
|
<img src="{$user.avatar|default='/static/images/avatar.png'}" class="avatar" alt="用户头像">
|
||||||
|
</div>
|
||||||
|
<h3 class="username">{$user.name}</h3>
|
||||||
|
<p class="email">{$user.account}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<nav class="menu">
|
||||||
|
<a href="javascript:;" class="menu-item active" data-target="profile-basic">
|
||||||
|
<i class="icon">👤</i>
|
||||||
|
<span>个人资料</span>
|
||||||
|
</a>
|
||||||
|
<a href="javascript:;" class="menu-item" data-target="profile-avatar">
|
||||||
|
<i class="icon">🖼️</i>
|
||||||
|
<span>修改头像</span>
|
||||||
|
</a>
|
||||||
|
<a href="javascript:;" class="menu-item" data-target="profile-password">
|
||||||
|
<i class="icon">🔒</i>
|
||||||
|
<span>修改密码</span>
|
||||||
|
</a>
|
||||||
|
<a href="javascript:;" class="menu-item" data-target="profile-messages">
|
||||||
|
<i class="icon">✉️</i>
|
||||||
|
<span>我的消息</span>
|
||||||
|
</a>
|
||||||
|
<a href="javascript:;" class="menu-item" data-target="profile-notifications">
|
||||||
|
<i class="icon">🔔</i>
|
||||||
|
<span>系统通知</span>
|
||||||
|
</a>
|
||||||
|
<a href="javascript:;" class="menu-item" data-target="profile-settings">
|
||||||
|
<i class="icon">⚙️</i>
|
||||||
|
<span>基本设置</span>
|
||||||
|
</a>
|
||||||
|
<a href="javascript:;" class="menu-item" data-target="profile-security">
|
||||||
|
<i class="icon">🛡️</i>
|
||||||
|
<span>安全设置</span>
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.sidebar {
|
||||||
|
width: 260px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
||||||
|
padding: 24px 0;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info {
|
||||||
|
text-align: center;
|
||||||
|
padding: 0 24px 24px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-wrapper {
|
||||||
|
width: 88px;
|
||||||
|
height: 88px;
|
||||||
|
margin: 0 auto 16px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 50%;
|
||||||
|
object-fit: cover;
|
||||||
|
border: 3px solid #f5f5f5;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.username {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin: 0 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 0 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px 16px;
|
||||||
|
color: #666;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item:hover {
|
||||||
|
background: #f5f7fa;
|
||||||
|
color: #1677ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item.active {
|
||||||
|
background: #e6f4ff;
|
||||||
|
color: #1677ff;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
font-size: 20px;
|
||||||
|
margin-right: 12px;
|
||||||
|
width: 24px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式适配 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.sidebar {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
// 获取当前页面路径
|
||||||
|
const currentPath = window.location.pathname;
|
||||||
|
|
||||||
|
// 移除所有active类
|
||||||
|
document.querySelectorAll('.menu-item').forEach(item => {
|
||||||
|
item.classList.remove('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 为当前页面对应的菜单项添加active类
|
||||||
|
document.querySelectorAll('.menu-item').forEach(item => {
|
||||||
|
if (item.getAttribute('href') === currentPath) {
|
||||||
|
item.classList.add('active');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
120
app/index/view/user/profile.php
Normal file
120
app/index/view/user/profile.php
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
{include file="component/head" /}
|
||||||
|
{include file="component/header-simple" /}
|
||||||
|
|
||||||
|
<div class="profile-container">
|
||||||
|
<div class="profile-sidebar">
|
||||||
|
{include file="user/component/sidebar" /}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="profile-main">
|
||||||
|
<div class="content-area">
|
||||||
|
<!-- 个人资料 -->
|
||||||
|
<div id="profile-basic" class="content-section active">
|
||||||
|
{include file="user/component/basic" /}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 修改头像 -->
|
||||||
|
<div id="profile-avatar" class="content-section">
|
||||||
|
{include file="user/component/avatar" /}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 修改密码 -->
|
||||||
|
<div id="profile-password" class="content-section">
|
||||||
|
{include file="user/component/password" /}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 我的消息 -->
|
||||||
|
<div id="profile-messages" class="content-section">
|
||||||
|
{include file="user/component/messages" /}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 系统通知 -->
|
||||||
|
<div id="profile-notifications" class="content-section">
|
||||||
|
{include file="user/component/notifications" /}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 基本设置 -->
|
||||||
|
<div id="profile-settings" class="content-section">
|
||||||
|
{include file="user/component/settings" /}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 安全设置 -->
|
||||||
|
<div id="profile-security" class="content-section">
|
||||||
|
{include file="user/component/security" /}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.profile-container {
|
||||||
|
display: flex;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 40px auto;
|
||||||
|
gap: 24px;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-sidebar {
|
||||||
|
width: 260px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-main {
|
||||||
|
flex: 1;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
||||||
|
padding: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-section {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-section.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式适配 */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.profile-container {
|
||||||
|
flex-direction: column;
|
||||||
|
margin: 20px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-sidebar {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-main {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const menuItems = document.querySelectorAll('.menu-item');
|
||||||
|
|
||||||
|
menuItems.forEach(item => {
|
||||||
|
item.addEventListener('click', function () {
|
||||||
|
const target = this.getAttribute('data-target');
|
||||||
|
|
||||||
|
// 移除所有active类
|
||||||
|
document.querySelectorAll('.menu-item').forEach(menuItem => {
|
||||||
|
menuItem.classList.remove('active');
|
||||||
|
});
|
||||||
|
document.querySelectorAll('.content-section').forEach(section => {
|
||||||
|
section.classList.remove('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加active类
|
||||||
|
this.classList.add('active');
|
||||||
|
document.getElementById(target).classList.add('active');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{include file="component/foot" /}
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.9 MiB After Width: | Height: | Size: 28 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 71 KiB |
@ -1,4 +1,4 @@
|
|||||||
<?php /*a:5:{s:63:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\articles\detail.php";i:1747711602;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\head.php";i:1747617129;s:71:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\header-simple.php";i:1747705841;s:64:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\footer.php";i:1747617266;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\foot.php";i:1747616844;}*/ ?>
|
<?php /*a:5:{s:63:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\articles\detail.php";i:1747818914;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\head.php";i:1747617129;s:71:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\header-simple.php";i:1748316508;s:64:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\footer.php";i:1747617266;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\foot.php";i:1747616844;}*/ ?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
@ -18,37 +18,43 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<?php
|
||||||
|
// 获取当前登录状态
|
||||||
|
$isLoggedIn = false;
|
||||||
|
$userInfo = [
|
||||||
|
'is_login' => false,
|
||||||
|
'name' => '',
|
||||||
|
'avatar' => '/static/images/avatar.png' // 默认头像
|
||||||
|
];
|
||||||
|
|
||||||
|
// 检查cookie
|
||||||
|
$userAccount = cookie('user_account');
|
||||||
|
if ($userAccount) {
|
||||||
|
$isLoggedIn = true;
|
||||||
|
$userInfo = [
|
||||||
|
'is_login' => true,
|
||||||
|
'name' => cookie('user_name'),
|
||||||
|
'avatar' => cookie('user_avatar') ? cookie('user_avatar') : '/static/images/avatar.png'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加一个隐藏的div来存储登录状态
|
||||||
|
$loginStatus = [
|
||||||
|
'isLoggedIn' => $isLoggedIn,
|
||||||
|
'userAccount' => $userAccount ?? ''
|
||||||
|
];
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!-- 添加一个隐藏的div来存储登录状态 -->
|
||||||
|
<div id="loginStatus" style="display: none;" data-is-logged-in="<?php echo htmlentities((string) $isLoggedIn); ?>" data-user-account="<?php echo isset($userAccount) ? htmlentities((string) $userAccount) : ''; ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
<div style="display: flex;flex-direction: column;">
|
<div style="display: flex;flex-direction: column;">
|
||||||
<div class="topbar-one">
|
|
||||||
<div class="container">
|
|
||||||
<div style="width: 70%;">
|
|
||||||
<ul class="list-unstyled topbar-one__info">
|
|
||||||
<li class="topbar-one__info__item">
|
|
||||||
<span class="topbar-one__info__icon fas fa-phone-alt" style="margin-right: 10px;"></span>
|
|
||||||
<a href="<?php echo htmlentities((string) $config['admin_phone']); ?>"><?php echo htmlentities((string) $config['admin_phone']); ?></a>
|
|
||||||
</li>
|
|
||||||
<li class="topbar-one__info__item">
|
|
||||||
<span class="topbar-one__info__icon fas fa-envelope" style="margin-right: 10px;"></span>
|
|
||||||
<a href="mailto:<?php echo htmlentities((string) $config['admin_email']); ?>"><?php echo htmlentities((string) $config['admin_email']); ?></a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="topbar-one__social" style="width: 30%;">
|
|
||||||
<a href="/index/user/login" class="mr-10"><i class="layui-icon layui-icon-username"></i> 登录</a>
|
|
||||||
<a href="/index/user/register" class="mr-10"><i class="layui-icon layui-icon-user"></i> 注册</a>
|
|
||||||
<a href="javascript:;" class="qrcode-trigger"><i class="layui-icon layui-icon-qrcode"></i> 公众号</a>
|
|
||||||
<div class="qrcode-popup"
|
|
||||||
style="display:none;position:absolute;right:54px;top:32px;background:#fff;padding:10px;box-shadow:0 0 10px rgba(0,0,0,0.1); z-index: 1000;">
|
|
||||||
<img src="<?php echo htmlentities((string) $config['admin_wechat']); ?>" alt="公众号二维码" style="width:180px;height:180px;">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 导航栏 -->
|
<!-- 导航栏 -->
|
||||||
<div class="main-menu">
|
<div class="main-menu">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="main-menu__logo">
|
<div class="main-menu__logo">
|
||||||
<a href="index.html"><img src="/static/images/logo1.png" width="186" alt="Logo"></a>
|
<a href="/index.html"><img src="/static/images/logo1.png" width="186" alt="Logo"></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="main-menu__nav">
|
<div class="main-menu__nav">
|
||||||
<ul class="main-menu__list">
|
<ul class="main-menu__list">
|
||||||
@ -59,27 +65,40 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="main-menu__right">
|
<div class="main-menu__right">
|
||||||
|
<div class="username">
|
||||||
|
<?php if ($userInfo['is_login']): ?>
|
||||||
|
<span class="username-text"><?php echo htmlentities((string) $userInfo['name']); ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
<div class="layui-inline" style="position: relative;">
|
<!-- 根据登录状态显示不同的内容 -->
|
||||||
<img src="/static/images/avatar.webp" class="layui-circle"
|
<?php if ($isLoggedIn): ?>
|
||||||
style="width: 40px; height: 40px; cursor: pointer;" id="userAvatarMain">
|
<div class="layui-inline" style="position: relative;margin-left:20px;">
|
||||||
<div class="user-dropdown" id="userDropdownMain">
|
<img src="<?php echo htmlentities((string) $userInfo['avatar']); ?>" class="layui-circle"
|
||||||
<ul>
|
style="width: 40px; height: 40px; cursor: pointer;" id="userAvatarSticky">
|
||||||
<li>
|
<div class="user-dropdown" id="userDropdownSticky">
|
||||||
<a href="/index/user/profile"><i
|
<ul>
|
||||||
class="layui-icon layui-icon-user"></i><span>个人中心</span></a>
|
<li>
|
||||||
</li>
|
<a href="/index/user/profile"><i
|
||||||
<li>
|
class="layui-icon layui-icon-user"></i><span>个人中心</span></a>
|
||||||
<a href="/index/user/settings"><i
|
</li>
|
||||||
class="layui-icon layui-icon-set"></i><span>账号管理</span></a>
|
<li>
|
||||||
</li>
|
<a href="/index/user/settings"><i
|
||||||
<li>
|
class="layui-icon layui-icon-set"></i><span>账号管理</span></a>
|
||||||
<a href="javascript:;" class="logout-btn"><i
|
</li>
|
||||||
class="layui-icon layui-icon-logout"></i><span>退出登录</span></a>
|
<li>
|
||||||
</li>
|
<a href="javascript:;" class="logout-btn"><i
|
||||||
</ul>
|
class="layui-icon layui-icon-logout"></i><span>退出登录</span></a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<?php else: ?>
|
||||||
|
<div class="layui-inline">
|
||||||
|
<a href="/index/user/login" class="layui-btn layui-btn-normal">登录</a>
|
||||||
|
<a href="/index/user/register" class="layui-btn layui-btn-primary">注册</a>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -90,7 +109,7 @@
|
|||||||
<div class="sticky-nav" style="display: none;">
|
<div class="sticky-nav" style="display: none;">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="sticky-nav__logo">
|
<div class="sticky-nav__logo">
|
||||||
<a href="index.html"><img src="/static/images/logo1.png" width="150" alt="Logo"></a>
|
<a href="/index.html"><img src="/static/images/logo1.png" width="150" alt="Logo"></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="sticky-nav__menu">
|
<div class="sticky-nav__menu">
|
||||||
<ul>
|
<ul>
|
||||||
@ -102,27 +121,40 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="sticky-nav__right">
|
<div class="sticky-nav__right">
|
||||||
<div class="main-menu__right">
|
<div class="main-menu__right">
|
||||||
|
<div class="username">
|
||||||
|
<?php if ($userInfo['is_login']): ?>
|
||||||
|
<span class="username-text"><?php echo htmlentities((string) $userInfo['name']); ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
<div class="layui-inline" style="position: relative;">
|
<!-- 根据登录状态显示不同的内容 -->
|
||||||
<img src="/static/images/avatar.webp" class="layui-circle"
|
<?php if ($isLoggedIn): ?>
|
||||||
style="width: 40px; height: 40px; cursor: pointer;" id="userAvatarSticky">
|
<div class="layui-inline" style="position: relative;margin-left:20px;">
|
||||||
<div class="user-dropdown" id="userDropdownSticky">
|
<img src="<?php echo htmlentities((string) $userInfo['avatar']); ?>" class="layui-circle"
|
||||||
<ul>
|
style="width: 40px; height: 40px; cursor: pointer;" id="userAvatarSticky">
|
||||||
<li>
|
<div class="user-dropdown" id="userDropdownSticky">
|
||||||
<a href="/index/user/profile"><i
|
<ul>
|
||||||
class="layui-icon layui-icon-user"></i><span>个人中心</span></a>
|
<li>
|
||||||
</li>
|
<a href="/index/user/profile"><i
|
||||||
<li>
|
class="layui-icon layui-icon-user"></i><span>个人中心</span></a>
|
||||||
<a href="/index/user/settings"><i
|
</li>
|
||||||
class="layui-icon layui-icon-set"></i><span>账号管理</span></a>
|
<li>
|
||||||
</li>
|
<a href="/index/user/settings"><i
|
||||||
<li>
|
class="layui-icon layui-icon-set"></i><span>账号管理</span></a>
|
||||||
<a href="javascript:;" class="logout-btn"><i
|
</li>
|
||||||
class="layui-icon layui-icon-logout"></i><span>退出登录</span></a>
|
<li>
|
||||||
</li>
|
<a href="javascript:;" class="logout-btn"><i
|
||||||
</ul>
|
class="layui-icon layui-icon-logout"></i><span>退出登录</span></a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<?php else: ?>
|
||||||
|
<div class="layui-inline">
|
||||||
|
<a href="/index/user/login" class="layui-btn layui-btn-normal">登录</a>
|
||||||
|
<a href="/index/user/register" class="layui-btn layui-btn-primary">注册</a>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -328,51 +360,107 @@
|
|||||||
#test10 [carousel-item]>* {
|
#test10 [carousel-item]>* {
|
||||||
background: none !important;
|
background: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.main-menu__right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
// 在页面加载时立即执行
|
||||||
|
(function () {
|
||||||
|
// 检查是否已经刷新过
|
||||||
|
if (sessionStorage.getItem('has_refreshed') === 'true') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查localStorage中是否有用户账号
|
||||||
|
var userAccount = localStorage.getItem('user_account');
|
||||||
|
if (userAccount) {
|
||||||
|
// 同步到cookie
|
||||||
|
document.cookie = "user_account=" + userAccount + "; path=/";
|
||||||
|
|
||||||
|
// 如果有其他必要的数据,也同步到cookie
|
||||||
|
var userId = localStorage.getItem('user_id');
|
||||||
|
var userName = localStorage.getItem('user_name');
|
||||||
|
var userAvatar = localStorage.getItem('user_avatar');
|
||||||
|
|
||||||
|
if (userId) document.cookie = "user_id=" + userId + "; path=/";
|
||||||
|
if (userName) document.cookie = "user_name=" + userName + "; path=/";
|
||||||
|
if (userAvatar) document.cookie = "user_avatar=" + userAvatar + "; path=/";
|
||||||
|
|
||||||
|
// 刷新页面以应用新的cookie,并标记已刷新
|
||||||
|
if (!document.cookie.includes('user_id')) {
|
||||||
|
sessionStorage.setItem('has_refreshed', 'true');
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
layui.use(['carousel', 'form', 'layer'], function () {
|
layui.use(['carousel', 'form', 'layer'], function () {
|
||||||
var carousel = layui.carousel, form = layui.form, layer = layui.layer, $ = layui.$;
|
var carousel = layui.carousel, form = layui.form, layer = layui.layer, $ = layui.$;
|
||||||
|
|
||||||
// 加载banner数据
|
// 检查本地存储并自动登录
|
||||||
$.ajax({
|
function checkAutoLogin() {
|
||||||
url: '/index/index/bannerlist',
|
// 如果已经登录,不再执行自动登录
|
||||||
type: 'GET',
|
if ($('#userAvatarMain').length > 0) {
|
||||||
success: function (res) {
|
return;
|
||||||
if (res.code === 1) {
|
|
||||||
var bannerHtml = '';
|
|
||||||
res.banner.forEach(function (banner) {
|
|
||||||
bannerHtml += '<div>' +
|
|
||||||
'<div class="banner-content">' +
|
|
||||||
'<div class="banner-image">' +
|
|
||||||
'<img src="' + banner.image + '" alt="' + (banner.title || '') + '">' +
|
|
||||||
'</div>' +
|
|
||||||
'<div class="banner-text">' +
|
|
||||||
'<span class="banner-title">' + (banner.title || '') + '</span>' +
|
|
||||||
'<span class="banner-desc">' + (banner.desc || '') + '</span>' +
|
|
||||||
'<a href="' + (banner.url || 'javascript:;') + '" class="banner-slide">' +
|
|
||||||
'<span class="banner-btn">查看详情</span>' +
|
|
||||||
'</a>' +
|
|
||||||
'</div>' +
|
|
||||||
'</div>' +
|
|
||||||
'</div>';
|
|
||||||
});
|
|
||||||
$('#test10 div[carousel-item]').html(bannerHtml);
|
|
||||||
|
|
||||||
// 图片轮播
|
|
||||||
carousel.render({
|
|
||||||
elem: '#test10',
|
|
||||||
width: '100%',
|
|
||||||
height: '100vh',
|
|
||||||
interval: 4000,
|
|
||||||
anim: 'fade',
|
|
||||||
autoplay: true,
|
|
||||||
full: false,
|
|
||||||
arrow: 'hover'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
// 如果已经尝试过自动登录,不再执行
|
||||||
|
if (sessionStorage.getItem('auto_login_attempted') === 'true') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从localStorage获取用户账号
|
||||||
|
var userAccount = localStorage.getItem('user_account');
|
||||||
|
if (userAccount) {
|
||||||
|
// 标记已尝试自动登录
|
||||||
|
sessionStorage.setItem('auto_login_attempted', 'true');
|
||||||
|
|
||||||
|
// 发送自动登录请求
|
||||||
|
$.ajax({
|
||||||
|
url: '/index/user/login',
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
account: userAccount,
|
||||||
|
password: atob(localStorage.getItem('user_password'))
|
||||||
|
},
|
||||||
|
dataType: 'json',
|
||||||
|
success: function (res) {
|
||||||
|
if (res.code === 0) {
|
||||||
|
// 设置cookie
|
||||||
|
document.cookie = "user_id=" + res.data.id + "; path=/";
|
||||||
|
document.cookie = "user_name=" + res.data.name + "; path=/";
|
||||||
|
document.cookie = "user_avatar=" + res.data.avatar + "; path=/";
|
||||||
|
document.cookie = "user_account=" + userAccount + "; path=/";
|
||||||
|
|
||||||
|
// 同时更新localStorage
|
||||||
|
localStorage.setItem('user_id', res.data.id);
|
||||||
|
localStorage.setItem('user_name', res.data.name);
|
||||||
|
localStorage.setItem('user_avatar', res.data.avatar);
|
||||||
|
|
||||||
|
// 登录成功,强制刷新页面
|
||||||
|
window.location.href = window.location.href + '?t=' + new Date().getTime();
|
||||||
|
} else {
|
||||||
|
// 登录失败,清除所有相关存储
|
||||||
|
localStorage.removeItem('user_account');
|
||||||
|
localStorage.removeItem('user_password');
|
||||||
|
sessionStorage.removeItem('auto_login_attempted');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页面加载时检查自动登录
|
||||||
|
checkAutoLogin();
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
// 主导航头像
|
// 主导航头像
|
||||||
@ -406,7 +494,36 @@
|
|||||||
layer.confirm('确定要退出登录吗?', {
|
layer.confirm('确定要退出登录吗?', {
|
||||||
btn: ['确定', '取消']
|
btn: ['确定', '取消']
|
||||||
}, function () {
|
}, function () {
|
||||||
window.location.href = '/index/user/logout';
|
// 先发送退出请求
|
||||||
|
$.ajax({
|
||||||
|
url: '/index/user/logout',
|
||||||
|
type: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
success: function (res) {
|
||||||
|
if (res.code === 0) {
|
||||||
|
// 清除localStorage
|
||||||
|
localStorage.removeItem('user_account');
|
||||||
|
localStorage.removeItem('user_password');
|
||||||
|
localStorage.removeItem('user_id');
|
||||||
|
localStorage.removeItem('user_name');
|
||||||
|
localStorage.removeItem('user_avatar');
|
||||||
|
|
||||||
|
// 清除sessionStorage
|
||||||
|
sessionStorage.removeItem('auto_login_attempted');
|
||||||
|
sessionStorage.removeItem('has_refreshed');
|
||||||
|
|
||||||
|
// 清除cookie
|
||||||
|
document.cookie = "user_id=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||||
|
document.cookie = "user_name=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||||
|
document.cookie = "user_avatar=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||||
|
document.cookie = "user_account=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||||
|
document.cookie = "user_password=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||||
|
|
||||||
|
// 强制刷新页面,不使用缓存
|
||||||
|
window.location.href = window.location.href + '?t=' + new Date().getTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -443,6 +560,62 @@
|
|||||||
popup.addEventListener('mouseleave', function () {
|
popup.addEventListener('mouseleave', function () {
|
||||||
popup.style.display = 'none';
|
popup.style.display = 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
form.on('submit(accountLogin)', function (data) {
|
||||||
|
$.ajax({
|
||||||
|
url: '<?php echo url("index/user/login"); ?>',
|
||||||
|
type: 'POST',
|
||||||
|
data: data.field,
|
||||||
|
dataType: 'json',
|
||||||
|
success: function (res) {
|
||||||
|
if (res.code === 0) {
|
||||||
|
// 存储登录数据,设置7天过期
|
||||||
|
var expireTime = new Date().getTime() + 7 * 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
|
// 设置localStorage
|
||||||
|
localStorage.setItem('user_account', data.field.account);
|
||||||
|
localStorage.setItem('user_password', btoa(data.field.password));
|
||||||
|
localStorage.setItem('expire_time', expireTime);
|
||||||
|
localStorage.setItem('is_auto_login', 'true');
|
||||||
|
|
||||||
|
// 设置cookie
|
||||||
|
document.cookie = "user_id=" + res.data.id + "; path=/";
|
||||||
|
document.cookie = "user_name=" + res.data.name + "; path=/";
|
||||||
|
document.cookie = "user_avatar=" + res.data.avatar + "; path=/";
|
||||||
|
document.cookie = "expire_time=" + expireTime + "; path=/";
|
||||||
|
document.cookie = "is_auto_login=true; path=/";
|
||||||
|
document.cookie = "user_account=" + data.field.account + "; path=/";
|
||||||
|
document.cookie = "user_password=" + btoa(data.field.password) + "; path=/";
|
||||||
|
|
||||||
|
// 设置sessionStorage
|
||||||
|
sessionStorage.setItem('auto_login_attempted', 'true');
|
||||||
|
|
||||||
|
layer.msg('登录成功', {
|
||||||
|
icon: 1,
|
||||||
|
time: 2000,
|
||||||
|
shade: 0.3
|
||||||
|
}, function () {
|
||||||
|
// 获取当前页面URL
|
||||||
|
var currentUrl = window.location.href;
|
||||||
|
|
||||||
|
// 如果当前页面是登录页面,则跳转到首页
|
||||||
|
if (currentUrl.includes('/index/user/login')) {
|
||||||
|
window.location.href = '/index.html';
|
||||||
|
} else {
|
||||||
|
// 否则刷新当前页面
|
||||||
|
window.location.href = currentUrl + '?t=' + new Date().getTime();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
layer.msg(res.msg, {
|
||||||
|
icon: 2,
|
||||||
|
time: 2000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
@ -469,6 +642,15 @@
|
|||||||
<div class="article-content" id="articleContent">
|
<div class="article-content" id="articleContent">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="disclaimers">
|
||||||
|
<div class="disclaimer-item">
|
||||||
|
<div class="disclaimer-title">免责声明:</div>
|
||||||
|
<div class="disclaimer-content">
|
||||||
|
<?php echo $config['disclaimers'] ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="article-tags">
|
<div class="article-tags">
|
||||||
<span class="tag-label">标签:</span>
|
<span class="tag-label">标签:</span>
|
||||||
<div id="articleTags"></div>
|
<div id="articleTags"></div>
|
||||||
@ -615,6 +797,7 @@
|
|||||||
color: #333;
|
color: #333;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-content img {
|
.article-content img {
|
||||||
@ -915,6 +1098,28 @@
|
|||||||
.location-item a {
|
.location-item a {
|
||||||
color: #000 !important;
|
color: #000 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.disclaimers {
|
||||||
|
color: #b1b1b1;
|
||||||
|
width: 80%;
|
||||||
|
margin: 20px auto;
|
||||||
|
margin-bottom: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disclaimer-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disclaimer-content {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disclaimer-content p {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -1074,12 +1279,12 @@
|
|||||||
// 添加点赞状态
|
// 添加点赞状态
|
||||||
likeBtn.classList.add('liked');
|
likeBtn.classList.add('liked');
|
||||||
likeBtn.querySelector('i').style.color = '#f57005';
|
likeBtn.querySelector('i').style.color = '#f57005';
|
||||||
layer.msg('点赞成功', {icon: 1});
|
layer.msg('点赞成功', { icon: 1 });
|
||||||
} else {
|
} else {
|
||||||
// 如果请求失败,恢复按钮状态
|
// 如果请求失败,恢复按钮状态
|
||||||
likeBtn.style.pointerEvents = 'auto';
|
likeBtn.style.pointerEvents = 'auto';
|
||||||
likeBtn.style.cursor = 'pointer';
|
likeBtn.style.cursor = 'pointer';
|
||||||
layer.msg('点赞失败:' + data.msg, {icon: 2});
|
layer.msg('点赞失败:' + data.msg, { icon: 2 });
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
@ -1087,7 +1292,7 @@
|
|||||||
likeBtn.style.pointerEvents = 'auto';
|
likeBtn.style.pointerEvents = 'auto';
|
||||||
likeBtn.style.cursor = 'pointer';
|
likeBtn.style.cursor = 'pointer';
|
||||||
console.error('点赞请求失败:', error);
|
console.error('点赞请求失败:', error);
|
||||||
layer.msg('点赞失败,请稍后重试', {icon: 2});
|
layer.msg('点赞失败,请稍后重试', { icon: 2 });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
<?php /*a:4:{s:59:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\index\index.php";i:1746865108;s:64:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\header.php";i:1747445574;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\main.php";i:1747646542;s:64:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\footer.php";i:1747617266;}*/ ?>
|
<?php /*a:4:{s:59:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\index\index.php";i:1746865108;s:64:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\header.php";i:1748316235;s:62:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\main.php";i:1747817496;s:64:"E:\Demos\DemoOwns\PHP\yunzer\app\index\view\component\footer.php";i:1747617266;}*/ ?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
@ -16,7 +16,38 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div style="display: flex;flex-direction: column;">
|
<?php
|
||||||
|
// 获取当前登录状态
|
||||||
|
$isLoggedIn = false;
|
||||||
|
$userInfo = [
|
||||||
|
'is_login' => false,
|
||||||
|
'name' => '',
|
||||||
|
'avatar' => '/static/images/avatar.png' // 默认头像
|
||||||
|
];
|
||||||
|
|
||||||
|
// 检查cookie
|
||||||
|
$userAccount = cookie('user_account');
|
||||||
|
if ($userAccount) {
|
||||||
|
$isLoggedIn = true;
|
||||||
|
$userInfo = [
|
||||||
|
'is_login' => true,
|
||||||
|
'name' => cookie('user_name'),
|
||||||
|
'avatar' => cookie('user_avatar') ? cookie('user_avatar') : '/static/images/avatar.png'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加一个隐藏的div来存储登录状态
|
||||||
|
$loginStatus = [
|
||||||
|
'isLoggedIn' => $isLoggedIn,
|
||||||
|
'userAccount' => $userAccount ?? ''
|
||||||
|
];
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!-- 添加一个隐藏的div来存储登录状态 -->
|
||||||
|
<div id="loginStatus" style="display: none;" data-is-logged-in="<?php echo htmlentities((string) $isLoggedIn); ?>" data-user-account="<?php echo isset($userAccount) ? htmlentities((string) $userAccount) : ''; ?>">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="display: flex;flex-direction: column;">
|
||||||
<div class="topbar-one">
|
<div class="topbar-one">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div style="width: 70%;">
|
<div style="width: 70%;">
|
||||||
@ -32,8 +63,6 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="topbar-one__social" style="width: 30%;">
|
<div class="topbar-one__social" style="width: 30%;">
|
||||||
<a href="/index/user/login" class="mr-10"><i class="layui-icon layui-icon-username"></i> 登录</a>
|
|
||||||
<a href="/index/user/register" class="mr-10"><i class="layui-icon layui-icon-user"></i> 注册</a>
|
|
||||||
<a href="javascript:;" class="qrcode-trigger"><i class="layui-icon layui-icon-qrcode"></i> 公众号</a>
|
<a href="javascript:;" class="qrcode-trigger"><i class="layui-icon layui-icon-qrcode"></i> 公众号</a>
|
||||||
<div class="qrcode-popup"
|
<div class="qrcode-popup"
|
||||||
style="display:none;position:absolute;right:54px;top:32px;background:#fff;padding:10px;box-shadow:0 0 10px rgba(0,0,0,0.1); z-index: 1000;">
|
style="display:none;position:absolute;right:54px;top:32px;background:#fff;padding:10px;box-shadow:0 0 10px rgba(0,0,0,0.1); z-index: 1000;">
|
||||||
@ -57,27 +86,40 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="main-menu__right">
|
<div class="main-menu__right">
|
||||||
|
<div class="username">
|
||||||
|
<?php if ($userInfo['is_login']): ?>
|
||||||
|
<span class="username-text"><?php echo htmlentities((string) $userInfo['name']); ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
<div class="layui-inline" style="position: relative;">
|
<!-- 根据登录状态显示不同的内容 -->
|
||||||
<img src="/static/images/avatar.webp" class="layui-circle"
|
<?php if ($userInfo['is_login']): ?>
|
||||||
style="width: 40px; height: 40px; cursor: pointer;" id="userAvatarMain">
|
<div class="layui-inline" style="position: relative;margin-left:20px;">
|
||||||
<div class="user-dropdown" id="userDropdownMain">
|
<img src="<?php echo htmlentities((string) $userInfo['avatar']); ?>" class="layui-circle"
|
||||||
<ul>
|
style="width: 40px; height: 40px; cursor: pointer;" id="userAvatarMain">
|
||||||
<li>
|
<div class="user-dropdown" id="userDropdownMain">
|
||||||
<a href="/index/user/profile"><i
|
<ul>
|
||||||
class="layui-icon layui-icon-user"></i><span>个人中心</span></a>
|
<li>
|
||||||
</li>
|
<a href="/index/user/profile"><i
|
||||||
<li>
|
class="layui-icon layui-icon-user"></i><span>个人中心</span></a>
|
||||||
<a href="/index/user/settings"><i
|
</li>
|
||||||
class="layui-icon layui-icon-set"></i><span>账号管理</span></a>
|
<li>
|
||||||
</li>
|
<a href="/index/user/settings"><i
|
||||||
<li>
|
class="layui-icon layui-icon-set"></i><span>账号管理</span></a>
|
||||||
<a href="javascript:;" class="logout-btn"><i
|
</li>
|
||||||
class="layui-icon layui-icon-logout"></i><span>退出登录</span></a>
|
<li>
|
||||||
</li>
|
<a href="javascript:;" class="logout-btn"><i
|
||||||
</ul>
|
class="layui-icon layui-icon-logout"></i><span>退出登录</span></a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<?php else: ?>
|
||||||
|
<div class="layui-inline">
|
||||||
|
<a href="/index/user/login" class="layui-btn layui-btn-normal">登录</a>
|
||||||
|
<a href="/index/user/register" class="layui-btn layui-btn-primary">注册</a>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -107,27 +149,40 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="sticky-nav__right">
|
<div class="sticky-nav__right">
|
||||||
<div class="main-menu__right">
|
<div class="main-menu__right">
|
||||||
|
<div class="username">
|
||||||
|
<?php if ($userInfo['is_login']): ?>
|
||||||
|
<span class="username-text"><?php echo htmlentities((string) $userInfo['name']); ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
<div class="layui-inline">
|
<div class="layui-inline">
|
||||||
<div class="layui-inline" style="position: relative;">
|
<!-- 根据登录状态显示不同的内容 -->
|
||||||
<img src="/static/images/avatar.webp" class="layui-circle"
|
<?php if ($userInfo['is_login']): ?>
|
||||||
style="width: 40px; height: 40px; cursor: pointer;" id="userAvatarSticky">
|
<div class="layui-inline" style="position: relative;margin-left:20px;">
|
||||||
<div class="user-dropdown" id="userDropdownSticky">
|
<img src="<?php echo htmlentities((string) $userInfo['avatar']); ?>" class="layui-circle"
|
||||||
<ul>
|
style="width: 40px; height: 40px; cursor: pointer;" id="userAvatarSticky">
|
||||||
<li>
|
<div class="user-dropdown" id="userDropdownSticky">
|
||||||
<a href="/index/user/profile"><i
|
<ul>
|
||||||
class="layui-icon layui-icon-user"></i><span>个人中心</span></a>
|
<li>
|
||||||
</li>
|
<a href="/index/user/profile"><i
|
||||||
<li>
|
class="layui-icon layui-icon-user"></i><span>个人中心</span></a>
|
||||||
<a href="/index/user/settings"><i
|
</li>
|
||||||
class="layui-icon layui-icon-set"></i><span>账号管理</span></a>
|
<li>
|
||||||
</li>
|
<a href="/index/user/settings"><i
|
||||||
<li>
|
class="layui-icon layui-icon-set"></i><span>账号管理</span></a>
|
||||||
<a href="javascript:;" class="logout-btn"><i
|
</li>
|
||||||
class="layui-icon layui-icon-logout"></i><span>退出登录</span></a>
|
<li>
|
||||||
</li>
|
<a href="javascript:;" class="logout-btn"><i
|
||||||
</ul>
|
class="layui-icon layui-icon-logout"></i><span>退出登录</span></a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<?php else: ?>
|
||||||
|
<div class="layui-inline">
|
||||||
|
<a href="/index/user/login" class="layui-btn layui-btn-normal">登录</a>
|
||||||
|
<a href="/index/user/register" class="layui-btn layui-btn-primary">注册</a>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -333,12 +388,108 @@
|
|||||||
#test10 [carousel-item]>* {
|
#test10 [carousel-item]>* {
|
||||||
background: none !important;
|
background: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.main-menu__right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
// 在页面加载时立即执行
|
||||||
|
(function () {
|
||||||
|
// 检查是否已经刷新过
|
||||||
|
if (sessionStorage.getItem('has_refreshed') === 'true') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查localStorage中是否有用户账号
|
||||||
|
var userAccount = localStorage.getItem('user_account');
|
||||||
|
if (userAccount) {
|
||||||
|
// 同步到cookie
|
||||||
|
document.cookie = "user_account=" + userAccount + "; path=/";
|
||||||
|
|
||||||
|
// 如果有其他必要的数据,也同步到cookie
|
||||||
|
var userId = localStorage.getItem('user_id');
|
||||||
|
var userName = localStorage.getItem('user_name');
|
||||||
|
var userAvatar = localStorage.getItem('user_avatar');
|
||||||
|
|
||||||
|
if (userId) document.cookie = "user_id=" + userId + "; path=/";
|
||||||
|
if (userName) document.cookie = "user_name=" + userName + "; path=/";
|
||||||
|
if (userAvatar) document.cookie = "user_avatar=" + userAvatar + "; path=/";
|
||||||
|
|
||||||
|
// 刷新页面以应用新的cookie,并标记已刷新
|
||||||
|
if (!document.cookie.includes('user_id')) {
|
||||||
|
sessionStorage.setItem('has_refreshed', 'true');
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
layui.use(['carousel', 'form', 'layer'], function () {
|
layui.use(['carousel', 'form', 'layer'], function () {
|
||||||
var carousel = layui.carousel, form = layui.form, layer = layui.layer, $ = layui.$;
|
var carousel = layui.carousel, form = layui.form, layer = layui.layer, $ = layui.$;
|
||||||
|
|
||||||
|
// 检查本地存储并自动登录
|
||||||
|
function checkAutoLogin() {
|
||||||
|
// 如果已经登录,不再执行自动登录
|
||||||
|
if ($('#userAvatarMain').length > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果已经尝试过自动登录,不再执行
|
||||||
|
if (sessionStorage.getItem('auto_login_attempted') === 'true') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从localStorage获取用户账号
|
||||||
|
var userAccount = localStorage.getItem('user_account');
|
||||||
|
if (userAccount) {
|
||||||
|
// 标记已尝试自动登录
|
||||||
|
sessionStorage.setItem('auto_login_attempted', 'true');
|
||||||
|
|
||||||
|
// 发送自动登录请求
|
||||||
|
$.ajax({
|
||||||
|
url: '/index/user/login',
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
account: userAccount,
|
||||||
|
password: atob(localStorage.getItem('user_password'))
|
||||||
|
},
|
||||||
|
dataType: 'json',
|
||||||
|
success: function (res) {
|
||||||
|
if (res.code === 0) {
|
||||||
|
// 设置cookie
|
||||||
|
document.cookie = "user_id=" + res.data.id + "; path=/";
|
||||||
|
document.cookie = "user_name=" + res.data.name + "; path=/";
|
||||||
|
document.cookie = "user_avatar=" + res.data.avatar + "; path=/";
|
||||||
|
document.cookie = "user_account=" + userAccount + "; path=/";
|
||||||
|
|
||||||
|
// 同时更新localStorage
|
||||||
|
localStorage.setItem('user_id', res.data.id);
|
||||||
|
localStorage.setItem('user_name', res.data.name);
|
||||||
|
localStorage.setItem('user_avatar', res.data.avatar);
|
||||||
|
|
||||||
|
// 登录成功,强制刷新页面
|
||||||
|
window.location.href = window.location.href + '?t=' + new Date().getTime();
|
||||||
|
} else {
|
||||||
|
// 登录失败,清除所有相关存储
|
||||||
|
localStorage.removeItem('user_account');
|
||||||
|
localStorage.removeItem('user_password');
|
||||||
|
sessionStorage.removeItem('auto_login_attempted');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页面加载时检查自动登录
|
||||||
|
checkAutoLogin();
|
||||||
|
|
||||||
// 加载banner数据
|
// 加载banner数据
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '/index/index/bannerlist',
|
url: '/index/index/bannerlist',
|
||||||
@ -411,7 +562,36 @@
|
|||||||
layer.confirm('确定要退出登录吗?', {
|
layer.confirm('确定要退出登录吗?', {
|
||||||
btn: ['确定', '取消']
|
btn: ['确定', '取消']
|
||||||
}, function () {
|
}, function () {
|
||||||
window.location.href = '/index/user/logout';
|
// 先发送退出请求
|
||||||
|
$.ajax({
|
||||||
|
url: '/index/user/logout',
|
||||||
|
type: 'POST',
|
||||||
|
dataType: 'json',
|
||||||
|
success: function (res) {
|
||||||
|
if (res.code === 0) {
|
||||||
|
// 清除localStorage
|
||||||
|
localStorage.removeItem('user_account');
|
||||||
|
localStorage.removeItem('user_password');
|
||||||
|
localStorage.removeItem('user_id');
|
||||||
|
localStorage.removeItem('user_name');
|
||||||
|
localStorage.removeItem('user_avatar');
|
||||||
|
|
||||||
|
// 清除sessionStorage
|
||||||
|
sessionStorage.removeItem('auto_login_attempted');
|
||||||
|
sessionStorage.removeItem('has_refreshed');
|
||||||
|
|
||||||
|
// 清除cookie
|
||||||
|
document.cookie = "user_id=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||||
|
document.cookie = "user_name=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||||
|
document.cookie = "user_avatar=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||||
|
document.cookie = "user_account=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||||
|
document.cookie = "user_password=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||||
|
|
||||||
|
// 强制刷新页面,不使用缓存
|
||||||
|
window.location.href = window.location.href + '?t=' + new Date().getTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -448,6 +628,62 @@
|
|||||||
popup.addEventListener('mouseleave', function () {
|
popup.addEventListener('mouseleave', function () {
|
||||||
popup.style.display = 'none';
|
popup.style.display = 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
form.on('submit(accountLogin)', function (data) {
|
||||||
|
$.ajax({
|
||||||
|
url: '<?php echo url("index/user/login"); ?>',
|
||||||
|
type: 'POST',
|
||||||
|
data: data.field,
|
||||||
|
dataType: 'json',
|
||||||
|
success: function (res) {
|
||||||
|
if (res.code === 0) {
|
||||||
|
// 存储登录数据,设置7天过期
|
||||||
|
var expireTime = new Date().getTime() + 7 * 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
|
// 设置localStorage
|
||||||
|
localStorage.setItem('user_account', data.field.account);
|
||||||
|
localStorage.setItem('user_password', btoa(data.field.password));
|
||||||
|
localStorage.setItem('expire_time', expireTime);
|
||||||
|
localStorage.setItem('is_auto_login', 'true');
|
||||||
|
|
||||||
|
// 设置cookie
|
||||||
|
document.cookie = "user_id=" + res.data.id + "; path=/";
|
||||||
|
document.cookie = "user_name=" + res.data.name + "; path=/";
|
||||||
|
document.cookie = "user_avatar=" + res.data.avatar + "; path=/";
|
||||||
|
document.cookie = "expire_time=" + expireTime + "; path=/";
|
||||||
|
document.cookie = "is_auto_login=true; path=/";
|
||||||
|
document.cookie = "user_account=" + data.field.account + "; path=/";
|
||||||
|
document.cookie = "user_password=" + btoa(data.field.password) + "; path=/";
|
||||||
|
|
||||||
|
// 设置sessionStorage
|
||||||
|
sessionStorage.setItem('auto_login_attempted', 'true');
|
||||||
|
|
||||||
|
layer.msg('登录成功', {
|
||||||
|
icon: 1,
|
||||||
|
time: 2000,
|
||||||
|
shade: 0.3
|
||||||
|
}, function () {
|
||||||
|
// 获取当前页面URL,如果是从其他页面跳转来的,则返回上一页
|
||||||
|
var currentUrl = window.location.href;
|
||||||
|
var referrer = document.referrer;
|
||||||
|
|
||||||
|
// 如果是从登录页面跳转来的,则返回上一页
|
||||||
|
if (referrer && referrer.includes('/index/user/login')) {
|
||||||
|
window.location.href = referrer;
|
||||||
|
} else {
|
||||||
|
// 否则刷新当前页面
|
||||||
|
window.location.href = currentUrl + '?t=' + new Date().getTime();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
layer.msg(res.msg, {
|
||||||
|
icon: 2,
|
||||||
|
time: 2000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<main class="main-content">
|
<main class="main-content">
|
||||||
@ -536,6 +772,27 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 游戏下载模块 -->
|
||||||
|
<div class="core-block core-module" id="gameDownload" style="order: 3;">
|
||||||
|
<div class="module-header">
|
||||||
|
<div>
|
||||||
|
<div class="ModuleTitle_titleWrapper">
|
||||||
|
<h3 class="ModuleTitle_title">游戏下载</h3>
|
||||||
|
<div class="tab-container">
|
||||||
|
<div class="tab-header">
|
||||||
|
<div class="tab-item active" data-tab="all">全部</div>
|
||||||
|
<!-- 分类标签将通过JavaScript动态加载 -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="more-btn">更多</div>
|
||||||
|
</div>
|
||||||
|
<div class="product-list" id="gameDownloadList">
|
||||||
|
<!-- 游戏将通过JavaScript动态加载 -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
@ -656,6 +913,32 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 加载游戏下载
|
||||||
|
function loadGames() {
|
||||||
|
fetch('/index/index/gameList')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(result => {
|
||||||
|
if (result.code === 0) {
|
||||||
|
// 渲染分类标签
|
||||||
|
if (result.data.categories) {
|
||||||
|
renderCategoryTabs(result.data.categories, 'gameDownload');
|
||||||
|
}
|
||||||
|
// 渲染游戏列表
|
||||||
|
if (result.data.games && result.data.games.length > 0) {
|
||||||
|
renderGames(result.data.games, 'gameDownloadList');
|
||||||
|
} else {
|
||||||
|
showNoData('gameDownloadList');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showNoData('gameDownloadList');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('请求失败:', error);
|
||||||
|
showError('gameDownloadList');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 显示无数据提示
|
// 显示无数据提示
|
||||||
function showNoData(containerId) {
|
function showNoData(containerId) {
|
||||||
document.getElementById(containerId).innerHTML = '<div class="no-data">暂无数据</div>';
|
document.getElementById(containerId).innerHTML = '<div class="no-data">暂无数据</div>';
|
||||||
@ -718,6 +1001,9 @@
|
|||||||
case 'programDownload':
|
case 'programDownload':
|
||||||
loadCategoryPrograms(selectedCategoryId, 'programDownloadList');
|
loadCategoryPrograms(selectedCategoryId, 'programDownloadList');
|
||||||
break;
|
break;
|
||||||
|
case 'gameDownload':
|
||||||
|
loadCategoryGames(selectedCategoryId, 'gameDownloadList');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -958,12 +1244,71 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 渲染游戏列表
|
||||||
|
function renderGames(games, containerId) {
|
||||||
|
const container = document.getElementById(containerId);
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
let html = '';
|
||||||
|
if (Array.isArray(games)) {
|
||||||
|
games.forEach(game => {
|
||||||
|
html += createGameHtml(game);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
container.innerHTML = html || '<div class="no-data">暂无数据</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建游戏HTML
|
||||||
|
function createGameHtml(game) {
|
||||||
|
if (!game) return '';
|
||||||
|
|
||||||
|
return `
|
||||||
|
<div class="opencourse product-item" onclick="window.open('/index/game/detail?id=${game.id || ''}', '_blank')">
|
||||||
|
<div class="video">
|
||||||
|
<img src="${game.icon || '/static/images/default-game.png'}" alt="" class="cover">
|
||||||
|
</div>
|
||||||
|
<div class="introduction">
|
||||||
|
<div class="title">${game.title || '无标题'}</div>
|
||||||
|
<div class="publishdate">${game.create_time || ''}</div>
|
||||||
|
</div>
|
||||||
|
<div class="bottom">
|
||||||
|
<div class="views"><i class="fa-solid fa-eye"></i><span style="margin-left: 5px;">${game.views || 0}</span></div>
|
||||||
|
<div class="author"><i class="fa-regular fa-user"></i><span style="margin-left: 5px;">${game.uploader || '未知作者'}</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载分类游戏
|
||||||
|
function loadCategoryGames(categoryId, containerId) {
|
||||||
|
fetch('/index/index/gameList')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(result => {
|
||||||
|
if (result.code === 0) {
|
||||||
|
if (categoryId === 'all') {
|
||||||
|
renderGames(result.data.games, containerId);
|
||||||
|
} else {
|
||||||
|
const filteredGames = result.data.games.filter(game => game.cate == categoryId);
|
||||||
|
renderGames(filteredGames, containerId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showNoData(containerId);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('请求失败:', error);
|
||||||
|
showError(containerId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 页面加载完成后执行
|
// 页面加载完成后执行
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
loadWebArticles();
|
loadWebArticles();
|
||||||
loadTechArticles();
|
loadTechArticles();
|
||||||
loadResources();
|
loadResources();
|
||||||
loadPrograms();
|
loadPrograms();
|
||||||
|
loadGames();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<footer class="footer" style="background-image: url(/static/images/footer-bg-1.png)">
|
<footer class="footer" style="background-image: url(/static/images/footer-bg-1.png)">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user