diff --git a/Bootstrap.Admin/Bootstrap.Admin.csproj b/Bootstrap.Admin/Bootstrap.Admin.csproj index a1b55f84..4e5ecfc7 100644 --- a/Bootstrap.Admin/Bootstrap.Admin.csproj +++ b/Bootstrap.Admin/Bootstrap.Admin.csproj @@ -1,4 +1,4 @@ - + netcoreapp2.2 diff --git a/Bootstrap.Admin/BootstrapAdmin.db b/Bootstrap.Admin/BootstrapAdmin.db index 415a47b1..46aab330 100644 Binary files a/Bootstrap.Admin/BootstrapAdmin.db and b/Bootstrap.Admin/BootstrapAdmin.db differ diff --git a/Bootstrap.Admin/Controllers/AccountController.cs b/Bootstrap.Admin/Controllers/AccountController.cs index 58053a60..93dccc9b 100644 --- a/Bootstrap.Admin/Controllers/AccountController.cs +++ b/Bootstrap.Admin/Controllers/AccountController.cs @@ -33,7 +33,7 @@ namespace Bootstrap.Admin.Controllers ViewBag.UserName = "Admin"; 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()); } /// @@ -56,8 +56,8 @@ namespace Bootstrap.Admin.Controllers // redirect origin url var originUrl = Request.Query[CookieAuthenticationDefaults.ReturnUrlParameter].FirstOrDefault() ?? "~/Home/Index"; return Redirect(originUrl); - } - return View("Login", new ModelBase()); + } + return View("Login", new LoginModel()); } /// diff --git a/Bootstrap.Admin/Models/LoginModel.cs b/Bootstrap.Admin/Models/LoginModel.cs new file mode 100644 index 00000000..af634097 --- /dev/null +++ b/Bootstrap.Admin/Models/LoginModel.cs @@ -0,0 +1,23 @@ +using Bootstrap.DataAccess; + +namespace Bootstrap.Admin.Models +{ + /// + /// + /// + public class LoginModel : ModelBase + { + /// + /// + /// + public LoginModel() + { + ImageLibUrl = DictHelper.RetrieveImagesLibUrl(); + } + + /// + /// 验证码图床地址 + /// + public string ImageLibUrl { get; protected set; } + } +} diff --git a/Bootstrap.Admin/Views/Account/Login.cshtml b/Bootstrap.Admin/Views/Account/Login.cshtml index c60ab59e..1d13da13 100644 --- a/Bootstrap.Admin/Views/Account/Login.cshtml +++ b/Bootstrap.Admin/Views/Account/Login.cshtml @@ -1,219 +1,220 @@ -@model ModelBase -@{ - ViewBag.Title = Model.Title; - Layout = "_Layout"; -} -@section css { - - - - - - - - - - - - - - - @if (!string.IsNullOrEmpty(Model.Theme)) - { - - } -} -@section javascript { - - - - - - - - - - - - - - - - -} -
- -
- - +@model LoginModel +@{ + ViewBag.Title = Model.Title; + Layout = "_Layout"; +} +@section css { + + + + + + + + + + + + + + + @if (!string.IsNullOrEmpty(Model.Theme)) + { + + } +} +@section javascript { + + + + + + + + + + + + + + + + +} +
+ + +
+ + diff --git a/Bootstrap.Admin/wwwroot/js/login.js b/Bootstrap.Admin/wwwroot/js/login.js index 784b663e..8f221036 100644 --- a/Bootstrap.Admin/wwwroot/js/login.js +++ b/Bootstrap.Admin/wwwroot/js/login.js @@ -1,4 +1,5 @@ $(function () { + var $imgUrl = $('#imgUrl'); $(".container").autoCenter(); $("a[data-method]").on('click', function () { @@ -94,8 +95,11 @@ $('#captcha, #regcap, #forgotcap').sliderCaptcha({ width: $.capWidth(), height: $.capHeight(), + localImages: function () { + return '../../lib/captcha/images/Pic' + Math.round(Math.random() * 4) + '.jpg'; + }, 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 () { var parent = this.$element.parents('.slidercaptcha').removeClass('d-block'); diff --git a/Bootstrap.Admin/wwwroot/images/Pic0.jpg b/Bootstrap.Admin/wwwroot/lib/captcha/images/Pic0.jpg similarity index 100% rename from Bootstrap.Admin/wwwroot/images/Pic0.jpg rename to Bootstrap.Admin/wwwroot/lib/captcha/images/Pic0.jpg diff --git a/Bootstrap.Admin/wwwroot/images/Pic1.jpg b/Bootstrap.Admin/wwwroot/lib/captcha/images/Pic1.jpg similarity index 100% rename from Bootstrap.Admin/wwwroot/images/Pic1.jpg rename to Bootstrap.Admin/wwwroot/lib/captcha/images/Pic1.jpg diff --git a/Bootstrap.Admin/wwwroot/images/Pic2.jpg b/Bootstrap.Admin/wwwroot/lib/captcha/images/Pic2.jpg similarity index 100% rename from Bootstrap.Admin/wwwroot/images/Pic2.jpg rename to Bootstrap.Admin/wwwroot/lib/captcha/images/Pic2.jpg diff --git a/Bootstrap.Admin/wwwroot/images/Pic3.jpg b/Bootstrap.Admin/wwwroot/lib/captcha/images/Pic3.jpg similarity index 100% rename from Bootstrap.Admin/wwwroot/images/Pic3.jpg rename to Bootstrap.Admin/wwwroot/lib/captcha/images/Pic3.jpg diff --git a/Bootstrap.Admin/wwwroot/images/Pic4.jpg b/Bootstrap.Admin/wwwroot/lib/captcha/images/Pic4.jpg similarity index 100% rename from Bootstrap.Admin/wwwroot/images/Pic4.jpg rename to Bootstrap.Admin/wwwroot/lib/captcha/images/Pic4.jpg diff --git a/Bootstrap.Admin/wwwroot/lib/captcha/longbow.slidercaptcha.js b/Bootstrap.Admin/wwwroot/lib/captcha/longbow.slidercaptcha.js index 9af4f3ca..800c4380 100644 --- a/Bootstrap.Admin/wwwroot/lib/captcha/longbow.slidercaptcha.js +++ b/Bootstrap.Admin/wwwroot/lib/captcha/longbow.slidercaptcha.js @@ -1,4 +1,4 @@ -(function ($) { +(function ($) { 'use strict'; var SliderCaptcha = function (element, options) { @@ -16,11 +16,15 @@ PI: Math.PI, sliderL: 42, // 滑块边长 sliderR: 9, // 滑块半径 + offset: 5, // 容错偏差 loadingText: '正在加载中...', failedText: '再试一次', barText: '向右滑动填充拼图', repeatIcon: 'fa fa-repeat', - maxLoadCount: 3 + maxLoadCount: 3, + localImages: function () { + return 'images/Pic' + Math.round(Math.random() * 4) + '.jpg'; + } }; function Plugin(option) { @@ -40,9 +44,9 @@ var _proto = SliderCaptcha.prototype; _proto.init = function () { - this.initDOM() - this.initImg() - this.bindEvents() + this.initDOM(); + this.initImg(); + this.bindEvents(); }; _proto.initDOM = function () { @@ -86,7 +90,7 @@ Object.assign(this, { canvas, block, - sliderContainer : $(sliderContainer), + sliderContainer: $(sliderContainer), refreshIcon, slider, sliderMask, @@ -127,9 +131,6 @@ 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; @@ -158,8 +159,8 @@ that.text.text('加载失败').addClass('text-danger'); return; } - img.src = localImg(); - } + img.src = that.options.localImages(); + }; img.setSrc = function () { var src = ''; loadCount = 0; @@ -250,7 +251,7 @@ setTimeout(() => { that.text.text(that.options.failedText); that.reset(); - }, 1000) + }, 1000); } }; @@ -261,8 +262,8 @@ 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 () { @@ -274,7 +275,7 @@ 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, + spliced: Math.abs(left - this.x) < this.options.offset, verified: stddev !== 0, // 简单验证下拖动轨迹,为零时表示Y轴上下没有波动,可能非人为操作 } }; diff --git a/Bootstrap.Client.DataAccess/DictHelper.cs b/Bootstrap.Client.DataAccess/DictHelper.cs index b4ca3970..70db656e 100644 --- a/Bootstrap.Client.DataAccess/DictHelper.cs +++ b/Bootstrap.Client.DataAccess/DictHelper.cs @@ -82,5 +82,11 @@ namespace Bootstrap.Client.DataAccess ///
/// public static string RetrieveIconFolderPath() => (RetrieveDicts().FirstOrDefault(d => d.Name == "头像路径" && d.Category == "头像地址" && d.Define == 0) ?? new BootstrapDict() { Code = "~/images/uploader/" }).Code; + + /// + /// 获取验证码图床 + /// + /// + 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; } } diff --git a/Bootstrap.Client/Models/NavigatorBarModel.cs b/Bootstrap.Client/Models/NavigatorBarModel.cs index 671c38de..27889239 100644 --- a/Bootstrap.Client/Models/NavigatorBarModel.cs +++ b/Bootstrap.Client/Models/NavigatorBarModel.cs @@ -17,10 +17,17 @@ namespace Bootstrap.Client.Models public NavigatorBarModel(ControllerBase controller) : base(controller.User.Identity) { Navigations = MenuHelper.RetrieveAppMenus(UserName, $"~/{controller.ControllerContext.ActionDescriptor.ControllerName}/{controller.ControllerContext.ActionDescriptor.ActionName}"); + ImageLibUrl = DictHelper.RetrieveImagesLibUrl(); } + /// /// /// public IEnumerable Navigations { get; } + + /// + /// + /// + public string ImageLibUrl { get; set; } } } \ No newline at end of file diff --git a/Bootstrap.Client/Views/Home/Index.cshtml b/Bootstrap.Client/Views/Home/Index.cshtml index b1ddf8ef..45aa67eb 100644 --- a/Bootstrap.Client/Views/Home/Index.cshtml +++ b/Bootstrap.Client/Views/Home/Index.cshtml @@ -15,6 +15,6 @@

-
+

\ No newline at end of file diff --git a/Bootstrap.Client/wwwroot/js/index.js b/Bootstrap.Client/wwwroot/js/index.js index e879261d..a0048af4 100644 --- a/Bootstrap.Client/wwwroot/js/index.js +++ b/Bootstrap.Client/wwwroot/js/index.js @@ -1,14 +1,19 @@ $(function () { - $('#captcha').sliderCaptcha({ + var $captcha = $('#captcha'); + + $captcha.sliderCaptcha({ + localImages: function () { + return '../../lib/captcha/images/Pic' + Math.round(Math.random() * 4) + '.jpg'; + }, 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 () { var that = this; setTimeout(() => { that.parent().removeClass('d-inline-block'); that.sliderCaptcha('reset'); - window.location.href = "/BA/Admin/Profiles"; + $('.userinfo .dropdown-menu a:first')[0].click(); }, 1000); } }); diff --git a/Bootstrap.Client/wwwroot/lib/captcha/images/Pic0.jpg b/Bootstrap.Client/wwwroot/lib/captcha/images/Pic0.jpg new file mode 100644 index 00000000..ccfbedd1 Binary files /dev/null and b/Bootstrap.Client/wwwroot/lib/captcha/images/Pic0.jpg differ diff --git a/Bootstrap.Client/wwwroot/lib/captcha/images/Pic1.jpg b/Bootstrap.Client/wwwroot/lib/captcha/images/Pic1.jpg new file mode 100644 index 00000000..689cc20c Binary files /dev/null and b/Bootstrap.Client/wwwroot/lib/captcha/images/Pic1.jpg differ diff --git a/Bootstrap.Client/wwwroot/lib/captcha/images/Pic2.jpg b/Bootstrap.Client/wwwroot/lib/captcha/images/Pic2.jpg new file mode 100644 index 00000000..6ec84255 Binary files /dev/null and b/Bootstrap.Client/wwwroot/lib/captcha/images/Pic2.jpg differ diff --git a/Bootstrap.Client/wwwroot/lib/captcha/images/Pic3.jpg b/Bootstrap.Client/wwwroot/lib/captcha/images/Pic3.jpg new file mode 100644 index 00000000..d1d1553d Binary files /dev/null and b/Bootstrap.Client/wwwroot/lib/captcha/images/Pic3.jpg differ diff --git a/Bootstrap.Client/wwwroot/lib/captcha/images/Pic4.jpg b/Bootstrap.Client/wwwroot/lib/captcha/images/Pic4.jpg new file mode 100644 index 00000000..d718c2bb Binary files /dev/null and b/Bootstrap.Client/wwwroot/lib/captcha/images/Pic4.jpg differ diff --git a/Bootstrap.Client/wwwroot/lib/captcha/longbow.slidercaptcha.js b/Bootstrap.Client/wwwroot/lib/captcha/longbow.slidercaptcha.js index 8ffe2aa5..800c4380 100644 --- a/Bootstrap.Client/wwwroot/lib/captcha/longbow.slidercaptcha.js +++ b/Bootstrap.Client/wwwroot/lib/captcha/longbow.slidercaptcha.js @@ -1,292 +1,293 @@ -(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(); - }; +(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, // 滑块半径 + offset: 5, // 容错偏差 + loadingText: '正在加载中...', + failedText: '再试一次', + barText: '向右滑动填充拼图', + repeatIcon: 'fa fa-repeat', + maxLoadCount: 3, + localImages: function () { + return 'images/Pic' + Math.round(Math.random() * 4) + '.jpg'; + } + }; + + 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 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 = that.options.localImages(); + }; + 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) < this.options.offset, + 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.DataAccess/Dict.cs b/Bootstrap.DataAccess/Dict.cs index ae20f704..46908bec 100644 --- a/Bootstrap.DataAccess/Dict.cs +++ b/Bootstrap.DataAccess/Dict.cs @@ -1,180 +1,186 @@ -using Bootstrap.Security; -using Bootstrap.Security.DataAccess; -using Longbow; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Bootstrap.DataAccess -{ - /// - /// - /// - public class Dict : BootstrapDict - { - /// - /// 删除字典中的数据 - /// - /// 需要删除的IDs - /// - public virtual bool Delete(IEnumerable value) - { - if (!value.Any()) return true; - var ids = string.Join(",", value); - string sql = $"where ID in ({ids})"; - DbManager.Create().Delete(sql); - return true; - } - - /// - /// 保存新建/更新的字典信息 - /// - /// - /// - public virtual bool Save(BootstrapDict dict) - { - 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.Code.Length > 50) dict.Code = dict.Code.Substring(0, 50); - - DbManager.Create().Save(dict); - return true; - } - - /// - /// 保存网站个性化设置 - /// - /// - /// - public virtual bool SaveSettings(BootstrapDict dict) - { - DbManager.Create().Update("set Code = @Code where Category = @Category and Name = @Name", dict); - return true; - } - - /// - /// 获取字典分类名称 - /// - /// - public virtual IEnumerable RetrieveCategories() => DictHelper.RetrieveDicts().OrderBy(d => d.Category).Select(d => d.Category).Distinct(); - - /// - /// - /// - /// - public virtual string RetrieveWebTitle() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "网站标题" && d.Category == "网站设置" && d.Define == 0) ?? new BootstrapDict() { Code = "后台管理系统" }).Code; - - /// - /// - /// - /// - public virtual string RetrieveWebFooter() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "网站页脚" && d.Category == "网站设置" && d.Define == 0) ?? new BootstrapDict() { Code = "2016 © 通用后台管理系统" }).Code; - - /// - /// 获得系统中配置的可以使用的网站样式 - /// - /// - public virtual IEnumerable RetrieveThemes() => DictHelper.RetrieveDicts().Where(d => d.Category == "网站样式"); - - /// - /// 获得网站设置中的当前样式 - /// - /// - public virtual string RetrieveActiveTheme() - { - 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); - } - - /// - /// 获取头像路径 - /// - /// - public virtual string RetrieveIconFolderPath() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "头像路径" && d.Category == "头像地址" && d.Define == 0) ?? new BootstrapDict { Code = "~/images/uploader/" }).Code; - - /// - /// 获得默认的前台首页地址,默认为~/Home/Index - /// - /// - /// - public virtual string RetrieveHomeUrl(string appCode) - { - // https://gitee.com/LongbowEnterprise/dashboard/issues?id=IS0WK - var url = "~/Home/Index"; - var dicts = DictHelper.RetrieveDicts(); - if (appCode != "0") - { - var appUrl = dicts.FirstOrDefault(d => d.Name.Equals(appCode, StringComparison.OrdinalIgnoreCase) && d.Category == "应用首页" && d.Define == 0)?.Code; - if (!string.IsNullOrEmpty(appUrl)) - { - url = appUrl; - return url; - } - } - var defaultUrl = dicts.FirstOrDefault(d => d.Name == "前台首页" && d.Category == "网站设置" && d.Define == 0)?.Code; - if (!string.IsNullOrEmpty(defaultUrl)) url = defaultUrl; - return url; - } - - /// - /// - /// - /// - public virtual IEnumerable> RetrieveApps() => DictHelper.RetrieveDicts().Where(d => d.Category == "应用程序" && d.Define == 0).Select(d => new KeyValuePair(d.Code, d.Name)).OrderBy(d => d.Key); - - /// - /// 通过数据库获得所有字典表配置信息,缓存Key=DictHelper-RetrieveDicts - /// - /// - public virtual IEnumerable RetrieveDicts() => DbHelper.RetrieveDicts(); - - /// - /// 程序异常时长 默认1月 - /// - /// - public int RetrieveExceptionsLogPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "程序异常保留时长" && d.Define == 0)?.Code, 1); - - /// - /// 操作日志时长 默认12月 - /// - /// - public int RetrieveLogsPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "操作日志保留时长" && d.Define == 0)?.Code, 12); - - /// - /// 登录日志时长 默认12月 - /// - /// - public int RetrieveLoginLogsPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "登录日志保留时长" && d.Define == 0)?.Code, 12); - - /// - /// Cookie保存时长 默认7天 - /// - /// - public int RetrieveCookieExpiresPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "Cookie保留时长" && d.Define == 0)?.Code, 7); - - /// - /// 获得 IP地理位置 - /// - /// - public string RetrieveLocaleIPSvr() => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "IP地理位置接口" && d.Define == 0)?.Code; - - /// - /// 获得 项目是否获取登录地点 默认为false - /// - /// 服务提供名称 - /// - public string RetrieveLocaleIPSvrUrl(string ipSvr) => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == ipSvr && d.Define == 0)?.Code; - - /// - /// 获得 访问日志保留时长 默认为1个月 - /// - /// - public int RetrieveAccessLogPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "访问日志保留时长" && d.Define == 0)?.Code, 1); - - /// - /// 获得 是否为演示系统 默认为 false 不是演示系统 - /// - /// - public bool RetrieveSystemModel() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "演示系统" && d.Define == 0)?.Code, "0") == "1"; - } -} +using Bootstrap.Security; +using Bootstrap.Security.DataAccess; +using Longbow; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Bootstrap.DataAccess +{ + /// + /// + /// + public class Dict : BootstrapDict + { + /// + /// 删除字典中的数据 + /// + /// 需要删除的IDs + /// + public virtual bool Delete(IEnumerable value) + { + if (!value.Any()) return true; + var ids = string.Join(",", value); + string sql = $"where ID in ({ids})"; + DbManager.Create().Delete(sql); + return true; + } + + /// + /// 保存新建/更新的字典信息 + /// + /// + /// + public virtual bool Save(BootstrapDict dict) + { + 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.Code.Length > 50) dict.Code = dict.Code.Substring(0, 50); + + DbManager.Create().Save(dict); + return true; + } + + /// + /// 保存网站个性化设置 + /// + /// + /// + public virtual bool SaveSettings(BootstrapDict dict) + { + DbManager.Create().Update("set Code = @Code where Category = @Category and Name = @Name", dict); + return true; + } + + /// + /// 获取字典分类名称 + /// + /// + public virtual IEnumerable RetrieveCategories() => DictHelper.RetrieveDicts().OrderBy(d => d.Category).Select(d => d.Category).Distinct(); + + /// + /// + /// + /// + public virtual string RetrieveWebTitle() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "网站标题" && d.Category == "网站设置" && d.Define == 0) ?? new BootstrapDict() { Code = "后台管理系统" }).Code; + + /// + /// + /// + /// + public virtual string RetrieveWebFooter() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "网站页脚" && d.Category == "网站设置" && d.Define == 0) ?? new BootstrapDict() { Code = "2016 © 通用后台管理系统" }).Code; + + /// + /// 获得系统中配置的可以使用的网站样式 + /// + /// + public virtual IEnumerable RetrieveThemes() => DictHelper.RetrieveDicts().Where(d => d.Category == "网站样式"); + + /// + /// 获得网站设置中的当前样式 + /// + /// + public virtual string RetrieveActiveTheme() + { + 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); + } + + /// + /// 获取头像路径 + /// + /// + public virtual string RetrieveIconFolderPath() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Name == "头像路径" && d.Category == "头像地址" && d.Define == 0) ?? new BootstrapDict { Code = "~/images/uploader/" }).Code; + + /// + /// 获得默认的前台首页地址,默认为~/Home/Index + /// + /// + /// + public virtual string RetrieveHomeUrl(string appCode) + { + // https://gitee.com/LongbowEnterprise/dashboard/issues?id=IS0WK + var url = "~/Home/Index"; + var dicts = DictHelper.RetrieveDicts(); + if (appCode != "0") + { + var appUrl = dicts.FirstOrDefault(d => d.Name.Equals(appCode, StringComparison.OrdinalIgnoreCase) && d.Category == "应用首页" && d.Define == 0)?.Code; + if (!string.IsNullOrEmpty(appUrl)) + { + url = appUrl; + return url; + } + } + var defaultUrl = dicts.FirstOrDefault(d => d.Name == "前台首页" && d.Category == "网站设置" && d.Define == 0)?.Code; + if (!string.IsNullOrEmpty(defaultUrl)) url = defaultUrl; + return url; + } + + /// + /// + /// + /// + public virtual IEnumerable> RetrieveApps() => DictHelper.RetrieveDicts().Where(d => d.Category == "应用程序" && d.Define == 0).Select(d => new KeyValuePair(d.Code, d.Name)).OrderBy(d => d.Key); + + /// + /// 通过数据库获得所有字典表配置信息,缓存Key=DictHelper-RetrieveDicts + /// + /// + public virtual IEnumerable RetrieveDicts() => DbHelper.RetrieveDicts(); + + /// + /// 程序异常时长 默认1月 + /// + /// + public int RetrieveExceptionsLogPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "程序异常保留时长" && d.Define == 0)?.Code, 1); + + /// + /// 操作日志时长 默认12月 + /// + /// + public int RetrieveLogsPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "操作日志保留时长" && d.Define == 0)?.Code, 12); + + /// + /// 登录日志时长 默认12月 + /// + /// + public int RetrieveLoginLogsPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "登录日志保留时长" && d.Define == 0)?.Code, 12); + + /// + /// Cookie保存时长 默认7天 + /// + /// + public int RetrieveCookieExpiresPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "Cookie保留时长" && d.Define == 0)?.Code, 7); + + /// + /// 获得 IP地理位置 + /// + /// + public string RetrieveLocaleIPSvr() => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "IP地理位置接口" && d.Define == 0)?.Code; + + /// + /// 获得 项目是否获取登录地点 默认为false + /// + /// 服务提供名称 + /// + public string RetrieveLocaleIPSvrUrl(string ipSvr) => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == ipSvr && d.Define == 0)?.Code; + + /// + /// 获得 访问日志保留时长 默认为1个月 + /// + /// + public int RetrieveAccessLogPeriod() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "访问日志保留时长" && d.Define == 0)?.Code, 1); + + /// + /// 获得 是否为演示系统 默认为 false 不是演示系统 + /// + /// + public bool RetrieveSystemModel() => LgbConvert.ReadValue(DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "系统设置" && d.Name == "演示系统" && d.Define == 0)?.Code, "0") == "1"; + + /// + /// 获得 验证码图床地址 + /// + /// + 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/"); + } +} diff --git a/Bootstrap.DataAccess/Helper/DictHelper.cs b/Bootstrap.DataAccess/Helper/DictHelper.cs index 93ae369f..0f704c63 100644 --- a/Bootstrap.DataAccess/Helper/DictHelper.cs +++ b/Bootstrap.DataAccess/Helper/DictHelper.cs @@ -200,5 +200,11 @@ namespace Bootstrap.DataAccess ///
/// public static bool RetrieveSystemModel() => DbContextManager.Create().RetrieveSystemModel(); + + /// + /// 获得验证码图床地址 + /// + /// + public static string RetrieveImagesLibUrl() => DbContextManager.Create().RetrieveImagesLibUrl(); } } diff --git a/DatabaseScripts/InitData.sql b/DatabaseScripts/InitData.sql index 836f9c2d..cf6e47d4 100644 --- a/DatabaseScripts/InitData.sql +++ b/DatabaseScripts/InitData.sql @@ -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'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'验证码图床', 'https://longbow-1258823021.cos.ap-shanghai.myqcloud.com/pic/280/150/', 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') diff --git a/DatabaseScripts/MongoDB/BootstrapAdmin.Dicts.json b/DatabaseScripts/MongoDB/BootstrapAdmin.Dicts.json index 83a3db13..9cf9fbf8 100644 --- a/DatabaseScripts/MongoDB/BootstrapAdmin.Dicts.json +++ b/DatabaseScripts/MongoDB/BootstrapAdmin.Dicts.json @@ -341,5 +341,12 @@ "Name": "演示系统", "Code": "0", "Define": NumberInt(0) + }, + { + "_id": ObjectId("5bd6c73d5fa31256f77e4a49"), + "Category": "系统设置", + "Name": "验证码图床", + "Code": "https://longbow-1258823021.cos.ap-shanghai.myqcloud.com/pic/280/150/", + "Define": NumberInt(0) } ] \ No newline at end of file diff --git a/DatabaseScripts/MySQL/initData.sql b/DatabaseScripts/MySQL/initData.sql index e4ba462a..348e6142 100644 --- a/DatabaseScripts/MySQL/initData.sql +++ b/DatabaseScripts/MySQL/initData.sql @@ -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 ('系统设置', '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 ('系统设置', '验证码图床', 'https://longbow-1258823021.cos.ap-shanghai.myqcloud.com/pic/280/150/', 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'); diff --git a/DatabaseScripts/Postgresql/initData.sql b/DatabaseScripts/Postgresql/initData.sql index e82d2ca7..0489a044 100644 --- a/DatabaseScripts/Postgresql/initData.sql +++ b/DatabaseScripts/Postgresql/initData.sql @@ -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 ('系统设置', '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 ('系统设置', '验证码图床', 'https://longbow-1258823021.cos.ap-shanghai.myqcloud.com/pic/280/150/', 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'); diff --git a/DatabaseScripts/SQLite/InitData.sql b/DatabaseScripts/SQLite/InitData.sql index d05ec895..d9f71359 100644 --- a/DatabaseScripts/SQLite/InitData.sql +++ b/DatabaseScripts/SQLite/InitData.sql @@ -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 ('系统设置', '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 ('系统设置', '验证码图床', 'https://longbow-1258823021.cos.ap-shanghai.myqcloud.com/pic/280/150/', 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');