提交 ed4d83b1 编写于 作者: ModStart's avatar ModStart

develop

上级 388d49f1
- 新增:管理员绑定手机号
\ No newline at end of file
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class ModifyAdminUserAddPhoneEmail extends Migration
{
public function up()
{
$connection = config('modstart.admin.database.connection') ?: config('database.default');
Schema::connection($connection)->table('admin_user', function (Blueprint $table) {
$table->string('phone', 11)->comment('')->nullable();
$table->string('email', 100)->comment('')->nullable();
$table->unique('phone');
$table->unique('email');
});
}
public function down()
{
}
}
......@@ -4,7 +4,7 @@
"Vendor"
],
"title": "后台管理配置",
"version": "1.2.0",
"version": "1.3.0",
"author": "官方",
"description": "提供管理员角色、管理员、管理日志功能"
}
......@@ -15,7 +15,7 @@ class VerifySmsTemplateProvider extends AbstractSmsTemplateProvider
public function title()
{
return '验证码';
return '用户验证码';
}
public function description()
......
......@@ -40,9 +40,10 @@
</div>
</div>
@if(modstart_config('loginCaptchaEnable',false))
@if(modstart_config('loginCaptchaProvider',null))
<?php $providerName = modstart_config('loginCaptchaProvider',null); ?>
@if($providerName && ($provider = \Module\Vendor\Provider\Captcha\CaptchaProvider::get($providerName)))
<div style="padding:0.5rem;">
{!! \Module\Vendor\Provider\Captcha\CaptchaProvider::get(modstart_config('loginCaptchaProvider',null))->render() !!}
{!! $provider->render() !!}
</div>
@else
<div class="line">
......
......@@ -7,6 +7,13 @@ namespace Module\Vendor\Provider\Captcha;
abstract class AbstractCaptchaProvider
{
protected $param = [];
public function setParam($key, $value)
{
$this->param[$key] = $value;
}
abstract public function name();
abstract public function title();
......
......@@ -51,7 +51,7 @@ class CaptchaProvider
return $item;
}
}
BizException::throws('没有找到CaptchaProvider');
return null;
}
......
!function(r){var n={};function o(e){if(n[e])return n[e].exports;var t=n[e]={i:e,l:!1,exports:{}};return r[e].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.m=r,o.c=n,o.d=function(e,t,r){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(o.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)o.d(r,n,function(e){return t[e]}.bind(null,n));return r},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="/asset//",o(o.s=294)}({294:function(e,t,r){var i=r(5);window.api.commonVerify=function(e){var r=i.extend({generateServer:"",selectorTarget:"",selectorGenerate:"",selectorCountdown:"",selectorRegenerate:"",selectorCaptcha:"",selectorCaptchaImg:"",interval:60,tipError:function(e){window.api.dialog.tipError(e)},sendError:function(e){window.api.dialog.tipError(e)}},e),n=0,o=function(){var e=i(r.selectorCountdown);e.is("input")?e.val(n+" s"):e.html(n+" s"),0<n?(n--,setTimeout(o,1e3),i(r.selectorCountdown).show(),i(r.selectorRegenerate).hide()):(e.hide(),i(r.selectorCountdown).hide(),i(r.selectorRegenerate).show())},a=!1,e=function(){var e=i(r.selectorTarget).val(),t=null;return r.selectorCaptcha&&!(t=i(r.selectorCaptcha).val())?r.tipError("图片验证码为空"):a||(a=!0,window.api.dialog.loadingOn(),window.api.base.post(r.generateServer,{target:e,captcha:t},function(e){window.api.dialog.loadingOff(),a=!1,window.api.base.defaultFormCallback(e,{success:function(e){e.data&&alert(e.data),i(r.selectorGenerate).hide(),n=r.interval,o(n)},error:function(e){i(r.selectorCaptchaImg).click(),e.data&&alert(e.data),r.sendError(e.msg)}})})),!1};i(r.selectorGenerate).on("click",e),i(r.selectorRegenerate).on("click",e)}},5:function(e,t){e.exports=window.$}});
\ No newline at end of file
!function(r){var n={};function o(e){if(n[e])return n[e].exports;var t=n[e]={i:e,l:!1,exports:{}};return r[e].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.m=r,o.c=n,o.d=function(e,t,r){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(o.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)o.d(r,n,function(e){return t[e]}.bind(null,n));return r},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="/asset//",o(o.s=294)}({294:function(e,t,r){var c=r(5);window.api.commonVerify=function(e){var n=c.extend({generateServer:"",selectorTarget:"",selectorGenerate:"",selectorCountdown:"",selectorRegenerate:"",selectorCaptcha:"",selectorCaptchaImg:"",interval:60,tipError:function(e){window.api.dialog.tipError(e)},sendError:function(e){window.api.dialog.tipError(e)},formData:function(){return{}}},e),o=0,a=function(){var e=c(n.selectorCountdown);e.is("input")?e.val(o+" s"):e.html(o+" s"),0<o?(o--,setTimeout(a,1e3),c(n.selectorCountdown).show(),c(n.selectorRegenerate).hide()):(e.hide(),c(n.selectorCountdown).hide(),c(n.selectorRegenerate).show())},i=!1,e=function(){var e=c(n.selectorTarget).val(),t=null;if(n.selectorCaptcha&&!(t=c(n.selectorCaptcha).val()))return n.tipError("图片验证码为空"),!1;if(i)return!1;i=!0,window.api.dialog.loadingOn();var r=n.formData();return window.api.base.post(n.generateServer,Object.assign(r,{target:e,captcha:t}),function(e){window.api.dialog.loadingOff(),i=!1,window.api.base.defaultFormCallback(e,{success:function(e){e.data&&alert(e.data),c(n.selectorGenerate).hide(),o=n.interval,a(o)},error:function(e){c(n.selectorCaptchaImg).click(),e.data&&alert(e.data),n.sendError(e.msg)}})}),!1};c(n.selectorGenerate).on("click",e),c(n.selectorRegenerate).on("click",e)}},5:function(e,t){e.exports=window.$}});
\ No newline at end of file
!function(r){var n={};function o(e){if(n[e])return n[e].exports;var t=n[e]={i:e,l:!1,exports:{}};return r[e].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.m=r,o.c=n,o.d=function(e,t,r){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(o.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)o.d(r,n,function(e){return t[e]}.bind(null,n));return r},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="/asset//",o(o.s=294)}({294:function(e,t,r){var i=r(5);window.api.commonVerify=function(e){var r=i.extend({generateServer:"",selectorTarget:"",selectorGenerate:"",selectorCountdown:"",selectorRegenerate:"",selectorCaptcha:"",selectorCaptchaImg:"",interval:60,tipError:function(e){window.api.dialog.tipError(e)},sendError:function(e){window.api.dialog.tipError(e)}},e),n=0,o=function(){var e=i(r.selectorCountdown);e.is("input")?e.val(n+" s"):e.html(n+" s"),0<n?(n--,setTimeout(o,1e3),i(r.selectorCountdown).show(),i(r.selectorRegenerate).hide()):(e.hide(),i(r.selectorCountdown).hide(),i(r.selectorRegenerate).show())},a=!1,e=function(){var e=i(r.selectorTarget).val(),t=null;return r.selectorCaptcha&&!(t=i(r.selectorCaptcha).val())?r.tipError("图片验证码为空"):a||(a=!0,window.api.dialog.loadingOn(),window.api.base.post(r.generateServer,{target:e,captcha:t},function(e){window.api.dialog.loadingOff(),a=!1,window.api.base.defaultFormCallback(e,{success:function(e){e.data&&alert(e.data),i(r.selectorGenerate).hide(),n=r.interval,o(n)},error:function(e){i(r.selectorCaptchaImg).click(),e.data&&alert(e.data),r.sendError(e.msg)}})})),!1};i(r.selectorGenerate).on("click",e),i(r.selectorRegenerate).on("click",e)}},5:function(e,t){e.exports=window.$}});
\ No newline at end of file
!function(r){var n={};function o(e){if(n[e])return n[e].exports;var t=n[e]={i:e,l:!1,exports:{}};return r[e].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.m=r,o.c=n,o.d=function(e,t,r){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(o.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)o.d(r,n,function(e){return t[e]}.bind(null,n));return r},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="/asset//",o(o.s=294)}({294:function(e,t,r){var c=r(5);window.api.commonVerify=function(e){var n=c.extend({generateServer:"",selectorTarget:"",selectorGenerate:"",selectorCountdown:"",selectorRegenerate:"",selectorCaptcha:"",selectorCaptchaImg:"",interval:60,tipError:function(e){window.api.dialog.tipError(e)},sendError:function(e){window.api.dialog.tipError(e)},formData:function(){return{}}},e),o=0,a=function(){var e=c(n.selectorCountdown);e.is("input")?e.val(o+" s"):e.html(o+" s"),0<o?(o--,setTimeout(a,1e3),c(n.selectorCountdown).show(),c(n.selectorRegenerate).hide()):(e.hide(),c(n.selectorCountdown).hide(),c(n.selectorRegenerate).show())},i=!1,e=function(){var e=c(n.selectorTarget).val(),t=null;if(n.selectorCaptcha&&!(t=c(n.selectorCaptcha).val()))return n.tipError("图片验证码为空"),!1;if(i)return!1;i=!0,window.api.dialog.loadingOn();var r=n.formData();return window.api.base.post(n.generateServer,Object.assign(r,{target:e,captcha:t}),function(e){window.api.dialog.loadingOff(),i=!1,window.api.base.defaultFormCallback(e,{success:function(e){e.data&&alert(e.data),c(n.selectorGenerate).hide(),o=n.interval,a(o)},error:function(e){c(n.selectorCaptchaImg).click(),e.data&&alert(e.data),n.sendError(e.msg)}})}),!1};c(n.selectorGenerate).on("click",e),c(n.selectorRegenerate).on("click",e)}},5:function(e,t){e.exports=window.$}});
\ No newline at end of file
......@@ -182,4 +182,6 @@ return [
'Edit file' => '编辑文件',
'Reverse Select Order' => '反转选择顺序',
'Expand All' => '展开全部',
'Phone' => '手机',
'Email' => '邮箱',
];
......@@ -16,6 +16,9 @@ var CommonVerify = function (option) {
},
sendError: function (msg) {
window.api.dialog.tipError(msg);
},
formData: function () {
return {}
}
}, option);
......@@ -55,7 +58,11 @@ var CommonVerify = function (option) {
}
sending = true;
window.api.dialog.loadingOn();
window.api.base.post(opt.generateServer, {target: target, captcha: captcha}, function (res) {
var formData = opt.formData();
window.api.base.post(opt.generateServer, Object.assign(formData, {
target: target,
captcha: captcha
}), function (res) {
window.api.dialog.loadingOff();
sending = false;
window.api.base.defaultFormCallback(res, {
......
......@@ -29,7 +29,13 @@ class AdminUserController extends Controller
{
$grid = new Grid(AdminUser::class, function (Grid $grid) {
$grid->display('id', L('ID'))->sortable(true)->width(80);
$grid->text('username', L('Username'))->width(100);
$grid->text('username', L('Username'));
if (modstart_config('AdminManagerEnhance_EnablePhone', false)) {
$grid->text('phone', L('Phone'));
}
if (modstart_config('AdminManagerEnhance_EnableEmail', false)) {
$grid->text('email', L('Email'));
}
$grid->tags('roles', L('Roles'))->hookFormatValue(function ($value, AbstractField $field) {
$item = $field->item();
/** @var \stdClass $item */
......@@ -38,8 +44,8 @@ class AdminUserController extends Controller
}
return collect($value)->pluck('name')->toArray();
});
$grid->text('lastLoginTime', L('Last Login Time'))->width(150);
$grid->text('lastLoginIp', L('Last Login Ip'))->width(150);
$grid->text('lastLoginTime', L('Last Login Time'));
$grid->text('lastLoginIp', L('Last Login Ip'));
$grid->gridFilter(function (GridFilter $filter) {
$filter->eq('id', L('ID'));
$filter->like('username', L('Username'));
......@@ -67,6 +73,12 @@ class AdminUserController extends Controller
->hookFormatValue(function ($value, AbstractField $field) {
return '';
});
if (modstart_config('AdminManagerEnhance_EnablePhone', false)) {
$form->text('phone', L('Phone'))->ruleUnique('admin_user');
}
if (modstart_config('AdminManagerEnhance_EnableEmail', false)) {
$form->text('email', L('Email'))->ruleUnique('admin_user');
}
/** @var AdminUser $item */
$item = $form->item();
$rolesField = $form->checkbox('roles', L('Roles'))
......@@ -120,6 +132,12 @@ class AdminUserController extends Controller
$detail = new Detail(AdminUser::class, function (Detail $detail) {
$detail->display('id', L('ID'));
$detail->text('username', L('Username'));
if (modstart_config('AdminManagerEnhance_EnablePhone', false)) {
$detail->text('phone', L('Phone'));
}
if (modstart_config('AdminManagerEnhance_EnableEmail', false)) {
$detail->text('email', L('Email'));
}
$detail->tags('roles', L('Roles'))->hookFormatValue(function ($value, AbstractField $field) {
$item = $field->item();
/** @var \stdClass $item */
......
......@@ -12,6 +12,7 @@ use ModStart\Core\Input\InputPackage;
use ModStart\Core\Input\Request;
use ModStart\Core\Input\Response;
use ModStart\Core\Util\StrUtil;
use Module\Vendor\Provider\Captcha\CaptchaProvider;
class AuthController extends Controller
{
......@@ -41,8 +42,17 @@ class AuthController extends Controller
return Response::json(-2, L('Password Required'));
}
if (config('modstart.admin.login.captcha', false)) {
if (!Captcha::check($input->getTrimString('captcha'))) {
return Response::json(-1, L('Captcha Incorrect'), null, "[js]$('[data-captcha]').click();");
$providerName = modstart_config('AdminManagerEnhance_LoginCaptchaProvider', null);
if ($providerName && ($provider = CaptchaProvider::get($providerName))) {
$provider->setParam('biz', 'admin');
$ret = $provider->validate();
if (Response::isError($ret)) {
return Response::jsonFromGenerate($ret);
}
} else {
if (!Captcha::check($input->getTrimString('captcha'))) {
return Response::json(-1, L('Captcha Incorrect'), null, "[js]$('[data-captcha]').click();");
}
}
}
$ret = Admin::login($username, $password);
......
......@@ -19,17 +19,25 @@
<input type="password" name="password" value="{{\Illuminate\Support\Facades\Input::get('password','')}}" placeholder="{{ L('Please Input') }}"/>
</div>
@if(config('modstart.admin.login.captcha',false))
<div class="line">
{{ L('Captcha') }}
<div class="row">
<div class="col-6">
<input type="text" name="captcha" value="" autocomplete="off" placeholder="{{ L('Please Input') }}"/>
</div>
<div class="col-6">
<img data-captcha style="height:40px;width:100%;border:1px solid #CCC;border-radius:3px;" data-uk-tooltip title="{{ L('Click To Refresh') }}" src="{{action('\ModStart\Admin\Controller\AuthController@loginCaptcha')}}" onclick="this.src='{{action('\ModStart\Admin\Controller\AuthController@loginCaptcha')}}?'+Math.random();" />
<?php $providerName = modstart_config('AdminManagerEnhance_LoginCaptchaProvider',null); ?>
@if($providerName && ($provider = \Module\Vendor\Provider\Captcha\CaptchaProvider::get($providerName)))
<?php $provider->setParam('biz','admin'); ?>
<div style="padding:0.5rem;">
{!! $provider->render() !!}
</div>
@else
<div class="line">
{{ L('Captcha') }}
<div class="row">
<div class="col-6">
<input type="text" name="captcha" value="" autocomplete="off" placeholder="{{ L('Please Input') }}"/>
</div>
<div class="col-6">
<img data-captcha style="height:40px;width:100%;border:1px solid #CCC;border-radius:3px;" data-uk-tooltip title="{{ L('Click To Refresh') }}" src="{{action('\ModStart\Admin\Controller\AuthController@loginCaptcha')}}" onclick="this.src='{{action('\ModStart\Admin\Controller\AuthController@loginCaptcha')}}?'+Math.random();" />
</div>
</div>
</div>
</div>
@endif
@endif
<div class="line">
<input type="hidden" name="redirect" value="<?php echo htmlspecialchars(\Illuminate\Support\Facades\Input::get('redirect',config('env.ADMIN_PATH','/admin/'))); ?>">
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册