Compare commits

...

15 Commits

Author SHA1 Message Date
2248356998 qq.com
5ee8b50a92 build: 10.11.99 2025-10-13 22:11:05 +08:00
2248356998 qq.com
301beda2a2 build: 10.11.98 2025-10-13 21:10:39 +08:00
2248356998 qq.com
628b51a353 build: 10.11.97 2025-10-12 15:15:42 +08:00
2248356998 qq.com
f03445bc83 更新依赖 2025-10-12 00:25:57 +08:00
2248356998 qq.com
55a2ff5487 build: 10.11.96 2025-10-11 13:38:28 +08:00
2248356998 qq.com
0fef7dcf3b 更新依赖 2025-10-10 21:41:24 +08:00
2248356998 qq.com
19d9702606 fix: sqlite 批量更新 2025-10-10 14:19:43 +08:00
2248356998 qq.com
a8a9774932 fix: orm 序列化 2025-10-10 12:26:35 +08:00
2248356998 qq.com
aad0f0e8c3 fix: orm批量插入 2025-10-10 11:19:14 +08:00
2248356998 qq.com
e74eae50a7 build: 10.11.87 2025-10-09 20:58:16 +08:00
2248356998 qq.com
3b16d7019f feat: 优化orm 批量插入 2025-10-09 20:57:18 +08:00
2248356998 qq.com
3e038028c2 feat: 优化orm 批量插入 2025-10-09 19:19:18 +08:00
2248356998 qq.com
b1d8041f7e feat: 优化orm BulkCopy 2025-10-09 19:05:33 +08:00
2248356998 qq.com
53a98b26cd fix: 数据库插件保留天数逻辑错误 2025-10-09 08:52:02 +08:00
2248356998 qq.com
42c740fa1b 更新依赖 2025-10-07 22:25:38 +08:00
335 changed files with 2535 additions and 1688 deletions

View File

@@ -20,7 +20,7 @@
<ItemGroup>
<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 Condition=" '$(TargetFramework)' == 'net8.0' ">
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.1" />

View File

@@ -5,7 +5,7 @@
<ItemGroup>
<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.WinBox" Version="9.0.7" />
<PackageReference Include="BootstrapBlazor.CodeEditor" Version="9.0.3" />

View File

@@ -16,6 +16,8 @@ using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Text.RegularExpressions;
using ThingsGateway.Extension;
namespace ThingsGateway.Common.Extension;
/// <summary>
/// 对象拓展类
@@ -48,113 +50,7 @@ public static class ObjectExtensions
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>
/// 合并两个字典

View File

@@ -12,9 +12,9 @@
</PropertyGroup>
<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="BootstrapBlazor" Version="9.11.0" />
<PackageReference Include="BootstrapBlazor" Version="9.11.1" />
</ItemGroup>
<ItemGroup>

View File

@@ -12,7 +12,7 @@
using Microsoft.AspNetCore.Hosting;
using ThingsGateway;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.Reflection;
namespace Microsoft.Extensions.Hosting;

View File

@@ -20,7 +20,7 @@ using System.Text.RegularExpressions;
using ThingsGateway.NewLife;
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// 对象拓展类
@@ -28,70 +28,10 @@ namespace ThingsGateway.Extensions;
[SuppressSniffer]
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>
/// 将 IFormFile 转换成 byte[]

View File

@@ -11,7 +11,7 @@
using Microsoft.AspNetCore.Mvc.ModelBinding;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.AspNetCore;

View File

@@ -11,7 +11,7 @@
using Microsoft.AspNetCore.Mvc.ModelBinding;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.AspNetCore;

View File

@@ -12,7 +12,7 @@
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.AspNetCore;

View File

@@ -18,7 +18,7 @@ using System.Reflection;
using ThingsGateway;
using ThingsGateway.ConfigurableOptions;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace Microsoft.Extensions.DependencyInjection;

View File

@@ -16,7 +16,7 @@ using System.ComponentModel.DataAnnotations;
using System.Reflection;
using System.Text.RegularExpressions;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.Templates.Extensions;
namespace ThingsGateway.DataValidation;

View File

@@ -21,7 +21,7 @@ using System.Collections.Concurrent;
using System.Reflection;
using System.Text.RegularExpressions;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.UnifyResult;
namespace ThingsGateway.DynamicApiController;

