From 32894af881133a4762db578962688fff6171d0bb Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Wed, 10 Apr 2019 13:22:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8A=9F=E8=83=BD=E6=9B=B4?= =?UTF-8?q?=EF=BC=9A=E5=89=8D=E5=8F=B0=E6=BC=94=E7=A4=BA=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=A1=8C=E4=B8=BA=E9=AA=8C=E8=AF=81=E7=A0=81?= =?UTF-8?q?=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bootstrap.Client/Views/Home/About.cshtml | 8 +- Bootstrap.Client/Views/Home/Index.cshtml | 24 +- Bootstrap.Client/wwwroot/css/theme.css | 1225 ++++++++--------- Bootstrap.Client/wwwroot/js/index.js | 20 + .../lib/captcha/longbow.slidercaptcha.js | 292 ++++ .../wwwroot/lib/captcha/slidercaptcha.css | 131 ++ 6 files changed, 1078 insertions(+), 622 deletions(-) create mode 100644 Bootstrap.Client/wwwroot/js/index.js create mode 100644 Bootstrap.Client/wwwroot/lib/captcha/longbow.slidercaptcha.js create mode 100644 Bootstrap.Client/wwwroot/lib/captcha/slidercaptcha.css diff --git a/Bootstrap.Client/Views/Home/About.cshtml b/Bootstrap.Client/Views/Home/About.cshtml index 2711273b..3808999e 100644 --- a/Bootstrap.Client/Views/Home/About.cshtml +++ b/Bootstrap.Client/Views/Home/About.cshtml @@ -1,4 +1,4 @@ -@{ - ViewData["Title"] = "测试网页"; -} -

测试网页

\ No newline at end of file +@{ + ViewData["Title"] = "关于"; +} +

我是关于网页

