From f8445ab2e4738d0c00ac1b6cfb9154c335405f42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Mon, 20 Feb 2023 21:10:06 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E8=AE=B0=E5=BD=95=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Extensions/HttpContextExtensions.cs | 48 ++++++++++++++++ .../ApplicationContractsSwaggerDoc.xml | 20 +++++++ .../Dtos/LoginLog/LoginLogGetListInputVo.cs | 17 ++++++ .../Dtos/LoginLog/LoginLogGetListOutputDto.cs | 38 +++++++++++++ .../Logs/LoginLogService.cs | 32 +++++++++++ .../Identity/Etos/LoginEventArgs.cs | 1 + .../rbac/Yi.RBAC.Domain/DomainSwaggerDoc.xml | 30 ++++++++++ .../Identity/Event/LoginEventHandler .cs | 19 ------- .../Logs/Entities/LoginLogEntity.cs | 52 ++++++++++++++++++ .../Logs/Event/LoginEventHandler .cs | 36 ++++++++++++ .../rbac/Yi.RBAC.Web/yi-sqlsugar-dev.db | Bin 118784 -> 126976 bytes Yi.RuoYi.Vue3/src/api/monitor/logininfor.js | 7 +-- .../src/views/monitor/logininfor/index.vue | 2 +- 13 files changed, 278 insertions(+), 24 deletions(-) create mode 100644 Yi.Framework.Net6/src/framework/Yi.Framework.AspNetCore/Extensions/HttpContextExtensions.cs create mode 100644 Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application.Contracts/Logs/Dtos/LoginLog/LoginLogGetListInputVo.cs create mode 100644 Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application.Contracts/Logs/Dtos/LoginLog/LoginLogGetListOutputDto.cs create mode 100644 Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application/Logs/LoginLogService.cs delete mode 100644 Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain/Identity/Event/LoginEventHandler .cs create mode 100644 Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain/Logs/Entities/LoginLogEntity.cs create mode 100644 Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain/Logs/Event/LoginEventHandler .cs diff --git a/Yi.Framework.Net6/src/framework/Yi.Framework.AspNetCore/Extensions/HttpContextExtensions.cs b/Yi.Framework.Net6/src/framework/Yi.Framework.AspNetCore/Extensions/HttpContextExtensions.cs new file mode 100644 index 00000000..759555ed --- /dev/null +++ b/Yi.Framework.Net6/src/framework/Yi.Framework.AspNetCore/Extensions/HttpContextExtensions.cs @@ -0,0 +1,48 @@ +using Microsoft.AspNetCore.Http; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace Yi.Framework.AspNetCore.Extensions +{ + public static class HttpContextExtensions + { + /// + /// 获取客户端IP + /// + /// + /// + public static string GetClientIp(this HttpContext context) + { + if (context == null) return ""; + var result = context.Request.Headers["X-Forwarded-For"].FirstOrDefault(); + if (string.IsNullOrEmpty(result)) + { + result = context.Connection.RemoteIpAddress?.ToString(); + } + if (string.IsNullOrEmpty(result) || result.Contains("::1")) + result = "127.0.0.1"; + + result = result.Replace("::ffff:", "127.0.0.1"); + + //Ip规则效验 + var regResult = Regex.IsMatch(result, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$"); + + result = regResult ? result : "127.0.0.1"; + return result; + } + + /// + /// 获取浏览器标识 + /// + /// + /// + public static string GetUserAgent(this HttpContext context) + { + return context.Request.Headers["User-Agent"]; + } + } +} diff --git a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application.Contracts/ApplicationContractsSwaggerDoc.xml b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application.Contracts/ApplicationContractsSwaggerDoc.xml index d5bee59e..a211a924 100644 --- a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application.Contracts/ApplicationContractsSwaggerDoc.xml +++ b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application.Contracts/ApplicationContractsSwaggerDoc.xml @@ -74,6 +74,26 @@ User服务抽象 + + + 登录Ip + + + + + 浏览器 + + + + + 操作系统 + + + + + 登录信息 + + Config输入创建对象 diff --git a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application.Contracts/Logs/Dtos/LoginLog/LoginLogGetListInputVo.cs b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application.Contracts/Logs/Dtos/LoginLog/LoginLogGetListInputVo.cs new file mode 100644 index 00000000..c35b995a --- /dev/null +++ b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application.Contracts/Logs/Dtos/LoginLog/LoginLogGetListInputVo.cs @@ -0,0 +1,17 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Ddd.Dtos; + +namespace Yi.RBAC.Application.Contracts.Logs.Dtos.LoginLog +{ + public class LoginLogGetListInputVo: PagedAllResultRequestDto + { + public string? LoginUser { get; set; } + + public string? LoginIp { get; set; } + } +} diff --git a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application.Contracts/Logs/Dtos/LoginLog/LoginLogGetListOutputDto.cs b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application.Contracts/Logs/Dtos/LoginLog/LoginLogGetListOutputDto.cs new file mode 100644 index 00000000..3ca4a77d --- /dev/null +++ b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application.Contracts/Logs/Dtos/LoginLog/LoginLogGetListOutputDto.cs @@ -0,0 +1,38 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Ddd.Dtos; + +namespace Yi.RBAC.Application.Contracts.Logs.Dtos.LoginLog +{ + public class LoginLogGetListOutputDto:EntityDto + { + public DateTime CreationTime { get; } + + + public string? LoginUser { get; set; } + + public string? LoginLocation { get; set; } + /// + /// 登录Ip + /// + public string? LoginIp { get; set; } + /// + /// 浏览器 + /// + public string? Browser { get; set; } + /// + /// 操作系统 + /// + public string? Os { get; set; } + /// + /// 登录信息 + /// + public string? LogMsg { get; set; } + + public long? CreatorId { get; set; } + } +} diff --git a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application/Logs/LoginLogService.cs b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application/Logs/LoginLogService.cs new file mode 100644 index 00000000..183c206e --- /dev/null +++ b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Application/Logs/LoginLogService.cs @@ -0,0 +1,32 @@ +using NET.AutoWebApi.Setting; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Ddd.Dtos; +using Yi.Framework.Ddd.Services; +using Yi.RBAC.Application.Contracts.Logs.Dtos.LoginLog; +using Yi.RBAC.Application.Contracts.Setting.Dtos; +using Yi.RBAC.Domain.Logs.Entities; + +namespace Yi.RBAC.Application.Logs +{ + [AppService] + public class LoginLogService : CrudAppService, IAutoApiService + { + public override async Task> GetListAsync(LoginLogGetListInputVo input) + { + var entity = await MapToEntityAsync(input); + + RefAsync total = 0; + + var entities = await _DbQueryable.WhereIF(!string.IsNullOrEmpty(input.LoginIp), x => x.LoginIp.Contains(input.LoginIp!)) + .WhereIF(!string.IsNullOrEmpty(input.LoginUser), x => x.LoginUser!.Contains(input.LoginUser!)) + .WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime) + .ToPageListAsync(input.PageNum, input.PageSize, total); + return new PagedResultDto(total, await MapToGetListOutputDtosAsync(entities)); + } + } +} diff --git a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain.Shared/Identity/Etos/LoginEventArgs.cs b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain.Shared/Identity/Etos/LoginEventArgs.cs index 925b5eea..102d43d6 100644 --- a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain.Shared/Identity/Etos/LoginEventArgs.cs +++ b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain.Shared/Identity/Etos/LoginEventArgs.cs @@ -11,5 +11,6 @@ namespace Yi.RBAC.Domain.Shared.Identity.Etos public long UserId { get; set; } public string UserName { get; set; } + public string LogMsg { get; set; } } } diff --git a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain/DomainSwaggerDoc.xml b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain/DomainSwaggerDoc.xml index eba4aa75..92e534db 100644 --- a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain/DomainSwaggerDoc.xml +++ b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain/DomainSwaggerDoc.xml @@ -711,6 +711,36 @@ + + + 登录用户 + + + + + 登录地点 + + + + + 登录Ip + + + + + 浏览器 + + + + + 操作系统 + + + + + 登录信息 + + 配置表 diff --git a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain/Identity/Event/LoginEventHandler .cs b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain/Identity/Event/LoginEventHandler .cs deleted file mode 100644 index 2cd87ee3..00000000 --- a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain/Identity/Event/LoginEventHandler .cs +++ /dev/null @@ -1,19 +0,0 @@ -using Cike.EventBus.EventHandlerAbstracts; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Yi.RBAC.Domain.Shared.Identity.Etos; - -namespace Yi.RBAC.Domain.Identity.Event -{ - public class LoginEventHandler : IDistributedEventHandler - { - public Task HandlerAsync(LoginEventArgs eventData) - { - Console.WriteLine(eventData.UserName+"登录系统"); - return Task.CompletedTask; - } - } -} diff --git a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain/Logs/Entities/LoginLogEntity.cs b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain/Logs/Entities/LoginLogEntity.cs new file mode 100644 index 00000000..4aa2fea1 --- /dev/null +++ b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain/Logs/Entities/LoginLogEntity.cs @@ -0,0 +1,52 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Data.Auditing; +using Yi.Framework.Ddd.Entities; + +namespace Yi.RBAC.Domain.Logs.Entities +{ + [SugarTable("LoginLog")] + public class LoginLogEntity : IEntity, ICreationAuditedObject + { + [SugarColumn(ColumnName = "Id", IsPrimaryKey = true)] + public long Id { get; set; } + public DateTime CreationTime { get; } + + /// + /// 登录用户 + /// + [SugarColumn(ColumnName = "LoginUser")] + public string? LoginUser { get; set; } + /// + /// 登录地点 + /// + [SugarColumn(ColumnName = "LoginLocation")] + public string? LoginLocation { get; set; } + /// + /// 登录Ip + /// + [SugarColumn(ColumnName = "LoginIp")] + public string? LoginIp { get; set; } + /// + /// 浏览器 + /// + [SugarColumn(ColumnName = "Browser")] + public string? Browser { get; set; } + /// + /// 操作系统 + /// + [SugarColumn(ColumnName = "Os")] + public string? Os { get; set; } + /// + /// 登录信息 + /// + [SugarColumn(ColumnName = "LogMsg")] + public string? LogMsg { get; set; } + + public long? CreatorId { get; set; } + } +} diff --git a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain/Logs/Event/LoginEventHandler .cs b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain/Logs/Event/LoginEventHandler .cs new file mode 100644 index 00000000..7ff2d211 --- /dev/null +++ b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Domain/Logs/Event/LoginEventHandler .cs @@ -0,0 +1,36 @@ +using Cike.EventBus.EventHandlerAbstracts; +using Microsoft.AspNetCore.Http; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Ddd.Repositories; +using Yi.RBAC.Domain.Logs.Entities; +using Yi.RBAC.Domain.Shared.Identity.Etos; + +namespace Yi.RBAC.Domain.Logs.Event +{ + public class LoginEventHandler : IDistributedEventHandler + { + private readonly IRepository _loginLogRepository; + private readonly HttpContext _httpContext; + public LoginEventHandler(IRepository loginLogRepository, IHttpContextAccessor httpContextAccessor) + { + _loginLogRepository = loginLogRepository; + _httpContext = httpContextAccessor.HttpContext; + } + public Task HandlerAsync(LoginEventArgs eventData) + { + var loginLogEntity = new LoginLogEntity(); + loginLogEntity.Id = SnowflakeHelper.NextId; + loginLogEntity.LogMsg = eventData.LogMsg; + loginLogEntity.LoginUser = eventData.UserName; + + _loginLogRepository.InsertAsync(loginLogEntity); + Console.WriteLine(eventData.UserName + "登录系统"); + return Task.CompletedTask; + } + } +} diff --git a/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Web/yi-sqlsugar-dev.db b/Yi.Framework.Net6/src/project/rbac/Yi.RBAC.Web/yi-sqlsugar-dev.db index 78a5f2e4c5d09d67f2b53f32054b2a01eba80afe..54b2b1599c7a9b68b4f927acc2457a8a7028033e 100644 GIT binary patch delta 462 zcmZozz~1nHeS)-L8Uq7^JP^Zx&_o?$#Y0TZeW$ZGFeXVs|Li_<}xrt7pa zN-!%ZXl`HE#Q2w)nUB$U`?@wpeMTmIndyZ+j53NaTjLF3EO`!R1`d!PwWZj^?IkB~ zB>itqF`v>X`+Z)=g(`U{u~5sL;Z+eO(jd rUuI@!#+>cz+8Fg2CvRY5o1W3dXw0T9#U^eqIe8 { - logininforList.value = response.data.data; + logininforList.value = response.data.items; total.value = response.data.total; loading.value = false; });