mirror of
https://github.com/cjango/dcat-vue.git
synced 2025-12-07 06:50:03 +08:00
合并验证码
This commit is contained in:
17
README.md
17
README.md
@@ -100,6 +100,23 @@
|
|||||||
->optionsFromKeyValue('kvs'); // 用于结合vKeyValue进行选项选择
|
->optionsFromKeyValue('kvs'); // 用于结合vKeyValue进行选项选择
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##### 登录验证码
|
||||||
|

|
||||||
|
|
||||||
|
```php
|
||||||
|
class SettingController extends Controller
|
||||||
|
{
|
||||||
|
public function index(Content $content): Content
|
||||||
|
{
|
||||||
|
$tab = Tab::make();
|
||||||
|
$tab->add('站点配置', new AuthSetting());
|
||||||
|
|
||||||
|
return $content->title('配置')
|
||||||
|
->body($tab->withCard());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
[comment]: <> (### Donate)
|
[comment]: <> (### Donate)
|
||||||
|
|
||||||
[comment]: <> ()
|
[comment]: <> ()
|
||||||
|
|||||||
12
resources/lang/en/auth.php
Normal file
12
resources/lang/en/auth.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'captcha' => 'Captcha',
|
||||||
|
'enable_captcha' => 'Enable Captcha',
|
||||||
|
'background' => 'Auth Background',
|
||||||
|
'footer' => 'Footer',
|
||||||
|
'footers' => [
|
||||||
|
'name' => 'ICP',
|
||||||
|
'path' => 'Link'
|
||||||
|
],
|
||||||
|
];
|
||||||
12
resources/lang/zh_CN/auth.php
Normal file
12
resources/lang/zh_CN/auth.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'captcha' => '验证码',
|
||||||
|
'enable_captcha' => '开启验证码',
|
||||||
|
'background' => '登录背景',
|
||||||
|
'footer' => '页脚',
|
||||||
|
'footers' => [
|
||||||
|
'name' => '备案号',
|
||||||
|
'path' => '链接'
|
||||||
|
],
|
||||||
|
];
|
||||||
239
resources/views/login.blade.php
Normal file
239
resources/views/login.blade.php
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
<style>
|
||||||
|
.login-box {
|
||||||
|
margin-top: -10rem;
|
||||||
|
padding: 5px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-card-body {
|
||||||
|
padding: 1.5rem 1.8rem 1.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card, .card-body {
|
||||||
|
width: inherit;
|
||||||
|
border-radius: .25rem
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-btn {
|
||||||
|
padding-left: 2rem !important;;
|
||||||
|
padding-right: 1.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group .control-label {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#auth-captcha {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-page {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 100vh;
|
||||||
|
background: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-footer {
|
||||||
|
width: 100vw;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: rgba(1, 1, 1, 0.2);
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-footer a {
|
||||||
|
color: #d3d3d3;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
min-height: 720px!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
@if($config->get('background'))
|
||||||
|
body {
|
||||||
|
background-image: url("{{ \Illuminate\Support\Facades\Storage::url($config->get('background')) }}");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
min-height: 720px!important;
|
||||||
|
}
|
||||||
|
@endif
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="auth-page">
|
||||||
|
<div class="login-box">
|
||||||
|
<div class="login-logo mb-2">
|
||||||
|
{{ config('admin.name') }}
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body login-card-body shadow-100">
|
||||||
|
<p class="login-box-msg mt-1 mb-1">{{ __('admin.welcome_back') }}</p>
|
||||||
|
|
||||||
|
<form id="login-form" method="POST" action="{{ admin_url('auth/login') }}">
|
||||||
|
|
||||||
|
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
|
||||||
|
|
||||||
|
<fieldset class="form-label-group form-group position-relative has-icon-left">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-control {{ $errors->has('username') ? 'is-invalid' : '' }}"
|
||||||
|
name="username"
|
||||||
|
placeholder="{{ trans('admin.username') }}"
|
||||||
|
value="{{ old('username') }}"
|
||||||
|
required
|
||||||
|
autofocus
|
||||||
|
>
|
||||||
|
|
||||||
|
<div class="form-control-position">
|
||||||
|
<i class="feather icon-user"></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label for="email">{{ trans('admin.username') }}</label>
|
||||||
|
|
||||||
|
<div class="help-block with-errors"></div>
|
||||||
|
@if($errors->has('username'))
|
||||||
|
<span class="invalid-feedback text-danger" role="alert">
|
||||||
|
@foreach($errors->get('username') as $message)
|
||||||
|
<span class="control-label" for="inputError"><i
|
||||||
|
class="feather icon-x-circle"></i> {{$message}}</span><br>
|
||||||
|
@endforeach
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset class="form-label-group form-group position-relative has-icon-left">
|
||||||
|
<input
|
||||||
|
minlength="5"
|
||||||
|
maxlength="20"
|
||||||
|
id="password"
|
||||||
|
type="password"
|
||||||
|
class="form-control {{ $errors->has('password') ? 'is-invalid' : '' }}"
|
||||||
|
name="password"
|
||||||
|
placeholder="{{ trans('admin.password') }}"
|
||||||
|
required
|
||||||
|
autocomplete="current-password"
|
||||||
|
>
|
||||||
|
|
||||||
|
<div class="form-control-position">
|
||||||
|
<i class="feather icon-lock"></i>
|
||||||
|
</div>
|
||||||
|
<label for="password">{{ trans('admin.password') }}</label>
|
||||||
|
|
||||||
|
<div class="help-block with-errors"></div>
|
||||||
|
@if($errors->has('password'))
|
||||||
|
<span class="invalid-feedback text-danger" role="alert">
|
||||||
|
@foreach($errors->get('password') as $message)
|
||||||
|
<span class="control-label" for="inputError"><i
|
||||||
|
class="feather icon-x-circle"></i> {{$message}}</span><br>
|
||||||
|
@endforeach
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
@if($config->get('enable_captcha'))
|
||||||
|
<fieldset class="row">
|
||||||
|
<div class="col-8 form-label-group form-group position-relative has-icon-left">
|
||||||
|
<input
|
||||||
|
minlength="4"
|
||||||
|
maxlength="4"
|
||||||
|
id="captcha"
|
||||||
|
type="text"
|
||||||
|
class="form-control {{ $errors->has('captcha') ? 'is-invalid' : '' }}"
|
||||||
|
name="captcha"
|
||||||
|
placeholder="{{ \Weiwait\DcatVue\DcatVueServiceProvider::trans('auth.captcha') }}"
|
||||||
|
required
|
||||||
|
>
|
||||||
|
|
||||||
|
<div class="form-control-position">
|
||||||
|
<i class="feather icon-feather"></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label class="pl-1"
|
||||||
|
for="captcha">{{ \Weiwait\DcatVue\DcatVueServiceProvider::trans('auth.captcha') }}</label>
|
||||||
|
|
||||||
|
<div class="help-block with-errors"></div>
|
||||||
|
@if($errors->has('captcha'))
|
||||||
|
<span class="invalid-feedback text-danger" role="alert">
|
||||||
|
@foreach($errors->get('captcha') as $message)
|
||||||
|
<span class="control-label" for="inputError"><i
|
||||||
|
class="feather icon-x-circle"></i> {{$message}}</span><br>
|
||||||
|
@endforeach
|
||||||
|
</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-4 pl-0">
|
||||||
|
<img src="{{ captcha_src() }}" alt=""
|
||||||
|
onclick="this.src = '{{ captcha_src() }}' + Math.random()"
|
||||||
|
id="auth-captcha">
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="form-group d-flex justify-content-between align-items-center">
|
||||||
|
<div class="text-left">
|
||||||
|
@if(config('admin.auth.remember'))
|
||||||
|
<fieldset class="checkbox">
|
||||||
|
<div class="vs-checkbox-con vs-checkbox-primary">
|
||||||
|
<input id="remember" name="remember" value="1"
|
||||||
|
type="checkbox" {{ old('remember') ? 'checked' : '' }}>
|
||||||
|
<span class="vs-checkbox">
|
||||||
|
<span class="vs-checkbox--check">
|
||||||
|
<i class="vs-icon feather icon-check"></i>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span> {{ trans('admin.remember_me') }}</span>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary float-right login-btn">
|
||||||
|
|
||||||
|
{{ __('admin.login') }}
|
||||||
|
|
||||||
|
<i class="feather icon-arrow-right"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if($config->get('footer'))
|
||||||
|
<div class="auth-footer">
|
||||||
|
@foreach($config->get('footer') as $item)
|
||||||
|
<a href="{{ $item['path'] }}">{{$item['name']}}</a>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Dcat.ready(function () {
|
||||||
|
// ajax表单提交
|
||||||
|
$('#login-form').form({
|
||||||
|
validate: true,
|
||||||
|
error() {
|
||||||
|
document.querySelector('#auth-captcha').src = '{{ captcha_src() }}' + Math.random()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -74,10 +74,9 @@ class DcatVueServiceProvider extends ServiceProvider
|
|||||||
|
|
||||||
$configs = collect(admin_setting_array('weiwait_filesystem'));
|
$configs = collect(admin_setting_array('weiwait_filesystem'));
|
||||||
|
|
||||||
// dd($configs);
|
|
||||||
|
|
||||||
app()->booted(function () use ($configs) {
|
app()->booted(function () use ($configs) {
|
||||||
Helper::injectFilesystemConfig($configs);
|
Helper::injectFilesystemConfig($configs);
|
||||||
|
Helper::injectAuthConfigs();
|
||||||
});
|
});
|
||||||
|
|
||||||
Event::listen('admin:booted', function () use ($configs) {
|
Event::listen('admin:booted', function () use ($configs) {
|
||||||
|
|||||||
51
src/Forms/AuthSetting.php
Normal file
51
src/Forms/AuthSetting.php
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Weiwait\DcatVue\Forms;
|
||||||
|
|
||||||
|
use Dcat\Admin\Extend\Setting as Form;
|
||||||
|
use Dcat\Admin\Form\NestedForm;
|
||||||
|
use Illuminate\Support\Facades\Artisan;
|
||||||
|
use Weiwait\DcatVue\DcatVueServiceProvider;
|
||||||
|
|
||||||
|
class AuthSetting extends Form
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle the form request.
|
||||||
|
*
|
||||||
|
* @param array $input
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle(array $input)
|
||||||
|
{
|
||||||
|
admin_setting(['weiwait_auth' => $input]);
|
||||||
|
|
||||||
|
is_file(app()->getCachedConfigPath()) && Artisan::call('config:cache');
|
||||||
|
|
||||||
|
return $this
|
||||||
|
->response()
|
||||||
|
->success('保存成功')
|
||||||
|
->refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function form()
|
||||||
|
{
|
||||||
|
$this->switch('enable_captcha', DcatVueServiceProvider::trans('auth.enable_captcha'))
|
||||||
|
->default(true);
|
||||||
|
$this->vImage('background', DcatVueServiceProvider::trans('auth.background'));
|
||||||
|
$this->array('footer', DcatVueServiceProvider::trans('auth.footer'), function (NestedForm $form) {
|
||||||
|
$form->text('name', DcatVueServiceProvider::trans('auth.footers.name'));
|
||||||
|
$form->text('path', DcatVueServiceProvider::trans('auth.footers.path'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The data of the form.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function default()
|
||||||
|
{
|
||||||
|
return admin_setting_array('weiwait_auth');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -103,4 +103,12 @@ class Helper
|
|||||||
// 获取临时密钥,计算签名
|
// 获取临时密钥,计算签名
|
||||||
return (new Sts())->getTempKeys($config);
|
return (new Sts())->getTempKeys($config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function injectAuthConfigs()
|
||||||
|
{
|
||||||
|
config()->set('captcha.default.length', 4);
|
||||||
|
config()->set('captcha.default.height', 34);
|
||||||
|
config()->set('captcha.default.width', 100);
|
||||||
|
config()->set('captcha.default.quality', 100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
58
src/Http/Controllers/DcatAuthController.php
Normal file
58
src/Http/Controllers/DcatAuthController.php
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Weiwait\DcatVue\Http\Controllers;
|
||||||
|
|
||||||
|
use Dcat\Admin\Http\Controllers\AuthController;
|
||||||
|
use Dcat\Admin\Layout\Content;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
|
||||||
|
class DcatAuthController extends AuthController
|
||||||
|
{
|
||||||
|
protected Collection $config;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->config = collect(admin_setting()->getArray('weiwait_auth'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLogin(Content $content)
|
||||||
|
{
|
||||||
|
if ($this->guard()->check()) {
|
||||||
|
return redirect($this->getRedirectPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $content->full()->body(view('weiwait.dcat-vue::login', ['config' => $this->config]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function postLogin(Request $request)
|
||||||
|
{
|
||||||
|
$credentials = $request->only([$this->username(), 'password']);
|
||||||
|
$remember = (bool) $request->input('remember', false);
|
||||||
|
|
||||||
|
$rules = [
|
||||||
|
$this->username() => 'required',
|
||||||
|
'password' => 'required',
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($this->config->get('enable_captcha')) {
|
||||||
|
$rules['captcha'] = 'required|captcha';
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var \Illuminate\Validation\Validator $validator */
|
||||||
|
$validator = Validator::make($request->all(), $rules, ['captcha.captcha' => '验证码错误']);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
return $this->validationErrorsResponse($validator);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->guard()->attempt($credentials, $remember)) {
|
||||||
|
return $this->sendLoginResponse($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->validationErrorsResponse([
|
||||||
|
$this->username() => $this->getFailedLoginMessage(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,3 +23,7 @@ Route::get('weiwait/distpicker/address2ll', [Controllers\DcatVueController::clas
|
|||||||
// 坐标位置信息
|
// 坐标位置信息
|
||||||
Route::get('weiwait/distpicker/ll2address', [Controllers\DcatVueController::class, 'll2address'])
|
Route::get('weiwait/distpicker/ll2address', [Controllers\DcatVueController::class, 'll2address'])
|
||||||
->name('weiwait.distpicker.ll2address');
|
->name('weiwait.distpicker.ll2address');
|
||||||
|
|
||||||
|
// 替换原生登录
|
||||||
|
Route::get('auth/login', [Controllers\DcatAuthController::class, 'getLogin']);
|
||||||
|
Route::post('auth/login', [Controllers\DcatAuthController::class, 'postLogin']);
|
||||||
|
|||||||
@@ -3,16 +3,35 @@
|
|||||||
namespace Weiwait\DcatVue;
|
namespace Weiwait\DcatVue;
|
||||||
|
|
||||||
use Dcat\Admin\Extend\Setting as Form;
|
use Dcat\Admin\Extend\Setting as Form;
|
||||||
|
use Dcat\Admin\Form\NestedForm;
|
||||||
|
use Dcat\Admin\Http\JsonResponse;
|
||||||
|
|
||||||
class Setting extends Form
|
class Setting extends Form
|
||||||
{
|
{
|
||||||
public function form()
|
public function form()
|
||||||
{
|
{
|
||||||
// Todo
|
$this->tab('站点', function (\Dcat\Admin\Widgets\Form $form) {
|
||||||
|
$form->switch('weiwait_auth.enable_captcha', DcatVueServiceProvider::trans('auth.enable_captcha'))
|
||||||
|
->default(true);
|
||||||
|
$form->vImage('weiwait_auth.background', DcatVueServiceProvider::trans('auth.background'));
|
||||||
|
$form->array('weiwait_auth.footer', DcatVueServiceProvider::trans('auth.footer'), function (NestedForm $form) {
|
||||||
|
$form->text('name', DcatVueServiceProvider::trans('auth.footers.name'));
|
||||||
|
$form->text('path', DcatVueServiceProvider::trans('auth.footers.path'));
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle(array $input)
|
public function handle(array $input): JsonResponse
|
||||||
{
|
{
|
||||||
// Todo
|
admin_setting(['weiwait_auth' => $input['weiwait_auth']]);
|
||||||
|
|
||||||
|
return $this->response()->success('保存成功')->refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function default(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'weiwait_auth' => admin_setting_array('weiwait_auth'),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,4 +80,7 @@ return [
|
|||||||
'修复vList为空时dcat依赖的默认值',
|
'修复vList为空时dcat依赖的默认值',
|
||||||
'一些优化',
|
'一些优化',
|
||||||
],
|
],
|
||||||
|
'2.6.0' => [
|
||||||
|
'合并验证码到此',
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
Reference in New Issue
Block a user