增加功能:增加登录日志页面Admin/Logins link #IS7RM

This commit is contained in:
Argo Zhang 2019-03-04 13:21:04 +08:00
parent 348438896c
commit 64c2e10290
16 changed files with 170 additions and 12 deletions

View File

@ -52,6 +52,12 @@ namespace Bootstrap.Admin.Controllers
/// <returns></returns>
public ActionResult Logs() => View(new NavigatorBarModel(this));
/// <summary>
///
/// </summary>
/// <returns></returns>
public ActionResult Logins() => View(new NavigatorBarModel(this));
/// <summary>
///
/// </summary>

View File

@ -3,6 +3,8 @@ using Bootstrap.Security;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Linq;
namespace Bootstrap.Admin.Controllers.Api
{
@ -16,6 +18,13 @@ namespace Bootstrap.Admin.Controllers.Api
[ApiController]
public class LoginController : ControllerBase
{
/// <summary>
/// 获得登录历史记录
/// </summary>
/// <returns></returns>
[HttpGet]
public IEnumerable<LoginUser> Get() => LoginHelper.Retrieves();
/// <summary>
///
/// </summary>

View File

@ -0,0 +1,29 @@
@model NavigatorBarModel
@{
ViewBag.Title = "登录日志";
}
@section css {
<environment include="Development">
<link href="~/lib/bootstrap-table/bootstrap-table.css" rel="stylesheet" />
</environment>
<environment exclude="Development">
<link href="~/lib/bootstrap-table/bootstrap-table.min.css" rel="stylesheet" />
</environment>
}
@section javascript {
<environment include="Development">
<script src="~/lib/bootstrap-table/bootstrap-table.js"></script>
<script src="~/lib/bootstrap-table/locale/bootstrap-table-zh-CN.js"></script>
</environment>
<environment exclude="Development">
<script src="~/lib/bootstrap-table/bootstrap-table.min.js"></script>
<script src="~/lib/bootstrap-table/locale/bootstrap-table-zh-CN.min.js"></script>
</environment>
<script src="~/js/logins.js" asp-append-version="true"></script>
}
<div class="card">
<div class="card-header">在线用户<span class="pull-right"><a id="refreshUsers" href="javascript:;" class="fa fa-refresh" title="点击刷新" data-toggle="tooltip" data-placement="left"></a></span></div>
<div class="card-body" style="padding-top: 25px;">
<table></table>
</div>
</div>

View File

@ -1,6 +1,6 @@
@model NavigatorBarModel
@{
ViewBag.Title = "系统日志";
ViewBag.Title = "操作日志";
}
@section css {
<environment include="Development">

View File

@ -65,6 +65,7 @@
"KeepExceptionsPeriod": 12,
"KeepLogsPeriod": 12,
"CookieExpiresDays": 7,
"KeepLoginLogsPeriod": 7,
"LongbowCache": {
"Enabled": true,
"CorsItems": [

View File

@ -0,0 +1,31 @@
// 登录日志
$(function () {
var apiUrl = "api/Login";
var $table = $('table').smartTable({
url: apiUrl,
method: "get",
sidePagination: "client",
showToggle: false,
showRefresh: false,
showColumns: false,
columns: [
{
title: "序号", formatter: function (value, row, index) {
var options = $table.bootstrapTable('getOptions');
return options.pageSize * (options.pageNumber - 1) + index + 1;
}
},
{ title: "登陆名称", field: "UserName" },
{ title: "登录时间", field: "LoginTime" },
{ title: "主机", field: "Ip" },
{ title: "登录地点", field: "City" },
{ title: "浏览器", field: "Browser" },
{ title: "操作系统", field: "OS" },
{ title: "登录结果", field: "Result" }
]
});
$('#refreshUsers').tooltip().on('click', function () {
$table.bootstrapTable('refresh');
});
});

View File

@ -1,4 +1,7 @@
namespace Bootstrap.DataAccess.MongoDB
using MongoDB.Driver;
using System.Collections.Generic;
namespace Bootstrap.DataAccess.MongoDB
{
/// <summary>
///
@ -15,5 +18,11 @@
DbManager.LoginUsers.InsertOne(user);
return true;
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public override IEnumerable<DataAccess.LoginUser> Retrieves() => DbManager.LoginUsers.Find(FilterDefinition<DataAccess.LoginUser>.Empty).SortByDescending(user => user.LoginTime).ToList();
}
}

View File

@ -1,4 +1,6 @@
using Longbow.Data;
using Longbow.Cache;
using Longbow.Data;
using System.Collections.Generic;
namespace Bootstrap.DataAccess
{
@ -7,11 +9,26 @@ namespace Bootstrap.DataAccess
/// </summary>
public static class LoginHelper
{
/// <summary>
///
/// </summary>
public const string RetrieveLoginLogsDataKey = "LoginHelper-Retrieves";
/// <summary>
///
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
public static bool Log(LoginUser user) => DbContextManager.Create<LoginUser>().Log(user);
public static bool Log(LoginUser user)
{
var ret = DbContextManager.Create<LoginUser>().Log(user);
if (ret) CacheManager.Clear(RetrieveLoginLogsDataKey);
return ret;
}
/// <summary>
/// 查询一个月内所有登录信息
/// </summary>
public static IEnumerable<LoginUser> Retrieves() => CacheManager.GetOrAdd(RetrieveLoginLogsDataKey, key => DbContextManager.Create<LoginUser>().Retrieves());
}
}

View File

@ -1,5 +1,8 @@
using PetaPoco;
using Longbow;
using Longbow.Configuration;
using PetaPoco;
using System;
using System.Collections.Generic;
namespace Bootstrap.DataAccess
{
@ -60,5 +63,16 @@ namespace Bootstrap.DataAccess
db.Save(user);
return true;
}
/// <summary>
///
/// </summary>
protected const string KeepLoginLogsPeriodKey = "KeepLoginLogsPeriod";
/// <summary>
///
/// </summary>
/// <returns></returns>
public virtual IEnumerable<LoginUser> Retrieves() => DbManager.Create().Fetch<LoginUser>("Where LoginTime > @0 Order by LoginTime desc", DateTime.Today.AddDays(0 - LgbConvert.ReadValue(ConfigurationManager.AppSettings[KeepLoginLogsPeriodKey], 7)));
}
}

View File

@ -45,7 +45,9 @@ INSERT [dbo].[Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [C
INSERT [dbo].[Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (10, 0, N'站内消息', 100, N'fa fa-envelope', N'~/Admin/Messages', N'0')
INSERT [dbo].[Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (11, 0, N'任务管理', 110, N'fa fa fa-tasks', N'~/Admin/Tasks', N'0')
INSERT [dbo].[Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (12, 0, N'通知管理', 120, N'fa fa-bell', N'~/Admin/Notifications', N'0')
INSERT [dbo].[Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (13, 0, N'系统日志', 130, N'fa fa-gears', N'~/Admin/Logs', N'0')
INSERT [dbo].[Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (13, 0, N'日志管理', 130, N'fa fa-gears', N'#', N'0')
INSERT [dbo].[Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (20, 13, N'操作日志', 10, N'fa fa-edit', N'~/Admin/Logs', N'0')
INSERT [dbo].[Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (21, 13, N'登录日志', 20, N'fa fa-user-circle-o', N'~/Admin/Logins', N'0')
INSERT [dbo].[Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (14, 0, N'在线用户', 140, N'fa fa-users', N'~/Admin/Online', N'0')
INSERT [dbo].[Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (15, 0, N'程序异常', 150, N'fa fa-cubes', N'~/Admin/Exceptions', N'0')
INSERT [dbo].[Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (16, 0, N'工具集合', 160, N'fa fa-gavel', N'#', N'0')

View File

@ -146,15 +146,39 @@
{
"_id": ObjectId("5bd7b8445fa31256f77e4b9c"),
"ParentId": "0",
"Name": "系统日志",
"Name": "日志管理",
"Order": NumberInt(130),
"Icon": "fa fa-gears",
"Url": "#",
"Category": "0",
"Target": "_self",
"IsResource": NumberInt(0),
"Application": "0"
},
{
"_id": ObjectId("5bd9b3d868aa001661776f57"),
"ParentId": "5bd7b8445fa31256f77e4b9c",
"Name": "操作日志",
"Order": NumberInt(10),
"Icon": "fa fa-edit",
"Url": "~/Admin/Logs",
"Category": "0",
"Target": "_self",
"IsResource": NumberInt(0),
"Application": "0"
},
{
"_id": ObjectId("5bd9b3d868aa001661776f58"),
"ParentId": "5bd7b8445fa31256f77e4b9c",
"Name": "登录日志",
"Order": NumberInt(20),
"Icon": "fa fa-user-circle-o",
"Url": "~/Admin/Logins",
"Category": "0",
"Target": "_self",
"IsResource": NumberInt(0),
"Application": "0"
},
{
"_id": ObjectId("5bd7b8445fa31256f77e4b89"),
"ParentId": "0",

View File

@ -42,7 +42,9 @@ INSERT INTO Navigations (ID, ParentId, Name, `Order`, Icon, Url, Category) VALUE
INSERT INTO Navigations (ID, ParentId, Name, `Order`, Icon, Url, Category) VALUES (10, 0, '站内消息', 100, 'fa fa-envelope', '~/Admin/Messages', '0');
INSERT INTO Navigations (ID, ParentId, Name, `Order`, Icon, Url, Category) VALUES (11, 0, '任务管理', 110, 'fa fa fa-tasks', '~/Admin/Tasks', '0');
INSERT INTO Navigations (ID, ParentId, Name, `Order`, Icon, Url, Category) VALUES (12, 0, '通知管理', 120, 'fa fa-bell', '~/Admin/Notifications', '0');
INSERT INTO Navigations (ID, ParentId, Name, `Order`, Icon, Url, Category) VALUES (13, 0, '系统日志', 130, 'fa fa-gears', '~/Admin/Logs', '0');
INSERT INTO Navigations (ID, ParentId, Name, `Order`, Icon, Url, Category) VALUES (13, 0, '系统日志', 130, 'fa fa-gears', '#', '0');
INSERT INTO Navigations (ID, ParentId, Name, `Order`, Icon, Url, Category) VALUES (20, 13, '操作日志', 10, 'fa fa-edit', '~/Admin/Logs', '0');
INSERT INTO Navigations (ID, ParentId, Name, `Order`, Icon, Url, Category) VALUES (21, 13, '登录日志', 20, 'fa fa-user-circle-o', '~/Admin/Logins', '0');
INSERT INTO Navigations (ID, ParentId, Name, `Order`, Icon, Url, Category) VALUES (14, 0, '在线用户', 140, 'fa fa-users', '~/Admin/Online', '0');
INSERT INTO Navigations (ID, ParentId, Name, `Order`, Icon, Url, Category) VALUES (15, 0, '程序异常', 150, 'fa fa-cubes', '~/Admin/Exceptions', '0');
INSERT INTO Navigations (ID, ParentId, Name, `Order`, Icon, Url, Category) VALUES (16, 0, '工具集合', 160, 'fa fa-gavel', '#', '0');

View File

@ -42,7 +42,9 @@ INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (0
INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (0, '站内消息', 100, 'fa fa-envelope', '~/Admin/Messages', '0');
INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (0, '任务管理', 110, 'fa fa fa-tasks', '~/Admin/Tasks', '0');
INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (0, '通知管理', 120, 'fa fa-bell', '~/Admin/Notifications', '0');
INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (0, '系统日志', 130, 'fa fa-gears', '~/Admin/Logs', '0');
INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (0, '系统日志', 130, 'fa fa-gears', '#', '0');
INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (currval('navigations_id_seq') - 1, 0, '操作日志', 10, 'fa fa-edit', '~/Admin/Logs', '0');
INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (currval('navigations_id_seq') - 2, 0, '登录日志', 20, 'fa fa-user-circle-o', '~/Admin/Logins', '0');
INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (0, '在线用户', 140, 'fa fa-users', '~/Admin/Online', '0');
INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (0, '程序异常', 150, 'fa fa-cubes', '~/Admin/Exceptions', '0');
INSERT INTO Navigations (ParentId, Name, "order", Icon, Url, Category) VALUES (0, '工具集合', 160, 'fa fa-gavel', '#', '0');

View File

@ -39,7 +39,9 @@ INSERT INTO [Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Ca
INSERT INTO [Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (10, 0, '站内消息', 100, 'fa fa-envelope', '~/Admin/Messages', '0');
INSERT INTO [Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (11, 0, '任务管理', 110, 'fa fa fa-tasks', '~/Admin/Tasks', '0');
INSERT INTO [Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (12, 0, '通知管理', 120, 'fa fa-bell', '~/Admin/Notifications', '0');
INSERT INTO [Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (13, 0, '系统日志', 130, 'fa fa-gears', '~/Admin/Logs', '0');
INSERT INTO [Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (13, 0, '系统日志', 130, 'fa fa-gears', '#', '0');
INSERT INTO [Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (20, 13, '操作日志', 10, 'fa fa-edit', '~/Admin/Logs', '0');
INSERT INTO [Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (21, 13, '登录日志', 20, 'fa fa-user-circle-o', '~/Admin/Logins', '0');
INSERT INTO [Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (14, 0, '在线用户', 140, 'fa fa-users', '~/Admin/Online', '0');
INSERT INTO [Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (15, 0, '程序异常', 150, 'fa fa-cubes', '~/Admin/Exceptions', '0');
INSERT INTO [Navigations] ([ID], [ParentId], [Name], [Order], [Icon], [Url], [Category]) VALUES (16, 0, '工具集合', 160, 'fa fa-gavel', '#', '0');

View File

@ -1,4 +1,6 @@
using System.Net.Http;
using Bootstrap.DataAccess;
using System.Collections.Generic;
using System.Net.Http;
using Xunit;
namespace Bootstrap.Admin.Api
@ -7,6 +9,13 @@ namespace Bootstrap.Admin.Api
{
public LoginTest(BAWebHost factory) : base(factory, "api/Login") { }
[Fact]
public async void Login_Get()
{
var users = await Client.GetAsJsonAsync<IEnumerable<LoginUser>>();
Assert.NotEmpty(users);
}
[Fact]
public async void Login_Ok()
{

View File

@ -14,7 +14,8 @@ namespace Bootstrap.Admin.Controllers
[InlineData("Dicts", "字典表维护")]
[InlineData("Roles", "角色管理")]
[InlineData("Menus", "菜单管理")]
[InlineData("Logs", "系统日志")]
[InlineData("Logs", "操作日志")]
[InlineData("Logins", "登录日志")]
[InlineData("FAIcon", "图标集")]
[InlineData("IconView", "图标分类")]
[InlineData("Settings", "网站设置")]