增加功能:字典表配置增加图床路径配置

#Comment
更新最新的行为式验证码脚本,增加本地图片路径
This commit is contained in:
Argo Zhang 2019-04-13 16:01:06 +08:00 committed by Argo-MacBookPro
parent fe91321f3c
commit 92a7336b96
29 changed files with 785 additions and 714 deletions

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web"> <Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework> <TargetFramework>netcoreapp2.2</TargetFramework>

Binary file not shown.

View File

@ -33,7 +33,7 @@ namespace Bootstrap.Admin.Controllers
ViewBag.UserName = "Admin"; ViewBag.UserName = "Admin";
ViewBag.Password = "123789"; ViewBag.Password = "123789";
} }
return User.Identity.IsAuthenticated ? (ActionResult)Redirect("~/Home/Index") : View("Login", new ModelBase()); return User.Identity.IsAuthenticated ? (ActionResult)Redirect("~/Home/Index") : View("Login", new LoginModel());
} }
/// <summary> /// <summary>
@ -56,8 +56,8 @@ namespace Bootstrap.Admin.Controllers
// redirect origin url // redirect origin url
var originUrl = Request.Query[CookieAuthenticationDefaults.ReturnUrlParameter].FirstOrDefault() ?? "~/Home/Index"; var originUrl = Request.Query[CookieAuthenticationDefaults.ReturnUrlParameter].FirstOrDefault() ?? "~/Home/Index";
return Redirect(originUrl); return Redirect(originUrl);
} }
return View("Login", new ModelBase()); return View("Login", new LoginModel());
} }
/// <summary> /// <summary>

View File

@ -0,0 +1,23 @@
using Bootstrap.DataAccess;
namespace Bootstrap.Admin.Models
{
/// <summary>
///
/// </summary>
public class LoginModel : ModelBase
{
/// <summary>
///
/// </summary>
public LoginModel()
{
ImageLibUrl = DictHelper.RetrieveImagesLibUrl();
}
/// <summary>
/// 验证码图床地址
/// </summary>
public string ImageLibUrl { get; protected set; }
}
}

View File

