新增验证码长度配置&优化后台管理菜单

pull/354/MERGE
Karson 2021-12-27 15:53:09 +08:00
parent d1cdc51798
commit e3169bcaf4
20 changed files with 114 additions and 77 deletions

View File

@ -449,8 +449,9 @@ class Auth extends \fast\Auth
$referer = [];
}
$select_id = $selected ? $selected['id'] : 0;
$select_id = $referer ? $referer['id'] : ($selected ? $selected['id'] : 0);
$menu = $nav = '';
$showSubmenu = (int)cookie('show_submenu');
if (Config::get('fastadmin.multiplenav')) {
$topList = [];
foreach ($ruleList as $index => $item) {
@ -471,7 +472,7 @@ class Auth extends \fast\Auth
$select_id,
'',
'ul',
'class="treeview-menu"'
'class="treeview-menu' . ($showSubmenu ? ' menu-open' : '') . '"'
);
$current = in_array($item['id'], $selectParentIds);
$url = $childList ? 'javascript:;' : $item['url'];
@ -493,7 +494,7 @@ class Auth extends \fast\Auth
$select_id,
'',
'ul',
'class="treeview-menu"'
'class="treeview-menu' . ($showSubmenu ? ' menu-open' : '') . '"'
);
if ($selected) {
$nav .= '<li role="presentation" id="tab_' . $selected['id'] . '" class="' . ($referer ? '' : 'active') . '"><a href="#con_' . $selected['id'] . '" node-id="' . $selected['id'] . '" aria-controls="' . $selected['id'] . '" role="tab" data-toggle="tab"><i class="' . $selected['icon'] . ' fa-fw"></i> <span>' . $selected['title'] . '</span> </a></li>';

View File

@ -16,8 +16,8 @@
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label>
<div class="col-xs-12 col-sm-8">
<span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><small>{:__('Check all')}</small></label></span>
<span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><small>{:__('Expand all')}</small></label></span>
<span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><span>{:__('Check all')}</span></label></span>
<span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><span>{:__('Expand all')}</span></label></span>
<div id="treeview"></div>
</div>

View File

@ -16,8 +16,8 @@
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Permission')}:</label>
<div class="col-xs-12 col-sm-8">
<span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><small>{:__('Check all')}</small></label></span>
<span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><small>{:__('Expand all')}</small></label></span>
<span class="text-muted"><input type="checkbox" name="" id="checkall" /> <label for="checkall"><span>{:__('Check all')}</span></label></span>
<span class="text-muted"><input type="checkbox" name="" id="expandall" /> <label for="expandall"><span>{:__('Expand all')}</span></label></span>
<div id="treeview"></div>
</div>

View File

@ -29,8 +29,8 @@
</div>
<!--如果想始终显示子菜单,则给ul加上show-submenu类即可,当multiplenav开启的情况下默认为展开-->
<ul class="sidebar-menu {if $Think.config.fastadmin.multiplenav||$Think.cookie.show_submenu}show-submenu{/if}">
<!-- 左侧菜单栏 -->
<ul class="sidebar-menu {if $Think.cookie.show_submenu}show-submenu{/if}">
<!-- 菜单可以在 后台管理->权限管理->菜单规则 中进行增删改排序 -->
{$menulist}

View File

@ -42,7 +42,7 @@
<footer class="main-footer hide">
<div class="pull-right hidden-xs">
</div>
<strong>Copyright &copy; 2017-2020 <a href="__PUBLIC__">{$site.name}</a>.</strong> All rights reserved.
<strong>Copyright &copy; 2017-{:date("Y")} <a href="__PUBLIC__">{$site.name}</a>.</strong> All rights reserved.
</footer>
<!-- 右侧控制栏 -->

View File

@ -113,7 +113,7 @@
{if $Think.config.fastadmin.login_captcha}
<div class="input-group">
<div class="input-group-addon"><span class="glyphicon glyphicon-option-horizontal" aria-hidden="true"></span></div>
<input type="text" name="captcha" class="form-control" placeholder="{:__('Captcha')}" data-rule="{:__('Captcha')}:required;length(4)" autocomplete="off"/>
<input type="text" name="captcha" class="form-control" placeholder="{:__('Captcha')}" data-rule="{:__('Captcha')}:required;length({$Think.config.captcha.length})" autocomplete="off"/>
<span class="input-group-addon" style="padding:0;border:none;cursor:pointer;">
<img src="{:rtrim('__PUBLIC__', '/')}/index.php?s=/captcha" width="100" height="30" onclick="this.src = '{:rtrim('__PUBLIC__', '/')}/index.php?s=/captcha&r=' + Math.random();"/>
</span>

View File

@ -2,6 +2,7 @@
namespace app\common\library;
use fast\Random;
use think\Hook;
/**
@ -49,7 +50,7 @@ class Ems
*/
public static function send($email, $code = null, $event = 'default')
{
$code = is_null($code) ? mt_rand(1000, 9999) : $code;
$code = is_null($code) ? Random::numeric(config('captcha.length')) : $code;
$time = time();
$ip = request()->ip();
$ems = \app\common\model\Ems::create(['event' => $event, 'email' => $email, 'code' => $code, 'ip' => $ip, 'createtime' => $time]);

View File

@ -2,6 +2,7 @@
namespace app\common\library;
use fast\Random;
use think\Hook;
/**
@ -49,7 +50,7 @@ class Sms
*/
public static function send($mobile, $code = null, $event = 'default')
{
$code = is_null($code) ? mt_rand(1000, 9999) : $code;
$code = is_null($code) ? Random::numeric(config('captcha.length')) : $code;
$time = time();
$ip = request()->ip();
$sms = \app\common\model\Sms::create(['event' => $event, 'mobile' => $mobile, 'code' => $code, 'ip' => $ip, 'createtime' => $time]);

View File

@ -1,25 +1,25 @@
<!--@formatter:off-->
{if "[type]" == 'email'}
<input type="text" name="captcha" class="form-control" data-rule="required;length(4);integer[+];remote({:url('api/validate/check_ems_correct')}, event=[event], email:#email)" />
<input type="text" name="captcha" class="form-control" data-rule="required;length({$Think.config.captcha.length});integer[+];remote({:url('api/validate/check_ems_correct')}, event=[event], email:#email)" />
<span class="input-group-btn" style="padding:0;border:none;">
<a href="javascript:;" class="btn btn-info btn-captcha btn-lg" data-url="{:url('api/ems/send')}" data-type="email" data-event="[event]">发送验证码</a>
<a href="javascript:;" class="btn btn-info btn-captcha" data-url="{:url('api/ems/send')}" data-type="email" data-event="[event]">发送验证码</a>
</span>
{elseif "[type]" == 'mobile'/}
<input type="text" name="captcha" class="form-control" data-rule="required;length(4);integer[+];remote({:url('api/validate/check_sms_correct')}, event=[event], mobile:#mobile)" />
<input type="text" name="captcha" class="form-control" data-rule="required;length({$Think.config.captcha.length});integer[+];remote({:url('api/validate/check_sms_correct')}, event=[event], mobile:#mobile)" />
<span class="input-group-btn" style="padding:0;border:none;">
<a href="javascript:;" class="btn btn-info btn-captcha btn-lg" data-url="{:url('api/sms/send')}" data-type="mobile" data-event="[event]">发送验证码</a>
<a href="javascript:;" class="btn btn-info btn-captcha" data-url="{:url('api/sms/send')}" data-type="mobile" data-event="[event]">发送验证码</a>
</span>
{elseif "[type]" == 'wechat'/}
{if get_addon_info('wechat')}
<input type="text" name="captcha" class="form-control" data-rule="required;length(4);remote({:addon_url('wechat/captcha/check')}, event=[event])" />
<input type="text" name="captcha" class="form-control" data-rule="required;length({$Think.config.captcha.length});remote({:addon_url('wechat/captcha/check')}, event=[event])" />
<span class="input-group-btn" style="padding:0;border:none;">
<a href="javascript:;" class="btn btn-info btn-captcha btn-lg" data-url="{:addon_url('wechat/captcha/send')}" data-type="wechat" data-event="[event]">获取验证码</a>
<a href="javascript:;" class="btn btn-info btn-captcha" data-url="{:addon_url('wechat/captcha/send')}" data-type="wechat" data-event="[event]">获取验证码</a>
</span>
{else/}
请在后台插件管理中安装《微信管理插件》
{/if}
{elseif "[type]" == 'text' /}
<input type="text" name="captcha" class="form-control" data-rule="required;length(4)" />
<input type="text" name="captcha" class="form-control" data-rule="required;length({$Think.config.captcha.length})" />
<span class="input-group-btn" style="padding:0;border:none;">
<img src="{:captcha_src()}" width="100" height="32" onclick="this.src = '{:captcha_src()}?r=' + Math.random();"/>
</span>

View File

@ -67,7 +67,7 @@
<label for="captcha" class="control-label col-xs-12 col-sm-3">{:__('Captcha')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input type="text" name="captcha" class="form-control" data-rule="required;length(4);integer[+];remote({:url('api/validate/check_ems_correct')}, event=resetpwd, email:#email)"/>
<input type="text" name="captcha" class="form-control" data-rule="required;length({$Think.config.captcha.length});integer[+];remote({:url('api/validate/check_ems_correct')}, event=resetpwd, email:#email)"/>
<span class="input-group-btn" style="padding:0;border:none;">
<a href="javascript:;" class="btn btn-primary btn-captcha" data-url="{:url('api/ems/send')}" data-type="email" data-event="resetpwd">{:__('Send verification code')}</a>
</span>

View File

@ -121,7 +121,7 @@
<label class="control-label col-xs-12 col-sm-3">{:__('Captcha')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input type="text" name="captcha" id="email-captcha" class="form-control" data-rule="required;length(4);integer[+];remote({:url('api/validate/check_ems_correct')}, event=changeemail, email:#email)" />
<input type="text" name="captcha" id="email-captcha" class="form-control" data-rule="required;length({$Think.config.captcha.length});integer[+];remote({:url('api/validate/check_ems_correct')}, event=changeemail, email:#email)" />
<span class="input-group-btn" style="padding:0;border:none;">
<a href="javascript:;" class="btn btn-info btn-captcha" data-url="{:url('api/ems/send')}" data-type="email" data-event="changeemail">获取验证码</a>
</span>
@ -155,7 +155,7 @@
<label for="mobile-captcha" class="control-label col-xs-12 col-sm-3">{:__('Captcha')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input type="text" name="captcha" id="mobile-captcha" class="form-control" data-rule="required;length(4);integer[+];remote({:url('api/validate/check_sms_correct')}, event=changemobile, mobile:#mobile)" />
<input type="text" name="captcha" id="mobile-captcha" class="form-control" data-rule="required;length({$Think.config.captcha.length});integer[+];remote({:url('api/validate/check_sms_correct')}, event=changemobile, mobile:#mobile)" />
<span class="input-group-btn" style="padding:0;border:none;">
<a href="javascript:;" class="btn btn-info btn-captcha" data-url="{:url('api/sms/send')}" data-type="mobile" data-event="changemobile">获取验证码</a>
</span>

View File

@ -326,7 +326,7 @@ class Tree
'@addtabs' => $childdata || !isset($value['@url']) ? "" : (stripos($value['@url'], "?") !== false ? "&" : "?") . "ref=addtabs",
'@caret' => ($childdata && (!isset($value['@badge']) || !$value['@badge']) ? '<i class="fa fa-angle-left"></i>' : ''),
'@badge' => isset($value['@badge']) ? $value['@badge'] : '',
'@class' => ($selected ? ' active' : '') . ($disabled ? ' disabled' : '') . ($childdata ? ' treeview' : ''),
'@class' => ($selected ? ' active' : '') . ($disabled ? ' disabled' : '') . ($childdata ? ' treeview' . (cookie('show_submenu') ? ' treeview-open' : '') : ''),
);
$str .= strtr($nstr, $value);
}

View File

@ -614,6 +614,7 @@ form.form-horizontal .control-label {
/*顶栏addtabs*/
.nav-addtabs {
height: 100%;
overflow-y: hidden;
border: none;
}
.nav-addtabs.disable-top-badge > li > a > .pull-right-container {
@ -846,7 +847,7 @@ form.form-horizontal .control-label {
.input-group .sp_result_area {
width: 100%;
}
.sidebar-menu.show-submenu .treeview-menu {
.sidebar-menu .treeview-open > .treeview-menu {
display: block;
}
.sidebar-menu > li .badge {
@ -1466,6 +1467,15 @@ table.table-nowrap thead > tr > th {
min-height: 41px;
overflow-x: hidden !important;
}
.fixed-columns .fixed-table-body .btn-dragsort,
.fixed-columns-right .fixed-table-body .btn-dragsort {
pointer-events: none;
cursor: not-allowed;
opacity: 0.65;
filter: alpha(opacity=65);
-webkit-box-shadow: none;
box-shadow: none;
}
.fixed-columns {
left: 0;
}
@ -1490,8 +1500,9 @@ table.table-nowrap thead > tr > th {
.sidebar-menu li.treeview-open > a > .fa-angle-left,
.sidebar-menu li.treeview-open > a > .pull-right-container > .fa-angle-left {
-webkit-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
-moz-transform: rotate(-90deg);
-o-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.sidebar-menu .treeview-menu > li {

View File

@ -309,7 +309,11 @@ a:focus {
box-shadow: 0px 20px 30px rgba(83, 88, 93, 0.05), 0px 0px 30px rgba(83, 88, 93, 0.1);
}
@media (min-width: 768px) {
.navbar-white .navbar-brand {
.navbar-default .navbar-brand {
height: 60px;
line-height: 27px;
}
.navbar-default .navbar-nav > li > a {
height: 60px;
line-height: 27px;
}

View File

@ -1,10 +1,10 @@
@font-face {font-family: "iconfont";
src: url('../fonts/iconfont/iconfont.eot?t=1487643189178'); /* IE9*/
src: url('../fonts/iconfont/iconfont.eot?t=1487643189178#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/iconfont/iconfont.woff?t=1487643189178') format('woff'), /* chrome, firefox */
url('../fonts/iconfont/iconfont.ttf?t=1487643189178') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('../fonts/iconfont/iconfont.svg?t=1487643189178#iconfont') format('svg'); /* iOS 4.1- */
src: url('../fonts/iconfont/iconfont.eot'); /* IE9*/
src: url('../fonts/iconfont/iconfont.eot#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../fonts/iconfont/iconfont.woff') format('woff'), /* chrome, firefox */
url('../fonts/iconfont/iconfont.ttf') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('../fonts/iconfont/iconfont.svg#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {

View File

@ -498,7 +498,7 @@ function _init() {
parent_li.addClass('treeview-open');
} else {
if (!$this.parent().hasClass("active")) {
$this.parent().addClass("active");
// $this.parent().addClass("active");
}
// modified by FastAdmin
if ($(".show-submenu", menu).size() == 0 && $this.parent().parent().hasClass("sidebar-menu")) {

View File

@ -65,7 +65,7 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
}
var visible = nextul.is(":visible");
if (!visible) {
if (nextul.length == 0) {
$(this).parents("li").addClass("active");
} else {
}
@ -108,7 +108,7 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
}
});
var multiplenav = $("#secondnav").size() > 0 ? true : false;
var multiplenav = $("body").hasClass("multiplenav") > 0 ? true : false;
var firstnav = $("#firstnav .nav-addtabs");
var nav = multiplenav ? $("#secondnav .nav-addtabs") : firstnav;
@ -125,6 +125,7 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
firstnav.html(data.navlist);
}
$("li[role='presentation'].active a", nav).trigger('click');
$(window).trigger("resize");
return false;
}, function () {
return false;
@ -285,8 +286,8 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'adminlte', 'form'], functi
// 切换子菜单显示和菜单小图标的显示
$("[data-menu]").on('click', function () {
if ($(this).data("menu") == 'show-submenu') {
$("ul.sidebar-menu").toggleClass("show-submenu");
createCookie('show_submenu', $(this).prop("checked") ? 1 : 0)
createCookie('show_submenu', $(this).prop("checked") ? 1 : 0);
location.reload();
} else {
nav.toggleClass("disable-top-badge");
}

View File

@ -8,19 +8,10 @@ define(['jquery', 'bootstrap', 'frontend', 'form', 'template'], function ($, und
};
var Controller = {
login: function () {
//本地验证未通过时提示
$("#login-form").data("validator-options", validatoroptions);
$(document).on("change", "input[name=type]", function () {
var type = $(this).val();
$("div.form-group[data-type]").addClass("hide");
$("div.form-group[data-type='" + type + "']").removeClass("hide");
$('#resetpwd-form').validator("setField", {
captcha: "required;length(4);integer[+];remote(" + $(this).data("check-url") + ", event=resetpwd, " + type + ":#" + type + ")",
});
$(".btn-captcha").data("url", $(this).data("send-url")).data("type", type);
});
//为表单绑定事件
Form.api.bindevent($("#login-form"), function (data, ret) {
setTimeout(function () {
@ -28,10 +19,7 @@ define(['jquery', 'bootstrap', 'frontend', 'form', 'template'], function ($, und
}, 1000);
});
Form.api.bindevent($("#resetpwd-form"), function (data) {
Layer.closeAll();
});
//忘记密码
$(document).on("click", ".btn-forgot", function () {
var id = "resetpwdtpl";
var content = Template(id, {});
@ -41,9 +29,19 @@ define(['jquery', 'bootstrap', 'frontend', 'form', 'template'], function ($, und
area: ["450px", "355px"],
content: content,
success: function (layero) {
var rule = $("#resetpwd-form input[name='captcha']").data("rule");
Form.api.bindevent($("#resetpwd-form", layero), function (data) {
Layer.closeAll();
});
$(layero).on("change", "input[name=type]", function () {
var type = $(this).val();
$("div.form-group[data-type]").addClass("hide");
$("div.form-group[data-type='" + type + "']").removeClass("hide");
$('#resetpwd-form').validator("setField", {
captcha: rule.replace(/remote\((.*)\)/, "remote(" + $(this).data("check-url") + ", event=resetpwd, " + type + ":#" + type + ")")
});
$(".btn-captcha").data("url", $(this).data("send-url")).data("type", type);
});
}
});
});
@ -155,9 +153,11 @@ define(['jquery', 'bootstrap', 'frontend', 'form', 'template'], function ($, und
return '<div style="width:120px;margin:0 auto;text-align:center;overflow:hidden;white-space: nowrap;text-overflow: ellipsis;">' + html + '</div>';
}
},
{field: 'filename', title: __('Filename'), formatter: function (value, row, index) {
{
field: 'filename', title: __('Filename'), formatter: function (value, row, index) {
return '<div style="width:150px;margin:0 auto;text-align:center;overflow:hidden;white-space: nowrap;text-overflow: ellipsis;">' + Table.api.formatter.search.call(this, value, row, index) + '</div>';
}, operate: 'like'},
}, operate: 'like'
},
{field: 'imagewidth', title: __('Imagewidth'), operate: false},
{field: 'imageheight', title: __('Imageheight'), operate: false},
{field: 'mimetype', title: __('Mimetype'), formatter: Table.api.formatter.search},

View File

@ -454,6 +454,7 @@ form.form-horizontal .control-label {
/*顶栏addtabs*/
.nav-addtabs {
height: 100%;
overflow-y: hidden;
&.disable-top-badge {
> li > a > .pull-right-container {
@ -738,10 +739,9 @@ form.form-horizontal .control-label {
}
.sidebar-menu {
&.show-submenu {
.treeview-menu {
display: block;
}
.treeview-open > .treeview-menu {
display: block;
}
> li .badge {
@ -1315,6 +1315,7 @@ table.table-nowrap {
.btn {
min-height: 33px;
}
a.btn-refresh, a.btn-del, a.btn-add, a.btn-edit, a.btn-import, a.btn-more, a.btn-recyclebin, .btn-mini-xs, .btn-multi {
font-size: 0;
@ -1473,7 +1474,16 @@ table.table-nowrap {
.fixed-table-body {
min-height: 41px;
overflow-x: hidden !important
overflow-x: hidden !important;
.btn-dragsort {
pointer-events: none;
cursor: not-allowed;
opacity: 0.65;
filter: alpha(opacity=65);
-webkit-box-shadow: none;
box-shadow: none;
}
}
}
@ -1504,10 +1514,7 @@ table.table-nowrap {
}
.sidebar-menu li.treeview-open > a > .fa-angle-left, .sidebar-menu li.treeview-open > a > .pull-right-container > .fa-angle-left {
-webkit-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
-o-transform: rotate(-90deg);
transform: rotate(-90deg);
.rotate(-90deg);
}
.sidebar-menu > li {

View File

@ -72,25 +72,36 @@ a {
}
@media (min-width: 768px) {
.navbar-white .navbar-brand {
height: 60px;
line-height: 27px;
}
.navbar-default {
.navbar-brand {
height: 60px;
line-height: 27px;
}
.navbar-white .navbar-nav > li > a {
height: 60px;
line-height: 27px;
color: #555;
&:hover, &:focus {
color: @primary-color;
.navbar-nav {
> li > a {
height: 60px;
line-height: 27px;
}
}
}
.navbar-white .navbar-nav > .active > a {
&, &:hover, &:focus {
background-color: inherit;
color: @primary-color;
.navbar-white .navbar-nav {
> li > a {
height: 60px;
line-height: 27px;
color: #555;
&:hover, &:focus {
color: @primary-color;
}
}
> .active > a {
&, &:hover, &:focus {
background-color: inherit;
color: @primary-color;
}
}
}
}