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');