first commit

This commit is contained in:
Mr.Qin
2022-08-19 19:48:37 +08:00
commit afdd648b65
3275 changed files with 631084 additions and 0 deletions

View 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());
}
}
}
}

View 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']);
}
}

View 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);
}
}

View 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);
}
}