yuan xue 1 рік тому
батько
коміт
44903fc22b

+ 1 - 21
Admin.NET/Admin.NET.Core/Logging/DatabaseLoggingWriter.cs

@@ -79,7 +79,7 @@ public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
         if (string.IsNullOrEmpty(remoteIPv4))
             remoteIPv4 = loggingMonitor.remoteIPv4;
 
-        (string ipLocation, double? longitude, double? latitude) = GetIpAddress(remoteIPv4);
+        (string ipLocation, double? longitude, double? latitude) = CommonUtil.GetIpAddress(remoteIPv4);
 
         var browser = "";
         var os = "";
@@ -201,26 +201,6 @@ public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
         }
     }
 
-    /// <summary>
-    /// 解析IP地址
-    /// </summary>
-    /// <param name="ip"></param>
-    /// <returns></returns>
-    internal static (string ipLocation, double? longitude, double? latitude) GetIpAddress(string ip)
-    {
-        try
-        {
-            var ipInfo = IpTool.SearchWithI18N(ip); // 国际化查询,默认中文 中文zh-CN、英文en
-            var addressList = new List<string>() { ipInfo.Country, ipInfo.Province, ipInfo.City, ipInfo.NetworkOperator };
-            return (string.Join(" ", addressList.Where(u => u != "0" && !string.IsNullOrWhiteSpace(u)).ToList()), ipInfo.Longitude, ipInfo.Latitude); // 去掉0及空并用空格连接
-        }
-        catch
-        {
-            // 不做处理
-        }
-        return ("未知", 0, 0);
-    }
-
     /// <summary>
     /// 释放服务作用域
     /// </summary>

+ 5 - 5
Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs

@@ -208,7 +208,7 @@ public class SysAuthService : IDynamicApiController, ITransient
     /// <param name="user"></param>
     /// <returns></returns>
     [NonAction]
-    public virtual async Task<LoginOutput> CreateToken(SysUser user)
+    internal virtual async Task<LoginOutput> CreateToken(SysUser user)
     {
         // 单用户登录
         await _sysOnlineUserService.SingleLogin(user.Id);
@@ -238,16 +238,16 @@ public class SysAuthService : IDynamicApiController, ITransient
         // ke.global.setAllHeader('Authorization', 'Bearer ' + ke.response.headers['access-token']);
 
         // 更新用户登录信息
-        string remoteIPv4 = App.HttpContext.GetRemoteIpAddressToIPv4();
-        (string ipLocation, double? longitude, double? latitude) = DatabaseLoggingWriter.GetIpAddress(remoteIPv4);
-        user.LastLoginIp = remoteIPv4;
-        user.LastLoginAddress = ipLocation;
+        user.LastLoginIp = _httpContextAccessor.HttpContext.GetRemoteIp();
+        (user.LastLoginAddress, _, _) = CommonUtil.GetIpAddress(user.LastLoginIp);
         user.LastLoginTime = DateTime.Now;
+        user.LastLoginDevice = CommonUtil.GetClientDeviceInfo(_httpContextAccessor.HttpContext?.Request?.Headers?.UserAgent);
         await _sysUserRep.AsUpdateable(user).UpdateColumns(it => new
         {
             it.LastLoginIp,
             it.LastLoginAddress,
             it.LastLoginTime,
+            it.LastLoginDevice,
         }).ExecuteCommandAsync();
 
         return new LoginOutput

+ 1 - 7
Admin.NET/Admin.NET.Core/Service/Config/SysConfigService.cs

@@ -14,18 +14,12 @@ public class SysConfigService : IDynamicApiController, ITransient
 {
     private readonly SysCacheService _sysCacheService;
     private readonly SqlSugarRepository<SysConfig> _sysConfigRep;
-    private readonly IHttpContextAccessor _httpContextAccessor;
-    private readonly UserManager _userManager;
 
     public SysConfigService(SysCacheService sysCacheService,
-        SqlSugarRepository<SysConfig> sysConfigRep,
-        IHttpContextAccessor httpContextAccessor,
-        UserManager userManager)
+        SqlSugarRepository<SysConfig> sysConfigRep)
     {
         _sysCacheService = sysCacheService;
         _sysConfigRep = sysConfigRep;
-        _httpContextAccessor = httpContextAccessor;
-        _userManager = userManager;
     }
 
     /// <summary>

+ 45 - 0
Admin.NET/Admin.NET.Core/Util/CommonUtil.cs

@@ -4,10 +4,12 @@
 //
 // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
 
+using IPTools.Core;
 using Magicodes.ExporterAndImporter.Core.Models;
 using System.Xml;
 using System.Xml.Linq;
 using System.Xml.Serialization;
+using UAParser;
 
 namespace Admin.NET.Core;
 
@@ -369,4 +371,47 @@ public static class CommonUtil
 
         return propMappings;
     }
+
+    /// <summary>
+    /// 解析IP地址
+    /// </summary>
+    /// <param name="ip"></param>
+    /// <returns></returns>
+    public static (string ipLocation, double? longitude, double? latitude) GetIpAddress(string ip)
+    {
+        try
+        {
+            var ipInfo = IpTool.SearchWithI18N(ip); // 国际化查询,默认中文 中文zh-CN、英文en
+            var addressList = new List<string>() { ipInfo.Country, ipInfo.Province, ipInfo.City, ipInfo.NetworkOperator };
+            return (string.Join(" ", addressList.Where(u => u != "0" && !string.IsNullOrWhiteSpace(u)).ToList()), ipInfo.Longitude, ipInfo.Latitude); // 去掉0及空并用空格连接
+        }
+        catch
+        {
+            // 不做处理
+        }
+        return ("未知", 0, 0);
+    }
+
+    /// <summary>
+    /// 获取客户端设备信息(操作系统+浏览器)
+    /// </summary>
+    /// <param name="userAgent"></param>
+    /// <returns></returns>
+    public static string GetClientDeviceInfo(string userAgent)
+    {
+        try
+        {
+            if (userAgent != null)
+            {
+                var client = Parser.GetDefault().Parse(userAgent);
+                if (client.Device.IsSpider)
+                    return "爬虫";
+                return $"{client.OS.Family} {client.OS.Major} {client.OS.Minor}" +
+                    $"|{client.UA.Family} {client.UA.Major}.{client.UA.Minor} / {client.Device.Family}";
+            }
+        }
+        catch
+        { }
+        return "未知";
+    }
 }

+ 1 - 0
Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/Service.cs.vm

@@ -18,6 +18,7 @@ using Microsoft.AspNetCore.Http;
     }
 }
 namespace @Model.NameSpace;
+
 /// <summary>
 /// @(@Model.BusName)服务
 /// </summary>