View File

@@ -17,7 +17,7 @@ using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Reflection;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.Templates.Extensions;
namespace ThingsGateway.FriendlyException;

View File

@@ -16,7 +16,7 @@ using Microsoft.AspNetCore.SignalR;
using System.Reflection;
using ThingsGateway;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.InstantMessaging;
namespace Microsoft.AspNetCore.Builder;

View File

@@ -9,7 +9,7 @@
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// ------------------------------------------------------------------------
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.Logging;

View File

@@ -36,7 +36,7 @@ using System.Text.Json;
using ThingsGateway;
using ThingsGateway.DataValidation;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.FriendlyException;
using ThingsGateway.JsonSerialization;
using ThingsGateway.Logging;

View File

@@ -16,7 +16,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
using System.Linq.Expressions;
using System.Reflection;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.Options;
namespace Microsoft.Extensions.Options;

View File

@@ -31,7 +31,7 @@ using System.Xml.Linq;
using System.Xml.XPath;
using ThingsGateway.DynamicApiController;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.Reflection;
namespace ThingsGateway.SpecificationDocument;

View File

@@ -20,7 +20,7 @@ using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.SpecificationDocument;

View File

@@ -11,7 +11,7 @@
using System.Text.RegularExpressions;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.Templates.Extensions;

View File

@@ -29,7 +29,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.5" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.6" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="$(NET10Version)" />
</ItemGroup>

View File

@@ -13,7 +13,7 @@ using Microsoft.AspNetCore.Http;
using System.Reflection;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.UnifyResult;
namespace Microsoft.AspNetCore.Mvc;

View File

@@ -22,7 +22,7 @@ using Microsoft.Extensions.Options;
using System.Collections.Concurrent;
using System.Reflection;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.FriendlyException;
namespace ThingsGateway.UnifyResult;

View File

@@ -12,7 +12,7 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.Converters.Json;

View File

@@ -11,7 +11,7 @@
using System.Reflection;
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// <see cref="Assembly" /> 拓展类

View File

@@ -11,7 +11,7 @@
using System.Collections.Concurrent;
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// <see cref="ConcurrentDictionary{TKey, TValue}" /> 拓展类

View File

@@ -15,7 +15,7 @@ using Microsoft.Extensions.Hosting;
using System.Reflection;
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// 核心模块 <see cref="IServiceCollection" /> 拓展类

View File

@@ -11,7 +11,7 @@
using System.Data;
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// <see cref="DataTable" /> 和 <see cref="DataSet" /> 拓展类

View File

@@ -9,7 +9,7 @@
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// ------------------------------------------------------------------------
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// 委托拓展类

View File

@@ -12,7 +12,7 @@
using System.ComponentModel;
using System.Reflection;
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// 枚举拓展类

View File

@@ -9,7 +9,7 @@
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// ------------------------------------------------------------------------
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// <see cref="EventHandler{TEventArgs}" /> 拓展类

View File

@@ -11,7 +11,7 @@
using System.Diagnostics.CodeAnalysis;
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// <see cref="ICollection{T}" /> 拓展类

View File

@@ -11,7 +11,7 @@
using System.Collections.Concurrent;
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// <see cref="IDictionary{TKey, TValue}" /> 拓展类

View File

@@ -9,7 +9,7 @@
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// ------------------------------------------------------------------------
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// <see cref="IEnumerable" /> 拓展类

View File

@@ -18,7 +18,7 @@ using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Linq;
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// System.Text.Json 拓展类

View File

@@ -12,7 +12,7 @@
using System.Linq.Expressions;
using System.Reflection;
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// <see cref="Expression" /> 拓展类

View File

@@ -12,7 +12,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// <see cref="MethodInfo" /> 拓展类

View File

@@ -9,7 +9,7 @@
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// ------------------------------------------------------------------------
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// 数值类型拓展类

View File

@@ -17,7 +17,7 @@ using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// <see cref="string" /> 拓展类

View File

@@ -15,7 +15,7 @@ using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// <see cref="Type" /> 拓展类

View File

@@ -13,7 +13,7 @@ using System.Buffers;
using System.Text;
using System.Text.Json;
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// <see cref="Utf8JsonReader" /> 拓展类

View File

