Переглянути джерело

水印字段添加客户端IP地址、用户名、时间字段,便于拍照或截屏追溯

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

+ 42 - 0
Admin.NET/Admin.NET.Core/Extension/HttpContextExtension.cs

@@ -0,0 +1,42 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Net;
+
+namespace Admin.NET.Core;
+
+/// <summary>
+/// HttpContext拓展
+/// </summary>
+[SuppressSniffer]
+public static partial class HttpContextExtension
+{
+    /// <summary>
+    /// 获取客户端真实IP地址
+    /// </summary>
+    /// <returns>bool</returns>
+    public static string GetRemoteIp(this HttpContext httpContext)
+    {
+        var ip = string.Empty;
+        try
+        {
+            // 尝试从X-Forwarded-For头获取
+            ip = httpContext.Request.Headers["X-Forwarded-For"];
+            if (string.IsNullOrEmpty(ip))
+            {
+                // 直接从连接获取
+                ip = httpContext.GetRemoteIpAddressToIPv4();
+            }
+            // 验证IP地址的有效性
+            if (!IPAddress.TryParse(ip, out _))
+            {
+                ip = null;
+            }
+        }
+        catch { }
+        return ip;
+    }
+}

+ 12 - 2
Admin.NET/Admin.NET.Core/Service/Config/SysConfigService.cs

@@ -14,12 +14,18 @@ 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)
+        SqlSugarRepository<SysConfig> sysConfigRep,
+        IHttpContextAccessor httpContextAccessor,
+        UserManager userManager)
     {
         _sysCacheService = sysCacheService;
         _sysConfigRep = sysConfigRep;
+        _httpContextAccessor = httpContextAccessor;
+        _userManager = userManager;
     }
 
     /// <summary>
@@ -245,13 +251,17 @@ public class SysConfigService : IDynamicApiController, ITransient
         var sysCopyright = await GetConfigValue<string>("sys_web_copyright");
         var sysIcp = await GetConfigValue<string>("sys_web_icp");
         var sysIcpUrl = await GetConfigValue<string>("sys_web_icpUrl");
+
+        string ip = _httpContextAccessor.HttpContext.GetRemoteIp();
+        string watermark = $"{sysWatermark}-{DateTime.Now}-{ip}-{_userManager.RealName}";
+
         return new
         {
             SysLogo = sysLogo,
             SysTitle = sysTitle,
             SysViceTitle = sysViceTitle,
             SysViceDesc = sysViceDesc,
-            SysWatermark = sysWatermark,
+            SysWatermark = watermark,
             SysCopyright = sysCopyright,
             SysIcp = sysIcp,
             SysIcpUrl = sysIcpUrl

+ 3 - 3
Web/src/utils/watermark.ts

@@ -3,14 +3,14 @@ const setWatermark = (str: string) => {
 	const id = '1.23452384164.123412416';
 	if (document.getElementById(id) !== null) document.body.removeChild(<HTMLElement>document.getElementById(id));
 	const can = document.createElement('canvas');
-	can.width = 200;
-	can.height = 130;
+	can.width = 400;
+	can.height = 200;
 	const cans = <CanvasRenderingContext2D>can.getContext('2d');
 	cans.rotate((-20 * Math.PI) / 180);
 	cans.font = '12px Vedana';
 	cans.fillStyle = 'rgba(200, 200, 200, 0.30)';
 	cans.textBaseline = 'middle';
-	cans.fillText(str, can.width / 10, can.height / 2);
+	cans.fillText(str, can.width / 10, can.height, can.width);
 	const div = document.createElement('div');
 	div.id = id;
 	div.style.pointerEvents = 'none';