mirror of
https://github.com/ThingsGateway/ThingsGateway.git
synced 2026-10-16 20:51:21 +08:00
新增: 新增网关冗余的数据同步使能配置项,关闭后不再同步数据
This commit is contained in:
+9
-20
@@ -13,14 +13,14 @@
|
||||
CS8002;NU1510;SYSLIB5007;CS8603;CS8618;CS1591;CS8625;CS8602;CS8604;CS8600;CS8601;CS8714;CS8619;CS8629;CS8765;CS8634;CS8621;CS8767;CS8633;CS8620;CS8610;CS8631;CS8605;CS8622;CS8613;NU5100;NU5104;NU1903;NU1902;CA1863;CA1812;CA1805;CA1515;CA1508;CA1819;CA1852;CA5394;CA1822;CA1815;CA1813;CA5358;CA5384;CA5400;CA5401;CA1814;CA1835;CA5392;CA5350;CA2100;CA1848;CA1810;CA1513;CA5351;CA1510;CA1512;CA1823;RCS1102;RCS1194;NETSDK1206
|
||||
</NoWarn>
|
||||
<TouchSocketVersion>4.1.7</TouchSocketVersion>
|
||||
<AdminVersion>12.4.56</AdminVersion>
|
||||
<FoundationVersion>12.4.71</FoundationVersion>
|
||||
<PluginVersion>12.4.57</PluginVersion>
|
||||
<ProPluginVersion>12.4.47</ProPluginVersion>
|
||||
<GatewayVersion>12.4.96</GatewayVersion>
|
||||
<AdminVersion>12.4.57</AdminVersion>
|
||||
<FoundationVersion>12.4.72</FoundationVersion>
|
||||
<PluginVersion>12.4.58</PluginVersion>
|
||||
<ProPluginVersion>12.4.48</ProPluginVersion>
|
||||
<GatewayVersion>12.4.97</GatewayVersion>
|
||||
<Version>$(GatewayVersion)</Version>
|
||||
|
||||
<ManagementVersion>12.4.41</ManagementVersion>
|
||||
|
||||
<ManagementVersion>12.4.42</ManagementVersion>
|
||||
|
||||
|
||||
<LangVersion>preview</LangVersion>
|
||||
@@ -30,12 +30,11 @@
|
||||
<NET8Version>8.0.24</NET8Version>
|
||||
<SatelliteResourceLanguages>zh-Hans;en-US</SatelliteResourceLanguages>
|
||||
|
||||
|
||||
<!--设置为 true时,删除特定于全球化的代码和数据。 有关详细信息,请参阅固定模式。-->
|
||||
<InvariantGlobalization>false</InvariantGlobalization>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' != 'net8.0' ">
|
||||
<PluginTargetFramework>net10.0</PluginTargetFramework>
|
||||
</PropertyGroup>
|
||||
@@ -45,30 +44,20 @@
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
<AnalysisModeDesign>None</AnalysisModeDesign>
|
||||
<AnalysisModeDocumentation>All</AnalysisModeDocumentation>
|
||||
<AnalysisModeGlobalization>None</AnalysisModeGlobalization>
|
||||
<AnalysisModeInteroperability>All</AnalysisModeInteroperability>
|
||||
<AnalysisModeMaintainability>All</AnalysisModeMaintainability>
|
||||
<AnalysisModeNaming>None</AnalysisModeNaming>
|
||||
<AnalysisModePerformance>All</AnalysisModePerformance>
|
||||
<AnalysisModeSingleFile>All</AnalysisModeSingleFile>
|
||||
<AnalysisModeReliability>All</AnalysisModeReliability>
|
||||
<AnalysisModeSecurity>All</AnalysisModeSecurity>
|
||||
<AnalysisModeUsage>None</AnalysisModeUsage>
|
||||
<AnalysisModeStyle>None</AnalysisModeStyle>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="$(MSBuildThisFileDirectory)Directory.Build.props" Pack="true" PackagePath="\" />
|
||||
<None Include="$(MSBuildThisFileDirectory)Directory.Build.props" Pack="false" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<DebugSymbols>True</DebugSymbols>
|
||||
<DebugType>Embedded</DebugType>
|
||||
<EmbedAllSources>True</EmbedAllSources>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
<Project>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="$(MSBuildThisFileDirectory)Directory.Build.targets" Pack="false" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<PropertyGroup Condition="($([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0')) OR $([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net10.0'))) AND '$(EnableAot)' == 'true'">
|
||||
|
||||
<!--AOT 兼容性分析器-->
|
||||
<IsAotCompatible>true</IsAotCompatible>
|
||||
<IsTrimmable>true</IsTrimmable>
|
||||
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
|
||||
<EnableSingleFileAnalyzer>true</EnableSingleFileAnalyzer>
|
||||
<EnableAotAnalyzer>true</EnableAotAnalyzer>
|
||||
|
||||
<!--本机调试信息-->
|
||||
<StripSymbols>true</StripSymbols>
|
||||
|
||||
<!--编译器选择混合方法:生成快速代码,或优先考虑可执行文件的大小-->
|
||||
<!--<OptimizationPreference>Speed</OptimizationPreference>-->
|
||||
<OptimizationPreference>Speed</OptimizationPreference>
|
||||
|
||||
<!--设置为 false时,将删除对解析非文件 URL System.Xml的支持。 仅支持文件系统解析。-->
|
||||
<XmlResolverIsNetworkingEnabledByDefault>false</XmlResolverIsNetworkingEnabledByDefault>
|
||||
|
||||
<!--设置为 true时,将去除程序集的 System.* 异常消息。 从 System.* 程序集引发异常时,该消息是简化的资源 ID,而不是完整消息-->
|
||||
<UseSystemResourceKeys>true</UseSystemResourceKeys>
|
||||
|
||||
<!--设置为 true时,使用 Android 和 iOS 的默认平台实现 HttpMessageHandler 并删除托管实现。-->
|
||||
<UseNativeHttpHandler>true</UseNativeHttpHandler>
|
||||
|
||||
<!--如果设置为true ,则删除 LINQ 中的某些吞吐量优化,以免对应用程序的大小产生不利影响-->
|
||||
<UseSizeOptimizedLinq>false</UseSizeOptimizedLinq>
|
||||
|
||||
<!--设置为 false时,删除运行时生成堆栈跟踪(例如或 Environment.StackTraceException.ToString)的支持。 从堆栈跟踪字符串中删除的信息量可能取决于其他部署选项。 此选项不会影响调试器生成的堆栈跟踪。-->
|
||||
<StackTraceSupport>true</StackTraceSupport>
|
||||
|
||||
<!--设置为 false时,删除对检测的支持 System.Diagnostics.Metrics 。-->
|
||||
<MetricsSupport>false</MetricsSupport>
|
||||
|
||||
<!--设置为 false时,删除与热重载相关的元数据更新特定逻辑。-->
|
||||
<MetadataUpdaterSupport>false</MetadataUpdaterSupport>
|
||||
|
||||
<!--设置为 true时,删除特定于全球化的代码和数据。 有关详细信息,请参阅固定模式。-->
|
||||
<InvariantGlobalization>false</InvariantGlobalization>
|
||||
|
||||
<!--设置为 false时,删除与诊断支持 System.Net.Http相关的代码。-->
|
||||
<HttpActivityPropagationSupport>false</HttpActivityPropagationSupport>
|
||||
|
||||
<!--设置为 false时,删除与对 HTTP/3 的支持 System.Net.Http相关的代码。-->
|
||||
<Http3Support>false</Http3Support>
|
||||
|
||||
<!--设置为 false时,删除与 EventSource 相关的代码和逻辑。-->
|
||||
<EventSourceSupport>false</EventSourceSupport>
|
||||
|
||||
<!--设置为 false后,删除不安全的 UTF-7 编码代码。 有关详细信息,请参阅 UTF-7 代码路径已过时。-->
|
||||
<EnableUnsafeUTF7Encoding>false</EnableUnsafeUTF7Encoding>
|
||||
|
||||
<!--设置为 false时,删除 BinaryFormatter 序列化支持。 有关详细信息,请参阅 BinaryFormatter 序列化方法已过时 , 并且已删除内置 BinaryFormatter 实现,并且始终引发。-->
|
||||
<EnableUnsafeBinaryFormatterSerialization>false</EnableUnsafeBinaryFormatterSerialization>
|
||||
|
||||
<!--设置为 false时,删除支持更好的调试体验的代码。 此设置还会删除符号。-->
|
||||
<DebuggerSupport>false</DebuggerSupport>
|
||||
|
||||
<!--设置为 false时,删除在受支持的平台上创建 自动发布池 的代码。 false 是 .NET SDK 的默认值。-->
|
||||
<AutoreleasePoolSupport>false</AutoreleasePoolSupport>
|
||||
|
||||
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
|
||||
</Project>
|
||||
+32
-14
@@ -1,4 +1,9 @@
|
||||
<Project>
|
||||
<PropertyGroup Condition="'$(DisableDebugSymbols)' != 'true'">
|
||||
<DebugSymbols>True</DebugSymbols>
|
||||
<DebugType>Embedded</DebugType>
|
||||
<EmbedAllSources>True</EmbedAllSources>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -11,18 +16,32 @@
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
|
||||
|
||||
<SignAssembly>True</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)ThingsGateway.snk</AssemblyOriginatorKeyFile>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<!--Condition="'$(Configuration)' == 'Release'"-->
|
||||
<PropertyGroup>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="$(MSBuildThisFileDirectory)PackNuget.props" Pack="false" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="$(MSBuildThisFileDirectory)README.md" Pack="true" PackagePath="\" />
|
||||
<None Include="$(MSBuildThisFileDirectory)LICENSE" Pack="true" PackagePath="\" />
|
||||
<None Include="$(MSBuildThisFileDirectory)icon.png" Pack="true" PackagePath="\" />
|
||||
<None Include="$(MSBuildThisFileDirectory)logo.svg" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Roslynator.Analyzers" Version="4.15.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
@@ -35,16 +54,15 @@
|
||||
</PackageReference>
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="$(MSBuildThisFileDirectory)PackNuget.props" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="$(MSBuildThisFileDirectory)README.md" Pack="true" PackagePath="\" />
|
||||
<None Include="$(MSBuildThisFileDirectory)LICENSE" Pack="true" PackagePath="\" />
|
||||
<None Include="$(MSBuildThisFileDirectory)icon.png" Pack="true" PackagePath="\" />
|
||||
<None Include="$(MSBuildThisFileDirectory)logo.svg" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</Project>
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
<Solution>
|
||||
<Folder Name="/Benchmark/" />
|
||||
<Folder Name="/benchmark/" />
|
||||
<Folder Name="/src/">
|
||||
<Project Path="src/ThingsGateway.Foundation.Razor/ThingsGateway.Foundation.Razor.csproj" />
|
||||
<Project Path="src/ThingsGateway.Gateway.Application/ThingsGateway.Gateway.Application.csproj" />
|
||||
@@ -8,10 +8,10 @@
|
||||
<Project Path="src/ThingsGateway.Management.Application/ThingsGateway.Management.Application.csproj" />
|
||||
<Project Path="src/ThingsGateway.Management.Razor/ThingsGateway.Management.Razor.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/Test/">
|
||||
<Folder Name="/test/">
|
||||
<Project Path="test/ThingsGateway.Gateway.Test/ThingsGateway.Gateway.Test.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/解决方案项/">
|
||||
<Folder Name="/props/">
|
||||
<File Path=".gitignore" />
|
||||
<File Path="Directory.Build.props" />
|
||||
<File Path="PackNuget.props" />
|
||||
|
||||
@@ -15,7 +15,6 @@ using Microsoft.Extensions.Localization;
|
||||
|
||||
using ThingsGateway.Foundation;
|
||||
using ThingsGateway.Foundation.Common;
|
||||
using ThingsGateway.Foundation.Common.Extension;
|
||||
using ThingsGateway.Foundation.Common.Json.Extension;
|
||||
|
||||
using TouchSocket.Core;
|
||||
|
||||
@@ -14,6 +14,7 @@ using Riok.Mapperly.Abstractions;
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using ThingsGateway.Foundation.Common.Json.Extension;
|
||||
|
||||
namespace ThingsGateway.Gateway.Application;
|
||||
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
"Status": "Current Site Status",
|
||||
"Switch": "Switch",
|
||||
"SyncInterval": "Data Synchronization Interval",
|
||||
"SyncEnable": "Enable Data Synchronization",
|
||||
"VerifyToken": "Verification Token"
|
||||
},
|
||||
"ThingsGateway.Gateway.Application.RedundancyService": {
|
||||
|
||||
@@ -134,6 +134,7 @@
|
||||
"Status": "当前站点状态",
|
||||
"Switch": "切换",
|
||||
"SyncInterval": "数据同步间隔",
|
||||
"SyncEnable": "数据同步使能",
|
||||
"VerifyToken": "验证令牌"
|
||||
},
|
||||
"ThingsGateway.Gateway.Application.RedundancyService": {
|
||||
|
||||
@@ -14,6 +14,7 @@ using Riok.Mapperly.Abstractions;
|
||||
using System.Collections.Concurrent;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text.Json.Nodes;
|
||||
using ThingsGateway.Foundation.Common.Json.Extension;
|
||||
using ThingsGateway.Gateway.Application.Extensions;
|
||||
|
||||
#if !Management
|
||||
|
||||
@@ -71,7 +71,15 @@
|
||||
"Code": "3000",
|
||||
"IsDelete": "0",
|
||||
"SortCode": 99
|
||||
},
|
||||
{
|
||||
"Id": 234511701160015,
|
||||
"DictType": "System",
|
||||
"Category": "RedundancyOptions",
|
||||
"Name": "SyncEnable",
|
||||
"Code": "true",
|
||||
"IsDelete": "0",
|
||||
"SortCode": 99
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
+5
@@ -63,4 +63,9 @@ public class RedundancyOptions
|
||||
/// </summary>
|
||||
[MinValue(1000)]
|
||||
public int SyncInterval { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置开启冗余数据同步。
|
||||
/// </summary>
|
||||
public bool SyncEnable { get; set; } = true;
|
||||
}
|
||||
|
||||
+2
@@ -39,6 +39,7 @@ internal sealed class RedundancyService : BaseService<SysDict>, IRedundancyServi
|
||||
new SysDict() { DictType = DictTypeEnum.System, Category = nameof(RedundancyOptions), Name = nameof(RedundancyOptions.MaxErrorCount), Code = input.MaxErrorCount.ToString() },
|
||||
new SysDict() { DictType = DictTypeEnum.System, Category = nameof(RedundancyOptions), Name = nameof(RedundancyOptions.IsStartBusinessDevice), Code = input.IsStartBusinessDevice.ToString() },
|
||||
new SysDict() { DictType = DictTypeEnum.System, Category = nameof(RedundancyOptions), Name = nameof(RedundancyOptions.SyncInterval), Code = input.SyncInterval.ToString() },
|
||||
new SysDict() { DictType = DictTypeEnum.System, Category = nameof(RedundancyOptions), Name = nameof(RedundancyOptions.SyncEnable), Code = input.SyncEnable.ToString() },
|
||||
};
|
||||
var storageable = await db.Storageable(dicts).WhereColumns(it => new { it.DictType, it.Category, it.Name }).ToStorageAsync().ConfigureAwait(false);
|
||||
|
||||
@@ -77,6 +78,7 @@ internal sealed class RedundancyService : BaseService<SysDict>, IRedundancyServi
|
||||
redundancy.MaxErrorCount = sysDicts.FirstOrDefault(a => a.Category == nameof(RedundancyOptions) && a.Name == nameof(RedundancyOptions.MaxErrorCount))?.Code.ToInt() ?? 3000;
|
||||
redundancy.IsStartBusinessDevice = sysDicts.FirstOrDefault(a => a.Category == nameof(RedundancyOptions) && a.Name == nameof(RedundancyOptions.IsStartBusinessDevice))?.Code.ToBoolean() ?? false;
|
||||
redundancy.SyncInterval = sysDicts.FirstOrDefault(a => a.Category == nameof(RedundancyOptions) && a.Name == nameof(RedundancyOptions.SyncInterval))?.Code.ToInt() ?? 30000;
|
||||
redundancy.SyncEnable = sysDicts.FirstOrDefault(a => a.Category == nameof(RedundancyOptions) && a.Name == nameof(RedundancyOptions.SyncEnable))?.Code.ToBoolean() ?? true;
|
||||
|
||||
App.CacheService.Set(key, redundancy);
|
||||
}
|
||||
|
||||
+32
-4
@@ -66,6 +66,26 @@ internal sealed class RedundancyTask : IRpcDriver, IAsyncDisposable
|
||||
? highMemorySize
|
||||
: defaultSize;
|
||||
}
|
||||
|
||||
private IEnumerable<DeviceDataWithValue> GetDeviceDataWithValues(IEnumerable<VariableRuntime> variableBasicDatas)
|
||||
{
|
||||
foreach (var item in variableBasicDatas.GroupBy(a => a.DeviceId))
|
||||
{
|
||||
if (GlobalData.IdDevices.TryGetValue(item.Key, out var device))
|
||||
{
|
||||
DeviceDataWithValue deviceDataWithValue = new();
|
||||
deviceDataWithValue.ActiveTime = device.ActiveTime;
|
||||
deviceDataWithValue.DeviceStatus = device.DeviceStatus;
|
||||
deviceDataWithValue.LastErrorMessage = device.LastErrorMessage;
|
||||
deviceDataWithValue.Name = device.Name;
|
||||
|
||||
deviceDataWithValue.ReadOnlyVariableRuntimes = item.ToDictionary(a => a.Name, a => a.AdaptVariableDataWithValue());
|
||||
|
||||
yield return deviceDataWithValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 主站
|
||||
/// </summary>
|
||||
@@ -73,6 +93,8 @@ internal sealed class RedundancyTask : IRpcDriver, IAsyncDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!RedundancyOptions.SyncEnable) return;
|
||||
|
||||
bool online = false;
|
||||
|
||||
var waitInvoke = CreateDmtpInvokeOption(stoppingToken);
|
||||
@@ -86,16 +108,22 @@ internal sealed class RedundancyTask : IRpcDriver, IAsyncDisposable
|
||||
// 如果 online 为 true,表示设备在线
|
||||
if (online)
|
||||
{
|
||||
int batchSize = 50;
|
||||
|
||||
var deviceRunTimes = GlobalData.ReadOnlyIdDevices.Where(a => a.Value.IsCollect == true).Select(a => a.Value).Concat([GlobalData.MemoryDeviceRuntime]).Batch(batchSize);
|
||||
var batchSize = GetBatchSize();
|
||||
var variableBasicDatas = GlobalData.GetEnableVariables();
|
||||
var deviceRunTimes = variableBasicDatas.ChunkBetter(batchSize);
|
||||
|
||||
var dataChunks = deviceRunTimes
|
||||
.Select(chunk => GetDeviceDataWithValues(chunk).ToList())
|
||||
.Where(data => data.Count > 0)
|
||||
;
|
||||
|
||||
foreach (var item in _tcpDmtpService.Clients)
|
||||
{
|
||||
foreach (var deviceDataWithValues in deviceRunTimes)
|
||||
foreach (var deviceDataWithValues in dataChunks)
|
||||
{
|
||||
// 将 GlobalData.CollectDevices 和 GlobalData.Variables 同步到从站
|
||||
await item.GetDmtpRpcActor().UpDataAsync(deviceDataWithValues.AdaptListDeviceDataWithValue(), waitInvoke).ConfigureAwait(false);
|
||||
await item.GetDmtpRpcActor().UpDataAsync(deviceDataWithValues, waitInvoke).ConfigureAwait(false);
|
||||
}
|
||||
LogMessage?.LogTrace($"{item.Id} Update StandbyStation data success");
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ using ThingsGateway.Blazor.Diagrams.Core;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Anchors;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Geometry;
|
||||
using ThingsGateway.Blazor.Diagrams.Core.Models;
|
||||
using ThingsGateway.Foundation.Common.Json.Extension;
|
||||
|
||||
namespace ThingsGateway.Gateway.Application;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Text.Json.Nodes;
|
||||
using ThingsGateway.Foundation.Common.Json.Extension;
|
||||
|
||||
namespace ThingsGateway.Gateway.Application;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Text.Json.Nodes;
|
||||
using ThingsGateway.Foundation.Common.Json.Extension;
|
||||
|
||||
namespace ThingsGateway.Gateway.Application;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Portable.BouncyCastle" Version="1.9.0" />
|
||||
<PackageReference Include="Riok.Mapperly" Version="4.3.1" ExcludeAssets="runtime" PrivateAssets="all" />
|
||||
|
||||
|
||||
<PackageReference Include="Rougamo.Fody" Version="5.0.2" />
|
||||
<PackageReference Include="TouchSocket.Dmtp" Version="$(TouchSocketVersion)" />
|
||||
<PackageReference Include="TouchSocket.WebApi" Version="$(TouchSocketVersion)" />
|
||||
|
||||
@@ -12,8 +12,6 @@ using Microsoft.AspNetCore.ResponseCompression;
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
using ThingsGateway.Admin.Application;
|
||||
using ThingsGateway.Common;
|
||||
using ThingsGateway.DB;
|
||||
using ThingsGateway.Foundation.Common;
|
||||
|
||||
Reference in New Issue
Block a user