@@ -16,7 +16,7 @@ using System.Text.Json;
using ThingsGateway.Utilities;
namespace ThingsGateway.Extensions;
namespace ThingsGateway.Extension;
/// <summary>
/// <see cref="object" /> 拓展类

View File

@@ -13,7 +13,7 @@ using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.Reflection;

View File

@@ -13,7 +13,7 @@ using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.Reflection;

View File

@@ -11,7 +11,7 @@
using System.Diagnostics.CodeAnalysis;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.Utilities;

View File

@@ -11,7 +11,7 @@
using System.Text;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.Utilities;

View File

@@ -18,7 +18,7 @@ using Microsoft.Net.Http.Headers;
using System.Net.Mime;
using ThingsGateway.AspNetCore.Extensions;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue;

View File

@@ -12,7 +12,7 @@
using System.Net.Http.Headers;
using System.Threading.Channels;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.Utilities;
namespace ThingsGateway.HttpRemote;

View File

@@ -16,7 +16,7 @@ using System.Text;
using System.Text.Json;
using System.Threading.Channels;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.Utilities;
namespace ThingsGateway.HttpRemote;

View File

@@ -16,7 +16,7 @@ using Microsoft.Extensions.Logging;
using System.Reflection;
using System.Text;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -17,7 +17,7 @@ using System.Net.Mime;
using System.Text;
using System.Text.Json;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.Utilities;
using MediaTypeHeaderValue = System.Net.Http.Headers.MediaTypeHeaderValue;

View File

@@ -16,7 +16,7 @@ using System.Globalization;
using System.Net.Http.Headers;
using System.Net.Mime;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using CacheControlHeaderValue = System.Net.Http.Headers.CacheControlHeaderValue;
using StringWithQualityHeaderValue = System.Net.Http.Headers.StringWithQualityHeaderValue;

View File

@@ -14,7 +14,7 @@
using System.Collections.Concurrent;
using System.Reflection;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -12,7 +12,7 @@
using System.Net.Mime;
using System.Reflection;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -11,7 +11,7 @@
using System.Reflection;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.Utilities;
namespace ThingsGateway.HttpRemote;

View File

@@ -11,7 +11,7 @@
using System.Reflection;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.Utilities;
namespace ThingsGateway.HttpRemote;

View File

@@ -14,7 +14,7 @@ using System.Net.Mime;
using System.Reflection;
using System.Text;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -9,7 +9,7 @@
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// ------------------------------------------------------------------------
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.Utilities;
namespace ThingsGateway.HttpRemote;

View File

@@ -11,7 +11,7 @@
using System.Reflection;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.Utilities;
namespace ThingsGateway.HttpRemote;

View File

@@ -11,7 +11,7 @@
using System.Reflection;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.Utilities;
namespace ThingsGateway.HttpRemote;

View File

@@ -12,7 +12,7 @@
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -12,7 +12,7 @@
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -14,7 +14,7 @@ using Microsoft.Extensions.DependencyInjection;
using System.Net.Http.Headers;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote.Extensions;

View File

@@ -18,7 +18,7 @@ using System.Net.Http.Headers;
using System.Text;
using System.Text.RegularExpressions;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.Utilities;
using StringWithQualityHeaderValue = System.Net.Http.Headers.StringWithQualityHeaderValue;

View File

@@ -11,7 +11,7 @@
using Microsoft.Extensions.DependencyInjection;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -11,7 +11,7 @@
using System.Text;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -14,7 +14,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.HttpRemote.Extensions;
namespace ThingsGateway.HttpRemote;

View File

@@ -11,7 +11,7 @@
using System.Globalization;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -15,7 +15,7 @@ using Microsoft.Extensions.Options;
using System.Diagnostics;
using System.Threading.Channels;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -15,7 +15,7 @@ using Microsoft.Extensions.Options;
using System.Diagnostics;
using System.Threading.Channels;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -14,7 +14,7 @@ using Microsoft.Extensions.Options;
using System.Threading.Channels;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -16,7 +16,7 @@ using System.Diagnostics.CodeAnalysis;
using System.Text;
using System.Threading.Channels;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -9,7 +9,7 @@
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// ------------------------------------------------------------------------
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.Utilities;
namespace ThingsGateway.HttpRemote;

View File

