mirror of
				https://gitee.com/ThingsGateway/ThingsGateway.git
				synced 2025-10-31 15:43:59 +08:00 
			
		
		
		
	Compare commits
	
		
			23 Commits
		
	
	
		
			10.11.72.0
			...
			10.11.98.0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 301beda2a2 | ||
|   | 628b51a353 | ||
|   | f03445bc83 | ||
|   | 55a2ff5487 | ||
|   | 0fef7dcf3b | ||
|   | 19d9702606 | ||
|   | a8a9774932 | ||
|   | aad0f0e8c3 | ||
|   | e74eae50a7 | ||
|   | 3b16d7019f | ||
|   | 3e038028c2 | ||
|   | b1d8041f7e | ||
|   | 53a98b26cd | ||
|   | 42c740fa1b | ||
|   | 556819c90c | ||
|   | 2522333a9c | ||
|   | bd4ce7c09b | ||
|   | 156ed88bd6 | ||
|   | 2416226eb0 | ||
|   | 976323a716 | ||
|   | 3c9e397403 | ||
|   | 79406ad4a0 | ||
|   | 20c44f10ca | 
| @@ -45,6 +45,7 @@ public class VerificatInfo : PrimaryIdEntity | |||||||
|     /// 登录IP |     /// 登录IP | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     [AutoGenerateColumn(Filterable = true, Sortable = true, Width = 200)] |     [AutoGenerateColumn(Filterable = true, Sortable = true, Width = 200)] | ||||||
|  |     [SugarColumn(IsNullable = true)] | ||||||
|     public string LoginIp { get; set; } |     public string LoginIp { get; set; } | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
| @@ -78,5 +79,6 @@ public class VerificatInfo : PrimaryIdEntity | |||||||
|     /// 登录设备 |     /// 登录设备 | ||||||
|     /// </summary> |     /// </summary> | ||||||
|     [AutoGenerateColumn(Filterable = true, Sortable = true, Width = 100)] |     [AutoGenerateColumn(Filterable = true, Sortable = true, Width = 100)] | ||||||
|  |     [SugarColumn(IsNullable = true)] | ||||||
|     public string Device { get; set; } |     public string Device { get; set; } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -145,7 +145,7 @@ public class AdminOAuthHandler<TOptions>( | |||||||
|         var loginEvent = new LoginEvent |         var loginEvent = new LoginEvent | ||||||
|         { |         { | ||||||
|             Ip = appService.RemoteIpAddress, |             Ip = appService.RemoteIpAddress, | ||||||
|             Device = appService.UserAgent?.Platform, |             Device = appService.UserAgent?.Platform ?? "Unknown", | ||||||
|             Expire = expire, |             Expire = expire, | ||||||
|             SysUser = sysUser, |             SysUser = sysUser, | ||||||
|             VerificatId = CommonUtils.GetSingleId() |             VerificatId = CommonUtils.GetSingleId() | ||||||
| @@ -156,7 +156,7 @@ public class AdminOAuthHandler<TOptions>( | |||||||
|         //生成verificat信息 |         //生成verificat信息 | ||||||
|         var verificatInfo = new VerificatInfo |         var verificatInfo = new VerificatInfo | ||||||
|         { |         { | ||||||
|             Device = loginEvent.Device, |             Device = loginEvent.Device ?? "Unknown", | ||||||
|             Expire = loginEvent.Expire, |             Expire = loginEvent.Expire, | ||||||
|             VerificatTimeout = tokenTimeout, |             VerificatTimeout = tokenTimeout, | ||||||
|             Id = loginEvent.VerificatId, |             Id = loginEvent.VerificatId, | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ | |||||||
|       "Module": 2, |       "Module": 2, | ||||||
|       "Title": "权限管理", |       "Title": "权限管理", | ||||||
|       "Code": "System", |       "Code": "System", | ||||||
|       "NavLinkMatch": "All", |       "NavLinkMatch": "Prefix", | ||||||
|       "Category": "MENU", |       "Category": "MENU", | ||||||
|       "Target": "_self", |       "Target": "_self", | ||||||
|       "Href": null, |       "Href": null, | ||||||
| @@ -47,7 +47,7 @@ | |||||||
|       "ParentId": 0, |       "ParentId": 0, | ||||||
|       "Module": 2, |       "Module": 2, | ||||||
|       "Title": "系统运维", |       "Title": "系统运维", | ||||||
|       "NavLinkMatch": "All", |       "NavLinkMatch": "Prefix", | ||||||
|       "Code": "System", |       "Code": "System", | ||||||
|       "Category": "MENU", |       "Category": "MENU", | ||||||
|       "Target": "_self", |       "Target": "_self", | ||||||
|   | |||||||
| @@ -235,7 +235,7 @@ public class AuthService : IAuthService | |||||||
|         var logingEvent = new LoginEvent |         var logingEvent = new LoginEvent | ||||||
|         { |         { | ||||||
|             Ip = _appService.RemoteIpAddress, |             Ip = _appService.RemoteIpAddress, | ||||||
|             Device = _appService.UserAgent?.Platform, |             Device = _appService.UserAgent?.Platform ?? "Unknown", | ||||||
|             Expire = expire, |             Expire = expire, | ||||||
|             SysUser = sysUser, |             SysUser = sysUser, | ||||||
|             VerificatId = verificatId |             VerificatId = verificatId | ||||||
| @@ -344,7 +344,7 @@ public class AuthService : IAuthService | |||||||
|         //生成verificat信息 |         //生成verificat信息 | ||||||
|         var verificatInfo = new VerificatInfo |         var verificatInfo = new VerificatInfo | ||||||
|         { |         { | ||||||
|             Device = loginEvent.Device, |             Device = loginEvent.Device ?? "Unknown", | ||||||
|             Expire = loginEvent.Expire, |             Expire = loginEvent.Expire, | ||||||
|             VerificatTimeout = tokenTimeout, |             VerificatTimeout = tokenTimeout, | ||||||
|             Id = loginEvent.VerificatId, |             Id = loginEvent.VerificatId, | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ | |||||||
| 	 | 	 | ||||||
| 	<ItemGroup> | 	<ItemGroup> | ||||||
| 		<PackageReference Include="Riok.Mapperly" Version="4.2.1" ExcludeAssets="runtime" PrivateAssets="all" /> | 		<PackageReference Include="Riok.Mapperly" Version="4.2.1" ExcludeAssets="runtime" PrivateAssets="all" /> | ||||||
| 		<PackageReference Include="Rougamo.Fody" Version="5.0.1" /> | 		<PackageReference Include="Rougamo.Fody" Version="5.0.2" /> | ||||||
| 	</ItemGroup> | 	</ItemGroup> | ||||||
| 	<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' "> | 	<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' "> | ||||||
| 		<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.1" /> | 		<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.1" /> | ||||||
|   | |||||||
| @@ -125,13 +125,22 @@ public class BlazorAppContext | |||||||
|             var ownMenus = OwnMenus.Where(a => a.Module == CurrentModuleId); |             var ownMenus = OwnMenus.Where(a => a.Module == CurrentModuleId); | ||||||
|             OwnMenuItems = AdminResourceUtil.BuildMenuTrees(ownMenus).ToList(); |             OwnMenuItems = AdminResourceUtil.BuildMenuTrees(ownMenus).ToList(); | ||||||
|             AllOwnMenuItems = AdminResourceUtil.BuildMenuTrees(OwnMenus).ToList(); |             AllOwnMenuItems = AdminResourceUtil.BuildMenuTrees(OwnMenus).ToList(); | ||||||
|             OwnSameLevelMenuItems = ownMenus.Where(a => !a.Href.IsNullOrWhiteSpace()).Select(item => new MenuItem() |             OwnSameLevelMenuItems = ownMenus.Where(a => !a.Href.IsNullOrWhiteSpace()).Select(item => | ||||||
|             { |             { | ||||||
|                 Match = item.NavLinkMatch ?? Microsoft.AspNetCore.Components.Routing.NavLinkMatch.All, |                 var menu = new MenuItem() | ||||||
|  |                 { | ||||||
|  |                     Match = item.NavLinkMatch ?? Microsoft.AspNetCore.Components.Routing.NavLinkMatch.Prefix, | ||||||
|                     Text = item.Title, |                     Text = item.Title, | ||||||
|                     Icon = item.Icon, |                     Icon = item.Icon, | ||||||
|                     Url = item.Href, |                     Url = item.Href, | ||||||
|                     Target = item.Target.ToString(), |                     Target = item.Target.ToString(), | ||||||
|  |                 }; | ||||||
|  |                 if (menu.Url.IsNullOrEmpty()) | ||||||
|  |                 { | ||||||
|  |                     menu.Match = Microsoft.AspNetCore.Components.Routing.NavLinkMatch.Prefix; | ||||||
|  |                 } | ||||||
|  |                 return menu; | ||||||
|  |  | ||||||
|             }).ToList(); |             }).ToList(); | ||||||
|             UserWorkbenchOutputs = AllMenus.Where(it => UserWorkBench.Shortcuts.Contains(it.Id)).ToList(); |             UserWorkbenchOutputs = AllMenus.Where(it => UserWorkBench.Shortcuts.Contains(it.Id)).ToList(); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
|  |  | ||||||
| 	<ItemGroup> | 	<ItemGroup> | ||||||
| 		<ProjectReference Include="..\ThingsGateway.Admin.Application\ThingsGateway.Admin.Application.csproj" /> | 		<ProjectReference Include="..\ThingsGateway.Admin.Application\ThingsGateway.Admin.Application.csproj" /> | ||||||
| 		<PackageReference Include="BootstrapBlazor.Chart" Version="9.0.1" /> | 		<PackageReference Include="BootstrapBlazor.Chart" Version="9.0.3" /> | ||||||
| 		<PackageReference Include="BootstrapBlazor.UniverSheet" Version="9.0.5" /> | 		<PackageReference Include="BootstrapBlazor.UniverSheet" Version="9.0.5" /> | ||||||
| 		<PackageReference Include="BootstrapBlazor.WinBox" Version="9.0.7" /> | 		<PackageReference Include="BootstrapBlazor.WinBox" Version="9.0.7" /> | ||||||
| 		<PackageReference Include="BootstrapBlazor.CodeEditor" Version="9.0.3" /> | 		<PackageReference Include="BootstrapBlazor.CodeEditor" Version="9.0.3" /> | ||||||
|   | |||||||
| @@ -41,14 +41,21 @@ public static class AdminResourceUtil | |||||||
|         return items |         return items | ||||||
|         .Where(it => it.ParentId == parentId) |         .Where(it => it.ParentId == parentId) | ||||||
|         .Select((item, index) => |         .Select((item, index) => | ||||||
|             new MenuItem() |  | ||||||
|         { |         { | ||||||
|                 Match = item.NavLinkMatch ?? Microsoft.AspNetCore.Components.Routing.NavLinkMatch.All, |             var menu = new MenuItem() | ||||||
|  |             { | ||||||
|  |                 Match = item.NavLinkMatch ?? Microsoft.AspNetCore.Components.Routing.NavLinkMatch.Prefix, | ||||||
|                 Text = item.Title, |                 Text = item.Title, | ||||||
|                 Icon = item.Icon, |                 Icon = item.Icon, | ||||||
|                 Url = item.Href, |                 Url = item.Href, | ||||||
|                 Target = item.Target.ToString(), |                 Target = item.Target.ToString(), | ||||||
|                 Items = BuildMenuTrees(items, item.Id).ToList() |                 Items = BuildMenuTrees(items, item.Id).ToList() | ||||||
|  |             }; | ||||||
|  |             if (menu.Url.IsNullOrEmpty()) | ||||||
|  |             { | ||||||
|  |                 menu.Match = Microsoft.AspNetCore.Components.Routing.NavLinkMatch.Prefix; | ||||||
|  |             } | ||||||
|  |             return menu; | ||||||
|         } |         } | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -21,12 +21,12 @@ | |||||||
|     <link rel="apple-touch-icon" href="favicon.png"> |     <link rel="apple-touch-icon" href="favicon.png"> | ||||||
|     <base href="/" /> |     <base href="/" /> | ||||||
|     <title>ThingsGateway</title> |     <title>ThingsGateway</title> | ||||||
|     <link rel="stylesheet" href=@($"_content/BootstrapBlazor.FontAwesome/css/font-awesome.min.css?v={this.GetType().Assembly.GetName().Version}") /> |     <link rel="stylesheet" href=@($"_content/BootstrapBlazor.FontAwesome/css/font-awesome.min.css") /> | ||||||
|     <link rel="stylesheet" href=@($"_content/BootstrapBlazor/css/bootstrap.blazor.bundle.min.css?v={this.GetType().Assembly.GetName().Version}") /> |     <link rel="stylesheet" href=@($"_content/BootstrapBlazor/css/bootstrap.blazor.bundle.min.css") /> | ||||||
|     <link rel="stylesheet" href=@($"_content/BootstrapBlazor/css/motronic.min.css?v={this.GetType().Assembly.GetName().Version}") /> |     <link rel="stylesheet" href=@($"_content/BootstrapBlazor/css/motronic.min.css") /> | ||||||
|     <link rel="stylesheet" href=@($"ThingsGateway.AdminServer.styles.css?v={this.GetType().Assembly.GetName().Version}") /> |     <link rel="stylesheet" href=@($"ThingsGateway.AdminServer.styles.css") /> | ||||||
|     <link rel="stylesheet" href=@($"{WebsiteConst.DefaultResourceUrl}css/site.css?v={this.GetType().Assembly.GetName().Version}") /> |     <link rel="stylesheet" href=@($"{WebsiteConst.DefaultResourceUrl}css/site.css") /> | ||||||
|     <link rel="stylesheet" href=@($"{WebsiteConst.DefaultResourceUrl}css/devui.css?v={this.GetType().Assembly.GetName().Version}") /> |     <link rel="stylesheet" href=@($"{WebsiteConst.DefaultResourceUrl}css/devui.css") /> | ||||||
|  |  | ||||||
|     @* <script src=@($"{WebsiteConst.DefaultResourceUrl}js/theme.js") type="module"></script><!-- 初始主题 --> *@ |     @* <script src=@($"{WebsiteConst.DefaultResourceUrl}js/theme.js") type="module"></script><!-- 初始主题 --> *@ | ||||||
|     <!-- PWA Manifest --> |     <!-- PWA Manifest --> | ||||||
| @@ -40,8 +40,8 @@ | |||||||
|  |  | ||||||
|     <BlazorReconnector @rendermode="new InteractiveServerRenderMode(false)" /> |     <BlazorReconnector @rendermode="new InteractiveServerRenderMode(false)" /> | ||||||
|  |  | ||||||
|     <script src=@($"_content/BootstrapBlazor/js/bootstrap.blazor.bundle.min.js?v={this.GetType().Assembly.GetName().Version}")></script> |     <script src=@($"_content/BootstrapBlazor/js/bootstrap.blazor.bundle.min.js")></script> | ||||||
|     <script src=@($"{WebsiteConst.DefaultResourceUrl}js/localStorageUtil.js?v={this.GetType().Assembly.GetName().Version}")></script> |     <script src=@($"{WebsiteConst.DefaultResourceUrl}js/localStorageUtil.js")></script> | ||||||
|     <script src="_framework/blazor.web.js"></script> |     <script src="_framework/blazor.web.js"></script> | ||||||
|     <!-- PWA Service Worker --> |     <!-- PWA Service Worker --> | ||||||
|     <script type="text/javascript">'serviceWorker' in navigator && navigator.serviceWorker.register('./service-worker.js')</script> |     <script type="text/javascript">'serviceWorker' in navigator && navigator.serviceWorker.register('./service-worker.js')</script> | ||||||
|   | |||||||
| @@ -70,7 +70,7 @@ | |||||||
|                         <Button @onclick="ShowAbout" class="layout-header-bar d-none d-lg-flex px-2" Icon="fa fa-info" Color="Color.None" TooltipText="@Localizer[nameof(About)]" /> |                         <Button @onclick="ShowAbout" class="layout-header-bar d-none d-lg-flex px-2" Icon="fa fa-info" Color="Color.None" TooltipText="@Localizer[nameof(About)]" /> | ||||||
|                     } |                     } | ||||||
|                     @* 版本号 *@ |                     @* 版本号 *@ | ||||||
|                     <div class="px-1 navbar-header-text d-none d-lg-block">@_versionString</div> |                     <div class="px-1 navbar-header-text text-nowrap d-none d-lg-block">@_versionString</div> | ||||||
|  |  | ||||||
|                     @* 主题切换 *@ |                     @* 主题切换 *@ | ||||||
|                     @* <ThemeToggle /> *@ |                     @* <ThemeToggle /> *@ | ||||||
|   | |||||||
| @@ -16,6 +16,8 @@ using System.Runtime.CompilerServices; | |||||||
| using System.Text.Json; | using System.Text.Json; | ||||||
| using System.Text.RegularExpressions; | using System.Text.RegularExpressions; | ||||||
|  |  | ||||||
|  | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Common.Extension; | namespace ThingsGateway.Common.Extension; | ||||||
| /// <summary> | /// <summary> | ||||||
| /// 对象拓展类 | /// 对象拓展类 | ||||||
| @@ -48,113 +50,7 @@ public static class ObjectExtensions | |||||||
|         bool IsTheRawGenericType(Type type) => generic == (type.IsGenericType ? type.GetGenericTypeDefinition() : type); |         bool IsTheRawGenericType(Type type) => generic == (type.IsGenericType ? type.GetGenericTypeDefinition() : type); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     /// 将 DateTimeOffset 转换成本地 DateTime |  | ||||||
|     /// </summary> |  | ||||||
|     /// <param name="dateTime"></param> |  | ||||||
|     /// <returns></returns> |  | ||||||
|     public static DateTime ConvertToDateTime(this DateTimeOffset dateTime) |  | ||||||
|     { |  | ||||||
|         if (dateTime.Offset.Equals(TimeSpan.Zero)) |  | ||||||
|             return dateTime.UtcDateTime; |  | ||||||
|         if (dateTime.Offset.Equals(TimeZoneInfo.Local.GetUtcOffset(dateTime.DateTime))) |  | ||||||
|             return dateTime.ToLocalTime().DateTime; |  | ||||||
|         else |  | ||||||
|             return dateTime.DateTime; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     /// 将 DateTimeOffset? 转换成本地 DateTime? |  | ||||||
|     /// </summary> |  | ||||||
|     /// <param name="dateTime"></param> |  | ||||||
|     /// <returns></returns> |  | ||||||
|     public static DateTime? ConvertToDateTime(this DateTimeOffset? dateTime) |  | ||||||
|     { |  | ||||||
|         return dateTime.HasValue ? dateTime.Value.ConvertToDateTime() : null; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     /// 将 DateTime 转换成 DateTimeOffset |  | ||||||
|     /// </summary> |  | ||||||
|     /// <param name="dateTime"></param> |  | ||||||
|     /// <returns></returns> |  | ||||||
|     public static DateTimeOffset ConvertToDateTimeOffset(this DateTime dateTime) |  | ||||||
|     { |  | ||||||
|         return DateTime.SpecifyKind(dateTime, DateTimeKind.Local); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     /// 将 DateTime? 转换成 DateTimeOffset? |  | ||||||
|     /// </summary> |  | ||||||
|     /// <param name="dateTime"></param> |  | ||||||
|     /// <returns></returns> |  | ||||||
|     public static DateTimeOffset? ConvertToDateTimeOffset(this DateTime? dateTime) |  | ||||||
|     { |  | ||||||
|         return dateTime.HasValue ? dateTime.Value.ConvertToDateTimeOffset() : null; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     /// 将流保存到本地磁盘 |  | ||||||
|     /// </summary> |  | ||||||
|     /// <param name="stream"></param> |  | ||||||
|     /// <param name="path"></param> |  | ||||||
|     /// <returns></returns> |  | ||||||
|     public static void CopyToSave(this Stream stream, string path) |  | ||||||
|     { |  | ||||||
|         // 空检查 |  | ||||||
|         if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullException(nameof(path)); |  | ||||||
|  |  | ||||||
|         using var fileStream = File.Create(path); |  | ||||||
|         stream.CopyTo(fileStream); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     /// 将字节数组保存到本地磁盘 |  | ||||||
|     /// </summary> |  | ||||||
|     /// <param name="bytes"></param> |  | ||||||
|     /// <param name="path"></param> |  | ||||||
|     /// <returns></returns> |  | ||||||
|     public static void CopyToSave(this byte[] bytes, string path) |  | ||||||
|     { |  | ||||||
|         using var stream = new MemoryStream(bytes); |  | ||||||
|         stream.CopyToSave(path); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     /// 将流保存到本地磁盘 |  | ||||||
|     /// </summary> |  | ||||||
|     /// <param name="stream"></param> |  | ||||||
|     /// <param name="path">需包含文件名完整路径</param> |  | ||||||
|     /// <returns></returns> |  | ||||||
|     public static async Task CopyToSaveAsync(this Stream stream, string path) |  | ||||||
|     { |  | ||||||
|         // 空检查 |  | ||||||
|         if (string.IsNullOrWhiteSpace(path)) |  | ||||||
|         { |  | ||||||
|             throw new ArgumentNullException(nameof(path)); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // 文件名判断 |  | ||||||
|         if (string.IsNullOrWhiteSpace(Path.GetFileName(path))) |  | ||||||
|         { |  | ||||||
|             throw new ArgumentException("The parameter of <path> parameter must include the complete file name."); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         using var fileStream = File.Create(path); |  | ||||||
|         await stream.CopyToAsync(fileStream).ConfigureAwait(false); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     /// 将字节数组保存到本地磁盘 |  | ||||||
|     /// </summary> |  | ||||||
|     /// <param name="bytes"></param> |  | ||||||
|     /// <param name="path"></param> |  | ||||||
|     /// <returns></returns> |  | ||||||
|     public static async Task CopyToSaveAsync(this byte[] bytes, string path) |  | ||||||
|     { |  | ||||||
|         using var stream = new MemoryStream(bytes); |  | ||||||
|         await stream.CopyToSaveAsync(path).ConfigureAwait(false); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     /// 合并两个字典 |     /// 合并两个字典 | ||||||
|   | |||||||
| @@ -12,9 +12,9 @@ | |||||||
| 	</PropertyGroup> | 	</PropertyGroup> | ||||||
| 	 | 	 | ||||||
| 	<ItemGroup> | 	<ItemGroup> | ||||||
| 		<PackageReference Include="BootstrapBlazor.TableExport" Version="9.2.6" /> | 		<PackageReference Include="BootstrapBlazor.TableExport" Version="9.2.7" /> | ||||||
| 		<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" /> | 		<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" /> | ||||||
| 		<PackageReference Include="BootstrapBlazor" Version="9.10.2" /> | 		<PackageReference Include="BootstrapBlazor" Version="9.11.1" /> | ||||||
| 	</ItemGroup> | 	</ItemGroup> | ||||||
|  |  | ||||||
| 	<ItemGroup> | 	<ItemGroup> | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
| using Microsoft.AspNetCore.Hosting; | using Microsoft.AspNetCore.Hosting; | ||||||
|  |  | ||||||
| using ThingsGateway; | using ThingsGateway; | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.Reflection; | using ThingsGateway.Reflection; | ||||||
|  |  | ||||||
| namespace Microsoft.Extensions.Hosting; | namespace Microsoft.Extensions.Hosting; | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ using System.Text.RegularExpressions; | |||||||
|  |  | ||||||
| using ThingsGateway.NewLife; | using ThingsGateway.NewLife; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| /// 对象拓展类 | /// 对象拓展类 | ||||||
| @@ -28,70 +28,10 @@ namespace ThingsGateway.Extensions; | |||||||
| [SuppressSniffer] | [SuppressSniffer] | ||||||
| public static class ObjectExtensions | public static class ObjectExtensions | ||||||
| { | { | ||||||
|     /// <summary> |  | ||||||
|     /// 将 DateTimeOffset 转换成本地 DateTime |  | ||||||
|     /// </summary> |  | ||||||
|     /// <param name="dateTime"></param> |  | ||||||
|     /// <returns></returns> |  | ||||||
|     public static DateTime ConvertToDateTime(this DateTimeOffset dateTime) |  | ||||||
|     { |  | ||||||
|         if (dateTime.Offset.Equals(TimeSpan.Zero)) |  | ||||||
|             return dateTime.UtcDateTime; |  | ||||||
|         if (dateTime.Offset.Equals(TimeZoneInfo.Local.GetUtcOffset(dateTime.DateTime))) |  | ||||||
|             return dateTime.ToLocalTime().DateTime; |  | ||||||
|         else |  | ||||||
|             return dateTime.DateTime; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     /// 将 DateTimeOffset? 转换成本地 DateTime? |  | ||||||
|     /// </summary> |  | ||||||
|     /// <param name="dateTime"></param> |  | ||||||
|     /// <returns></returns> |  | ||||||
|     public static DateTime? ConvertToDateTime(this DateTimeOffset? dateTime) |  | ||||||
|     { |  | ||||||
|         return dateTime.HasValue ? dateTime.Value.ConvertToDateTime() : null; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     /// 将 DateTime 转换成 DateTimeOffset |  | ||||||
|     /// </summary> |  | ||||||
|     /// <param name="dateTime"></param> |  | ||||||
|     /// <returns></returns> |  | ||||||
|     public static DateTimeOffset ConvertToDateTimeOffset(this DateTime dateTime) |  | ||||||
|     { |  | ||||||
|         return DateTime.SpecifyKind(dateTime, DateTimeKind.Local); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     /// 将 DateTime? 转换成 DateTimeOffset? |  | ||||||
|     /// </summary> |  | ||||||
|     /// <param name="dateTime"></param> |  | ||||||
|     /// <returns></returns> |  | ||||||
|     public static DateTimeOffset? ConvertToDateTimeOffset(this DateTime? dateTime) |  | ||||||
|     { |  | ||||||
|         return dateTime.HasValue ? dateTime.Value.ConvertToDateTimeOffset() : null; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     /// 将时间戳转换为 DateTime |  | ||||||
|     /// </summary> |  | ||||||
|     /// <param name="timestamp"></param> |  | ||||||
|     /// <returns></returns> |  | ||||||
|     internal static DateTime ConvertToDateTime(this long timestamp) |  | ||||||
|     { |  | ||||||
|         var timeStampDateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); |  | ||||||
|         var digitCount = (int)Math.Floor(Math.Log10(timestamp) + 1); |  | ||||||
|  |  | ||||||
|         if (digitCount != 13 && digitCount != 10) |  | ||||||
|         { |  | ||||||
|             throw new ArgumentException("Data is not a valid timestamp format."); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         return (digitCount == 13 |  | ||||||
|             ? timeStampDateTime.AddMilliseconds(timestamp)  // 13 位时间戳 |  | ||||||
|             : timeStampDateTime.AddSeconds(timestamp)).ToLocalTime();   // 10 位时间戳 |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     /// 将 IFormFile 转换成 byte[] |     /// 将 IFormFile 转换成 byte[] | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| using Microsoft.AspNetCore.Mvc.ModelBinding; | using Microsoft.AspNetCore.Mvc.ModelBinding; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.AspNetCore; | namespace ThingsGateway.AspNetCore; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| using Microsoft.AspNetCore.Mvc.ModelBinding; | using Microsoft.AspNetCore.Mvc.ModelBinding; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.AspNetCore; | namespace ThingsGateway.AspNetCore; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
| using Microsoft.AspNetCore.Mvc.ModelBinding; | using Microsoft.AspNetCore.Mvc.ModelBinding; | ||||||
| using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; | using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.AspNetCore; | namespace ThingsGateway.AspNetCore; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ using System.Reflection; | |||||||
|  |  | ||||||
| using ThingsGateway; | using ThingsGateway; | ||||||
| using ThingsGateway.ConfigurableOptions; | using ThingsGateway.ConfigurableOptions; | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace Microsoft.Extensions.DependencyInjection; | namespace Microsoft.Extensions.DependencyInjection; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,7 +10,6 @@ | |||||||
| // ------------------------------------------------------------------------ | // ------------------------------------------------------------------------ | ||||||
|  |  | ||||||
| using System.Security.Cryptography; | using System.Security.Cryptography; | ||||||
| using System.Text; |  | ||||||
|  |  | ||||||
| namespace ThingsGateway.DataEncryption; | namespace ThingsGateway.DataEncryption; | ||||||
|  |  | ||||||
| @@ -36,7 +35,7 @@ public static class PBKDF2Encryption | |||||||
|         var salt = new byte[saltSize]; |         var salt = new byte[saltSize]; | ||||||
|         rng.GetBytes(salt); |         rng.GetBytes(salt); | ||||||
| #if NET10_0_OR_GREATER | #if NET10_0_OR_GREATER | ||||||
|          var hash = Rfc2898DeriveBytes.Pbkdf2(Encoding.UTF8.GetBytes(text), salt, iterationCount, HashAlgorithmName.SHA256, derivedKeyLength); |         var hash = Rfc2898DeriveBytes.Pbkdf2(System.Text.Encoding.UTF8.GetBytes(text), salt, iterationCount, HashAlgorithmName.SHA256, derivedKeyLength); | ||||||
| #else | #else | ||||||
|         using var pbkdf2 = new Rfc2898DeriveBytes(text, salt, iterationCount, HashAlgorithmName.SHA256); |         using var pbkdf2 = new Rfc2898DeriveBytes(text, salt, iterationCount, HashAlgorithmName.SHA256); | ||||||
|         var hash = pbkdf2.GetBytes(derivedKeyLength); |         var hash = pbkdf2.GetBytes(derivedKeyLength); | ||||||
| @@ -70,7 +69,7 @@ public static class PBKDF2Encryption | |||||||
|                 return false; |                 return false; | ||||||
|  |  | ||||||
| #if NET10_0_OR_GREATER | #if NET10_0_OR_GREATER | ||||||
|             var computedHash = Rfc2898DeriveBytes.Pbkdf2(Encoding.UTF8.GetBytes(text), saltBytes, iterationCount, HashAlgorithmName.SHA256, derivedKeyLength); |             var computedHash = Rfc2898DeriveBytes.Pbkdf2(System.Text.Encoding.UTF8.GetBytes(text), saltBytes, iterationCount, HashAlgorithmName.SHA256, derivedKeyLength); | ||||||
| #else | #else | ||||||
|             using var pbkdf2 = new Rfc2898DeriveBytes(text, saltBytes, iterationCount, HashAlgorithmName.SHA256); |             using var pbkdf2 = new Rfc2898DeriveBytes(text, saltBytes, iterationCount, HashAlgorithmName.SHA256); | ||||||
|             var computedHash = pbkdf2.GetBytes(derivedKeyLength); |             var computedHash = pbkdf2.GetBytes(derivedKeyLength); | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ using System.ComponentModel.DataAnnotations; | |||||||
| using System.Reflection; | using System.Reflection; | ||||||
| using System.Text.RegularExpressions; | using System.Text.RegularExpressions; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.Templates.Extensions; | using ThingsGateway.Templates.Extensions; | ||||||
|  |  | ||||||
| namespace ThingsGateway.DataValidation; | namespace ThingsGateway.DataValidation; | ||||||
|   | |||||||
| @@ -21,7 +21,7 @@ using System.Collections.Concurrent; | |||||||
| using System.Reflection; | using System.Reflection; | ||||||
| using System.Text.RegularExpressions; | using System.Text.RegularExpressions; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.UnifyResult; | using ThingsGateway.UnifyResult; | ||||||
|  |  | ||||||
| namespace ThingsGateway.DynamicApiController; | namespace ThingsGateway.DynamicApiController; | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ using System.ComponentModel.DataAnnotations; | |||||||
| using System.Diagnostics; | using System.Diagnostics; | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.Templates.Extensions; | using ThingsGateway.Templates.Extensions; | ||||||
|  |  | ||||||
| namespace ThingsGateway.FriendlyException; | namespace ThingsGateway.FriendlyException; | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ using Microsoft.AspNetCore.SignalR; | |||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| using ThingsGateway; | using ThingsGateway; | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.InstantMessaging; | using ThingsGateway.InstantMessaging; | ||||||
|  |  | ||||||
| namespace Microsoft.AspNetCore.Builder; | namespace Microsoft.AspNetCore.Builder; | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ | |||||||
| // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | ||||||
| // ------------------------------------------------------------------------ | // ------------------------------------------------------------------------ | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Logging; | namespace ThingsGateway.Logging; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -36,7 +36,7 @@ using System.Text.Json; | |||||||
|  |  | ||||||
| using ThingsGateway; | using ThingsGateway; | ||||||
| using ThingsGateway.DataValidation; | using ThingsGateway.DataValidation; | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.FriendlyException; | using ThingsGateway.FriendlyException; | ||||||
| using ThingsGateway.JsonSerialization; | using ThingsGateway.JsonSerialization; | ||||||
| using ThingsGateway.Logging; | using ThingsGateway.Logging; | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; | |||||||
| using System.Linq.Expressions; | using System.Linq.Expressions; | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.Options; | using ThingsGateway.Options; | ||||||
|  |  | ||||||
| namespace Microsoft.Extensions.Options; | namespace Microsoft.Extensions.Options; | ||||||
|   | |||||||
| @@ -204,7 +204,7 @@ internal sealed partial class SchedulerFactory : ISchedulerFactory | |||||||
|             } |             } | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 _logger.LogWarning("Schedule hosted service preload completed, and a total of <{Count}> schedulers are appended.", _schedulers.Count); |                 _logger.LogInformation("Schedule hosted service preload completed, and a total of <{Count}> schedulers are appended.", _schedulers.Count); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ using System.Xml.Linq; | |||||||
| using System.Xml.XPath; | using System.Xml.XPath; | ||||||
|  |  | ||||||
| using ThingsGateway.DynamicApiController; | using ThingsGateway.DynamicApiController; | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.Reflection; | using ThingsGateway.Reflection; | ||||||
|  |  | ||||||
| namespace ThingsGateway.SpecificationDocument; | namespace ThingsGateway.SpecificationDocument; | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ using System.Reflection; | |||||||
| using System.Text; | using System.Text; | ||||||
| using System.Text.RegularExpressions; | using System.Text.RegularExpressions; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.SpecificationDocument; | namespace ThingsGateway.SpecificationDocument; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| using System.Text.RegularExpressions; | using System.Text.RegularExpressions; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Templates.Extensions; | namespace ThingsGateway.Templates.Extensions; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ | |||||||
| 	</ItemGroup> | 	</ItemGroup> | ||||||
|  |  | ||||||
| 	<ItemGroup> | 	<ItemGroup> | ||||||
| 		<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.4" /> | 		<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.6" /> | ||||||
| 		<PackageReference Include="System.Text.Encoding.CodePages" Version="$(NET10Version)" /> | 		<PackageReference Include="System.Text.Encoding.CodePages" Version="$(NET10Version)" /> | ||||||
| 	</ItemGroup> | 	</ItemGroup> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ using Microsoft.AspNetCore.Http; | |||||||
|  |  | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.UnifyResult; | using ThingsGateway.UnifyResult; | ||||||
|  |  | ||||||
| namespace Microsoft.AspNetCore.Mvc; | namespace Microsoft.AspNetCore.Mvc; | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ using Microsoft.Extensions.Options; | |||||||
| using System.Collections.Concurrent; | using System.Collections.Concurrent; | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.FriendlyException; | using ThingsGateway.FriendlyException; | ||||||
|  |  | ||||||
| namespace ThingsGateway.UnifyResult; | namespace ThingsGateway.UnifyResult; | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
| using System.Text.Json; | using System.Text.Json; | ||||||
| using System.Text.Json.Serialization; | using System.Text.Json.Serialization; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Converters.Json; | namespace ThingsGateway.Converters.Json; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     <see cref="Assembly" /> 拓展类 | ///     <see cref="Assembly" /> 拓展类 | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| using System.Collections.Concurrent; | using System.Collections.Concurrent; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     <see cref="ConcurrentDictionary{TKey, TValue}" /> 拓展类 | ///     <see cref="ConcurrentDictionary{TKey, TValue}" /> 拓展类 | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ using Microsoft.Extensions.Hosting; | |||||||
|  |  | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     核心模块 <see cref="IServiceCollection" /> 拓展类 | ///     核心模块 <see cref="IServiceCollection" /> 拓展类 | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| using System.Data; | using System.Data; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     <see cref="DataTable" /> 和 <see cref="DataSet" /> 拓展类 | ///     <see cref="DataTable" /> 和 <see cref="DataSet" /> 拓展类 | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ | |||||||
| // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | ||||||
| // ------------------------------------------------------------------------ | // ------------------------------------------------------------------------ | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     委托拓展类 | ///     委托拓展类 | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
| using System.ComponentModel; | using System.ComponentModel; | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     枚举拓展类 | ///     枚举拓展类 | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ | |||||||
| // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | ||||||
| // ------------------------------------------------------------------------ | // ------------------------------------------------------------------------ | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     <see cref="EventHandler{TEventArgs}" /> 拓展类 | ///     <see cref="EventHandler{TEventArgs}" /> 拓展类 | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| using System.Diagnostics.CodeAnalysis; | using System.Diagnostics.CodeAnalysis; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     <see cref="ICollection{T}" /> 拓展类 | ///     <see cref="ICollection{T}" /> 拓展类 | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| using System.Collections.Concurrent; | using System.Collections.Concurrent; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     <see cref="IDictionary{TKey, TValue}" /> 拓展类 | ///     <see cref="IDictionary{TKey, TValue}" /> 拓展类 | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ | |||||||
| // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | ||||||
| // ------------------------------------------------------------------------ | // ------------------------------------------------------------------------ | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     <see cref="IEnumerable" /> 拓展类 | ///     <see cref="IEnumerable" /> 拓展类 | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ using System.Text.RegularExpressions; | |||||||
| using System.Xml; | using System.Xml; | ||||||
| using System.Xml.Linq; | using System.Xml.Linq; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     System.Text.Json 拓展类 | ///     System.Text.Json 拓展类 | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
| using System.Linq.Expressions; | using System.Linq.Expressions; | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     <see cref="Expression" /> 拓展类 | ///     <see cref="Expression" /> 拓展类 | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
| using System.Diagnostics.CodeAnalysis; | using System.Diagnostics.CodeAnalysis; | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     <see cref="MethodInfo" /> 拓展类 | ///     <see cref="MethodInfo" /> 拓展类 | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ | |||||||
| // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | ||||||
| // ------------------------------------------------------------------------ | // ------------------------------------------------------------------------ | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     数值类型拓展类 | ///     数值类型拓展类 | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ using System.Reflection; | |||||||
| using System.Text; | using System.Text; | ||||||
| using System.Text.RegularExpressions; | using System.Text.RegularExpressions; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     <see cref="string" /> 拓展类 | ///     <see cref="string" /> 拓展类 | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ using System.Reflection; | |||||||
| using System.Reflection.Emit; | using System.Reflection.Emit; | ||||||
| using System.Runtime.CompilerServices; | using System.Runtime.CompilerServices; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     <see cref="Type" /> 拓展类 | ///     <see cref="Type" /> 拓展类 | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ using System.Buffers; | |||||||
| using System.Text; | using System.Text; | ||||||
| using System.Text.Json; | using System.Text.Json; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     <see cref="Utf8JsonReader" /> 拓展类 | ///     <see cref="Utf8JsonReader" /> 拓展类 | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ using System.Text.Json; | |||||||
|  |  | ||||||
| using ThingsGateway.Utilities; | using ThingsGateway.Utilities; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Extensions; | namespace ThingsGateway.Extension; | ||||||
|  |  | ||||||
| /// <summary> | /// <summary> | ||||||
| ///     <see cref="object" /> 拓展类 | ///     <see cref="object" /> 拓展类 | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ using System.Collections.Concurrent; | |||||||
| using System.Diagnostics.CodeAnalysis; | using System.Diagnostics.CodeAnalysis; | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Reflection; | namespace ThingsGateway.Reflection; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ using System.Collections.Concurrent; | |||||||
| using System.Diagnostics.CodeAnalysis; | using System.Diagnostics.CodeAnalysis; | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Reflection; | namespace ThingsGateway.Reflection; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| using System.Diagnostics.CodeAnalysis; | using System.Diagnostics.CodeAnalysis; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Utilities; | namespace ThingsGateway.Utilities; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| using System.Text; | using System.Text; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Utilities; | namespace ThingsGateway.Utilities; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ using Microsoft.Net.Http.Headers; | |||||||
| using System.Net.Mime; | using System.Net.Mime; | ||||||
|  |  | ||||||
| using ThingsGateway.AspNetCore.Extensions; | using ThingsGateway.AspNetCore.Extensions; | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue; | using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
| using System.Net.Http.Headers; | using System.Net.Http.Headers; | ||||||
| using System.Threading.Channels; | using System.Threading.Channels; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.Utilities; | using ThingsGateway.Utilities; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ using System.Text; | |||||||
| using System.Text.Json; | using System.Text.Json; | ||||||
| using System.Threading.Channels; | using System.Threading.Channels; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.Utilities; | using ThingsGateway.Utilities; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ using Microsoft.Extensions.Logging; | |||||||
| using System.Reflection; | using System.Reflection; | ||||||
| using System.Text; | using System.Text; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ using System.Net.Mime; | |||||||
| using System.Text; | using System.Text; | ||||||
| using System.Text.Json; | using System.Text.Json; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.Utilities; | using ThingsGateway.Utilities; | ||||||
|  |  | ||||||
| using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue; | using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue; | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ using System.Globalization; | |||||||
| using System.Net.Http.Headers; | using System.Net.Http.Headers; | ||||||
| using System.Net.Mime; | using System.Net.Mime; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| using CacheControlHeaderValue = System.Net.Http.Headers.CacheControlHeaderValue; | using CacheControlHeaderValue = System.Net.Http.Headers.CacheControlHeaderValue; | ||||||
| using StringWithQualityHeaderValue = System.Net.Http.Headers.StringWithQualityHeaderValue; | using StringWithQualityHeaderValue = System.Net.Http.Headers.StringWithQualityHeaderValue; | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ | |||||||
| using System.Collections.Concurrent; | using System.Collections.Concurrent; | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
| using System.Net.Mime; | using System.Net.Mime; | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.Utilities; | using ThingsGateway.Utilities; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.Utilities; | using ThingsGateway.Utilities; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ using System.Net.Mime; | |||||||
| using System.Reflection; | using System.Reflection; | ||||||
| using System.Text; | using System.Text; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ | |||||||
| // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | ||||||
| // ------------------------------------------------------------------------ | // ------------------------------------------------------------------------ | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.Utilities; | using ThingsGateway.Utilities; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.Utilities; | using ThingsGateway.Utilities; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.Utilities; | using ThingsGateway.Utilities; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
| using System.ComponentModel.DataAnnotations; | using System.ComponentModel.DataAnnotations; | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
| using System.Diagnostics.CodeAnalysis; | using System.Diagnostics.CodeAnalysis; | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ using Microsoft.Extensions.DependencyInjection; | |||||||
|  |  | ||||||
| using System.Net.Http.Headers; | using System.Net.Http.Headers; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote.Extensions; | namespace ThingsGateway.HttpRemote.Extensions; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ using System.Net.Http.Headers; | |||||||
| using System.Text; | using System.Text; | ||||||
| using System.Text.RegularExpressions; | using System.Text.RegularExpressions; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.Utilities; | using ThingsGateway.Utilities; | ||||||
|  |  | ||||||
| using StringWithQualityHeaderValue = System.Net.Http.Headers.StringWithQualityHeaderValue; | using StringWithQualityHeaderValue = System.Net.Http.Headers.StringWithQualityHeaderValue; | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| using Microsoft.Extensions.DependencyInjection; | using Microsoft.Extensions.DependencyInjection; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| using System.Text; | using System.Text; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ using Microsoft.AspNetCore.Mvc; | |||||||
| using Microsoft.AspNetCore.Mvc.Controllers; | using Microsoft.AspNetCore.Mvc.Controllers; | ||||||
| using Microsoft.AspNetCore.Mvc.Filters; | using Microsoft.AspNetCore.Mvc.Filters; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.HttpRemote.Extensions; | using ThingsGateway.HttpRemote.Extensions; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| using System.Globalization; | using System.Globalization; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ using Microsoft.Extensions.Options; | |||||||
| using System.Diagnostics; | using System.Diagnostics; | ||||||
| using System.Threading.Channels; | using System.Threading.Channels; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ using Microsoft.Extensions.Options; | |||||||
| using System.Diagnostics; | using System.Diagnostics; | ||||||
| using System.Threading.Channels; | using System.Threading.Channels; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ using Microsoft.Extensions.Options; | |||||||
|  |  | ||||||
| using System.Threading.Channels; | using System.Threading.Channels; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ using System.Diagnostics.CodeAnalysis; | |||||||
| using System.Text; | using System.Text; | ||||||
| using System.Threading.Channels; | using System.Threading.Channels; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ | |||||||
| // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | ||||||
| // ------------------------------------------------------------------------ | // ------------------------------------------------------------------------ | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.Utilities; | using ThingsGateway.Utilities; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ using System.Net.Http.Headers; | |||||||
| using System.Net.Mime; | using System.Net.Mime; | ||||||
| using System.Text; | using System.Text; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ using System.Net.Http.Headers; | |||||||
| using System.Reflection; | using System.Reflection; | ||||||
| using System.Text; | using System.Text; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
| using System.Net.Mime; | using System.Net.Mime; | ||||||
| using System.Text; | using System.Text; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ using System.Globalization; | |||||||
| using System.Net.Http.Headers; | using System.Net.Http.Headers; | ||||||
| using System.Text; | using System.Text; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ using System.Text; | |||||||
| using System.Text.Json; | using System.Text.Json; | ||||||
| using System.Text.Json.Nodes; | using System.Text.Json.Nodes; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ using System.Net; | |||||||
| using System.Reflection; | using System.Reflection; | ||||||
| using System.Text.RegularExpressions; | using System.Text.RegularExpressions; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ | |||||||
| // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | ||||||
| // ------------------------------------------------------------------------ | // ------------------------------------------------------------------------ | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
| using System.Net.WebSockets; | using System.Net.WebSockets; | ||||||
| using System.Text; | using System.Text; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.HttpRemote; | namespace ThingsGateway.HttpRemote; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ using System.Net.Mime; | |||||||
| using System.Reflection; | using System.Reflection; | ||||||
| using System.Web; | using System.Web; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Shapeless; | namespace ThingsGateway.Shapeless; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ using System.Text.Json.Nodes; | |||||||
| using System.Xml; | using System.Xml; | ||||||
| using System.Xml.Linq; | using System.Xml.Linq; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Shapeless; | namespace ThingsGateway.Shapeless; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ using System.Dynamic; | |||||||
| using System.Reflection; | using System.Reflection; | ||||||
| using System.Text.Json; | using System.Text.Json; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| using ThingsGateway.Shapeless.Extensions; | using ThingsGateway.Shapeless.Extensions; | ||||||
|  |  | ||||||
| using Binder = Microsoft.CSharp.RuntimeBinder.Binder; | using Binder = Microsoft.CSharp.RuntimeBinder.Binder; | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ using System.Dynamic; | |||||||
| using System.Text.Json; | using System.Text.Json; | ||||||
| using System.Text.Json.Nodes; | using System.Text.Json.Nodes; | ||||||
|  |  | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
|  |  | ||||||
| namespace ThingsGateway.Shapeless; | namespace ThingsGateway.Shapeless; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,30 +5,101 @@ namespace ThingsGateway.NewLife; | |||||||
|  |  | ||||||
| public class ExpiringDictionary<TKey, TValue> : IDisposable | public class ExpiringDictionary<TKey, TValue> : IDisposable | ||||||
| { | { | ||||||
|     private ConcurrentDictionary<TKey, TValue> _dict = new(); |     /// <summary>缓存项</summary> | ||||||
|     private readonly TimerX _cleanupTimer; |     public class CacheItem | ||||||
|  |  | ||||||
|     public ExpiringDictionary(int cleanupInterval = 60000) |  | ||||||
|     { |     { | ||||||
|         _cleanupTimer = new TimerX(Clear, null, cleanupInterval, cleanupInterval) { Async = true }; |         private TValue? _value; | ||||||
|  |         /// <summary>数值</summary> | ||||||
|  |         public TValue? Value { get => _value; } | ||||||
|  |  | ||||||
|  |         /// <summary>过期时间。系统启动以来的毫秒数</summary> | ||||||
|  |         public Int64 ExpiredTime { get; set; } | ||||||
|  |  | ||||||
|  |         /// <summary>是否过期</summary> | ||||||
|  |         public Boolean Expired => ExpiredTime <= Runtime.TickCount64; | ||||||
|  |  | ||||||
|  |         /// <summary>访问时间</summary> | ||||||
|  |         public Int64 VisitTime { get; private set; } | ||||||
|  |  | ||||||
|  |         /// <summary>构造缓存项</summary> | ||||||
|  |         /// <param name="value"></param> | ||||||
|  |         /// <param name="expire"></param> | ||||||
|  |         public CacheItem(TValue? value, Int32 expire) => Set(value, expire); | ||||||
|  |  | ||||||
|  |         /// <summary>设置数值和过期时间</summary> | ||||||
|  |         /// <param name="value"></param> | ||||||
|  |         /// <param name="expire">过期时间,秒</param> | ||||||
|  |         public void Set(TValue value, Int32 expire) | ||||||
|  |         { | ||||||
|  |             _value = value; | ||||||
|  |  | ||||||
|  |             var now = VisitTime = Runtime.TickCount64; | ||||||
|  |             if (expire <= 0) | ||||||
|  |                 ExpiredTime = Int64.MaxValue; | ||||||
|  |             else | ||||||
|  |                 ExpiredTime = now + expire * 1000L; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     public void TryAdd(TKey key, TValue value) |         /// <summary>更新访问时间并返回数值</summary> | ||||||
|  |         /// <returns></returns> | ||||||
|  |         public TValue? Visit() | ||||||
|         { |         { | ||||||
|         _dict.TryAdd(key, value); |             VisitTime = Runtime.TickCount64; | ||||||
|  |             var rs = _value; | ||||||
|  |             if (rs == null) return default; | ||||||
|  |  | ||||||
|  |             return rs; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private ConcurrentDictionary<TKey, CacheItem> _dict = new(); | ||||||
|  |     private readonly TimerX _cleanupTimer; | ||||||
|  |     private int defaultExpire = 60; | ||||||
|  |     public ExpiringDictionary(int expire = 60) | ||||||
|  |     { | ||||||
|  |         defaultExpire = expire; | ||||||
|  |         _cleanupTimer = new TimerX(TimerClear, null, 10000, 10000) { Async = true }; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     public bool TryAdd(TKey key, TValue value) | ||||||
|  |     { | ||||||
|  |         if (_dict.TryGetValue(key, out var item)) | ||||||
|  |         { | ||||||
|  |             if (!item.Expired) return false; | ||||||
|  |             item.Set(value, defaultExpire); | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |         return _dict.TryAdd(key, new CacheItem(value, defaultExpire)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public bool TryGetValue(TKey key, out TValue value) |     public bool TryGetValue(TKey key, out TValue value) | ||||||
|     { |     { | ||||||
|         return _dict.TryGetValue(key, out value); |         value = default; | ||||||
|  |  | ||||||
|  |         // 没有值,直接结束 | ||||||
|  |         if (!_dict.TryGetValue(key, out var item) || item == null) return false; | ||||||
|  |  | ||||||
|  |         // 得到已有值 | ||||||
|  |         value = item.Visit(); | ||||||
|  |  | ||||||
|  |         // 是否未过期的有效值 | ||||||
|  |         return !item.Expired; | ||||||
|     } |     } | ||||||
|     public TValue GetOrAdd(TKey key, Func<TKey, TValue> func) |     public TValue GetOrAdd(TKey key, Func<TKey, TValue> func) | ||||||
|     { |     { | ||||||
|         return _dict.GetOrAdd(key, func); |         CacheItem? item = null; | ||||||
|     } |         do | ||||||
|     public TValue GetOrAdd(TKey key, TValue value) |  | ||||||
|         { |         { | ||||||
|         return _dict.GetOrAdd(key, value); |             if (_dict.TryGetValue(key, out item) && item != null) return item.Visit(); | ||||||
|  |  | ||||||
|  |             item ??= new CacheItem(func(key), defaultExpire); | ||||||
|  |         } | ||||||
|  |         while (!_dict.TryAdd(key, item)); | ||||||
|  |  | ||||||
|  |         return item.Visit(); | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public bool TryRemove(TKey key) => _dict.TryRemove(key, out _); |     public bool TryRemove(TKey key) => _dict.TryRemove(key, out _); | ||||||
| @@ -41,7 +112,31 @@ public class ExpiringDictionary<TKey, TValue> : IDisposable | |||||||
|         _dict = new(); |         _dict = new(); | ||||||
|         data.Clear(); |         data.Clear(); | ||||||
|     } |     } | ||||||
|  |     private void TimerClear(object? state) | ||||||
|  |     { | ||||||
|  |  | ||||||
|  |         var dic = _dict; | ||||||
|  |         if (dic.IsEmpty) return; | ||||||
|  |  | ||||||
|  |         // 60分钟之内过期的数据,进入LRU淘汰 | ||||||
|  |         var now = Runtime.TickCount64; | ||||||
|  |  | ||||||
|  |         // 这里先计算,性能很重要 | ||||||
|  |         var toDels = new List<TKey>(); | ||||||
|  |         foreach (var item in dic) | ||||||
|  |         { | ||||||
|  |             // 已过期,准备删除 | ||||||
|  |             var ci = item.Value; | ||||||
|  |             if (ci.ExpiredTime <= now) | ||||||
|  |                 toDels.Add(item.Key); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // 确认删除 | ||||||
|  |         foreach (var item in toDels) | ||||||
|  |         { | ||||||
|  |             _dict.Remove(item); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|     public void Dispose() |     public void Dispose() | ||||||
|     { |     { | ||||||
|         _dict.Clear(); |         _dict.Clear(); | ||||||
|   | |||||||
| @@ -66,7 +66,7 @@ public sealed class WaitLock : IDisposable | |||||||
|             } |             } | ||||||
|             catch (SemaphoreFullException) |             catch (SemaphoreFullException) | ||||||
|             { |             { | ||||||
|                 XTrace.WriteException(new Exception($"WaitLock {_name} 释放失败,当前信号量无需释放")); |                 //XTrace.WriteException(new Exception($"WaitLock {_name} 释放失败,当前信号量无需释放")); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -155,7 +155,7 @@ public static class DateExtensions | |||||||
|     /// </summary> |     /// </summary> | ||||||
|     /// <param name="timestamp"></param> |     /// <param name="timestamp"></param> | ||||||
|     /// <returns></returns> |     /// <returns></returns> | ||||||
|     internal static DateTime ConvertToDateTime(this long timestamp) |     public static DateTime ConvertToDateTime(this long timestamp) | ||||||
|     { |     { | ||||||
|         var timeStampDateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); |         var timeStampDateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); | ||||||
|         var digitCount = (int)Math.Floor(Math.Log10(timestamp) + 1); |         var digitCount = (int)Math.Floor(Math.Log10(timestamp) + 1); | ||||||
| @@ -169,4 +169,5 @@ public static class DateExtensions | |||||||
|             ? timeStampDateTime.AddMilliseconds(timestamp)  // 13 位时间戳 |             ? timeStampDateTime.AddMilliseconds(timestamp)  // 13 位时间戳 | ||||||
|             : timeStampDateTime.AddSeconds(timestamp)).ToLocalTime();   // 10 位时间戳 |             : timeStampDateTime.AddSeconds(timestamp)).ToLocalTime();   // 10 位时间戳 | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -8,13 +8,14 @@ | |||||||
| // 项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。 | // 项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。 | ||||||
| // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 | ||||||
| // ------------------------------------------------------------------------ | // ------------------------------------------------------------------------ | ||||||
| 
 |  | ||||||
| using Newtonsoft.Json; | using Newtonsoft.Json; | ||||||
| using Newtonsoft.Json.Linq; | using Newtonsoft.Json.Linq; | ||||||
| 
 | 
 | ||||||
|  | #if NET6_0_OR_GREATER | ||||||
| using System.Text.Json; | using System.Text.Json; | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| using ThingsGateway.Extensions; | using ThingsGateway.Extension; | ||||||
| 
 | 
 | ||||||
| namespace ThingsGateway.JsonSerialization; | namespace ThingsGateway.JsonSerialization; | ||||||
| 
 | 
 | ||||||
| @@ -23,6 +24,7 @@ namespace ThingsGateway.JsonSerialization; | |||||||
| /// </summary> | /// </summary> | ||||||
| internal static class Penetrates | internal static class Penetrates | ||||||
| { | { | ||||||
|  | #if NET6_0_OR_GREATER | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     /// 转换 |     /// 转换 | ||||||
|     /// </summary> |     /// </summary> | ||||||
| @@ -35,7 +37,6 @@ internal static class Penetrates | |||||||
|         { |         { | ||||||
|             return longValue.ConvertToDateTime(); |             return longValue.ConvertToDateTime(); | ||||||
|         } |         } | ||||||
| 
 |  | ||||||
|         var stringValue = reader.GetString(); |         var stringValue = reader.GetString(); | ||||||
| 
 | 
 | ||||||
|         // 处理时间戳自动转换 |         // 处理时间戳自动转换 | ||||||
| @@ -46,6 +47,9 @@ internal static class Penetrates | |||||||
| 
 | 
 | ||||||
|         return Convert.ToDateTime(stringValue); |         return Convert.ToDateTime(stringValue); | ||||||
|     } |     } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|     /// <summary> |     /// <summary> | ||||||
|     /// 转换 |     /// 转换 | ||||||
| @@ -69,4 +73,6 @@ internal static class Penetrates | |||||||
| 
 | 
 | ||||||
|         return Convert.ToDateTime(stringValue); |         return Convert.ToDateTime(stringValue); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  | 
 | ||||||
| @@ -53,12 +53,16 @@ public static class LinqExtensions | |||||||
|     /// <inheritdoc/> |     /// <inheritdoc/> | ||||||
|     public static void RemoveWhere<T>(this ICollection<T> @this, Func<T, bool> @where) |     public static void RemoveWhere<T>(this ICollection<T> @this, Func<T, bool> @where) | ||||||
|     { |     { | ||||||
|         foreach (var obj in @this.Where(where).ToList()) |         var del = new List<T>(); | ||||||
|  |         foreach (var obj in @this.Where(where)) | ||||||
|  |         { | ||||||
|  |             del.Add(obj); | ||||||
|  |         } | ||||||
|  |         foreach (var obj in del) | ||||||
|         { |         { | ||||||
|             @this.Remove(obj); |             @this.Remove(obj); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <inheritdoc/> |     /// <inheritdoc/> | ||||||
|     public static IEnumerable<T> WhereIf<T>(this IEnumerable<T> thisValue, bool isOk, Func<T, bool> predicate) |     public static IEnumerable<T> WhereIf<T>(this IEnumerable<T> thisValue, bool isOk, Func<T, bool> predicate) | ||||||
|     { |     { | ||||||
|   | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user