mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-10-29 06:33:58 +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()
|
||||||
Text = item.Title,
|
{
|
||||||
Icon = item.Icon,
|
Match = item.NavLinkMatch ?? Microsoft.AspNetCore.Components.Routing.NavLinkMatch.Prefix,
|
||||||
Url = item.Href,
|
Text = item.Title,
|
||||||
Target = item.Target.ToString(),
|
Icon = item.Icon,
|
||||||
|
Url = item.Href,
|
||||||
|
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,15 +41,22 @@ 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()
|
{
|
||||||
|
var menu = new MenuItem()
|
||||||
{
|
{
|
||||||
Match = item.NavLinkMatch ?? Microsoft.AspNetCore.Components.Routing.NavLinkMatch.All,
|
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,10 +69,10 @@ 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);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return computedHash.SequenceEqual(storedHashBytes);
|
return computedHash.SequenceEqual(storedHashBytes);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>更新访问时间并返回数值</summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public TValue? Visit()
|
||||||
|
{
|
||||||
|
VisitTime = Runtime.TickCount64;
|
||||||
|
var rs = _value;
|
||||||
|
if (rs == null) return default;
|
||||||
|
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TryAdd(TKey key, TValue value)
|
private ConcurrentDictionary<TKey, CacheItem> _dict = new();
|
||||||
|
private readonly TimerX _cleanupTimer;
|
||||||
|
private int defaultExpire = 60;
|
||||||
|
public ExpiringDictionary(int expire = 60)
|
||||||
{
|
{
|
||||||
_dict.TryAdd(key, value);
|
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)
|
{
|
||||||
{
|
if (_dict.TryGetValue(key, out item) && item != null) return item.Visit();
|
||||||
return _dict.GetOrAdd(key, value);
|
|
||||||
|
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