diff --git a/db/MongoDB/Dicts.js b/db/MongoDB/Dicts.js index 0b4d1cd4..2853f411 100644 --- a/db/MongoDB/Dicts.js +++ b/db/MongoDB/Dicts.js @@ -360,4 +360,22 @@ "Code": "/favicon.png", "Define": NumberInt(1) } + { + "Category": "系统首页", + "Name": "高仿码云", + "Code": "Login-Gitee", + "Define": NumberInt(0) + }, + { + "Category": "系统首页", + "Name": "系统默认", + "Code": "Login", + "Define": NumberInt(0) + }, + { + "Category": "网站设置", + "Name": "登录界面", + "Code": "Login", + "Define": NumberInt(0) + } ]; \ No newline at end of file diff --git a/db/MySQL/initData.sql b/db/MySQL/initData.sql index 1e179238..979c83dc 100644 --- a/db/MySQL/initData.sql +++ b/db/MySQL/initData.sql @@ -77,6 +77,12 @@ INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('网站设置', '默认 INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('网站设置', '后台地址', 'http://localhost:50852', 0); +-- 系统登录首页设置 +INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统首页', '高仿码云', 'Login-Gitee', 1); +INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('系统首页', '系统默认', 'Login', 1); + +INSERT INTO Dicts (Category, Name, Code, Define) VALUES ('网站设置', '登录界面', 'Login', 1); + DELETE FROM Navigations Where Category = '0'; INSERT INTO Navigations (ParentId, Name, `Order`, Icon, Url, Category) VALUES (0, '后台管理', 10, 'fa fa-gear', '~/Admin/Index', '0'); INSERT INTO Navigations (ParentId, Name, `Order`, Icon, Url, Category) VALUES (0, '个人中心', 20, 'fa fa-suitcase', '~/Admin/Profiles', '0'); diff --git a/db/Oracle/InitData.sql b/db/Oracle/InitData.sql index 1d14392a..14b4bece 100644 --- a/db/Oracle/InitData.sql +++ b/db/Oracle/InitData.sql @@ -76,6 +76,12 @@ INSERT INTO Dicts (Id, Category, Name, Code, Define) Values (SEQ_DICTS_ID.NEXTVA INSERT INTO Dicts (Id, Category, Name, Code, Define) Values (SEQ_DICTS_ID.NEXTVAL, '网站设置', '默认应用程序', '0', 0); INSERT INTO Dicts (Id, Category, Name, Code, Define) Values (SEQ_DICTS_ID.NEXTVAL, '网站设置', '后台地址', 'http://localhost:50852', 0); +-- 系统登录首页设置 +INSERT INTO Dicts (Id, Category, Name, Code, Define) VALUES (SEQ_DICTS_ID.NEXTVAL, '系统首页', '高仿码云', 'Login-Gitee', 1); +INSERT INTO Dicts (Id, Category, Name, Code, Define) VALUES (SEQ_DICTS_ID.NEXTVAL, '系统首页', '系统默认', 'Login', 1); + +INSERT INTO Dicts (Id, Category, Name, Code, Define) VALUES (SEQ_DICTS_ID.NEXTVAL, '网站设置', '登录界面', 'Login', 1); + DELETE FROM Navigations Where Category = '0'; INSERT INTO Navigations (Id, ParentId, Name, "ORDER", Icon, Url, Category) Values (SEQ_NAVIGATIONS_ID.NEXTVAL, 0, '后台管理', 10, 'fa fa-gear', '~/Admin/Index', '0'); INSERT INTO Navigations (Id, ParentId, Name, "ORDER", Icon, Url, Category) Values (SEQ_NAVIGATIONS_ID.NEXTVAL, 0, '个人中心', 20, 'fa fa-suitcase', '~/Admin/Profiles', '0'); diff --git a/db/SQLite/InitData.sql b/db/SQLite/InitData.sql index 34c2d516..2693a851 100644 --- a/db/SQLite/InitData.sql +++ b/db/SQLite/InitData.sql @@ -81,6 +81,12 @@ INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('网站设置 INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('网站设置', '后台地址', 'http://localhost:50852', 0); +-- 系统登录首页设置 +INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('系统首页', '高仿码云', 'Login-Gitee', 1); +INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('系统首页', '系统默认', 'Login', 1); + +INSERT INTO [Dicts] ([Category], [Name], [Code], [Define]) VALUES ('网站设置', '登录界面', 'Login', 1); + DELETE FROM Navigations Where Category = '0'; INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (0, '后台管理', 10, 'fa fa-gear', '~/Admin/Index', '0'); INSERT INTO [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (0, '个人中心', 20, 'fa fa-suitcase', '~/Admin/Profiles', '0'); diff --git a/db/SqlServer/InitData.sql b/db/SqlServer/InitData.sql index 4de9a43a..7db66186 100644 --- a/db/SqlServer/InitData.sql +++ b/db/SqlServer/InitData.sql @@ -81,6 +81,12 @@ INSERT [dbo].[Dicts] ([Category], [Name], [Code], [Define]) VALUES (N'网站设 INSERT [dbo].[Dicts] ([Category], [Name], [Code], [Define]) VALUES (N'网站设置', N'后台地址', 'http://localhost:50852', 0) +-- 系统登录首页设置 +INSERT INTO Dicts (Category, Name, Code, Define) VALUES (N'系统首页', N'高仿码云', N'Login-Gitee', 1); +INSERT INTO Dicts (Category, Name, Code, Define) VALUES (N'系统首页', N'系统默认', N'Login', 1); + +INSERT INTO Dicts (Category, Name, Code, Define) VALUES (N'网站设置', N'登录界面', N'Login', 1); + DELETE FROM Navigations Where Category = N'0' INSERT [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (0, N'后台管理', 10, N'fa fa-gear', N'~/Admin/Index', N'0') INSERT [Navigations] ([ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (0, N'个人中心', 20, N'fa fa-suitcase', N'~/Admin/Profiles', N'0') diff --git a/src/admin/Bootstrap.Admin/BootstrapAdmin.db b/src/admin/Bootstrap.Admin/BootstrapAdmin.db index d586549c..48864744 100644 Binary files a/src/admin/Bootstrap.Admin/BootstrapAdmin.db and b/src/admin/Bootstrap.Admin/BootstrapAdmin.db differ diff --git a/src/admin/Bootstrap.Admin/Controllers/AccountController.cs b/src/admin/Bootstrap.Admin/Controllers/AccountController.cs index 739c784f..3d1888b4 100644 --- a/src/admin/Bootstrap.Admin/Controllers/AccountController.cs +++ b/src/admin/Bootstrap.Admin/Controllers/AccountController.cs @@ -74,16 +74,27 @@ namespace Bootstrap.Admin.Controllers /// 系统登录方法 /// /// + /// /// [HttpGet] - public ActionResult Login([FromQuery]string? appId = null) + public ActionResult Login([FromQuery]string? appId = null, [FromQuery]string view = "") { if (DictHelper.RetrieveSystemModel()) { ViewBag.UserName = "Admin"; ViewBag.Password = "123789"; } - return User.Identity.IsAuthenticated ? (ActionResult)Redirect("~/Home/Index") : View("Login", new LoginModel(appId)); + return User.Identity.IsAuthenticated ? (ActionResult)Redirect("~/Home/Index") : LoginView(view, new LoginModel(appId)); + } + + private ViewResult LoginView(string view, LoginModel model) + { + if (string.IsNullOrEmpty(view)) + { + // retrieve login view from db + view = DictHelper.RetrieveLoginView(); + } + return View(view, model); } /// diff --git a/src/admin/Bootstrap.Admin/Models/SettingsModel.cs b/src/admin/Bootstrap.Admin/Models/SettingsModel.cs index 4d164881..af2123d6 100644 --- a/src/admin/Bootstrap.Admin/Models/SettingsModel.cs +++ b/src/admin/Bootstrap.Admin/Models/SettingsModel.cs @@ -32,6 +32,10 @@ namespace Bootstrap.Admin.Models EnableDemo = DictHelper.RetrieveSystemModel(); AdminPathBase = DictHelper.RetrievePathBase(); EnableHealth = DictHelper.RetrieveHealth(); + Logins = DictHelper.RetrieveLogins(); + var view = DictHelper.RetrieveLoginView(); + var viewName = Logins.FirstOrDefault(d => d.Code == view)?.Name ?? "系统默认"; + LoginView = new KeyValuePair(view, viewName); var dicts = DictHelper.RetrieveDicts(); Apps = DictHelper.RetrieveApps().Where(d => !d.Key.Equals("BA", StringComparison.OrdinalIgnoreCase)).Select(k => @@ -115,5 +119,15 @@ namespace Bootstrap.Admin.Models /// 获得/设置 是否开启健康检查 /// public bool EnableHealth { get; set; } + + /// + /// 获得/设置 字典表中登录首页集合 + /// + public IEnumerable Logins { get; set; } + + /// + /// 获得/设置 登录视图名称 默认是 Login + /// + public KeyValuePair LoginView { get; set; } } } diff --git a/src/admin/Bootstrap.Admin/Views/Account/Login-Gitee.cshtml b/src/admin/Bootstrap.Admin/Views/Account/Login-Gitee.cshtml new file mode 100644 index 00000000..cda75d4f --- /dev/null +++ b/src/admin/Bootstrap.Admin/Views/Account/Login-Gitee.cshtml @@ -0,0 +1,305 @@ +@model LoginModel +@{ + ViewBag.Title = Model.Title; + Layout = "_Layout"; +} +@section css { + + + + + + + + + + + +} +@section javascript { + + + + + + + + + + + + + + +} +
+ + + +
+ + diff --git a/src/admin/Bootstrap.Admin/Views/Admin/Settings.cshtml b/src/admin/Bootstrap.Admin/Views/Admin/Settings.cshtml index d3548662..1079fed4 100644 --- a/src/admin/Bootstrap.Admin/Views/Admin/Settings.cshtml +++ b/src/admin/Bootstrap.Admin/Views/Admin/Settings.cshtml @@ -57,6 +57,27 @@ +
+
+
+
+
+
+
+ + +
+ +
+
+
+
+
diff --git a/src/admin/Bootstrap.Admin/wwwroot/css/login-gitee.css b/src/admin/Bootstrap.Admin/wwwroot/css/login-gitee.css new file mode 100644 index 00000000..60585bd6 --- /dev/null +++ b/src/admin/Bootstrap.Admin/wwwroot/css/login-gitee.css @@ -0,0 +1,197 @@ +body { + -webkit-font-smoothing: antialiased; +} + +.form-control:focus { + border-color: #66afe9; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102,175,233,.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102,175,233,.6); +} + +.login-wrap .rememberPwd i { + width: 13px; +} + +.login-wrap .rememberPwd { + cursor: pointer; + margin-left: 2px; +} + +.container-fluid { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: flex; + align-items: center; + justify-content: center; + min-width: 1000px; +} + +.login-container { + min-height: 500px; + box-shadow: 0px 20px 80px 0px rgba(0,0,0,0.3); + display: flex; + width: 1000px; +} + + .login-container section { + width: 50%; + } + + .login-container .login-sidebox { + position: relative; + background: -webkit-gradient(linear, left bottom, left top, from(#3a485a), to(#607089)); + background: linear-gradient(0deg, #3a485a 0%, #607089 100%); + color: #fff; + } + + .login-container .login-sidebox::before, .login-container .login-sidebox::after { + content: ''; + top: 0; + right: 0; + bottom: 0; + left: 0; + position: absolute; + } + + .login-container .login-sidebox::before { + background: url(../images/left-1.png) no-repeat 0 0; + } + + .login-container .login-sidebox::after { + background: url(../images/left-2.png) no-repeat right bottom; + } + + .login-container .login-sidebox .login-sidebox-content { + padding: 80px 80px 48px; + position: relative; + z-index: 1; + } + +.login-sidebox-header { + margin-bottom: 40px; +} + +.login-sidebox-logo { + display: flex; + align-items: center; + margin-bottom: 14px; +} + + .login-sidebox-logo img { + width: 48px; + height: auto; + border-radius: 50%; + margin-right: 14px; + } + + .login-sidebox-logo span { + display: inline; + font-size: 1.5rem; + font-weight: 700; + } + +.login-sidebox-subtitle { + font-size: 20pt; + font-weight: normal; +} + +.login-sidebox-footer { + margin-top: 40px; + border-top: solid 1px #ddd; + padding-top: 28px; + font-size: 0.875rem; + font-weight: 500; +} + + .login-sidebox-footer a { + cursor: pointer; + color: #fff; + } + +.login-form { + padding: 64px; + font-size: 0.875rem; +} + +.login-form-header { + display: flex; + justify-content: space-between; + align-items: flex-end; + margin-bottom: 20px; +} + + .login-form-header h2 { + margin-bottom: 0; + font-size: 1.714rem; + } + +.login-other { + display: table; + text-align: center; + white-space: nowrap; + margin: 0.25rem 0 0.625rem 0; +} + + .login-other:before, .login-other:after { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAACCAYAAACuTHuKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1OThBRDY4OUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1OThBRDY4QUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjU5OEFENjg3Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjU5OEFENjg4Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+VU513gAAADVJREFUeNrs0DENACAQBDBIWLGBJQby/mUcJn5sJXQmOQMAAAAAAJqt+2prAAAAAACg2xdgANk6BEVuJgyMAAAAAElFTkSuQmCC"); + content: ''; + display: table-cell; + position: relative; + top: 50%; + width: 50%; + background-repeat: no-repeat; + } + + .login-other:before { + background-position: right 1em top 50%; + } + + .login-other:after { + background-position: left 1em top 50%; + } + +.login-list { + display: flex; + justify-content: space-between; +} + + .login-list .item { + width: 32px; + height: 32px; + } + +.btn-login { + color: #fff; + background: #fe7300; +} + + .btn-login:hover { + background: #f38d30; + color: #fff; + } + +.forget-password { + padding: 16px 0; +} + +.login-footer { + position: absolute; + bottom: 40px; +} + + .login-footer .login-footer-body { + display: flex; + width: 600px; + justify-content: space-around; + } + + .login-footer .login-footer-body li { + list-style: none; + } + + .login-footer .login-footer-body li a { + color: #7e8392; + } diff --git a/src/admin/Bootstrap.Admin/wwwroot/html/login1.html b/src/admin/Bootstrap.Admin/wwwroot/html/login1.html new file mode 100644 index 00000000..b71c2663 --- /dev/null +++ b/src/admin/Bootstrap.Admin/wwwroot/html/login1.html @@ -0,0 +1,163 @@ + + + + + + + + + + + 健康检查 + + + + + + + + + +
+ +
+ + + + + + + + + + \ No newline at end of file diff --git a/src/admin/Bootstrap.Admin/wwwroot/images/left-1.png b/src/admin/Bootstrap.Admin/wwwroot/images/left-1.png new file mode 100644 index 00000000..171999df Binary files /dev/null and b/src/admin/Bootstrap.Admin/wwwroot/images/left-1.png differ diff --git a/src/admin/Bootstrap.Admin/wwwroot/images/left-2.png b/src/admin/Bootstrap.Admin/wwwroot/images/left-2.png new file mode 100644 index 00000000..42cc4d26 Binary files /dev/null and b/src/admin/Bootstrap.Admin/wwwroot/images/left-2.png differ diff --git a/src/admin/Bootstrap.Admin/wwwroot/js/settings.js b/src/admin/Bootstrap.Admin/wwwroot/js/settings.js index 16dd4b76..f6a9fbd0 100644 --- a/src/admin/Bootstrap.Admin/wwwroot/js/settings.js +++ b/src/admin/Bootstrap.Admin/wwwroot/js/settings.js @@ -238,6 +238,12 @@ $(function () { } }); break; + case 'saveLoginView': + var logView = $('#loginView').val(); + $.bc({ + url: Settings.url, data: [{ name: 'Login', code: logView }], title: '保存登录界面设置', method: "post" + }); + break; } }); diff --git a/src/admin/Bootstrap.Admin/wwwroot/lib/longbow/longbow.common.js b/src/admin/Bootstrap.Admin/wwwroot/lib/longbow/longbow.common.js index ceceeeca..8661857c 100644 --- a/src/admin/Bootstrap.Admin/wwwroot/lib/longbow/longbow.common.js +++ b/src/admin/Bootstrap.Admin/wwwroot/lib/longbow/longbow.common.js @@ -298,6 +298,7 @@ $.fn.extend({ autoCenter: function (options) { + if (this.length === 0) return; options = $.extend({ top: 0 }, options); var that = this; var defaultVal = parseFloat(that.css('marginTop').replace('px', '')); diff --git a/src/admin/Bootstrap.DataAccess/Dict.cs b/src/admin/Bootstrap.DataAccess/Dict.cs index c8f836a3..290c731a 100644 --- a/src/admin/Bootstrap.DataAccess/Dict.cs +++ b/src/admin/Bootstrap.DataAccess/Dict.cs @@ -325,5 +325,17 @@ namespace Bootstrap.DataAccess /// /// public bool RetrieveHealth() => (DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "网站设置" && d.Name == "健康检查" && d.Define == 0)?.Code ?? "0") == "1"; + + /// + /// 获得字典表登录界面数据 + /// + /// + public IEnumerable RetrieveLogins() => DictHelper.RetrieveDicts().Where(d => d.Category == "系统首页" && d.Define == 1); + + /// + /// 获得使用中的登录视图名称 + /// + /// + public string? RetrieveLoginView() => DictHelper.RetrieveDicts().FirstOrDefault(d => d.Category == "网站设置" && d.Name == "登录界面" && d.Define == 1)?.Code; } } diff --git a/src/admin/Bootstrap.DataAccess/Helper/DictHelper.cs b/src/admin/Bootstrap.DataAccess/Helper/DictHelper.cs index 1ce3c93d..b77b21b5 100644 --- a/src/admin/Bootstrap.DataAccess/Helper/DictHelper.cs +++ b/src/admin/Bootstrap.DataAccess/Helper/DictHelper.cs @@ -165,7 +165,8 @@ namespace Bootstrap.DataAccess ["CookiePeriod"] = "Cookie保留时长", ["IPCachePeriod"] = "IP请求缓存时长", ["AppPath"] = "后台地址", - ["EnableHealth"] = "健康检查" + ["EnableHealth"] = "健康检查", + ["Login"] = "登录界面" }; var ret = SaveSettings(items.Where(i => cache.Any(c => c.Key == i.Name)).Select(i => new BootstrapDict() { @@ -391,6 +392,18 @@ namespace Bootstrap.DataAccess /// public static bool RetrieveHealth() => DbContextManager.Create()?.RetrieveHealth() ?? true; + /// + /// 获得登录界面数据 + /// + /// + public static IEnumerable RetrieveLogins() => DbContextManager.Create()?.RetrieveLogins() ?? new BootstrapDict[0]; + + /// + /// 获得使用中的登录视图名称 + /// + /// + public static string RetrieveLoginView() => DbContextManager.Create()?.RetrieveLoginView() ?? "Login"; + /// /// 保存前台应用配置信息 /// diff --git a/test/UnitTest/Bootstrap.Admin/Controllers/LoginTest.cs b/test/UnitTest/Bootstrap.Admin/Controllers/LoginTest.cs index d39bbb3a..404e1726 100644 --- a/test/UnitTest/Bootstrap.Admin/Controllers/LoginTest.cs +++ b/test/UnitTest/Bootstrap.Admin/Controllers/LoginTest.cs @@ -29,7 +29,7 @@ namespace Bootstrap.Admin.Controllers var content = await r.Content.ReadAsStringAsync(); Assert.Contains("登 录", content); - r = await client.GetAsync("/Account/Login"); + r = await client.GetAsync("/Account/Login?AppId=BA&View=Login1"); var view = await r.Content.ReadAsStringAsync(); var tokenTag = "