first commit
This commit is contained in:
81
catch/login/LoginLogListener.php
Normal file
81
catch/login/LoginLogListener.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
namespace catchAdmin\login;
|
||||
|
||||
use catchAdmin\user\model\Users;
|
||||
use think\facade\Db;
|
||||
|
||||
class LoginLogListener
|
||||
{
|
||||
public function handle($params)
|
||||
{
|
||||
$agent = request()->header('user-agent');
|
||||
|
||||
$username = Users::where('email', $params['email'])->value('username');
|
||||
|
||||
Db::name('login_log')->insert([
|
||||
'login_name' => $username ? : $params['email'],
|
||||
'login_ip' => request()->ip(),
|
||||
'browser' => $this->getBrowser($agent),
|
||||
'os' => $this->getOs($agent),
|
||||
'login_at' => time(),
|
||||
'status' => $params['success'] ? 1 : 2,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @time 2019年12月12日
|
||||
* @param $agent
|
||||
* @return string
|
||||
*/
|
||||
private function getOs($agent): string
|
||||
{
|
||||
if (false !== stripos($agent, 'win') && preg_match('/nt 6.1/i', $agent)) {
|
||||
return 'Windows 7';
|
||||
}
|
||||
if (false !== stripos($agent, 'win') && preg_match('/nt 6.2/i', $agent)) {
|
||||
return 'Windows 8';
|
||||
}
|
||||
if(false !== stripos($agent, 'win') && preg_match('/nt 10.0/i', $agent)) {
|
||||
return 'Windows 10';#添加win10判断
|
||||
}
|
||||
if (false !== stripos($agent, 'win') && preg_match('/nt 5.1/i', $agent)) {
|
||||
return 'Windows XP';
|
||||
}
|
||||
if (false !== stripos($agent, 'linux')) {
|
||||
return 'Linux';
|
||||
}
|
||||
if (false !== stripos($agent, 'mac')) {
|
||||
return 'mac';
|
||||
}
|
||||
|
||||
return '未知';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @time 2019年12月12日
|
||||
* @param $agent
|
||||
* @return string
|
||||
*/
|
||||
private function getBrowser($agent): string
|
||||
{
|
||||
if (false !== stripos($agent, "MSIE")) {
|
||||
return 'MSIE';
|
||||
}
|
||||
if (false !== stripos($agent, "Firefox")) {
|
||||
return 'Firefox';
|
||||
}
|
||||
if (false !== stripos($agent, "Chrome")) {
|
||||
return 'Chrome';
|
||||
}
|
||||
if (false !== stripos($agent, "Safari")) {
|
||||
return 'Safari';
|
||||
}
|
||||
if (false !== stripos($agent, "Opera")) {
|
||||
return 'Opera';
|
||||
}
|
||||
|
||||
return '未知';
|
||||
}
|
||||
}
|
77
catch/login/controller/Index.php
Normal file
77
catch/login/controller/Index.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
namespace catchAdmin\login\controller;
|
||||
|
||||
use app\exceptions\LoginFailedException;
|
||||
use catchAdmin\user\Auth;
|
||||
use catchAdmin\login\request\LoginRequest;
|
||||
use catcher\base\CatchController;
|
||||
use catcher\CatchResponse;
|
||||
use think\captcha\Captcha;
|
||||
|
||||
class Index extends CatchController
|
||||
{
|
||||
/**
|
||||
* 登录
|
||||
*
|
||||
* @time 2019年11月30日
|
||||
* @throws \Exception
|
||||
* @return string
|
||||
*/
|
||||
public function index(): string
|
||||
{
|
||||
return $this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 登陆
|
||||
*
|
||||
* @time 2019年11月28日
|
||||
* @param LoginRequest $request
|
||||
* @return bool|string
|
||||
* @throws \catcher\exceptions\LoginFailedException
|
||||
* @throws \cather\exceptions\LoginFailedException
|
||||
* @throws LoginFailedException
|
||||
*/
|
||||
public function login(LoginRequest $request)
|
||||
{
|
||||
$params = $request->param();
|
||||
$token = Auth::login($params);
|
||||
// 登录事件
|
||||
$params['success'] = $token;
|
||||
event('loginLog', $params);
|
||||
|
||||
return $token ? CatchResponse::success([
|
||||
'token' => $token,
|
||||
], '登录成功') :
|
||||
|
||||
CatchResponse::success('', '登录失败');
|
||||
}
|
||||
|
||||
/**
|
||||
* 登出
|
||||
*
|
||||
* @time 2019年11月28日
|
||||
* @return \think\response\Json
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function logout(): \think\response\Json
|
||||
{
|
||||
if (Auth::logout()) {
|
||||
return CatchResponse::success();
|
||||
}
|
||||
|
||||
return CatchResponse::fail('登出失败');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @time 2019年12月12日
|
||||
* @param Captcha $captcha
|
||||
* @param null $config
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function captcha(Captcha $captcha, $config = null): \think\Response
|
||||
{
|
||||
return $captcha->create($config);
|
||||
}
|
||||
}
|
13
catch/login/module.json
Normal file
13
catch/login/module.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "登陆",
|
||||
"alias": "login",
|
||||
"description": "",
|
||||
"keywords": [],
|
||||
"order": 1,
|
||||
"services": [
|
||||
"catchAdmin\\login\\LoginService"
|
||||
],
|
||||
"aliases": {},
|
||||
"files": [],
|
||||
"requires": []
|
||||
}
|
23
catch/login/request/LoginRequest.php
Normal file
23
catch/login/request/LoginRequest.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
namespace catchAdmin\login\request;
|
||||
|
||||
use catcher\base\CatchRequest;
|
||||
|
||||
class LoginRequest extends CatchRequest
|
||||
{
|
||||
protected function rules(): array
|
||||
{
|
||||
// TODO: Implement rules() method.
|
||||
return [
|
||||
'email|用户名' => 'email',
|
||||
'password|密码' => 'require',
|
||||
// 'captcha|验证码' => 'require|captcha'
|
||||
];
|
||||
}
|
||||
|
||||
protected function message(): array
|
||||
{
|
||||
// TODO: Implement message() method.
|
||||
return [];
|
||||
}
|
||||
}
|
11
catch/login/route.php
Normal file
11
catch/login/route.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
# 登陆页面
|
||||
$router->get('login', '\catchAdmin\login\controller\Index@index');
|
||||
# 登入
|
||||
$router->post('login', '\catchAdmin\login\controller\Index@login');
|
||||
# 登出
|
||||
$router->post('logout', '\catchAdmin\login\controller\Index@logout');
|
||||
# 验证码
|
||||
$router->get('catch/captcha/[:config]','\catchAdmin\login\controller\Index@captcha');
|
||||
|
130
catch/login/view/index.html
Normal file
130
catch/login/view/index.html
Normal file
@@ -0,0 +1,130 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<title>登录</title>
|
||||
<link rel="stylesheet" href="__CATCH_ADMIN_LIBS__/layui/css/layui.css"/>
|
||||
<link rel="stylesheet" href="__CATCH_ADMIN_CSS__/login.css?v=315">
|
||||
<link rel="stylesheet" href="__CATCH_ADMIN_MODULE__/admin.css?v=315">
|
||||
<!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
<script>
|
||||
if (window != top) {
|
||||
top.location.replace(location.href);
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.captcha {
|
||||
width: 114px;
|
||||
height: 38px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="login-wrapper">
|
||||
<div class="login-header">
|
||||
<img src="__CATCH_ADMIN_IMAGES__/logo.png"> CatchAdmin 后台管理系统
|
||||
</div>
|
||||
<div class="login-body">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">
|
||||
<i class="layui-icon layui-icon-engine"></i> 用户登录
|
||||
</div>
|
||||
<form class="layui-card-body layui-form layui-form-pane">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><i class="layui-icon layui-icon-username"></i></label>
|
||||
<div class="layui-input-block">
|
||||
<input name="email" type="text" placeholder="邮箱" class="layui-input"
|
||||
lay-verType="tips" lay-verify="required|email" required/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><i class="layui-icon layui-icon-password"></i></label>
|
||||
<div class="layui-input-block">
|
||||
<input name="password" type="password" placeholder="密码" class="layui-input"
|
||||
lay-verType="tips" lay-verify="required" required/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label"><i class="layui-icon layui-icon-vercode"></i></label>
|
||||
<div class="layui-input-block">
|
||||
<div class="layui-row inline-block">
|
||||
<div class="layui-col-xs7">
|
||||
<input name="captcha" type="text" placeholder="验证码" class="layui-input"
|
||||
autocomplete="off" lay-verType="tips" lay-verify="required" required/>
|
||||
</div>
|
||||
<div class="layui-col-xs5" style="padding-left: 6px;">
|
||||
<img src="{:url('catch/captcha')}" alt="captcha" class="captcha" onclick="this.src = this.src + '?t=' + (new Date).getTime();"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<!--<a href="javascript:;" class="layui-link">帐号注册</a>-->
|
||||
<!--<a href="javascript:;" class="layui-link pull-right">忘记密码?</a>-->
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<button lay-filter="login-submit" class="layui-btn layui-btn-fluid" lay-submit>登 录</button>
|
||||
</div>
|
||||
<!--<div class="layui-form-item login-other">
|
||||
<label>第三方登录</label>
|
||||
<a href="javascript:;"><i class="layui-icon layui-icon-login-qq"></i></a>
|
||||
<a href="javascript:;"><i class="layui-icon layui-icon-login-wechat"></i></a>
|
||||
<a href="javascript:;"><i class="layui-icon layui-icon-login-weibo"></i></a>
|
||||
</div>-->
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="login-footer">
|
||||
<p>© 2015 ~ {:date('Y', time())} @catchAdmin 版权所有</p>
|
||||
<!--<p>
|
||||
<span><a href="https://easyweb.vip" target="_blank">获取授权</a></span>
|
||||
<span><a href="https://easyweb.vip/doc/" target="_blank">开发文档</a></span>
|
||||
<span><a href="https://demo.easyweb.vip/spa/" target="_blank">单页面版</a></span>
|
||||
</p>-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- js部分 -->
|
||||
<script type="text/javascript" src="__CATCH_ADMIN_LIBS__/layui/layui.js"></script>
|
||||
<script type="text/javascript" src="__CATCH_ADMIN_JS__/common.js?v=315"></script>
|
||||
<script>
|
||||
layui.use(['layer', 'form'], function () {
|
||||
var $ = layui.jquery;
|
||||
var layer = layui.layer;
|
||||
var form = layui.form;
|
||||
|
||||
// 表单提交
|
||||
form.on('submit(login-submit)', function (obj) {
|
||||
$.ajax({
|
||||
url: "{:url('login')}",
|
||||
type: 'post',
|
||||
data: obj.field,
|
||||
success: function(response) {
|
||||
if (response.code === 10000) {
|
||||
layer.msg(response.msg, {
|
||||
icon: 1,
|
||||
time: 2000 //2秒关闭(如果不配置,默认是3秒)
|
||||
}, function () {
|
||||
//do something
|
||||
window.location.href = '/';
|
||||
})
|
||||
} else {
|
||||
layer.msg(response.msg, {
|
||||
icon: 2,
|
||||
time: 2000 //2秒关闭(如果不配置,默认是3秒)
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user