@ -1,219 +1,220 @@
@model ModelBase @model LoginModel
@{ @{
ViewBag.Title = Model.Title; ViewBag.Title = Model.Title;
Layout = "_Layout"; Layout = "_Layout";
} }
@section css { @section css {
<environment include="Development"> <environment include="Development">
<link href="~/lib/twitter-bootstrap/css/bootstrap.css" rel="stylesheet" /> <link href="~/lib/twitter-bootstrap/css/bootstrap.css" rel="stylesheet" />
<link href="~/lib/font-awesome/css/font-awesome.css" rel="stylesheet" /> <link href="~/lib/font-awesome/css/font-awesome.css" rel="stylesheet" />
<link href="~/lib/bootstrap-sweetalert/sweetalert.css" rel="stylesheet" /> <link href="~/lib/bootstrap-sweetalert/sweetalert.css" rel="stylesheet" />
</environment> </environment>
<environment exclude="Development"> <environment exclude="Development">
<link href="~/lib/twitter-bootstrap/css/bootstrap.min.css" rel="stylesheet" /> <link href="~/lib/twitter-bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<link href="~/lib/font-awesome/css/font-awesome.min.css" rel="stylesheet" /> <link href="~/lib/font-awesome/css/font-awesome.min.css" rel="stylesheet" />
<link href="~/lib/bootstrap-sweetalert/sweetalert.min.css" rel="stylesheet" /> <link href="~/lib/bootstrap-sweetalert/sweetalert.min.css" rel="stylesheet" />
</environment> </environment>
<link href="~/lib/captcha/slidercaptcha.css" rel="stylesheet" /> <link href="~/lib/captcha/slidercaptcha.css" rel="stylesheet" />
<link href="~/css/theme.css" rel="stylesheet" asp-append-version="true" /> <link href="~/css/theme.css" rel="stylesheet" asp-append-version="true" />
<link href="~/css/login.css" rel="stylesheet" asp-append-version="true" /> <link href="~/css/login.css" rel="stylesheet" asp-append-version="true" />
<link href="~/css/login-responsive.css" rel="stylesheet" asp-append-version="true" /> <link href="~/css/login-responsive.css" rel="stylesheet" asp-append-version="true" />
@if (!string.IsNullOrEmpty(Model.Theme)) @if (!string.IsNullOrEmpty(Model.Theme))
{ {
<link href="~/css/@Model.Theme" rel="stylesheet" asp-append-version="true" /> <link href="~/css/@Model.Theme" rel="stylesheet" asp-append-version="true" />
} }
} }
@section javascript { @section javascript {
<environment include="Development"> <environment include="Development">
<script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.js"></script> <script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.js"></script>
<script src="~/lib/validate/jquery.validate.js"></script> <script src="~/lib/validate/jquery.validate.js"></script>
<script src="~/lib/validate/localization/messages_zh.js"></script> <script src="~/lib/validate/localization/messages_zh.js"></script>
<script src="~/lib/bootstrap-sweetalert/sweetalert.js"></script> <script src="~/lib/bootstrap-sweetalert/sweetalert.js"></script>
</environment> </environment>
<environment exclude="Development"> <environment exclude="Development">
<script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.min.js"></script> <script src="~/lib/twitter-bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="~/lib/validate/jquery.validate.min.js"></script> <script src="~/lib/validate/jquery.validate.min.js"></script>
<script src="~/lib/validate/localization/messages_zh.min.js"></script> <script src="~/lib/validate/localization/messages_zh.min.js"></script>
<script src="~/lib/bootstrap-sweetalert/sweetalert.min.js"></script> <script src="~/lib/bootstrap-sweetalert/sweetalert.min.js"></script>
</environment> </environment>
<script src="~/lib/captcha/longbow.slidercaptcha.js"></script> <script src="~/lib/captcha/longbow.slidercaptcha.js"></script>
<script src="~/lib/longbow/longbow.common.js"></script> <script src="~/lib/longbow/longbow.common.js"></script>
<script src="~/lib/longbow/longbow.validate.js"></script> <script src="~/lib/longbow/longbow.validate.js"></script>
<script src="~/js/login.js" asp-append-version="true"></script> <script src="~/js/login.js" asp-append-version="true"></script>
} }
<div class="container"> <div class="container">
<form id="login" method="post" class="form-signin"> <input id="imgUrl" type="hidden" value="@Model.ImageLibUrl" />
<h2 class="form-signin-heading">@Model.Title</h2> <form id="login" method="post" class="form-signin">
<div class="login-wrap" data-toggle="LgbValidate" data-valid-button="button[type='submit']"> <h2 class="form-signin-heading">@Model.Title</h2>
<div class="form-group"> <div class="login-wrap" data-toggle="LgbValidate" data-valid-button="button[type='submit']">
<div class="input-group"> <div class="form-group">
<div class="input-group-prepend"> <div class="input-group">
<div class="input-group-text"> <div class="input-group-prepend">
<span class="fa fa-user"></span> <div class="input-group-text">
</div> <span class="fa fa-user"></span>
</div> </div>
<input type="text" name="userName" class="form-control" placeholder="用户名" maxlength="16" data-required-msg="请输入用户名" value="@ViewBag.UserName" autofocus data-valid="true" /> </div>
</div> <input type="text" name="userName" class="form-control" placeholder="用户名" maxlength="16" data-required-msg="请输入用户名" value="@ViewBag.UserName" autofocus data-valid="true" />
</div> </div>
<div class="form-group"> </div>
<div class="input-group"> <div class="form-group">
<div class="input-group-prepend"> <div class="input-group">
<div class="input-group-text"> <div class="input-group-prepend">
<span class="fa fa-lock"></span> <div class="input-group-text">
</div> <span class="fa fa-lock"></span>
</div> </div>
<input type="password" name="password" class="form-control" value="@ViewBag.Password" placeholder="密码" maxlength="16" data-required-msg="请输入密码" data-valid="true" /> </div>
</div> <input type="password" name="password" class="form-control" value="@ViewBag.Password" placeholder="密码" maxlength="16" data-required-msg="请输入密码" data-valid="true" />
</div> </div>
<div class="form-group rememberPwd" onselectstart="return false"> </div>
<i class="fa fa-square-o"></i> <div class="form-group rememberPwd" onselectstart="return false">
<span>记住密码自动登录</span> <i class="fa fa-square-o"></i>
<input id="remember" name="remember" type="hidden" value="false" /> <span>记住密码自动登录</span>
</div> <input id="remember" name="remember" type="hidden" value="false" />
<button class="btn btn-lg btn-login btn-block" type="submit">登 陆</button> </div>
<div class="login-footer"> <button class="btn btn-lg btn-login btn-block" type="submit">登 陆</button>
<a href="#" data-method="register">申请账号</a> <div class="login-footer">
<a href="#" data-method="forgot">忘记密码</a> <a href="#" data-method="register">申请账号</a>
</div> <a href="#" data-method="forgot">忘记密码</a>
<div class="slidercaptcha card"> </div>
<div class="card-header"> <div class="slidercaptcha card">
<span>请完成安全验证</span> <div class="card-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <span>请完成安全验证</span>
</div> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<div class="card-body"><div id="captcha"></div></div> </div>
</div> <div class="card-body"><div id="captcha"></div></div>
</div> </div>
</form> </div>
</div> </form>
<div class="modal fade" id="dialogNew" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myModalLabel" aria-hidden="true"> </div>
<div class="modal-dialog modal-dialog-centered modal-lg" role="document"> <div class="modal fade" id="dialogNew" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-content" data-toggle="LgbValidate" data-valid-button="#btnSubmit" data-valid-modal="#dialogNew"> <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
<div class="modal-header"> <div class="modal-content" data-toggle="LgbValidate" data-valid-button="#btnSubmit" data-valid-modal="#dialogNew">
<h5 class="modal-title" id="myModalLabel">新用户注册</h5> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <h5 class="modal-title" id="myModalLabel">新用户注册</h5>
</div> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<div class="modal-body"> </div>
<div class="form-group"> <div class="modal-body">
<label for="userName">登陆名称:</label> <div class="form-group">
<div class="input-group"> <label for="userName">登陆名称:</label>
<div class="input-group-prepend"> <div class="input-group">
<div class="input-group-text"> <div class="input-group-prepend">
<span class="fa fa-user-plus"></span> <div class="input-group-text">
</div> <span class="fa fa-user-plus"></span>
</div> </div>
<input type="text" id="userName" autocomplete="off" class="form-control" placeholder="登陆账号不可为空" userName="true" minlength="4" maxlength="16" remote="api/Register" data-remote-msg="此用户已存在" data-valid="true" /> </div>
</div> <input type="text" id="userName" autocomplete="off" class="form-control" placeholder="登陆账号不可为空" userName="true" minlength="4" maxlength="16" remote="api/Register" data-remote-msg="此用户已存在" data-valid="true" />
</div> </div>
<div class="form-group"> </div>
<label for="displayName">显示名称:</label> <div class="form-group">
<div class="input-group"> <label for="displayName">显示名称:</label>
<div class="input-group-prepend"> <div class="input-group">
<div class="input-group-text"> <div class="input-group-prepend">
<span class="fa fa-user-circle-o"></span> <div class="input-group-text">
</div> <span class="fa fa-user-circle-o"></span>
</div> </div>
<input type="text" id="displayName" class="form-control" value="" placeholder="显示名称不可为空" maxlength="20" data-valid="true" /> </div>
</div> <input type="text" id="displayName" class="form-control" value="" placeholder="显示名称不可为空" maxlength="20" data-valid="true" />
</div> </div>
<div class="form-group"> </div>
<label for="password">密码:</label> <div class="form-group">
<div class="input-group"> <label for="password">密码:</label>
<div class="input-group-prepend"> <div class="input-group">
<div class="input-group-text"> <div class="input-group-prepend">
<span class="fa fa-lock"></span> <div class="input-group-text">
</div> <span class="fa fa-lock"></span>
</div> </div>
<input type="password" id="password" class="form-control" value="" placeholder="密码不可为空" maxlength="16" data-valid="true" /> </div>
</div> <input type="password" id="password" class="form-control" value="" placeholder="密码不可为空" maxlength="16" data-valid="true" />
</div> </div>
<div class="form-group"> </div>
<label for="assurePassword">确认密码:</label> <div class="form-group">
<div class="input-group"> <label for="assurePassword">确认密码:</label>
<div class="input-group-prepend"> <div class="input-group">
<div class="input-group-text"> <div class="input-group-prepend">
<span class="fa fa-lock"></span> <div class="input-group-text">
</div> <span class="fa fa-lock"></span>
</div> </div>
<input type="password" id="assurePassword" class="form-control" value="" placeholder="确认密码" maxlength="16" equalTo="#password" data-valid="true" /> </div>
</div> <input type="password" id="assurePassword" class="form-control" value="" placeholder="确认密码" maxlength="16" equalTo="#password" data-valid="true" />
</div> </div>
<div class="form-group"> </div>
<label for="description">申请理由:</label> <div class="form-group">
<textarea id="description" class="form-control" placeholder="申请理由500字以内" rows="3" maxlength="500" data-valid="true"></textarea> <label for="description">申请理由:</label>
</div> <textarea id="description" class="form-control" placeholder="申请理由500字以内" rows="3" maxlength="500" data-valid="true"></textarea>
</div> </div>
<div class="modal-footer"> </div>
<button type="button" class="btn btn-secondary" data-dismiss="modal"> <div class="modal-footer">
<i class="fa fa-times"></i> <button type="button" class="btn btn-secondary" data-dismiss="modal">
<span>关闭</span> <i class="fa fa-times"></i>
</button> <span>关闭</span>
<button type="button" class="btn btn-primary" id="btnSubmit"> </button>
<i class="fa fa-save"></i> <button type="button" class="btn btn-primary" id="btnSubmit">
<span>提交</span> <i class="fa fa-save"></i>
</button> <span>提交</span>
<div class="slidercaptcha forgot reg card"> </button>
<div class="card-header"> <div class="slidercaptcha forgot reg card">
<span>请完成安全验证</span> <div class="card-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <span>请完成安全验证</span>
</div> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<div class="card-body"><div id="regcap"></div></div> </div>
</div> <div class="card-body"><div id="regcap"></div></div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="modal fade" id="dialogForgot" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myModalLabel" aria-hidden="true"> </div>
<div class="modal-dialog modal-dialog-centered modal-lg" role="document"> <div class="modal fade" id="dialogForgot" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-content" data-toggle="LgbValidate" data-valid-button="#btnForgot" data-valid-modal="#dialogForgot"> <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
<div class="modal-header"> <div class="modal-content" data-toggle="LgbValidate" data-valid-button="#btnForgot" data-valid-modal="#dialogForgot">
<h5 class="modal-title" id="myModalLabelForgot">忘记密码</h5> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> <h5 class="modal-title" id="myModalLabelForgot">忘记密码</h5>
</div> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<div class="modal-body"> </div>
<div class="form-group"> <div class="modal-body">
<label for="f_userName">登陆账号:</label> <div class="form-group">
<div class="input-group"> <label for="f_userName">登陆账号:</label>
<div class="input-group-prepend"> <div class="input-group">
<div class="input-group-text"> <div class="input-group-prepend">
<span class="fa fa-user-plus"></span> <div class="input-group-text">
</div> <span class="fa fa-user-plus"></span>
</div> </div>
<input type="text" id="f_userName" autocomplete="off" class="form-control" placeholder="登陆账号不可为空" minlength="4" maxlength="16" data-valid="true" /> </div>
</div> <input type="text" id="f_userName" autocomplete="off" class="form-control" placeholder="登陆账号不可为空" minlength="4" maxlength="16" data-valid="true" />
</div> </div>
<div class="form-group"> </div>
<label for="f_displayName">显示名称:</label> <div class="form-group">
<div class="input-group"> <label for="f_displayName">显示名称:</label>
<div class="input-group-prepend"> <div class="input-group">
<div class="input-group-text"> <div class="input-group-prepend">
<span class="fa fa-user-circle-o"></span> <div class="input-group-text">
</div> <span class="fa fa-user-circle-o"></span>
</div> </div>
<input type="text" id="f_displayName" class="form-control" value="" placeholder="显示名称不可为空" maxlength="20" data-valid="true" /> </div>
</div> <input type="text" id="f_displayName" class="form-control" value="" placeholder="显示名称不可为空" maxlength="20" data-valid="true" />
</div> </div>
<div class="form-group"> </div>
<label for="f_desc">申请理由:</label> <div class="form-group">
<textarea id="f_desc" class="form-control" placeholder="申请理由500字以内" rows="3" maxlength="500" data-valid="true">我是用户XXX我的手机号是XXXXXX由于密码忘记请将密码重置为123登录后我自行更改谢谢管理员</textarea> <label for="f_desc">申请理由:</label>
</div> <textarea id="f_desc" class="form-control" placeholder="申请理由500字以内" rows="3" maxlength="500" data-valid="true">我是用户XXX我的手机号是XXXXXX由于密码忘记请将密码重置为123登录后我自行更改谢谢管理员</textarea>
</div> </div>
<div class="modal-footer"> </div>
<button type="button" class="btn btn-secondary" data-dismiss="modal"> <div class="modal-footer">
<i class="fa fa-times"></i> <button type="button" class="btn btn-secondary" data-dismiss="modal">
<span>关闭</span> <i class="fa fa-times"></i>
</button> <span>关闭</span>
<button type="button" class="btn btn-danger" id="btnForgot"> </button>
<i class="fa fa-send-o"></i> <button type="button" class="btn btn-danger" id="btnForgot">
<span>提交</span> <i class="fa fa-send-o"></i>
</button> <span>提交</span>
<div class="slidercaptcha forgot card"> </button>
<div class="card-header"> <div class="slidercaptcha forgot card">
<span>请完成安全验证</span> <div class="card-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <span>请完成安全验证</span>
</div> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<div class="card-body"><div id="forgotcap"></div></div> </div>
</div> <div class="card-body"><div id="forgotcap"></div></div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>