@@ -14,7 +14,7 @@ using System.Net.Http.Headers;
using System.Net.Mime;
using System.Text;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -14,7 +14,7 @@ using System.Net.Http.Headers;
using System.Reflection;
using System.Text;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -12,7 +12,7 @@
using System.Net.Mime;
using System.Text;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -13,7 +13,7 @@ using System.Globalization;
using System.Net.Http.Headers;
using System.Text;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -20,7 +20,7 @@ using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -18,7 +18,7 @@ using System.Net;
using System.Reflection;
using System.Text.RegularExpressions;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -9,7 +9,7 @@
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// ------------------------------------------------------------------------
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -12,7 +12,7 @@
using System.Net.WebSockets;
using System.Text;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.HttpRemote;

View File

@@ -19,7 +19,7 @@ using System.Net.Mime;
using System.Reflection;
using System.Web;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.Shapeless;

View File

@@ -17,7 +17,7 @@ using System.Text.Json.Nodes;
using System.Xml;
using System.Xml.Linq;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.Shapeless;

View File

@@ -13,7 +13,7 @@ using System.Dynamic;
using System.Reflection;
using System.Text.Json;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
using ThingsGateway.Shapeless.Extensions;
using Binder = Microsoft.CSharp.RuntimeBinder.Binder;

View File

@@ -15,7 +15,7 @@ using System.Dynamic;
using System.Text.Json;
using System.Text.Json.Nodes;
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.Shapeless;

View File

@@ -5,30 +5,101 @@ namespace ThingsGateway.NewLife;
public class ExpiringDictionary<TKey, TValue> : IDisposable
{
private ConcurrentDictionary<TKey, TValue> _dict = new();
private readonly TimerX _cleanupTimer;
public ExpiringDictionary(int cleanupInterval = 60000)
/// <summary>缓存项</summary>
public class CacheItem
{
_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)
{
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)
{
return _dict.GetOrAdd(key, func);
}
public TValue GetOrAdd(TKey key, TValue value)
{
return _dict.GetOrAdd(key, value);
CacheItem? item = null;
do
{
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 _);
@@ -41,7 +112,31 @@ public class ExpiringDictionary<TKey, TValue> : IDisposable
_dict = new();
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()
{
_dict.Clear();

View File

@@ -66,7 +66,7 @@ public sealed class WaitLock : IDisposable
}
catch (SemaphoreFullException)
{
XTrace.WriteException(new Exception($"WaitLock {_name} 释放失败,当前信号量无需释放"));
//XTrace.WriteException(new Exception($"WaitLock {_name} 释放失败,当前信号量无需释放"));
}
}
}

View File

@@ -155,7 +155,7 @@ public static class DateExtensions
/// </summary>
/// <param name="timestamp"></param>
/// <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 digitCount = (int)Math.Floor(Math.Log10(timestamp) + 1);
@@ -169,4 +169,5 @@ public static class DateExtensions
? timeStampDateTime.AddMilliseconds(timestamp) // 13 位时间戳
: timeStampDateTime.AddSeconds(timestamp)).ToLocalTime(); // 10 位时间戳
}
}

View File

@@ -8,13 +8,14 @@
// 项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// ------------------------------------------------------------------------
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
#if NET6_0_OR_GREATER
using System.Text.Json;
#endif
using ThingsGateway.Extensions;
using ThingsGateway.Extension;
namespace ThingsGateway.JsonSerialization;
@@ -23,6 +24,7 @@ namespace ThingsGateway.JsonSerialization;
/// </summary>
internal static class Penetrates
{
#if NET6_0_OR_GREATER
/// <summary>
/// 转换
/// </summary>
@@ -35,7 +37,6 @@ internal static class Penetrates
{
return longValue.ConvertToDateTime();
}
var stringValue = reader.GetString();
// 处理时间戳自动转换
@@ -46,6 +47,9 @@ internal static class Penetrates
return Convert.ToDateTime(stringValue);
}
#endif
/// <summary>
/// 转换
@@ -69,4 +73,6 @@ internal static class Penetrates
return Convert.ToDateTime(stringValue);
}
}
}

View File

