first commit
This commit is contained in:
116
app/index/controller/Ajax.php
Normal file
116
app/index/controller/Ajax.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
// +----------------------------------------------------------------------
|
||||
// | swiftAdmin 极速开发框架 [基于WebMan开发]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
|
||||
// +----------------------------------------------------------------------
|
||||
// | swiftAdmin.net High Speed Development Framework
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\index\controller;
|
||||
|
||||
use app\common\library\Email;
|
||||
use app\common\library\Sms;
|
||||
use app\common\model\system\User;
|
||||
use app\HomeController;
|
||||
use support\Response;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
|
||||
/**
|
||||
* Ajax控制器
|
||||
* @ 异步调用
|
||||
*/
|
||||
class Ajax extends HomeController
|
||||
{
|
||||
/**
|
||||
* 首页
|
||||
*/
|
||||
public function index(): Response
|
||||
{
|
||||
return \response('Hello SWIFT!', 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送短信
|
||||
* @return mixed|void
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function smsSend()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
|
||||
$mobile = input('mobile');
|
||||
$event = input('event', 'register');
|
||||
|
||||
if (!is_mobile($mobile)) {
|
||||
return $this->error('手机号码不正确');
|
||||
}
|
||||
|
||||
$sms = Sms::instance();
|
||||
$data = $sms->getLast($mobile);
|
||||
if ($data && (time() - strtotime($data['create_time'])) < 60) {
|
||||
return $this->error(__('发送频繁'));
|
||||
}
|
||||
|
||||
$userinfo = User::getByMobile($mobile);
|
||||
if (in_array($event, ['register', 'changer']) && $userinfo) {
|
||||
return $this->error('当前手机号已被占用');
|
||||
} else if ($event == 'forgot' && !$userinfo) {
|
||||
return $this->error('当前手机号未注册');
|
||||
}
|
||||
|
||||
if ($sms->send($mobile, $event)) {
|
||||
return $this->success("验证码发送成功!");
|
||||
} else {
|
||||
return $this->error($sms->getError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送邮件
|
||||
* @return mixed|void
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function emailSend()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
|
||||
$email = input('email');
|
||||
$event = input('event', 'register');
|
||||
|
||||
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
return $this->error('邮件格式不正确');
|
||||
}
|
||||
|
||||
$Ems = Email::instance();
|
||||
$data = $Ems->getLast($email);
|
||||
|
||||
if ($data && (time() - strtotime($data['create_time'])) < 60) {
|
||||
return $this->error(__('发送频繁'));
|
||||
}
|
||||
|
||||
$userinfo = User::getByEmail($email);
|
||||
if (in_array($event, ['register', 'changer']) && $userinfo) {
|
||||
return $this->error('当前邮箱已被注册');
|
||||
} else if ($event == 'forgot' && !$userinfo) {
|
||||
return $this->error('当前邮箱不存在');
|
||||
}
|
||||
|
||||
if ($Ems->captcha($email, $event)->send()) {
|
||||
return $this->success("验证码发送成功!");
|
||||
} else {
|
||||
return $this->error($Ems->getError());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
app/index/controller/Index.php
Normal file
30
app/index/controller/Index.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
// +----------------------------------------------------------------------
|
||||
// | swiftAdmin 极速开发框架 [基于WebMan开发]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
|
||||
// +----------------------------------------------------------------------
|
||||
// | swiftAdmin.net High Speed Development Framework
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\index\controller;
|
||||
|
||||
use app\HomeController;
|
||||
use Psr\SimpleCache\InvalidArgumentException;
|
||||
use support\Response;
|
||||
|
||||
class Index extends HomeController
|
||||
{
|
||||
/**
|
||||
* 前端首页
|
||||
* @return Response
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function index(): \support\Response
|
||||
{
|
||||
return $this->view('index/index', ['name' => 'meystack']);
|
||||
}
|
||||
}
|
||||
|
||||
286
app/index/controller/Third.php
Normal file
286
app/index/controller/Third.php
Normal file
@@ -0,0 +1,286 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
// +----------------------------------------------------------------------
|
||||
// | swiftAdmin 极速开发框架 [基于WebMan开发]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
|
||||
// +----------------------------------------------------------------------
|
||||
// | swiftAdmin.net High Speed Development Framework
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\index\controller;
|
||||
|
||||
use app\common\library\Auth;
|
||||
use app\common\library\ResultCode;
|
||||
use app\HomeController;
|
||||
use app\common\model\system\User;
|
||||
use app\common\model\system\UserThird;
|
||||
use support\Response;
|
||||
use system\Random;
|
||||
|
||||
/**
|
||||
* 社会化登录
|
||||
* @ QQ 微信 微博
|
||||
*/
|
||||
class Third extends HomeController
|
||||
{
|
||||
/**
|
||||
* 类型
|
||||
* @var string
|
||||
*/
|
||||
public $type = null;
|
||||
|
||||
/**
|
||||
* 类型实例
|
||||
* @var Object
|
||||
*/
|
||||
public $oauth = null;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $repeatLogin = [];
|
||||
|
||||
/**
|
||||
* 初始化构造函数
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取第三方登录配置
|
||||
* @return mixed|string
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function oType()
|
||||
{
|
||||
$this->type = input('type');
|
||||
$class = "\\system\\third\\" . $this->type;
|
||||
if (!class_exists($class)) {
|
||||
throw new \Exception('暂时还不支持该方式扩展');
|
||||
}
|
||||
|
||||
return new $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登录操作
|
||||
*/
|
||||
public function login(): \support\Response
|
||||
{
|
||||
try {
|
||||
$this->oauth = $this->oType();
|
||||
} catch (\Exception $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
$referer = input('ref', request()->server('HTTP_REFERER', '/'));
|
||||
request()->cookie('redirectUrl', $referer);
|
||||
return $this->oauth->login();
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户回调函数
|
||||
* @return mixed|void
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function callback()
|
||||
{
|
||||
try {
|
||||
$this->oauth = $this->oType();
|
||||
} catch (\Exception $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
$userInfos = $this->oauth->getUserInfo();
|
||||
if (!empty($userInfos) && !$this->auth->isLogin()) {
|
||||
return $this->register($userInfos, $this->type);
|
||||
} else if ($this->auth->isLogin()) { // 绑定用户
|
||||
return $this->doBind($userInfos, $this->type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户注册操作
|
||||
* @param array $userInfos
|
||||
* @param string|null $type
|
||||
* @return mixed
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
protected function register(array $userInfos = [], string $type = null)
|
||||
{
|
||||
$openid = $userInfos['openid'] ?? $userInfos['id'];
|
||||
$nickname = $userInfos['userinfo']['name'] ?? $userInfos['userinfo']['nickname'];
|
||||
$userInfo = UserThird::alias('th')
|
||||
->view('user', '*', 'user.id=th.user_id')
|
||||
->where(['openid' => $openid, 'type' => $type])
|
||||
->find();
|
||||
|
||||
if (!empty($userInfo)) {
|
||||
$array['id'] = $userInfo['id'];
|
||||
$array['login_time'] = time();
|
||||
$array['login_ip'] = request()->getRemoteIp();
|
||||
$array['login_count'] = $userInfo['login_count'] + 1;
|
||||
|
||||
if (User::update($array)) {
|
||||
$response = $this->auth->responseToken($userInfo);
|
||||
$response->withBody(json_encode(ResultCode::LOGINSUCCESS))->redirect(request()->cookie('redirectUrl', '/'));
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// 注册本地用户
|
||||
$data['nickname'] = $nickname;
|
||||
$data['avatar'] = $userInfos['userinfo']['avatar'];
|
||||
if (User::getByNickname($nickname)) {
|
||||
$data['nickname'] .= Random::alpha(3);
|
||||
}
|
||||
$data['group_id'] = 1;
|
||||
$data['create_ip'] = request()->getRemoteIp();
|
||||
$result = $this->auth->register($data);
|
||||
|
||||
// 封装第三方数据
|
||||
if (!empty($result)) {
|
||||
$userThird = [
|
||||
'type' => $this->type,
|
||||
'user_id' => $result['id'],
|
||||
'openid' => $openid,
|
||||
'nickname' => $nickname,
|
||||
'access_token' => $userInfos['access_token'],
|
||||
'refresh_token' => $userInfos['refresh_token'],
|
||||
'expires_in' => $userInfos['expires_in'],
|
||||
'login_time' => time(),
|
||||
'expiretime' => time() + $userInfos['expires_in'],
|
||||
];
|
||||
}
|
||||
|
||||
// 注册第三方数据
|
||||
if (isset($userThird) && is_array($userThird)) {
|
||||
if (UserThird::create($userThird)) {
|
||||
$response = $this->auth->responseToken($result);
|
||||
$response->withBody(json_encode(ResultCode::LOGINSUCCESS))->redirect(request()->cookie('redirectUrl', '/'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->error('登录失败');
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户绑定操作
|
||||
* @return Response
|
||||
*/
|
||||
public function bind(): \support\Response
|
||||
{
|
||||
if (Auth::instance()->isLogin()) {
|
||||
$buildQuery = [
|
||||
'bind' => true,
|
||||
'type' => input('type'),
|
||||
'ref' => input('ref', request()->server('HTTP_REFERER', '/')),
|
||||
];
|
||||
|
||||
return $this->redirect("/third/login?" . http_build_query($buildQuery));
|
||||
}
|
||||
|
||||
return $this->error('请先登录');
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户解除绑定
|
||||
* @return mixed|void
|
||||
* @throws \think\db\exception\DbException
|
||||
*/
|
||||
public function unbind(): \support\Response
|
||||
{
|
||||
try {
|
||||
$this->oauth = $this->oType();
|
||||
} catch (\Exception $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
if ($this->auth->isLogin()) {
|
||||
|
||||
$result = $this->auth->userInfo;
|
||||
if (!empty($result)) {
|
||||
|
||||
if (empty($result['email']) || empty($result['pwd'])) {
|
||||
return $this->error('解除绑定需要设置邮箱和密码!');
|
||||
}
|
||||
|
||||
$where['type'] = $this->type;
|
||||
$where['user_id'] = request()->cookie('uid');
|
||||
if (UserThird::where($where)->delete()) {
|
||||
return $this->success('解除绑定成功!');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->error();
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户绑定操作实例
|
||||
* @param array $userInfos
|
||||
* @param string|null $type
|
||||
* @return \support\Response|null
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
protected function doBind(array $userInfos = [], string $type = null)
|
||||
{
|
||||
|
||||
$openid = $userInfos['openid'] ?? $userInfos['id'];
|
||||
$nickname = $userInfos['userinfo']['name'] ?? $userInfos['userinfo']['nickname'];
|
||||
|
||||
// 查询是否被注册
|
||||
$where['openid'] = $openid;
|
||||
$where['type'] = $this->type;
|
||||
if (!UserThird::where($where)->find()) {
|
||||
|
||||
// 拼装数据
|
||||
$third = [
|
||||
'type' => $type,
|
||||
'user_id' => request()->cookie('uid'),
|
||||
'openid' => $openid,
|
||||
'nickname' => $nickname,
|
||||
'access_token' => $userInfos['access_token'],
|
||||
'refresh_token' => $userInfos['refresh_token'],
|
||||
'expires_in' => $userInfos['expires_in'],
|
||||
'login_time' => time(),
|
||||
'expiretime' => time() + $userInfos['expires_in'],
|
||||
];
|
||||
|
||||
if (UserThird::create($third)) {
|
||||
return $this->redirectUrl();
|
||||
} else {
|
||||
return $this->error('绑定异常');
|
||||
}
|
||||
}
|
||||
|
||||
return $this->error('当前用户已被其他账户绑定!');
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转URL
|
||||
* @return void
|
||||
*/
|
||||
protected function redirectUrl(): \support\Response
|
||||
{
|
||||
$referer = request()->cookie('redirectUrl', '/');
|
||||
|
||||
if (preg_match("/(user\/login|user\/register|user\/logout)/i", $referer)) {
|
||||
$referer = '/';
|
||||
}
|
||||
|
||||
request()->cookie('redirectUrl', null,1);
|
||||
return $this->redirect($referer);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
477
app/index/controller/User.php
Normal file
477
app/index/controller/User.php
Normal file
@@ -0,0 +1,477 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
// +----------------------------------------------------------------------
|
||||
// | swiftAdmin 极速开发框架 [基于WebMan开发]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
|
||||
// +----------------------------------------------------------------------
|
||||
// | swiftAdmin.net High Speed Development Framework
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: meystack <coolsec@foxmail.com> MIT License Code
|
||||
// +----------------------------------------------------------------------
|
||||
namespace app\index\controller;
|
||||
|
||||
use app\common\library\ResultCode;
|
||||
use app\HomeController;
|
||||
use app\common\library\Sms;
|
||||
use app\common\library\Email;
|
||||
use app\common\library\Upload;
|
||||
use app\common\model\system\User as UserModel;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use system\Random;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
|
||||
class User extends HomeController
|
||||
{
|
||||
/**
|
||||
* 鉴权控制器
|
||||
*/
|
||||
public $needLogin = true;
|
||||
|
||||
/**
|
||||
* 非登录鉴权方法
|
||||
*/
|
||||
public $noNeedAuth = ['login', 'register', 'forgot', 'check'];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->model = new UserModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
* @return Response
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function logout(): \support\Response
|
||||
{
|
||||
$this->auth->logout();
|
||||
return $this->success('退出成功', url('index/index'));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户中心
|
||||
* @return mixed
|
||||
*/
|
||||
public function index(): \support\Response
|
||||
{
|
||||
return view('/user/index');
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户注册
|
||||
* @return \support\Response
|
||||
* @throws \Psr\SimpleCache\InvalidArgumentException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function register(): \support\Response
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
|
||||
// 获取参数
|
||||
$post = \request()->post();
|
||||
$post = request_validate_rules($post, get_class($this->model));
|
||||
|
||||
if (!is_array($post)) {
|
||||
return $this->error($post);
|
||||
}
|
||||
|
||||
// 手机号注册
|
||||
if (saenv('user_register') == 'mobile') {
|
||||
$mobile = input('mobile');
|
||||
$captcha = input('captcha');
|
||||
if (!Sms::instance()->check($mobile, $captcha, 'register')) {
|
||||
return $this->error(Sms::instance()->getError());
|
||||
}
|
||||
}
|
||||
|
||||
$response = $this->auth->register($post);
|
||||
if (!$response) {
|
||||
return $this->error($this->auth->getError());
|
||||
}
|
||||
|
||||
return $response->withBody(json_encode(ResultCode::REGISTERSUCCESS));
|
||||
}
|
||||
|
||||
return view('/user/register', [
|
||||
'style' => saenv('user_register'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
* @return \support\Response
|
||||
*/
|
||||
public function login(): \support\Response
|
||||
{
|
||||
|
||||
if (request()->isPost()) {
|
||||
$nickname = \request()->post('nickname');
|
||||
$password = \request()->post('pwd');
|
||||
|
||||
$response = $this->auth->login($nickname, $password);
|
||||
if (!$response) {
|
||||
return $this->error($this->auth->getError());
|
||||
}
|
||||
|
||||
$response->withBody(json_encode(ResultCode::LOGINSUCCESS));
|
||||
return $response;
|
||||
}
|
||||
|
||||
return view('/user/login', [
|
||||
'referer' => request()->server('HTTP_REFERER', '/'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 找回密码
|
||||
* @return \support\Response
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function forgot(): \support\Response
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
|
||||
$email = input('email');
|
||||
$mobile = input('mobile');
|
||||
$event = input('event');
|
||||
$captcha = input('captcha');
|
||||
$pwd = input('pwd');
|
||||
|
||||
if (!empty($email)) {
|
||||
if (!Email::instance()->check($email, $captcha, $event)) {
|
||||
return $this->error(Email::instance()->getError());
|
||||
}
|
||||
} else {
|
||||
if (!Sms::instance()->check($mobile, $captcha, $event)) {
|
||||
return $this->error(Sms::instance()->getError());
|
||||
}
|
||||
}
|
||||
|
||||
$where = $email ? ['email' => $email] : ['mobile' => $mobile];
|
||||
$userInfo = $this->model->where($where)->find();
|
||||
if (!$userInfo) {
|
||||
return $this->error('用户不存在');
|
||||
}
|
||||
|
||||
try {
|
||||
$salt = Random::alpha();
|
||||
$pwd = encryptPwd($pwd, $salt);
|
||||
$this->model->update(['id' => $userInfo['id'], 'pwd' => $pwd, 'salt' => $salt]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return $this->error('修改密码失败,请联系管理员');
|
||||
}
|
||||
|
||||
return $this->success('修改密码成功!');
|
||||
}
|
||||
|
||||
return view('/user/forgot');
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户资料
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function profile(Request $request): \support\Response
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
|
||||
$nickname = input('nickname');
|
||||
$post = request_validate_rules(request()->Post(), get_class($this->model), 'nickname');
|
||||
if (!is_array($post)) {
|
||||
return $this->error($post);
|
||||
}
|
||||
|
||||
if ($this->model->where('nickname', $nickname)->find()) {
|
||||
return $this->error('当前昵称已被占用,请更换!');
|
||||
}
|
||||
|
||||
if ($this->model->update(['id' => $request->userId, 'nickname' => $nickname])) {
|
||||
return $this->success('修改昵称成功!', (string)url('/user/index'));
|
||||
}
|
||||
|
||||
return $this->error();
|
||||
}
|
||||
return view('/user/profile');
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function changePwd(Request $request): \support\Response
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
|
||||
// 获取参数
|
||||
$pwd = input('pwd');
|
||||
$oldPwd = input('oldpwd');
|
||||
$yPwd = encryptPwd($oldPwd, $request->userInfo->salt);
|
||||
|
||||
if ($yPwd != $request->userInfo->pwd) {
|
||||
return $this->error('原密码输入错误!');
|
||||
}
|
||||
|
||||
$salt = Random::alpha();
|
||||
$pwd = encryptPwd($pwd, $salt);
|
||||
$result = $this->model->update(['id' => $request->userId, 'pwd' => $pwd, 'salt' => $salt]);
|
||||
if (!empty($result)) {
|
||||
return $this->success('修改密码成功!');
|
||||
}
|
||||
|
||||
return $this->error();
|
||||
}
|
||||
|
||||
return view('/user/changepwd');
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请appKey
|
||||
* @return Response|void
|
||||
*/
|
||||
public function appid(Request $request)
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$data = array();
|
||||
$data['id'] = $request->userId;
|
||||
$data['app_id'] = 10000 + $request->userId;
|
||||
$data['app_secret'] = Random::alpha(22);
|
||||
if ($this->model->update($data)) {
|
||||
return $this->success();
|
||||
}
|
||||
return $this->error();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改邮箱
|
||||
* @return \support\Response
|
||||
* @throws \PHPMailer\PHPMailer\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function email(Request $request): \support\Response
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
|
||||
$email = input('email');
|
||||
$event = input('event');
|
||||
$captcha = input('captcha');
|
||||
|
||||
if (!$email || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
return $this->error("您输入的邮箱格式不正确!");
|
||||
}
|
||||
|
||||
if (UserModel::getByEmail($email)) {
|
||||
return $this->error("您输入的邮箱已被占用!");
|
||||
}
|
||||
|
||||
$Ems = Email::instance();
|
||||
if (!empty($email) && !empty($captcha)) {
|
||||
|
||||
if ($Ems->check($email, $captcha, $event)) {
|
||||
$this->model->update(['id' => $request->userId, 'email' => $email]);
|
||||
return $this->success('修改邮箱成功!');
|
||||
}
|
||||
|
||||
return $this->error($Ems->getError());
|
||||
}
|
||||
|
||||
$last = $Ems->getLast($email);
|
||||
if ($last && (time() - strtotime($last['create_time'])) < 60) {
|
||||
return $this->error(__('发送频繁'));
|
||||
}
|
||||
|
||||
if ($Ems->captcha($email, $event)->send()) {
|
||||
return $this->success("邮件发送成功,请查收!");
|
||||
} else {
|
||||
return $this->error($Ems->getError());
|
||||
}
|
||||
}
|
||||
|
||||
return view('/user/email');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改手机号
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws DataNotFoundException
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function mobile(Request $request): Response
|
||||
{
|
||||
|
||||
if (request()->isPost()) {
|
||||
|
||||
$mobile = input('mobile');
|
||||
$event = input('event');
|
||||
$captcha = input('captcha');
|
||||
|
||||
if (!is_mobile($mobile)) {
|
||||
return $this->error('手机号码不正确');
|
||||
}
|
||||
|
||||
if ($mobile && UserModel::getByMobile($mobile)) {
|
||||
return $this->error("您输入的手机号已被占用!");
|
||||
}
|
||||
|
||||
$Sms = Sms::instance();
|
||||
if (!empty($mobile) && !empty($captcha)) {
|
||||
|
||||
if ($Sms->check($mobile, $captcha, $event)) {
|
||||
$this->model->update(['id' => $request->userId, 'mobile' => (int)$mobile]);
|
||||
return $this->success('修改手机号成功!');
|
||||
}
|
||||
|
||||
return $this->error($Sms->getError());
|
||||
} else {
|
||||
|
||||
$data = $Sms->getLast($mobile);
|
||||
if ($data && (time() - strtotime($data['create_time'])) < 60) {
|
||||
return $this->error(__('发送频繁'));
|
||||
}
|
||||
|
||||
if ($Sms->send($mobile, $event)) {
|
||||
return $this->success("验证码发送成功");
|
||||
} else {
|
||||
return $this->error($Sms->getError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return view('/user/mobile');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置密保
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function protection(Request $request): \support\Response
|
||||
{
|
||||
$validate = [
|
||||
'你家的宠物叫啥?',
|
||||
'你的幸运数字是?',
|
||||
'你不想上班的理由是?',
|
||||
];
|
||||
|
||||
if (request()->isPost()) {
|
||||
$question = input('question');
|
||||
$answer = input('answer');
|
||||
|
||||
if (!$question || !$answer) {
|
||||
return $this->error('设置失败');
|
||||
}
|
||||
|
||||
if (!in_array($question, $validate)) {
|
||||
$question = current($validate);
|
||||
}
|
||||
|
||||
try {
|
||||
$request->userInfo->question = $question;
|
||||
$request->userInfo->answer = $answer;
|
||||
$request->userInfo->save();
|
||||
} catch (\Throwable $th) {
|
||||
return $this->error();
|
||||
}
|
||||
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
return view('/user/protection', [
|
||||
'validate' => $validate
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全配置中心
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function security(Request $request): Response
|
||||
{
|
||||
$maxProgress = 5;
|
||||
$thisProgress = 1;
|
||||
|
||||
if ($request->userInfo->email) {
|
||||
$thisProgress++;
|
||||
}
|
||||
|
||||
if ($request->userInfo->mobile) {
|
||||
$thisProgress++;
|
||||
}
|
||||
|
||||
if ($request->userInfo->answer) {
|
||||
$thisProgress++;
|
||||
}
|
||||
|
||||
if ($request->userInfo->wechat) {
|
||||
$thisProgress++;
|
||||
}
|
||||
|
||||
// 计算比例
|
||||
$progress = (($thisProgress / $maxProgress) * 100);
|
||||
return view('/user/security', [
|
||||
'progress' => $progress,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户头像上传
|
||||
* @param Request $request
|
||||
* @return Response|void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function avatar(Request $request)
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$response = Upload::instance()->upload();
|
||||
if (!$response) {
|
||||
return $this->error(Upload::instance()->getError());
|
||||
}
|
||||
$request->userInfo->avatar = $response['url'] . '?' . Random::alpha(12);
|
||||
if ($request->userInfo->save()) {
|
||||
return json($response);
|
||||
}
|
||||
}
|
||||
|
||||
return json(ResultCode::SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传函数
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function upload()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$file = Upload::instance()->upload();
|
||||
if (!$file) {
|
||||
return $this->error(Upload::instance()->getError());
|
||||
}
|
||||
return json($file);
|
||||
}
|
||||
|
||||
return json(ResultCode::SUCCESS);
|
||||
}
|
||||
}
|
||||
42
app/index/middleware/StaticFile.php
Normal file
42
app/index/middleware/StaticFile.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of webman.
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* For full copyright and license information, please see the MIT-LICENSE.txt
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @author walkor<walkor@workerman.net>
|
||||
* @copyright walkor<walkor@workerman.net>
|
||||
* @link http://www.workerman.net/
|
||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||||
*/
|
||||
|
||||
namespace app\index\middleware;
|
||||
|
||||
use Webman\MiddlewareInterface;
|
||||
use Webman\Http\Response;
|
||||
use Webman\Http\Request;
|
||||
|
||||
/**
|
||||
* Class StaticFile
|
||||
* @package app\middleware
|
||||
*/
|
||||
class StaticFile implements MiddlewareInterface
|
||||
{
|
||||
public function process(Request $request, callable $next): Response
|
||||
{
|
||||
// Access to files beginning with. Is prohibited
|
||||
if (strpos($request->path(), '/.') !== false) {
|
||||
return response('<h1>403 forbidden</h1>', 403);
|
||||
}
|
||||
/** @var Response $response */
|
||||
$response = $next($request);
|
||||
// Add cross domain HTTP header
|
||||
/*$response->withHeaders([
|
||||
'Access-Control-Allow-Origin' => '*',
|
||||
'Access-Control-Allow-Credentials' => 'true',
|
||||
]);*/
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
47
app/index/middleware/system/IndexInitialize.php
Normal file
47
app/index/middleware/system/IndexInitialize.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
declare (strict_types=1);
|
||||
// +----------------------------------------------------------------------
|
||||
// | swiftAdmin 极速开发框架 [基于WebMan开发]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2020-2030 http://www.swiftadmin.net
|
||||
// +----------------------------------------------------------------------
|
||||
// | swiftAdmin.net High Speed Development Framework
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: meystack <coolsec@foxmail.com> Apache 2.0 License
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\index\middleware\system;
|
||||
use Webman\Http\Request;
|
||||
use Webman\Http\Response;
|
||||
use Webman\MiddlewareInterface;
|
||||
use function redirect;
|
||||
use function root_path;
|
||||
|
||||
/**
|
||||
* 前台应用中间件
|
||||
* Class AppInitialize
|
||||
* @package app\index\middleware\system
|
||||
* @author meystack <
|
||||
*/
|
||||
|
||||
class IndexInitialize implements MiddlewareInterface
|
||||
{
|
||||
public function process(Request $request, callable $handler): Response
|
||||
{
|
||||
try {
|
||||
if (saenv('site_status')) {
|
||||
$content = file_get_contents(root_path('extend/conf/tpl') . 'close.tpl');
|
||||
$content = str_replace('{text}',saenv('site_notice'),$content);
|
||||
return \response($content, 503);
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
return \response('Web site has been closed', 503);
|
||||
}
|
||||
|
||||
if (!is_file(root_path('extend/conf').'install.lock')) {
|
||||
return redirect('/install/index');
|
||||
}
|
||||
|
||||
return $handler($request);
|
||||
}
|
||||
}
|
||||
85
app/index/middleware/system/IndexPermissions.php
Normal file
85
app/index/middleware/system/IndexPermissions.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace app\index\middleware\system;
|
||||
|
||||
use app\common\library\Auth;
|
||||
use support\View;
|
||||
use Webman\MiddlewareInterface;
|
||||
use Webman\Http\Response;
|
||||
use Webman\Http\Request;
|
||||
|
||||
/**
|
||||
* 管理员权限
|
||||
* @package app\admin\middleware\system
|
||||
* @author meystack <
|
||||
*/
|
||||
class IndexPermissions implements MiddlewareInterface
|
||||
{
|
||||
/**
|
||||
* 控制器登录鉴权
|
||||
* @var bool
|
||||
*/
|
||||
public $needLogin = false;
|
||||
|
||||
/**
|
||||
* 禁止登录重复
|
||||
* @var array
|
||||
*/
|
||||
public $repeatLogin = ['login', 'register'];
|
||||
|
||||
/**
|
||||
* 非鉴权方法
|
||||
* @var array
|
||||
*/
|
||||
public $noNeedAuth = [];
|
||||
|
||||
/**
|
||||
* 跳转URL地址
|
||||
* @var string
|
||||
*/
|
||||
public $JumpUrl = '/user/index';
|
||||
|
||||
/**
|
||||
* 校验权限
|
||||
* @param Request $request
|
||||
* @param callable $handler
|
||||
* @return Response
|
||||
*/
|
||||
public function process(Request $request, callable $handler): Response
|
||||
{
|
||||
$app = request()->getApp();
|
||||
$controller = request()->getController();
|
||||
$action = request()->getAction();
|
||||
|
||||
// 控制器是否存在
|
||||
$className = '\app' . $app . '\\controller\\' . $controller;
|
||||
$className = str_replace('/', '\\', $className);
|
||||
|
||||
if (class_exists($className)) {
|
||||
$refClass = new \ReflectionClass($className);
|
||||
$property = $refClass->getDefaultProperties();
|
||||
$this->needLogin = $property['needLogin'] ?? false;
|
||||
$this->noNeedAuth = $property['noNeedAuth'] ?? [];
|
||||
$this->repeatLogin = $property['repeatLogin'] ?? ['login', 'register'];
|
||||
$this->JumpUrl = $property['JumpUrl'] ?: '/user/index';
|
||||
}
|
||||
|
||||
// 是否验证登录器
|
||||
$auth = Auth::instance();
|
||||
if ($auth->isLogin()) {
|
||||
$request->userId = $auth->userInfo['id'];
|
||||
$request->userInfo = $auth->userInfo;
|
||||
if (in_array($action, $this->repeatLogin)) {
|
||||
return redirect($this->JumpUrl);
|
||||
}
|
||||
|
||||
View::assign('user', $auth->userInfo);
|
||||
} else {
|
||||
if ($this->needLogin && !in_array($action, $this->noNeedAuth)) {
|
||||
return redirect('/');
|
||||
}
|
||||
}
|
||||
|
||||
return $handler($request);
|
||||
}
|
||||
}
|
||||
74
app/index/view/index/index.html
Normal file
74
app/index/view/index/index.html
Normal file
@@ -0,0 +1,74 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>SwiftAdmin 官方演示站</title>
|
||||
<meta http-equiv="Cache-Control" content="no-transform " />
|
||||
<include file="public:header" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="header">
|
||||
<include file="public:nav"/>
|
||||
</div>
|
||||
|
||||
<div id="content" >
|
||||
<div class="layui-container">
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-md6">
|
||||
<div class="layui-swift-box">
|
||||
<h1>SWIFTADMIN 极速开发框架</h1>
|
||||
<h1 style="font-size: 26px; font-weight: 300">基于高性能WM框架,性能在TP5 10倍以上</h1>
|
||||
<p>SwiftAdmin框架主张简单就是高效的原则,在设计和运维上采用最精简最高效的做法去完成业务系统的需求,并且基于ant Design的设计原则,是一款优秀的前后台极速开发解决方案。相信你第一眼就有立刻想体验SwiftAdmin框架的冲动和热情!</p>
|
||||
<div class="layui-swift-desc">
|
||||
<a href="#" onclick="javascript:layui.layer.msg('基于高性能WebMan');return false;" target="_blank">
|
||||
<img src="https://badgen.net/badge/WebMan/1.4LTS/red" alt="WebMan">
|
||||
</a>
|
||||
<a href="#" onclick="javascript:layui.layer.msg('前端采用Layui经典规范');return false;" target="_blank">
|
||||
<img src="https://badgen.net/badge/layui/2DEV/" alt="layui">
|
||||
</a>
|
||||
<a href="https://gitee.com/meystack/swiftadmin/stargazers" target="_blank">
|
||||
<img src="https://gitee.com/meystack/swiftadmin/badge/star.svg?theme=gvp" alt="star">
|
||||
</a>
|
||||
<a class="fork" href="https://gitee.com/meystack/swiftadmin/members" target="_blank">
|
||||
<img src="https://gitee.com/meystack/swiftadmin/badge/fork.svg?theme=gvp" alt="fork">
|
||||
</a>
|
||||
<a href="#" onclick="javascript:layui.layer.msg('请遵循Apache2.0开源协议精神');return false;" target="_blank">
|
||||
<img src="https://badgen.net/badge/license/Apache/" alt="swiftadmin">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="layui-swift-images">
|
||||
<img src="/static/images/demo/1.png" >
|
||||
<img src="/static/images/demo/2.png" >
|
||||
<img src="/static/images/demo/3.png" >
|
||||
<img class="hidden" src="/static/images/demo/4.png" >
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-col-md6">
|
||||
<img src="/static/images/hero-img.png" width="90%" height="500" alt="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<include file="public:footer"/>
|
||||
</body>
|
||||
<script>
|
||||
layui.use(['jquery','layer'],function(){
|
||||
var $ = layui.jquery;
|
||||
var layer = layui.layer;
|
||||
|
||||
$('.layui-swift-images img').click(function(){
|
||||
layer.photos({
|
||||
photos: '.layui-swift-images',
|
||||
shadeClose: true,
|
||||
closeBtn: 2,
|
||||
anim: 10
|
||||
})
|
||||
})
|
||||
})
|
||||
</script>
|
||||
</html>
|
||||
11
app/index/view/layout/layout.html
Normal file
11
app/index/view/layout/layout.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>控制台 | 用户中心</title>
|
||||
<include file="user:include"/>
|
||||
</head>
|
||||
<body>
|
||||
{__CONTENT__}
|
||||
</body>
|
||||
</html>
|
||||
5
app/index/view/public/footer.html
Normal file
5
app/index/view/public/footer.html
Normal file
@@ -0,0 +1,5 @@
|
||||
<div id="footer" >
|
||||
<div class="layui-footer" >
|
||||
<div style="text-align: center;"> copyright © 2020 www.swiftadmin.net all rights reserved.</div>
|
||||
</div>
|
||||
</div>
|
||||
14
app/index/view/public/header.html
Normal file
14
app/index/view/public/header.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<link rel="stylesheet" href="/static/js/layui/css/layui.css">
|
||||
<link rel="stylesheet" href="/static/css/style.css?v={:release()}">
|
||||
<script src="/static/js/layui/layui.js"></script>
|
||||
<script src="/static/js/common.js?v={:release()}"></script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
|
||||
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
21
app/index/view/public/nav.html
Normal file
21
app/index/view/public/nav.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<div class="layui-container" >
|
||||
<div class="layui-logo">
|
||||
<a href="/"><img src="/static/system/images/logo.png" alt="logo" height="26">SWIFTADMIN</a>
|
||||
</div>
|
||||
<ul class="layui-nav">
|
||||
<li class="layui-nav-item active"><a href="/" class="nav-link">主页</a></li>
|
||||
<li class="layui-nav-item "><a href="#" onclick="layer.msg('感谢您使用SAPHP<br><br>您可以尽情在此框架上二次开发');" class="nav-link">关于</a></li>
|
||||
<li class="layui-nav-item "><a href="https://www.swiftadmin.net/plugin/" class="nav-link">插件市场</a></li>
|
||||
<li class="layui-nav-item layui-hide-xs"><a href="https://www.swiftadmin.net/agreement.html" class="nav-link">使用协议</a></li>
|
||||
<li class="layui-nav-item layui-hide-xs"><a href="https://doc.swiftadmin.net/help/" class="nav-link">帮助文档</a></li>
|
||||
<li class="layui-nav-item layui-hide-xs"><a href="https://ask.swiftadmin.net/" class="nav-link">社区中心</a></li>
|
||||
<li class="layui-nav-item layui-hide-xs"><a href="https://qm.qq.com/cgi-bin/qm/qr?k=rUxEL3_DV8PnflvZiJamjED0dfHwpiMw&jump_from=webapi" target="_blank" class="nav-link">联系我们</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="layui-nav layui-hide-xs fr" id="login">
|
||||
<notempty name="$user.id"> <li class="layui-nav-item"><a class="" href="/user/index" >会员中心</a></li> <else/>
|
||||
<li class="layui-nav-item"><a href="javascript:;" lay-open data-title="用户注册" data-area="490px" data-url="/user/register" >注册</a></li>
|
||||
<li class="layui-nav-item"><a href="javascript:;" lay-open data-title="用户登录" data-area="450px,420px" data-url="/user/login" >登录</a></li>
|
||||
</notempty>
|
||||
</div>
|
||||
</div>
|
||||
79
app/index/view/user/changepwd.html
Normal file
79
app/index/view/user/changepwd.html
Normal file
@@ -0,0 +1,79 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>修改密码</title>
|
||||
<include file="user:include"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="layui-card-body">
|
||||
<form action="/user/changePwd" class="layui-form layui-form-fixed">
|
||||
<input type="text" name="nickname" value="{$user.nickname}" hidden="">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">原密码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="password" id="oldpwd" name="oldpwd" class="layui-input" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">新密码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="password" id="pwd" name="pwd" class="layui-input" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">确认密码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="password" id="repwd" name="repwd" class="layui-input" >
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item" style="margin-top: 22px;text-align: center;">
|
||||
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
|
||||
<button type="submit" class="layui-btn layui-btn-normal" lay-submit="" lay-filter="submit">立即提交</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<script>
|
||||
layui.use(['jquery','form'],function(){
|
||||
|
||||
let $ = layui.jquery;
|
||||
let form = layui.form;
|
||||
//监听提交
|
||||
form.on('submit(submit)', function(data){
|
||||
|
||||
if($("#pwd").val().length < 6){
|
||||
layer.tips('请至少输入6个字符作为密码',"#pwd",{'tips':3});
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($("#pwd").val() !== $("#repwd").val()) {
|
||||
layer.tips('两次输入的密码不一样!',"#repwd",{'tips':3});
|
||||
return false;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: $(this).attr('action'),
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
timeout: 6000,
|
||||
data: data.field,
|
||||
success: function(res){
|
||||
if (res.code === 200) {
|
||||
top.layer.msg(res.msg);
|
||||
}
|
||||
else {
|
||||
top.layer.msg(res.msg,'error');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
})
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
32
app/index/view/user/email.html
Normal file
32
app/index/view/user/email.html
Normal file
@@ -0,0 +1,32 @@
|
||||
<layout name="layout:layout"/>
|
||||
<!-- 内容主体区域 -->
|
||||
<div id="content">
|
||||
<div class="layui-fluid ">
|
||||
<form class="layui-form layui-form-fixed" action="/user/email">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('邮箱地址')}</label>
|
||||
<div class="layui-input-inline" style="width: 265px">
|
||||
<input name="email" placeholder="{:__('请输入邮箱地址')}" type="text" class="layui-input email"
|
||||
autocomplete="off" lay-verify="required|email"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('验证码')}</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="captcha" placeholder="{:__('请输入验证码')}" type="text" class="layui-input"
|
||||
autocomplete="off" lay-verify="required" maxlength="10"/>
|
||||
</div>
|
||||
<button class="layui-btn layui-btn-normal" type="button" lay-ajax data-url="/user/email"
|
||||
data-object="email:email,event:event">{:__('获取')}
|
||||
</button>
|
||||
</div>
|
||||
<input type="text" hidden name="event" class="event" value="change">
|
||||
<div class="layui-footer layui-form-item layui-center">
|
||||
<button class="layui-btn layui-btn-primary" type="button" sa-event="closeDialog">{:__('取消')}</button>
|
||||
<button class="layui-btn layui-btn-normal" data-reload="parent" lay-filter="submitIframe" lay-submit>{:__('提交')}</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
5
app/index/view/user/footer.html
Normal file
5
app/index/view/user/footer.html
Normal file
@@ -0,0 +1,5 @@
|
||||
<div class="layui-footer">
|
||||
<!-- 底部固定区域 -->
|
||||
copyright © <php>echo date('Y');</php> <a href="http://www.swiftadmin.net" target="_blank">SwiftAdmin</a> all rights reserved.
|
||||
<span class="layui-layout-right" style="margin-right: 10px;">Build {:release()}</span>
|
||||
</div>
|
||||
86
app/index/view/user/forgot.html
Normal file
86
app/index/view/user/forgot.html
Normal file
@@ -0,0 +1,86 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>SwiftAdmin 用户登录</title>
|
||||
<include file="public:header"/>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.layui-form-checked[lay-skin="primary"] i {
|
||||
border-color: #1890ff !important;
|
||||
background-color: #1890ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.layui-form-item {
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.red {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.layui-input:hover {
|
||||
border: 1px solid #1890ff!important;
|
||||
}
|
||||
|
||||
</style>
|
||||
<div class="layui-fluid">
|
||||
<form class="layui-form layui-form-fixed" action="/user/forgot" method="post" >
|
||||
<input type="hidden" name="__token__" value="{:token()}"/>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="red">*</span> {:__('手机/邮箱')}</label>
|
||||
<div class="layui-input-inline" style="width: 306px">
|
||||
<input id="string" name="mobile" placeholder="{:__('请输入邮箱或手机号')}" type="text" class="layui-input string"
|
||||
autocomplete="off" lay-verify="required"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="red">*</span> {:__('验证码')}</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="captcha" placeholder="{:__('请输入验证码')}" type="text" class="layui-input" autocomplete="off" lay-verify="required" maxlength="10"/>
|
||||
</div>
|
||||
<button id="send" class="layui-btn layui-btn-normal" type="button"
|
||||
lay-ajax data-url="/ajax/smssend" data-object="mobile:string,event:event">{:__('获取')}
|
||||
</button>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="red">*</span> {:__('新密码')}</label>
|
||||
<div class="layui-input-inline" style="width: 306px">
|
||||
<input type="password" id="pwd" name="pwd" lay-verify="required" placeholder="{:__('密码')}" class="layui-input" >
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" hidden name="event" class="event" value="forgot">
|
||||
<div class="layui-footer layui-form-item layui-center">
|
||||
<button class="layui-btn layui-btn-primary" type="button" sa-event="closeDialog">{:__('取消')}</button>
|
||||
<button class="layui-btn layui-btn-normal" lay-filter="submitIframe" lay-submit>{:__('提交')}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
layui.use('jquery', function() {
|
||||
|
||||
let $ = layui.jquery;
|
||||
|
||||
$('#string').on('keyup',function (e) {
|
||||
|
||||
let val = $(this).val();
|
||||
let string = $('#string');
|
||||
let send = $('#send');
|
||||
let regx = /^[1][3,4,5,6.7,8,9][0-9]{9}$/
|
||||
if (regx.test(val)) {
|
||||
string.attr('name','mobile');
|
||||
send.attr('data-object','mobile:string,event:event');
|
||||
send.attr('data-url','/ajax/smssend');
|
||||
} else {
|
||||
string.attr('name','email');
|
||||
send.attr('data-object','email:string,event:event');
|
||||
send.attr('data-url','/ajax/emailsend');
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
</script>
|
||||
</html>
|
||||
40
app/index/view/user/header.html
Normal file
40
app/index/view/user/header.html
Normal file
@@ -0,0 +1,40 @@
|
||||
<div class="layui-header">
|
||||
<div class="layui-logo layui-hide-xs layui-bg-black">
|
||||
<span class="logo-text">SAPHP <span style="font-size: medium ">用户后台</span></span>
|
||||
</div>
|
||||
<!-- 头部区域(可配合layui 已有的水平导航) -->
|
||||
<ul class="layui-nav layui-layout-left">
|
||||
<!-- 移动端显示 -->
|
||||
<li class="layui-nav-item layui-show-xs-inline-block" lay-header-event="menuLeft">
|
||||
<i class="layui-icon layui-icon-spread-left"></i>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="layui-nav layui-layout-right">
|
||||
|
||||
<li class="layui-nav-item" lay-unselect="">
|
||||
<a href="{$site_http}" lay-text="主页">
|
||||
<i class="layui-icon layui-icon-website"></i>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="layui-nav-item" lay-unselect="">
|
||||
<a href="javascript:;" sa-event="message" lay-text="消息中心" data-url="/admin.php/system.admin/message">
|
||||
<i class="layui-icon fa-bell-o"></i>
|
||||
<!-- 如果有新消息,则显示小圆点 -->
|
||||
<span class="layui-badge-dot"></span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="layui-nav-item layui-hide layui-show-md-inline-block">
|
||||
<a href="javascript:;"><img src="{$user.avatar}" alt="{$user.nickname}" class="layui-nav-img">{$user.nickname}</a>
|
||||
<dl class="layui-nav-child">
|
||||
<dd><a lay-open lay-title="修改密码" lay-url="/user/changepwd" lay-area="470px,330px" href="javascript:;">修改密码</a>
|
||||
</dd>
|
||||
<dd><a href="/user/logout" >退出</a></dd>
|
||||
</dl>
|
||||
</li>
|
||||
<li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
|
||||
<a href="javascript:;"><i class="layui-icon layui-icon-more-vertical"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
26
app/index/view/user/include.html
Normal file
26
app/index/view/user/include.html
Normal file
@@ -0,0 +1,26 @@
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<link rel="stylesheet" href="/static/js/layui/css/layui.css">
|
||||
<link href="/static/js/layui/css/font-awesome.css?v={:config('app.version')}" rel="stylesheet" type="text/css" />
|
||||
<link rel="stylesheet" href="/static/css/center.css?v={:release()}">
|
||||
<script src="/static/js/layui/layui.js"></script>
|
||||
<script src="/static/js/common.js?v={:release()}"></script>
|
||||
<!-- // 加载font-awesome图标 -->
|
||||
|
||||
<!--[if lt IE 9]>
|
||||
<script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
|
||||
<script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
<style>
|
||||
/* 移动端 */
|
||||
@media screen and (max-width: 768px) {
|
||||
.layui-layout-admin .layui-layout-left,
|
||||
.layui-layout-admin .layui-body,
|
||||
.layui-layout-admin .layui-footer{left: 0;}
|
||||
.layui-layout-admin .layui-side{width: 0px;}
|
||||
}
|
||||
</style>
|
||||
166
app/index/view/user/index.html
Normal file
166
app/index/view/user/index.html
Normal file
@@ -0,0 +1,166 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>控制台 | 用户中心</title>
|
||||
<include file="user:include"/>
|
||||
</head>
|
||||
<body>
|
||||
<div class="layui-layout layui-layout-admin">
|
||||
<div class="layui-header">
|
||||
<div class="layui-logo layui-side-body layui-hide-xs layui-bg-black">
|
||||
<!-- // 可以增加LOGO-->
|
||||
<img src="/static/system/images/logo.png" style="margin-bottom: 8px;margin-right: 10px" alt="logo" width="22" height="22" >
|
||||
<span class="logo-text">用户中心</span>
|
||||
</div>
|
||||
<ul class="layui-nav layui-layout-left">
|
||||
<li id="shrink" class="layui-nav-item layui-show-xs-inline-block" >
|
||||
<i class="layui-icon layui-icon-shrink-right"></i>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="layui-nav layui-layout-right">
|
||||
|
||||
<li class="layui-nav-item" lay-unselect="">
|
||||
<a href="/" title="主页">
|
||||
<i class="layui-icon fa-home"></i>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="layui-nav-item" >
|
||||
<a href="javascript:;" id="notice">
|
||||
<i class="layui-icon fa-bell-o"></i>
|
||||
<span class="layui-badge-dot"></span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="layui-nav-item layui-hide layui-show-md-inline-block">
|
||||
<a href="javascript:;"><img src="{$user.avatar}" alt="{$user.nickname}" class="layui-nav-img">{$user.nickname}</a>
|
||||
<dl class="layui-nav-child">
|
||||
<dd><a lay-open data-title="修改密码" data-url="/user/changepwd" data-area="470px,330px" href="javascript:;">修改密码</a>
|
||||
</dd>
|
||||
<dd><a href="/user/logout">退出</a></dd>
|
||||
</dl>
|
||||
</li>
|
||||
<li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
|
||||
<a href="javascript:;">
|
||||
<i id="skin" class="layui-icon fa-moon-o"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="layui-side layui-side-body layui-bg-black">
|
||||
<div class="layui-side-scroll">
|
||||
<!-- 左侧导航区域(可配合layui已有的垂直导航) -->
|
||||
<include file="user:userNav"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-body">
|
||||
<!-- 内容主体区域 -->
|
||||
<iframe id="iframe" src="/user/profile" frameborder="0" class="layui-layer-load" onload="this.className='';" ></iframe>
|
||||
</div>
|
||||
<include file="user:footer"/>
|
||||
</div>
|
||||
|
||||
<script !src="">
|
||||
|
||||
layui.use(['jquery','upload'],function(){
|
||||
let $ = layui.jquery;
|
||||
let upload = layui.upload;
|
||||
|
||||
// 默认展现首个菜单栏
|
||||
$('.layui-nav-tree .layui-nav-item').each(function (k,e) {
|
||||
if ($(e).find('dl.layui-nav-child').length) {
|
||||
$(e).addClass('layui-nav-itemed');
|
||||
return false;
|
||||
}
|
||||
})
|
||||
|
||||
// 点击切换页面地址
|
||||
$('body').on('click', '.layui-nav-tree a', function () {
|
||||
let href = $(this).attr('lay-href');
|
||||
if (href && href !== 'javascript:;') {
|
||||
$('#iframe').attr('class','layui-layer-load');
|
||||
$('#iframe').attr('src',href);
|
||||
}
|
||||
})
|
||||
|
||||
// 上传头像
|
||||
upload.render({
|
||||
elem: '.layui-user-avatar'
|
||||
,url: '/user/avatars'
|
||||
,method: 'post'
|
||||
,accept: 'file'
|
||||
,before: function(res) {
|
||||
layer.msg('上传中');
|
||||
},done: function(res, index, upload) {
|
||||
// 上传成功
|
||||
if (res.code == 200) {
|
||||
layer.msg(res.msg);
|
||||
$('#imgHead img').attr('src',res.url);
|
||||
} else {
|
||||
layer.msg(res.msg,'error');
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
let leftAnimate = function (action = true) {
|
||||
if (action) {
|
||||
$('.layui-side').animate({width: '0px'});
|
||||
$('.layui-body,.layui-footer').animate({left: '5px'});
|
||||
} else {
|
||||
$('.layui-side').animate({width: '200px'});
|
||||
$('.layui-body,.layui-footer').animate({left: '200px'});
|
||||
}
|
||||
}
|
||||
|
||||
$('#shrink i.layui-icon').click(function () {
|
||||
let right = 'layui-icon-shrink-right',
|
||||
left = 'layui-icon-spread-left';
|
||||
if ($(this).hasClass(right)) {
|
||||
leftAnimate();
|
||||
$(this).removeClass(right).addClass(left);
|
||||
|
||||
}else {
|
||||
leftAnimate(false);
|
||||
$(this).removeClass(left).addClass(right);
|
||||
}
|
||||
})
|
||||
|
||||
// 初始化宽度
|
||||
if ($(window).width() <= 992) {
|
||||
$('#shrink i.layui-icon-shrink-right').removeClass('layui-icon-shrink-right').addClass('layui-icon-spread-left');
|
||||
}
|
||||
|
||||
let skin = layui.data('skin').theme || undefined;
|
||||
if (skin === 'layui-bg-white') {
|
||||
$('.layui-side-body').removeClass('layui-bg-black').addClass(skin);
|
||||
$('#skin').removeClass('fa-moon-o').addClass('fa-sun-o');
|
||||
}
|
||||
|
||||
// 切换皮肤
|
||||
$('#skin').on('click',function () {
|
||||
let value = $(this).hasClass('fa-moon-o');
|
||||
console.log(value)
|
||||
if (value) {
|
||||
$(this).removeClass('fa-moon-o').addClass('fa-sun-o');
|
||||
$('.layui-side-body').removeClass('layui-bg-black').addClass('layui-bg-white');
|
||||
layui.data('skin',{
|
||||
key: 'theme',
|
||||
value: 'layui-bg-white'
|
||||
});
|
||||
} else {
|
||||
$(this).removeClass('fa-sun-o').addClass('fa-moon-o');
|
||||
$('.layui-side-body').removeClass('layui-bg-white').addClass('layui-bg-black');
|
||||
layui.data('skin',{
|
||||
key: 'theme',
|
||||
value: 'layui-bg-black'
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
62
app/index/view/user/login.html
Normal file
62
app/index/view/user/login.html
Normal file
@@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>SwiftAdmin 用户登录</title>
|
||||
<include file="public:header"/>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.layui-form-checked[lay-skin="primary"] i {
|
||||
border-color: #1890ff !important;
|
||||
background-color: #1890ff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.forget-link {
|
||||
margin-top: 7px;
|
||||
color: #1890ff;
|
||||
}
|
||||
</style>
|
||||
<div id="userLogin" class="layui-fluid">
|
||||
<div class="login-link">
|
||||
<span class="other">第三方账号登录:</span>
|
||||
<span>
|
||||
<a href="{:url('/third/login',['type'=>'qq'])}&ref={$referer}" class="qq" target="_top"></a>
|
||||
<a href="{:url('/third/login',['type'=>'weixin'])}&ref={$referer}" class="wx" target="_top"></a>
|
||||
<a href="{:url('/third/login',['type'=>'weibo'])}&ref={$referer}" class="sina" target="_top"></a>
|
||||
</span>
|
||||
</div>
|
||||
<form class="layui-form" action="/user/login" method="post" style="height: auto">
|
||||
<input type="hidden" name="__token__" value="{:token()}"/>
|
||||
<div class="layui-form-item">
|
||||
<div class="item">
|
||||
<label class="user-login-icon layui-icon layui-icon-username"></label>
|
||||
<input type="text" id="nickname" name="nickname" lay-verify="required|email"
|
||||
placeholder="{:__('请输入邮箱或手机号')}" class="layui-input" value="test@swiftadmin.net">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<div class="item">
|
||||
<label class="user-login-icon layui-icon layui-icon-password"></label>
|
||||
<input type="password" id="pwd" name="pwd" lay-verify="required" placeholder="{:__('密码')}"
|
||||
class="layui-input" value="admin888">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item" style="margin-bottom: 20px;">
|
||||
<div class="fl">
|
||||
<input type="checkbox" name="remember" lay-skin="primary" title="{:__('记住密码')}" checked>
|
||||
</div>
|
||||
<a lay-open data-title="找回密码" data-area="510px,360px" data-object="top" data-url="/user/forgot" class="forget-link fr" style="margin-top: 7px;">{:__('忘记密码?')}</a>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<input type="submit" value="{:__('立即登录')}" lay-submit="" lay-filter="submitIframe" data-reload="top"
|
||||
class="layui-btn layui-btn-fluid layui-btn-normal">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
30
app/index/view/user/mobile.html
Normal file
30
app/index/view/user/mobile.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<layout name="layout:layout"/>
|
||||
<!-- 内容主体区域 -->
|
||||
<div id="content">
|
||||
<div class="layui-fluid">
|
||||
<form class="layui-form layui-form-fixed" action="/user/mobile">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('手机号')}</label>
|
||||
<div class="layui-input-inline" style="width: 265px">
|
||||
<input name="mobile" placeholder="{:__('请输入号码')}" type="text" class="layui-input mobile"
|
||||
autocomplete="off" lay-verify="required|phone"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('验证码')}</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="captcha" placeholder="{:__('请输入验证码')}" type="text" class="layui-input"
|
||||
autocomplete="off" lay-verify="required" maxlength="10"/>
|
||||
</div>
|
||||
<button class="layui-btn layui-btn-normal" type="button" lay-ajax data-url="/user/mobile"
|
||||
data-object="mobile:mobile,event:event">{:__('获取')}
|
||||
</button>
|
||||
</div>
|
||||
<input type="text" hidden name="event" class="event" value="change">
|
||||
<div class="layui-footer layui-form-item layui-center">
|
||||
<button class="layui-btn layui-btn-primary" type="button" sa-event="closeDialog">{:__('取消')}</button>
|
||||
<button class="layui-btn layui-btn-normal" data-reload="parent" lay-filter="submitIframe" lay-submit>{:__('提交')}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
35
app/index/view/user/notice.html
Normal file
35
app/index/view/user/notice.html
Normal file
@@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>消息管理 | {$site_name}</title>
|
||||
<include file="user:include" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="layui-layout layui-layout-admin">
|
||||
<include file="user:header" />
|
||||
|
||||
<div class="layui-side layui-bg-black">
|
||||
<div class="layui-side-scroll">
|
||||
<!-- 左侧导航区域(可配合layui已有的垂直导航) -->
|
||||
<include file="user:userNav" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-body">
|
||||
<!-- 内容主体区域 -->
|
||||
<div id="content">
|
||||
<h1>消息 示例页面</h1>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<include file="user:footer"/>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
246
app/index/view/user/profile.html
Normal file
246
app/index/view/user/profile.html
Normal file
@@ -0,0 +1,246 @@
|
||||
<layout name="layout:layout"/>
|
||||
<!-- 内容主体区域 -->
|
||||
<div id="content">
|
||||
<div class="layui-row layui-col-space20">
|
||||
|
||||
<div class="layui-col-md9">
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body goindex">
|
||||
<div class="layui-col-md8">
|
||||
<div class="tips"> Hi,{$user.nickname} <span class="regular"> 下午好,今天是你加入的第 {$user.create_time|distance_day} 天~</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md4">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="profile" class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<h2>个人信息</h2>
|
||||
|
||||
<div class="clear">
|
||||
<div class="layui-col-md3">
|
||||
<div class="contract-title">手机</div>
|
||||
<div class="contract-detail">+86 {$user.mobile}
|
||||
<i class="layui-icon fa-edit" title="编辑" lay-open data-title="修改手机"
|
||||
data-url="/user/mobile" data-area="500px,300px"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-col-md3">
|
||||
<div class="contract-title">微信号</div>
|
||||
<div class="contract-detail">{$user.wechat|default='--'}</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-col-md3">
|
||||
<div class="contract-title">办公室邮箱</div>
|
||||
<div class="contract-detail">{$user.email}
|
||||
<i class="layui-icon fa-edit" title="编辑" lay-open data-title="修改邮箱"
|
||||
data-url="/user/email" data-area="500px,300px"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<div class="contract-title">登录IP</div>
|
||||
<div class="contract-detail">{$user.login_ip}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clear">
|
||||
<div class="layui-col-md3">
|
||||
<div class="contract-title">登陆次数</div>
|
||||
<div class="contract-detail">{$user.login_count}</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-col-md3">
|
||||
<div class="contract-title">用户组</div>
|
||||
<div class="contract-detail">{$user.group.title}</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-col-md3">
|
||||
<div class="contract-title">积分</div>
|
||||
<div class="contract-detail">{$user.score}</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-col-md3">
|
||||
<div class="contract-title">加入时间</div>
|
||||
<div class="contract-detail">{$user.create_time}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
<div class="contract-title">所在住址</div>
|
||||
<div class="contract-detail">{$user.address}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">我的帖子</div>
|
||||
<div class="layui-card-body">
|
||||
<table class="layui-table" lay-skin="nob">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>标题</th>
|
||||
<th>回答数</th>
|
||||
<th>发表时间</th>
|
||||
<th>访问量</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="layui-col-md3">
|
||||
|
||||
<div id="account" class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<div id="imgHead" class="layui-user-avatar">
|
||||
<img src="{$user.avatar}" alt="{$user.nickname}" class="avatar">
|
||||
</div>
|
||||
<div class="nickname">
|
||||
{$user.nickname}
|
||||
<span class="edits">
|
||||
<i class="layui-icon fa-edit" lay-open data-title="修改昵称" data-url="#nickname" data-area="398px,230px"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="intro">{$user.heart}</div>
|
||||
|
||||
<div id="thrid" class="layui-input-inline">
|
||||
|
||||
<if check_user_third(
|
||||
'qq',$user['id']) >
|
||||
<a lay-ajax data-url="{:url('/third/unbind',['type'=> 'qq'])}" title="点击解绑" type="button"
|
||||
class="layui-btn layui-btn-sm"><i
|
||||
class="layui-icon layui-icon-login-qq"></i></a>
|
||||
<else/>
|
||||
<a href="{:url('/third/bind?type=qq&ref=/user/index')}" title="点击绑定" type="button" target="_top"
|
||||
class="layui-btn layui-btn-sm layui-bind-third"><i
|
||||
class="layui-icon layui-icon-login-qq"></i></a>
|
||||
</if>
|
||||
|
||||
<if check_user_third(
|
||||
'weixin',$user['id']) >
|
||||
<a lay-ajax data-url="{:url('/third/unbind?type=weixin')}" title="点击解绑" type="button"
|
||||
class="layui-btn layui-btn-sm"><i
|
||||
class="layui-icon layui-icon-login-wechat"></i></a>
|
||||
<else/>
|
||||
<a href="{:url('/third/bind')}?type=weixin&ref=/user/index" title="点击绑定" type="button"
|
||||
target="_top"
|
||||
class="layui-btn layui-btn-sm layui-bind-third"><i
|
||||
class="layui-icon layui-icon-login-wechat"></i></a>
|
||||
</if>
|
||||
|
||||
<if check_user_third(
|
||||
'weibo',$user['id']) >
|
||||
<a lay-ajax data-url="{:url('/third/unbind?type=weibo')}" title="点击解绑" type="button"
|
||||
class="layui-btn layui-btn-sm"><i
|
||||
class="layui-icon layui-icon-login-weibo"></i></a>
|
||||
<else/>
|
||||
<a href="{:url('/third/bind')}?type=wiebo&ref=/user/index" title="点击绑定" type="button"
|
||||
target="_top"
|
||||
class="layui-btn layui-btn-sm layui-bind-third"><i
|
||||
class="layui-icon layui-icon-login-weibo"></i></a>
|
||||
</if>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">APP KEY</div>
|
||||
<div id="appkey" class="layui-card-body">
|
||||
<notempty name="user.app_id">
|
||||
<div class="layui-form">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">app_id:</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-form-mid layui-word-aux">{$user.app_id}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">app_secret:</label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-form-mid layui-word-aux">{$user.app_secret}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<button type="submit" class="layui-btn layui-btn-normal" lay-ajax=""
|
||||
data-url="/user/appid" data-reload="self">更换APPKEY
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<else/>
|
||||
<div class="layui-form">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-form-mid layui-word-aux">还没有生成appKey,请点击按钮生成!</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<button type="submit" class="layui-btn layui-btn-normal" lay-ajax=""
|
||||
data-url="/user/appid" data-reload="self">生成APPKEY
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</notempty>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- // 修改用户昵称 -->
|
||||
<script type="text/html" id="nickname">
|
||||
<div class="layui-fluid layui-bg-white">
|
||||
<form class="layui-form layui-form-fixed" action="/user/profile">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('用户昵称')}</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="nickname" autocomplete="off" placeholder="{:__('请输入昵称')}" type="text"
|
||||
class="layui-input" lay-verify="required"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-footer layui-form-item layui-center">
|
||||
<button class="layui-btn layui-btn-primary" type="button" sa-event="closeDialog">{:__('取消')}</button>
|
||||
<button class="layui-btn layui-btn-normal" lay-filter="submitPage" data-reload="parent" lay-submit>
|
||||
{:__('提交')}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
layui.use(['jquery', 'upload'], function () {
|
||||
var $ = layui.jquery;
|
||||
var upload = layui.upload;
|
||||
|
||||
// 上传头像
|
||||
upload.render({
|
||||
elem: '.layui-user-avatar'
|
||||
, url: '/user/avatar?action=avatar' // 默认的上传地址
|
||||
, method: 'post'
|
||||
, accept: 'image'
|
||||
, before: function (res) {
|
||||
layer.msg('上传中');
|
||||
}, done: function (res, index, upload) {
|
||||
// 上传成功
|
||||
if (res.code === 200) {
|
||||
$('.avatar').attr('src', res.url + '?' + parseInt(100 * Math.random()));
|
||||
return layer.msg(res.msg);
|
||||
}
|
||||
|
||||
layer.msg(res.msg, 'error');
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
30
app/index/view/user/protection.html
Normal file
30
app/index/view/user/protection.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<layout name="layout:layout"/>
|
||||
<!-- 内容主体区域 -->
|
||||
<div id="content">
|
||||
<div class="layui-fluid">
|
||||
<form class="layui-form layui-form-fixed" action="/user/protection">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('密保问题')}</label>
|
||||
<div class="layui-input-inline" style="width: 260px">
|
||||
<select name="question" lay-verify="required">
|
||||
<volist name="validate" id="vo">
|
||||
<option value="{$vo}">{$vo}</option>
|
||||
</volist>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">{:__('密保答案')}</label>
|
||||
<div class="layui-input-inline" style="width: 260px">
|
||||
<input name="answer" placeholder="{:__('请输入密保答案')}" type="text" class="layui-input"
|
||||
autocomplete="off" lay-verify="required"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-footer layui-form-item layui-center">
|
||||
<button class="layui-btn layui-btn-primary" type="button" sa-event="closeDialog">{:__('取消')}</button>
|
||||
<button class="layui-btn layui-btn-normal" lay-filter="submitIframe" data-reload="parent" lay-submit>{:__('提交')}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
86
app/index/view/user/register.html
Normal file
86
app/index/view/user/register.html
Normal file
@@ -0,0 +1,86 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>SwiftAdmin 用户注册</title>
|
||||
<include file="public:header"/>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
|
||||
.layui-form-item {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.red {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.layui-input:hover {
|
||||
border: 1px solid #1890ff !important;
|
||||
}
|
||||
</style>
|
||||
<div id="register" class="layui-fluid">
|
||||
<form class="layui-form layui-form-fixed" action="/user/register" method="post">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="red">*</span> 用户帐号</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="nickname" placeholder="请输入帐号" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="red">*</span> 密码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="password" id="pwd" name="pwd" placeholder="请输入密码" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="red">*</span> 确认密码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="password" id="repwd" name="repwd" placeholder="请输入确认密码" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<eq name="style" value="mobile">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="red">*</span> 手机号</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" id="mobile" name="mobile" placeholder="请输入手机号" lay-verify="require|phone"
|
||||
class="layui-input mobile">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="red">*</span> 验证码</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="captcha" placeholder="{:__('验证码')}" class="layui-input captcha">
|
||||
<div class="captcha fr">
|
||||
<button id="captcha" type="button" class="layui-btn layui-btn-normal"
|
||||
lay-ajax data-url="/ajax/smssend" data-object="mobile:mobile,event:event"
|
||||
>获取验证码
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<else/>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><span class="red">*</span> 邮箱地址</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="email" lay-verify="require|email" placeholder="请输入邮箱" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
</eq>
|
||||
|
||||
<input type="text" hidden name="event" class="event" value="register">
|
||||
<div class="layui-footer layui-form-item layui-center">
|
||||
<button class="layui-btn layui-btn-primary" type="button" sa-event="closeDialog">{:__('取消')}</button>
|
||||
<button class="layui-btn layui-btn-normal" lay-filter="submitIframe" data-reload="top" lay-submit>
|
||||
{:__('立即注册')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
115
app/index/view/user/security.html
Normal file
115
app/index/view/user/security.html
Normal file
@@ -0,0 +1,115 @@
|
||||
<layout name="layout:layout"/>
|
||||
<div id="content">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header"><h5>安全设置</h5></div>
|
||||
<div class="layui-card-body">
|
||||
<div id="user-detail">
|
||||
<div class="layui-user-avatar fl" >
|
||||
<img src="{$user.avatar}" alt="" width="80">
|
||||
</div>
|
||||
<div class="fl" style="margin-left: 35px">
|
||||
<div class="u-info"><span class="label">会员ID:</span>{$user.id}</div>
|
||||
<div class="u-info"><span class="label">注册日期:</span>{$user.create_time}</div>
|
||||
<div class="u-info">
|
||||
<span class="label">安全级别:</span>
|
||||
<div class="layui-progress layui-progress-big">
|
||||
<div class="layui-progress-bar layui-bg-blue" lay-percent="{$progress}%"></div>
|
||||
</div>
|
||||
<span class="text-stress">建议您启动全部安全设置,以保障账户及资金安全。</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-tier">
|
||||
<div class="settings-detail fl">
|
||||
<span class="setting-status">
|
||||
<i class="layui-icon fa-check"></i>
|
||||
</span>
|
||||
<span class="setting-name">修改密码</span>
|
||||
<span class="setting-intro">安全性高的密码可以使账户更安全;互联网账号存在被盗风险,建议您定期更换密码</span>
|
||||
</div>
|
||||
<div class="setting-operate fr">
|
||||
<a lay-open="" data-title="修改密码" data-url="/user/changepwd" data-area="470px,330px" href="javascript:;">修改</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-tier">
|
||||
<div class="settings-detail fl">
|
||||
<span class="setting-status">
|
||||
<empty name="$user['mobile']">
|
||||
<i class="layui-icon fa-warning"></i>
|
||||
<else/>
|
||||
<i class="layui-icon fa-check"></i>
|
||||
</empty>
|
||||
</span>
|
||||
<span class="setting-name">手机绑定</span>
|
||||
<span class="setting-intro">您的手机:
|
||||
<empty name="$user['mobile']">
|
||||
未绑定
|
||||
<else/>
|
||||
{:hide_str($user['mobile'])}
|
||||
</empty>。绑定认证后可用于手机找回密码、接收手机动态验证码等,保障您的账户安全。
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="setting-operate fr">
|
||||
<a lay-open data-title="修改手机" data-url="/user/mobile" data-area="500px,300px">修改</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-tier">
|
||||
<div class="settings-detail fl">
|
||||
<span class="setting-status">
|
||||
<empty name="$user['email']">
|
||||
<i class="layui-icon fa-warning"></i>
|
||||
<else/>
|
||||
<i class="layui-icon fa-check"></i>
|
||||
</empty>
|
||||
</span>
|
||||
<span class="setting-name">邮箱绑定 </span>
|
||||
<span class="setting-intro">您的邮箱:
|
||||
<empty name="$user['email']">
|
||||
未绑定
|
||||
<else/>
|
||||
{:hide_str($user['email'])}
|
||||
</empty>。绑定认证后可用于邮箱找回密码、接收订单提醒等,保障您的账户安全。
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="setting-operate fr">
|
||||
<a lay-open data-title="修改邮箱" data-url="/user/email" data-area="500px,300px">修改</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-tier">
|
||||
<div class="settings-detail fl">
|
||||
<span class="setting-status">
|
||||
<empty name="$user['answer']">
|
||||
<i class="layui-icon fa-warning"></i>
|
||||
<else/>
|
||||
<i class="layui-icon fa-check"></i>
|
||||
</empty>
|
||||
</span>
|
||||
<span class="setting-name">密保问题 </span>
|
||||
<span class="setting-intro">设置密保问题可以进一步提升您的账户安全性。是您找回登录密码的方式之一。</span>
|
||||
</div>
|
||||
|
||||
<div class="setting-operate fr">
|
||||
<a lay-open data-title="设置密保" data-url="/user/protection" data-area="500px,300px">设置</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-tier">
|
||||
<div class="settings-detail fl">
|
||||
<span class="setting-status">
|
||||
<i class="layui-icon fa-wechat"></i>
|
||||
</span>
|
||||
<span class="setting-name">微信绑定</span>
|
||||
<span class="setting-intro">暂未绑定。 绑定认证后可用于快捷登录、接收微信通知</span>
|
||||
</div>
|
||||
<div class="setting-operate fr"><a href="">绑定</a></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
15
app/index/view/user/userNav.html
Normal file
15
app/index/view/user/userNav.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!--// 初始化菜单-->
|
||||
<ul class="layui-nav layui-nav-tree" lay-filter="master">
|
||||
<li class="layui-nav-item layui-this">
|
||||
<a lay-href="/user/profile">控制台</a>
|
||||
</li>
|
||||
<!--// 前台菜单-->
|
||||
{:get_plugin_menu()}
|
||||
<li class="layui-nav-item">
|
||||
<a class="#" href="javascript:;">账号设置</a>
|
||||
<dl class="layui-nav-child">
|
||||
<dd><a lay-href="/user/security">安全设置</a></dd>
|
||||
</dl>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
Reference in New Issue
Block a user