View File

@ -1,4 +1,5 @@
$(function () { $(function () {
var $imgUrl = $('#imgUrl');
$(".container").autoCenter(); $(".container").autoCenter();
$("a[data-method]").on('click', function () { $("a[data-method]").on('click', function () {
@ -94,8 +95,11 @@
$('#captcha, #regcap, #forgotcap').sliderCaptcha({ $('#captcha, #regcap, #forgotcap').sliderCaptcha({
width: $.capWidth(), width: $.capWidth(),
height: $.capHeight(), height: $.capHeight(),
localImages: function () {
return '../../lib/captcha/images/Pic' + Math.round(Math.random() * 4) + '.jpg';
},
setSrc: function () { setSrc: function () {
return 'http://pocoafrro.bkt.clouddn.com/Pic' + Math.round(Math.random() * 136) + '.jpg'; return $imgUrl.val() + 'Pic' + Math.round(Math.random() * 136) + '.jpg';
}, },
onSuccess: function () { onSuccess: function () {
var parent = this.$element.parents('.slidercaptcha').removeClass('d-block'); var parent = this.$element.parents('.slidercaptcha').removeClass('d-block');

View File

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -1,4 +1,4 @@
(function ($) { (function ($) {
'use strict'; 'use strict';
var SliderCaptcha = function (element, options) { var SliderCaptcha = function (element, options) {
@ -16,11 +16,15 @@
PI: Math.PI, PI: Math.PI,
sliderL: 42, // 滑块边长 sliderL: 42, // 滑块边长
sliderR: 9, // 滑块半径 sliderR: 9, // 滑块半径
offset: 5, // 容错偏差
loadingText: '正在加载中...', loadingText: '正在加载中...',
failedText: '再试一次', failedText: '再试一次',
barText: '向右滑动填充拼图', barText: '向右滑动填充拼图',
repeatIcon: 'fa fa-repeat', repeatIcon: 'fa fa-repeat',
maxLoadCount: 3 maxLoadCount: 3,
localImages: function () {
return 'images/Pic' + Math.round(Math.random() * 4) + '.jpg';
}
}; };
function Plugin(option) { function Plugin(option) {
@ -40,9 +44,9 @@
var _proto = SliderCaptcha.prototype; var _proto = SliderCaptcha.prototype;
_proto.init = function () { _proto.init = function () {
this.initDOM() this.initDOM();
this.initImg() this.initImg();
this.bindEvents() this.bindEvents();
}; };
_proto.initDOM = function () { _proto.initDOM = function () {
@ -86,7 +90,7 @@
Object.assign(this, { Object.assign(this, {
canvas, canvas,
block, block,
sliderContainer : $(sliderContainer), sliderContainer: $(sliderContainer),
refreshIcon, refreshIcon,
slider, slider,
sliderMask, sliderMask,
@ -127,9 +131,6 @@
var getRandomNumberByRange = function (start, end) { var getRandomNumberByRange = function (start, end) {
return Math.round(Math.random() * (end - start) + start); return Math.round(Math.random() * (end - start) + start);
}; };
var localImg = function () {
return '../images/Pic' + Math.round(Math.random() * 4) + '.jpg';
};
var img = new Image(); var img = new Image();
img.crossOrigin = "Anonymous"; img.crossOrigin = "Anonymous";
var loadCount = 0; var loadCount = 0;
@ -158,8 +159,8 @@
that.text.text('加载失败').addClass('text-danger'); that.text.text('加载失败').addClass('text-danger');
return; return;
} }
img.src = localImg(); img.src = that.options.localImages();
} };
img.setSrc = function () { img.setSrc = function () {
var src = ''; var src = '';
loadCount = 0; loadCount = 0;
@ -250,7 +251,7 @@
setTimeout(() => { setTimeout(() => {
that.text.text(that.options.failedText); that.text.text(that.options.failedText);
that.reset(); that.reset();
}, 1000) }, 1000);
} }
}; };
@ -261,8 +262,8 @@
document.addEventListener('mouseup', handleDragEnd); document.addEventListener('mouseup', handleDragEnd);
document.addEventListener('touchend', handleDragEnd); document.addEventListener('touchend', handleDragEnd);
document.addEventListener('mousedown', function() { return false; }); document.addEventListener('mousedown', function () { return false; });
document.addEventListener('touchstart', function() { return false; }); document.addEventListener('touchstart', function () { return false; });
}; };
_proto.verify = function () { _proto.verify = function () {
@ -274,7 +275,7 @@
var stddev = Math.sqrt(deviations.map(square).reduce(sum) / arr.length); var stddev = Math.sqrt(deviations.map(square).reduce(sum) / arr.length);
var left = parseInt(this.block.style.left); var left = parseInt(this.block.style.left);
return { return {
spliced: Math.abs(left - this.x) < 4, spliced: Math.abs(left - this.x) < this.options.offset,
verified: stddev !== 0, // 简单验证下拖动轨迹为零时表示Y轴上下没有波动可能非人为操作 verified: stddev !== 0, // 简单验证下拖动轨迹为零时表示Y轴上下没有波动可能非人为操作
} }
}; };

View File

@ -82,5 +82,11 @@ namespace Bootstrap.Client.DataAccess
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public static string RetrieveIconFolderPath() => (RetrieveDicts().FirstOrDefault(d => d.Name == "头像路径" && d.Category == "头像地址" && d.Define == 0) ?? new BootstrapDict() { Code = "~/images/uploader/" }).Code; public static string RetrieveIconFolderPath() => (RetrieveDicts().FirstOrDefault(d => d.Name == "头像路径" && d.Category == "头像地址" && d.Define == 0) ?? new BootstrapDict() { Code = "~/images/uploader/" }).Code;
/// <summary>
/// 获取验证码图床
/// </summary>
/// <returns></returns>
public static string RetrieveImagesLibUrl() => (RetrieveDicts().FirstOrDefault(d => d.Name == "验证码图床" && d.Category == "系统设置" && d.Define == 0) ?? new BootstrapDict() { Code = "https://longbow-1258823021.cos.ap-shanghai.myqcloud.com/pic/280/150/" }).Code;
} }
} }

View File

@ -17,10 +17,17 @@ namespace Bootstrap.Client.Models
public NavigatorBarModel(ControllerBase controller) : base(controller.User.Identity) public NavigatorBarModel(ControllerBase controller) : base(controller.User.Identity)
{ {
Navigations = MenuHelper.RetrieveAppMenus(UserName, $"~/{controller.ControllerContext.ActionDescriptor.ControllerName}/{controller.ControllerContext.ActionDescriptor.ActionName}"); Navigations = MenuHelper.RetrieveAppMenus(UserName, $"~/{controller.ControllerContext.ActionDescriptor.ControllerName}/{controller.ControllerContext.ActionDescriptor.ActionName}");
ImageLibUrl = DictHelper.RetrieveImagesLibUrl();
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public IEnumerable<BootstrapMenu> Navigations { get; } public IEnumerable<BootstrapMenu> Navigations { get; }
/// <summary>
///
/// </summary>
public string ImageLibUrl { get; set; }
} }
} }

View File

@ -15,6 +15,6 @@
<p> <p>
<button id="btnCaptcha" class="btn btn-success"><i class="fa fa-send-o"></i><span>点击我出现行为验证码</span></button> <button id="btnCaptcha" class="btn btn-success"><i class="fa fa-send-o"></i><span>点击我出现行为验证码</span></button>
<div class="card d-none" style="padding: 10px; height: 222px;"> <div class="card d-none" style="padding: 10px; height: 222px;">
<div id="captcha"></div> <div id="captcha" data-imageLibUrl="@Model.ImageLibUrl"></div>
</div> </div>
</p> </p>

View File

@ -1,14 +1,19 @@
$(function () { $(function () {
$('#captcha').sliderCaptcha({ var $captcha = $('#captcha');
$captcha.sliderCaptcha({
localImages: function () {
return '../../lib/captcha/images/Pic' + Math.round(Math.random() * 4) + '.jpg';
},
setSrc: function () { setSrc: function () {
return 'http://pocoafrro.bkt.clouddn.com/Pic' + Math.round(Math.random() * 136) + '.jpg'; return $captcha.attr('data-imageLibUrl') + 'Pic' + Math.round(Math.random() * 136) + '.jpg';
}, },
onSuccess: function () { onSuccess: function () {
var that = this; var that = this;
setTimeout(() => { setTimeout(() => {
that.parent().removeClass('d-inline-block'); that.parent().removeClass('d-inline-block');
that.sliderCaptcha('reset'); that.sliderCaptcha('reset');
window.location.href = "/BA/Admin/Profiles"; $('.userinfo .dropdown-menu a:first')[0].click();
}, 1000); }, 1000);
} }
}); });

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -1,292 +1,293 @@
(function ($) { (function ($) {
'use strict'; 'use strict';
var SliderCaptcha = function (element, options) { var SliderCaptcha = function (element, options) {
this.$element = $(element); this.$element = $(element);
this.options = $.extend({}, SliderCaptcha.DEFAULTS, options); this.options = $.extend({}, SliderCaptcha.DEFAULTS, options);
this.$element.css({ 'position': 'relative', 'width': this.options.width + 'px', 'margin': '0 auto' }); this.$element.css({ 'position': 'relative', 'width': this.options.width + 'px', 'margin': '0 auto' });
this.init(); this.init();
}; };
SliderCaptcha.VERSION = '1.0'; SliderCaptcha.VERSION = '1.0';
SliderCaptcha.Author = 'argo@163.com'; SliderCaptcha.Author = 'argo@163.com';
SliderCaptcha.DEFAULTS = { SliderCaptcha.DEFAULTS = {
width: 280, // canvas宽度 width: 280, // canvas宽度
height: 155, // canvas高度 height: 155, // canvas高度
PI: Math.PI, PI: Math.PI,
sliderL: 42, // 滑块边长 sliderL: 42, // 滑块边长
sliderR: 9, // 滑块半径 sliderR: 9, // 滑块半径
loadingText: '正在加载中...', offset: 5, // 容错偏差
failedText: '再试一次', loadingText: '正在加载中...',
barText: '向右滑动填充拼图', failedText: '再试一次',
repeatIcon: 'fa fa-repeat', barText: '向右滑动填充拼图',
maxLoadCount: 3 repeatIcon: 'fa fa-repeat',
}; maxLoadCount: 3,
localImages: function () {
function Plugin(option) { return 'images/Pic' + Math.round(Math.random() * 4) + '.jpg';
return this.each(function () { }
var $this = $(this); };
var data = $this.data('lgb.SliderCaptcha');
var options = typeof option === 'object' && option; function Plugin(option) {
return this.each(function () {
if (!data && /init|reset|verify/.test(option)) return; var $this = $(this);
if (!data) $this.data('lgb.SliderCaptcha', data = new SliderCaptcha(this, options)); var data = $this.data('lgb.SliderCaptcha');
if (typeof option === 'string') data[option](); 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));
$.fn.sliderCaptcha = Plugin; if (typeof option === 'string') data[option]();
$.fn.sliderCaptcha.Constructor = SliderCaptcha; });
}
var _proto = SliderCaptcha.prototype;
_proto.init = function () { $.fn.sliderCaptcha = Plugin;
this.initDOM() $.fn.sliderCaptcha.Constructor = SliderCaptcha;
this.initImg()
this.bindEvents() var _proto = SliderCaptcha.prototype;
}; _proto.init = function () {
this.initDOM();
_proto.initDOM = function () { this.initImg();
var createElement = function (tagName, className) { this.bindEvents();
var elment = document.createElement(tagName); };
elment.className = className;
return elment; _proto.initDOM = function () {
}; var createElement = function (tagName, className) {
var elment = document.createElement(tagName);
var createCanvas = function (width, height) { elment.className = className;
var canvas = document.createElement('canvas'); return elment;
canvas.width = width; };
canvas.height = height;
return canvas; var createCanvas = function (width, height) {
}; var canvas = document.createElement('canvas');
canvas.width = width;
var canvas = createCanvas(this.options.width - 2, this.options.height) // 画布 canvas.height = height;
var block = canvas.cloneNode(true) // 滑块 return canvas;
var sliderContainer = createElement('div', 'sliderContainer'); };
var refreshIcon = createElement('i', 'refreshIcon ' + this.options.repeatIcon);
var sliderMask = createElement('div', 'sliderMask'); var canvas = createCanvas(this.options.width - 2, this.options.height) // 画布
var sliderbg = createElement('div', 'sliderbg'); var block = canvas.cloneNode(true) // 滑块
var slider = createElement('div', 'slider'); var sliderContainer = createElement('div', 'sliderContainer');
var sliderIcon = createElement('i', 'fa fa-arrow-right sliderIcon'); var refreshIcon = createElement('i', 'refreshIcon ' + this.options.repeatIcon);
var text = createElement('span', 'sliderText'); var sliderMask = createElement('div', 'sliderMask');
var sliderbg = createElement('div', 'sliderbg');
block.className = 'block' var slider = createElement('div', 'slider');
text.innerHTML = this.options.barText; var sliderIcon = createElement('i', 'fa fa-arrow-right sliderIcon');
var text = createElement('span', 'sliderText');
var el = this.$element;
el.append($(canvas)); block.className = 'block'
el.append($(refreshIcon)); text.innerHTML = this.options.barText;
el.append($(block));
slider.appendChild(sliderIcon); var el = this.$element;
sliderMask.appendChild(slider); el.append($(canvas));
sliderContainer.appendChild(sliderbg); el.append($(refreshIcon));
sliderContainer.appendChild(sliderMask); el.append($(block));
sliderContainer.appendChild(text); slider.appendChild(sliderIcon);
el.append($(sliderContainer)); sliderMask.appendChild(slider);
sliderContainer.appendChild(sliderbg);
Object.assign(this, { sliderContainer.appendChild(sliderMask);
canvas, sliderContainer.appendChild(text);
block, el.append($(sliderContainer));
sliderContainer : $(sliderContainer),
refreshIcon, Object.assign(this, {
slider, canvas,
sliderMask, block,
sliderIcon, sliderContainer: $(sliderContainer),
text: $(text), refreshIcon,
canvasCtx: canvas.getContext('2d'), slider,
blockCtx: block.getContext('2d') sliderMask,
}) sliderIcon,
}; text: $(text),
canvasCtx: canvas.getContext('2d'),
_proto.initImg = function () { blockCtx: block.getContext('2d')
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) { _proto.initImg = function () {
var l = that.options.sliderL; var that = this;
var r = that.options.sliderR; var isIE = window.navigator.userAgent.indexOf('Trident') > -1;
var PI = that.options.PI; var L = this.options.sliderL + this.options.sliderR * 2 + 3; // 滑块实际边长
var x = that.x; var drawImg = function (ctx, operation) {
var y = that.y; var l = that.options.sliderL;
ctx.beginPath() var r = that.options.sliderR;
ctx.moveTo(x, y) var PI = that.options.PI;
ctx.arc(x + l / 2, y - r + 2, r, 0.72 * PI, 2.26 * PI) var x = that.x;
ctx.lineTo(x + l, y) var y = that.y;
ctx.arc(x + l + r - 2, y + l / 2, r, 1.21 * PI, 2.78 * PI) ctx.beginPath()
ctx.lineTo(x + l, y + l) ctx.moveTo(x, y)
ctx.lineTo(x, y + l) ctx.arc(x + l / 2, y - r + 2, r, 0.72 * PI, 2.26 * PI)
ctx.arc(x + r - 2, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true) ctx.lineTo(x + l, y)
ctx.lineTo(x, y) ctx.arc(x + l + r - 2, y + l / 2, r, 1.21 * PI, 2.78 * PI)
ctx.lineWidth = 2 ctx.lineTo(x + l, y + l)
ctx.fillStyle = 'rgba(255, 255, 255, 0.7)' ctx.lineTo(x, y + l)
ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)' ctx.arc(x + r - 2, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true)
ctx.stroke() ctx.lineTo(x, y)
ctx[operation]() ctx.lineWidth = 2
ctx.globalCompositeOperation = isIE ? 'xor' : 'overlay' ctx.fillStyle = 'rgba(255, 255, 255, 0.7)'
} ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)'
ctx.stroke()
var getRandomNumberByRange = function (start, end) { ctx[operation]()
return Math.round(Math.random() * (end - start) + start); ctx.globalCompositeOperation = isIE ? 'xor' : 'overlay'
}; }
var localImg = function () {
return '../images/Pic' + Math.round(Math.random() * 4) + '.jpg'; var getRandomNumberByRange = function (start, end) {
}; return Math.round(Math.random() * (end - start) + start);
var img = new Image(); };
img.crossOrigin = "Anonymous"; var img = new Image();
var loadCount = 0; img.crossOrigin = "Anonymous";
img.onload = function () { 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)); that.x = getRandomNumberByRange(L + 10, that.options.width - (L + 10));
drawImg(that.canvasCtx, 'fill'); that.y = getRandomNumberByRange(10 + that.options.sliderR * 2, that.options.height - (L + 10));
drawImg(that.blockCtx, 'clip'); 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); that.canvasCtx.drawImage(img, 0, 0, that.options.width - 2, that.options.height);
var y = that.y - that.options.sliderR * 2 - 1; that.blockCtx.drawImage(img, 0, 0, that.options.width - 2, that.options.height);
var ImageData = that.blockCtx.getImageData(that.x - 3, y, L, L); var y = that.y - that.options.sliderR * 2 - 1;
that.block.width = L; var ImageData = that.blockCtx.getImageData(that.x - 3, y, L, L);
that.blockCtx.putImageData(ImageData, 0, y); that.block.width = L;
that.text.text(that.text.attr('data-text')); that.blockCtx.putImageData(ImageData, 0, y);
}; that.text.text(that.text.attr('data-text'));
img.onerror = function () { };
loadCount++; img.onerror = function () {
if (window.location.protocol === 'file:') { loadCount++;
loadCount = that.options.maxLoadCount; if (window.location.protocol === 'file:') {
console.error("can't load pic resource file from File protocal. Please try http or https"); 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'); if (loadCount >= that.options.maxLoadCount) {
return; that.text.text('加载失败').addClass('text-danger');
} return;
img.src = localImg(); }
} img.src = that.options.localImages();
img.setSrc = function () { };
var src = ''; img.setSrc = function () {
loadCount = 0; var src = '';
that.text.removeClass('text-danger'); loadCount = 0;
if ($.isFunction(that.options.setSrc)) src = that.options.setSrc(); that.text.removeClass('text-danger');
if (!src || src === '') src = 'https://picsum.photos/' + that.options.width + '/' + that.options.height + '/?image=' + Math.round(Math.random() * 20); if ($.isFunction(that.options.setSrc)) src = that.options.setSrc();
if (isIE) { // IE浏览器无法通过img.crossOrigin跨域使用ajax获取图片blob然后转为dataURL显示 if (!src || src === '') src = 'https://picsum.photos/' + that.options.width + '/' + that.options.height + '/?image=' + Math.round(Math.random() * 20);
var xhr = new XMLHttpRequest() if (isIE) { // IE浏览器无法通过img.crossOrigin跨域使用ajax获取图片blob然后转为dataURL显示
xhr.onloadend = function (e) { var xhr = new XMLHttpRequest()
var file = new FileReader(); // FileReader仅支持IE10+ xhr.onloadend = function (e) {
file.readAsDataURL(e.target.response); var file = new FileReader(); // FileReader仅支持IE10+
file.onloadend = function (e) { file.readAsDataURL(e.target.response);
img.src = e.target.result; file.onloadend = function (e) {
} img.src = e.target.result;
} }
xhr.open('GET', src); }
xhr.responseType = 'blob'; xhr.open('GET', src);
xhr.send(); xhr.responseType = 'blob';
} else img.src = src; xhr.send();
}; } else img.src = src;
img.setSrc(); };
this.text.attr('data-text', this.options.barText); img.setSrc();
this.text.text(this.options.loadingText); this.text.attr('data-text', this.options.barText);
this.img = img this.text.text(this.options.loadingText);
}; this.img = img
};
_proto.clean = function () {
this.canvasCtx.clearRect(0, 0, this.options.width, this.options.height); _proto.clean = function () {
this.blockCtx.clearRect(0, 0, this.options.width, this.options.height); this.canvasCtx.clearRect(0, 0, this.options.width, this.options.height);
this.block.width = this.options.width; this.blockCtx.clearRect(0, 0, this.options.width, this.options.height);
}; this.block.width = this.options.width;
};
_proto.bindEvents = function () {
var that = this; _proto.bindEvents = function () {
this.$element.on('selectstart', function () { var that = this;
return false; this.$element.on('selectstart', function () {
}); return false;
});
$(this.refreshIcon).on('click', function () {
that.text.text(that.options.barText); $(this.refreshIcon).on('click', function () {
that.reset(); that.text.text(that.options.barText);
if ($.isFunction(that.options.onRefresh)) that.options.onRefresh.call(that.$element); that.reset();
}); if ($.isFunction(that.options.onRefresh)) that.options.onRefresh.call(that.$element);
});
var originX, originY, trail = [],
isMouseDown = false var originX, originY, trail = [],
isMouseDown = false
var handleDragStart = function (e) {
if (that.text.hasClass('text-danger')) return; var handleDragStart = function (e) {
originX = e.clientX || e.touches[0].clientX; if (that.text.hasClass('text-danger')) return;
originY = e.clientY || e.touches[0].clientY; originX = e.clientX || e.touches[0].clientX;
isMouseDown = true; originY = e.clientY || e.touches[0].clientY;
}; isMouseDown = true;
};
var handleDragMove = function (e) {
if (!isMouseDown) return false; var handleDragMove = function (e) {
var eventX = e.clientX || e.touches[0].clientX; if (!isMouseDown) return false;
var eventY = e.clientY || e.touches[0].clientY; var eventX = e.clientX || e.touches[0].clientX;
var moveX = eventX - originX; var eventY = e.clientY || e.touches[0].clientY;
var moveY = eventY - originY; var moveX = eventX - originX;
if (moveX < 0 || moveX + 40 > that.options.width) return false; var moveY = eventY - originY;
that.slider.style.left = (moveX - 1) + 'px'; if (moveX < 0 || moveX + 40 > that.options.width) return false;
var blockLeft = (that.options.width - 40 - 20) / (that.options.width - 40) * moveX; that.slider.style.left = (moveX - 1) + 'px';
that.block.style.left = blockLeft + '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'; that.sliderContainer.addClass('sliderContainer_active');
trail.push(moveY); that.sliderMask.style.width = (moveX + 4) + 'px';
}; trail.push(moveY);
};
var handleDragEnd = function (e) {
if (!isMouseDown) return false var handleDragEnd = function (e) {
isMouseDown = false if (!isMouseDown) return false
var eventX = e.clientX || e.changedTouches[0].clientX isMouseDown = false
if (eventX == originX) return false var eventX = e.clientX || e.changedTouches[0].clientX
that.sliderContainer.removeClass('sliderContainer_active'); if (eventX == originX) return false
that.trail = trail that.sliderContainer.removeClass('sliderContainer_active');
var { that.trail = trail
spliced, var {
verified spliced,
} = that.verify() verified
if (spliced && verified) { } = that.verify()
that.sliderContainer.addClass('sliderContainer_success'); if (spliced && verified) {
if ($.isFunction(that.options.onSuccess)) that.options.onSuccess.call(that.$element); that.sliderContainer.addClass('sliderContainer_success');
} else { if ($.isFunction(that.options.onSuccess)) that.options.onSuccess.call(that.$element);
that.sliderContainer.addClass('sliderContainer_fail'); } else {
if ($.isFunction(that.options.onFail)) that.options.onFail.call(that.$element); that.sliderContainer.addClass('sliderContainer_fail');
setTimeout(() => { if ($.isFunction(that.options.onFail)) that.options.onFail.call(that.$element);
that.text.text(that.options.failedText); setTimeout(() => {
that.reset(); that.text.text(that.options.failedText);
}, 1000) that.reset();
} }, 1000);
}; }
};
this.slider.addEventListener('mousedown', handleDragStart);
this.slider.addEventListener('touchstart', handleDragStart); this.slider.addEventListener('mousedown', handleDragStart);
document.addEventListener('mousemove', handleDragMove); this.slider.addEventListener('touchstart', handleDragStart);
document.addEventListener('touchmove', handleDragMove); document.addEventListener('mousemove', handleDragMove);
document.addEventListener('mouseup', handleDragEnd); document.addEventListener('touchmove', handleDragMove);
document.addEventListener('touchend', handleDragEnd); document.addEventListener('mouseup', handleDragEnd);
document.addEventListener('touchend', handleDragEnd);
document.addEventListener('mousedown', function() { return false; });
document.addEventListener('touchstart', function() { return false; }); document.addEventListener('mousedown', function () { return false; });
}; document.addEventListener('touchstart', function () { return false; });
};
_proto.verify = function () {
var sum = function (x, y) { return x + y; }; _proto.verify = function () {
var square = function (x) { return x * x; }; var sum = function (x, y) { return x + y; };
var arr = this.trail // 拖动时y轴的移动距离 var square = function (x) { return x * x; };
var average = arr.reduce(sum) / arr.length; var arr = this.trail // 拖动时y轴的移动距离
var deviations = arr.map(function (x) { return x - average; }); var average = arr.reduce(sum) / arr.length;
var stddev = Math.sqrt(deviations.map(square).reduce(sum) / arr.length); var deviations = arr.map(function (x) { return x - average; });
var left = parseInt(this.block.style.left); var stddev = Math.sqrt(deviations.map(square).reduce(sum) / arr.length);
return { var left = parseInt(this.block.style.left);
spliced: Math.abs(left - this.x) < 4, return {
verified: stddev !== 0, // 简单验证下拖动轨迹为零时表示Y轴上下没有波动可能非人为操作 spliced: Math.abs(left - this.x) < this.options.offset,
} verified: stddev !== 0, // 简单验证下拖动轨迹为零时表示Y轴上下没有波动可能非人为操作
}; }
};
_proto.reset = function () {
this.sliderContainer.removeClass('sliderContainer_fail sliderContainer_success'); _proto.reset = function () {
this.slider.style.left = 0 this.sliderContainer.removeClass('sliderContainer_fail sliderContainer_success');
this.block.style.left = 0 this.slider.style.left = 0
this.sliderMask.style.width = 0 this.block.style.left = 0
this.clean() this.sliderMask.style.width = 0
this.text.attr('data-text', this.text.text()); this.clean()
this.text.text(this.options.loadingText); this.text.attr('data-text', this.text.text());
this.img.setSrc(); this.text.text(this.options.loadingText);
}; this.img.setSrc();
};
})(jQuery); })(jQuery);

View File

@ -1,180 +1,186 @@
using Bootstrap.Security; using Bootstrap.Security;
using Bootstrap.Security.DataAccess; using Bootstrap.Security.DataAccess;
using Longbow; using Longbow;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Bootstrap.DataAccess namespace Bootstrap.DataAccess
{ {
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
public class Dict : BootstrapDict public class Dict : BootstrapDict
{ {
/// <summary> /// <summary>
/// 删除字典中的数据 /// 删除字典中的数据
/// </summary> /// </summary>
/// <param name="value">需要删除的IDs</param> /// <param name="value">需要删除的IDs</param>
/// <returns></returns> /// <returns></returns>
public virtual bool Delete(IEnumerable<string> value) public virtual bool Delete(IEnumerable<string> value)
{ {
if (!value.Any()) return true; if (!value.Any()) return true;
var ids = string.Join(",", value); var ids = string.Join(",", value);
string sql = $"where ID in ({ids})"; string sql = $"where ID in ({ids})";
DbManager.Create().Delete<BootstrapDict>(sql); DbManager.Create().Delete<BootstrapDict>(sql);
return true; return true;
} }
/// <summary> /// <summary>
/// 保存新建/更新的字典信息 /// 保存新建/更新的字典信息
/// </summary> /// </summary>
/// <param name="dict"></param> /// <param name="dict"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool Save(BootstrapDict dict) public virtual bool Save(BootstrapDict dict)
{ {
if (dict.Category.Length > 50) dict.Category = dict.Category.Substring(0, 50); if (dict.Category.Length > 50) dict.Category = dict.Category.Substring(0, 50);
if (dict.Name.Length > 50) dict.Name = dict.Name.Substring(0, 50); if (dict.Name.Length > 50) dict.Name = dict.Name.Substring(0, 50);
if (dict.Code.Length > 50) dict.Code = dict.Code.Substring(0, 50); if (dict.Code.Length > 50) dict.Code = dict.Code.Substring(0, 50);
DbManager.Create().Save(dict); DbManager.Create().Save(dict);
return true; return true;
} }
/// <summary> /// <summary>
/// 保存网站个性化设置 /// 保存网站个性化设置
/// </summary> /// </summary>
/// <param name="dict"></param> /// <param name="dict"></param>
/// <returns></returns> /// <returns></returns>
public virtual bool SaveSettings(BootstrapDict dict) public virtual bool SaveSettings(BootstrapDict dict)
{ {
DbManager.Create().Update<BootstrapDict>("set Code = @Code where Category = @Category and Name = @Name", dict); DbManager.Create().Update<BootstrapDict>("set Code = @Code where Category = @Category and Name = @Name", dict);
return true; return true;
} }
/// <summary> /// <summary>
/// 获取字典分类名称 /// 获取字典分类名称
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<string> RetrieveCategories() => DictHelper.RetrieveDicts().OrderBy(d => d.Category).Select(d => d.Category).Distinct(); public virtual IEnumerable<string> RetrieveCategories() => DictHelper.RetrieveDicts().OrderBy(d => d.Category).Select(d => d.Category).Distinct();
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual string RetrieveWebTitle() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "网站标题" && d.Category == "网站设置" && d.Define == 0) ?? new BootstrapDict() { Code = "后台管理系统" }).Code; public virtual string RetrieveWebTitle() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "网站标题" && d.Category == "网站设置" && d.Define == 0) ?? new BootstrapDict() { Code = "后台管理系统" }).Code;
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual string RetrieveWebFooter() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "网站页脚" && d.Category == "网站设置" && d.Define == 0) ?? new BootstrapDict() { Code = "2016 © 通用后台管理系统" }).Code; public virtual string RetrieveWebFooter() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "网站页脚" && d.Category == "网站设置" && d.Define == 0) ?? new BootstrapDict() { Code = "2016 © 通用后台管理系统" }).Code;
/// <summary> /// <summary>
/// 获得系统中配置的可以使用的网站样式 /// 获得系统中配置的可以使用的网站样式
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<BootstrapDict> RetrieveThemes() => DictHelper.RetrieveDicts().Where(d => d.Category == "网站样式"); public virtual IEnumerable<BootstrapDict> RetrieveThemes() => DictHelper.RetrieveDicts().Where(d => d.Category == "网站样式");
/// <summary> /// <summary>
/// 获得网站设置中的当前样式 /// 获得网站设置中的当前样式
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual string RetrieveActiveTheme() public virtual string RetrieveActiveTheme()
{ {
var theme = DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "使用样式" && d.Category == "当前样式" && d.Define == 0); var theme = DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "使用样式" && d.Category == "当前样式" && d.Define == 0);
return theme == null ? string.Empty : (theme.Code.Equals("site.css", StringComparison.OrdinalIgnoreCase) ? string.Empty : theme.Code); return theme == null ? string.Empty : (theme.Code.Equals("site.css", StringComparison.OrdinalIgnoreCase) ? string.Empty : theme.Code);
} }
/// <summary> /// <summary>
/// 获取头像路径 /// 获取头像路径
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual string RetrieveIconFolderPath() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "头像路径" && d.Category == "头像地址" && d.Define == 0) ?? new BootstrapDict { Code = "~/images/uploader/" }).Code; public virtual string RetrieveIconFolderPath() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "头像路径" && d.Category == "头像地址" && d.Define == 0) ?? new BootstrapDict { Code = "~/images/uploader/" }).Code;
/// <summary> /// <summary>
/// 获得默认的前台首页地址,默认为~/Home/Index /// 获得默认的前台首页地址,默认为~/Home/Index
/// </summary> /// </summary>
/// <param name="appCode"></param> /// <param name="appCode"></param>
/// <returns></returns> /// <returns></returns>
public virtual string RetrieveHomeUrl(string appCode) public virtual string RetrieveHomeUrl(string appCode)
{ {
// https://gitee.com/LongbowEnterprise/dashboard/issues?id=IS0WK // https://gitee.com/LongbowEnterprise/dashboard/issues?id=IS0WK
var url = "~/Home/Index"; var url = "~/Home/Index";
var dicts = DictHelper.RetrieveDicts(); var dicts = DictHelper.RetrieveDicts();
if (appCode != "0") if (appCode != "0")
{ {
var appUrl = dicts.FirstOrDefault(d => d.Name.Equals(appCode, StringComparison.OrdinalIgnoreCase) && d.Category == "应用首页" && d.Define == 0)?.Code; var appUrl = dicts.FirstOrDefault(d => d.Name.Equals(appCode, StringComparison.OrdinalIgnoreCase) && d.Category == "应用首页" && d.Define == 0)?.Code;
if (!string.IsNullOrEmpty(appUrl)) if (!string.IsNullOrEmpty(appUrl))
{ {
url = appUrl; url = appUrl;
return url; return url;
} }
} }
var defaultUrl = dicts.FirstOrDefault(d => d.Name == "前台首页" && d.Category == "网站设置" && d.Define == 0)?.Code; var defaultUrl = dicts.FirstOrDefault(d => d.Name == "前台首页" && d.Category == "网站设置" && d.Define == 0)?.Code;
if (!string.IsNullOrEmpty(defaultUrl)) url = defaultUrl; if (!string.IsNullOrEmpty(defaultUrl)) url = defaultUrl;
return url; return url;
} }
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<KeyValuePair<string, string>> RetrieveApps() => DictHelper.RetrieveDicts().Where(d => d.Category == "应用程序" && d.Define == 0).Select(d => new KeyValuePair<string, string>(d.Code, d.Name)).OrderBy(d => d.Key); public virtual IEnumerable<KeyValuePair<string, string>> RetrieveApps() => DictHelper.RetrieveDicts().Where(d => d.Category == "应用程序" && d.Define == 0).Select(d => new KeyValuePair<string, string>(d.Code, d.Name)).OrderBy(d => d.Key);
/// <summary> /// <summary>
/// 通过数据库获得所有字典表配置信息缓存Key=DictHelper-RetrieveDicts /// 通过数据库获得所有字典表配置信息缓存Key=DictHelper-RetrieveDicts
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public virtual IEnumerable<BootstrapDict> RetrieveDicts() => DbHelper.RetrieveDicts(); public virtual IEnumerable<BootstrapDict> RetrieveDicts() => DbHelper.RetrieveDicts();
/// <summary> /// <summary>
/// 程序异常时长 默认1月 /// 程序异常时长 默认1月
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public int RetrieveExceptionsLogPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "程序异常保留时长" && d.Define == 0)?.Code, 1); public int RetrieveExceptionsLogPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "程序异常保留时长" && d.Define == 0)?.Code, 1);
/// <summary> /// <summary>
/// 操作日志时长 默认12月 /// 操作日志时长 默认12月
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public int RetrieveLogsPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "操作日志保留时长" && d.Define == 0)?.Code, 12); public int RetrieveLogsPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "操作日志保留时长" && d.Define == 0)?.Code, 12);
/// <summary> /// <summary>
/// 登录日志时长 默认12月 /// 登录日志时长 默认12月
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public int RetrieveLoginLogsPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "登录日志保留时长" && d.Define == 0)?.Code, 12); public int RetrieveLoginLogsPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "登录日志保留时长" && d.Define == 0)?.Code, 12);
/// <summary> /// <summary>
/// Cookie保存时长 默认7天 /// Cookie保存时长 默认7天
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public int RetrieveCookieExpiresPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "Cookie保留时长" && d.Define == 0)?.Code, 7); public int RetrieveCookieExpiresPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "Cookie保留时长" && d.Define == 0)?.Code, 7);
/// <summary> /// <summary>
/// 获得 IP地理位置 /// 获得 IP地理位置
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public string RetrieveLocaleIPSvr() => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "IP地理位置接口" && d.Define == 0)?.Code; public string RetrieveLocaleIPSvr() => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "IP地理位置接口" && d.Define == 0)?.Code;
/// <summary> /// <summary>
/// 获得 项目是否获取登录地点 默认为false /// 获得 项目是否获取登录地点 默认为false
/// </summary> /// </summary>
/// <param name="ipSvr">服务提供名称</param> /// <param name="ipSvr">服务提供名称</param>
/// <returns></returns> /// <returns></returns>
public string RetrieveLocaleIPSvrUrl(string ipSvr) => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == ipSvr && d.Define == 0)?.Code; public string RetrieveLocaleIPSvrUrl(string ipSvr) => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == ipSvr && d.Define == 0)?.Code;
/// <summary> /// <summary>
/// 获得 访问日志保留时长 默认为1个月 /// 获得 访问日志保留时长 默认为1个月
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public int RetrieveAccessLogPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "访问日志保留时长" && d.Define == 0)?.Code, 1); public int RetrieveAccessLogPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "访问日志保留时长" && d.Define == 0)?.Code, 1);
/// <summary> /// <summary>
/// 获得 是否为演示系统 默认为 false 不是演示系统 /// 获得 是否为演示系统 默认为 false 不是演示系统
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public bool RetrieveSystemModel() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "演示系统" && d.Define == 0)?.Code, "0") == "1"; public bool RetrieveSystemModel() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "演示系统" && d.Define == 0)?.Code, "0") == "1";
}
} /// <summary>
/// 获得 验证码图床地址
/// </summary>
/// <returns></returns>
public string RetrieveImagesLibUrl() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "验证码图床" && d.Define == 0)?.Code, "https://longbow-1258823021.cos.ap-shanghai.myqcloud.com/pic/280/150/");
}
}