@@ -53,12 +53,16 @@ public static class LinqExtensions
/// <inheritdoc/>
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);
}
}
/// <inheritdoc/>
public static IEnumerable<T> WhereIf<T>(this IEnumerable<T> thisValue, bool isOk, Func<T, bool> predicate)
{

View File

@@ -0,0 +1,34 @@
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://thingsgateway.cn/
// QQ群605534569
//------------------------------------------------------------------------------
using Newtonsoft.Json;
using System.Text;
namespace ThingsGateway.Foundation;
/// <inheritdoc/>
public class NewtonsoftEncodingConverter : Newtonsoft.Json.JsonConverter<Encoding>
{
/// <inheritdoc/>
public override Encoding? ReadJson(JsonReader reader, Type objectType, Encoding? existingValue, bool hasExistingValue, Newtonsoft.Json.JsonSerializer serializer)
{
// 从 JSON 字符串中读取编码名称,并创建相应的 Encoding 对象
string? encodingName = reader.Value as string;
return Encoding.GetEncoding(encodingName ?? Encoding.UTF8.WebName);
}
/// <inheritdoc/>
public override void WriteJson(JsonWriter writer, Encoding? value, Newtonsoft.Json.JsonSerializer serializer)
{
writer.WriteValue(value.WebName);
}
}

View File

@@ -8,6 +8,7 @@
// 项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// ------------------------------------------------------------------------
#if NET6_0_OR_GREATER
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -17,7 +18,6 @@ namespace ThingsGateway.JsonSerialization;
/// <summary>
/// DateOnly 类型序列化
/// </summary>
[SuppressSniffer]
public class NewtonsoftJsonDateOnlyJsonConverter : JsonConverter<DateOnly>
{
/// <summary>
@@ -72,7 +72,6 @@ public class NewtonsoftJsonDateOnlyJsonConverter : JsonConverter<DateOnly>
/// <summary>
/// DateOnly? 类型序列化
/// </summary>
[SuppressSniffer]
public class NewtonsoftJsonNullableDateOnlyJsonConverter : JsonConverter<DateOnly?>
{
/// <summary>
@@ -123,4 +122,6 @@ public class NewtonsoftJsonNullableDateOnlyJsonConverter : JsonConverter<DateOnl
if (value == null) writer.WriteNull();
else writer.WriteValue(value.Value.ToString(Format));
}
}
}
#endif

View File

