This commit is contained in:
hashbro
2026-08-09 02:08:42 +08:00
parent 74a67c3900
commit 5c7600744e
24 changed files with 1510 additions and 70 deletions
@@ -0,0 +1,177 @@
@extends('admin.content')
@section('title', '谷歌验证')
@section('content')
<div class="layui-card">
<div class="layui-card-header">谷歌验证(Google Authenticator)</div>
<div class="layui-card-body">
<p style="margin-bottom:16px;">
当前状态:
@if($enabled)
<span style="color:#16b777;">已开启</span>
@elseif($bound)
<span style="color:#ffb800;">已绑定未开启</span>
@else
<span style="color:#999;">未绑定</span>
@endif
</p>
@if(!$bound)
<form class="layui-form" lay-filter="LAY-ga-prepare" style="max-width:480px;">
<div class="layui-form-item">
<label class="layui-form-label">登录密码</label>
<div class="layui-input-block">
<input type="password" name="password" required lay-verify="required" class="layui-input" autocomplete="current-password">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="LAY-ga-prepare">获取绑定二维码</button>
</div>
</div>
</form>
<div id="LAY-ga-bind-box" style="display:none;max-width:480px;margin-top:24px;">
<div id="LAY-ga-qr" style="margin-bottom:12px;"></div>
<p style="margin-bottom:12px;">密钥:<code id="LAY-ga-secret"></code></p>
<form class="layui-form" lay-filter="LAY-ga-bind">
<input type="hidden" name="GASecret" id="LAY-ga-secret-input">
<div class="layui-form-item">
<label class="layui-form-label">验证码</label>
<div class="layui-input-block">
<input type="text" name="GAKey" required lay-verify="required" class="layui-input" inputmode="numeric" autocomplete="one-time-code" placeholder="扫码后输入 6 位验证码">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn layui-btn-normal" lay-submit lay-filter="LAY-ga-bind">确认绑定</button>
</div>
</div>
</form>
</div>
@else
<form class="layui-form" style="max-width:480px;">
<div class="layui-form-item">
<label class="layui-form-label">登录密码</label>
<div class="layui-input-block">
<input type="password" name="password" id="LAY-ga-password" class="layui-input" autocomplete="current-password">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">验证码</label>
<div class="layui-input-block">
<input type="text" name="GACode" id="LAY-ga-code" class="layui-input" inputmode="numeric" autocomplete="one-time-code" placeholder="关闭/解绑时需要">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
@if($enabled)
<button type="button" class="layui-btn layui-btn-warm" id="LAY-ga-close">关闭验证</button>
@else
<button type="button" class="layui-btn" id="LAY-ga-open">开启验证</button>
@endif
<button type="button" class="layui-btn layui-btn-danger" id="LAY-ga-unbind">解除绑定</button>
</div>
</div>
</form>
@endif
</div>
</div>
@endsection
@push('scripts')
<script>
layui.use(['form', 'layer'], function () {
var form = layui.form, layer = layui.layer, $ = layui.$;
var token = @json(csrf_token());
form.on('submit(LAY-ga-prepare)', function (data) {
$.ajax({
url: @json(route('admin.security.google2fa.prepare')),
method: 'POST',
data: Object.assign({}, data.field, { _token: token }),
success: function (res) {
if (res.code === 201) {
layer.msg(res.msg, { icon: 0 }, function () { location.reload(); });
return;
}
if (res.code !== 0) return layer.msg(res.msg || '失败', { icon: 2 });
$('#LAY-ga-qr').html(res.qr_svg || '');
$('#LAY-ga-secret').text(res.secret || '');
$('#LAY-ga-secret-input').val(res.secret || '');
$('#LAY-ga-bind-box').show();
},
error: function (xhr) {
layer.msg((xhr.responseJSON && (xhr.responseJSON.message || xhr.responseJSON.msg)) || '请求失败', { icon: 2 });
}
});
return false;
});
form.on('submit(LAY-ga-bind)', function (data) {
$.ajax({
url: @json(route('admin.security.google2fa.bind')),
method: 'POST',
data: Object.assign({}, data.field, { _token: token }),
success: function (res) {
layer.msg(res.msg || '', { icon: res.code === 0 ? 1 : 2 }, function () {
if (res.code === 0) location.reload();
});
},
error: function (xhr) {
layer.msg((xhr.responseJSON && (xhr.responseJSON.message || xhr.responseJSON.msg)) || '绑定失败', { icon: 2 });
}
});
return false;
});
function toggle(open) {
$.ajax({
url: @json(route('admin.security.google2fa.toggle')),
method: 'POST',
data: {
_token: token,
password: $('#LAY-ga-password').val(),
GACode: $('#LAY-ga-code').val(),
open: open
},
success: function (res) {
layer.msg(res.msg || '', { icon: res.code === 0 ? 1 : 2 }, function () {
if (res.code === 0) location.reload();
});
},
error: function (xhr) {
layer.msg((xhr.responseJSON && (xhr.responseJSON.message || xhr.responseJSON.msg)) || '操作失败', { icon: 2 });
}
});
}
$('#LAY-ga-open').on('click', function () { toggle(1); });
$('#LAY-ga-close').on('click', function () { toggle(0); });
$('#LAY-ga-unbind').on('click', function () {
layer.confirm('确定解除谷歌验证绑定?', function (index) {
$.ajax({
url: @json(route('admin.security.google2fa.unbind')),
method: 'POST',
data: {
_token: token,
password: $('#LAY-ga-password').val(),
GACode: $('#LAY-ga-code').val()
},
success: function (res) {
layer.close(index);
layer.msg(res.msg || '', { icon: res.code === 0 ? 1 : 2 }, function () {
if (res.code === 0) location.reload();
});
},
error: function (xhr) {
layer.msg((xhr.responseJSON && (xhr.responseJSON.message || xhr.responseJSON.msg)) || '解绑失败', { icon: 2 });
}
});
});
});
});
</script>
@endpush