View File

@ -200,5 +200,11 @@ namespace Bootstrap.DataAccess
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public static bool RetrieveSystemModel() => DbContextManager.Create<Dict>().RetrieveSystemModel(); public static bool RetrieveSystemModel() => DbContextManager.Create<Dict>().RetrieveSystemModel();
/// <summary>
/// 获得验证码图床地址
/// </summary>
/// <returns></returns>
public static string RetrieveImagesLibUrl() => DbContextManager.Create<Dict>().RetrieveImagesLibUrl();
} }
} }

View File

@ -44,6 +44,7 @@ INSERT [dbo].[Dicts] ([Category], [Name], [Code], [Define]) VALUES (N'系统设
INSERT [dbo].[Dicts] ([Category], [Name], [Code], [Define]) VALUES (N'系统设置', N'BaiDuIPSvr', 'http://api.map.baidu.com/location/ip?ak=6lvVPMDlm2gjLpU0aiqPsHXi2OiwGQRj&ip=', 0) INSERT [dbo].[Dicts] ([Category], [Name], [Code], [Define]) VALUES (N'系统设置', N'BaiDuIPSvr', 'http://api.map.baidu.com/location/ip?ak=6lvVPMDlm2gjLpU0aiqPsHXi2OiwGQRj&ip=', 0)
INSERT [dbo].[Dicts] ([Category], [Name], [Code], [Define]) VALUES (N'系统设置', N'JuheIPSvr', 'http://apis.juhe.cn/ip/ipNew?key=f57102d1b9fadd3f4a1c29072d0c0206&ip=', 0) INSERT [dbo].[Dicts] ([Category], [Name], [Code], [Define]) VALUES (N'系统设置', N'JuheIPSvr', 'http://apis.juhe.cn/ip/ipNew?key=f57102d1b9fadd3f4a1c29072d0c0206&ip=', 0)
INSERT [dbo].[Dicts] ([Category], [Name], [Code], [Define]) VALUES (N'系统设置', N'演示系统', '0', 0) INSERT [dbo].[Dicts] ([Category], [Name], [Code], [Define]) VALUES (N'系统设置', N'演示系统', '0', 0)
INSERT [dbo].[Dicts] ([Category], [Name], [Code], [Define]) VALUES (N'系统设置', N'验证码图床', 'https://longbow-1258823021.cos.ap-shanghai.myqcloud.com/pic/280/150/', 0)
DELETE FROM Navigations Where Category = N'0' DELETE FROM Navigations Where Category = N'0'
INSERT [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (0, N'后台管理', 10, N'fa fa-gear', N'~/Admin/Index', N'0') INSERT [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (0, N'后台管理', 10, N'fa fa-gear', N'~/Admin/Index', N'0')

View File

@ -341,5 +341,12 @@
"Name": "演示系统", "Name": "演示系统",
"Code": "0", "Code": "0",
"Define": NumberInt(0) "Define": NumberInt(0)
},
{
"_id": ObjectId("5bd6c73d5fa31256f77e4a49"),
"Category": "系统设置",
"Name": "验证码图床",
"Code": "https://longbow-1258823021.cos.ap-shanghai.myqcloud.com/pic/280/150/",
"Define": NumberInt(0)
} }
] ]