@@ -16,7 +16,7 @@ namespace ThingsGateway.JsonSerialization;
/// <summary>
/// DateTime 类型序列化
/// </summary>
[SuppressSniffer]
public class NewtonsoftJsonDateTimeJsonConverter : JsonConverter<DateTime>
{
/// <summary>
@@ -90,7 +90,7 @@ public class NewtonsoftJsonDateTimeJsonConverter : JsonConverter<DateTime>
/// <summary>
/// DateTime 类型序列化
/// </summary>
[SuppressSniffer]
public class NewtonsoftNullableJsonDateTimeJsonConverter : JsonConverter<DateTime?>
{
/// <summary>

View File

@@ -16,7 +16,6 @@ namespace ThingsGateway.JsonSerialization;
/// <summary>
/// DateTimeOffset 类型序列化
/// </summary>
[SuppressSniffer]
public class NewtonsoftJsonDateTimeOffsetJsonConverter : JsonConverter<DateTimeOffset>
{
/// <summary>
@@ -90,7 +89,6 @@ public class NewtonsoftJsonDateTimeOffsetJsonConverter : JsonConverter<DateTimeO
/// <summary>
/// DateTimeOffset 类型序列化
/// </summary>
[SuppressSniffer]
public class NewtonsoftJsonNullableDateTimeOffsetJsonConverter : JsonConverter<DateTimeOffset?>
{
/// <summary>

View File

@@ -8,7 +8,7 @@
// 项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// ------------------------------------------------------------------------
#if NET6_0_OR_GREATER
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -18,7 +18,6 @@ namespace ThingsGateway.JsonSerialization;
/// <summary>
/// <see cref="System.Text.Json.Nodes.JsonObject"/> 类型序列化
/// </summary>
[SuppressSniffer]
public class NewtonsoftJsonJsonObjectJsonConverter : JsonConverter<System.Text.Json.Nodes.JsonObject>
{
/// <summary>
@@ -50,7 +49,6 @@ public class NewtonsoftJsonJsonObjectJsonConverter : JsonConverter<System.Text.J
/// <summary>
/// <see cref="System.Text.Json.Nodes.JsonArray"/> 类型序列化
/// </summary>
[SuppressSniffer]
public class NewtonsoftJsonJsonArrayJsonConverter : JsonConverter<System.Text.Json.Nodes.JsonArray>
{
/// <summary>
@@ -77,4 +75,6 @@ public class NewtonsoftJsonJsonArrayJsonConverter : JsonConverter<System.Text.Js
{
writer.WriteRawValue(value.ToJsonString());
}
}
}
#endif

View File

@@ -17,7 +17,6 @@ namespace ThingsGateway.JsonSerialization;
/// <summary>
/// 解决 long 精度问题
/// </summary>
[SuppressSniffer]
public class NewtonsoftJsonLongToStringJsonConverter : JsonConverter<long>
{
/// <summary>
@@ -79,7 +78,6 @@ public class NewtonsoftJsonLongToStringJsonConverter : JsonConverter<long>
/// <summary>
/// 解决 long? 精度问题
/// </summary>
[SuppressSniffer]
public class NewtonsoftJsonNullableLongToStringJsonConverter : JsonConverter<long?>
{
/// <summary>

View File

@@ -8,7 +8,7 @@
// 项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// ------------------------------------------------------------------------
#if NET6_0_OR_GREATER
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -17,7 +17,6 @@ namespace ThingsGateway.JsonSerialization;
/// <summary>
/// TimeOnly 类型序列化
/// </summary>
[SuppressSniffer]
public class NewtonsoftJsonTimeOnlyJsonConverter : JsonConverter<TimeOnly>
{
/// <summary>
@@ -72,7 +71,6 @@ public class NewtonsoftJsonTimeOnlyJsonConverter : JsonConverter<TimeOnly>
/// <summary>
/// TimeOnly? 类型序列化
/// </summary>
[SuppressSniffer]
public class NewtonsoftJsonNullableTimeOnlyJsonConverter : JsonConverter<TimeOnly?>
{
/// <summary>
@@ -123,4 +121,6 @@ public class NewtonsoftJsonNullableTimeOnlyJsonConverter : JsonConverter<TimeOnl
if (value == null) writer.WriteNull();
else writer.WriteValue(value.Value.ToString(Format));
}
}
}
#endif

View File

@@ -8,6 +8,8 @@
// QQ群605534569
//------------------------------------------------------------------------------
using ThingsGateway.NewLife;
namespace ThingsGateway;
/// <inheritdoc/>
@@ -38,10 +40,8 @@ public static class PathExtensions
path = Path.Combine(path, text);
}
}
// 处理路径分隔符兼容Windows和Linux
var sep = Path.DirectorySeparatorChar;
var sep2 = sep == '/' ? '\\' : '/';
path = path.Replace(sep2, sep);
path = path.Replace('\\', '/');
return path;
}
}

View File

@@ -463,7 +463,7 @@ public static class ProcessHelper
StandardOutputEncoding = outputEncoding,
StandardErrorEncoding = outputEncoding,
};
var process = Process.Start(psi);
using var process = Process.Start(psi);
if (process == null) return null;
if (msWait > 0 && !process.WaitForExit(msWait))

View File

@@ -14,8 +14,6 @@ using System.Text.Json;
#endif
using Newtonsoft.Json;
using System.Text;
namespace ThingsGateway.Foundation;
@@ -41,21 +39,3 @@ public class EncodingConverter : System.Text.Json.Serialization.JsonConverter<En
}
}
#endif
/// <inheritdoc/>
public class NewtonsoftEncodingConverter : Newtonsoft.Json.JsonConverter<Encoding>
{
/// <inheritdoc/>
public override Encoding? ReadJson(JsonReader reader, Type objectType, Encoding? existingValue, bool hasExistingValue, Newtonsoft.Json.JsonSerializer serializer)
{
// 从 JSON 字符串中读取编码名称,并创建相应的 Encoding 对象
string? encodingName = reader.Value as string;
return Encoding.GetEncoding(encodingName ?? Encoding.UTF8.WebName);
}
/// <inheritdoc/>
public override void WriteJson(JsonWriter writer, Encoding? value, Newtonsoft.Json.JsonSerializer serializer)
{
writer.WriteValue(value.WebName);
}
}

Some files were not shown because too many files have changed in this diff Show More