\ No newline at end of file diff --git a/Bootstrap.Client/Views/Home/Index.cshtml b/Bootstrap.Client/Views/Home/Index.cshtml index 6997f02b..b1ddf8ef 100644 --- a/Bootstrap.Client/Views/Home/Index.cshtml +++ b/Bootstrap.Client/Views/Home/Index.cshtml @@ -1,6 +1,20 @@ -@{ - ViewData["Title"] = "Home Page"; +@model NavigatorBarModel +@{ + ViewData["Title"] = "前台首页"; } -

这是测试系统首页,欢迎测试使用

-

点击右上角登录信息下拉菜单中的设置按钮进入后台管理

-

由于本系统为演示系统,内部对一些敏感操作进行了限制操作,如一些特殊用户不能删除。

\ No newline at end of file +@section css { + +} +@section javascript { + + +} +

这是开源后台管理框架前台系统首页,欢迎使用

+

点击右上角登录信息下拉菜单中的设置按钮进入 后台管理 或者 直接进入

+

由于本系统为演示系统,内部对一些敏感操作进行了限制操作,如一些特殊用户不能删除。

+

+ +

+
+
+

\ No newline at end of file diff --git a/Bootstrap.Client/wwwroot/css/theme.css b/Bootstrap.Client/wwwroot/css/theme.css index 05402d83..44bfd954 100644 --- a/Bootstrap.Client/wwwroot/css/theme.css +++ b/Bootstrap.Client/wwwroot/css/theme.css @@ -1,613 +1,612 @@ -html { - font-size: 16px; - -ms-overflow-style: auto; -} - -body { - color: #797979; - background: #f1f2f7; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -webkit-overflow-scrolling: touch; -} - -a, a:hover, a:focus { - text-decoration: none; - outline: none; -} - -body, .form-control, .dropdown-menu, .btn:not(.btn-lg):not(.btn-xs), .input-group-text, .popover-header { - font-size: 0.875rem; -} - - .form-control:focus { - border-color: #66afe9; - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102,175,233,.6); - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102,175,233,.6); - } - -.container-fluid { - padding-top: 15px; -} - -.sidebar-open aside { - transform: translate(0); -} - -.sidebar-open footer, .sidebar-open .container-fluid { - display: none; -} - -.sidebar { - padding: 20px 0; - background: inherit; -} - - .sidebar .nav-item { - margin: 5px 10px; - } - - .sidebar .nav-item .nav-link:hover, .sidebar .nav-item .nav-link:focus { - background: #35404d; - color: #fff; - } - - .sidebar .nav-item.active > .nav-link { - color: #FF6C60; - } - - .sidebar .nav-link { - color: #aeb2b7; - padding: 15px 10px; - transition: all .3s linear; - display: flex; - align-items: center; - } - - .sidebar .nav-link .dcjq-icon { - height: 17px; - width: 17px; - background: url(../images/nav-expand.png) no-repeat; - margin-left: auto; - } - - .sidebar .nav-link i { - width: 22px; - } - - .sidebar .nav-link.active, .sidebar .nav-link.active + .sub, - .sidebar .sub .sub .nav-item .nav-link:hover, .sidebar .sub .sub .nav-item .nav-link:focus { - background: #35404D; - } - - .sidebar .nav-link.active .dcjq-icon { - background-position: bottom; - } - - .sidebar .sub .nav-item.dcjq-parent-li { - margin-left: 0; - margin-right: 0; - } - - .sidebar .sub .nav-item.dcjq-parent-li .nav-link { - padding-left: 20px; - } - - .sidebar .sub .dcjq-parent-li .nav-link.active, .sidebar .sub .dcjq-parent-li .nav-link.active + .sub, - .sidebar .sub .nav-item .nav-link:hover, .sidebar .sub .nav-item .nav-link:focus { - background: #3a4756; - } - -.sidebar-toggle-box { - display: block; - font-size: 1.25rem; - color: #eee; - flex: 1 1 auto; - padding: 12px 0; - transition: color .3s linear; -} - - .sidebar-toggle-box:hover { - color: #fff; - } - - .sidebar-toggle-box span { - display: none; - } - -aside { - transition: transform .4s ease-in-out; - transform: translate(-100%); - position: absolute; - top: 92px; - bottom: 0; - left: 0; - right: 0; - z-index: 4; - background: #2a3542; -} - -.breadcrumb { - border-top: solid 1px #ddd; - background-color: transparent; - border-radius: 0; - padding: 8px 10px; - margin-bottom: 0; -} - - .breadcrumb i { - padding-right: 6px; - } - -footer { - background: #5b6e84; - color: #fff; - padding: 10px 4px; - height: 40px; - left: 0; - bottom: 0; - right: 0; - z-index: 100; - display: flex; -} - - footer > span { - flex: 1 1 auto; - text-align: center; - margin-left: 4px; - display: inline-block; - } - -.go-top { - background: rgba(255,255,255,.5); - width: 20px; - height: 20px; - border-radius: 50%; - -webkit-border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - margin-right: 4px; -} - - .go-top:hover { - background-color: white; - } - - .go-top i { - color: #2A3542; - } - -.bs-bars { - display: none; -} - -.btn-fill { - width: 100%; -} - -.toolbar { - position: relative; - margin-top: 10px; - margin-bottom: 10px; - line-height: 34px; -} - - .toolbar .dropdown-menu a { - padding: 0 14px; - display: table-cell; - color: #504d4d; - } - - .toolbar .dropdown-menu a:not(:first-child) { - border-left: solid 1px #aeb2b7; - } - - .toolbar .dropdown-menu a:hover { - color: #235e90; - } - -.input-group .btn:focus, .btn-group .btn:focus, .page-link:focus { - box-shadow: none; -} - -.input-group .btn:not(.btn-secondary):not(.btn-primary):not(.btn-warning):not(.btn-info):not(.btn-danger) { - background-color: #e9ecef; - border-color: #ced4da; -} - -.nav-link { - transition: color .25s linear; -} - -.close { - transition: all .25s linear; -} - - .close:focus { - outline: none; - } - -.dropdown-select + .dropdown-menu a:hover { - background: #007AC0; - color: #fff; -} - -.dropdown-menu { - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.176); - padding: 0; -} - - .dropdown-menu a { - transition: all .25s linear; - padding: 6px 20px; - display: block; - } - -.dropdown-divider { - margin: 0.125rem 0; -} - -.dropdown-item.active, .dropdown-item:active { - color: rgba(0, 0, 0, 0.9); - background-color: rgba(0, 0, 0, 0.05); -} - -.dropdown-item i + span { - margin-left: 6px; -} - -.tooltip-inner { - max-width: 768px; -} - -.is-invalid .tooltip-inner { - background-color: #dc3545; -} - -.is-invalid .arrow:before { - border-top-color: #dc3545; - border-bottom-color: #dc3545; -} - -.radioGroup, .checkGroup, [radioGroup="true"], [checkGroup="true"] { - border: solid 1px transparent; - border-radius: 4px; - padding: 1px 4px; -} - - .radioGroup.is-invalid, .checkGroup.is-invalid, [radioGroup="true"].is-invalid, [checkGroup="true"].is-invalid { - border: solid 1px #dc3545; - } - - .radioGroup.is-invalid .form-check-input ~ .form-check-label, - .checkGroup.is-invalid .form-check-input ~ .form-check-label, - [radioGroup="true"].is-invalid .form-check-input ~ .form-check-label, - [checkGroup="true"].is-invalid .form-check-input ~ .form-check-label { - color: #dc3545; - } - - .radioGroup.is-valid .form-check-input ~ .form-check-label, - [radioGroup="true"].is-valid .form-check-input ~ .form-check-label { - color: #28a745; - } - - .checkGroup.is-valid .form-check-input ~ .form-check-label, - [checkGroup="true"].is-valid .form-check-input ~ .form-check-label { - color: unset; - } - - -input.is-invalid { - background-repeat: no-repeat; - background-image: url('../images/error.png'); - background-position: right 8px center; -} - -input.is-valid { - background-repeat: no-repeat; - background-image: url('../images/success.png'); - background-position: right 8px center; -} - -input.pending { - background-repeat: no-repeat; - background-image: url(../images/loading-sm.gif); - background-position: right 8px center; -} - -.form-inline .form-group { - margin-bottom: 15px; -} - - .form-inline .form-group .control-label { - margin-right: 10px; - width: 90px; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - justify-content: flex-start; - } - -.form-inline .form-row, .form-inline .row { - flex: 1 1 auto; -} - -.modal-header { - background-color: #f5f5f5; - padding: 10px 15px; -} - -.modal-body, .modal-footer, .popover-body { - background-color: #fff; -} - -.modal-title { - overflow-x: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.modal-body, .card-body { - padding: 15px 15px 0 15px; -} - -.modal-footer .btn span:last-child { - display: inline; -} - -.card { - margin-bottom: 15px; -} - - .card .card-header a { - color: #797979; - } - - .card .card-header a[data-toggle="collapse"] { - display: block; - } - - .card .card-header a[data-toggle="collapse"] i { - transition: all .25s linear; - } - - .card .card-header a[data-toggle="collapse"].collapsed i { - transform: rotate(-90deg); - } - - .card .card-header i + span { - margin-left: 6px; - } - -.btn i.fa + span { - margin-left: 4px; - display: none; -} - -.form-check-label { - cursor: pointer; -} - -.form-check-input + span, .form-check-input + label { - max-width: 98px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: inline-block; -} - -.bootstrap-table .table thead > tr > th { - border-top: none; -} - -.fixed-table-toolbar .bs-bars, .fixed-table-toolbar .search, .fixed-table-toolbar .columns { - line-height: normal; -} - -.table-condensed > thead > tr > th, .table-condensed > tfoot > tr > th, .table-condensed > tbody > tr > td { - padding: 2px 0; -} - -.fixed-table-loading { - padding: 8px; -} - -.bootstrap-table { - margin-bottom: 15px; -} - - .bootstrap-table .fixed-table-body .table { - border-bottom: none; - } - - .bootstrap-table .fixed-table-body .table td > a { - display: block; - } - - .bootstrap-table .fixed-table-toolbar .columns-right .btn-group .dropdown-menu { - padding-top: 8px; - } - - .bootstrap-table .fixed-table-container .card-view .value { - word-break: break-all; - } - - .bootstrap-table .fixed-table-container .card-view .value > a, .bootstrap-table .fixed-table-container .card-view .value > div:not(.form-check) { - min-width: 60px; - display: inline-block; - } - - .bootstrap-table .card-view:not(:last-child) { - margin-bottom: 6px; - } - -.card-body:not(.nobar) .bootstrap-table { - margin-top: -10px; -} - -.card-header a.fa { - transition: color .3s linear; -} - - .card-header a.fa:hover { - color: #333; - } - -.fixed-table-toolbar .dropdown-menu { - min-width: unset; -} - -.popover { - max-width: 320px; - padding: 0; -} - -.popover-content { - max-height: 240px; - overflow-y: auto; - overflow-x: hidden; -} - -.file-drop-zone.clickable:hover { - border: 1px dashed #999; -} - -[data-toggle="LgbValidate"] input[type="text"], [data-toggle="LgbValidate"] input[type="password"] { - padding-right: 30px; -} - -.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus, .was-validated .custom-select:invalid:focus, .custom-select.is-invalid:focus { - border-color: #dc3545; - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(220, 53, 69,.6); -} - -.was-validated .form-control:valid:focus, .form-control.is-valid:focus, .was-validated .custom-select:valid:focus, .custom-select.is-valid:focus { - border-color: #28a745; - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(40, 167, 69,.6); -} - -.arrow-primary { - border-color: transparent transparent #007bff; -} - -.arrow-success { - border-color: transparent transparent #28a745; -} - -.arrow-info { - border-color: transparent transparent #17a2b8; -} - -.arrow-warning { - border-color: transparent transparent #ffc107; -} - -.arrow-danger { - border-color: transparent transparent #dc3545; -} - -.show .shadow-primary, .shadow-primary:hover { - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(0, 123, 255, 0.5); - border-color: #007bff !important; -} - -.show .shadow-success, .shadow-success:hover { - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(40, 167, 69, 0.5); - border-color: #28a745 !important; -} - -.show .shadow-info, .shadow-info:hover { - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(23, 162, 184, 0.5); - border-color: #17a2b8 !important; -} - -.show .shadow-warning, .shadow-warning:hover { - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(255, 193, 7, 0.5); - border-color: #ffc107 !important; -} - -.show .shadow-danger, .shadow-danger:hover { - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(220, 53, 69, 0.5); - border: 1px solid #dc3545 !important; -} - -.show .shadow-default, .shadow-default:hover { - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102,175,233,.6); - border: 1px solid #337ab7; -} - -.mCSB_scrollTools { - width: 10px; -} - -.control-label > a { - margin-left: 6px; - color: #5bc0de; -} - -.date > input { - cursor: pointer; -} - -.datetimepicker { - padding: 4px; -} - - .datetimepicker table tr td span { - white-space: nowrap; - } - -.form-inline .form-group-dropdown { - display: flex; - flex-wrap: nowrap; -} - - .form-inline .form-group-dropdown .control-label { - padding: 6px 0; - margin: 0 10px 0 0; - } - - .form-inline .form-group-dropdown .dropdown, .form-inline .form-group-dropdown .dropup { - display: inline-block; - } - -.toggle .btn-default, .toggle.btn-default { - text-shadow: 0 1px 0 #fff; - background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); - background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%); - background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0)); - background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - border-color: #ccc; - box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); -} - - .toggle .btn-default.active { - background-image: none; - background-color: #e0e0e0; - border-color: #dbdbdb; - } - - .toggle .btn-default.active:hover { - color: #333; - background-color: #d4d4d4; - border-color: #8c8c8c; - } - -.toggle.btn .toggle-handle { - display: inline-block; - margin-left: 0; -} - -.sweet-alert h2 { - margin-top: 32px; - margin-bottom: 16px; - font-size: 1.5rem; -} - -.sweet-alert .sa-button-container .btn-lg { - padding: 0.375rem 1.5rem; - font-size: 1rem; -} +html { + font-size: 16px; + -ms-overflow-style: auto; +} + +body { + color: #797979; + background: #f1f2f7; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -webkit-overflow-scrolling: touch; +} + +a, a:hover, a:focus { + text-decoration: none; + outline: none; +} + +body, .form-control, .dropdown-menu, .btn:not(.btn-lg):not(.btn-xs), .input-group-text, .popover-header { + font-size: 0.875rem; +} + + .form-control:focus { + border-color: #66afe9; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102,175,233,.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102,175,233,.6); + } + +.container-fluid { + padding-top: 15px; +} + +.sidebar-open aside { + transform: translate(0); +} + +.sidebar-open footer, .sidebar-open .container-fluid { + display: none; +} + +.sidebar { + padding: 20px 0; + background: inherit; +} + + .sidebar .nav-item { + margin: 5px 10px; + } + + .sidebar .nav-item .nav-link:hover, .sidebar .nav-item .nav-link:focus { + background: #35404d; + color: #fff; + } + + .sidebar .nav-item.active > .nav-link { + color: #FF6C60; + } + + .sidebar .nav-link { + color: #aeb2b7; + padding: 15px 10px; + transition: all .3s linear; + display: flex; + align-items: center; + } + + .sidebar .nav-link .dcjq-icon { + height: 17px; + width: 17px; + background: url(../images/nav-expand.png) no-repeat; + margin-left: auto; + } + + .sidebar .nav-link i { + width: 22px; + } + + .sidebar .nav-link.active, .sidebar .nav-link.active + .sub, + .sidebar .sub .sub .nav-item .nav-link:hover, .sidebar .sub .sub .nav-item .nav-link:focus { + background: #35404D; + } + + .sidebar .nav-link.active .dcjq-icon { + background-position: bottom; + } + + .sidebar .sub .nav-item.dcjq-parent-li { + margin-left: 0; + margin-right: 0; + } + + .sidebar .sub .nav-item.dcjq-parent-li .nav-link { + padding-left: 20px; + } + + .sidebar .sub .dcjq-parent-li .nav-link.active, .sidebar .sub .dcjq-parent-li .nav-link.active + .sub, + .sidebar .sub .nav-item .nav-link:hover, .sidebar .sub .nav-item .nav-link:focus { + background: #3a4756; + } + +.sidebar-toggle-box { + display: block; + font-size: 1.25rem; + color: #eee; + flex: 1 1 auto; + padding: 12px 0; + transition: color .3s linear; +} + + .sidebar-toggle-box:hover { + color: #fff; + } + + .sidebar-toggle-box span { + display: none; + } + +aside { + transition: transform .4s ease-in-out; + transform: translate(-100%); + position: absolute; + top: 92px; + bottom: 0; + left: 0; + right: 0; + z-index: 4; + background: #2a3542; +} + +.breadcrumb { + border-top: solid 1px #ddd; + background-color: transparent; + border-radius: 0; + padding: 8px 10px; + margin-bottom: 0; +} + + .breadcrumb i { + padding-right: 6px; + } + +footer { + background: #5b6e84; + color: #fff; + padding: 10px 4px; + height: 40px; + left: 0; + bottom: 0; + right: 0; + z-index: 100; + display: flex; +} + + footer > span { + flex: 1 1 auto; + text-align: center; + margin-left: 4px; + display: inline-block; + } + +.go-top { + background: rgba(255,255,255,.5); + width: 20px; + height: 20px; + border-radius: 50%; + -webkit-border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin-right: 4px; +} + + .go-top:hover { + background-color: white; + } + + .go-top i { + color: #2A3542; + } + +.bs-bars { + display: none; +} + +.btn-fill { + width: 100%; +} + +.toolbar { + position: relative; + margin-top: 10px; + margin-bottom: 10px; + line-height: 34px; +} + + .toolbar .dropdown-menu a { + padding: 0 14px; + display: table-cell; + color: #504d4d; + } + + .toolbar .dropdown-menu a:not(:first-child) { + border-left: solid 1px #aeb2b7; + } + + .toolbar .dropdown-menu a:hover { + color: #235e90; + } + +.input-group .btn:focus, .btn-group .btn:focus, .page-link:focus { + box-shadow: none; +} + +.input-group .btn:not(.btn-secondary):not(.btn-primary):not(.btn-warning):not(.btn-info):not(.btn-danger) { + background-color: #e9ecef; + border-color: #ced4da; +} + +.nav-link { + transition: color .25s linear; +} + +.close { + transition: all .25s linear; +} + + .close:focus { + outline: none; + } + +.dropdown-select + .dropdown-menu a:hover { + background: #007AC0; + color: #fff; +} + +.dropdown-menu { + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.176); + padding: 0; +} + + .dropdown-menu a { + transition: all .25s linear; + padding: 6px 20px; + display: block; + } + +.dropdown-divider { + margin: 0.125rem 0; +} + +.dropdown-item.active, .dropdown-item:active { + color: rgba(0, 0, 0, 0.9); + background-color: rgba(0, 0, 0, 0.05); +} + +.dropdown-item i + span { + margin-left: 6px; +} + +.tooltip-inner { + max-width: 768px; +} + +.is-invalid .tooltip-inner { + background-color: #dc3545; +} + +.is-invalid .arrow:before { + border-top-color: #dc3545; + border-bottom-color: #dc3545; +} + +.radioGroup, .checkGroup, [radioGroup="true"], [checkGroup="true"] { + border: solid 1px transparent; + border-radius: 4px; + padding: 1px 4px; +} + + .radioGroup.is-invalid, .checkGroup.is-invalid, [radioGroup="true"].is-invalid, [checkGroup="true"].is-invalid { + border: solid 1px #dc3545; + } + + .radioGroup.is-invalid .form-check-input ~ .form-check-label, + .checkGroup.is-invalid .form-check-input ~ .form-check-label, + [radioGroup="true"].is-invalid .form-check-input ~ .form-check-label, + [checkGroup="true"].is-invalid .form-check-input ~ .form-check-label { + color: #dc3545; + } + + .radioGroup.is-valid .form-check-input ~ .form-check-label, + [radioGroup="true"].is-valid .form-check-input ~ .form-check-label { + color: #28a745; + } + + .checkGroup.is-valid .form-check-input ~ .form-check-label, + [checkGroup="true"].is-valid .form-check-input ~ .form-check-label { + color: unset; + } + + +input.is-invalid { + background-repeat: no-repeat; + background-image: url('../images/error.png'); + background-position: right 8px center; +} + +input.is-valid { + background-repeat: no-repeat; + background-image: url('../images/success.png'); + background-position: right 8px center; +} + +input.pending { + background-repeat: no-repeat; + background-image: url(../images/loading-sm.gif); + background-position: right 8px center; +} + +.form-inline .form-group { + margin-bottom: 15px; +} + + .form-inline .form-group .control-label { + margin-right: 10px; + width: 90px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + justify-content: flex-start; + } + +.form-inline .form-row, .form-inline .row { + flex: 1 1 auto; +} + +.modal-header { + background-color: #f5f5f5; + padding: 10px 15px; +} + +.modal-body, .modal-footer, .popover-body { + background-color: #fff; +} + +.modal-title { + overflow-x: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.modal-body, .card-body { + padding: 15px 15px 0 15px; +} + +.modal-footer .btn span:last-child { + display: inline; +} + +.card { + margin-bottom: 15px; +} + + .card .card-header a { + color: #797979; + } + + .card .card-header a[data-toggle="collapse"] { + display: block; + } + + .card .card-header a[data-toggle="collapse"] i { + transition: all .25s linear; + } + + .card .card-header a[data-toggle="collapse"].collapsed i { + transform: rotate(-90deg); + } + + .card .card-header i + span { + margin-left: 6px; + } + +.btn i.fa + span { + margin-left: 4px; +} + +.form-check-label { + cursor: pointer; +} + +.form-check-input + span, .form-check-input + label { + max-width: 98px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + display: inline-block; +} + +.bootstrap-table .table thead > tr > th { + border-top: none; +} + +.fixed-table-toolbar .bs-bars, .fixed-table-toolbar .search, .fixed-table-toolbar .columns { + line-height: normal; +} + +.table-condensed > thead > tr > th, .table-condensed > tfoot > tr > th, .table-condensed > tbody > tr > td { + padding: 2px 0; +} + +.fixed-table-loading { + padding: 8px; +} + +.bootstrap-table { + margin-bottom: 15px; +} + + .bootstrap-table .fixed-table-body .table { + border-bottom: none; + } + + .bootstrap-table .fixed-table-body .table td > a { + display: block; + } + + .bootstrap-table .fixed-table-toolbar .columns-right .btn-group .dropdown-menu { + padding-top: 8px; + } + + .bootstrap-table .fixed-table-container .card-view .value { + word-break: break-all; + } + + .bootstrap-table .fixed-table-container .card-view .value > a, .bootstrap-table .fixed-table-container .card-view .value > div:not(.form-check) { + min-width: 60px; + display: inline-block; + } + + .bootstrap-table .card-view:not(:last-child) { + margin-bottom: 6px; + } + +.card-body:not(.nobar) .bootstrap-table { + margin-top: -10px; +} + +.card-header a.fa { + transition: color .3s linear; +} + + .card-header a.fa:hover { + color: #333; + } + +.fixed-table-toolbar .dropdown-menu { + min-width: unset; +} + +.popover { + max-width: 320px; + padding: 0; +} + +.popover-content { + max-height: 240px; + overflow-y: auto; + overflow-x: hidden; +} + +.file-drop-zone.clickable:hover { + border: 1px dashed #999; +} + +[data-toggle="LgbValidate"] input[type="text"], [data-toggle="LgbValidate"] input[type="password"] { + padding-right: 30px; +} + +.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus, .was-validated .custom-select:invalid:focus, .custom-select.is-invalid:focus { + border-color: #dc3545; + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(220, 53, 69,.6); +} + +.was-validated .form-control:valid:focus, .form-control.is-valid:focus, .was-validated .custom-select:valid:focus, .custom-select.is-valid:focus { + border-color: #28a745; + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(40, 167, 69,.6); +} + +.arrow-primary { + border-color: transparent transparent #007bff; +} + +.arrow-success { + border-color: transparent transparent #28a745; +} + +.arrow-info { + border-color: transparent transparent #17a2b8; +} + +.arrow-warning { + border-color: transparent transparent #ffc107; +} + +.arrow-danger { + border-color: transparent transparent #dc3545; +} + +.show .shadow-primary, .shadow-primary:hover { + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(0, 123, 255, 0.5); + border-color: #007bff !important; +} + +.show .shadow-success, .shadow-success:hover { + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(40, 167, 69, 0.5); + border-color: #28a745 !important; +} + +.show .shadow-info, .shadow-info:hover { + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(23, 162, 184, 0.5); + border-color: #17a2b8 !important; +} + +.show .shadow-warning, .shadow-warning:hover { + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(255, 193, 7, 0.5); + border-color: #ffc107 !important; +} + +.show .shadow-danger, .shadow-danger:hover { + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(220, 53, 69, 0.5); + border: 1px solid #dc3545 !important; +} + +.show .shadow-default, .shadow-default:hover { + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102,175,233,.6); + border: 1px solid #337ab7; +} + +.mCSB_scrollTools { + width: 10px; +} + +.control-label > a { + margin-left: 6px; + color: #5bc0de; +} + +.date > input { + cursor: pointer; +} + +.datetimepicker { + padding: 4px; +} + + .datetimepicker table tr td span { + white-space: nowrap; + } + +.form-inline .form-group-dropdown { + display: flex; + flex-wrap: nowrap; +} + + .form-inline .form-group-dropdown .control-label { + padding: 6px 0; + margin: 0 10px 0 0; + } + + .form-inline .form-group-dropdown .dropdown, .form-inline .form-group-dropdown .dropup { + display: inline-block; + } + +.toggle .btn-default, .toggle.btn-default { + text-shadow: 0 1px 0 #fff; + background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0)); + background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + border-color: #ccc; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); +} + + .toggle .btn-default.active { + background-image: none; + background-color: #e0e0e0; + border-color: #dbdbdb; + } + + .toggle .btn-default.active:hover { + color: #333; + background-color: #d4d4d4; + border-color: #8c8c8c; + } + +.toggle.btn .toggle-handle { + display: inline-block; + margin-left: 0; +} + +.sweet-alert h2 { + margin-top: 32px; + margin-bottom: 16px; + font-size: 1.5rem; +} + +.sweet-alert .sa-button-container .btn-lg { + padding: 0.375rem 1.5rem; + font-size: 1rem; +} diff --git a/Bootstrap.Client/wwwroot/js/index.js b/Bootstrap.Client/wwwroot/js/index.js new file mode 100644 index 00000000..07b6a82d --- /dev/null +++ b/Bootstrap.Client/wwwroot/js/index.js @@ -0,0 +1,20 @@ +$(function () { + $('#captcha').sliderCaptcha({ + setSrc: function () { + return 'http://pocoafrro.bkt.clouddn.com/Pic' + Math.round(Math.random() * 136) + '.jpg'; + }, + onSuccess: function () { + var that = this; + setTimeout(() => { + that.parent().removeClass('d-inline-block'); + that.sliderCaptcha('reset'); + }, 1000); + } + }); + + $('#btnCaptcha').on('click', function () { + $('#captcha').parent().addClass('d-inline-block'); + }); + + $.footer(); +}); \ No newline at end of file diff --git a/Bootstrap.Client/wwwroot/lib/captcha/longbow.slidercaptcha.js b/Bootstrap.Client/wwwroot/lib/captcha/longbow.slidercaptcha.js new file mode 100644 index 00000000..8ffe2aa5 --- /dev/null +++ b/Bootstrap.Client/wwwroot/lib/captcha/longbow.slidercaptcha.js @@ -0,0 +1,292 @@ +(function ($) { + 'use strict'; + + var SliderCaptcha = function (element, options) { + this.$element = $(element); + this.options = $.extend({}, SliderCaptcha.DEFAULTS, options); + this.$element.css({ 'position': 'relative', 'width': this.options.width + 'px', 'margin': '0 auto' }); + this.init(); + }; + + SliderCaptcha.VERSION = '1.0'; + SliderCaptcha.Author = 'argo@163.com'; + SliderCaptcha.DEFAULTS = { + width: 280, // canvas宽度 + height: 155, // canvas高度 + PI: Math.PI, + sliderL: 42, // 滑块边长 + sliderR: 9, // 滑块半径 + loadingText: '正在加载中...', + failedText: '再试一次', + barText: '向右滑动填充拼图', + repeatIcon: 'fa fa-repeat', + maxLoadCount: 3 + }; + + function Plugin(option) { + return this.each(function () { + var $this = $(this); + var data = $this.data('lgb.SliderCaptcha'); + var options = typeof option === 'object' && option; + + if (!data && /init|reset|verify/.test(option)) return; + if (!data) $this.data('lgb.SliderCaptcha', data = new SliderCaptcha(this, options)); + if (typeof option === 'string') data[option](); + }); + } + + $.fn.sliderCaptcha = Plugin; + $.fn.sliderCaptcha.Constructor = SliderCaptcha; + + var _proto = SliderCaptcha.prototype; + _proto.init = function () { + this.initDOM() + this.initImg() + this.bindEvents() + }; + + _proto.initDOM = function () { + var createElement = function (tagName, className) { + var elment = document.createElement(tagName); + elment.className = className; + return elment; + }; + + var createCanvas = function (width, height) { + var canvas = document.createElement('canvas'); + canvas.width = width; + canvas.height = height; + return canvas; + }; + + var canvas = createCanvas(this.options.width - 2, this.options.height) // 画布 + var block = canvas.cloneNode(true) // 滑块 + var sliderContainer = createElement('div', 'sliderContainer'); + var refreshIcon = createElement('i', 'refreshIcon ' + this.options.repeatIcon); + var sliderMask = createElement('div', 'sliderMask'); + var sliderbg = createElement('div', 'sliderbg'); + var slider = createElement('div', 'slider'); + var sliderIcon = createElement('i', 'fa fa-arrow-right sliderIcon'); + var text = createElement('span', 'sliderText'); + + block.className = 'block' + text.innerHTML = this.options.barText; + + var el = this.$element; + el.append($(canvas)); + el.append($(refreshIcon)); + el.append($(block)); + slider.appendChild(sliderIcon); + sliderMask.appendChild(slider); + sliderContainer.appendChild(sliderbg); + sliderContainer.appendChild(sliderMask); + sliderContainer.appendChild(text); + el.append($(sliderContainer)); + + Object.assign(this, { + canvas, + block, + sliderContainer : $(sliderContainer), + refreshIcon, + slider, + sliderMask, + sliderIcon, + text: $(text), + canvasCtx: canvas.getContext('2d'), + blockCtx: block.getContext('2d') + }) + }; + + _proto.initImg = function () { + var that = this; + var isIE = window.navigator.userAgent.indexOf('Trident') > -1; + var L = this.options.sliderL + this.options.sliderR * 2 + 3; // 滑块实际边长 + var drawImg = function (ctx, operation) { + var l = that.options.sliderL; + var r = that.options.sliderR; + var PI = that.options.PI; + var x = that.x; + var y = that.y; + ctx.beginPath() + ctx.moveTo(x, y) + ctx.arc(x + l / 2, y - r + 2, r, 0.72 * PI, 2.26 * PI) + ctx.lineTo(x + l, y) + ctx.arc(x + l + r - 2, y + l / 2, r, 1.21 * PI, 2.78 * PI) + ctx.lineTo(x + l, y + l) + ctx.lineTo(x, y + l) + ctx.arc(x + r - 2, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true) + ctx.lineTo(x, y) + ctx.lineWidth = 2 + ctx.fillStyle = 'rgba(255, 255, 255, 0.7)' + ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)' + ctx.stroke() + ctx[operation]() + ctx.globalCompositeOperation = isIE ? 'xor' : 'overlay' + } + + var getRandomNumberByRange = function (start, end) { + return Math.round(Math.random() * (end - start) + start); + }; + var localImg = function () { + return '../images/Pic' + Math.round(Math.random() * 4) + '.jpg'; + }; + var img = new Image(); + img.crossOrigin = "Anonymous"; + var loadCount = 0; + img.onload = function () { + // 随机创建滑块的位置 + that.x = getRandomNumberByRange(L + 10, that.options.width - (L + 10)); + that.y = getRandomNumberByRange(10 + that.options.sliderR * 2, that.options.height - (L + 10)); + drawImg(that.canvasCtx, 'fill'); + drawImg(that.blockCtx, 'clip'); + + that.canvasCtx.drawImage(img, 0, 0, that.options.width - 2, that.options.height); + that.blockCtx.drawImage(img, 0, 0, that.options.width - 2, that.options.height); + var y = that.y - that.options.sliderR * 2 - 1; + var ImageData = that.blockCtx.getImageData(that.x - 3, y, L, L); + that.block.width = L; + that.blockCtx.putImageData(ImageData, 0, y); + that.text.text(that.text.attr('data-text')); + }; + img.onerror = function () { + loadCount++; + if (window.location.protocol === 'file:') { + loadCount = that.options.maxLoadCount; + console.error("can't load pic resource file from File protocal. Please try http or https"); + } + if (loadCount >= that.options.maxLoadCount) { + that.text.text('加载失败').addClass('text-danger'); + return; + } + img.src = localImg(); + } + img.setSrc = function () { + var src = ''; + loadCount = 0; + that.text.removeClass('text-danger'); + if ($.isFunction(that.options.setSrc)) src = that.options.setSrc(); + if (!src || src === '') src = 'https://picsum.photos/' + that.options.width + '/' + that.options.height + '/?image=' + Math.round(Math.random() * 20); + if (isIE) { // IE浏览器无法通过img.crossOrigin跨域,使用ajax获取图片blob然后转为dataURL显示 + var xhr = new XMLHttpRequest() + xhr.onloadend = function (e) { + var file = new FileReader(); // FileReader仅支持IE10+ + file.readAsDataURL(e.target.response); + file.onloadend = function (e) { + img.src = e.target.result; + } + } + xhr.open('GET', src); + xhr.responseType = 'blob'; + xhr.send(); + } else img.src = src; + }; + img.setSrc(); + this.text.attr('data-text', this.options.barText); + this.text.text(this.options.loadingText); + this.img = img + }; + + _proto.clean = function () { + this.canvasCtx.clearRect(0, 0, this.options.width, this.options.height); + this.blockCtx.clearRect(0, 0, this.options.width, this.options.height); + this.block.width = this.options.width; + }; + + _proto.bindEvents = function () { + var that = this; + this.$element.on('selectstart', function () { + return false; + }); + + $(this.refreshIcon).on('click', function () { + that.text.text(that.options.barText); + that.reset(); + if ($.isFunction(that.options.onRefresh)) that.options.onRefresh.call(that.$element); + }); + + var originX, originY, trail = [], + isMouseDown = false + + var handleDragStart = function (e) { + if (that.text.hasClass('text-danger')) return; + originX = e.clientX || e.touches[0].clientX; + originY = e.clientY || e.touches[0].clientY; + isMouseDown = true; + }; + + var handleDragMove = function (e) { + if (!isMouseDown) return false; + var eventX = e.clientX || e.touches[0].clientX; + var eventY = e.clientY || e.touches[0].clientY; + var moveX = eventX - originX; + var moveY = eventY - originY; + if (moveX < 0 || moveX + 40 > that.options.width) return false; + that.slider.style.left = (moveX - 1) + 'px'; + var blockLeft = (that.options.width - 40 - 20) / (that.options.width - 40) * moveX; + that.block.style.left = blockLeft + 'px'; + + that.sliderContainer.addClass('sliderContainer_active'); + that.sliderMask.style.width = (moveX + 4) + 'px'; + trail.push(moveY); + }; + + var handleDragEnd = function (e) { + if (!isMouseDown) return false + isMouseDown = false + var eventX = e.clientX || e.changedTouches[0].clientX + if (eventX == originX) return false + that.sliderContainer.removeClass('sliderContainer_active'); + that.trail = trail + var { + spliced, + verified + } = that.verify() + if (spliced && verified) { + that.sliderContainer.addClass('sliderContainer_success'); + if ($.isFunction(that.options.onSuccess)) that.options.onSuccess.call(that.$element); + } else { + that.sliderContainer.addClass('sliderContainer_fail'); + if ($.isFunction(that.options.onFail)) that.options.onFail.call(that.$element); + setTimeout(() => { + that.text.text(that.options.failedText); + that.reset(); + }, 1000) + } + }; + + this.slider.addEventListener('mousedown', handleDragStart); + this.slider.addEventListener('touchstart', handleDragStart); + document.addEventListener('mousemove', handleDragMove); + document.addEventListener('touchmove', handleDragMove); + document.addEventListener('mouseup', handleDragEnd); + document.addEventListener('touchend', handleDragEnd); + + document.addEventListener('mousedown', function() { return false; }); + document.addEventListener('touchstart', function() { return false; }); + }; + + _proto.verify = function () { + var sum = function (x, y) { return x + y; }; + var square = function (x) { return x * x; }; + var arr = this.trail // 拖动时y轴的移动距离 + var average = arr.reduce(sum) / arr.length; + var deviations = arr.map(function (x) { return x - average; }); + var stddev = Math.sqrt(deviations.map(square).reduce(sum) / arr.length); + var left = parseInt(this.block.style.left); + return { + spliced: Math.abs(left - this.x) < 4, + verified: stddev !== 0, // 简单验证下拖动轨迹,为零时表示Y轴上下没有波动,可能非人为操作 + } + }; + + _proto.reset = function () { + this.sliderContainer.removeClass('sliderContainer_fail sliderContainer_success'); + this.slider.style.left = 0 + this.block.style.left = 0 + this.sliderMask.style.width = 0 + this.clean() + this.text.attr('data-text', this.text.text()); + this.text.text(this.options.loadingText); + this.img.setSrc(); + }; +})(jQuery); \ No newline at end of file diff --git a/Bootstrap.Client/wwwroot/lib/captcha/slidercaptcha.css b/Bootstrap.Client/wwwroot/lib/captcha/slidercaptcha.css new file mode 100644 index 00000000..ac97699d --- /dev/null +++ b/Bootstrap.Client/wwwroot/lib/captcha/slidercaptcha.css @@ -0,0 +1,131 @@ +body { + overflow-x: hidden; +} + +.block { + position: absolute; + left: 0; + top: 0; +} + +.sliderContainer { + position: relative; + text-align: center; + line-height: 40px; + background: #f7f9fa; + color: #45494c; + border-radius: 2px; +} + +.sliderbg { + position: absolute; + left: 0; + right: 0; + top: 0; + background-color: #f7f9fa; + height: 40px; + border-radius: 2px; + border: 1px solid #e6e8eb; +} + +.sliderContainer_active .slider { + top: -1px; + border: 1px solid #1991FA; +} + +.sliderContainer_active .sliderMask { + border-width: 1px 0 1px 1px; +} + +.sliderContainer_success .slider { + top: -1px; + border: 1px solid #52CCBA; + background-color: #52CCBA !important; +} + +.sliderContainer_success .sliderMask { + border: 1px solid #52CCBA; + border-width: 1px 0 1px 1px; + background-color: #D2F4EF; +} + +.sliderContainer_success .sliderIcon:before { + content: "\f00c"; +} + +.sliderContainer_fail .slider { + top: -1px; + border: 1px solid #f57a7a; + background-color: #f57a7a !important; +} + +.sliderContainer_fail .sliderMask { + border: 1px solid #f57a7a; + background-color: #fce1e1; + border-width: 1px 0 1px 1px; +} + +.sliderContainer_fail .sliderIcon:before { + content: "\f00d"; +} +.sliderContainer_active .sliderText, .sliderContainer_success .sliderText, .sliderContainer_fail .sliderText { + display: none; +} + +.sliderMask { + position: absolute; + left: 0; + top: 0; + height: 40px; + border: 0 solid #1991FA; + background: #D1E9FE; + border-radius: 2px; +} + +.slider { + position: absolute; + top: 0; + left: 0; + width: 40px; + height: 40px; + background: #fff; + box-shadow: 0 0 3px rgba(0, 0, 0, 0.3); + cursor: pointer; + transition: background .2s linear; + border-radius: 2px; + display: flex; + align-items: center; + justify-content: center; +} + +.slider:hover { + background: #1991FA; +} + +.slider:hover .sliderIcon { + background-position: 0 -13px; +} + +.sliderText { + position: relative; +} + +.sliderIcon { + +} + +.refreshIcon { + position: absolute; + right: 0; + top: 0; + cursor: pointer; + margin: 6px; + color: rgba(0,0,0,.25); + font-size: 1rem; + z-index: 5; + transition: color .3s linear; +} + + .refreshIcon:hover { + color: #6c757d; + }