View File

@ -41,6 +41,7 @@ INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'IP地
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'BaiDuIPSvr', 'http://api.map.baidu.com/location/ip?ak=6lvVPMDlm2gjLpU0aiqPsHXi2OiwGQRj&ip=', 0); INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'BaiDuIPSvr', 'http://api.map.baidu.com/location/ip?ak=6lvVPMDlm2gjLpU0aiqPsHXi2OiwGQRj&ip=', 0);
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'JuheIPSvr', 'http://apis.juhe.cn/ip/ipNew?key=f57102d1b9fadd3f4a1c29072d0c0206&ip=', 0); INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'JuheIPSvr', 'http://apis.juhe.cn/ip/ipNew?key=f57102d1b9fadd3f4a1c29072d0c0206&ip=', 0);
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', '演示系统', '0', 0); INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', '演示系统', '0', 0);
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', '验证码图床', 'https://longbow-1258823021.cos.ap-shanghai.myqcloud.com/pic/280/150/', 0);
DELETE FROM Navigations Where Category = '0'; DELETE FROM Navigations Where Category = '0';
INSERT INTO Navigations (ParentId, Name, `Order`, Icon, Url, Category) VALUES (0, '后台管理', 10, 'fa fa-gear', '~/Admin/Index', '0'); INSERT INTO Navigations (ParentId, Name, `Order`, Icon, Url, Category) VALUES (0, '后台管理', 10, 'fa fa-gear', '~/Admin/Index', '0');

View File

@ -40,6 +40,7 @@ INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'IP地
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'BaiDuIPSvr', 'http://api.map.baidu.com/location/ip?ak=6lvVPMDlm2gjLpU0aiqPsHXi2OiwGQRj&ip=', 0); INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'BaiDuIPSvr', 'http://api.map.baidu.com/location/ip?ak=6lvVPMDlm2gjLpU0aiqPsHXi2OiwGQRj&ip=', 0);
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'JuheIPSvr', 'http://apis.juhe.cn/ip/ipNew?key=f57102d1b9fadd3f4a1c29072d0c0206&ip=', 0); INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', 'JuheIPSvr', 'http://apis.juhe.cn/ip/ipNew?key=f57102d1b9fadd3f4a1c29072d0c0206&ip=', 0);
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', '演示系统', '0', 0); INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', '演示系统', '0', 0);
INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统设置', '验证码图床', 'https://longbow-1258823021.cos.ap-shanghai.myqcloud.com/pic/280/150/', 0);
DELETE FROM Navigations Where Category = '0'; DELETE FROM Navigations Where Category = '0';
INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (0, '后台管理', 10, 'fa fa-gear', '~/Admin/Index', '0'); INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (0, '后台管理', 10, 'fa fa-gear', '~/Admin/Index', '0');

View File

@ -39,6 +39,7 @@ INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('系统设置
INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('系统设置', 'BaiDuIPSvr', 'http://api.map.baidu.com/location/ip?ak=6lvVPMDlm2gjLpU0aiqPsHXi2OiwGQRj&ip=', 0); INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('系统设置', 'BaiDuIPSvr', 'http://api.map.baidu.com/location/ip?ak=6lvVPMDlm2gjLpU0aiqPsHXi2OiwGQRj&ip=', 0);
INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('系统设置', 'JuheIPSvr', 'http://apis.juhe.cn/ip/ipNew?key=f57102d1b9fadd3f4a1c29072d0c0206&ip=', 0); INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('系统设置', 'JuheIPSvr', 'http://apis.juhe.cn/ip/ipNew?key=f57102d1b9fadd3f4a1c29072d0c0206&ip=', 0);
INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('系统设置', '演示系统', '0', 0); INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('系统设置', '演示系统', '0', 0);
INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('系统设置', '验证码图床', 'https://longbow-1258823021.cos.ap-shanghai.myqcloud.com/pic/280/150/', 0);
DELETE FROM Navigations Where Category = '0'; DELETE FROM Navigations Where Category = '0';
INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (0, '后台管理', 10, 'fa fa-gear', '~/Admin/Index', '0'); INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (0, '后台管理', 10, 'fa fa-gear', '~/Admin/Index', '0');